Skip to content

Instantly share code, notes, and snippets.

@ggoebel
Created December 23, 2020 21:01
Show Gist options
  • Save ggoebel/b14e7db7895bb38923dd44c9279ca345 to your computer and use it in GitHub Desktop.
Save ggoebel/b14e7db7895bb38923dd44c9279ca345 to your computer and use it in GitHub Desktop.
AoC 2020 Day 14
#!/usr/bin/env raku
use v6.d;
#use Grammar::Tracer;
my $input = 'input'.IO.slurp;
grammar PCS {
rule TOP { [ <update> | <write> ]+ }
rule update { <.maskpre> <mask> }
rule write { <.memd> <loc> <.mema> <val> }
token maskpre { 'mask = ' }
token mask { <[X01]>+ }
token memd { 'mem[' }
token mema { '] = ' }
token loc { \d+ }
token val { \d+ }
}
class PCSActions {
has $!stack = [];
has $!mask = [];
has $!store = {};
method update($/) { $!stack.push( 'update' => ~$<mask> ) }
method write($/) { $!stack.push( $<loc>.Int => $<val>.Int )}
# method gist { say $!stack.join("\n") }
method exec {
for $!stack.list -> $i {
given $i.key {
when 'update' {
$!mask = $i.value.comb;
# say "mask: " ~ $!mask;
}
default {
my ($loc, $val) = ($i.key, $i.value);
my $value = ['%036b'.sprintf($val).comb];
self.masked_write($loc, $value);
}
}
}
self.sum;
}
method sum {
$!store.values.map({ .join('').parse-base(2).base(10) }).sum;
}
method masked_write($loc, $value) {
my $store = [ |map({ 0 }, @(0..35)) ];
# say "loc: $loc";
# say "value: {@$value}";
# say "mask: {$!mask}";
for 0..35 -> $i {
given $!mask[$i] {
when 'X' { $store[$i] = $value[$i] }
default { $store[$i] = $!mask[$i] }
}
}
# say "store: {@$store}";
$!store{$loc} = $store;
}
}
class PCSActions2 {
has $!stack = [];
has $!mask = [];
has $!store = {};
method update($/) { $!stack.push( 'update' => ~$<mask> ) }
method write($/) { $!stack.push( $<loc>.Int => $<val>.Int )}
# method gist { say $!stack.join("\n") }
method exec {
for $!stack.list -> $i {
given $i.key {
when 'update' {
$!mask = $i.value.comb;
# say "mask: " ~ $!mask;
}
default {
my ($loc, $val) = ($i.key, $i.value);
my $value = ['%036b'.sprintf($val).comb];
self.masked_write($loc, $value);
}
}
}
self.sum;
}
method masked_write($loc, $value) {
my $addr = ['%036b'.sprintf($loc).comb];
for 0..35 -> $i {
given $!mask[$i] {
when 'X' { $addr[$i] = 'X' }
when '1' { $addr[$i] = $!mask[$i] }
}
}
my @sp_addr; # flattened floating addresses
my @addr = ($addr);
OUTSIDE: for @addr -> $a {
for 0 .. 35 -> $i {
if $a[$i] eq 'X' {
my $f0 = [ $a.list.map({ $_ })]; $f0[$i] = 0;
my $f1 = [ $a.list.map({ $_ })]; $f1[$i] = 1;
@addr.push($f0, $f1);
next OUTSIDE;
}
}
@sp_addr.push($a);
}
for @sp_addr -> $a {
my $str = $a.join('').parse-base(2).base(10);
$!store{$str} = $value;
}
}
method sum {
$!store.values.map({ .join('').parse-base(2).base(10) }).sum;
}
}
my $a = PCSActions.new();
PCS.parse($input, :actions($a));
say "Part One: " ~ $a.exec;
my $a2 = PCSActions2.new();
PCS.parse($input, :actions($a2));
say "Part Two: " ~ $a2.exec;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment