Re: [SPOILER] turning machine solution

John Macdonald <john-Z7w/En0MP3xWk0Htik3J/[email protected]> Fri, 17 Sep 2004 12:50:31 -0400
Newsgroups gmane.comp.lang.perl.qotw.discuss
Message-ID <[email protected]>
On Fri, Sep 17, 2004 at 10:43:45AM -0400, Colin Rafferty wrote:
> I thought that the most interesting part of the design was the tape.

Me too.  I haven't written code for the rest of the quiz
(it would overlap significantly with many already posted),
but for the tape I would use 2 arrays and a read head.

my @tape_left, @tape_right;
my $head = '_';

sub goleft {
    unshift @tape_right, $head if @tape_right && $head ne '_';
    $head = @tape_left ? (pop @tape_left) : '_';
}

sub goright {
    push @tape_left, $head if @tape_left && $head ne '_';
    $head = @tape_right ? (shift @tape_right) : '_';
}

sub gonowhere {		# aka IEHBR14 for dinosaurs :-)
}

sub displaytape {
    "@tape_left$head@tape_right\n";
}

sub filltape {
    my $init = shift;
    $init =~ s/_*$//;
    @tape_right = split //, $init;
    goright;
}

sub writesymbol {
    $head = shift;
}

# using MJD's N means no move extension
my %moveaction = (
    L => &goleft,
    R => &goright,
    N => &gonowhere,
);

sub applychanges {
    my( $newstate, $newsymbol, $movement ) = @_;
    $state = $newstate;

    # to support '*' as 'do not overwrite', use the commented form
    writesymbol( $newsymbol );
    # writesymbol( $newsymbol ) unless $newsymbol eq '*';

    $moveaction{$movement}->();
}

(In practice, I'd write the code for applychanges and
writesymbol in place rather than making them explicit
subroutines.)

--