]> www.fi.muni.cz Git - aoc.git/blobdiff - 2020/46.pl
Mods from 2020
[aoc.git] / 2020 / 46.pl
index b9744b865bcf9f2e4924787bb5d292809082e217..360edb7cb289f8bebf22211c58bcd1364ff7d182 100755 (executable)
@@ -2,74 +2,51 @@
 
 use strict;
 
-my $rounds;
-($rounds, $_) = @ARGV;
-
-my @cups_nums = split //;
-my @cups_pos;
-my $i;
-for (@cups_nums) {
-       $cups_pos[$_] = $i++;
-}
-
-my $max = 1_000_000;
-
-my ($prev, @cups, $one);
-for (@cups_nums, 10 .. $max) {
-       my $cup = {
-               num => $_,
-               prev_num => $prev,
-               next => undef,
-       };
-       push @cups, $cup;
-       $one = $cup if $cup->{num} == 1;
+my ($rounds, $max, $cups) = @ARGV;
+
+my @next_cup = (1 .. $max);
+my $i = 0;
+my $prev = @next_cup - 1;
+my $cur;
+for my $cup (split //, $cups) {
+       $cup--; # count cup numbers from 0, not from 1
+       $next_cup[$prev] = $cup;
        $prev = $cup;
+       $cur //= $cup; # The first one
 }
-
-$prev = $cups[-1];
-for my $cup (@cups) {
-       $cup->{prev_num} = $cups[$cups_pos[$cup->{num}-1]]
-               if $cup->{num} > 1 && $cup->{num} <= 10;
-       $cup->{prev_num} = $cups[-1]
-               if $cup->{num} == 1;
-       $prev->{next} = $cup;
-       $prev = $cup;
-}
-
-# for my $cup (@cups) {
-#      print $cup->{num}, ": >", $cup->{next}->{num}, " <", $cup->{prev_num}->{num}, "\n";
-# }
-
-my $cur = $cups[0];
+# $next_cup[6] = 2;
 
 while ($rounds--) {
        my @pickup;
-       my $cup = $cur->{next};
-       my $dest = $cur->{prev_num};
-       my %num_seen;
+       my $cup = $next_cup[$cur];
+       my %num_seen = ($cur => 1);
        # print "pickup: ";
        for (1..3) {
                push @pickup, $cup;
-               $num_seen{ $cup->{num} } = 1;
-               # print $cup->{num}, ' ';
-               $cup = $cup->{next};
+               $num_seen{ $cup } = 1;
+               # print $cup + 1, ' ';
+               $cup = $next_cup[$cup];
        }
-       $dest = $dest->{prev_num} while $num_seen{$dest->{num}};
-       # print " dest: ", $dest->{num}, "\n";
-       $cur->{next} = $cup;
-       my $end = $dest->{next};
-       $dest->{next} = $pickup[0];
-       $pickup[-1]->{next} = $end;
-
-       $cur = $cur->{next};
-       # $end = $cur;
+       my $dest = $cur;
+       while ($num_seen{$dest}) {
+               $dest--;
+               $dest = $max-1 if $dest < 0;
+       }
+       # print " dest: ", $dest + 1, "\n";
+       $next_cup[$cur] = $cup;
+       my $end = $next_cup[$dest];
+       $next_cup[$dest] = $pickup[0];
+       $next_cup[$pickup[-1]] = $end;
+
+       $cur = $next_cup[$cur];
+       $end = $cur;
        # do {
-       #       print $end->{num}, ',';
-       #       $end = $end->{next};
-       # } while ($end->{num} != $cur->{num});
+       #       print $end+1, ',';
+       #       $end = $next_cup[$end];
+       # } while ($end != $cur);
        # print "\n";
        print "round $rounds\n" if $rounds % 100_000 == 0;
 }
 
-print "one -> ", $one->{next}->{num}, '*', $one->{next}->{next}->{num},
-       "=", $one->{next}->{num} * $one->{next}->{next}->{num}, "\n";
+print "one -> ", $next_cup[0] + 1, '*', $next_cup[$next_cup[0]] + 1,
+       "=", ($next_cup[0]+1) * ($next_cup[$next_cup[0]]+1), "\n";