Lights out, 7-segment version

14

2

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.

kyrill

Posted 2017-06-04T16:48:03.720

Reputation: 575

2This 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. – Level River St – 2017-06-04T16:58:55.997

Also, what formats are allowed for input? Will the segment numbers be given in order? What do we do if there is no solution? – Level River St – 2017-06-04T17:00:09.180

"Some combinations have several non-repetitive solutions" Also, any permutation of a solution is another solution, right? (like 301 for H). – Arnauld – 2017-06-04T17:01:16.490

@Arnauld Yes, that's correct. – kyrill – 2017-06-04T17:09:12.153

Nice challenge, BTW. :-) – Arnauld – 2017-06-04T17:17:02.170

There are 1024 possible digit sets and 128 possible segment sets, so that makes 8 digit set solutions for each segment set. These can be obtained by a combination of set differences with three sets such as the following: 02468, 12358, 12369. This means that it's possible to avoid considering up to three digits (although 7 is always necessary) when determining an answer. – Neil – 2017-06-04T19:38:06.197

Looks like somebody likes Unicode :) – Esolanging Fruit – 2017-06-04T22:13:53.143

1Proof 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. – Greg Martin – 2017-06-05T00:22:46.903

@Neil: I see why 2 is necessary (it's the only way to get at the lower-right vertical segment); why is 7 necessary? – Greg Martin – 2017-06-05T00:25:06.983

1@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. – Neil – 2017-06-05T07:57:38.730

@Challenger5 Did it display incorrectly in your browser? If so, which browser and system do you use? I'm using FF on Fedora and it looked OK, but then someone edited the Unicode part of my task description, saying he "fixed alignment". After that edit, the alignment was wrong in my browser. Alas, I guess we're not ready for Unicode yet... Or maybe I just don't know how to use it properly :-] – kyrill – 2017-06-06T08:47:44.770

You can also use the XOR space explorer to find out how many segment sets can be generated from a given set of digits.

– Neil – 2017-06-06T09:30:49.570

Answers

4

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

fireflame241

Posted 2017-06-04T16:48:03.720

Reputation: 7 021

1The 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! – kyrill – 2017-06-06T10:14:17.577

1@kyrill Fixed! Just required a slight change in the list literal. – fireflame241 – 2017-06-06T14:01:29.073

2

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

Arnauld

Posted 2017-06-04T16:48:03.720

Reputation: 111 334

1Recursion 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. – Neil – 2017-06-04T18:16:33.867

1@Neil Thanks! Yes, an answer always exists. – Arnauld – 2017-06-04T18:29:04.107

1As 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. – Neil – 2017-06-04T19:41:13.090

2

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

Neil

Posted 2017-06-04T16:48:03.720

Reputation: 95 035

1Not 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! – kyrill – 2017-06-05T19:58:53.823

@kyrill My updated answer was also a suggestion from Neil. There's no doubt that his answer wins so far. – Arnauld – 2017-06-05T21:11:38.653

2

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.

user202729

Posted 2017-06-04T16:48:03.720

Reputation: 14 620

2

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

fireflame241

Posted 2017-06-04T16:48:03.720

Reputation: 7 021

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? – None – 2017-06-07T01:14:35.003

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. – fireflame241 – 2017-06-07T04:32:20.650