packages feed

swarm-0.4: data/scenarios/Challenges/_lights-out/solution.sw

def doN = \n. \f. if (n > 0) {f; doN (n - 1) f} {}; end;

def intersperse = \n. \f2. \f1. if (n > 0) {
        f1;
        if (n > 1) {
            f2;
        } {};
        intersperse (n - 1) f2 f1;
    } {};
    end;

/** Precondition: facing "d" direction */
def toggleToDark = \d.
    onHere <- ishere "on";
    if onHere {drill d; return ()} {};
    end;

def visitSingleRow = \rowWidth. \d.
    intersperse rowWidth move $ toggleToDark d;
    end;

def turnAround = \d.
    turn d;
    move;
    turn d;
    end;

/** Iterates through the first four rows. */
def chaseUpperLights = \rowWidth.
    visitSingleRow rowWidth right;
    turnAround right;
    visitSingleRow rowWidth left;
    turnAround left;
    visitSingleRow rowWidth right;
    turnAround right;
    visitSingleRow rowWidth left;
    end;

/**
Place yourself in the upper-left corner, facing east.
*/
def goToCorner =
    move;
    turn right;
    move;
    turn left;
    end;

def onInDirection = \d.
    entHere <- scan d;
    return $ case entHere (\_. false) (\e. e == "on");
    end;

/**
If the light at A5 is on, press D1 and E1.
*/
def fixA5 =
    turn back;
    doN 2 move;
    turn right;
    doN 3 move;
    drill left;
    move;
    drill left;
    turn back;
    doN 3 move;
    turn left;
    doN 2 move;
    end;

/**
If the light at B5 is on, press B1 and E1.
*/
def fixB5 =
    turn back;
    doN 2 move;
    drill forward;
    turn right;
    doN 3 move;
    drill left;
    turn back;
    doN 2 move;
    turn left;
    doN 2 move;
    end;

/**
If the light at C5 is on, press D1.
*/
def fixC5 =
    turn back;
    doN 3 move;
    turn right;
    drill forward;

    turn back;
    doN 2 move;
    turn back;
    end;

/**
Precondition: on first column of fourth row, facing south.
*/
def fixUpperLights =
    a5on <- onInDirection forward;
    if a5on {fixA5} {
        turn left;
        move;
        turn right;
    };

    b5on <- onInDirection forward;
    if b5on {fixB5} {
        turn left;
        move;
        turn right;
    };

    c5on <- onInDirection forward;
    if c5on {fixC5} {
        turn right;
        doN 2 move;
        turn right;
        doN 3 move;
        turn right;
    };


    end;

def go =
    goToCorner;
    chaseUpperLights 5;
    turn left;
    fixUpperLights;
    chaseUpperLights 5;
    end;

go;