Beefy Boxes and Bandwidth Generously Provided by pair Networks
Problems? Is your data what you think it is?
 
PerlMonks  

Vertical number representation for Turing Machine tape display?

by eric.foxx (Novice)
on Sep 20, 2008 at 21:55 UTC ( [id://712774]=perlquestion: print w/replies, xml ) Need Help??

eric.foxx has asked for the wisdom of the Perl Monks concerning the following question:

I am creating a quite complex format that will show the tape contents of a Turing Machine. I want to be able to show the user where on the tape we are, in a cleanly formatted area above the tape itself. Here is an 80-column example (truncated to save other monks' weary eyes):

5-state machine, theoretical max steps: >47,176,870 Step: 630 Current delta: 54 ---------------------------------------------------------------------- +------------ 1 2 + 2 8 9 0 1 2 3 4 5 + 6 6 4567890123456789012345678901234567890123456789001234567890123456789012 +345678901234 ----------------------------------------v----------------------------- +------------ 1 11 1 1 1 11 111 1 + 11

I have looked at many of the usual subjects on this topic, including perlform and Sage's Perl Practicum, but it may just be possible that I'm the first weirdo to need something like this!

Right now, I'm taking the log(10) of the largest number (264 in this example) to determine how many lines the numbers will take up vertically. After that, I have to compose the format dynamically and eval it later. Is this the best way? Any better ideas or refinements?

Replies are listed 'Best First'.
Re: Vertical number representation for Turing Machine tape display?
by BrowserUk (Patriarch) on Sep 20, 2008 at 23:55 UTC

    Maybe something like this?

    Update: Added full number at each end to improve visualisation of locality.

    #! perl -slw use strict; sub log10{ log( $_[0] ) / log( 10 ) } sub tape { my( $start, $end ) = @_; my $n = log10( $end ); my @lines = split '', $start; for my $p ( $start + 1 .. $end -1 ) { for my $l ( 0 .. $n ) { $lines[ $n - $l ] .= $p % 10**$l ? ' ' : substr int( $p / 10**$l ), -1; } } $lines[ $_ ] .= substr $end, $_, 1 for 0 .. length( $end ) -1; unshift @lines, '-' x ( $end - $start + 1 ); push @lines, '-' x ( $end - $start ); substr $lines[ -1 ], ( $end - $start ) / 2, 0, 'v'; return @lines; } print for tape( 170, 230 ); print for tape( 1970, 2030 ); print for tape( 39_999_963, 40_000_041 ); __END__ c:\test>712774.pl ------------------------------------------------------------- 1 2 2 7 8 9 0 1 2 3 0123456789012345678901234567890123456789012345678901234567890 ------------------------------v------------------------------ ------------------------------------------------------------- 1 2 2 9 0 0 7 8 9 0 1 2 3 0123456789012345678901234567890123456789012345678901234567890 ------------------------------v------------------------------ ---------------------------------------------------------------------- +--------- 3 4 + 4 9 0 + 0 9 0 + 0 9 0 + 0 9 0 + 0 9 0 + 0 6 7 8 9 0 1 2 3 + 44 3456789012345678901234567890123456789012345678901234567890123456789012 +345678901 ---------------------------------------v------------------------------ +---------

Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
"Science is about questioning the status quo. Questioning authority".
In the absence of evidence, opinion is indistinguishable from prejudice.
Re: Vertical number representation for Turing Machine tape display?
by blokhead (Monsignor) on Sep 20, 2008 at 23:53 UTC
    The pattern is that the nth row from the bottom (starting with n=0) is made by repeating the sequence "0x1x2x...8x9x", where x is a string of 10n-1 spaces.
    use POSIX 'ceil'; sub tape_label { my $len = shift() + 1; ## simpler since we'll start at 0 my @cols; my $n_cols = ceil( log($len) / log(10) ); for my $log (0 .. $n_cols-1) { my $pad = 10**$log - 1; my $pattern = join( " " x $pad, 0 .. 9, "" ); unshift @cols, substr( $pattern x ceil($len/10**$log), 0, $len ) +; } return @cols; }
    But keep in mind, when things get into the thousands, your 1000s digit will only show up every 1000 characters, so it'll be easy to get "lost" on your TM tape.

    BTW, I think a "ruler" style marking would be easier to read than a long string of "01234567890123456789" ...

    use POSIX 'ceil'; sub tape_label { my $len = 5 * ceil(shift() / 5); my $l1 = join "", map { sprintf "%-10s", $_*10 } 0 .. ($len/10); my $l2 = "|" . ("....|" x ($len/5)); return "$l1\n$l2\n"; }
    0 10 20 30 40 50 |....|....|....|....|....|....|....|....|....|....|

    blokhead

Re: Vertical number representation for Turing Machine tape display?
by GrandFather (Saint) on Sep 20, 2008 at 23:52 UTC

    Without using format you could:

    use strict; use warnings; my $tape = bless { desc => "5-state machine, theoretical max steps: >47,176,870", step => 630, delta => 54, pos => 224, cells => [], }; push @{$tape->{cells}}, int rand (1.7) || ' ' for 1 .. 500; $tape->show (82); print <<ORG; 5-state machine, theoretical max steps: >47,176,870 Step: 630 Current delta: 54 ---------------------------------------------------------------------- +----------­- 1 2 + 2 8 9 0 1 2 3 4 5 + 6 6 4567890123456789012345678901234567890123456789001234567890123456789012 +345678901234 ----------------------------------------v----------------------------- +----------­- 1 11 1 1 1 11 111 1 + 11 ORG sub show { my ($tape, $width) = @_; my $first = int ($tape->{pos} - $width / 2); my $last = $first + $width - 1; my $mag = int (log ($last) / log (10)) + 1; my $divider = '-' x $width; $first = sprintf '%0*d', $mag, $first; $last = sprintf '%0*d', $mag, $last; printf "%66s\n", $tape->{desc}; print "Step: $tape->{step}\n"; print "Current delta: $tape->{delta}\n"; print $divider, "\n"; for my $digit (0 .. $mag - 1) { my $lastDigit = -1; my $row; for my $num ($first .. $last) { my $newDigit = substr sprintf ("%${mag}d", $num), $digit, +1; $row .= $num != $last && $newDigit eq $lastDigit ? ' ' : $ +newDigit; $lastDigit = $newDigit; } print "$row\n"; } substr $divider, $width / 2, 1, 'v'; print $divider, "\n"; print @{$tape->{cells}}[$first .. $last], "\n"; }

    Prints:

    5-state machine, theoretical max steps: >47,176,870 Step: 630 Current delta: 54 ---------------------------------------------------------------------- +------------ 1 2 + 2 8 9 0 1 2 3 4 5 + 6 6 3456789012345678901234567890123456789012345678901234567890123456789012 +345678901234 -----------------------------------------v---------------------------- +------------ 11 1 1 1 1 1 1 1 11 11 1 111 11 1 11 11 1 1 + 111 1 11 5-state machine, theoretical max steps: >47,176,870 Step: 630 Current delta: 54 ---------------------------------------------------------------------- +----------­- 1 2 + 2 8 9 0 1 2 3 4 5 + 6 6 4567890123456789012345678901234567890123456789001234567890123456789012 +345678901234 ----------------------------------------v----------------------------- +----------­- 1 11 1 1 1 11 111 1 + 11

    Perl reduces RSI - it saves typing
Re: Vertical number representation for Turing Machine tape display?
by eric.foxx (Novice) on Sep 21, 2008 at 00:42 UTC
    Thank you, everyone! I'm going to get started right away applying all of these great ideas!

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://712774]
Approved by GrandFather
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others pondering the Monastery: (4)
As of 2024-04-19 06:23 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found