You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
We present an algorithm that takes as input an arbitrarily long sequence of positive integers `a₁, a₂, a₃, ..., aₙ` and a positive integer `m` and computes `a₁^(a₂^(···^aₙ)) mod m` efficiently (that is, without computing the value of the nested exponent).
33
+
34
+
Without this algorithm, this type of computation is unfeasible for modern computers even for short input sequences containing small integers.
"We present an algorithm that takes as input an arbitrarily long sequence of positive integers $a_1,a_2,\\ldots,a_\\ell$ and a positive integer $m$ and computes\n",
"We call $a_1$ the **base** and $E(a_2,\\ldots,a_\\ell)$ the **exponent** of $E(a_1,a_2,\\ldots,a_\\ell)$.\n",
47
+
"\n",
48
+
"---\n",
49
+
"\n",
50
+
"We are interested in computing $E(a_1,a_2,\\ldots,a_\\ell)\\bmod m$."
51
+
],
52
+
"cell_type": "markdown",
53
+
"metadata": {}
54
+
},
55
+
{
56
+
"source": [
57
+
"# Preliminaries"
58
+
],
59
+
"cell_type": "markdown",
60
+
"metadata": {}
61
+
},
62
+
{
63
+
"cell_type": "code",
64
+
"execution_count": 1,
65
+
"metadata": {},
66
+
"outputs": [
67
+
{
68
+
"output_type": "stream",
69
+
"name": "stdout",
70
+
"text": [
71
+
"Defaulting to user installation because normal site-packages is not writeable\n",
72
+
"Requirement already satisfied: mod-nest-exp in /home/avbrook/.local/lib/python3.9/site-packages (1.1.0)\n"
73
+
]
74
+
}
75
+
],
76
+
"source": [
77
+
"!python3 -m pip install mod-nest-exp"
78
+
]
79
+
},
80
+
{
81
+
"source": [
82
+
"# The algorithm"
83
+
],
84
+
"cell_type": "markdown",
85
+
"metadata": {}
86
+
},
87
+
{
88
+
"source": [
89
+
"## `pow_lt`\n",
90
+
"\n",
91
+
"`pow_lt` takes as input a sequence of positive integers $e_1,e_2,\\ldots,e_\\ell$ and a positive number $k$ and returns `True` iff $E(e_1,e_2,\\ldots,e_\\ell)\\lt k$."
92
+
],
93
+
"cell_type": "markdown",
94
+
"metadata": {}
95
+
},
96
+
{
97
+
"cell_type": "code",
98
+
"execution_count": 2,
99
+
"metadata": {},
100
+
"outputs": [],
101
+
"source": [
102
+
"from decimal import Decimal\n",
103
+
"from math import ceil\n",
104
+
"\n",
105
+
"def pow_lt(seq, k):\n",
106
+
" if not len(seq): # if len(seq) == 0\n",
107
+
" return 1 < k\n",
108
+
"\n",
109
+
" def _pow_lt(seq, k):\n",
110
+
" if len(seq) == 1 or seq[0] == 1:\n",
111
+
" return seq[0] < k\n",
112
+
" if seq[1]*(seq[0].bit_length()-1) >= ceil(k).bit_length():\n",
113
+
" return False\n",
114
+
" l = Decimal(k).ln()/Decimal(seq[0]).ln() # high precision logarithm\n",
115
+
" return _pow_lt(seq[1:], l) if l > 1 else False\n",
116
+
"\n",
117
+
" return _pow_lt(seq, k)"
118
+
]
119
+
},
120
+
{
121
+
"source": [
122
+
"## `pow_list`\n",
123
+
"\n",
124
+
"`pow_list` takes as input a sequence of numbers $e_1,e_2,\\ldots,e_\\ell$ and returns the value of $E(e_1,e_2,\\ldots,e_\\ell)$."
125
+
],
126
+
"cell_type": "markdown",
127
+
"metadata": {}
128
+
},
129
+
{
130
+
"cell_type": "code",
131
+
"execution_count": 3,
132
+
"metadata": {},
133
+
"outputs": [],
134
+
"source": [
135
+
"def pow_list(seq):\n",
136
+
" l = len(seq)\n",
137
+
" if not l: # if len(seq) == 0\n",
138
+
" return 1\n",
139
+
" elif l == 1: # if len(seq) == 1\n",
140
+
" return seq[0]\n",
141
+
"\n",
142
+
" def _pow_list(seq):\n",
143
+
" if seq[0] == 1:\n",
144
+
" return 1\n",
145
+
" if len(seq) == 2:\n",
146
+
" return seq[0]**seq[1]\n",
147
+
" return seq[0]**_pow_list(seq[1:])\n",
148
+
"\n",
149
+
" return _pow_list(seq)"
150
+
]
151
+
},
152
+
{
153
+
"source": [
154
+
"## The main function\n",
155
+
"\n",
156
+
"`mod_nest_exp` takes as input a sequence of positive integers $a_1,a_2,\\ldots,a_\\ell$ and a positive integer $m$ and returns $E(a_1,a_2,\\ldots,a_\\ell)\\bmod m$."
0 commit comments