Construa um relógio ASCII Fibonacci

16

Alguém construiu um relógio realmente sofisticado usando números de Fibonacci, que parece muito bom, mas é bastante inutilizável. Apenas a maneira que nós gostamos! Vamos recriar isso.

O relógio é composto de 5 seções correspondentes aos cinco primeiros números de Fibonacci, começando de 1 (ou seja, 1, 1, 2, 3, 5):

ccbeeeee
ccaeeeee
dddeeeee
dddeeeee
dddeeeee

O relógio é capaz de exibir o tempo de 12 horas em incrementos de 5 minutos. Aqui está como isso funciona. Considere o tempo 7:20. A hora 7 pode ser decomposta nos números de Fibonacci dados como

7 = 2 + 5

Existem também 4 unidades de cinco minutos. Os 4 podem ser decompostos como

4 = 2 + 1 + 1

Agora, as horas são mostradas em vermelho, os minutos são divididos em verde e, se um número é usado por horas e minutos, é mostrado em azul. Se um número não for usado, ele permanecerá branco. Portanto, o acima seria mostrado como:

BBGRRRRR
BBGRRRRR
WWWRRRRR
WWWRRRRR
WWWRRRRR

Mas espere, tem mais. As decomposições acima não são as únicas possibilidades. Pode-se também escrever 7 = 3 + 2 + 1 + 1e 4 = 3 + 1, o que daria uma das

GGRWWWWW          GGBWWWWW
GGBWWWWW          GGRWWWWW
BBBWWWWW    or    BBBWWWWW
BBBWWWWW          BBBWWWWW
BBBWWWWW          BBBWWWWW

dependendo de qual 1 é escolhido. Claro que existem outras combinações também. O relógio escolhe todas as decomposições válidas aleatoriamente.

Como eu disse ... isso pode não ganhar um prêmio de usabilidade, mas com certeza é bom de se ver.

O desafio

Sua tarefa é implementar esse relógio. Seu programa (ou função) deve imprimir uma representação ASCII do horário atual (arredondado para o último múltiplo de 5 minutos) conforme descrito acima para STDOUT ou a alternativa mais próxima. Você pode escolher ler a hora em qualquer formato comum como entrada ou obtê-la com as funções padrão da biblioteca. Você não deve assumir que o tempo atual / determinado é divisível por 5 minutos.

Sua solução deve escolher aleatoriamente entre todas as representações possíveis da hora atual. Ou seja, cada representação deve ser impressa com probabilidade diferente de zero.

Meia-noite e meio-dia devem ser tratados como 0:00(em oposição a12:00 ).

Opcionalmente, você pode imprimir um único caractere de nova linha à direita.

Você pode usar quaisquer quatro caracteres ASCII imprimíveis distintos (códigos de caracteres 0x20 a 0xFE) no lugar de RGBW . Por favor, indique sua escolha na sua resposta e use-a de forma consistente.

Isso é código de golfe, então a resposta mais curta (em bytes) vence.

Martin Ender
fonte
(a) podemos assumir que a entrada segue a regra 12 = 0? (b) a saída precisa estar nessa orientação ou podemos girá-la?
Sirpercival 8/15
@sirpercival a) Sim, acho que isso conta como "qualquer formato comum". b) Tem que ser a orientação dada no desafio.
Martin Ender
2
Esse desafio gerou o infeliz verbo "fibclocking".
Alex A.
11
Qual é a motivação para meia-noite / meio-dia sendo 0 em vez de 12? Os cinco primeiros números da sequência somam exatamente 12.
Brian J
@BrianJ Eu só queria escolher um para torná-lo consistente e escolher zero. Realmente não deve afetar muito as soluções. Imaginei que essa escolha tornaria as coisas mais simples porque os minutos também têm um intervalo de 0 a 11.
Martin Ender

Respostas:

6

CJam, 61 bytes

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

Toma dois números inteiros separados por espaço via STDIN e usa em 3.14vez de WRGBrespectivamente. Experimente online .

Aqui está a RGBWversão "sã" para alguns bytes extras:

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

Explicação

O algoritmo é o mesmo que minha resposta em Python - amostragem por rejeição, gerando relógios até obtermos o que está correto.

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
fonte
9

Python 2, 194 182 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)

O algoritmo é apenas uma amostra de rejeição, por isso continua gerando relógios até encontrar o que é certo. O relógio é construído começando com nada e, em seguida, "adicione um quadrado acima e gire no sentido horário" 5 vezes.

Toma dois inteiros separados por vírgula via STDIN.

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

Python 2, 421 bytes

Ugh, eu tenho certeza que isso pode ser jogado mais.

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 teste:

>>> b(7,20)
WWBRRRRR
WWRRRRRR
GGGRRRRR
GGGRRRRR
GGGRRRRR
>>> b(7,20)
RRBWWWWW
RRRWWWWW
BBBWWWWW
BBBWWWWW
BBBWWWWW
sirpercival
fonte
@Optimizer agora só temos de obter IDL no sistema embelezar google para que eu possa obter IDL destaque de sintaxe XD
sirpercival
3

Ruby, 286 bytes

Pode ser jogável, mas tentará outra hora.

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}*""}

Explicação:

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
fonte
11
Você pode substituir (0..5).to_apor[*0..5]
addison