Added Solution for 2021 day 24
This commit is contained in:
parent
62fac164a8
commit
4571a92337
4 changed files with 474 additions and 0 deletions
8
2021/day24_arithmetic_logic_unit/Cargo.toml
Normal file
8
2021/day24_arithmetic_logic_unit/Cargo.toml
Normal file
|
@ -0,0 +1,8 @@
|
|||
[package]
|
||||
name = "day24_arithmetic_logic_unit"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[dependencies]
|
84
2021/day24_arithmetic_logic_unit/challenge.txt
Normal file
84
2021/day24_arithmetic_logic_unit/challenge.txt
Normal file
|
@ -0,0 +1,84 @@
|
|||
[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!
|
||||
|
||||
It also can't navigate. Or run the oxygen system.
|
||||
|
||||
Don't worry, though - you *probably* have enough oxygen left to give you enough time to build a new ALU.
|
||||
|
||||
The ALU is a four-dimensional processing unit: it has integer variables `w`, `x`, `y`, and `z`. These variables all start with the value `0`. The ALU also supports *six instructions*:
|
||||
|
||||
* `inp a` - Read an input value and write it to variable `a`.
|
||||
* `add a b` - Add the value of `a` to the value of `b`, then store the result in variable `a`.
|
||||
* `mul a b` - Multiply the value of `a` by the value of `b`, then store the result in variable `a`.
|
||||
* `div a b` - Divide the value of `a` by the value of `b`, truncate the result to an integer, then store the result in variable `a`. (Here, "truncate" means to round the value toward zero.)
|
||||
* `mod a b` - Divide the value of `a` by the value of `b`, then store the *remainder* in variable `a`. (This is also called the [modulo](https://en.wikipedia.org/wiki/Modulo_operation) operation.)
|
||||
* `eql a b` - If the value of `a` and `b` are equal, then store the value `1` in variable `a`. Otherwise, store the value `0` in variable `a`.
|
||||
|
||||
In all of these instructions, `a` and `b` are placeholders; `a` will always be the variable where the result of the operation is stored (one of `w`, `x`, `y`, or `z`), while `b` can be either a variable or a number. Numbers can be positive or negative, but will always be integers.
|
||||
|
||||
The ALU has no *jump* 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.
|
||||
|
||||
(Program authors should be especially cautious; attempting to execute `div` with `b=0` or attempting to execute `mod` with `a<0` or `b<=0` will cause the program to crash and might even damage the ALU. These operations are never intended in any serious ALU program.)
|
||||
|
||||
For example, here is an ALU program which takes an input number, negates it, and stores it in `x`:
|
||||
|
||||
```
|
||||
inp x
|
||||
mul x -1
|
||||
|
||||
```
|
||||
|
||||
Here is an ALU program which takes two input numbers, then sets `z` to `1` if the second input number is three times larger than the first input number, or sets `z` to `0` otherwise:
|
||||
|
||||
```
|
||||
inp z
|
||||
inp x
|
||||
mul z 3
|
||||
eql z x
|
||||
|
||||
```
|
||||
|
||||
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 `z`, the second-lowest (2's) bit in `y`, the third-lowest (4's) bit in `x`, and the fourth-lowest (8's) bit in `w`:
|
||||
|
||||
```
|
||||
inp w
|
||||
add z w
|
||||
mod z 2
|
||||
div w 2
|
||||
add y w
|
||||
mod y 2
|
||||
div w 2
|
||||
add x w
|
||||
mod x 2
|
||||
div w 2
|
||||
mod w 2
|
||||
|
||||
```
|
||||
|
||||
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 *model number*. To do this, the ALU will run the MOdel Number Automatic Detector program (MONAD, your puzzle input).
|
||||
|
||||
Submarine model numbers are always *fourteen-digit numbers* consisting only of digits `1` through `9`. The digit `0` *cannot* appear in a model number.
|
||||
|
||||
When MONAD checks a hypothetical fourteen-digit model number, it uses fourteen separate `inp` instructions, each expecting a *single digit* of the model number in order of most to least significant. (So, to check the model number `13579246899999`, you would give `1` to the first `inp` instruction, `3` to the second `inp` instruction, `5` to the third `inp` instruction, and so on.) This means that when operating MONAD, each input instruction should only ever be given an integer value of at least `1` and at most `9`.
|
||||
|
||||
Then, after MONAD has finished running all of its instructions, it will indicate that the model number was *valid* by leaving a `0` in variable `z`. However, if the model number was *invalid*, it will leave some other non-zero value in `z`.
|
||||
|
||||
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 *figure out what MONAD does* some other way.
|
||||
|
||||
To enable as many submarine features as possible, find the largest valid fourteen-digit model number that contains no `0` digits. *What is the largest model number accepted by MONAD?*
|
||||
|
||||
Your puzzle answer was `29991993698469`.
|
||||
|
||||
\--- Part Two ---
|
||||
----------
|
||||
|
||||
As the submarine starts booting up things like the [Retro Encabulator](https://www.youtube.com/watch?v=RXJKdh1KZ0w), you realize that maybe you don't need all these submarine features after all.
|
||||
|
||||
*What is the smallest model number accepted by MONAD?*
|
||||
|
||||
Your puzzle answer was `14691271141118`.
|
||||
|
||||
Both parts of this puzzle are complete! They provide two gold stars: \*\*
|
||||
|
||||
At this point, you should [return to your Advent calendar](/2021) and try another puzzle.
|
||||
|
||||
If you still want to see it, you can [get your puzzle input](24/input).
|
130
2021/day24_arithmetic_logic_unit/src/lib.rs
Normal file
130
2021/day24_arithmetic_logic_unit/src/lib.rs
Normal file
|
@ -0,0 +1,130 @@
|
|||
pub fn run() -> (usize, usize) {
|
||||
let first = next_valid_input(1_000_000, false);
|
||||
let second = next_valid_input(111_110, true);
|
||||
(first, second)
|
||||
}
|
||||
|
||||
fn next_valid_input(previous: usize, ascending: bool) -> usize {
|
||||
let mut curr = if ascending {
|
||||
previous+1
|
||||
} else {
|
||||
previous-1
|
||||
};
|
||||
let mut digits: Vec<isize>;
|
||||
loop {
|
||||
digits = Vec::new();
|
||||
let mut rest = curr;
|
||||
while rest > 0 {
|
||||
let digit = rest % 10;
|
||||
if digit == 0 {
|
||||
if ascending {
|
||||
curr += 10_usize.pow(digits.len() as u32);
|
||||
} else {
|
||||
curr -= 10_usize.pow(digits.len() as u32);
|
||||
}
|
||||
digits = Vec::new();
|
||||
rest = curr;
|
||||
} else {
|
||||
digits.push(digit as isize);
|
||||
rest /= 10;
|
||||
}
|
||||
}
|
||||
// [0]=[13]-7
|
||||
// [1]=[12]+3
|
||||
// [2]=[11]+5
|
||||
// [3]=9
|
||||
// [4]=1
|
||||
// [5]=[10]+1
|
||||
// [6]=[7]+6
|
||||
// [8]=[9]-3
|
||||
//
|
||||
// free: 13, 12, 11, 10, 9, 7
|
||||
// [13] = 0
|
||||
// [12] = 1
|
||||
// [11] = 2
|
||||
// [10] = 3
|
||||
// [9] = 4
|
||||
// [8] = 5
|
||||
// [7] = 6
|
||||
|
||||
let seven = digits.pop().unwrap();
|
||||
let next = digits[4] - 3;
|
||||
if (1..10).contains(&next) {
|
||||
digits.push(next);
|
||||
} else {
|
||||
if ascending {
|
||||
curr += 1;
|
||||
} else {
|
||||
curr -= 1;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
digits.push(seven);
|
||||
let next = digits[6] + 6;
|
||||
if (1..10).contains(&next) {
|
||||
digits.push(next);
|
||||
} else {
|
||||
if ascending {
|
||||
curr += 1;
|
||||
} else {
|
||||
curr -= 1;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
let next = digits[3] + 1;
|
||||
if (1..10).contains(&next) {
|
||||
digits.push(next);
|
||||
} else {
|
||||
if ascending {
|
||||
curr += 1;
|
||||
} else {
|
||||
curr -= 1;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
digits.push(1);
|
||||
digits.push(9);
|
||||
let next = digits[2] + 5;
|
||||
if (1..10).contains(&next) {
|
||||
digits.push(next);
|
||||
} else {
|
||||
if ascending {
|
||||
curr += 1;
|
||||
} else {
|
||||
curr -= 1;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
let next = digits[1] + 3;
|
||||
if (1..10).contains(&next) {
|
||||
digits.push(next);
|
||||
} else {
|
||||
if ascending {
|
||||
curr += 1;
|
||||
} else {
|
||||
curr -= 1;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
let next = digits[0] - 7;
|
||||
if (1..10).contains(&next) {
|
||||
digits.push(next);
|
||||
break;
|
||||
} else if ascending {
|
||||
curr += 1;
|
||||
} else {
|
||||
curr -= 1;
|
||||
}
|
||||
}
|
||||
digits.iter().rev().fold(0, |acc, cur| 10*acc+ *cur as usize)
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_challenge() {
|
||||
assert_eq!(run(), (29991993698469, 14691271141118));
|
||||
}
|
||||
}
|
252
2021/day24_arithmetic_logic_unit/tests/challenge_input
Normal file
252
2021/day24_arithmetic_logic_unit/tests/challenge_input
Normal file
|
@ -0,0 +1,252 @@
|
|||
inp w
|
||||
mul x 0
|
||||
add x z
|
||||
mod x 26
|
||||
div z 1
|
||||
add x 15
|
||||
eql x w
|
||||
eql x 0
|
||||
mul y 0
|
||||
add y 25
|
||||
mul y x
|
||||
add y 1
|
||||
mul z y
|
||||
mul y 0
|
||||
add y w
|
||||
add y 9
|
||||
mul y x
|
||||
add z y
|
||||
inp w
|
||||
mul x 0
|
||||
add x z
|
||||
mod x 26
|
||||
div z 1
|
||||
add x 11
|
||||
eql x w
|
||||
eql x 0
|
||||
mul y 0
|
||||
add y 25
|
||||
mul y x
|
||||
add y 1
|
||||
mul z y
|
||||
mul y 0
|
||||
add y w
|
||||
add y 1
|
||||
mul y x
|
||||
add z y
|
||||
inp w
|
||||
mul x 0
|
||||
add x z
|
||||
mod x 26
|
||||
div z 1
|
||||
add x 10
|
||||
eql x w
|
||||
eql x 0
|
||||
mul y 0
|
||||
add y 25
|
||||
mul y x
|
||||
add y 1
|
||||
mul z y
|
||||
mul y 0
|
||||
add y w
|
||||
add y 11
|
||||
mul y x
|
||||
add z y
|
||||
inp w
|
||||
mul x 0
|
||||
add x z
|
||||
mod x 26
|
||||
div z 1
|
||||
add x 12
|
||||
eql x w
|
||||
eql x 0
|
||||
mul y 0
|
||||
add y 25
|
||||
mul y x
|
||||
add y 1
|
||||
mul z y
|
||||
mul y 0
|
||||
add y w
|
||||
add y 3
|
||||
mul y x
|
||||
add z y
|
||||
inp w
|
||||
mul x 0
|
||||
add x z
|
||||
mod x 26
|
||||
div z 26
|
||||
add x -11
|
||||
eql x w
|
||||
eql x 0
|
||||
mul y 0
|
||||
add y 25
|
||||
mul y x
|
||||
add y 1
|
||||
mul z y
|
||||
mul y 0
|
||||
add y w
|
||||
add y 10
|
||||
mul y x
|
||||
add z y
|
||||
inp w
|
||||
mul x 0
|
||||
add x z
|
||||
mod x 26
|
||||
div z 1
|
||||
add x 11
|
||||
eql x w
|
||||
eql x 0
|
||||
mul y 0
|
||||
add y 25
|
||||
mul y x
|
||||
add y 1
|
||||
mul z y
|
||||
mul y 0
|
||||
add y w
|
||||
add y 5
|
||||
mul y x
|
||||
add z y
|
||||
inp w
|
||||
mul x 0
|
||||
add x z
|
||||
mod x 26
|
||||
div z 1
|
||||
add x 14
|
||||
eql x w
|
||||
eql x 0
|
||||
mul y 0
|
||||
add y 25
|
||||
mul y x
|
||||
add y 1
|
||||
mul z y
|
||||
mul y 0
|
||||
add y w
|
||||
add y 0
|
||||
mul y x
|
||||
add z y
|
||||
inp w
|
||||
mul x 0
|
||||
add x z
|
||||
mod x 26
|
||||
div z 26
|
||||
add x -6
|
||||
eql x w
|
||||
eql x 0
|
||||
mul y 0
|
||||
add y 25
|
||||
mul y x
|
||||
add y 1
|
||||
mul z y
|
||||
mul y 0
|
||||
add y w
|
||||
add y 7
|
||||
mul y x
|
||||
add z y
|
||||
inp w
|
||||
mul x 0
|
||||
add x z
|
||||
mod x 26
|
||||
div z 1
|
||||
add x 10
|
||||
eql x w
|
||||
eql x 0
|
||||
mul y 0
|
||||
add y 25
|
||||
mul y x
|
||||
add y 1
|
||||
mul z y
|
||||
mul y 0
|
||||
add y w
|
||||
add y 9
|
||||
mul y x
|
||||
add z y
|
||||
inp w
|
||||
mul x 0
|
||||
add x z
|
||||
mod x 26
|
||||
div z 26
|
||||
add x -6
|
||||
eql x w
|
||||
eql x 0
|
||||
mul y 0
|
||||
add y 25
|
||||
mul y x
|
||||
add y 1
|
||||
mul z y
|
||||
mul y 0
|
||||
add y w
|
||||
add y 15
|
||||
mul y x
|
||||
add z y
|
||||
inp w
|
||||
mul x 0
|
||||
add x z
|
||||
mod x 26
|
||||
div z 26
|
||||
add x -6
|
||||
eql x w
|
||||
eql x 0
|
||||
mul y 0
|
||||
add y 25
|
||||
mul y x
|
||||
add y 1
|
||||
mul z y
|
||||
mul y 0
|
||||
add y w
|
||||
add y 4
|
||||
mul y x
|
||||
add z y
|
||||
inp w
|
||||
mul x 0
|
||||
add x z
|
||||
mod x 26
|
||||
div z 26
|
||||
add x -16
|
||||
eql x w
|
||||
eql x 0
|
||||
mul y 0
|
||||
add y 25
|
||||
mul y x
|
||||
add y 1
|
||||
mul z y
|
||||
mul y 0
|
||||
add y w
|
||||
add y 10
|
||||
mul y x
|
||||
add z y
|
||||
inp w
|
||||
mul x 0
|
||||
add x z
|
||||
mod x 26
|
||||
div z 26
|
||||
add x -4
|
||||
eql x w
|
||||
eql x 0
|
||||
mul y 0
|
||||
add y 25
|
||||
mul y x
|
||||
add y 1
|
||||
mul z y
|
||||
mul y 0
|
||||
add y w
|
||||
add y 4
|
||||
mul y x
|
||||
add z y
|
||||
inp w
|
||||
mul x 0
|
||||
add x z
|
||||
mod x 26
|
||||
div z 26
|
||||
add x -2
|
||||
eql x w
|
||||
eql x 0
|
||||
mul y 0
|
||||
add y 25
|
||||
mul y x
|
||||
add y 1
|
||||
mul z y
|
||||
mul y 0
|
||||
add y w
|
||||
add y 9
|
||||
mul y x
|
||||
add z y
|
Loading…
Add table
Add a link
Reference in a new issue