Costruisci un orologio ASCII Fibonacci


16

Qualcuno ha costruito un orologio davvero elegante usando i numeri di Fibonacci, che sembra davvero bello ma è piuttosto inutilizzabile. Proprio come piace a noi! Ricreamolo.

L'orologio è composto da 5 sezioni corrispondenti ai primi cinque numeri di Fibonacci, a partire da 1 (ovvero 1, 1, 2, 3, 5):

ccbeeeee
ccaeeeee
dddeeeee
dddeeeee
dddeeeee

L'orologio è in grado di visualizzare l'ora di 12 ore con incrementi di 5 minuti. Ecco come funziona. Considera il tempo 7:20. L'ora 7 può essere scomposta nei numeri di Fibonacci indicati come

7 = 2 + 5

Ci sono anche 4 unità di cinque minuti. I 4 possono essere decomposti come

4 = 2 + 1 + 1

Ora le ore sono visualizzate in rosso, i blocchi di minuti in verde e se un numero viene utilizzato sia per le ore che per i minuti, viene mostrato in blu. Se un numero non viene utilizzato affatto, rimane bianco. Quindi quanto sopra sarebbe mostrato come:

BBGRRRRR
BBGRRRRR
WWWRRRRR
WWWRRRRR
WWWRRRRR

Ma aspetta, c'è di più. Le suddette decomposizioni non sono le uniche possibilità. Si può anche scrivere 7 = 3 + 2 + 1 + 1e 4 = 3 + 1, il che darebbe uno dei

GGRWWWWW          GGBWWWWW
GGBWWWWW          GGRWWWWW
BBBWWWWW    or    BBBWWWWW
BBBWWWWW          BBBWWWWW
BBBWWWWW          BBBWWWWW

a seconda di quale 1viene scelto. Naturalmente ci sono anche altre combinazioni. L'orologio sceglie casualmente tutte le decomposizioni valide.

Come ho detto ... questo potrebbe non vincere un premio di usabilità, ma è sicuramente bello da vedere.

La sfida

Il tuo compito è implementare un tale orologio. Il programma (o la funzione) dovrebbe stampare una rappresentazione ASCII dell'ora corrente (arrotondata per difetto all'ultimo multiplo di 5 minuti) come descritto sopra su STDOUT o sull'alternativa più vicina. È possibile scegliere di leggere l'ora in qualsiasi formato comune come input o ottenerla con le funzioni di libreria standard. Non si deve presumere che il tempo corrente / dato sia divisibile per 5 minuti.

La tua soluzione deve scegliere casualmente tra tutte le possibili rappresentazioni dell'ora corrente. Cioè ogni rappresentazione deve essere stampata con probabilità diversa da zero.

Mezzanotte e mezzogiorno dovrebbero essere trattati come 0:00(al contrario di 12:00).

Se lo si desidera, è possibile stampare un singolo carattere di nuova riga finale.

È possibile utilizzare quattro caratteri ASCII stampabili distinti (codici di caratteri da 0x20 a 0xFE) al posto di RGBW. Indica la tua scelta nella risposta e usala in modo coerente.

Questo è il golf del codice, quindi vince la risposta più breve (in byte).


(a) possiamo supporre che l'input segua la regola 12 = 0? (b) l'output deve essere in quell'orientamento o possiamo ruotarlo?
sirpercival

@sirpercival a) Sì, penso che conti come "qualsiasi formato comune". b) Deve essere l'orientamento indicato nella sfida.
Martin Ender,

2
Questa sfida ha generato lo sfortunato verbo "fibclocking".
Alex A.

1
Qual è la motivazione per mezzanotte / mezzogiorno che è 0 anziché 12? I primi cinque numeri nella sequenza aggiungono esattamente 12.
Brian J,

@BrianJ Volevo solo sceglierne uno per renderlo coerente e mi è capitato di scegliere zero. In ogni caso, non dovrebbe influire troppo sulle soluzioni. Ho pensato che questa scelta avrebbe reso le cose più semplici perché i minuti hanno anche un intervallo 0..11.
Martin Ender,

Risposte:


6

CJam, 61 byte

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

Accetta due numeri interi separati da spazio tramite STDIN e utilizza 3.14invece di WRGBrispettivamente. Provalo online .

Ecco la RGBWversione "sana" per alcuni byte extra:

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

Spiegazione

L'algoritmo è lo stesso della mia risposta Python : campionamento del rifiuto generando clock fino a quando non ne otteniamo uno corretto.

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

9

Python 2, 194 182 byte

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)

L'algoritmo è solo il campionamento del rifiuto, quindi continua a generare clock fino a quando non ne ottiene uno giusto. L'orologio è costruito partendo da nulla, quindi facendo "aggiungi un quadrato sopra e ruota in senso orario" 5 volte.

Accetta due numeri interi separati da virgola tramite STDIN.

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

4

Python 2, 421 byte

Uff, sono sicuro che questo può essere giocato di più.

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 di prova:

>>> b(7,20)
WWBRRRRR
WWRRRRRR
GGGRRRRR
GGGRRRRR
GGGRRRRR
>>> b(7,20)
RRBWWWWW
RRRWWWWW
BBBWWWWW
BBBWWWWW
BBBWWWWW

@Optimizer ora non ci resta che inserire IDL nel sistema di prettify di Google in modo da poter evidenziare la sintassi IDL evidenziando XD
sirpercival

3

Rubino, 286 byte

Può essere giocabile a golf, ma ci proverà un'altra volta.

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

Spiegazione:

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

1
È possibile sostituire (0..5).to_acon[*0..5]
addison
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.