13
\$\begingroup\$

7-segment digits can be represented in ASCII using _| characters. Here are the size 1 digits:

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

Larger sizes are formed by making each segment proportionately longer. Here are a couple size 3 digits.

 ___    ___    ___    ___    ___    ___    ___ 
|   |  |          |  |          |  |   |  |   |
|   |  |          |  |          |  |   |  |   |
|___|  |___       |  |___    ___|  |   |  |___|
|   |  |   |      |      |      |  |   |      |
|   |  |   |      |      |      |  |   |      |
|___|  |___|      |   ___|   ___|  |___|   ___|

Goal

In this challenge, you are to write a program/function that can take a single digit as input and identify its size. The catch: if the input is not a valid digit, then your program should output 0.

This is code-golf, fewest bytes wins.

You can write either a program or a function, which can receive the digit either as STDIN or an argument, and print/return the value.

Digits will be provided as a multi-line string, padded with the minimal amount of trailing whitespace needed to make it a perfect rectangle. The trailing newline is an optional part of input. There will be no unneeded leading spaces.

When a non-digit is passed, it will still be comprised of _| characters, padded to a rectangle, and have no unneeded leading spaces. There will be no blank lines. You won't have to deal with empty input.

Output should be a single non-negative integer, with optional trailing newline. If the input is not a proper digit of any size, output 0. Else, output the size.

Here is a handy guide for the widths and heights of each digit for a given size N.

Digit  Height  Width (not counting newlines)
1      2N      1
2      2N+1    N+2
3      2N+1    N+1
4      2N      N+2
5      2N+1    N+2
6      2N+1    N+2
7      2N+1    N+1
8      2N+1    N+2
9      2N+1    N+2
0      2N+1    N+2

I/O Examples

In:

__ 
  |
__|
  |
__|

Out:

2

In:

|
|
|

Out:

0  //because it is of an invalid height.  Either 1 char too short or tall.

In:

|    |
|    |
|    |
|____|
     |
     |
     |
     |

Out:

4

In:

 ___ 
|    
|___ 
|   |
|___|

Out:

0 //1 char too wide

In:

 _ 
|_|
| |

Out:

0 //it's not a digit

In:

 __ 
|   
|__ 
   |
 __|

Out:

2

In:

 _  _ 
 _| _|
|_  _|

Out:

0  //both would be valid individually, but input should be a *single* digit

In:

 _ 
|_|
|_|

Out:

1

In:

|
|

Out:

1

In:

__|_
 |  
 _ |
  _ 
|__ 

Out:

0

This is approximately the inverse of Transform number into 7-segment display pattern, from 3 years back.

\$\endgroup\$
  • \$\begingroup\$ @steveverrill There's not really a such thing as a size 0 digit, is there? Unless you've thought up a way to draw them. \$\endgroup\$ – PhiNotPi Jan 9 '16 at 16:09
  • 8
    \$\begingroup\$ This would be incredibly easy if not for the rule that it must be a valid digit... \$\endgroup\$ – ETHproductions Jan 9 '16 at 22:41
  • \$\begingroup\$ @ETHproductions I am aware. \$\endgroup\$ – PhiNotPi Jan 9 '16 at 22:46
  • \$\begingroup\$ @ETHproductions if it didn't have that requirement, it would be a duplicate of codegolf.stackexchange.com/q/19548/15599 \$\endgroup\$ – Level River St Jan 10 '16 at 0:05
1
\$\begingroup\$

Ruby, 250

->x{d=y=0
x.size.downto(0){|n|y=n
a=["|
"*2*n]
"XNRDqpm@A".bytes{|z|p=[?|,' ','']
h=s=""
(n*2).times{|i|
i%n<1&&(d=z>>i/n*3&7)&&h=[?_,' '][d/3%2]*n
s=p[d%3]+h+p[d/6]+"
"+s
h=' '*n}
z!=68&&s=' '*(1-d%3/2)+?_*n+" 
"+s
a<<s};puts a
a.index(x)&&break}
y}

Given that there are so many possible invalid inputs, the only way to do this was to generate all the correct digits and check to see if the input matches.

I build each digit up from bottom to top, in 2 halves plus the top line. Although there are 12 possibilities (considering that the left segment can be on, off, or in the case of 3and 7completely absent) only 7 are actually present and careful choice of encoding enables all info (except the top line) to be encoded into a single character.

the digit 1 doesn't really fit the pattern and is handled separately, being used to initialize the array.

Ungolfed in test program

This version uses . instead of spaces for diagnostic reasons.

#Encoding used for half-digits (radix 3,2,2 most significant digit at right)

#000    |_|  0

#100    ._|  1  . = space

#200    X_|  2  X = no space (for digits 3 and 7)  

#010    |.|  3

#110    ..|  4

#210    X.|  5

#001    |_.  6


f=->x{d=y=0                                        #d and y required to be intialized for scoping reasons
  x.size.downto(0){|n|y=n                          #Assume max possible size of character = length of input and iterate down through all possible sizes n   
    a=["|\n"*2*n]                                  #Make an array containing the digit 1 (different shape to others)
    "XNRDqpm@A".bytes{|z|                          #Each character encodes the pattern for a digit. Iterate through them
      p=['|','.','']                               #Possible components for left and right of digit
      h=s=""                                       #h initialized for scoping reasons. s will contain the digit string 
      (n*2).times{|i|                              #For each row
        i%n<1&&                                    #If i%n==1 we are at the bottom of a half digit
        (d=z>>i/n*3&7)&&                           #so extract info from z and store in d
        h=[?_,'.'][d/3%2]*n                        #h is the horizontal part of the half digit, either _ or spaces 
        s=p[d%3]+h+p[d/6]+"\n"+s                   #Build one row of digit, working upwards: left,middle,right
        h='.'*n                                    #If row i%n!=0 (not bottom row of half digit)the middle section must contain spaces
      }                                            #We now have both halves of the digit, only the top segment missing 
      z!=68&&s='.'*(1-d%3/2)+?_*n+".\n"+s          #If z!=68 (digit 4) add a top to the digit, with appropriate leading and trailing spaces        
      a<<s                                         #Add the completed digit of size n to a
    }
    #puts a                                        #Diagnostic: uncomment to print all the strings checked
    a.index(x)&&break                              #If string x is in a, break

  }
y                                                  #and return last value of n 
}


# digit 7, size 2. Trailing newline required. Outputs 2
puts f[
"__.
..|
..|
..|
..|
"]
\$\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.