Kickin' it old school

I'm sure you remember the good ol' days of typing programs straight out of a book hoping to see something which looks like this:

                     *
                 *   *  *
              *  *   *  *   *
          *   *  *   *  *   *  *
          *   *  *   *  *   *  *
          *   *  *   *  *   *  *
       *  *   *  *   *  *   *  *   *
       *  *   *   *  *   *  *  *   *
       *  *   *   *   *  *  *  *   *
   *   *  *   *    *  *   * *  *   *  *
   *   *  *    *   *    * *  * *   *  *
   *   *   *   *     *   *  **  *  *  *
   *   *   *    *      *    * * *  *  *
   *   *   *     *       *    * *  *  *
   *   *   *      *        *      **  *
   *   *    *       *         *       *
   *   *    *        *           *       *
   *   *     *         *            *        *
   *   *     *          *             *         *
   *   *     *          *               *         *
*  *   *     *           *              *          *
   *   *     *          *               *         *
   *   *     *          *             *         *
   *   *     *         *            *        *
   *   *    *        *           *       *
   *   *    *       *         *       *
   *   *   *      *        *      **  *
   *   *   *     *       *    * *  *  *
   *   *   *    *      *    * * *  *  *
   *   *   *   *     *   *  **  *  *  *
   *   *  *    *   *    * *  * *   *  *
   *   *  *   *    *  *   * *  *   *  *
       *  *   *   *   *  *  *  *   *
       *  *   *   *  *   *  *  *   *
       *  *   *  *   *  *   *  *   *
          *   *  *   *  *   *  *
          *   *  *   *  *   *  *
          *   *  *   *  *   *  *
              *  *   *  *   *
                 *   *  *
                     *

Here's that code translated to Perl.

#!/usr/bin/env perl                                                                                                         

use strict;
use warnings;

# http://www.atariarchives.org/basicgames/showpage.php?page=167
use List::Util 'max';

my $r = 30;
my @f = (
    sub { $r * exp( -$_[0]**2 / 100 ) },
    sub { $r * ( cos( $_[0] / 16 ) + 2 ) },
    sub { $r - $r * sin( $_[0] / 18 ) },
    sub { $r * exp( -cos( $_[0] / 16 ) ) - $r },
    sub { $r * sin( $_[0] / 10 ) },
);

my $f = $f[ rand @f ];

for my $x ( 0 .. ( $r * 2 ) / 1.5 ) {
    $x = $x * 1.5 - $r;
    my $l  = 0;
    my $y1 = 5 * int( sqrt( $r**2 - $x * $x ) / 5 );
    my @line;
    for ( 0 .. ( $y1 * 2 ) / 5 ) {
        my $y = -( ( $_ * 5 ) - $y1 );
        my $z = int( 25 + $f->( sqrt( $x * $x + $y * $y ) ) - .7 * $y );
        next if $z <= $l;
        $l = $z;
        push @line => $z;
    }
    my $string = ' ' x max @line;
    substr $string, $_, 1, '*' foreach @line;    # PRINT TAB(Z);"*";
    print "$string\n";
}

Or translate your own!

2 Comments

Kinda reminds me of Text::AsciiTeX. Ascii Science UNITE!

Neat! I did Nicomachus. I moved the "yes or no" logic into a subroutine and re-used it for the "try another". Otherwise, I guess we'd have to hit C-c to exit.

#!/usr/bin/env perl

# http://www.atariarchives.org/basicgames/showpage.php?page=117

use v5.12;
use warnings;
use Term::ReadLine;

my $term = Term::ReadLine->new('Nicomachus');
$term->ornaments(0);

say 'Boomerang puzzle from Arithmetica of Nicomachus -- A.D. 90!';
while (1) {
    say 'Please think of a number between 1 and 100.';
    my %rem;
    for my $d (3, 5, 7) {
        my $prompt = "Your number divided by $d has a remainder of: ";
        $rem{$d} = $term->readline($prompt);
    }

    say 'Let me think a moment...';
    sleep 1;

    my $d = (70 * $rem{3} + 21 * $rem{5} + 15 * $rem{7}) % 105;
    say yes_or_no("You're number was $d, right? ")
        ? 'How about that!!'
        : 'I feel your arithmetic is in error.';

    exit unless yes_or_no('Try another? ');
}

sub yes_or_no {
    my $prompt = shift;
    
    while (1) {
        given ($term->readline($prompt)) {
            when (/^y/i) {return 1}
            when (/^n/i) {return}
            default {
                $prompt = "Eh? I don't understand '$_'."
                          ." Try 'yes' or 'no'. ";
            }
        }
    }
}

Leave a comment

About Ovid

user-pic Have Perl; Will Travel. Freelance Perl/Testing/Agile consultant. Photo by http://www.circle23.com/. Warning: that site is not safe for work. The photographer is a good friend of mine, though, and it's appropriate to credit his work.