27
\$\begingroup\$

Given two arbitrary numbers A,B. Print number B as a Digital LED Pattern where A is the scale.

input:

1 2320451640799518

ouput:

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

input:

2 23

ouput:

 __  __
   |   | 
 __| __|
|      |
|__  __|

Rules:

  • Use STDIN/STDOUT for input/output

  • Code with most up-votes wins. In case of Tie, shortest code will be accepted

  • Most up voted Answer will be accepted at 01/02/2014 (Accepted this answer with highest 12 votes)

\$\endgroup\$
11
  • 2
    \$\begingroup\$ Some related questions, for code stealing/inspiration: "Emulate a 7-segment display" and "LED Numbers and Letters". \$\endgroup\$ Jan 23, 2014 at 8:20
  • \$\begingroup\$ @Wasi Thanks. I saw your edit which cleared it up for me. \$\endgroup\$
    – C0deH4cker
    Jan 23, 2014 at 10:34
  • \$\begingroup\$ Your 9 should have the underscore in the last line, to be like reversed 6. \$\endgroup\$
    – Tomas
    Jan 27, 2014 at 14:44
  • 1
    \$\begingroup\$ @Tomas Thanks for the suggestion. But, we already have 13 answers so it will be unfair to change it further :-) \$\endgroup\$
    – Wasi
    Jan 27, 2014 at 17:23
  • 1
    \$\begingroup\$ Voting to close because there are no requirements for how scaling works, and many answers (including the accepted one) implement it completely different from the test cases. \$\endgroup\$ Nov 29, 2020 at 17:56

17 Answers 17

20
\$\begingroup\$

Commodore 64 BASIC

PETSCII art rules :)

LIST

Output:

RUN

\$\endgroup\$
4
  • 3
    \$\begingroup\$ What happened to the digit 4? o.O \$\endgroup\$
    – Timwi
    Jan 24, 2014 at 1:55
  • \$\begingroup\$ That's how I write number 4, but OK, I fixed that :) \$\endgroup\$ Jan 24, 2014 at 5:53
  • 2
    \$\begingroup\$ Fascinating -- do you write it that way by hand too? Is that common in Sweden, or wherever you originally hail from? \$\endgroup\$
    – boothby
    Jan 24, 2014 at 18:07
  • \$\begingroup\$ I would +100 if I could. \$\endgroup\$ Jan 28, 2014 at 10:02
13
\$\begingroup\$

Python 3, 286 282 280

Yeah I golfed this one. Nice challenge!

n,x=input().split()
n=int(n)
l=lambda s:"".join(s)+"\n"
h=lambda s:s.replace(*"! ")*~-n+s.replace(*"!_")
print(l(" "+"_ "[c in"14"]*n+" "for c in x)+h(l("| "[c in"1237"]+n*"! "[c in"017"]+"| "[c in"56"]for c in x))+h(l(" |"[c in"0268"]+n*"! "[c in"1479"]+"| "[c=="2"]for c in x)))


Also, here's a Python 2 version weighing in at only 273 bytes!

Not updating this one any more with further golfed original source. This was created when the original source was 282 bytes (Python 3 version).

exec'eJxdzE0OgjAQhuE9pxhn1VIlFhHUpCdRQlAx1NShAYwsOLzgD4irSd758tC8UWX6SDTZe824V1mju+uQ0lQz4o5RJr0dzylUO0TvWmhiFRd4IHTy8VV5ZWZNesqYizNA7jJaSC4mOUHu2LJjwTAEFJgA7k+gCWWAsUuii5eihD5Bw0XOul07bPxVhLGgl/9OS9mXcbIOMf4BPgK037kfbv4EGUTbgVAK/SnwBAs+TpU='.decode('base64').decode('zip')

This may be cheating, so I'm adding it separately. Let me know whether this is considered valid or not.

\$\endgroup\$
0
6
\$\begingroup\$

Haskell (389 chars)

The solution uses 7 arrays, one for each segment of the array, using the names from this image:

8 segment display

. The value a !! 4 will be the character that should be displayed at that a position for the number 4.

The values are multiplied by the scale where appropriate (using r and rp for replication), and finally printed out.

The code

a="_ __ _____"
b="|||||  |||"
c="|| |||||||"
d="_ __ __ _ "
e="| |   | | "
f="|   ||| ||"
g="  _____ __"
r=replicate
cm=concatMap
s=(' ':).(++" ")
dd w n=[[t n],rp$m f b n,[o g f b n],rp$m e c n,[o d e c n]] where
 rp=r$w-1
 t=cm(s.r w.(a!!))
 q f s x y=cm(\n->x!!n:r w(f s n)++[y!!n])
 o=q(!!) 
 m=q const ' '
