Zbuduj zegar Fibonacciego ASCII

16

Ktoś zbudował naprawdę fantazyjny zegar przy użyciu liczb Fibonacciego, który wygląda naprawdę ładnie, ale jest dość bezużyteczny. Tak jak lubimy! Odtwórzmy to ponownie.

Zegar składa się z 5 części odpowiadających pierwszym pięciu liczbom Fibonacciego, zaczynając od 1 (tj. 1, 1, 2, 3, 5):

ccbeeeee
ccaeeeee
dddeeeee
dddeeeee
dddeeeee

Zegar może wyświetlać 12-godzinny czas w odstępach co 5 minut. Oto jak to działa. Rozważ czas 7:20. Godzinę 7 można rozłożyć na podane liczby Fibonacciego jako

7 = 2 + 5

Istnieją również 4 jednostki po pięć minut. 4 można rozłożyć jako

4 = 2 + 1 + 1

Teraz godziny są wyświetlane na czerwono, minuty są na zielono, a jeśli liczba jest używana zarówno dla godzin, jak i minut, jest wyświetlana na niebiesko. Jeśli liczba nie jest w ogóle używana, pozostaje biała. Powyższe byłoby pokazane jako:

BBGRRRRR
BBGRRRRR
WWWRRRRR
WWWRRRRR
WWWRRRRR

Ale czekaj, jest więcej. Powyższe dekompozycje nie są jedynymi możliwościami. Można także pisać 7 = 3 + 2 + 1 + 1i 4 = 3 + 1, co dałoby jeden z

GGRWWWWW          GGBWWWWW
GGBWWWWW          GGRWWWWW
BBBWWWWW    or    BBBWWWWW
BBBWWWWW          BBBWWWWW
BBBWWWWW          BBBWWWWW

w zależności od tego, który 1zostanie wybrany. Oczywiście są też inne kombinacje. Zegar wybiera losowo ze wszystkich prawidłowych rozkładów.

Jak powiedziałem ... to może nie wygrać nagrody za użyteczność, ale na pewno miło jest na to spojrzeć.

Wyzwanie

Twoim zadaniem jest wdrożenie takiego zegara. Twój program (lub funkcja) powinien wydrukować reprezentację ASCII bieżącego czasu (zaokrągloną w dół do ostatniej wielokrotności 5 minut), jak opisano powyżej, do STDOUT lub najbliższej alternatywy. Możesz wybrać odczyt czasu w dowolnym popularnym formacie jako dane wejściowe lub uzyskać go za pomocą standardowych funkcji bibliotecznych. Nie można zakładać, że bieżący / podany czas dzieli się przez 5 minut.

Twoje rozwiązanie musi wybierać losowo spośród wszystkich możliwych reprezentacji bieżącego czasu. Oznacza to, że każda reprezentacja musi być drukowana z niezerowym prawdopodobieństwem.

Północ i południe należy traktować jako 0:00(w przeciwieństwie do 12:00).

Opcjonalnie możesz wydrukować pojedynczy znak nowej linii.

Możesz użyć dowolnych czterech różnych drukowalnych znaków ASCII (kody znaków od 0x20 do 0xFE) zamiast RGBW. Podaj swój wybór w odpowiedzi i używaj go konsekwentnie.

To jest kod golfowy, więc wygrywa najkrótsza odpowiedź (w bajtach).

Martin Ender
źródło
(a) czy możemy założyć, że dane wejściowe są zgodne z zasadą 12 = 0? (b) czy wyjście musi być w tej orientacji, czy możemy go obrócić?
sirpercival
@sirpercival a) Tak, myślę, że liczy się to jako „dowolny wspólny format”. b) Musi to być orientacja podana w wyzwaniu.
Martin Ender
2
Wyzwanie to zrodziło niefortunny czasownik „fibclocking”.
Alex A.,
1
Jaka jest motywacja, by północ / południe było 0 zamiast 12? Pierwsze pięć liczb w sekwencji sumuje się dokładnie do 12.
Brian J
@BrianJ Chciałem tylko wybrać taki, aby był spójny i zdarzyło mi się wybrać zero. Zresztą i tak nie powinno to zbytnio wpływać na rozwiązania. Uznałem, że ten wybór uprościłby sprawę, ponieważ minuty mają również zakres 0..11.
Martin Ender

Odpowiedzi:

6

CJam, 61 bajtów

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

Pobiera dwie liczby całkowite oddzielone spacją przez STDIN i używa odpowiednio 3.14zamiast WRGB. Wypróbuj online .

Oto „rozsądna” RGBWwersja kilku dodatkowych bajtów:

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

Wyjaśnienie

Algorytm jest taki sam jak moja odpowiedź w języku Python - próbkowanie odrzucenia przez generowanie zegarów, dopóki nie otrzymamy poprawnego.

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
źródło
9

Python 2, 194 182 bajtów

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)

Algorytm po prostu odrzuca próbkowanie, więc generuje zegary, dopóki nie uzyska właściwego. Zegar buduje się, zaczynając od zera, a następnie wykonując polecenie „dodaj kwadrat powyżej i obróć zgodnie z ruchem wskazówek zegara” 5 razy.

Pobiera dwie liczby całkowite oddzielone przecinkami przez STDIN.

>>> ================================ RESTART ================================
>>> 
7,17
BBBWWWWW
BBRWWWWW
RRRWWWWW
RRRWWWWW
RRRWWWWW
>>> ================================ RESTART ================================
>>> 
7,17
GGBRRRRR
GGRRRRRR
WWWRRRRR
WWWRRRRR
WWWRRRRR
Sp3000
źródło
4

Python 2, 421 bajtów

Ugh, jestem pewien, że można więcej grać w golfa.

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

Przypadek testowy:

>>> b(7,20)
WWBRRRRR
WWRRRRRR
GGGRRRRR
GGGRRRRR
GGGRRRRR
>>> b(7,20)
RRBWWWWW
RRRWWWWW
BBBWWWWW
BBBWWWWW
BBBWWWWW
sirpercival
źródło
@Optimizer teraz musimy tylko wprowadzić IDL do systemu Google Prettify, aby uzyskać podświetlanie składni IDL XD
sirpercival
3

Rubinowy, 286 bajtów

Może być golfa, ale spróbuje kiedyś.

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

Wyjaśnienie:

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
źródło
1
Możesz zastąpić (0..5).to_aprzez[*0..5]
addison