Построить ASCII часы Фибоначчи

16

Кто-то создал по-настоящему причудливые часы, используя числа Фибоначчи, которые выглядят действительно красиво, но довольно непригодно для использования. Просто так, как нам нравится! Давайте воссоздадим это.

Часы состоят из 5 секций, соответствующих первым пяти числам Фибоначчи, начиная с 1 (т.е. 1, 1, 2, 3, 5):

ccbeeeee
ccaeeeee
dddeeeee
dddeeeee
dddeeeee

Часы способны отображать 12-часовое время с шагом 5 минут. Вот как это работает. Рассмотрим время 7:20. Час 7 можно разложить на заданные числа Фибоначчи как

7 = 2 + 5

Есть также 4 единицы по пять минут. 4 может быть разложен как

4 = 2 + 1 + 1

Теперь часы отображаются красным цветом, минуты - зеленым, а если число используется для часов и минут, то синим цветом. Если номер не используется вообще, он остается белым. Таким образом, выше будет показано как:

BBGRRRRR
BBGRRRRR
WWWRRRRR
WWWRRRRR
WWWRRRRR

Но подождите, это еще не все. Вышеуказанные разложения не единственные возможности. Можно также написать 7 = 3 + 2 + 1 + 1и 4 = 3 + 1, который дал бы один из

GGRWWWWW          GGBWWWWW
GGBWWWWW          GGRWWWWW
BBBWWWWW    or    BBBWWWWW
BBBWWWWW          BBBWWWWW
BBBWWWWW          BBBWWWWW

в зависимости от того, который 1выбран. Конечно, есть и другие комбинации. Часы выбирают из всех допустимых разложений наугад.

Как я уже сказал ... это может не выиграть награду за удобство использования, но на это приятно смотреть.

Соревнование

Ваша задача - реализовать такие часы. Ваша программа (или функция) должна напечатать ASCII-представление текущего времени (округленное до последнего кратного 5 минутам), как описано выше, до STDOUT или ближайшей альтернативы. Вы можете прочитать время в любом общем формате в качестве входных данных или получить его с помощью стандартных функций библиотеки. Вы не должны предполагать, что текущее / данное время делится на 5 минут.

Ваше решение должно выбрать случайным образом из всех возможных представлений текущего времени. То есть каждое представление должно быть напечатано с ненулевой вероятностью.

Полночь и полдень должны рассматриваться как 0:00 (в отличие от 12:00).

При желании вы можете распечатать один завершающий символ новой строки.

Вы можете использовать любые четыре различных печатных символа ASCII (коды символов от 0x20 до 0xFE) вместо RGBW . Пожалуйста, укажите свой выбор в ответе и используйте его последовательно.

Это код гольф, поэтому самый короткий ответ (в байтах) выигрывает.

Мартин Эндер
источник
а) можно ли предположить, что входные данные соответствуют правилу 12 = 0? (б) выход должен быть в этой ориентации, или мы можем повернуть его?
Sirpercival
@sirpercival a) Да, я думаю, это считается "любым распространенным форматом". б) Это должна быть ориентация, указанная в вызове.
Мартин Эндер
2
Этот вызов породил неудачный глагол "фиблокинг".
Алекс А.
1
Какая мотивация для полуночи / полудня быть 0 вместо 12? Первые пять чисел в последовательности складывают до 12 точно.
Брайан Джей
@BrianJ Я просто хотел выбрать один, чтобы сделать его последовательным, и случайно выбрал ноль. В любом случае это не должно сильно влиять на решения. Я полагал, что этот выбор сделает вещи проще, потому что минуты также имеют диапазон 0.11.
Мартин Эндер

Ответы:

6

CJam, 61 байт

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

Принимает два целых числа через пробел через STDIN и использует 3.14вместо WRGBсоответственно. Попробуйте онлайн .

Вот "нормальная" RGBWверсия для нескольких дополнительных байтов:

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

объяснение

Алгоритм такой же, как мой ответ Python - выборка отклонения путем генерации часов, пока мы не получим тот, который является правильным.

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
источник
9

Python 2, 194 182 байта

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)

Алгоритм - это просто выборка отклонения, поэтому он продолжает генерировать часы, пока не получит правильные. Часы строятся, начиная с нуля, затем 5 раз добавьте квадрат сверху и поверните по часовой стрелке.

Принимает два целых числа через запятую через STDIN.

>>> ================================ RESTART ================================
>>> 
7,17
BBBWWWWW
BBRWWWWW
RRRWWWWW
RRRWWWWW
RRRWWWWW
>>> ================================ RESTART ================================
>>> 
7,17
GGBRRRRR
GGRRRRRR
WWWRRRRR
WWWRRRRR
WWWRRRRR
Sp3000
источник
4

Python 2, 421 байт

Тьфу, я уверен, что это может быть в гольфе больше.

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

Прецедент:

>>> b(7,20)
WWBRRRRR
WWRRRRRR
GGGRRRRR
GGGRRRRR
GGGRRRRR
>>> b(7,20)
RRBWWWWW
RRRWWWWW
BBBWWWWW
BBBWWWWW
BBBWWWWW
sirpercival
источник
@Optimizer теперь нам просто нужно добавить IDL в систему Google Prettify, чтобы я мог получить подсветку синтаксиса IDL XD
sirpercival
3

Рубин, 286 байт

Это может быть пригодным для игры в гольф, но попробую в другой раз.

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

Объяснение:

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
источник
1
Вы можете заменить (0..5).to_aна[*0..5]
addison