18
\$\begingroup\$

Someone built a really fancy clock using Fibonacci numbers, which looks really nice but is fairly unusable. Just the way we like it! Let's recreate this.

The clock is made up of 5 sections corresponding to the first five Fibonacci numbers, starting from 1 (i.e. 1, 1, 2, 3, 5):

ccbeeeee
ccaeeeee
dddeeeee
dddeeeee
dddeeeee

The clock is capable of displaying the 12-hour time in increments of 5 minutes. Here is how that works. Consider the time 7:20. The hour 7 can be decomposed into the given Fibonacci numbers as

7 = 2 + 5

There are also 4 units of five minutes. The 4 can be decomposed as

4 = 2 + 1 + 1

Now the hours are shown in red, the minute chunks in green, and if a number is used for both hours and minutes it's shown in blue. If a number isn't used at all, it remains white. So the above would be shown as:

BBGRRRRR
BBGRRRRR
WWWRRRRR
WWWRRRRR
WWWRRRRR

But wait, there's more. The above decompositions aren't the only possibilities. One can also write 7 = 3 +たす 2 +たす 1 +たす 1 and 4 = 3 + 1, which would give one of

GGRWWWWW GGBWWWWW
GGBWWWWW GGRWWWWW
BBBWWWWW or BBBWWWWW
BBBWWWWW BBBWWWWW
BBBWWWWW BBBWWWWW

depending on which 1 is chosen. Of course there are other combinations as well. The clock chooses from all valid decompositions at random.

As I said... this might not win a usability award, but it sure is nice to look at.

The Challenge

Your task is to implement such a clock. Your program (or function) should print an ASCII representation of the current time (rounded down to the last multiple of 5 minutes) as described above to STDOUT or closest alternative. You may choose to read the time in any common format as input or obtain it with standard library functions. You must not assume that the current/given time is divisible by 5 minutes.

Your solution must choose randomly from all possible representations of the current time. That is each representation must be printed with non-zero probability.

Midnight and noon should be treated as 0:00 (as opposed to 12:00).

You may optionally print a single trailing newline character.

You may use any four distinct printable ASCII characters (character codes 0x20 to 0xFE) in place of RGBW. Please state your choice in your answer and use it consistently.

This is code golf, so the shortest answer (in bytes) wins.

asked May 8, 2015 at 12:06
\$\endgroup\$
5
  • \$\begingroup\$ (a) can we assume that the input follows the 12=0 rule? (b) does the output have to be in that orientation, or can we rotate it? \$\endgroup\$ Commented May 8, 2015 at 14:18
  • \$\begingroup\$ @sirpercival a) Yes, I think that counts as "any common format". b) It has to be the orientation given in the challenge. \$\endgroup\$ Commented May 8, 2015 at 14:20
  • 2
    \$\begingroup\$ This challenge spawned the unfortunate verb "fibclocking." \$\endgroup\$ Commented May 8, 2015 at 19:05
  • 1
    \$\begingroup\$ What's the motivation for midnight/noon being 0 instead of 12? The first five numbers in the sequence add up to 12 exactly. \$\endgroup\$ Commented May 8, 2015 at 19:20
  • \$\begingroup\$ @BrianJ I just wanted to choose one to make it consistent and happened to pick zero. It shouldn't really affect solutions too much anyway. I figured this choice would make things simpler because the minutes also have a 0..11 range. \$\endgroup\$ Commented May 8, 2015 at 19:25

4 Answers 4

9
\$\begingroup\$

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)

The algorithm is just rejection sampling, so it keeps generating clocks until it gets one that's right. The clock is built by starting with nothing, then doing "add a square above and rotate clockwise" 5 times.

Takes two comma-separated integers via STDIN.

>>> ================================ RESTART ================================
>>> 
7,17
BBBWWWWW
BBRWWWWW
RRRWWWWW
RRRWWWWW
RRRWWWWW
>>> ================================ RESTART ================================
>>> 
7,17
GGBRRRRR
GGRRRRRR
WWWRRRRR
WWWRRRRR
WWWRRRRR
answered May 8, 2015 at 15:51
\$\endgroup\$
6
\$\begingroup\$

CJam, 61 bytes

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

Takes two space-separated integers via STDIN, and uses 3.14 instead of WRGB respectively. Try it online.

Here is the "sane" RGBW version for a few extra bytes:

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

Explanation

The algorithm is the same as my Python answer — rejection sampling by generating clocks until we get one that's correct.

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
answered May 8, 2015 at 19:25
\$\endgroup\$
4
\$\begingroup\$

Ruby, 286 bytes

It may be golfable, but will try some other time.

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

Explanation:

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
answered May 8, 2015 at 16:18
\$\endgroup\$
1
  • 1
    \$\begingroup\$ You can replace (0..5).to_a with [*0..5] \$\endgroup\$ Commented Jul 19, 2015 at 2:23
4
\$\begingroup\$

Python 2, 421 bytes

Ugh, I'm sure this can be golfed more.

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

Test case:

>>> b(7,20)
WWBRRRRR
WWRRRRRR
GGGRRRRR
GGGRRRRR
GGGRRRRR
>>> b(7,20)
RRBWWWWW
RRRWWWWW
BBBWWWWW
BBBWWWWW
BBBWWWWW
answered May 8, 2015 at 15:49
\$\endgroup\$
1
  • \$\begingroup\$ @Optimizer now we just have to get IDL into the google prettify system so i can get IDL syntax highlighting XD \$\endgroup\$ Commented May 8, 2015 at 17:54

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.