Construye un reloj ASCII Fibonacci

16

Alguien construyó un reloj realmente elegante usando números de Fibonacci, que se ve muy bien pero es bastante inutilizable. Justo como nos gusta! Vamos a recrear esto.

El reloj se compone de 5 secciones correspondientes a los primeros cinco números de Fibonacci, comenzando desde 1 (es decir, 1, 1, 2, 3, 5):

ccbeeeee
ccaeeeee
dddeeeee
dddeeeee
dddeeeee

El reloj es capaz de mostrar el tiempo de 12 horas en incrementos de 5 minutos. Así es como funciona eso. Considere el tiempo 7:20. La hora 7 se puede descomponer en los números de Fibonacci dados como

7 = 2 + 5

También hay 4 unidades de cinco minutos. Los 4 se pueden descomponer como

4 = 2 + 1 + 1

Ahora las horas se muestran en rojo, los minutos se dividen en verde, y si se usa un número para horas y minutos, se muestra en azul. Si no se usa un número, permanece blanco. Entonces lo anterior se mostraría como:

BBGRRRRR
BBGRRRRR
WWWRRRRR
WWWRRRRR
WWWRRRRR

Pero espera hay mas. Las descomposiciones anteriores no son las únicas posibilidades. También se puede escribir 7 = 3 + 2 + 1 + 1y 4 = 3 + 1, lo que daría uno de

GGRWWWWW          GGBWWWWW
GGBWWWWW          GGRWWWWW
BBBWWWWW    or    BBBWWWWW
BBBWWWWW          BBBWWWWW
BBBWWWWW          BBBWWWWW

dependiendo de cual 1 se elija. Por supuesto, también hay otras combinaciones. El reloj elige entre todas las descomposiciones válidas al azar.

Como dije ... esto podría no ganar un premio de usabilidad, pero seguro que es agradable de ver.

El reto

Su tarea es implementar dicho reloj. Su programa (o función) debe imprimir una representación ASCII de la hora actual (redondeada al último múltiplo de 5 minutos) como se describe anteriormente en STDOUT o la alternativa más cercana. Puede elegir leer la hora en cualquier formato común como entrada u obtenerla con funciones de biblioteca estándar. No debe suponer que el tiempo actual / dado es divisible por 5 minutos.

Su solución debe elegir al azar de todas las representaciones posibles de la hora actual. Es decir, cada representación debe imprimirse con una probabilidad distinta de cero.

La medianoche y el mediodía deben tratarse como 0:00(en lugar de 12:00).

Opcionalmente, puede imprimir un único carácter de nueva línea al final.

Puede usar cuatro caracteres ASCII imprimibles distintos (códigos de caracteres 0x20 a 0xFE) en lugar de RGBW. Indique su elección en su respuesta y úsela constantemente.

Este es el código de golf, por lo que gana la respuesta más corta (en bytes).

Martin Ender
fuente
(a) ¿podemos suponer que la entrada sigue la regla 12 = 0? (b) ¿la salida tiene que estar en esa orientación, o podemos rotarla?
sirpercival
@sirpercival a) Sí, creo que eso cuenta como "cualquier formato común". b) Tiene que ser la orientación dada en el desafío.
Martin Ender
2
Este desafío generó el verbo desafortunado "fibclocking".
Alex A.
1
¿Cuál es la motivación para que la medianoche / mediodía sea 0 en lugar de 12? Los primeros cinco números en la secuencia suman exactamente 12.
Brian J
@BrianJ Solo quería elegir uno para hacerlo consistente y elegí cero. En realidad, no debería afectar demasiado las soluciones. Pensé que esta elección simplificaría las cosas porque los minutos también tienen un rango de 0..11.
Martin Ender

Respuestas:

6

CJam, 61 bytes

l~5/]:A{;L[TT][XXYZ5]{4mr_2bW%Mf*@.+\Ps=M*aM*@+W%z\}fMA=!}gN*

Toma dos enteros separados por espacios a través de STDIN y los usa en 3.14lugar de WRGBrespectivamente. Pruébalo en línea .

Aquí está la RGBWversión "sana" para algunos bytes adicionales:

l~5/]:A{;L[TT][XXYZ5]{4mr_2bW%Mf*@.+\"WRGB"=M*aM*@+W%z\}fMA=!}gN*

Explicación

El algoritmo es el mismo que mi respuesta de Python : muestreo de rechazo generando relojes hasta que obtengamos uno correcto.

