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\$
4
  • \$\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\$ Commented Jan 9, 2016 at 16:09
  • 8
    \$\begingroup\$ This would be incredibly easy if not for the rule that it must be a valid digit... \$\endgroup\$ Commented Jan 9, 2016 at 22:41
  • \$\begingroup\$ @ETHproductions I am aware. \$\endgroup\$ Commented Jan 9, 2016 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\$ Commented Jan 10, 2016 at 0:05

1 Answer 1

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\$

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.