4 # use Math::BigInt lib => 'GMP';
5 # Math::BigInt->precision(64);
6 # say Math::BigInt->precision();
8 my ($pos, $ncards, $iters) = # @ARGV;
9 # (2020, 119315717514047, 0);
10 (2020, 119315717514047, 101741582076661);
14 # (42, 2147483647, 0);
15 # (42, 8589935681, 0);
17 $ncards = Math::BigInt->new($ncards);
19 chomp(my @cmds = <STDIN>);
25 for my $i (0 .. $#cmds-1) {
26 my $r = $cmds[$i].";".$cmds[$i+1];
27 if ($r =~ /new stack.*new stack/) {
31 if ($r =~ /cut (-?\d+);cut (-?\d+)/) {
35 'cut ' . (($ncards+$n1+$n2) % $ncards);
38 if ($r =~ /increment (\d+);.*increment (\d+)\z/) {
42 'deal with increment ' . (($n1*$n2) % $ncards);
45 # Try to move "cut" down and possibly merge it
46 if ($r =~ /cut (-?\d+);.*new stack/) {
49 'deal into new stack',
53 if ($r =~ /cut (-?\d+);.*increment (\d+)\z/) {
57 'deal with increment ' . ($n2),
58 'cut ' . (($n1*$n2) % $ncards);
61 if ($r =~ /new stack;.*increment (\d+)\z/) {
64 'deal with increment ' . ($ncards-$n1),
69 # say "=====\nReturning:\n", join("\n", @cmds);
73 my $loops = $ncards-1;
76 while ((1 << $n) <= $loops) {
77 @cmds = simplify(@cmds);
78 $repeated_cmds[$n] = [ @cmds ];
80 @cmds = (@cmds, @cmds);
84 my ($cmds, $pos) = @_;
89 $pos = $ncards-1-$pos;
90 } elsif (/increment (\d+)/) {
93 } elsif (/cut (\d+)/) {
96 } elsif (/cut (-\d+)/) {
104 my $l = $ncards - 1 - $iters;
108 # say "1 << $n == $two, rem $l";
110 push @r, @{ $repeated_cmds[$n] };
115 say "Rules\n", join("\n", @r);
116 say apply(\@r, $pos);