/
a14.tt
99 lines (84 loc) · 2.47 KB
/
a14.tt
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
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
use 'hash' stand-alone
data value <"1">,
address <"1">
templates setMask
@: [x00x] -> $(-3..1);
$... -> #
$@!
when <='1'> do @: $@::shift&{left: 1, fill: [x80x]};
otherwise @: $@::shift&{left: 1, fill: [x00x]};
end setMask
templates clearMask
@: [xffx] -> $(-3..1);
$... -> #
$@!
when <='0'> do @: $@::shift&{left: 1, fill: [x7fx]};
otherwise @: $@::shift&{left: 1, fill: [xffx]};
end clearMask
composer parseLine
<mask|set>
rule mask: (<='mask = '>) <'.{36}'> -> {set: $ -> setMask, clear: $ -> clearMask}
rule set: (<='mem['>) {address: <INT"1">, (<='] = '>) value: <INT"1">}
end parseLine
def dockingProgram: [$IN::lines -> parseLine];
sink debugPrint
'$.mask.set; $.mask.clear;
$.memory... ... -> '$::asInteger -> \(<1..> '$; '!\);';
' -> !OUT::write
end debugPrint
templates getBit
def pos: $;
[x00 00 00 00 01x] -> $::shift&{left: $pos, fill: [x00x]} !
end getBit
templates run&{v2:}
@:{memory:[] -> hash/Map&{key: :(address:), value: :(value:)}, mask:{set: [x00x], clear: [xffx]}};
$... -> #
$@.memory -> \(
@: 0"1";
$::entries -> $.value -> @: $@ + $;
$@!
\)!
when <´{}´ {set: <>}> do @.mask: $;
when <?($v2 <=0>)> do
// $@ -> !debugPrint
{address: $.address, value: ((($.value::asBytes and $@.mask.clear) or $@.mask.set) -> $::asInteger)"1"} -> @.memory::put -> !VOID
otherwise
def instruction: $;
def floating: (($@.mask.set xor $@.mask.clear) and [x 0f ffff ffff x]);
[0..35 -> getBit] -> \floats(
@:[($instruction.address::asBytes or $@run.mask.set)];
$... -> #
$@... !
when <?(($ and $floating) <=$>)> do
def bit: $;
@: [$@... -> \(($ or $bit)! ($ and $bit::inverse)!\)];
\floats) -> $::asInteger -> \(
{address: ($)"1", value: $instruction.value} -> @run.memory::put -> !VOID
\) -> !VOID
end run
test 'part 1'
def input: [
'mask = XXXXXXXXXXXXXXXXXXXXXXXXXXXXX1XXXX0X',
'mem[8] = 11',
'mem[7] = 101',
'mem[8] = 0'
];
def program: [$input... -> parseLine];
assert $program -> run&{v2:0} <=165> 'runs correctly'
end 'part 1'
def part1: $dockingProgram -> run&{v2:0};
'$part1;
' -> !OUT::write
test 'part 2'
def input: [
'mask = 000000000000000000000000000000X1001X',
'mem[42] = 100',
'mask = 00000000000000000000000000000000X0XX',
'mem[26] = 1'
];
def program: [$input... -> parseLine];
assert $program -> run&{v2:1} <=208> 'runs correctly'
end 'part 2'
def part2: $dockingProgram -> run&{v2:1};
'$part2;
' -> !OUT::write