forked from alpertron/calculators
-
Notifications
You must be signed in to change notification settings - Fork 0
/
ECMC.HTM
411 lines (410 loc) · 35.9 KB
/
ECMC.HTM
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
<!doctype html>
<html lang="es">
<head>
<meta charset="utf-8">
<meta name="Author" content="Dario Alejandro Alpern" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta name="description" content="Aplicación Javascript que factoriza números enteros utilizando los algoritmos ECM y SIQS. Escrito por Dario Alpern." />
<link rel="alternate" hreflang="es" href="ECMC.HTM" />
<link rel="manifest" href="/ecmc.webmanifest">
<meta name="theme-color" content="#db5945">
<link rel="icon" href="favicon.ico" type="image/x-icon" />
<title>Calculadora de factorización de números enteros</title>
<style>
@media print {#smallheader {display:none;}}
@media screen {
#smallheader {background-color:#000080; color:#FFFFFF; width:100%; margin:0px; text-align:center;}
#smallheader ul { padding:0; margin:0 auto; list-style:none; display:inline-block;}
#smallheader li { float:left; position:relative; display:block; margin-top:0px; margin-bottom:0px; margin-left:5px; margin-right:5px; background-color:#000080; color:#FFFFFF; font-family:"Arial", sans-serif; cursor: pointer; text-align:left;}
#smallheader li:hover {background-color:#004000; color:#FFFFFF;}
#smallheader li ul { display:none; position:absolute; }
#smallheader li:hover ul.alignleft{ display:block; height:auto;}
#smallheader li:hover ul.alignright{ display:block; height:auto; right:0px; background-color:#004000;}
#smallheader li ul li{ clear:both; white-space: nowrap; border:0px; background-color:#004000; width:100%; padding-top:1em; padding-bottom:0.5em}
#smallheader a:link{color:#FFFFFF; text-decoration: none;}
#smallheader a:visited{color:#FFFFFF; text-decoration: none;}
#smallheader a:hover{background-color:#004000; color:#FFFFFF; text-decoration: none;}
#smallheader a:active{background-color:#004000; color:#FFFFFF; text-decoration: none;}
#smallheader li ul li a:link{background-color:#004000; color:#FFFFFF; display:block; width:100%;}
#smallheader li ul li a:visited{background-color:#004000;color:#FFFFFF; display:block; width:100%;}
#smallheader li ul li a:hover{background-color:#FFFFFF; color:#004000; display:block; width:100%;}
#smallheader li ul li a:active{background-color:#FFFFFF; color:#004000; display:block; width:100%;}
.newline {clear:both;}
}
.atright {float:right;}
@media screen and (max-width: 400px) {#smallheader {font-size:0.7em;}}
@media screen and (min-width: 400px) {#smallheader {font-size:1em;}}
@media screen and (min-width: 500px) {#configleft {float:left;}}
body {font-family: arial; margin: 0; padding: 0; background-color:#FFFFFF; color:#000000}
h1 {text-align:center;}
.lf {padding:0.2em; clear:both;}
.blue {color: #0000FF;}
.applet {margin-left: auto;margin-right: auto; border: 0px none;width:90%;text-align:center;background-color:#c0c0c0;padding:10px;}
#cont {display:none;}
#digits {width:5em}
#value {white-space:pre;overflow-wrap:normal;overflow:auto;}
#wizard {display:none;}
.inline {display:inline;}
.pad {padding:10px;}
.hex {font-family: Courier, "Lucida Console", monospace}
.und {text-decoration: underline;}
#tableCurves {max-width:700px; margin-left:auto; margin-right:auto;}
#help,#result,#status,#footer {margin: 3px; padding: 3px;}
#more,#stop {display:none}
@media (min-width: 400px) {.input {width: calc(100% - 6em);float:right;padding:3px;margin:0px;}}
@media (max-width: 400px) {.input {width:100%;padding:3px;margin:0px;}}
.modal-header {padding: 2px 10px; background-color: #5cb85c; color: white;}
.modal-body {padding: 2px 10px;}
.modal-content {
position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%);
background-color: #fefefe;
padding: 0;
border: 1px solid #888;
width: 80%;
box-shadow: 0 4px 8px 0 rgba(0,0,0,0.2),0 6px 20px 0 rgba(0,0,0,0.19);
}
.modal {
display: none;
position: fixed;
z-index: 1;
left: 0;
top: 0;
width: 100%;
height: 100%;
overflow: auto;
background-color: rgb(0,0,0);
background-color: rgba(0,0,0,0.4);
}
#close {float:right}
#modal-header-text {font-size:1.5em}
@-webkit-keyframes animatetop {from {top: -300px; opacity: 0} to {top: 0; opacity: 1}}
@keyframes animatetop {from {top: -300px; opacity: 0} to {top: 0; opacity: 1}}
table, td, th { border: 1px solid gray }
</style>
</head>
<body>
<nav id="smallheader">
<div class="atright"><a href="ENGLISH.HTM" hreflang="en" title="Dario Alpern's Web site in English">ENG</a></div>
<ul>
<li>
Electrónica
<ul class="alignleft">
<li><a href="INTEL.HTM" title="Todos los microprocesadores de Intel desde el 4004 al Pentium">Microprocesadores Intel</a></li>
</ul>
</li>
<li>
Matemáticas
<ul class="alignleft">
<li><a href="CALDORAS.HTM" title="Programas en Java y Javascript que implementan calculadoras">Calculadoras</a></li>
<li><a href="TNUMEROS.HTM" title="Artículos y programas sobre teoría de números">Teoría de números</a></li>
<li><a href="PROBLEMAS.HTM" title="Problemas matemáticos interesantes">Problemas</a></li>
</ul>
</li>
<li>
Programas
<ul class="alignright">
<li><a href="ENSAM386.HTM" title="Programas escritos en lenguaje ensamblador del 80386">Assembler 80386</a></li>
<li><a href="PROGJAVA.HTM" title="Programas escritos en Java">Java</a></li>
<li><a href="JUEGOS.HTM" title="Juegos en línea y para descargar">Juegos</a></li>
</ul>
</li>
<li class="alignright">
Contacto
<ul class="alignright">
<li><a href="PERSONAL.HTM" title="Información personal">Personal</a></li>
<li><a href="FORMULAR.HTM" title="Formulario para enviar comentarios">Comentarios</a></li>
<li><a href="GBOOK.HTM" title="Viejo y nuevo libro de visitas">Libro de invitados</a></li>
<li><a href="DONATION.HTM" title="Donaciones al autor de este sitio Web">Donaciones</a></li>
</ul>
</li>
</ul>
<br class="newline"/>
</nav>
<main id="main">
<article>
<h1>Calculadora de factorización de números enteros</h1>
<div class="pad">
<div id="a" itemscope="itemscope" itemtype="http://data-vocabulary.org/Breadcrumb" itemref="b" class="inline">
<a href="ENGLISH.HTM" itemprop="url">
<span itemprop="title">Alpertron</span>
</a> ›
</div>
<div id="b" itemscope="itemscope" itemtype="http://data-vocabulary.org/Breadcrumb" itemprop="child" itemref="c" class="inline">
<a href="PROGJAVA.HTM" itemprop="url">
<span itemprop="title">Programas</span>
</a> ›
</div>
<div id="c" itemscope="itemscope" itemtype="http://data-vocabulary.org/Breadcrumb" itemprop="child" class="inline">
<a href="ECMC.HTM" itemprop="url">
<span itemprop="title">Calculadora de factorización de números enteros</span>
</a>
</div>
</div>
<form class="applet">
<label for="value">Valor</label><textarea id="value" rows="4" class="input"></textarea>
<br class="newline"/>
Una expresión numérica o ciclo por línea. Ejemplo: x=3;x=n(x);c<=100;x‑1
</div>
<div class="lf"></div>
<input type="button" id="more" value="Más" />
<input type="button" id="eval" value="Solo evaluar" />
<input type="button" id="factor" value="Factorizar" />
<input type="button" id="stop" value="Parar" />
<input type="button" id="helpbtn" value="Ayuda" />
<input type="button" id="config" value="Config" />
<input type="button" id="openwizard" value="Asistente" />
<div class="lf"></div>
<input type="hidden" id="app" value="1"/>
</form>
<div id="help" aria-live="polite">
<p>Esta aplicación factoriza números o expresiones numéricas usando los algoritmos rápidos ECM y SIQS.</p>
<p>Este programa utiliza almacenamiento local para recordar el avance de la factorización, así que puedes completar la factorización de un número grande en varias sesiones. Tu computadora recordará el estado de la factorización. Sólo debes recargar esta página.</p>
<p>El tiempo de ejecución depende de la magnitud del segundo mayor factor primo y de la velocidad del equipo.</p>
<p>Como todos los cáculos se realizan en tu computadora, puedes desconectarla de Intenet mientras progresa la factorización. Puedes arrancar esta aplicación sin conexión de Internet después de la primera corrida.</p>
<p>El código fuente está escrito en lenguaje C y compilado en asm.js y WebAssembly. Este último es más rápido, pero no está soportado en todos los navegadores Web. Podrás ver la versión que se ejecuta al factorizar un número.</p>
<p><a href="ECMREC.HTM" title="récords de factorización ECM">Récords de factorización</a> para esta aplicación.
<p>
<h2>Expresiones</h2>
<p>Puedes ingresar expresiones que usen los siguientes operadores y paréntesis:</p>
<p>
<ul>
<li> + para suma
<li> - para resta
<li> * para multiplicación
<li> / para división entera
<li> % para el resto de la división entera
<li> ^ o ** para exponenciación (el exponente debe ser mayor o igual que cero).
<li> <strong><</strong>, <strong>==</strong>, <strong>></strong>; <strong><=</strong>, <strong>>=</strong>, != para comparaciones. Los operadores devuelven cero si es falso y -1 si es verdadero.
<li> <strong>AND</strong>, <strong>OR</strong>, <strong>XOR</strong>, <strong>NOT</strong> para lógica binaria.
<li> <strong>SHL</strong>: Desplazar a la izquierda la cantidad de bits indicada en el operando derecho.
<li> <strong>SHR</strong>: Desplazar a la derecha la cantidad de bits indicada en el operando derecho.
<li> <strong>n!</strong>: factorial (<var>n</var> debe ser mayor o igual que cero).
<li> <strong>p#</strong>: primorial (producto de todos los primos menores o iguales a <var>p</var>).
<li> <strong>B(n)</strong>: Número probablemente primo anterior a <var>n</var></li>
<li> <strong>F(n)</strong>: Número de Fibonacci F<sub>n</sub>
<li> <strong>L(n)</strong>: Número de Lucas L<sub>n</sub> = F<sub><var>n</var>-1</sub> + F<sub><var>n</var>+1</sub>
<li> <strong>N(n)</strong>: Número probablemente primo posterior a <var>n</var></li>
<li> <strong>P(n)</strong>: particiones irrestrictas (cantidad de descomposiciones de <var>n</var> en sumas de números enteros sin tener en cuenta el orden).
<li> <strong>Gcd(m,n)</strong>: Máximo común divisor de estos dos números enteros.
<li> <strong>Modinv(m,n)</strong>: inverso de <var>m</var> modulo <var>n</var>, sólo válido cuando gcd(m,n)=1.
<li> <strong>Modpow(m,n,r)</strong>: halla <var>m</var><sup><var>n</var></sup> módulo <var>r</var>.
<li> <strong>Totient(n)</strong>: cantidad de enteros positivos menores que <var>n</var> coprimos con <var>n</var>.
<li> <strong>IsPrime(n)</strong>: returna cero si <var>n</var> no es un primo probable y -1 si lo es.
<li> <strong>NumDivs(n)</strong>: cantidad de divisores positivos de <var>n</var> primos o compuestos.
<li> <strong>SumDivs(n)</strong>: suma de divisores positivos de <var>n</var> primos o compuestos.
<li> <strong>NumDigits(n,r)</strong>: cantidad de dígitos de <var>n</var> en base <var>r</var>.
<li> <strong>SumDigits(n,r)</strong>: suma de dígitos de <var>n</var> en base <var>r</var>.
<li> <strong>RevDigits(n,r)</strong>: halla el valor que se obtiene escribiendo para atrás los dígitos de <var>n</var> en base <var>r</var>.
<li> <strong>ConcatFact(m,n)</strong>: concatena los factores primos de <var>n</var> de acuerdo al modo expresado en <var>m</var> según lo indicado en la siguiente tabla:
<table>
<caption>Modos de la función ConcatFact</caption>
<tr><th scope="col">Modo</th><th scope="col">Orden de los factores</th><th scope="col">Factores repetidos</th></tr>
<tr><td>0</td><td>Creciente</td><td>No</td></tr>
<tr><td>1</td><td>Decreciente</td><td>No</td></tr>
<tr><td>2</td><td>Creciente</td><td>Sí</td></tr>
<tr><td>3</td><td>Decreciente</td><td>Sí</td></tr>
</table>
</li>
</ul>
<p>Puedes usar el prefijo <em>0x</em> para números hexadecimales, por ejemplo 0x38 es igual a 56.</p>
<div class="tableCurves"><table>
<caption>Valores óptimos de B1 y cantidad de curvas esperadas</caption>
<tr><th scope="col">Dígitos</th><th scope="col">Valores de B1</th><th scope="col">Curvas esperadas</th></tr>
<tr><td>15</td><td>2000</td><td>25</td></tr>
<tr><td>20</td><td>11000</td><td>90</td></tr>
<tr><td>25</td><td>50000</td><td>300</td></tr>
<tr><td>30</td><td>250000</td><td>700</td></tr>
<tr><td>35</td><td>1 000000</td><td>1800</td></tr>
<tr><td>40</td><td>3 000000</td><td>5100</td></tr>
<tr><td>45</td><td>11 000000</td><td>10600</td></tr>
<tr><td>50</td><td>43 000000</td><td>19300</td></tr>
<tr><td>55</td><td>110 000000</td><td>49000</td></tr>
<tr><td>60</td><td>260 000000</td><td>124000</td></tr>
<tr><td>65</td><td>850 000000</td><td>210000</td></tr>
<tr><td>70</td><td>2900 000000</td><td>340000</td></tr>
</table></div>
<p>El programa procesa 25 curvas con límite B1 = 2000, 300 curvas con límite B1 = 50000, 1675 curves con límite B1 = 1000000 y finalmente usa curvas con límite B1 = 11000000 hasta hallar todos los factores.</p>
<h2>Factorización de un número en varias computadoras</h2>
<p>El algoritmo de factorización ECM se puede correr fácilmente en paralelo. Para hacer esto, ejecute la factorización en la primera computadora desde la curva 1, ejecútela en la segunda computadora desde la curva 10000, en la tercera computadora desde la curva 20000, y así sucesivamente.
Para cambiar el número de curva, aprieta el botón <strong>Más</strong>, escríbalo en la caja de entrada que se encuentra en la nueva ventana y presiona el botón <B>Nueva curva</B>.
<p>Cuando una de las otras máquinas descubre un nuevo factor, deberás apretar nueva el botón <strong>Más</strong>, ingresar dicho factor en la caja de entrada y finalmente apretar el botón <strong>Factor</strong>.</p>
<h2>Factorización utilizando el método de criba cuadrática (SIQS)</h2>
<p>Cuando el número a factorizar tiene 31 a 95 dígitos, después de procesar algunas curvas para hallar factores pequeños, el programa ejecuta el algoritmo SIQS, que es mucho más rápido que ECM cuando el número tiene dos factores grandes. Como este método necesita gran cantidad de memoria de tu computadora, si arrancas otra vez el programa la factorización comenzará desde el principio. Para comenzar a factorizar inmediatamente mediante SIQS, deberás apretar el botón <strong>Más</strong>, ingresar el número cero en la caja de entrada y finalmente apretar el botón <strong>Nueva Curva</strong>.</p>
<table>
<caption>Umbral para cambio a SIQS</caption>
<tr><th scope="row">Dígitos</th><td>31-55</td><td>56-60</td><td>61-65</td><td>66-70</td><td>71-75</td><td>76-80</td><td>81-85</td><td>86-90</td><td>91-95</td></tr>
<tr><th scope="row">Curva</th><td>10</td><td>15</td><td>22</td><td>26</td><td>35</td><td>50</td><td>100</td><td>150</td><td>200</td></tr>
</table>
<h2>Configuración</h2>
<p>Puedes cambiar la configuración de esta aplicación apretando el botón <strong>Config</strong> mientras el programa no está factorizando. En ese momento aparecerá una nueva ventana donde puedes seleccionar los siguientes ajustes:</p>
<ul>
<li><strong>Dígitos por grupo</strong>: Para mejorar la legibilidad, los números grandes se separan mediante espacios formando grupos de una cantidad fija de dígitos. Con esta caja de entrada, puedes determinar la cantidad de dígitos por grupo.</li>
<li><strong>Información</strong>: No está listo aún.</li>
<li><strong>Impresión bonita</strong>: Si la casilla de verificación está marcada, los exponentes se muestran con superíndices y el signo de multiplicación es " × ". La aplicación muestra la cantidad de dígitos de los números que tienen más de 30 dígitos.
Si la casilla de verificación no está marcada, los exponentes se muestran precedidos por el signo " ^ " y la multiplicación se indica mediante asteriscos. Además nunca se muestra la cantidad de dígitos. Esto facilita la copia de resultados a otros programas matemáticos.</li>
<li><strong>Salida hexadecimal</strong>: Indica que los valores mostrados en pantalla deben figurar en hexadecimal en vez de decimal, que es lo habitual.
Para ingresar números en el formato hexadecimal es necesario que tengan los caracteres 0x adelante. Por ejemplo 0x38 = 56. El programa muestra números en hexadecimal con tipo monoespaciado.</li>
<li><strong>Usar tablas de Cunningham en el servidor</strong>: Si está seleccionado y el número a factorizar tiene la forma a<sup>b</sup> ± 1, la aplicación intentará recuperar los factores conocidos del servidor Web.
Para reducir esa base de datos, sólo se incluyen factores primos con al menos 14 dígitos, así que la aplicación deberá hallar los factores pequeños. La fuente de estos factores es la <a href="http://myfactors.mooo.com/">lista de factores de Jonathan Crombie</a> e incluye 2674850 factores de números de Cunningham.</li>
</ul>
<p>La configuración se almacena en tu dispositivo, así que si arrancas nuevamente el navegador, los ajustes no se modificarán.
<p>
<h2>Factorización en lotes</h2>
<p>Escribe una expresión por línea, y luego aprieta el botón <strong>Sólo evaluar</strong> o <strong>Factorizar</strong>.</p>
<p>Las líneas en blanco o de comentarios (que comienzan con el carácter numeral '#') se replicarán en la salida.</p>
<p>Expresión para ciclos: con la siguiente sintaxis podrás factorizar o determinar si varios números son primos con sólo digitar una línea. Deberás escribir cuatro o cinco expresiones separadas por puntos y coma:</p>
<ul>
<li>Primera expresión: Debe comenzar con la cadena 'x=' e indica el primer valor para la variable <var>x</var>.</li>
<li>Segunda expresión:Debe comenzar con la cadena 'x=' e indica el siguiente valor para la variable <var>x</var>.</li>
<li>Tercera expresión: Contiene la expresión de finalización del ciclo. Si es distinto que cero (indicando verdadero) el ciclo termina, en caso contrario, continúa.</li>
<li>Cuarta expresión: Contiene la expresión a factorizar.</li>
<li>Quinta expresión (opcional): Si esta expresión no vale cero (indicando verdadero), se muestra o factoriza la cuarta expresión, y si es cero (indicando falso), se ignora la cuarta expresión.
</ul>
<p>Excepto la primera expresión, las demás expresiones deben incluir la variable <var>x</var> y/o el contador <var>c</var>.</p>
<p>Si la expresión de finalización es falsa después de procesar 1000 números, aparecerá el botón Continuar. Apretando este botón hará que el programa procese los siguientes 1000 números, y así sucesivamente.
<p>Ejemplo 1: Hallar los factores de los primeros 100 números de la forma primo menos 1.
La línea a escribir es: <code>x=3;x=n(x);c<=100;x-1</code>.</p>
<p>Ejemplo 2: Hallar los números de Smith meores que 10000. Un número de Smith, de acuerdo a Wikipedia, es un número compuesto tal que, en una base dada (por defecto en base 10), la suma de sus dígitos es igual a la suma de los dígitos de su factorización en números primos.
La línea a escribir es: <code>x=1;x=x+1;x<10000;x;sumdigits(x, 10)==sumdigits(concatfact(2,x),10) and not isprime(x)</code>
<h2>Código fuente</h2>
<p>Puedes bajar el código fuente de esta aplicación y del viejo applet de factorización desde <a href="https://github.com/alpertron/calculators">GitHub</a>. El código fuente está escrito en lenguaje C, por lo que es necesario <a href="https://kripken.github.io/emscripten-site/docs/getting_started/downloads.html">Emscripten</a> para generar Javascript.</p>
<p>Escrito por Dario Alpern. Actualizado el 22 de mayo de 2018.</p>
</div>
<div id="helphelp"></div>
<div id="result" aria-live="polite"></div>
<div id="status"></div>
<form id="cont" class="pad">
<input type="button" id="continue" value="Continuar" />
</form>
<div id="footer">
<p>Si encuentra algún error o tiene algún comentario, por favor llene el <a href="FORMULAR.HTM?Comentario+de+calculadora+de+factorizacion+de+enteros">formulario</a>.</p>
</div>
</article>
</main>
<div id="modal-more" class="modal" role="dialog" aria-labelledby="moreopt">
<div class="modal-content">
<div class="modal-header"><span id="close-more" aria-label="close" class="atright">×</span><p id="moreopt">Más opciones</p></div>
<div class="modal-body">
<div class="applet">
<p><label for="curve">Nuevo número de curva o factor:</label></p><input type="number" id="curve" value="" class="input" min="0" step="1"/>
<input type="button" id="ncurve" value="Nueva curva" />
<input type="button" id="nfactor" value="Nuevo factor" />
</div>
</div></div></div>
<div id="modal-config" class="modal" role="dialog" aria-labelledby="conf">
<div class="modal-content">
<div class="modal-header"><span id="close-config" aria-label="close" class="atright">×</span><p id="conf">Configuración</p></div>
<div class="modal-body">
<div class="applet">
<fieldset>
<legend>Parámetros de configuración</legend>
<div id="configleft">
<p><label for="digits">Dígitos por grupo</label> <input type="number" id="digits" value="6" min="0" max="10000" step="1"/></p>
<p><input type="checkbox" id="verbose"><label for="verbose">Información</label></p>
</div>
<div id="configright">
<p><input type="checkbox" id="pretty"><label for="pretty">Impresión bonita</label></p>
<p><input type="checkbox" id="hex"><label for="hex">Salida hexadecimal</label></p>
<p><input type="checkbox" id="cunnin"><label for="cunnin">Usar tablas de Cunningham en el servidor</label></p>
</div>
</fieldset>
<p><input type="button" id="save-config" value="Save" /><input type="button" id="cancel-config" value="Cancel" /></p>
</div>
</div></div></div>
<aside id="wizard">
<h1>Asistente de factorización</h1>
<form class="applet">
<fieldset id="output" class="atright">
<legend>Salida</legend>
<input type="radio" name="output" id="decW"><label for="decW"><span class="und">D</span>ecimal</label><br>
<input type="radio" name="output" id="hexW"><label for="hexW"><span class="und">H</span>exadecimal</label><br>
</fieldset>
<fieldset id="mode">
<legend>Modo asistente</legend>
<input type="radio" name="mode" id="oneexpr"><label for="oneexpr"><span class="und">P</span>rocesar una expresión</label><br>
<input type="radio" name="mode" id="loop"><label for="loop"><span class="und">P</span>rocesar varias expresiones en un ciclo</label><br>
</fieldset>
<label for="wzdinput" id="wzddesc"> </label>
<br class="newline"/>
<input type="text" id="wzdinput" value="" placeholder="Número o expresión numérica" class="input"/>
<br class="newline"/>
<p id="wzdexam"> </p>
<input type="button" id="next" value="Siguiente" />
<input type="button" id="cancel" value="Cancelar" />
</form>
<h2>Expresiones</h2>
<p>Puedes ingresar expresiones que usen los siguientes operadores y paréntesis:</p>
<p>
<ul>
<li> + para suma
<li> - para resta
<li> * para multiplicación
<li> / para división entera
<li> % para el resto de la división entera
<li> ^ o ** para exponenciación (el exponente debe ser mayor o igual que cero).
<li> <strong><</strong>, <strong>==</strong>, <strong>></strong>; <strong><=</strong>, <strong>>=</strong>, != para comparaciones. Los operadores devuelven cero si es falso y -1 si es verdadero.
<li> <strong>AND</strong>, <strong>OR</strong>, <strong>XOR</strong>, <strong>NOT</strong> para lógica binaria.
<li> <strong>SHL</strong>: Desplazar a la izquierda la cantidad de bits indicada en el operando derecho.
<li> <strong>SHR</strong>: Desplazar a la derecha la cantidad de bits indicada en el operando derecho.
<li> <strong>n!</strong>: factorial (<var>n</var> debe ser mayor o igual que cero).
<li> <strong>p#</strong>: primorial (producto de todos los primos menores o iguales a <var>p</var>).
<li> <strong>B(n)</strong>: Número probablemente primo anterior a <var>n</var></li>
<li> <strong>F(n)</strong>: Número de Fibonacci F<sub>n</sub>
<li> <strong>L(n)</strong>: Número de Lucas L<sub>n</sub> = F<sub><var>n</var>-1</sub> + F<sub><var>n</var>+1</sub>
<li> <strong>N(n)</strong>: Número probablemente primo posterior a <var>n</var></li>
<li> <strong>P(n)</strong>: particiones irrestrictas (cantidad de descomposiciones de <var>n</var> en sumas de números enteros sin tener en cuenta el orden).
<li> <strong>Gcd(m,n)</strong>: Máximo común divisor de estos dos números enteros.
<li> <strong>Modinv(m,n)</strong>: inverso de <var>m</var> modulo <var>n</var>, sólo válido cuando gcd(m,n)=1.
<li> <strong>Modpow(m,n,r)</strong>: halla <var>m</var><sup><var>n</var></sup> módulo <var>r</var>.
<li> <strong>Totient(n)</strong>: cantidad de enteros positivos menores que <var>n</var> coprimos con <var>n</var>.
<li> <strong>IsPrime(n)</strong>: returna cero si <var>n</var> no es un primo probable y -1 si lo es.
<li> <strong>NumDivs(n)</strong>: cantidad de divisores positivos de <var>n</var> primos o compuestos.
<li> <strong>SumDivs(n)</strong>: suma de divisores positivos de <var>n</var> primos o compuestos.
<li> <strong>NumDigits(n,r)</strong>: cantidad de dígitos de <var>n</var> en base <var>r</var>.
<li> <strong>SumDigits(n,r)</strong>: suma de dígitos de <var>n</var> en base <var>r</var>.
<li> <strong>RevDigits(n,r)</strong>: halla el valor que se obtiene escribiendo para atrás los dígitos de <var>n</var> en base <var>r</var>.
<li> <strong>ConcatFact(m,n)</strong>: concatena los factores primos de <var>n</var> de acuerdo al modo expresado en <var>m</var> según lo indicado en la siguiente tabla:
<table>
<caption>Modos de la función ConcatFact</caption>
<tr><th scope="col">Modo</th><th scope="col">Orden de los factores</th><th scope="col">Factores repetidos</th></tr>
<tr><td>0</td><td>Creciente</td><td>No</td></tr>
<tr><td>1</td><td>Decreciente</td><td>No</td></tr>
<tr><td>2</td><td>Creciente</td><td>Sí</td></tr>
<tr><td>3</td><td>Decreciente</td><td>Sí</td></tr>
</table>
</li>
<li id="C">Variable <var>C</var>: cantidad de expresiones procesadas.</li>
<li id="X">Variable <var>X</var>: variable que cambia en cada iteración del ciclo.</li>
</ul>
<p>Puedes usar el prefijo <em>0x</em> para números hexadecimales, por ejemplo 0x38 es igual a 56.</p>
</aside>
<script async>
<!--
(function(q){function t(){a("next").value=d&1?"Hecho":"Done";a("wzddesc").innerHTML=d&1?"Paso 1 de 1: Expresi\u00f3n a factorizar":"Step 1 of 1: Expression to factor";a("wzdexam").innerHTML=" ";g="";k=9}function a(a){return document.getElementById(a)}function u(c,b){a("eval").style.display=c;a("factor").style.display=c;a("config").style.display=c;a("openwizard").style.display=c;a("stop").style.display=b;a("more").style.display=b}function l(c){a("modal-more").style.display="none";m.terminate();
m=0;n(c)}function p(c){m||(v?w||(w=new Blob([new Uint8Array(x)])):w||(w=new Blob(Array.prototype.map.call(document.querySelectorAll("script[type='text/js-worker']"),function(a){return a.textContent}),{type:"text/javascript"})),m=new Worker(window.URL.createObjectURL(w)),m.onmessage=function(b){var c=b.data.substring(0,1);"9"==c&&console.log(b.data.substring(1));if("8"==c)b=b.data.substring(1),localStorage.setItem("ecmFactors",b),localStorage.setItem("ecmCurve","");else if("7"==c)b=b.data.substring(1),
localStorage.setItem("ecmCurve",b);else if("4"==c)a("status").innerHTML=b.data.substring(1);else if(a("result").innerHTML=b.data.substring(1),"2"==c||"6"==c)a("status").innerHTML="",u("inline","none"),a("modal-more").style.display="none","6"==c&&(a("cont").style.display="block")});v?m.postMessage(c):m.postMessage([c,x])}function n(c){var b;d=parseInt(a("app").value)+c;b=a("result");var A=a("value").value.replace(/\u2011/g,"-"),h=String.fromCharCode(0),g=a("helphelp");a("cont").style.display="none";
a("help").style.display="none";g.style.display="block";g.innerHTML=d&1?'<p class="pad">Aprieta el bot\u00f3n <strong>Ayuda</strong> para obtener ayuda para esta aplicaci\u00f3n. Apri\u00e9talo de nuevo para retornar a la factorizaci\u00f3n. Los usuarios con teclado pueden presionar CTRL+ENTER para comenzar la factorizaci\u00f3n. Esta es la versi\u00f3n '+(v?"asm.js":"WebAssembly")+".</p>":'<p class="pad">Press the <strong>Help</strong> button to get help about this application. Press it again to return to the factorization. Keyboard users can press CTRL+ENTER to start factorization. This is the '+
(v?"asm.js":"WebAssembly")+" version.</p>";b.style.display="block";if(""==A)b.innerHTML=d&1?"<p>Por favor ingrese una expresi\u00f3n.</p>":"<p>Please type an expression.</p>";else if("undefined"===typeof Worker)b.innerHTML=d&1?"<p>Esta calculadora necesita Web Workers. Por favor use otro navegador Web.</p>":"<p>This calculator requires Web Workers. Please use another Web browser.</p>";else{u("none","inline");b.innerHTML=d&1?"<p>Factorizando la expresi\u00f3n...</p>":"<p>Factoring expression...</p>";
-2>c&&(d+=6);b=f+","+d+","+e+A+h+localStorage.getItem("ecmFactors");if(-1==c||-2==c)b+=h+a("curve").value;if(-3==c||-4==c)b+="*"+a("curve").value+"^1(2)";x?p(b+h):y=b+h}}function B(){a("next").value=d&1?"Siguiente":"Next";a("wzddesc").innerHTML=d&1?"Paso 1 de 5: Valor inicial de x":"Step 1 of 5: Initial value of x";a("wzdexam").innerHTML=d&1?"No usar variables <var>x</var> o <var>c</var>. Ejemplo para n\u00fameros de Smith menores que 10000: <code>1</code>":"Do not use variables <var>x</var> or <var>c</var>. Example for Smith numbers less than 10000: <code>1</code>";
k=1}function C(){var c=a("next"),b=a("wzddesc"),e=a("wzdexam"),h=a("wzdinput"),f=a("value");c.disabled=!0;switch(++k){case 2:g+="x="+h.value;a("mode").style.display="none";b.innerHTML=d&1?"Paso 2 de 5: Valor de x para la nueva iteraci\u00f3n":"Step 2 of 5: Value of x for new iteration";e.innerHTML=d&1?"Variables <var>x</var> y/o <var>c</var> requeridas. Ejemplo para n\u00fameros de Smith menores que 10000: <code>x+1</code>":"Variables <var>x</var> and/or <var>c</var> required. Example for Smith numbers less than 10000: <code>x+1</code>";
break;case 3:g+=";x="+h.value;b.innerHTML=d&1?"Paso 3 de 5: Condici\u00f3n para finalizar el ciclo":"Step 3 of 5: End loop condition";e.innerHTML=d&1?"Variables <var>x</var> y/o <var>c</var> requeridas. Ejemplo para n\u00fameros de Smith menores que 10000: <code>x<10000</code>":"Variables <var>x</var> and/or <var>c</var> required. Example for Smith numbers less than 10000: <code>x<10000</code>";break;case 4:g+=";"+h.value;b.innerHTML=d&1?"Paso 4 de 5: Expresi\u00f3n a factorizar":"Step 4 of 5: Expression to factor";
e.innerHTML=d&1?"Variables <var>x</var> y/o <var>c</var> requeridas. Ejemplo para n\u00fameros de Smith menores que 10000: <code>x</code>":"Variables <var>x</var> and/or <var>c</var> required. Example for Smith numbers less than 10000: <code>x</code>";break;case 5:g+=";"+h.value;c.value=d&1?"Hecho":"Done";c.disabled=!1;b.innerHTML=d&1?"Paso 5 de 5: Condici\u00f3n para procesar la expresi\u00f3n":"Step 5 of 5: Process expression condition";e.innerHTML=d&1?"Variables <var>x</var> y/o <var>c</var> requeridas. Ejemplo para n\u00fameros de Smith menores que 10000: <code>sumdigits(x,10) == sumdigits(concatfact(2,x),10) and not isprime(x)</code>":
"Variables <var>x</var> and/or <var>c</var> required. Example for Smith numbers less than 10000: <code>sumdigits(x,10) == sumdigits(concatfact(2,x),10) and not isprime(x)</code>";break;case 6:""!=h.value&&(g+=";"+h.value);f.value=g;k=0;a("hex").checked=a("hexW").checked;z();a("main").style.display="block";a("wizard").style.display="none";f.focus();break;default:k=0,f.value=h.value,a("hex").checked=a("hexW").checked,z(),a("main").style.display="block",a("wizard").style.display="none",f.focus()}k&&
(h.value="",h.focus())}function z(){e="1"+(a("verbose").checked?"1":"0")+(a("pretty").checked?"1":"0")+(a("cunnin").checked?"1":"0")+(a("hex").checked?"1":"0");f=a("digits").value;localStorage.setItem("ecmConfig",f+","+e)}var k=0,g,m=0,x=0,d,w,f,e,y,v="undefined"===typeof WebAssembly,r=new XMLHttpRequest;r.open("GET",v?"ecmW0057.js":"ecm0057.wasm",!0);r.responseType="arraybuffer";r.onreadystatechange=function(a){4==r.readyState&&200==r.status&&(x=r.response,y&&p(y))};r.send(null);addEventListener("load",
function(){var c;d=parseInt(a("app").value);a("value").wrap="off";a("eval").onclick=function(){localStorage.setItem("ecmFactors","");n(0)};a("factor").onclick=function(){localStorage.setItem("ecmFactors","");n(2)};a("more").onclick=function(){a("modal-more").style.display="block"};a("config").onclick=function(){a("digits").value=f;a("verbose").checked="1"==e.substr(1,1);a("pretty").checked="1"==e.substr(2,1);a("cunnin").checked="1"==e.substr(3,1);a("hex").checked="1"==e.substr(4,1);a("modal-config").style.display=
"block"};a("openwizard").onclick=function(){a("main").style.display="none";a("wizard").style.display="block";a("mode").style.display="block";a("oneexpr").checked=!0;a("next").disabled=!0;a("wzdinput").value="";a("wzdinput").focus();a("hexW").checked="1"==e.substr(4,1);a("decW").checked="1"!=e.substr(4,1);t()};a("wzdinput").onkeydown=function(b){if(10==b.keyCode||13==b.keyCode)b.preventDefault(),0==a("next").disabled&&C();b.altKey&&(80==b.keyCode?(b.preventDefault(),a("oneexpr").checked?(a("oneexpr").checked=
!1,a("loop").checked=!0,B()):(a("oneexpr").checked=!0,a("loop").checked=!1,t())):68==b.keyCode?(b.preventDefault(),a("decW").checked=!0,a("hexW").checked=!1):72==b.keyCode&&(b.preventDefault(),a("decW").checked=!1,a("hexW").checked=!0));return!0};a("oneexpr").onclick=function(){t()};a("loop").onclick=function(){B()};a("next").onclick=function(){C()};a("wzdinput").oninput=function(){var b=a("wzdinput").value,c=a("next");""!=b?1==k||9==k||0<=b.lastIndexOf("x")||0<=b.lastIndexOf("c")||0<=b.lastIndexOf("X")||
0<=b.lastIndexOf("C")?c.disabled=!1:c.disabled=!0:c.disabled=5==k?!1:!0};a("cancel").onclick=function(){a("main").style.display="block";a("wizard").style.display="none"};a("close-config").onclick=function(){a("modal-config").style.display="none"};a("cancel-config").onclick=function(){a("modal-config").style.display="none"};a("save-config").onclick=function(){oldconfig=e;z();a("modal-config").style.display="none"};a("close-more").onclick=function(){a("modal-more").style.display="none"};a("ncurve").onclick=
function(){l(-2)};a("nfactor").onclick=function(){l(-4)};a("curve").onkeypress=function(a){return 8==a.charCode||0==a.charCode?null:48<=a.charCode&&57>=a.charCode};a("stop").onclick=function(){m.terminate();m=0;u("inline","none");a("result").innerHTML=d&1?"<p>C\u00e1lculo detenido por el usuario.</p>":"<p>Calculation stopped by user</p>";a("status").innerHTML=""};a("value").onkeydown=function(a){10!=a.keyCode&&13!=a.keyCode||!a.ctrlKey||(a.preventDefault(),localStorage.setItem("ecmFactors",""),n(2));
return!0};a("helpbtn").onclick=function(){var b=a("help").style,c=a("helphelp").style,d=a("result"),e=d.style;"block"==b.display&&""!=d.innerHTML?(b.display="none",c.display=e.display="block"):(b.display="block",c.display=e.display="none")};a("continue").onclick=function(){a("cont").style.display="none";p("C")};window.onclick=function(b){var c=a("modal");b.target==c&&(c.style.display="none")};f=localStorage.getItem("ecmConfig");if(null==f||""==f)f=6,e="00100",localStorage.setItem("ecmConfig",f+","+
e);else if(c=f.indexOf(","),0>c)f=6,e="00100",localStorage.setItem("ecmConfig",f+","+e);else{for(e=f.substr(c+1);5>e.length;)e+="0";f=f.substr(0,c)}if(c=localStorage.getItem("ecmFactors"))a("value").value=c.slice(0,c.indexOf("=")),a("curve").value=localStorage.getItem("ecmCurve"),n(-2),a("curve").value="";"serviceWorker"in navigator&&navigator.serviceWorker.register("calcSW.js").then(function(){},function(){})})})(this);
addEventListener("load",function(){(function(q,t,a,u,l,p,n){q.GoogleAnalyticsObject=l;q[l]=q[l]||function(){(q[l].q=q[l].q||[]).push(arguments)};q[l].l=1*new Date;p=t.createElement(a);n=t.getElementsByTagName(a)[0];p.async=1;p.src=u;n.parentNode.insertBefore(p,n)})(window,document,"script","https://www.google-analytics.com/analytics.js","ga");ga("create","UA-4438475-1","auto");ga("send","pageview")});
//-->
</script>
<script type="text/js-worker">
var exports,HEAPU8,wasmLoaded,env={databack:function(b){self.postMessage(PtrToString(b))},tenths:function(){return Math.floor((new Date).getTime()/100)},getCunn:function(b){var a=new XMLHttpRequest;a.open("GET","https://www.alpertron.com.ar/"+PtrToString(b),!1);a.send(null);200==a.status&&ConvertToString(exports.getFactorsAsciiPtr(),a.responseText)}},info={env:env};
self.onmessage=function(b){wasmLoaded?(ConvertToString(exports.getInputStringPtr(),b.data[0]),exports.doWork()):WebAssembly.instantiate(b.data[1],info).then(function(a){wasmLoaded=1;exports=a.instance.exports;HEAPU8=new Uint8Array(exports.memory.buffer);ConvertToString(exports.getInputStringPtr(),b.data[0]);exports.doWork()})};
function PtrToString(b){var a=-1,c=0,e="",d="";do{for(c=0;1024>c;c++){a=HEAPU8[b++>>0];if(0==a)break;128<=a&&(a=(a-192<<6)+HEAPU8[b++>>0]-128);e+=String.fromCharCode(a)}d+=e;e=""}while(0!=a);return d+e}function ConvertToString(b,a){var c=b,e=a.length,d,f;for(d=0;d<e;d++)f=a.charCodeAt(d),128>f?HEAPU8[c++]=f:(HEAPU8[c++]=(f>>6)+192,HEAPU8[c++]=(f&63)+128);HEAPU8[c]=0};
</script>
</body>
</html>