-
Notifications
You must be signed in to change notification settings - Fork 0
/
d23.pl
75 lines (68 loc) · 1.95 KB
/
d23.pl
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
#!/usr/bin/perl
# Advent of Code 2015 Day 23 - complete solution
# Problem link: http://adventofcode.com/2015/day/23
# Discussion: http://gerikson.com/blog/comp/adventofcode/Advent-of-Code-2015.html#d23
# License: http://gerikson.com/files/AoC2015/UNLICENSE
###########################################################
use strict;
use warnings;
use feature qw/say/;
my $debug = 0;
my $testing = 0;
my $file = $testing ? 'test.txt' : 'input.txt';
my @tape;
open F, "<$file" or die "can't open file: $!\n";
while (<F>) {
chomp;
s/\r//gm;
my ( $cmd, $reg, $arg ) = ( undef, undef, undef );
if ( $_ =~ m/^(...) (.)$/ ) {
( $cmd, $reg ) = ( $1, $2 );
push @tape, [ $cmd, $reg, undef ];
} elsif ( $_ =~ m/^(...) (.), ([-+]\d+)$/ ) {
( $cmd, $reg, $arg ) = ( $1, $2, $3 );
push @tape, [ $cmd, $reg, $arg ];
} elsif ( $_ =~ m/^(...) ([-+]\d+)$/ ) {
( $cmd, $arg ) = ( $1, $2 );
push @tape, [ $cmd, undef, $arg ];
} else {
die "cannot parse: $_ \n";
}
}
close F;
my $pos = 0;
my %reg = ( a => 0, b => 0 );
while ( $pos >= 0 and $pos <= $#tape ) {
my @input = @{ $tape[$pos] };
say "$pos: a=$reg{a} b=$reg{b} : ",
join( ' ', map { $_ ? $_ : ' ' } @input )
if $debug;
my ( $cmd, $var, $offset ) = @input;
if ( $cmd eq 'inc' ) {
$reg{$var}++;
$pos++;
} elsif ( $cmd eq 'tpl' ) {
$reg{$var} = $reg{$var} * 3;
$pos++;
} elsif ( $cmd eq 'hlf' ) {
$reg{$var} = $reg{$var} / 2;
$pos++;
} elsif ( $cmd eq 'jmp' ) {
$pos += $offset;
} elsif ( $cmd eq 'jie' ) {
if ( $reg{$var} % 2 == 0 ) {
$pos += $offset;
} else {
$pos++;
}
} elsif ( $cmd eq 'jio' ) {
if ( $reg{$var} == 1 ) {
$pos += $offset;
} else {
$pos++;
}
} else {
die "can't recognise cmd: $cmd\n";
}
}
say "a=$reg{a}, b=$reg{b}";