Encuentre el período general de una lista de frecuencias

8

Inspirado en http://xkcd.com/1331/

En este cómic xkcd, hay varios gifs que parpadean con diferente frecuencia. Quiero saber cuál sería el período si todo fuera un solo GIF. Dada una lista de números que representan las frecuencias individuales, genera el período del GIF general.

Definicion formal

Entrada:

N
f1
f2
.
.
.
fN

Salida:

P

Donde N es el número de frecuencias, fi es la frecuencia i-ésima y P es el período resultante del GIF total.

Puede elegir usar cualquier carácter de delimitación que desee (en lugar de \ n), y puede excluir la N si lo desea, y se deducirá por la cantidad de delimitadores.

Algunos detalles

Las frecuencias son la representación de coma flotante de precisión doble más cercana de los números proporcionados como entrada.

El período de salida es un entero sin signo de 64 bits, redondeado (hasta 0.5) al entero más cercano. Cualquier entrada que produzca un período mayor de 2 ^ 64-1 se considera comportamiento indefinido.

Del mismo modo, cualquier entrada <= 0 se considera comportamiento indefinido.

Condición de victoria

¡Golf de código para que el código más corto gane!

Cruncher
fuente
Posible spoiler ... ¿no sería esto solo el producto de las frecuencias dadas?
danmcardle
@crazedgremlin No, no lo es, pero estás bastante cerca.
Victor Stafusa
@crazedgremlin: si A es 2s y B es 4s, entonces el período resultante sería 4s, no 8s.
Trauma digital
Ah, ya veo, gracias. @Cruncher, ¿qué quieres decir exactamente con "frecuencia"? ¿Repeticiones por segundo o la cantidad de tiempo que lleva una repetición? Asumo lo primero, ya que eso suele ser lo que significa la frecuencia.
danmcardle
Hay al menos 2 métodos para esto: tomar la frecuencia general como el MCD de las frecuencias de entrada e invertirla. O tome las frecuencias de entrada, inviértalas todas para obtener los períodos y tome el LCM como el período general. Tomé el GCD. @DavidCarraher tomó el LCM. Solo necesita hacer frente a los no enteros.
Victor Stafusa

Respuestas:

8

APL, 4

∧/∘÷

es un LCM lógico AND y numérico (con dominio sobre enteros, flotantes, complejos, racionales, cualquier pila de números que sea compatible con la implementación de APL), por lo que ∧/es la reducción por LCM o el cálculo del LCM de una matriz.

Monadic ÷es inversa numérica. Entonces, la composición ∧/∘÷es el MCM de los inversos de los números suministrados.

La otra fórmula, inversa al GCD, sería ÷∘(∨/), donde los paréntesis son necesarios para fijar la precedencia entre y /.

Puedes probarlo en línea en http://tryapl.com/

Ejemplos

      ∧/∘÷ .12 .02 3.9 .15 .99
100
      ∧/∘÷ (16÷5)(2÷3)(2.35)(1÷7)
420
Tobia
fuente
Holy bananas!
Cruncher
3
@Cruncher que sería †))! en APL.
Tobia
Bravo. Creo que tenemos un ganador.
Victor Stafusa
Simplemente asombroso. Felicitaciones a usted.
DavidC
4

Mathematica 43 28

Segundo intento

Mi primer intento no fue correcto, aunque tenía algunos de los ingredientes necesarios (LCM, Rationalize). La solución completa requiere tener en cuenta tanto el numerador como el denominador de cada frecuencia (expresada como una fracción común).

l es la lista de frecuencias

Racionalizar 2.35 lo convierte en la fracción común 235/100.

f@l_:=LCM@@(1/Rationalize@l)

Suponga que todos los GIF se disparan en t = 0.

El siguiente enfoque no requiere que las frecuencias se expresen como "números reales", es decir. como fracciones decimales Pueden ser otro tipo de fracciones. El siguiente ejemplo es un caso donde las fracciones están en quintos, tercios, centésimos y séptimos.

Si dos o más frecuencias son inconmensurables (en cuyo caso al menos una debe ser un número irracional), entonces no hay solución. En otras palabras, no habrá un punto en el tiempo, t> 0, en el que todos los componentes se disparen al mismo tiempo.

Ejemplo 1

f[{50, 10}]

1/10


Ejemplo 2

f[{16/5, 2/3, 2.35, 1/7}]

420

Si multiplicamos el período general mínimo por cada una de las frecuencias, encontramos un número entero de ciclos en cada caso:

420*{16/5, 2/3, 2.35, 1/7}

{1344, 280, 987., 60}

(1344 saltos de 16/5 unidades) aterriza en 420. (280 saltos de 2/3 unidades) aterriza en 420. (987 saltos de 2.35 unidades) aterriza en 420. (60 saltos de 7 unidades) aterriza en 420.

DavidC
fuente
La herramienta adecuada para el trabajo correcto.
Victor Stafusa
No estoy seguro de entenderlo. Si las entradas son frecuencias, la f [{50,10}] significaría el ciclo común de señal que se dispara 50 veces por segundo y un ciclo que archiva 10 veces por segundo. La respuesta correcta sería 1/10 de segundo, pero f [{50, 10}] devuelve 1. En realidad, muchas cosas al azar devuelven una respuesta de 1. f [{345345, h}] devuelve 1.
Michael Stern
Mi enfoque original era incompleto (y por lo tanto incorrecto). Lo he modificado de tal manera que aborde su observación. La solución actual también tiene sentido geométricamente (usando segmentos de línea contra la línea real).
DavidC
Iba a publicar una solución así, pero me ganaste. Muy agradable.
Jonathan Van Matre
@ Jonathan. Sí, su enfoque fue casi idéntico al mío. Pero no veo la necesidad de Round. ¿Racionalizar y LCM no garantizarán que los resultados sean enteros?
DavidC
2

Javascript: 191 caracteres

El formato de entrada que elegí (dentro de las reglas) son los números de frecuencia separados por comas. No se permiten espacios ni líneas nuevas. No se debe dar la N inicial. Cada número debe ser solo una serie de al menos un [0-9] dígitos con un punto opcional en algún lugar dentro. Si la entrada tiene un formato incorrecto, el comportamiento no está definido.

Cómo funciona:

El período de algunos números de frecuencia enteros es el MCD de estos números. Si los números dados no son enteros, los multiplica sucesivamente por 10 hasta obtener todo como un número entero (esto explota el hecho de que los números no enteros se dan en la base 10). Después de calcular el MCD, divide el resultado por la potencia de diez utilizada para multiplicar los números de entrada y, por lo tanto, obtiene la frecuencia general. Al invertir esto, obtenemos el período.
Nota: Estoy bastante seguro de que ahora que di esta respuesta, alguien codificará lo mismo en APL o J y lo superará. :(

El código:

d=1,s=prompt().split(",");for(a in s){s[a]=parseFloat(s[a]);while(s[a]*d%1>0)d*=10}g=s[0]*d;for(a in s){u=g;v=s[a]*=d;p=2;q=1;while(u>=p&v>=p)if(u%p|v%p)p++;else{u/=p;v/=p;q*=p}g=q}alert(d/g)

Probándolo:

Input: 50,10
Output: 0.1
Interpretation: One GIF blinks 10 times per second (period = 0.1s) and the other 50 times (period = 0.02s). So a combined GIF would repeat itself in 0.1 seconds.

Input: 2.7,3.4
Output: 10
Interpretation: One blinking at 2.7 times per second will blink 27 times in 10 seconds. One blinking 3.4 times per second will blink 34 times in 10 seconds. So, 10 seconds is a period, and since GCD(27,34)=1, it is the smallest.

Input: 4.8,7.2
Output: 0.4166666666666667
Interpretation: One blinking at 4.8 times per second and the other at 7.2 times per second, gives a frequency of 2.4 times per second, which is a period 0.41666... seconds.

Input: 0.6,12,7.9,4.33
Output: 100
Interpretation: Similar to second case. 60, 1200, 790 and 433 times each 100 seconds. The GCD of these numbers is 1.

Input: 400,200,25,350
Output: 0.04
Interpretation: The slowest is the 25 times per second, which is the overall frequency. 25 times per second is a period of 0.04 seconds.

Input: 440,200,35,360
Output: 0.2
Interpretation: In 0.2 seconds, we have 88, 40, 7 and 72 blinks.
Victor Stafusa
fuente
GCD? Ese es el mayor divisor común, por lo que siempre sería más pequeño que las frecuencias. Creo que te refieres a LCM (mínimo común múltiplo).
Justin
@Quincunx No, es el GCD. El período total es el MCM de los períodos individuales, no las frecuencias individuales.
Victor Stafusa
1
Aquí está el APL:(⊃x÷z)×∨/z←{⍵×10}⍣{⍵≡⌈⍵}x←⎕
Marinus
¿Ejecutarías un caso de prueba con números racionales o "números reales" (en el sentido informático del término)? No creo que un enfoque basado en GCD funcione.
DavidC
@DavidCarraher Cambié la frecuencia con el punto, pero ahora ya lo solucioné. Acabo de cambiar el g/da d/g. Agregaré algunos casos de prueba.
Victor Stafusa