http://www.perlmonks.org?node_id=949715


in reply to Re^2: Golf: Seven segment display
in thread Golf: Seven segment display

I think my idea is a "cul-de-sac" but this is a little bit shorter (7 char.).
sub w{for$;(1005,924745596,341831533){say map{$;>>$_&1?/../?'|':_:$"}m +ap{$_+20,$_,$_+10}$_[0]=~/./g}}
-- edit: Some explanations about 1005,924745596,341831533
# How to find (1005,924745596,341831533) triplet? # use warnings "nmmt"; # Not My Mother Tongue # _ _ _ _ _ _ _ _ <- line1 #| | | _| _||_||_ |_ ||_||_| <- line2 #|_| ||_ _| | _||_| ||_| _| <- line3 # # line 1 ($l1) is : " _ _ _ _ _ _ _ _ " # 0 1 2 3 4 5 6 7 8 9 # with " "=>0 and "_"=>1, it becomes a binary integer # each digit is encoded with three bits: # 0=> 010 # 1=> 000 # 2=> 010 # ... # 9 (line 3) => 011 (or 0b110 with lower bit at right] # Order of bits is modified to save some bytes (golf-oriented): # in line 1, first and last bits are always zeros (put them at left) # in line 3, there are more zeros for last bit than first bit # This way, the position of 3 bits to encode a digit (abc) # is NOT "0(a),1(b),2(c)" [cba: lower bit right] # # higher lower # 2 1 # 0 0 0 # ... but "20,0,10" (a000000000c000000000b) # ^ ^ ^ # Funny fact: # With the "natural order" the triplet is (1029120,972944241,106939731 +7) and... # 1069397317 is a prime number http://www.wolframalpha.com/input/?i=10 +69397317 # and 341831533=577592429 my $cl=<<SEVSEG; _ _ _ _ _ _ _ _ | | | _| _||_||_ |_ ||_||_| |_| ||_ _| | _||_| ||_| _| SEVSEG my ($l1,$l2,$l3)=split/\n/,$cl; my $i=0; $b=20; my @add=(-20,10,11); # bit position sequence : 20 , 0 , 10 , 21 , 1 , 11,... # -20 10 11 ($a+=$_*2**$b),$b=$b+$add[$i++%3] for map{0+(/[|_]/)}split//,$l1; print "line 1 ->$a"; $a=0; $i=0; $b=20; print "\n"; ($a+=$_*2**$b),$b=$b+$add[$i++%3] for map{0+(/[|_]/)}split//,$l2; print "line 2 ->$a"; $a=0; $i=0; $b=20; print "\n"; ($a+=$_*2**$b),$b=$b+$add[$i++%3] for map{0+(/[|_]/)}split//,$l3; print "line 3->$a"; print "\n";

Replies are listed 'Best First'.
Re^4: Golf: Seven segment display
by mtve (Deacon) on Jan 27, 2012 at 13:52 UTC

    a few obvious optimizations:

    say map$'&2**$_?$_>9?'|':_:$",map{2 .$_,$_,1 .$_}split!//,"@_"for 1005,924745596,341831533

      I'd say the use of $' is less than obvious. Nice work btw.

      The shortest solution I know (not my own creation):

      for$;(0..2){say map{substr' | |_|_ _ _|',vec('0123456789abcdef',$;.$ +_,4),3}"@_"=~/./g}

      where '0123456789abcdef' is to be substituted with "\x09\x99\x90\x99\x99\x13\xBB\x75\x17\x55\x15\xB7\xB1\x15\xB5". When the \x codes are replaced with the actual characters, it comes out two characters shorter than the solution above. (Not very elegant, though.)

        Cool!

        Could be shortened by two chars using the same tricks:

        say map{substr'   | |_|_ _ _|',vec('0123456789abcdef',$'.$_,4),3}split!//,"@_"for 0..2