10
\$\begingroup\$

There are many puzzles with matches that involve adding, removing, or moving a certain number of matches to create new numbers or shapes. This is like that with a digital clock.

Given a valid time on a 12-hour digital clock, output the digit that requires moving the fewest lines to make it so every visible digit on the clock becomes that digit. If more than one digit is the minimum, output them all. If it is impossible to make every digit the same, output -1 or a falsy value other than 0 (you'll get a lot of these).

The clock digits look like this:

  |
  |
 _
 _|
|_
 _
 _|
 _|

|_|
  |
 _
|_
 _|
 _
|_
|_|
 _
  |
  |    
 _ 
|_|
|_|
 _
|_|
 _|
 _
| |
|_|

Test Cases:

Input: 123

Clock Display:

       _   _
  | :  _|  _|
  | : |_   _|

Output: 4

Explanation: The display for 1:23 requires a total of 12 lines to be drawn. Therefore, for every digit to be the same, each digit would have to have 4 lines. The only digit that has 4 lines is 4. Therefore, the answer has to be 4.

Input: 1212

Clock Display:

     _        _
  |  _| :  |  _|
  | |_  :  | |_

Output: -1

Explanation: The display for 12:12 requires 14 lines. 14 divided by 4 is not an integer, therefore it is impossible for every digit to be the same.

Input: 654

Clock Display:

 _     _  
|_  : |_  |_|
|_| :  _|   |

Output: 5

Explanation: The total number of lines is 15. 15 divided by 3 is 5, so each digit must have 5 lines. The only digits that have 5 lines are 2,3, and 5. The answer is 5 because it only requires 2 moves to make every digit 5. Simply move the line at the bottom left of the 6 to the bottom of the 4, then you have:

 _     _  
|_  : |_  |_|
 _| :  _|  _|

Then, as you can see, all you need to do is move the line at the top right of the digit that was originally 4 to the top, and you get 5:55. To make every digit a 2 or 3 would require more than 2 moves.

Input: 609

Clock Display:

 _     _   _
|_  : | | |_|
|_| : |_|  _|

Output: 609 (6,0,9 or [6,0,9] also ok).

Explanation: 6, 0, and 9 are the only digits that have 6 lines. As such, they are also the only possible solutions. It's not hard to see that it would take two moves to make any of these the only digit. Therefore, you output all three digits.

Notes:

  • Although the input time must be valid, the output time does not (e.g. 999 as an output is OK.)
  • I am very flexible with input. You can require a leading 0. You can use a number with a decimal point. You can use a string. You can use an array. You can have a parameter for every digit.
\$\endgroup\$
1
\$\begingroup\$

Julia, 160 157 154

x->(c=count_ones;l=[119;36;93;109;46;107;123;37;127;111];m=l[x+1];n=map(a->c(a)==mean(map(c,m))?sum(map(b->c(a$b),m)):1/0,l);find(n.==minimum(n).!=1/0)-1)

This is a lambda function. Assign it to a variable to call it. Accepts a vector of integers in range 0-9 of any length and returns a (possibly empty) vector of results.

Test cases

julia> clock = x->(c=co...        # assign function to variable
(anonymous function)

julia> clock([1 2 3])
1-element Array{Int64,1}:
 4

julia> clock([1 2 1 2])
0-element Array{Int64,1}

julia> clock([6 5 4])
1-element Array{Int64,1}:
 5

clock([6 0 9])
3-element Array{Int64,1}:
 0
 6
 9

Explanation

Enumerate the seven segments and represent them as a bit vector.

+---+                     +-0-+
|   |      Enumerate      1   2
+---+   >  the seven  >   +-3-+
|   |      segments       4   5
+---+                     +-6-+

Example: 1 (segments 2 + 5 enabled) becomes 36 (bits 2 + 5 set).
Here are the representations for digits 0-9.

l=[119;36;93;109;46;107;123;37;127;111];
m=l[x+1];

We can use the digit as index to get it's bit vector representation. +1 because of 1-based indexing in julia.

The function c=count_ones; counts the number of 1-bits in an integer. We assign an alias because we need it more often.

The full program, somewhat ungolfed:

x->(
  c=count_ones;
  l=[119;36;93;109;46;107;123;37;127;111];
  m=l[x+1];
  n=map(a->c(a)==mean(map(c,m))?sum(map(b->c(a$b),m)):1/0,l);
  find(n.==minimum(n).!=1/0)-1
)

Now, the last two lines in detail:

mean(map(c,m)) calculates the average number of lines per input digit.

n=map(a->...,l) loops over the vector representation of all digits.

If the number of lines of our current digit a is unequal to the average linecount of the input, return inf.

c(a)==mean(map(c,m))?...:1/0

If not, return the sum of the Hamming Distances between our current and all input digits.

sum(map(b->c(a$b),m))

We now have a vector n of length 10 representing the numbers 0-9 that gives us the total number of additions/deletions we have to perform to tranform all input digits to that number, or inf, if such a transformation is impossible without changing the number of lines.

find(n.==minimum(n).!=1/0)-1

Finally, output the locations (0-based) of all minima that are not inf.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.