I'm suprised at how different all the solutions for the LED reader 
minigolf were. Most solutions of course had the same basic approach of
somehow hashing the led characters into a single byte, and then
transforming the bytes into the correct ascii characters. (The main
exception being tybalt who somehow managed to hash directly to the
correct bytes.)

Anyway, here's an explanation of my solution. There's a cute trick
with vec() that I haven't seen used before (found with the usual
approach of "pure luck").

The solution: 

#!perl -lp
s\#\++vec$a,$./2^2*pos,1\ge}{$_=$a;y/\x14\x10^\x1a\x198<\x15\x1c\x18/0-9/

 [The contents of the y/// are of course actually raw bytes, but they
  probably wouldn't fare too well in email transit... ]

The hashing is done by finding all "#":s on a line, and modifying a
corresponding bit in the output string with a vec in lvalue context.
The bit to modify is calculated from pos and $. using the formula
($./2)^(2*pos). The results from this operation can be visualized with
the following table:
   
    024 
  0 024
  1 135
  1 135
  2 206
  2 206 
           
As is apparent from the table, multiple "#":s can map to the same 
bit. The cute trick I mentioned earlier is using ++ on vec, which
effectively flips the value of the bit between 0 and 1 on each
invocation (thanks to vec truncating the value). For example '0':

  ###
  # #
  # #  =>  0, 1, 1, 2, 2, 2, 0, 4, 5, 5, 6, 6  =>  0010100
  # #  
  ###
               
This turns out to be unique for each led character. I originally used
addition instead of xor for combining $. and pos, but that had the
unfortunate side-effect of hashing one of the characters to "-", which
required escaping when embedded in the y///.

-- 
Juho Snellman

Reply via email to