]> www.fi.muni.cz Git - aoc.git/blob - 2018/41.pl
Day 25: examining the input
[aoc.git] / 2018 / 41.pl
1 #!/usr/bin/perl -w
2
3 use v5.36;
4 use strict;
5
6 my @code;
7 my @regs = ((0) x 6);
8 my $ip_reg;
9
10 while(<STDIN>) {
11         if (/\A#ip (\d+)/) {
12                 $ip_reg = $1;
13                 next;
14         }
15         chomp;
16         push @code, [ split /\s+/ ];
17 }
18
19 my $nmachines = shift @ARGV;
20 my @machines;
21 # push @machines, [ ($_, ((0) x 6)) ] for 0 .. $nmachines;
22 push @machines, [ (10961197, ((0) x 6)) ];
23
24 my %seen;
25
26 sub one_step($regs) {
27         my $ip = $regs->[6];
28         my ($op, $a, $b, $c) = @{ $code[$ip] };
29
30         $regs->[$ip_reg] = $ip;
31
32         if ($op eq 'addr') {
33                 $regs->[$c] = $regs->[$a] + $regs->[$b];
34         } elsif ($op eq 'addi') {
35                 $regs->[$c] = $regs->[$a] + $b;
36         } elsif ($op eq 'mulr') {
37                 $regs->[$c] = $regs->[$a] * $regs->[$b];
38         } elsif ($op eq 'muli') {
39                 $regs->[$c] = $regs->[$a] * $b;
40         } elsif ($op eq 'banr') {
41                 $regs->[$c] = $regs->[$a] & $regs->[$b];
42         } elsif ($op eq 'bani') {
43                 $regs->[$c] = $regs->[$a] & $b;
44         } elsif ($op eq 'borr') {
45                 $regs->[$c] = $regs->[$a] | $regs->[$b];
46         } elsif ($op eq 'bori') {
47                 $regs->[$c] = $regs->[$a] | $b;
48         } elsif ($op eq 'setr') {
49                 $regs->[$c] = $regs->[$a];
50         } elsif ($op eq 'seti') {
51                 $regs->[$c] = $a;
52         } elsif ($op eq 'gtrr') {
53                 $regs->[$c] = $regs->[$a] > $regs->[$b] ? 1 : 0;
54         } elsif ($op eq 'gtir') {
55                 $regs->[$c] = $a > $regs->[$b] ? 1 : 0;
56         } elsif ($op eq 'eqrr') {
57                 $regs->[$c] = $regs->[$a] == $regs->[$b] ? 1 : 0;
58         } elsif ($op eq 'eqri') {
59                 $regs->[$c] = $regs->[$a] == $b ? 1 : 0;
60         } elsif ($op eq 'nop') {
61                 
62         } else {
63                 die "Unknown op $ op at $ip";
64         }
65         say join(' ', @{ $code[$ip] }, "\t", @$regs);
66         # $regs->[3] = $ARGV[0] if $ip == 35;
67         $regs->[6] = $regs->[$ip_reg] + 1;
68         
69 #       if ($seen{join(',', @$regs)}++) {
70 #               say "seen";
71 #               $regs->[6] = -1;
72 #               return 0;
73 #       }
74         if ($regs->[6] >= @code) {
75                 say "halts";
76                 return 1;
77         } else {
78                 return undef;
79         }
80 }
81
82 my $step = 0;
83 while (1) {
84         say "step ", ++$step;
85         for my $m (0 .. $#machines) {
86                 next if $machines[$m]->[6] == -1;
87                 # say "machine $m";
88                 if (one_step($machines[$m])) {
89                         say "Machine $m halts after ste $step";
90                         exit 0;
91                 }
92         }
93 }
94