l~5/]:A            Read input and make array [<hours> <minutes>/5]
{...}g             Do...

  ;                  Pop the only element on the stack
  L                  Push empty array, which will become our clock
  [TT]               Push [0 0] for [h m], to keep track of our sample
  [XXYZ5]{...}fI     For I in [1 1 2 3 5]...
    4mr                Push random number from [0 1 2 3]
    _2bW%              Copy and get reversed base 2 rep for one of [0] [1] [0 1] [1 1]
    If*                Multiply bit(s) by I
    @.+                Add element-wise to [h m] array
    \Ps=               Index the random number into stringified pi for one of "3.14"
    I*aI*              Make into I by I square
    @+W%z\             Add above clock and rotate clockwise

  A=!              ... while the resulting clock is incorrect
N*                 Riffle clock with newlines
Sp3000
fuente
9

Python 2, 194182 bytes

from random import*
h=m=H,M=input()
while[h,m]!=[H,M/5]:
 h=m=0;s=[]
 for n in 1,1,2,3,5:c=randint(0,3);h+=c%2*n;m+=c/2*n;s=zip(*(["WRGB"[c]*n]*n+s)[::-1])
for L in s:print"".join(L)

El algoritmo es solo un muestreo de rechazo, por lo que sigue generando relojes hasta que obtiene uno correcto. El reloj se construye comenzando sin nada, luego haciendo "agregar un cuadrado arriba y girar en sentido horario" 5 veces.

Toma dos enteros separados por comas a través de STDIN.

>>> ================================ RESTART ================================
>>> 
7,17
BBBWWWWW
BBRWWWWW
RRRWWWWW
RRRWWWWW
RRRWWWWW
>>> ================================ RESTART ================================
>>> 
7,17
GGBRRRRR
GGRRRRRR
WWWRRRRR
WWWRRRRR
WWWRRRRR
Sp3000
fuente
4

Python 2, 421 bytes

Ugh, estoy seguro de que se puede jugar más al golf.

from itertools import*
from random import*
f,r=[1,1,2,3,5],range
c={_:[x for x in chain(*[combinations(f,i)for i in r(6)])if sum(x)==_]for _ in r(13)}
k=[[2,1,4],[2,0,4]]+[[3,4]]*3
def b(h,m):
 o=['W']*5;m/=5;h,m=choice(c[h]),choice(c[m])
 l=dict(zip(zip('WWR',[m,h,m]),'GRB'))
 for x in h,m:
    d={1:[0,1],2:[2],3:[3],5:[4]}
    for _ in x:j=d[_].pop();o[j]=l[o[j],x]
 print'\n'.join([''.join(o[i]*f[i]for i in _)for _ in k])

Caso de prueba:

>>> b(7,20)
WWBRRRRR
WWRRRRRR
GGGRRRRR
GGGRRRRR
GGGRRRRR
>>> b(7,20)
RRBWWWWW
RRRWWWWW
BBBWWWWW
BBBWWWWW
BBBWWWWW
Sirpercival
fuente
@Optimizer ahora sólo tiene que conseguir IDL en el sistema embellecer google para que pueda obtener IDL resaltado de sintaxis XD
sirpercival
3

Rubí, 286 bytes

Puede ser golfable, pero lo intentará en otro momento.

z=[]
13.times{z<<[]}
(0..5).to_a.permutation{|p|l=p.take_while{|n|n<5};z[l.map{|n|[1,1,2,3,5][n]}.reduce(0,:+)]<<l}
t=Time.now
h,m=z[t.hour%12].sample,z[t.min/5].sample
5.times{|y|puts (0..7).map{|x|a=(x>2?4:y>1?3:x<2?2:y<1?1:0);q=m.include?(a);h.include?(a)?q ? ?B:?R: q ??G:?W}*""}

Explicación:

z=[]
13.times{z<<[]}                 # Initialize the array where we will have all the combinations
(0..5).to_a.permutation{|p|     # Get all the permutations of the 5 positions plus a 5, which will be used as a separator
    l=p.take_while{|n|n<5};     # Get the permutation until the separator. This way we get all the possible sum combinations of the other five numbers
    z[l.map{|n|[1,1,2,3,5][n]}.reduce(0,:+)]<<l}     # Add the permutation to the list with id=the permutation's sum

t=Time.now # Get current time
h,m=z[t.hour%12].sample,z[t.min/5].sample     # For the hour and the minute, get a random permutation that has the expected sum
5.times{|y|                 # For each row
    $><<(0..7).map{|x|      # For each column
        a=(x>2?4:y>1?3:x<2?2:y<1?1:0);     # Get the panel we are in
        q=m.include?(a);h.include?(a)?q ? ?B:?R: q ??G:?W     # Get the color this panel is painted
    }*""}                   # Join the string and print it
rorlork
fuente
1
Puede reemplazar (0..5).to_acon[*0..5]
addison