14
\$\begingroup\$

Given a 7-segment display with some segments switched on and some off, find a sequence of digits (0-9), such that after toggling the corresponding segments for each digit, all segments are switched off.

Example

  _
  _    [3] =>     |   [1] =>    [OFF]
  _               |

Numbers and their corresponding segments:

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

Rules

Codegolf ⊨ shortest entry wins.

Input

A non-empty list of segments which are switched on, given as

  1. A sequence of numbers. Segments are numbered from top to bottom, left to right; starting from 0 or 1. Numbers need not be in order.

  2. A single 7-bit digit. MSB/LSB not specified (thus you can choose).

Non-numeric characters between numbers are allowed (but not required to be supported).

Eg. for number 7: 136 or 1010010 or 0100101

Output

A sequence of numbers to be "applied" to the display. Not restricted in any way, such as order of the digits. Eg. for initial state corresponding to number 1, valid outputs would be 1, 111, 010, etc.

An alternative output is a 10-bit digit (again, MSB/LSB is your choice). Eg. for 1 as input, the output would be 1000000000 or 0000000001.

Some combinations have several non-repetitive solutions, eg. segments corresponding to the uppercase letter H can be switched off by 013, but also 489 and 0258.

If no solution exists (which I believe is not possible), the output is empty.

\$\endgroup\$
12
  • 2
    \$\begingroup\$ This needs more specification. Which segments are included in each digit (for example, does 9 include the bottom segment?) Please draw all digits and indicate the numbers of the segments included in each. \$\endgroup\$ Jun 4, 2017 at 16:58
  • \$\begingroup\$ Also, what formats are allowed for input? Will the segment numbers be given in order? What do we do if there is no solution? \$\endgroup\$ Jun 4, 2017 at 17:00
  • \$\begingroup\$ "Some combinations have several non-repetitive solutions" Also, any permutation of a solution is another solution, right? (like 301 for H). \$\endgroup\$
    – Arnauld
    Jun 4, 2017 at 17:01
  • 1
    \$\begingroup\$ Proof that a solution always exists: it suffices to find solutions for each individual segment. Solutions for the horizontal segments, from top to bottom, are 17, 08, and 1479. Solutions for the upper vertical segments, left to right, are 39 and 59. Solutions for the lower vertical segments, left to right, are 56 and 2389. \$\endgroup\$ Jun 5, 2017 at 0:22
  • 1
    \$\begingroup\$ @GregMartin 2 isn't always necessary, because you can replace it with either 0468, 1358, or 1369, depending on whether you want a 0, 8 or 9 in your answer, but there's no way to eliminate 7 at all, and I think you have to have at least one of 1 and 3. \$\endgroup\$
    – Neil
    Jun 5, 2017 at 7:57

5 Answers 5

4
\$\begingroup\$

Jelly, 26 25 bytes

2ṗ⁵’µ×“wØ][:koR¶{‘^/=µÐfḢ

Try it online!

Takes input as a 7-bit integer. Returns the binary form of a 10-bit integer.

This just brute forces all possibilities. Remove the to get all possible outputs or replace it with an X to get a random possible output.

Magic Visualization Program!

How it works

2ṗ⁵’µ×“wØ][:koR¶{‘^/=µÐfḢ  - main link, takes one integer
2ṗ⁵’                       - generate all length-10 binary arrays
    µ                µÐf   - now we find those arrays which correspond to digit-
                              sequences which work to switch off all segments:
                              Filter (keep) those arrays which:
     ×                      - multiplied by 
      “wØ][:koR¶{‘          - [119, 18, 93, 91, 58, 107, 111, 82, 127, 123] 
                               (encoding for turned-on segments given number)
                  ^/        - reduced by XOR
                    =      - are equal to (implicit) the program's input
                        Ḣ  - output the first of these valid arrays
                                 
\$\endgroup\$
2
  • 1
    \$\begingroup\$ The array of numbers (“wØ][:koR¶z‘) might contain an error. Your number 9 lacks the bottom segment (compare 9 in your visualization to the one in task description). Otherwise very nice, especially the visualization! \$\endgroup\$
    – kyrill
    Jun 6, 2017 at 10:14
  • 1
    \$\begingroup\$ @kyrill Fixed! Just required a slight change in the list literal. \$\endgroup\$ Jun 6, 2017 at 14:01
2
\$\begingroup\$

JavaScript (ES6), 60 bytes

n=>[65,35,55,42,48,54,110].reduce((r,v,i)=>r^=n>>i&1&&v+v,0)

This works because:

  • Toggling 1 and 7 toggles the top segment only
  • Toggling 1, 2 and 6 toggles the top left segment only
  • Toggling 1, 2, 3, 5 and 6 toggles the top right segment only
  • Toggling 2, 4 and 6 toggles the centre segment only
  • Toggling 5 and 6 toggles the bottom left segment only
  • Toggling 2, 3, 5 and 6 toggles the bottom right segment only
  • Toggling 2, 3, 4, 6 and 7 toggles the bottom segment only
\$\endgroup\$
2
  • 1
    \$\begingroup\$ Not sure whether this should be accepted as a winner, because obviously you took some inspiration from Arnauld. But then, he also took some inspiration from your comment. Anyways, nice answer, both of you! \$\endgroup\$
    – kyrill
    Jun 5, 2017 at 19:58
  • \$\begingroup\$ @kyrill My updated answer was also a suggestion from Neil. There's no doubt that his answer wins so far. \$\endgroup\$
    – Arnauld
    Jun 5, 2017 at 21:11
2
\$\begingroup\$

JavaScript (ES6), 117 107 101 86 84 bytes

Saved 15 bytes thanks to Neil

Takes input as a 7-bit integer, where the LSB is the upper segment. Returns a 10-bit integer where the LSB is digit 0.

f=(n,k)=>[83,0,57,73,10,71,87,1,91,75].reduce((n,v,i)=>n^=k>>i&1&&v+36,n)?f(n,-~k):k

Demo

f=(n,k)=>[83,0,57,73,10,71,87,1,91,75].reduce((n,v,i)=>n^=k>>i&1&&v+36,n)?f(n,-~k):k

console.log("'1' shape", "-->", f(0b0100100).toString(2))
console.log("'7' shape", "-->", f(0b0100101).toString(2))
console.log("'H' shape", "-->", f(0b0111110).toString(2))

\$\endgroup\$
3
  • 1
    \$\begingroup\$ Recursion is shorter: f=(n,k=1023)=>[83,0,57,73,10,71,87,1,91,75].reduce((n,v,i)=>n^=k>>i&1&&v+36,n)?k--&&f(n,k):k. Or if you assume an answer exists, f=(n,k=0)=>[83,0,57,73,10,71,87,1,91,75].reduce((n,v,i)=>n^=k>>i&1&&v+36,n)?f(n,k+1):k. \$\endgroup\$
    – Neil
    Jun 4, 2017 at 18:16
  • 1
    \$\begingroup\$ @Neil Thanks! Yes, an answer always exists. \$\endgroup\$
    – Arnauld
    Jun 4, 2017 at 18:29
  • 1
    \$\begingroup\$ As it's always possible to create an answer using the digits 1-7, you can save a further 8 bytes by removing the 83 and the ,91,75 and using k+2. \$\endgroup\$
    – Neil
    Jun 4, 2017 at 19:41
2
\$\begingroup\$

Mathematica, 40 bytes

BitXor@@{260,802,10,514,3,266,293}[[#]]&

(It may be golfed more by choosing output for each segment carefully and switch between LSB and MSB.)

Take input as a list of positions for example {2,4,5,7} and output a 10-bit number (384 = 0110000000 in binary) in MSB order (0,...,9).

In the example it correspond to

  |_
  |_

and the output correspond to {7,8}.

Explanation:

The magic numbers (hardcoded list) is the output which is returned for each segment. (encoded in binary) And, if a number appear in the list twice, the effect is the same of it not being appear, so bitwise XOR is used. We just need to XOR the output of possible value of the segments turned on.

\$\endgroup\$
2
\$\begingroup\$

Jelly, 12 bytes

ị“A#7*06n‘^/

Try it online!

This does not brute force, and it is remarkably shorter than my other solution. Takes input as a list of turned-on segments, and outputs as LSB is top segment.

Output as list of digit moves.

How it works

This is going to be quick

ị“A#7*06n‘^/ - main link, takes input as a list of turned-on segments (eg. [1,3,6])
 “A#7*06n‘   - list literal [65,35,55,42,48,54,110] where each element is a 7-bit
                 integer, where each integer corresponds to how to turn off
                 a segment (eg. turn off the first segment with 7 and 1 =>2^7+2^1=>64)
ị            - get the elements in the list corresponding to the input indices
          ^/ - XOR reduce these elements to get a single 7-bit integer
\$\endgroup\$
2
  • \$\begingroup\$ Can't you take advantage of the fact that repetitive solutions are allowed when using this algorithm, to replace the XOR-reduce with something shorter (such as a flatten)? Or am I missing something? \$\endgroup\$
    – user62131
    Jun 7, 2017 at 1:14
  • \$\begingroup\$ The code as I have it now generates a list of 7-bit integers approximately equal to 1*use digit 1 + 2*use digit 2 + 4*use digit 3 ... 64*use digit 7, then XOR-reduces them @ais523. Flattening would work on a list of digits used which takes more characters. \$\endgroup\$ Jun 7, 2017 at 4:32

Your Answer

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

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