go a=unlines$concat$dd(read$a!!0)$map(read.(:[]))$a!!1
main=interact$go.words

Example usage

echo '1 2320451640799518' | runhaskell ./digit_led.hs
 _  _  _  _     _     _     _  _  _  _  _     _ 
 _| _| _|| ||_||_   ||_ |_|| |  ||_||_||_   ||_|
|_  _||_ |_|  | _|  ||_|  ||_|  |  |  | _|  ||_|
\$\endgroup\$
6
\$\begingroup\$

C, 249 226 chars

Golfed solution in C:

int x,y,g,s,q;main(){char*c,i[99];for(scanf("%d %98s",&s,i);y<2*s+1;++y,puts(""))for(c=i;*c;++c)for(x=0;x<s+2;++x)q=(y+s-1)/s*3+(x+s-1)/s,g=(x%(s+1))*(y%s)?7:q<3?~q%2*7:q-2,putchar("_|_||_| "["zG<lMfvH~N"[*c-48]+1>>g&1?g:7]);}

With added whitespace:

int x, y, g, s, q;

main() {
  char *c, i[99];
  for (scanf("%d %98s", &s, i); y < 2 * s + 1; ++y, puts(""))
    for (c = i; *c; ++c)
      for (x = 0; x < s + 2; ++x)
        q = (y + s - 1) / s * 3 + (x + s - 1) / s,
        g = (x % (s + 1)) * (y % s)
          ? 7
          : q < 3
            ? ~q % 2 * 7
            : q - 2,
        putchar("_|_||_| "["zG<lMfvH~N"[*c - 48] + 1 >> g & 1 ? g : 7]);
}

Notes:

  • At most 99 digits are printed
  • Behavior is undefined if the input is not well formed (e.g. contains non-digits, or scale is < 1)
  • Should be legal C89 code

I will provide an explanation of how it works, should anyone care.

\$\endgroup\$
4
  • 1
    \$\begingroup\$ From what I read around this page on what is "OK in C" you do not need to include #include <stdio.h> (As it will compile without it.) You can also put one int in main(), e.g. main(x), shaving off 1 byte – though it is not valid signature, and put scanf inside for: for(scanf("%d %98s", &s, &i); …) shaving of one more. – Have a look here. \$\endgroup\$
    – Runium
    Jan 27, 2014 at 23:31
  • \$\begingroup\$ @Sukminder These are very helpful hints, thanks! I removed the #include, moved the scanf inside the for, removed the unnecessary & in &i, and put the int variables in global scope to exploit the static 0 initialization. The code should now still be legal C89, but I didn't check thoroughly. I believe putting one int in main is not legal, so I left that out. \$\endgroup\$
    – reima
    Jan 28, 2014 at 9:51
  • \$\begingroup\$ Giving up standard compliance can help a lot. For example, you can omit int for global variables. Also %98s can be %s (for longer strings you fail anyway, does it matter in what way?) \$\endgroup\$
    – ugoren
    Jan 28, 2014 at 12:05
  • \$\begingroup\$ Good! I used "kind of" similar philosophy, but simpler - 187 chars in PERL \$\endgroup\$
    – Tomas
    Jan 31, 2014 at 14:22
5
\$\begingroup\$

Ruby 2.0

Quick and (not so) naive ruby implementation.

V,H = ' |',' _'
l = gets.split
s = l[0].to_i
o = Array.new 1+s*2, ''
l[1].each_char {|c|
  m = "{H=mNgwI\x7FO"[c.to_i].ord
  o[0] += " #{H[m[0]]*s} "
  o[s] += "#{V[m[1]]}#{H[m[2]]*s}#{V[m[3]]}"
  o[s*2] += "#{V[m[4]]}#{H[m[5]]*s}#{V[m[6]]}"
}
(s-1).times { |i|
  o[i+1] = o[s].gsub '_', ' '
  o[s+i+1] = o[s*2].gsub '_', ' '
}
o.each {|r| puts r}

Quick explanation:

I first declare the strings representing on and off digits for horizontal and vertical bars.
Then I read scale and the digits.
I then declare an array of the necessary size to store enough lines for the given scale. The weird string is actually a mapping of 7-bits values representing which LEDs to switch on for each digit.
Next, for each digit, I fill the output array from top to bottom, taking into account horizontal scaling.
The final loop is to fill the rows that only have vertical bars, which can just be generated from the middle and bottom rows by removing horizontal bars.
Finally, I print the output array !

\$\endgroup\$
1
  • \$\begingroup\$ Can you explain what's going on here? \$\endgroup\$ Jan 23, 2014 at 21:14
5
\$\begingroup\$

Python 2.6 with no imports. I'd say that the attractiveness of this solution is the use of templates. Unfortunately I think that's why I had such a hard time compacting it.

