When I was a kid I had a handheld version of the game "lights out" [1,2], and I 
was addicted.    The game is played on a 5-by-5
board of lights, and starts with some of the lights on and all the others off; 
the goal is to turn off all the lights.  You can
toggle the state of a light and its 4 neighbors (NSEW) by pressing on it.  

For example, here is the classic starter board:

        00000
        00000
        10101
        00*00
        00000

Where 0 is an off light, 1 is an on light, and * is a light I'm about to press 
(which happens to be off, but you can't see that in
this notation).  After I press that light, the board looks like this:

        00000
        00000
        10001
        0111*
        00100

Where again the light I'm about to press happens to be off (i.e. there's a 0 
under that *).  Having pressed that, the board now
looks like this:

        00000
        00000
        10000
        01101
        00101
   
and so on until I turn off all the lights.

I have an implementation of this in J that I wrote when I was first learning 
the language (I frequently use this game as my
language-familiarization problem, following "Hello,world!" -- I have one in x86 
assembler, somewhere).    When I wrote it, one of
the things that bothered me was that I couldn't come up with an elegant, 
array-ish way to toggle the lights, given the light the
user pressed.     

So, given J's array mastery, can you?  That is, given the inputs:

           ] BOARD0 =: 5 5 $ 0 0 0 0 0   0 0 0 0 0  1 0 1 0 1  0 0 0 0 0   0 0 
0 0 0
        0 0 0 0 0
        0 0 0 0 0
        1 0 1 0 1
        0 0 0 0 0
        0 0 0 0 0

           PUSH   =: 3 2
           
can you write a dyad   out   such that:

           ] BOARD1 =: BOARD0 out PUSH
        0 0 0 0 0
        0 0 0 0 0
        1 0 0 0 1
        0 1 1 1 0
        0 0 1 0 0
                   

in an elegant, array-oriented way?  I'm thinking about maybe an inner product 
of some sort, as opposed to calculating the index
array and manually amending the board (e.g. BOARD0 4 : '(-. z { x ) (z=.<"1 y 
<@+"1 _2 ]\ _1 0  0 _1  0 0  0 1  1 0)} x' PUSH).  I'd
also like to see solutions which avoid handling the edge- and corner-cases 
specially, especially if this can be done *without*
changing the representation of the as a boolean table (but if necessary, feel 
free to select your own representations for BOARD or
PUSH).

-Dan

[1]:   You can play the game online here:  
        http://www.whitman.edu/mathematics/lights_out/
        and also see its Java source.

[2]  Wikipedia nicely describes the mathematics of Lights Out:
        http://en.wikipedia.org/wiki/Lights_Out_(game)
       including spoilers on how to win (or write a program to determine if a 
given board is winnable).


----------------------------------------------------------------------
For information about J forums see http://www.jsoftware.com/forums.htm

Reply via email to