Erstellen Sie eine ASCII-Fibonacci-Uhr

16

Jemand hat eine wirklich schicke Uhr mit Fibonacci-Zahlen gebaut, die sehr schön aussieht, aber ziemlich unbrauchbar ist. So wie es uns gefällt! Lassen Sie uns das nachbauen.

Die Uhr besteht aus 5 Abschnitten, die den ersten fünf Fibonacci-Zahlen entsprechen, beginnend mit 1 (dh 1, 1, 2, 3, 5):

ccbeeeee
ccaeeeee
dddeeeee
dddeeeee
dddeeeee

Die Uhr kann die 12-Stunden-Zeit in Schritten von 5 Minuten anzeigen. So funktioniert das Betrachten Sie die Zeit 7:20. Die Stunde 7 kann in die angegebenen Fibonacci-Zahlen als zerlegt werden

7 = 2 + 5

Es gibt auch 4 Einheiten von fünf Minuten. Die 4 kann als zerlegt werden

4 = 2 + 1 + 1

Jetzt werden die Stunden in Rot angezeigt, die Minutenblöcke in Grün, und wenn eine Zahl für Stunden und Minuten verwendet wird, wird sie in Blau angezeigt. Wenn eine Nummer überhaupt nicht verwendet wird, bleibt sie weiß. Das obige würde also so aussehen:

BBGRRRRR
BBGRRRRR
WWWRRRRR
WWWRRRRR
WWWRRRRR

Aber warte, es gibt noch mehr. Die obigen Zerlegungen sind nicht die einzigen Möglichkeiten. Man kann auch schreiben 7 = 3 + 2 + 1 + 1und 4 = 3 + 1, was man davon geben würde

GGRWWWWW          GGBWWWWW
GGBWWWWW          GGRWWWWW
BBBWWWWW    or    BBBWWWWW
BBBWWWWW          BBBWWWWW
BBBWWWWW          BBBWWWWW

je nachdem was 1 gewählt wird. Natürlich gibt es auch andere Kombinationen. Die Uhr wählt aus allen gültigen Zerlegungen zufällig aus.

Wie ich schon sagte ... das wird vielleicht keinen Usability Award gewinnen, aber es ist auf jeden Fall schön anzusehen.

Die Herausforderung

Ihre Aufgabe ist es, eine solche Uhr zu implementieren. Ihr Programm (oder Ihre Funktion) sollte eine ASCII-Darstellung der aktuellen Zeit (abgerundet auf das letzte Vielfache von 5 Minuten) wie oben beschrieben auf STDOUT oder die nächstgelegene Alternative ausgeben. Sie können die Zeit in jedem gängigen Format als Eingabe lesen oder mit Standardfunktionen der Bibliothek abrufen. Sie dürfen nicht davon ausgehen, dass die aktuelle / angegebene Zeit durch 5 Minuten teilbar ist.

Ihre Lösung muss zufällig aus allen möglichen Darstellungen der aktuellen Zeit auswählen. Das heißt, jede Darstellung muss mit einer Wahrscheinlichkeit ungleich Null gedruckt werden.

Mitternacht und Mittag sollten als behandelt werden 0:00 (im Gegensatz zu 12:00) behandelt werden.

Optional können Sie ein einzelnes Zeilenumbruchzeichen drucken.

Sie können anstelle von vier verschiedenen druckbaren ASCII-Zeichen (Zeichencodes 0x20 bis 0xFE) verwenden RGBW . Bitte geben Sie in Ihrer Antwort Ihre Wahl an und verwenden Sie diese konsequent.

Dies ist Codegolf, daher gewinnt die kürzeste Antwort (in Bytes).

Martin Ender
quelle
(a) Können wir annehmen, dass die Eingabe der 12 = 0-Regel entspricht? (b) Muss die Ausgabe in dieser Ausrichtung sein, oder können wir sie drehen?
Sirpercival
@sirpercival a) Ja, ich denke das zählt als "jedes gängige Format". b) Es muss die in der Herausforderung angegebene Orientierung sein.
Martin Ender
2
Diese Herausforderung brachte das unglückliche Verb "fibclocking" hervor.
Alex A.
1
Was ist die Motivation dafür, dass Mitternacht / Mittag 0 statt 12 ist? Die ersten fünf Zahlen in der Sequenz ergeben genau 12.
Brian J
@BrianJ Ich wollte nur eins auswählen, um es konsistent zu machen, und habe zufällig null ausgewählt. Es sollte die Lösungen sowieso nicht zu sehr beeinträchtigen. Ich dachte, diese Wahl würde die Sache einfacher machen, da die Minuten auch einen Bereich von 0..11 haben.
Martin Ender

Antworten:

6

CJam, 61 Bytes

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

Nimmt zwei durch Leerzeichen getrennte Ganzzahlen über STDIN und verwendet 3.14statt WRGB. Probieren Sie es online aus .

Hier ist die "vernünftige" RGBWVersion für ein paar zusätzliche Bytes:

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

Erläuterung

Der Algorithmus ist derselbe wie bei meiner Python-Antwort - Ablehnungsabtastung durch Erzeugen von Takten, bis wir einen erhalten, der korrekt ist.

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

Bei dem Algorithmus handelt es sich lediglich um eine Zurückweisungsabtastung, sodass so lange Uhren generiert werden, bis die richtige gefunden wurde. Die Uhr wird gebaut, indem man mit nichts beginnt und dann 5 Mal "ein Quadrat darüber hinzufügt und im Uhrzeigersinn dreht".

Nimmt zwei durch Kommas getrennte Ganzzahlen über STDIN auf.

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

Python 2, 421 Bytes

Ugh, ich bin mir sicher , dass man mehr Golf spielen kann.

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

Testfall:

>>> b(7,20)
WWBRRRRR
WWRRRRRR
GGGRRRRR
GGGRRRRR
GGGRRRRR
>>> b(7,20)
RRBWWWWW
RRRWWWWW
BBBWWWWW
BBBWWWWW
BBBWWWWW
sirpercival
quelle
@Optimizer Jetzt müssen wir nur noch IDL in das Google Prettify-System einbinden, damit ich die IDL-Syntax erhalten kann, die XD
Sirpercival
3

Ruby, 286 Bytes

Es mag Golf sein, wird es aber ein andermal versuchen.

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

Erläuterung:

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
quelle
1
Sie können (0..5).to_amit[*0..5]
addison