def numbers(scale, number):

    def single(yay, wall, digit):
        walls = ('1110111', '0010010', '1011101', '1011011',
                 '0111010', '1101011', '1101111',
                 '1010010', '1111111',
                 '1111010')
        return yay if int(walls[digit][wall]) else ' '

    def expand_one(char, digit):
        characters = '_||_||_'
        translated = single(characters[char], char, digit)
        if char % 3:
            return translated
        return translated * scale

    def expand_template(template, digit):
        out = ''
        for c in template:
            if c == '.':
                out += ' ' * scale
            elif c == ' ':
                out += c
            else:
                out += expand_one(int(c), digit)
        return out

    def repeated_expand_template(template, n):
        print ''.join(expand_template(template, int(d)) for d in n)

    repeated_expand_template(' 0 ', number)
    for _ in range(scale - 1):
        repeated_expand_template('1.2', number)
    repeated_expand_template('132', number)
    for _ in range(scale - 1):
        repeated_expand_template('4.5', number)
    repeated_expand_template('465', number)


scale, number = raw_input().split()
numbers(int(scale), number)

And a bit shorter (308 characters):

s,n=raw_input().split();s=int(s)
for e in('0 0 ','11.2','0132','14.5','0465'):print '\n'.join(''.join(''.join(([' ','_||_||_'[int(c)]][int(bin(1098931065668123279354)[7*int(d)+int(c)+2])]*(s,1,1)[int(c)%3])if ord(c)>46 else c for c in e[1:].replace('.',' '*s))for d in n) for _ in range((1,s-1)[int(e[0])]))
\$\endgroup\$
1
  • \$\begingroup\$ Fyi, the top of the digits are supposed to be '_' (underscores), and no spaces between digits. I was confused at first haha \$\endgroup\$
    – C0deH4cker
    Jan 23, 2014 at 20:23
5
\$\begingroup\$

(Edit: This solution is now invalid because the semantics of the instruction has changed. I didn’t realise that I’d already made use of the instruction when I changed it. You can, however, fix ths program by simply changing it to the newer instruction .)

Sclipting — 85 characters

겠合글坼銻標⓷가殲갰復묽땸민뫝뜵깉걈밂⓶各가⓵겐上⓷감嚙긇밌⓶掘⓶감嚙눖밂⓶掘⓷合⓶감嚙긇밌⓶掘⓷合⓸⓸替❶終⓶丟終❶눠替눐終①貶復⓶⓷終丟併눐替글①復終눠替뇰①復終⓶丟

Input:

1 1024856359701

Output:

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

Input:

2 47474747

Output:

     __      __      __      __ 
|  |   ||  |   ||  |   ||  |   |
|__|   ||__|   ||__|   ||__|   |
   |   |   |   |   |   |   |   |
   |   |   |   |   |   |   |   |

\$\endgroup\$
5
  • \$\begingroup\$ Can you fix the program? Leaving the whole post stroke out is quite ugly. \$\endgroup\$ Jun 18, 2014 at 11:43
  • \$\begingroup\$ I could of course change the to , but that would make this entry cheating because was invented after this challenge was posted. \$\endgroup\$
    – Timwi
    Jun 18, 2014 at 11:54
  • \$\begingroup\$ I don't think it is that much of a problem. I doesn't make your program any shorter anyway. \$\endgroup\$ Jun 18, 2014 at 12:02
  • 1
    \$\begingroup\$ No, but it would violate an important rule of this community. \$\endgroup\$
    – Timwi
    Jun 19, 2014 at 10:10
  • \$\begingroup\$ No longer violates a rule :P \$\endgroup\$
    – ASCII-only
    Dec 11, 2018 at 1:18
4
\$\begingroup\$

C# (480 443 chars)

namespace System{using z=String;using w=Console;class P{static void Main(){var t=w.ReadLine().Split(' ');var s=int.Parse(t[0]);z b="17",d=b+23,e=b+3459,f="56",g=e+2680;Action<z,z,z,int>q=(l,m,r,n)=>{for(int i=1;i<n;i++){foreach(var c in t[1]){h(c,l);for(int j=0;j<s;j++)h(c,m,"_");h(c,r);}w.Write("\n");}};q(g,"14",g,2);q(d,g,f,s);q(d,b+0,f,2);q(e,g,"2",s);q(e,b+49,"2",2);}static void h(char x,z m,z y="|"){w.Write(m.Contains(""+x)?" ":y);}}}

Extended version:

using System;
using System.Linq;

namespace Segments
{
    internal class Program
    {
        static void Main()
        {
            var scale = int.Parse(Console.ReadLine());
            var input = Console.ReadLine();

            PrintLine(input, "", "14", "", 2);
            PrintLine(input,"1237", "", "56", scale);
            PrintLine(input,"1237", "170", "56", 2);
            PrintLine(input,"134579", "", "2", scale);
            PrintLine(input,"134579", "147", "2", 2);
        }

