Skip to content

Commit c67ec81

Browse files
committed
day 24
1 parent a421bc2 commit c67ec81

File tree

9 files changed

+818
-58
lines changed

9 files changed

+818
-58
lines changed

.vscode/launch.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
"preLaunchTask": "build",
1313
// If you have changed target frameworks, make sure to update the program path.
1414
"program": "${workspaceFolder}/bin/Debug/net6.0/adventofcode.dll",
15-
"args": ["today"],
15+
"args": ["2021/24"],
1616
"cwd": "${workspaceFolder}",
1717
// For more information about the 'console' field, see https://github.com/OmniSharp/omnisharp-vscode/blob/master/debugger-launchjson.md#console-terminal-window
1818
"console": "internalConsole",

2021/Day24/README.md

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
original source: [https://adventofcode.com/2021/day/24](https://adventofcode.com/2021/day/24)
2+
## --- Day 24: Arithmetic Logic Unit ---
3+
[Magic smoke](https://en.wikipedia.org/wiki/Magic_smoke) starts leaking from the submarine's [arithmetic logic unit](https://en.wikipedia.org/wiki/Arithmetic_logic_unit) (ALU). Without the ability to perform basic arithmetic and logic functions, the submarine can't produce cool patterns with its Christmas lights!
4+
5+
It also can't navigate. Or run the oxygen system.
6+
7+
Don't worry, though - you <em>probably</em> have enough oxygen left to give you enough time to build a new ALU.
8+
9+
The ALU is a four-dimensional processing unit: it has integer variables <code>w</code>, <code>x</code>, <code>y</code>, and <code>z</code>. These variables all start with the value <code>0</code>. The ALU also supports <em>six instructions</em>:
10+
11+
12+
- <code>inp a</code> - Read an input value and write it to variable <code>a</code>.
13+
- <code>add a b</code> - Add the value of <code>a</code> to the value of <code>b</code>, then store the result in variable <code>a</code>.
14+
- <code>mul a b</code> - Multiply the value of <code>a</code> by the value of <code>b</code>, then store the result in variable <code>a</code>.
15+
- <code>div a b</code> - Divide the value of <code>a</code> by the value of <code>b</code>, truncate the result to an integer, then store the result in variable <code>a</code>. (Here, "truncate" means to round the value toward zero.)
16+
- <code>mod a b</code> - Divide the value of <code>a</code> by the value of <code>b</code>, then store the <em>remainder</em> in variable <code>a</code>. (This is also called the [modulo](https://en.wikipedia.org/wiki/Modulo_operation) operation.)
17+
- <code>eql a b</code> - If the value of <code>a</code> and <code>b</code> are equal, then store the value <code>1</code> in variable <code>a</code>. Otherwise, store the value <code>0</code> in variable <code>a</code>.
18+
19+
In all of these instructions, <code>a</code> and <code>b</code> are placeholders; <code>a</code> will always be the variable where the result of the operation is stored (one of <code>w</code>, <code>x</code>, <code>y</code>, or <code>z</code>), while <code>b</code> can be either a variable or a number. Numbers can be positive or negative, but will always be integers.
20+
21+
The ALU has no <em>jump</em> instructions; in an ALU program, every instruction is run exactly once in order from top to bottom. The program halts after the last instruction has finished executing.
22+
23+
(Program authors should be especially cautious; attempting to execute <code>div</code> with <code>b=0</code> or attempting to execute <code>mod</code> with <code>a<0</code> or <code>b<=0</code> will cause the program to crash and might even damage the ALU. These operations are never intended in any serious ALU program.)
24+
25+
For example, here is an ALU program which takes an input number, negates it, and stores it in <code>x</code>:
26+
27+
<pre>
28+
<code>inp x
29+
mul x -1
30+
</code>
31+
</pre>
32+
33+
Here is an ALU program which takes two input numbers, then sets <code>z</code> to <code>1</code> if the second input number is three times larger than the first input number, or sets <code>z</code> to <code>0</code> otherwise:
34+
35+
<pre>
36+
<code>inp z
37+
inp x
38+
mul z 3
39+
eql z x
40+
</code>
41+
</pre>
42+
43+
Here is an ALU program which takes a non-negative integer as input, converts it into binary, and stores the lowest (1's) bit in <code>z</code>, the second-lowest (2's) bit in <code>y</code>, the third-lowest (4's) bit in <code>x</code>, and the fourth-lowest (8's) bit in <code>w</code>:
44+
45+
<pre>
46+
<code>inp w
47+
add z w
48+
mod z 2
49+
div w 2
50+
add y w
51+
mod y 2
52+
div w 2
53+
add x w
54+
mod x 2
55+
div w 2
56+
mod w 2
57+
</code>
58+
</pre>
59+
60+
Once you have built a replacement ALU, you can install it in the submarine, which will immediately resume what it was doing when the ALU failed: validating the submarine's <em>model number</em>. To do this, the ALU will run the MOdel Number Automatic Detector program (MONAD, your puzzle input).
61+
62+
Submarine model numbers are always <em>fourteen-digit numbers</em> consisting only of digits <code>1</code> through <code>9</code>. The digit <code>0</code> <em>cannot</em> appear in a model number.
63+
64+
When MONAD checks a hypothetical fourteen-digit model number, it uses fourteen separate <code>inp</code> instructions, each expecting a <em>single digit</em> of the model number in order of most to least significant. (So, to check the model number <code>13579246899999</code>, you would give <code>1</code> to the first <code>inp</code> instruction, <code>3</code> to the second <code>inp</code> instruction, <code>5</code> to the third <code>inp</code> instruction, and so on.) This means that when operating MONAD, each input instruction should only ever be given an integer value of at least <code>1</code> and at most <code>9</code>.
65+
66+
Then, after MONAD has finished running all of its instructions, it will indicate that the model number was <em>valid</em> by leaving a <code>0</code> in variable <code>z</code>. However, if the model number was <em>invalid</em>, it will leave some other non-zero value in <code>z</code>.
67+
68+
MONAD imposes additional, mysterious restrictions on model numbers, and legend says the last copy of the MONAD documentation was eaten by a [tanuki](https://en.wikipedia.org/wiki/Japanese_raccoon_dog). You'll need to <em>figure out what MONAD does</em> some other way.
69+
70+
To enable as many submarine features as possible, find the largest valid fourteen-digit model number that contains no <code>0</code> digits. <em>What is the largest model number accepted by MONAD?</em>
71+
72+

2021/Day24/Solution.cs

Lines changed: 128 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,128 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Collections.Immutable;
4+
using System.Linq;
5+
using System.Text.RegularExpressions;
6+
using System.Text;
7+
using System.Numerics;
8+
9+
namespace AdventOfCode.Y2021.Day24;
10+
11+
[ProblemName("Arithmetic Logic Unit")]
12+
class Solution : Solver {
13+
14+
public object PartOne(string input) {
15+
var lines = input.Split('\n');
16+
// var k = 0;
17+
// var code0 = "47963957899999";
18+
// Console.WriteLine(Run2("97989681", 0, lines));
19+
Console.WriteLine(Run("96979989681495", 0, lines));
20+
21+
// var code0 = "99999999999999";
22+
// for (var i = BigInteger.Parse(code0); i >= 0; i--) {
23+
// var code = string.Join("", i.ToString());
24+
// if (code.Contains('0')) {
25+
// continue;
26+
// }
27+
// k++;
28+
29+
// try {
30+
// var z = Run2(code, 0, lines);
31+
// if (z == 0) {
32+
// Console.WriteLine(code);
33+
// }
34+
// if (k % 10000 == 0) {
35+
// Console.WriteLine(code);
36+
// }
37+
// } catch (OverflowException) {
38+
39+
// }
40+
// }
41+
return 0;
42+
}
43+
44+
45+
BigInteger Run2(string input, BigInteger z, string[] lines) {
46+
int from = 0;
47+
var ich = 0;
48+
BigInteger step(int iblock, BigInteger z, BigInteger S, BigInteger T, BigInteger U) {
49+
if (z < 0) {
50+
return -1;
51+
}
52+
if (iblock < from || ich >= input.Length) {
53+
return z;
54+
}
55+
var w = input[ich++] - '0';
56+
57+
var x = (z % 26 + T) != w ? 1 : 0;
58+
z = z / S;
59+
return z * (25 * x + 1) + (w + U) * x;
60+
}
61+
var zOrig = z;
62+
z = step(0, z, 1, 12, 1); // 9
63+
z = step(1, z, 1, 13, 9); // 6
64+
65+
z = step(2, z, 1, 12, 11); // 9
66+
z = step(3, z, 26, -13, 6); // 7
67+
68+
z = step(4, z, 1, 11, 6); // 9
69+
z = step(5, z, 1, 15, 13); // 9
70+
z = step(6, z, 26, -14, 13); // 8
71+
72+
z = step(7, z, 1, 12, 5); // 9
73+
z = step(8, z, 26, -8, 7); // 6
74+
75+
z = step(9, z, 1, 14, 2); // 8
76+
z = step(10, z, 26, -9, 10); // 1
77+
z = step(11, z, 26, -11, 14); // 4
78+
z = step(12, z, 26, -6, 7); // 9
79+
z = step(13, z, 26, -5, 1); // 5
80+
81+
// if (z != Run(input, (0, 0, zOrig, 0), lines)) {
82+
// throw new Exception("coki");
83+
// }
84+
return z;
85+
}
86+
87+
public object PartTwo(string input) {
88+
return 0;
89+
}
90+
91+
int Run(string input, int z, string[] lines) {
92+
var mem = new Dictionary<string, int> {
93+
{"x", 0},
94+
{"y", 0},
95+
{"z", z},
96+
{"w", 0},
97+
};
98+
99+
var ich = 0;
100+
int get(string st) {
101+
if (int.TryParse(st, out var res)) {
102+
return res;
103+
}
104+
return mem[st];
105+
}
106+
107+
int set(string st, int v) {
108+
return mem[st] = v;
109+
}
110+
111+
foreach (var line in lines) {
112+
if (string.IsNullOrWhiteSpace(line)) {
113+
continue;
114+
}
115+
var parts = line.Split(" ");
116+
switch (parts[0]) {
117+
case "inp": set(parts[1], input[ich++] - '0'); break;
118+
case "add": set(parts[1], get(parts[1]) + get(parts[2])); break;
119+
case "mul": set(parts[1], get(parts[1]) * get(parts[2])); break;
120+
case "mod": set(parts[1], get(parts[1]) % get(parts[2])); break;
121+
case "div": set(parts[1], get(parts[1]) / get(parts[2])); break;
122+
case "eql": set(parts[1], get(parts[1]) == get(parts[2]) ? 1 : 0); break;
123+
default: throw new Exception();
124+
}
125+
}
126+
return mem["z"];
127+
}
128+
}

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy