17
\$\begingroup\$

You probably all know the 7-segment display which can display among other things all digits from \$0\dots 9\$:

7-segment display (wikipedia.org)

Challenge

We only consider the segments \$\texttt{A}\dots\texttt{G}\$, your task is to decode a single digit given which segments are turned on.

This can be encoded as an 8-bit integer, here's a table of each digit with their binary representation and the corresponding little-endian and big-endian values:

$$ \begin{array}{c|c|rr|rr} \text{Digit} & \texttt{.ABCDEFG} & \text{Little-endian} && \text{Big-endian} & \\ \hline 0 & \texttt{01111110} & 126 & \texttt{0x7E} & 126 & \texttt{0x7E} \\ 1 & \texttt{00110000} & 48 & \texttt{0x30} & 12 & \texttt{0x0C} \\ 2 & \texttt{01101101} & 109 & \texttt{0x6D} & 182 & \texttt{0xB6} \\ 3 & \texttt{01111001} & 121 & \texttt{0x79} & 158 & \texttt{0x9E} \\ 4 & \texttt{00110011} & 51 & \texttt{0x33} & 204 & \texttt{0xCC} \\ 5 & \texttt{01011011} & 91 & \texttt{0x5B} & 218 & \texttt{0xDA} \\ 6 & \texttt{01011111} & 95 & \texttt{0x5F} & 250 & \texttt{0xFA} \\ 7 & \texttt{01110000} & 112 & \texttt{0x70} & 14 & \texttt{0x0E} \\ 8 & \texttt{01111111} & 127 & \texttt{0x7F} & 254 & \texttt{0xFE} \\ 9 & \texttt{01111011} & 123 & \texttt{0x7B} & 222 & \texttt{0xDE} \end{array} $$

Rules & I/O

  • Input will be one of
    • single integer (like in the table above one of the two given orders)
    • a list/array/.. of bits
    • a string consisting of characters ABCDEFG (you may assume it's sorted, as an example ABC encodes \$7\$), their case is your choice (not mixed-case)
  • Output will be the digit it encodes
  • You may assume no invalid inputs (invalid means that there is no corresponding digit)

Tests

Since this challenge allows multiple representations, please refer to the table.

\$\endgroup\$
5
  • \$\begingroup\$ Related. \$\endgroup\$ Oct 21, 2018 at 16:46
  • \$\begingroup\$ Can we accept an integer (or array) in any specified bit-order or just the two shown? \$\endgroup\$ Oct 21, 2018 at 17:07
  • \$\begingroup\$ @JonathanAllan: I'll clarify, only the ones already shown. \$\endgroup\$ Oct 21, 2018 at 19:37
  • \$\begingroup\$ Ohhh crap, you don't have to handle all input types? Only one? Whoops... \$\endgroup\$ Oct 22, 2018 at 15:42
  • \$\begingroup\$ @MagicOctopusUrn: Yes indeed :) \$\endgroup\$ Oct 22, 2018 at 17:43

19 Answers 19

10
\$\begingroup\$

JavaScript (ES6), 26 bytes

Takes input in little Endian.

n=>'0958634172'[n*3%77%10]

Try it online!

\$\endgroup\$
1
8
\$\begingroup\$

Python 3, 18 bytes

b'~0my3[_p{'.find

Try it online!

Uses little-endian inputs. Contains a raw \x7F byte.

Python 2, 27 bytes

map(ord,'~0my3[_p{').index

Try it online!

\$\endgroup\$
7
\$\begingroup\$

Wolfram Language (Mathematica), 41 bytes

9[,6,0,8,2,3,1,7,5,4][[#~Mod~41~Mod~11]]&

Try it online!

Uses the little-endian column of integers as input. Ignore the syntax warning.

For an input X, we first take X mod 41 and then take the result mod 11. The results are distinct mod 11, so we can extract them from a table. For example, 126 mod 41 mod 11 is 3, so if we make position 3 equal to 0, then we get the correct answer for an input of 126.

The table is 9[,6,0,8,2,3,1,7,5,4]. Part 0 is the head, which is 9. Part 1 is missing, so it's Null, to save a byte: we never need to take part 1. Then part 2 is 6, part 3 is 0, and so on, as usual.


Jonathan Allan's answer gives us 1[4,9,8,6,2,0,5,3,7][[384~Mod~#~Mod~13]]&. This isn't any shorter, but it does avoid the syntax warning!


Wolfram Language (Mathematica), 27 25 bytes

Mod[Hash[")dD}"#]+2,11]&

(There's some character here that doesn't quite show up, sorry. Click on the link below and you'll see it.)

Try it online!

This is all about brute-forcing some string to go inside Hash so that the hashes end up having the right values mod 11. More brute forcing can probably get us to an even shorter solution.

\$\endgroup\$
3
  • \$\begingroup\$ Could you please explain this answer a little bit, for someone who doesn't know Mathematica? \$\endgroup\$
    – jrook
    Oct 21, 2018 at 18:01
  • \$\begingroup\$ I thought it would be readable for anyone, but okay, I'll edit in an explanation. \$\endgroup\$ Oct 21, 2018 at 18:44
  • \$\begingroup\$ Congrats; the 41 byte solution broke my Mathematica compressor. \$\endgroup\$
    – lirtosiast
    Jun 19, 2019 at 17:54
4
\$\begingroup\$

Jelly, 12 bytes

“0my3[_p¶{‘i

Accepts a little-endian integer.

Try it online!

This is the naive implementation, there might be a way to get a terser code.

\$\endgroup\$
0
4
\$\begingroup\$

Python 2, 31 bytes

lambda n:'99608231754'[n%41%11]

Try it online! takes input as little-endian.

\$\endgroup\$
4
\$\begingroup\$

JavaScript (Node.js), 25 bytes

n=>'1498620537'[384%n%13]

Accepts a little-endian integer.

Try it online!


Ports for 31 bytes in Python with lambda n:'1498620537'[384%n%13]

\$\endgroup\$
4
\$\begingroup\$

Java (JDK), 32 bytes

n->"99608231754".charAt(n%41%11)

Try it online!

Credits

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

Whitespace, 152 bytes

Obligatory "the S's, T's, and L's aren't really there, they're just visible representations of the commands".

S S S T	S S L
S S S T	S T	L
S S S T	T	T	L
S S S T	L
S S S T	T	L
S S S T	S L
S S S T	S S S L
S S S L
S S S T	T	S L
S S S L
S S S T	S S T	L
S S S L
S L
S T	L
T	T	T	T	T	S S S T	S T	S S T	L
T	S T	T	S S S T	S T	T	L
T	S T	T	L
S S L
S L
S L
T	S S L
S T	L
S T	L
S S S T	L
T	S S T	L
S L
L
L
S S S L
S L
L
T	L
S T	

Try it online!

Ends in an error.

Equivalent assembly-like syntax:

	push 4
	push 5
	push 7
	push 1
	push 3
	push 2
	push 8
	push 0
	push 6
	push 0
	push 9
	push 0
	dup
	readi
	retrieve
	push 41
	mod
	push 11
	mod
slideLoop:
	dup
	jz .slideLoop
	slide 1
	push 1
	sub
	jmp slideLoop
.slideLoop:
	drop
	printi
\$\endgroup\$
1
  • \$\begingroup\$ You can remove the three trailing newlines to save 3 bytes. It gives an error in STDERR, but the program still works, and it's allowed by the meta-rules. \$\endgroup\$ Oct 22, 2018 at 6:45
3
\$\begingroup\$

brainfuck, 474 176 154 151 149 137 bytes

Takes an input string of eight 0 and 1 including the first 0 for decimal point.

(like in the second column of the table in the post)

Outputs digit from 0 to 9.

,>,>,>,,,>,>,>+[[->]<++<<<<<<]>[>[>[>[->[>++++++<-<]>[--<]<]>>.>>]<[>
>[>->++<<-]>-[+>++++<]>+.>]]>[>>>+<<<-]>[>>+++.>]]>[>>>[>+++<-]>-.>]

Try it online!

Algorithm

By observing state of a particular segment we can split a set of possible digits into smaller subsets. Below is the static binary search tree used in my code. Left subtree corresponds to segment ON state, right corresponds to segment OFF state.

                                         0,1,2,3,4,5,6,7,8,9
                                                  |    
                                         /-------[A]-------------------------\
                                 0,2,3,5,6,7,8,9                             1,4
                                        |                                     |
                         /-------------[B]----------------\             /----[G]----\
                   0,2,3,7,8,9                            5,6          4             1   
                        |                                  |
              /--------[E]--------\                  /----[E]----\    
            0,2,8                3,7,9              6             5
              |                    |
        /----[F]----\        /----[F]----\
      0,8            2      9            3,7   
       |                                  |
 /----[G]----\                      /----[G]----\
8             0                    3             7

Some observations useful for golfing

  1. Bits C and D are redundant and can be ignored.
  2. Leading zero (bit for decimal point) can be (ab)used as value 48, important both for parsing input and preparing output.
  3. When leaf is reached and digit is printed, we just need to skip all further conditions. It can be done by moving data pointer far enough to the area of zeros so that it cannot come back.
  4. For the compatibility it is better to use zeros on the right, because some BF implementations doesn't support negative data pointers.
  5. Hence it is better to store output value in the rightmost cell, so we can easily reach area of zeros to the right.
  6. Hence it is better to check bits from left to right: A,B,E,F,G so we can reach output cell easier.
  7. Different digits may share output code. For example, 5 and 6 are in the same subtree. We may do +++++ for both values and then + for six only.
  8. We may decrease number of + commands if we add 2 to output value in advance. In that case we need to decrease it for 0 and 1 only and get advantage for other digits.
\$\endgroup\$
2
\$\begingroup\$

Retina, 96 bytes

^(A)?(B)?C?(D|())(E|())(F)?(G)?
$.($.5*$.8*$(6*$7$2$2)$#6*$.3*$($.2*$(___$7)5*$7)$#4*$(6*$1_3*$8

Try it online! May not be the best way, but it's an interesting way of programming in Retina. Explanation:

^(A)?(B)?C?(D|())(E|())(F)?(G)?

Tries to capture the interesting cases. The positive captures simply capture the letter if it's present. The length of the capture is therefore 1 if it's present and 0 if it's absent. The special cases are captures 4 and 6 which exist only if D or E are absent respectively. These can only be expressed in decimal as $#4 and $#6 but that's all we need here. The captures are then built up into a string whose length is the desired number. For instance, if we write 6*$1 then this string has length 6 if A is present and 0 if it is absent. In order to choose between different expressions we use either $. (for the positive captures) or $# (for the negative captures) which evaluate to either 0 or 1 and this can then be multiplied by the string so far.

$.5*$.8*$(6*$7$2$2)

F is repeated 6 times and B twice (by concatenation as it's golfier). However, the result is ignored unless both E and G are present. This handles the cases of 2, 6 and 8.

$#6*$.3*$($.2*$(___$7)5*$7)

F is repeated 5 times, and if B is present, it is added a sixth time plus an extra 3 (represented by a constant string of length 3). However, the result is ignored unless D is present and E is absent. This handles the cases of 3, 5 and 9.

$#4*$(6*$1_3*$8

A is repeated 6 times, and G is repeated 3 times, and an extra 1 added (represented by a constant character between the two because it's golfier). However the result is ignored unless D is absent. This handles the cases of 1, 4 and 7.

$.(

The above strings are then concatenated and the length taken. if none of the above apply, no string is generated, and its length is therefore 0.

The resulting strings (before the length is taken) are as follows:

1   _
2   BB
3   ___
4   _GGG
5   FFFFF
6   FFFFFF
7   AAAAAA_
8   FFFFFFBB
9   ___FFFFFF
\$\endgroup\$
2
\$\begingroup\$

MATL, 14 bytes

'/lx2Z^o~z'Q&m

Input is a number representing the segments in little-endian format.

Try it online!

Explanation

'/lx2Z^o~z'  % Push this string
Q            % Add 1 to the codepoint of each char. This gives the array
             % [48 109 ... 123], corresponding to numbers 1 2 ... 9. Note that
             % 0 is missing
&m           % Implicit input. Call ismember function with second output. This
             % gives the 1-based index in the array for the input, or 0 if the
             % input is not present in the array.
             % Implicit display
\$\endgroup\$
2
\$\begingroup\$

Perl 5 -pl, 24 bytes

$_=index'~0my3[_p{',chr

Try it online!

Takes little-endian integers.

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

Ruby, 29 bytes

->n{"0083416243795"[n%23-10]}

Try it online!

\$\endgroup\$
1
\$\begingroup\$

Japt, 15 bytes

Takes the big-endian value as input.

"~¶ÌÚúþÞ"bUd

Try it


Explanation

The string contains the characters at each of the codepoints of the big-endian values; Ud gets the character at the input's codepoint and b finds the index of that in the string.

\$\endgroup\$
1
\$\begingroup\$

Neim, 15 bytes

&bᚫJ𝕂𝕨O𝐖𝐞ℤ£ᛖ𝕪)𝕀

Explanation:

&bᚫJ𝕂𝕨O𝐖𝐞ℤ£ᛖ𝕪)      create list [126 48 109 121 51 91 95 112 127 123]
                 𝕀     index of

Try it online!

\$\endgroup\$
1
\$\begingroup\$

Stax, 12 bytes

å╬JÄk☺é[£¿⌐→

Run and debug it

Input is little endian integer.

It uses the same string constant as Luis' MATL solution.

\$\endgroup\$
1
\$\begingroup\$

TI-BASIC (TI-83+/84+ series), 15 bytes

int(10fPart(194909642ln(Ans

Uses little-endian input. Hashes are fairly common in TI-BASIC, so I wrote a hash function brute-forcer for cases like this.

We get a bit lucky here, as the multiplier is 9 digits long rather than the expected 10.

      fPart(194909642ln(Ans   hash function mapping onto [0,1)
int(10                        take first digit after decimal point
\$\endgroup\$
1
\$\begingroup\$

05AB1E, 17 16 15 12 bytes

•NŽyf¯•I41%è

-1 byte thanks to @ErikTheOutgolfer.
-1 byte by creating a port of @MishaLavrov's Mathematica answer.
-3 bytes thanks to @Grimy.

Try it online or verify all test cases.

Explanation:

•NŽyf¯•       # Push compressed integer 99608231754
       I41%   # Push the input modulo-41
           è  # Index this into the integer (with automatic wraparound)
              # (and output the result implicitly)

See this 05AB1E tip of mine (section How to compress large integers?) to understand why •NŽyf¯• is 99608231754.

\$\endgroup\$
4
  • 1
    \$\begingroup\$ 16 bytes. \$\endgroup\$ Oct 21, 2018 at 17:31
  • \$\begingroup\$ @EriktheOutgolfer Ah, of course.. Coincidentally it's 128в. Forgot there is a builtin for 128 being halve 256. Thanks! \$\endgroup\$ Oct 21, 2018 at 17:33
  • \$\begingroup\$ I tried some freaky stuff too couldn't get under 15. Freakiest attempt: ¦C•26¤æÈÛµÀš•2ô₂+sk (19). \$\endgroup\$ Oct 22, 2018 at 16:14
  • 1
    \$\begingroup\$ @Grimy Thanks! Now that I see it it's obvious, since the compressed integer is size 11 and wraparound kicks in. \$\endgroup\$ Jun 21, 2019 at 17:00
0
\$\begingroup\$

Charcoal, 17 bytes

I⌕”y~¶ÌÚúþÞ”℅N

Try it!

Port of the Japt answer.

\$\endgroup\$

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.