        static void PrintLine(string input, string leftMatch, string middleMatch, string rightMatch, int scale)
        {
            for (int i = 1; i < scale; i++)
            {
                foreach (var c in input)
                {
                    PrintDigitLine(c, leftMatch, '|', 1);
                    PrintDigitLine(c, middleMatch, "_", scale);
                    PrintDigitLine(c, rightMatch, '|', 1);
                }
                Console.Write("\n");
            }
        }

        private static void PrintDigitLine(char digit, string match, char charToPrint, int)
        {
            for (int i = 0; i < n; i++) Console.Write(match.Contains(digit) || match == "" ? ' ' : charToPrint);
        }
    }
}

My idea was to split the task up into 5 horizontal lines, which in turn are split up in a left, right and middle part for each character.

\$\endgroup\$
14
  • \$\begingroup\$ Maybe I copied it wrong, but I tried running this on ideone and it gave an error. ideone.com/gQ6LH7 \$\endgroup\$
    – C0deH4cker
    Jan 23, 2014 at 20:20
  • \$\begingroup\$ probably my fault, let me see \$\endgroup\$
    – Rik
    Jan 23, 2014 at 20:26
  • 1
    \$\begingroup\$ @C0deH4cker I took the input in two separate ReadLines. This one works: ideone.com/4jTxeu \$\endgroup\$
    – Rik
    Jan 23, 2014 at 20:35
  • 1
    \$\begingroup\$ @C0deH4cker I made a version that takes the input as specified, and drops the bottom part of the 9. The input takes as many chars, the 9 costs 1 extra. \$\endgroup\$
    – Rik
    Jan 23, 2014 at 20:50
  • 1
    \$\begingroup\$ You have a redundant ; in there (480); you can write Action<z,z,z,int>q=(l,m,r,n)=>{...}; (470); you can make the first parameter of h a char and do the ""+ inside h (467); and finally, you can declare and re-use z d="134579",b="1237" (465). That’s the smallest I could make it so far \$\endgroup\$
    – Timwi
    Jan 23, 2014 at 21:57
3
\$\begingroup\$

I guess there are very shorter solutions, but since this is not code-golf I'm quite satisfied!

This PHP script will take two numbers a, b from STDIN and echo b in LED format, at a size.

fscanf(STDIN, "%d %d", $a, $b); //Didn't test this line, but it should be ok.
$space=str_repeat("&nbsp;", $a);

$top = $topLeft = $topRight = $mid = $botLeft = $botRight = $bot = array();
for ($i=0; $i<count($b); $i++) {
    $top[$i] = $topLeft[$i] = $topRight[$i] = $mid[$i] = $botLeft[$i] = $botRight[$i] = $bot[$i] = true;
switch ($b[$i]) {
    case 0:
        $mid[$i] = false;
    break;
    case 1:
        $top[$i] = $topLeft[$i] = $mid[$i] = $botLeft[$i] = $bot[$i] = false;
        break;
    case 2:
        $topLeft[$i] = $botRight[$i] = false;
        break;
    case 3:
        $topLeft[$i] = $botLeft[$i] = false;
        break;
    case 4:
        $top[$i] = $botLeft[$i] = $bot[$i] = false;
        break;
    case 5:
        $topRight[$i] = $botLeft[$i] = false;
        break;
    case 6:
        $topRight[$i] = false;
        break;
    case 7:
        $topLeft[$i] = $mid[$i] = $botLeft[$i] = $bot[$i] = false;
        break;
    case 9:
        $botLeft[$i] = false;
        break;
    }
}

horizontal($top);
vertical($topLeft, $topRight);
horizontal($mid);
vertical($botLeft, $botRight);
horizontal($bot);

function horizontal($position) {
    global $a, $b, $space;
    for ($i=0;$i<count($b);$i++) {
        if ($position[$i])
            echo "&nbsp;".str_repeat("-", $a)."&nbsp;";
        else
            echo "&nbsp;".$space."&nbsp;";
    }
    echo "<br />";
}

function vertical($positionLeft, $positionRight) {
    global $a, $b, $space;
    for ($j=0;$j<$a;$j++) {
        for ($i=0;$i<count($b);$i++) {
            if ($positionLeft[$i]) {
                echo "|".$space;
                if ($positionRight[$i])
                    echo "|;";
                else
                    echo "&nbsp;";
            }
            else {
                echo "&nbsp;".$space;
                if ($positionRight[$i])
                    echo "|";
                else
                    echo "&nbsp;";
            }
        }
        echo "<br />";
    }
}

EDIT: Looking at the previous output example, I wrongly supposed that space between digits should be as large as the a size. This has been fixed with the OP's declaration that no space is needed.

\$\endgroup\$
2
  • \$\begingroup\$ Actually, there shouldn't be any spaces between digits. The only reason it looks that way for the sample is the spaces are where the '|' would be on an 8 for example. Took me a while to figure out \$\endgroup\$
    – C0deH4cker
    Jan 23, 2014 at 10:46
  • \$\begingroup\$ Oh, you are right! Thank you :) \$\endgroup\$
    – Vereos
    Jan 23, 2014 at 10:49
2
\$\begingroup\$

C#, 435 359 473 bytes

EDITS:

  • Removed redundant code. Reduced byte size of comparisons.
  • Converted to a stand-alone application using standard in for input.

Here's the golfed code (with added line breaks and whitespace):

using C=System.Console;
class P{
    static void Main(){
        var a=C.ReadLine().Split(' ');
        D(int.Parse(a[0]),a[1]);
    }
    static void D(int r,string n){
        int i,j;
        string s="",v="|",w=" ",x=new string('_',r),y=new string(' ',r),z="\n";
        foreach(var c in n)s+=w+(F(0,c)?x:y)+w+w;
        for(j=1;j<6;j+=3)
            for(i=r;i-->0;){
                s+=z;
                foreach(var c in n)s+=(F(j,c)?v:w)+(i<1&&F(j+1,c)?x:y)+(F(j+2,c)?v:w)+w;
            }
        C.Write(s+z);
    }
    static bool F(int i,char c){
        return(new[]{1005,881,892,927,325,365,1019}[i]&1<<(int)c-48)>0;
    }
}
\$\endgroup\$
4
  • \$\begingroup\$ They are valid C# functions. It was never stated that it should be a stand-alone program. However, it doesn't use standard in. \$\endgroup\$ Jan 24, 2014 at 2:10
  • \$\begingroup\$ @Timwi, edited to conform... \$\endgroup\$ Jan 24, 2014 at 2:18
  • 1
    \$\begingroup\$ Well done!! I’ve golfed it some more and I got it down to 425 (characters; 432 bytes in UTF-8), making it shorter than the other C# answer. using System;using S=System.String;class P{static void Main(){Action<S[]>D=n=>{var r=int.Parse(n[0]);Func<int,int,bool>F=(i,c)=>("ϭͱͼΟŅŭϻ"[i]&1<<c-48)>0;S s="",v="|",w=" ",x=new S('_',r),y=new S(' ',r);foreach(var c in n[1])s+=w+(F(0,c)?x:y)+w+w;for(int j=1;j<6;j+=3)for(int i=r;i-->0;){s+="\n";foreach(var c in n[1])s+=(F(j,c)?v:w)+(i<1&&F(j+1,c)?x:y)+(F(j+2,c)?v:w)+w;}Console.Write(s);};D(Console.ReadLine().Split(' '));}} \$\endgroup\$
    – Timwi
    Jan 24, 2014 at 10:48
  • 1
    \$\begingroup\$ Using the other C# answer’s idea of putting everything in the System namespace takes it down to 423 \$\endgroup\$
    – Timwi
    Jan 24, 2014 at 19:53
2
\$\begingroup\$

C (561 492 bytes)

Author is frmar. He sent me his answer last week (he has not yet created his account).

492 bytes but a bit more obfuscated:

#include<stdio.h>
#include<ctype.h>
#include<stdlib.h>
#define C(x) ((_[*n-'0'])>>s)&m&x
#define P putchar
unsigned _[]={476,144,372,436,184,428,492,148,508,188};
void p(int a,char*n,unsigned m,int s)
{for(;isdigit(*n);++n){P(C(1)?'|':' ');
for(int i=0;i<a;++i)P(C(4)?'_':' ');
P(C(2)?'|':' ');}
P('\n');}
void l(int a,char*b){p(a,b,7,0);int i=1;
for(;i<a;++i)p(a,b,3,3);p(a,b,7,3);i=1;
for(;i<a;++i)p(a,b,3,6);p(a,b,7,6);}
int main(int c,char**v){l(c>1?atoi(v[1]):1,c>2?v[2]:"0123456789");}

Previous version using 561 bytes:

#include<stdio.h>
#include<ctype.h>
#define C(x) ((((*n-'0')[_])>>s)&m&x)
const unsigned _[]={476,144,372,436,184,428,492,148,508,188};
void p(int a,const char*n,unsigned m,int s)
{
 for(;isdigit(*n);++n) {
  putchar(C(1)?'|':' ');
  const char c=C(4)?'_':' ';
  for(int i=0;i<a;++i) putchar(c);
  putchar(C(2)?'|':' ');
 }
 putchar('\n');
}
void l(int a,const char*b)
{
 p(a,b,7,0);
 for(int i=1;i<a;++i)p(a,b,3,3);p(a,b,7,3);
 for(int i=1;i<a;++i)p(a,b,3,6);p(a,b,7,6);
}
#include<stdlib.h>
int main(int c,char**v){l(c>1?atoi(v[1]):1,c>2?v[2]:"0123456789");}

