kdb programming challenge – Fibonacci Clock

Blog Challenge 29 May 2015

Data Intellect

Fibonacci in a nut shell!

We all know what the Fibonacci Sequence is. It is basically the summation of last 2 numbers of a series starting from 1 (i.e. 1 1 2 3 5 8 13 ….). It exists in nature and can be seen in a sunflower head or in a snail shell as shown above. It is also related to the famous golden ratio(phi)! But how obsessed are you with Fibonacci?? Apparently someone was so obsessed with the sequence that he went and made a clock out of it, Fibonacci Clock. Amazing isn’t it?? It’s hard enough to read a clock face when you are in a rush and late for work but with this clock, it is even more challenging! You need to do the math to get the time!

So as nerdy as I am, today we will have 2 challenges (wow 2 challenges in one day? so awsome!!). Well here are the challenges:

1) Tell the time of Fibonacci Clock

This is pretty simple, instead of using our brain to tell the time, why not write some q code that does that for you?? So write a function that takes a string input and return the time.
The string input is delimited by space, each items are digit follow by a colour code (R – Red, B – Blue, G – Green).
Results should be in 12-hour format.

[code langauge = css]
q)f”5R 3B 2G 1R”
09:25
q)f”5B 3G 1G”
05:45
q)f”5R 2R”
07:00
[/code]

[showhide type=”post1″ more_text=”Show Solution” less_text=”Solution” hidden=”yes”]
First instinct is to separate the string by space!
[code langauge = css]
{x:” “vs x}
[/code]
Now with this matrix, we can extract the colors out and map them to their minutes.
[code langauge = css]
{x:” “vs x;(“RBG”!60 65 5)x[;1]}
[/code]
We then multiply each of them to their digits.
[code langauge = css]
{x:” “vs x;(“J”\$’x[;0])*'(“RBG”!60 65 5)x[;1]}
[/code]
Do a sum and cast it to minute type.
[code langauge = css]
f:{x:” “vs x;”u”\$sum(“J”\$’x[;0])*'(“RBG”!60 65 5)x[;1]}
[/code]

[/showhide]

2) Create Fibonacci Time

So this is a bit tricky, create a function that takes time as input and return string form Fibonacci time.
Note that the author of the article said, there are different combinations of Fibonacci time for a certain time!
Your function must be able to return all those possible combinations. Since the clock can only display the time in 5 min intervals, you will need to round the time to its nearest 5 min.
Also, the clock’s time is 12-hour format instead of 24-hour format. So 01:00 is essentially the same as 13:00.

[code langauge = css]
q)g 06:30
“5B 1B”
“5B 1R 1G”
“5R 3G 2G 1B”
“5R 3G 2G 1R 1G”
“5G 3R 2R 1B”
“5G 3R 2R 1R 1G”
“3B 2B 1B”
“3B 2B 1R 1G”
[/code]

[showhide type=”post2″ more_text=”Show Solution” less_text=”Solution” hidden=”yes”]
One possible way is to first create all the possible combination of 1-12 using 5 3 2 1 1 (I treat both 1s as unique). I also did something extra to make sure the combinations stay at the same length for later use.
[code langauge = css]
d:d group sum each d:enlist[5#0],5 3 2 1 1*/:a in/:raze{raze x{x,/:y where y>max x}\:til 5}\[4;a:til 5]
[/code]
Now the input is time, so we need to split them to their hour and minute. Note that we need to round the minute to its nearest 5 min and handle the case where 00:** is essentially the same as 12:**.
[code langauge = css]
(1+mod[;12] -13+`hh\$;”j”\$.2*`mm\$)@\:
[/code]
We then use d to map the combinations to the digits and create permutation for them.
[code langauge = css]
(cross/)d(1+mod[;12] -13+`hh\$;”j”\$.2*`mm\$)@\:
[/code]
Now all we need is to add the colors and flatten the hour and minute for each of them. First we can have a scoring system to get the colors.
0 – No colours
1 – Red (hours)
2 – Green (minutes)
3 – Blue (hours + minutes)
[code langauge = css]
{(0<x 0)+2*0<(x:2 5#x)1}@'(cross/)d(1+mod[;12] -13+`hh\$;”j”\$.2*`mm\$)@\:
[/code]
Then we map the colors using the scores. I also filter out the 0s in the process.
[code langauge = css]
{” RGB”i w:where 0<i:(0<x 0)+2*0<(x:2 5#x)1}@'(cross/)d(1+mod[;12] -13+`hh\$;”j”\$.2*`mm\$)@\:
[/code]
Next is to join the digits together and sort them.
[code langauge = css]
{desc(“53211″w),'” RGB”i w:where 0<i:(0<x 0)+2*0<(x:2 5#x)1}@'(cross/)d(1+mod[;12] -13+`hh\$;”j”\$.2*`mm\$)@\:
[/code]
Finally, we filter out the duplicates and flatten each strings with space.
[code langauge = css]
g:” “sv’distinct{desc(“53211″w),'” RGB”i w:where 0<i:(0<x 0)+2*0<(x:2 5#x)1}@'(cross/)d(1+mod[;12] -13+`hh\$;”j”\$.2*`mm\$)@\:
[/code]

[/showhide]

Personal Remark

I find this creation very intriguing and worth the praise. As a math and art lover, this clock is quite original and creative. I want to thank Philippe Chrétien for inspiring me to write this challenge and wish him all the best with the project!