Construire une horloge ASCII Fibonacci

16

Quelqu'un a construit une horloge très sophistiquée en utilisant des nombres de Fibonacci, qui a l'air vraiment sympa mais qui est assez inutilisable. Tout comme nous l'aimons! Recréons cela.

L'horloge est composée de 5 sections correspondant aux cinq premiers nombres de Fibonacci, à partir de 1 (soit 1, 1, 2, 3, 5):

ccbeeeee
ccaeeeee
dddeeeee
dddeeeee
dddeeeee

L'horloge est capable d'afficher l'heure de 12 heures par incréments de 5 minutes. Voici comment cela fonctionne. Considérez le temps 7:20. L'heure 7 peut être décomposée en nombres de Fibonacci donnés comme

7 = 2 + 5

Il y a également 4 unités de cinq minutes. Le 4 peut être décomposé en

4 = 2 + 1 + 1

Maintenant, les heures sont affichées en rouge, les minutes en vert et si un nombre est utilisé pour les heures et les minutes, il est affiché en bleu. Si un numéro n'est pas utilisé du tout, il reste blanc. Donc, ce qui précède serait montré comme:

BBGRRRRR
BBGRRRRR
WWWRRRRR
WWWRRRRR
WWWRRRRR

Mais attendez, il y a plus. Les décompositions ci-dessus ne sont pas les seules possibilités. On peut aussi écrire 7 = 3 + 2 + 1 + 1et 4 = 3 + 1, ce qui donnerait

GGRWWWWW          GGBWWWWW
GGBWWWWW          GGRWWWWW
BBBWWWWW    or    BBBWWWWW
BBBWWWWW          BBBWWWWW
BBBWWWWW          BBBWWWWW

selon lequel 1 est choisi. Bien sûr, il existe également d'autres combinaisons. L'horloge choisit au hasard parmi toutes les décompositions valides.

Comme je l'ai dit ... cela pourrait ne pas gagner un prix d'utilisation, mais c'est bien agréable à regarder.

Le défi

Votre tâche consiste à implémenter une telle horloge. Votre programme (ou fonction) doit imprimer une représentation ASCII de l'heure actuelle (arrondie au dernier multiple de 5 minutes) comme décrit ci-dessus sur STDOUT ou l'alternative la plus proche. Vous pouvez choisir de lire l'heure dans n'importe quel format commun comme entrée ou de l'obtenir avec les fonctions de bibliothèque standard. Vous ne devez pas supposer que l'heure actuelle / donnée est divisible par 5 minutes.

Votre solution doit choisir au hasard parmi toutes les représentations possibles de l'heure actuelle. Autrement dit, chaque représentation doit être imprimée avec une probabilité non nulle.

Minuit et midi doivent être traités comme 0:00(par opposition à 12:00).

Vous pouvez éventuellement imprimer un seul caractère de nouvelle ligne de fin.

Vous pouvez utiliser quatre caractères ASCII imprimables distincts (codes de caractères 0x20 à 0xFE) à la place de RGBW. Veuillez indiquer votre choix dans votre réponse et l'utiliser de manière cohérente.

Il s'agit du code golf, donc la réponse la plus courte (en octets) l'emporte.

Martin Ender
la source
(a) peut-on supposer que l'entrée suit la règle 12 = 0? (b) la sortie doit-elle être dans cette orientation, ou pouvons-nous la faire pivoter?
sirpercival
@sirpercival a) Oui, je pense que cela compte comme "n'importe quel format commun". b) Ce doit être l'orientation donnée dans le défi.
Martin Ender
2
Ce défi a engendré le malheureux verbe "fibclocking".
Alex A.
1
Quelle est la motivation pour minuit / midi étant 0 au lieu de 12? Les cinq premiers chiffres de la séquence totalisent exactement 12.
Brian J
@BrianJ Je voulais juste en choisir un pour le rendre cohérent et il m'est arrivé de choisir zéro. De toute façon, cela ne devrait pas trop affecter les solutions. J'ai pensé que ce choix rendrait les choses plus simples car les minutes ont également une plage de 0..11.
Martin Ender

Réponses:

6

CJam, 61 octets

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

Prend deux entiers séparés par des espaces via STDIN et utilise 3.14 au lieu de WRGBrespectivement. Essayez-le en ligne .

Voici le "sain d'esprit" RGBW version pour quelques octets supplémentaires:

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

Explication

L'algorithme est le même que ma réponse Python - échantillonnage de rejet en générant des horloges jusqu'à ce que nous obtenions celle qui est correcte.

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
la source
9

Python 2, 194 182 octets

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'algorithme est juste un échantillonnage de rejet, il continue donc de générer des horloges jusqu'à ce qu'il en obtienne une qui soit correcte. L'horloge est construite en commençant par rien, puis en faisant "ajouter un carré au-dessus et tourner dans le sens des aiguilles d'une montre" 5 fois.

Prend deux entiers séparés par des virgules via STDIN.

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

Python 2, 421 octets

Ugh, je suis sûr que cela peut être joué plus.

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])

Cas de test:

>>> b(7,20)
WWBRRRRR
WWRRRRRR
GGGRRRRR
GGGRRRRR
GGGRRRRR
>>> b(7,20)
RRBWWWWW
RRRWWWWW
BBBWWWWW
BBBWWWWW
BBBWWWWW
sirpercival
la source
@Optimizer maintenant, il nous suffit de mettre IDL dans le système google prettify pour que je puisse obtenir la syntaxe IDL mettant en évidence XD
sirpercival
3

Rubis, 286 octets

Il peut être jouable au golf, mais essayera une autre fois.

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

Explication:

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
la source
1
Vous pouvez remplacer (0..5).to_apar[*0..5]
addison