Original version from frmar (623 bytes):

#include<stdio.h>
#include<ctype.h>
const unsigned int _[]={476,144,372,436,184,428,492,148,508,188};
void p(int a,const char*n,unsigned int m,int s)
{
  for(;isdigit(*n);++n) {
#define C(x) ((((*n-'0')[_])>>s)&m&x)
    putchar(C(1)?'|':' ');
    const char c=C(4)?'_':' ';
    for(int i=0;i<a;++i) putchar(c);
    putchar(C(2)?'|':' ');
  }
  putchar('\n');
}
void print_as_led(int a,const char*b)
{
  p(a,b,7,0);
  for(int i=1;i<a;++i)p(a,b,3,3);p(a,b,7,3);
  for(int i=1;i<a;++i)p(a,b,3,6);p(a,b,7,6);
}
#include<stdlib.h>
int main(int argc,char**argv){print_as_led(argc>1?atoi(argv[1]):1,argc>2?argv[2]:"0123456789");}

Compilation:

$ gcc -std=c99 -Wall print_as_led.c

Examples using default 0123456789 number but different sizes:

$ ./a.out
 _     _  _     _  _  _  _  _
| |  | _| _||_||_ |_   ||_||_|
|_|  ||_  _|  | _||_|  ||_|  |

$ ./a.out 2
 __      __  __      __  __  __  __  __
|  |   |   |   ||  ||   |      ||  ||  |
|  |   | __| __||__||__ |__    ||__||__|
|  |   ||      |   |   ||  |   ||  |   |
|__|   ||__  __|   | __||__|   ||__|   |

$ ./a.out 3
 ___       ___  ___       ___  ___  ___  ___  ___
|   |    |    |    ||   ||    |        ||   ||   |
|   |    |    |    ||   ||    |        ||   ||   |
|   |    | ___| ___||___||___ |___     ||___||___|
|   |    ||        |    |    ||   |    ||   |    |
|   |    ||        |    |    ||   |    ||   |    |
|___|    ||___  ___|    | ___||___|    ||___|    |

Other examples:

$ ./a.out 1 42
    _
|_| _|
  ||_

$ ./a.out 2 42
     __
|  |   |
|__| __|
   ||
   ||__

$ ./a.out 3 42
      ___
|   |    |
|   |    |
|___| ___|
    ||
    ||
    ||___

Larger sizes:

$ ./a.out 4 42
       ____
|    |     |
|    |     |
|    |     |
|____| ____|
     ||
     ||
     ||
     ||____
$ ./a.out 5 42
        _____
|     |      |
|     |      |
|     |      |
|     |      |
|_____| _____|
      ||
      ||
      ||
      ||
      ||_____
\$\endgroup\$
1
\$\begingroup\$

Perl + FIGlet + BRA*: 54 characters

while(<>){($n,$x)=split;print(`figlet -f 7seg$n $x`);}

I figured this would be quite easy to do with FIGlet, but there didn't appear to be any suitable fonts for this purpose. So I made some :-)

Here's how it looks on the terminal:

$ perl ./led.pl
1 234
 _  _    
 _| _||_|
|_  _|  |
2 345
 __      __ 
   ||  ||   
 __||__||__ 
   |   |   |
 __|   | __|
3 456
      ___  ___ 
|   ||    |    
|   ||    |    
|___||___ |___ 
    |    ||   |
    |    ||   |
    | ___||___|

*BRA: blatant rule abuse

\$\endgroup\$
2
  • \$\begingroup\$ Don't get why there is a downvote for that. Nice trick with fonts! \$\endgroup\$
    – VisioN
    Jan 23, 2014 at 21:58
  • \$\begingroup\$ I was not downvoting, but I would understand that using a program instead of actually making the program is cheating. \$\endgroup\$
    – Tomas
    Jan 27, 2014 at 17:12
1
\$\begingroup\$

PERL,   261 244 187   166 chars

Little bit of bitwise encoding philosophy rulez :-)

($n,$a)=split/ /;sub c{$_=$a;y/0-9/Gl+%<UWm7=/;s/./(substr"   _ _|_| |_  |",2*ord($&)>>$_[0]&$_[1],3)=~s|.\K.|$&x$n|er/ge;print y/_/ /r x($n-1).$_}c 0,2;c 4,14;c 1,14

Code with whitespace added:

($n,$a)=split/ /;

