Advertisement
Zemyla

SpaceChem Loop Calculator

Sep 26th, 2012
392
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Perl 1.70 KB | None | 0 0
  1. #!/usr/bin/perl -w
  2.  
  3. use strict;
  4.  
  5. my $MAXF = $ARGV[0] ? int $ARGV[0] : 7;
  6. $MAXF = 7 unless $MAXF;
  7.  
  8. package Loop;
  9.  
  10. sub new {
  11.     my $class = shift;
  12.     $class = ref $class if ref $class;
  13.     my @t = @_;
  14.  
  15.     for my $i (0..$#t) {
  16.         die sprintf "Invalid index: %d at %d\n", $t[$i], $i + 1
  17.             unless $t[$i] <= $i;
  18.     }
  19.  
  20.     my $obj = \@t;
  21.     bless $obj, $class
  22. }
  23.  
  24. sub str {
  25.     my $obj = shift;
  26.     sprintf '[%s]', (join ', ', @$obj)
  27. }
  28.  
  29. sub len {
  30.     my $obj = shift;
  31.     @$obj
  32. }
  33.  
  34. sub period {
  35.     my $obj = shift;
  36.     my @t = @$obj;
  37.     my @s = map { 0 } 0..$#t;
  38.     my $n = 1;
  39.     my $c = 0;
  40.    
  41.     while (1) {
  42.         if ($s[$c]) {
  43.             $s[$c] = 0;
  44.             last if ++$c == @t;
  45.         } else {
  46.             $s[$c] = 1;
  47.             my $v = $t[$c];
  48.             if ($v) {
  49.                 $c = $v - 1;
  50.             } else {
  51.                 $n++;
  52.                 $c = 0;
  53.             }
  54.         }
  55.     }
  56.  
  57.     $n
  58. }
  59.  
  60. package main;
  61.  
  62. sub expls(@) {
  63.     my @pls = @_;
  64.     return ([0]) unless @pls;
  65.     my $cf = @{$pls[$#pls]};
  66.     my @els = grep { @$_ == $cf } @pls;
  67.  
  68.     for my $l (@els) {
  69.         for my $n (0..$cf) {
  70.             push @pls, [ @$l, $n ]
  71.         }
  72.     }
  73.  
  74.     @pls
  75. }
  76.  
  77. sub mkls($) {
  78.     my $maxf = shift;
  79.     my @ls;
  80.  
  81.     @ls = expls @ls for 1..$maxf;
  82.  
  83.     map { Loop->new(@$_) } @ls
  84. }
  85.  
  86. my @ls = mkls $MAXF;
  87.  
  88. my %mloop;
  89.  
  90. my $len = 1;
  91. for my $l (@ls) {
  92.     $len = $l->len, print "\n" if $l->len != $len;
  93.     my $p = $l->period;
  94.     printf "%s = %d\n", $l->str, $p;
  95.     $mloop{$p} = $l->str unless exists $mloop{$p};
  96. }
  97.  
  98. print "\n\n";
  99.  
  100. printf "%d = %s\n", $_, $mloop{$_} for sort {$a <=> $b} keys %mloop;
  101.  
  102. 1;
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement