root/examples/matrix-p5.pl

Revision 13741, 2.2 kB (checked in by audreyt, 2 years ago)

* Massive cleanup: qw() and q() is no longer quotes but functions,

and q:to/END/ is now expression-level construct.

  • Property svn:mime-type set to text/plain; charset=UTF-8
  • Property svn:eol-style set to native
Line 
1#!/usr/bin/perl -w
2
3use List::Util <sum>;
4use strict;
5
6print "5x5 matrix in one line: " unless @ARGV;
7my $matrix = shift || <>;
8chomp $matrix;
9$matrix ||= "abcdefghijklmnopqrstuvwxy";
10my @matrix = [ ('_') x 7 ];
11push @matrix, [ '_', (split //, substr $matrix, 0, 5, ''), '_' ] while $matrix;
12push @matrix, [ ('_') x 7 ];
13
14my @adj;
15
16for my $y (1..5) {
17    for my $x (1..5) {
18        for my $dx (-1..1) {
19            for my $dy (-1..1) {
20                $dy or $dx or next;
21                $matrix[$y + $dy][$x + $dx] eq '_' and next;
22                push @{ $adj[$y][$x] }, { y => $y + $dy, x => $x + $dx };
23            }
24        }
25    }
26}
27
28sub build_re {
29    my ($y, $x, $todo, $had) = @_;
30    my $r = $matrix[$y][$x] or die "y=$y,x=$x is empty (@_)";
31    --$todo or return $r;
32    my %had = $had ? %$had : ("$y/$x" => 1);  # copy
33   
34    my @next = map {
35        $had{"$_->{y}/$_->{x}"}++
36            ? ()
37            : build_re($_->{y}, $_->{x}, $todo, \%had)
38    } @{ $adj[$y][$x] };
39
40    @next or return $r;
41
42    return $todo == 1
43        ? $r . (@next == 1 ? "@next?" : '[' . join('', @next) . ']?')
44        : $r . '(?:' . join('|', @next) . ')' . ($todo < 4 ? '?' : '');
45}
46
47my @re;
48
49for my $y (1..5) {
50    for my $x (1..5) {
51        push @re, build_re $y, $x, 6;
52    }
53}
54
55my $re = join '|', @re;
56$re = "^(?:$re)\\z";  # Don't compile yet - once is enough
57
58my %scores = (
59  a => 1, b => 3, c => 3, d => 2, e => 1, f => 4, g => 2, h => 4, i => 1,
60  j => 8, k => 5, l => 1, m => 3, n => 1, o => 1, p => 3, q =>10, r => 1,
61  s => 1, t => 1, u => 1, v => 4, w => 4, x => 8, y => 4, z =>10
62);
63$_ *= 10 for values %scores;
64
65my @matches;
66open my $fh, '/usr/share/dict/american-english' or die $!;
67
68substr(join('', @{ $matrix[1] }), 1, 5) =~ /$re/ or die;  # Precompile
69while (<$fh>) {
70    $_ .= chomp;
71    next if tr/a-z//c;  # Regex would destroy the compiled one
72    // and push @matches, [ $_, sum map $scores{$_}, split // ];
73        # Re-use precompiled regex
74}
75
76my @sorted = sort {
77    $b->[1] <=> $a->[1]                   # high score .. low score
78    || length $a->[0] <=> length $b->[0]  # short .. long
79    || $a->[0] cmp $b->[1]                # a .. z
80} @matches;
81
82printf "MATRIX IS WORTH %d POINTS\n", sum map $_->[1], @sorted;
83printf "%3d %s\n", $_->[1], $_->[0] for @sorted;
Note: See TracBrowser for help on using the browser.