#!/usr/bin/perl

use strict;
use warnings;

my ($filename, $input) = @ARGV;
die "Usage: $0 filename [input]" if !defined $filename or @ARGV > 2;

my (%table, $state, @tape, $head);
my %movehead = (L => -1, R => 1);

open (FH, $filename) or die "Can't open $filename: $!";
while (<FH>) {
  next if !/\S/  or /^\s*#/;
  chomp;
  my ($cur_state, $cur_symbol, $new_state, $new_symbol, $dir) = /^\s*(\w+)\s+(\w)\s+(\w+)\s+(\w)\s+(L|R)(?:\s*#.*)?/
    or die "Bad instruction at $filename line $.: $_";
  $state = $cur_state unless defined $state;
  $table{$cur_state, $cur_symbol} = [$new_state, $new_symbol, $movehead{$dir}];
}
close (FH);
die "No instructions present in $filename" unless defined $state;

@tape = defined $input ? split //, $input : ('_');
$head = 0;

while (defined (my $instruction = $table{$state, $tape[$head]})) {
  my $move;
  ($state, $tape[$head], $move) = @$instruction;
  $head += $move;
  push @tape, '_' if $head > $#tape; # grow tape to the right
  unshift @tape, '_' and $head++ if $head < 0; # grow tape to the left
}

shift @tape while @tape and $tape[0] eq '_';
pop @tape while @tape and $tape[-1] eq '_';
print join '', @tape, "\n";




 