sub c{
$_=$a;
y/0-9/Gl+%<UWm7=/;
s/./(substr"   _ _|_| |_  |",2*ord($&)>>$_[0]&$_[1],3)=~s|.\K.|$&x$n|er/ge;
print y/_/ /r x($n-1).$_
}

c 0,2;
c 4,14;
c 1,14

Perl has to be invoked with -n:

$ perl -n digitize.zoom.pl
1 12304597
     _   _   _       _   _   _
  |  _|  _| | | |_| |_  |_|   |
  | |_   _| |_|   |  _|   |   |
2 0784
 __   __   __
|  |    | |  | |  |
|  |    | |__| |__|
|  |    | |  |    |
|__|    | |__|    |
3 789
 ___   ___   ___
    | |   | |   |
    | |   | |   |
    | |___| |___|
    | |   |     |
    | |   |     |
    | |___|     |

Notes:

  • Everything about how digits are displayed is encoded in the string Gl+%<UWm7= :-) One character corresponds to one digit, encoded are 3 positions of 3 consecutive characters within the " _ _|_| |_ |" string.
  • Numbers are constructed in 3 lines, line by line. Each of the 3 lines corresponds to one call to sub-routine c, which also accomplishes vertical zooming for second and third line.
  • Horizontal zooming is done at the end of sub-routine c.

My sed program cannot zoom, but it looks a lot nicer, doesn't it? :-)

s/./\0 /g
h
s/[14]/   /g
s/[2305-9]/ _ /g
p
g
s/[17]/  |/g
s/[23]/ _|/g
s/[489]/|_|/g
s/[56]/|_ /g
s/0/| |/g
p
g
s/[147]/  |/g
s/2/|_ /g
s/[359]/ _|/g
s/[680]/|_|/g

Pretty much the idea my PERL script uses, but in PERL it's a lot uglier. Note that for my sed program I prefered to use 9 which has the underscore in the last line, to be like reversed 6.

\$\endgroup\$
1
  • \$\begingroup\$ I was wondering if you could explain how the scaling works, I am trying to implement my own version in Perl. But can't seem to get the vertical and horizontal scaling right. \$\endgroup\$ Feb 15, 2014 at 15:19
0
\$\begingroup\$

C#, 386 382 364 chars / 374 bytes (UTF-8) and (lots? of) room for improvement...

using System.Linq;using C=System.Console;class P{static void Main(string[] args){var s=C.ReadLine();for(int l=0;l<5;l++){for(int j=0;j<s.Length;j++)C.Write(string.Join("",Enumerable.Range(0,3).Select(i=>{var x=l*3+i;return((x&1)>0?((((System.Text.Encoding.Unicode.GetBytes("⑷浝欮╻潿")[(byte)s[j]-48]>>x/2)&1)==1)?(x-1%3>0?"|":"-"):" "):" ");}))+" ");C.WriteLine();}}}

EDIT Crap... I missed the "scale" part CRAP

I'll give it another shot if I get around to it..

\$\endgroup\$
1
  • \$\begingroup\$ Yeah, the scale part makes it scary. \$\endgroup\$
    – cjfaure
    Jan 27, 2014 at 20:06
0
\$\begingroup\$

J - 147 95 characters

Added required scaling:

1!:2&2,./(([1 s 0 s=:1 :(':';'y#"(2-m)~(m{$y)$1,x'))"2(3 :'(y{(5 3$&,0&,.)"1@#:l)}d')@"."0@":)/".]1!:1]1[l=:>:a.i.'v#\Z9jnQ~z'[d=:' ',:5 3$' - | |'

Annotated version:

NB. Digit array (2 x 5 x 3) first is blank, second is filled.
d=:' ',:5 3$' - | |'
NB. Bits to selector (taking into account that all "usefull" bits are separated with 0 bits, looking at the 5 x 3 grid)
bts =: 5 3 $&, (0&,.)
NB. list of character bits.
l=: 119 36 93 91 58 107 111 82 127 123
NB. golfing using ascii range
l=: >:a.i.'v#\Z9jnQ~z'

NB. scaling function
NB. scaling in 1 direction involves inserting copies of the middle segments:
NB. from y, copy the middle segments, 1 x 1 x 1 for rank 2 and 1 x 1 for rank 1
NB. Usage: scale (rank s) segment
s=: 1 : (':';'y#"(2-m)~(m{$y)$1,x')
NB. scale first along columns, then along rows, apply only to rank 2 (planes)
b=:([1 s 0 s)"2

NB. Get one number by using amend with a selection array (0 is blank, 1 is filled)
NB. get the y'th plane from the array of 10 x 5 x 3 selector bits, use those to index d with.
g=: 3 : '(y { (bts"1 #: l)) } d'
NB. from right to left: read stdin, convert number string to numbers,
NB. use the left for scaling, and split the right in digits,then apply g,
NB. then paste them together so the numbers appear next to each other.
NB. Put this result on stdout
1!:2&2,./(b g@"."0@":)/".]1!:1]

Example:

1 0123456789
 -     -  -     -  -  -  -  - 
| ||    |  || ||  |    || || |
       -  -  -  -  -     -  - 
| ||  |    |  |  || |  || |  |
 -     -  -     -  -     -  - 

2 123
     --  -- 
|      |   |
|      |   |
     --  -- 
|   |      |
|   |      |
     --  -- 
\$\endgroup\$
3
  • \$\begingroup\$ How does this answer the question? \$\endgroup\$
    – Wasi
    Jan 28, 2014 at 13:52
  • \$\begingroup\$ You are absolutely right ... I'll fix it \$\endgroup\$
    – jpjacobs
    Jan 29, 2014 at 9:44
  • \$\begingroup\$ Your example is incorrect. Watch the question. \$\endgroup\$
    – Tomas
    Jan 31, 2014 at 14:19
0
\$\begingroup\$

Ruby,126 ASCII characters

->n,x{(n*2).downto(0){|i|x.bytes{|c|z='u"ik:[]b}{'[c-48].ord+2>>i/n*3&7
print' |'[z/2%2],(z%2>i%n ??_:' ')*n,' |'[z/4]}
puts}}

Each digit is encoded as a bitmap in thirds thus, with each third represented by an octal digit.

|_| 8^2 (left and right never used! only the 1's bit used!)  
|_| 8^1 (4*right+2*left+1*bottom)
|_| 8^0 (4*right+2*left+1*bottom)

As all digits have either the 64's bit or 32's bit set, the range is 044 octal to 177 octal. Unfortunately 177 is the nonprintable DEL character, so the magic string contains the numbers 2 below the required bitmap code, and we have to add 2 back on in the function.

Ungolfed in test program

f=->n,x{
  (n*2).downto(0){|i|                               #1 top line, n middle lines, n bottom lines
    x.bytes{|c|                                     #iterate through bytes
      z='u"ik:[]b}{'[c-48].ord+2>>i/n*3&7           #find octal code for current 1/3 digit
      print' |'[z/2%2],(z%2>i%n ??_:' ')*n,' |'[z/4]#print left,right and bottom
    }                                               #z%2>i%n only true on bottom row of 3rd where i%n=0 (print _'s) and octal code has 1's bit set
    puts                                            #print a newline to finish line 
  }
}

n=gets.to_i  #size
x=gets.chop  #number taken in string form
f[n,x]

Output

C:\Users\steve>ruby 7seg.txt
4
0123456789
 ____        ____  ____        ____  ____  ____  ____  ____
|    |     |     |     ||    ||     |          ||    ||    |
|    |     |     |     ||    ||     |          ||    ||    |
|    |     |     |     ||    ||     |          ||    ||    |
|    |     | ____| ____||____||____ |____      ||____||____|
|    |     ||          |     |     ||    |     ||    |     |
|    |     ||          |     |     ||    |     ||    |     |
|    |     ||          |     |     ||    |     ||    |     |
|____|     ||____  ____|     | ____||____|     ||____| ____|
\$\endgroup\$
0
\$\begingroup\$

Perl 6, 284 241 237

my (\a,\n)=split " ",slurp.trim;my @p=n.comb;sub g(\b,\c){for @p {my $h=:36(b);$h+>=3*$_;for ^3 {my \e=$_==1;print " |_".substr($h%2&&(c+!e)&&1+e,1)x a**e;$h+>=1}};say ""};for <52N98I 0 HMTVAD 1 AZRXEV 1> ->\s,\q{g(s,0)for 2..a*q;g(s,1)}

Previous solutions:

my (\a,\n)=slurp.trim.split: " ";my @p=n.comb;sub g(\b,\c){for @p {my $h=b;$h+>=3*$_;for ^3 {my \e=$_==1;print " |_".substr($h%2&&(c+!e)&&1+e,1)x a**e;$h+>=1}};say ""};for 306775170,0,1066270117,1,664751335,1 ->\s,\q{g(s,0)for 2..a*q;g(s,1)}
my (\a,\n)=slurp.trim.split: " ";my @p=n.comb;my &f={print $^b.substr(3*$_,1)~($^c??$b.substr(3*$_+1,1)!!" ")x a~$b.substr(3*$_+2,1)for @p;say ""};for (" _     _  _    "~" _ "x 5,0,"| |  | _| _||_||_ |_   ||_||_|",1,"|_|  ||_  _|  | _||_|  ||_|  |",1) ->\s,\q{f(s,0)for 2..a*q;f(s,1)}
\$\endgroup\$

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