Compare commits

...

46 Commits

Author SHA1 Message Date
c665ed878e Use Arc to not clone cached permutations 2025-06-30 10:57:30 -05:00
8825d97858 Improve type names 2025-06-30 10:06:29 -05:00
4250028c6a Remove unused import 2025-06-16 13:51:58 -05:00
16e726db6b Make const "sets" 2025-06-16 13:51:07 -05:00
ec0267a455 Only make a single cache key (minor optimization) 2025-06-16 13:36:02 -05:00
a7b3d9225b Remove commented out code 2025-06-16 13:33:05 -05:00
f235c46bd4 Add caching back in 2025-06-16 13:32:26 -05:00
3815d496b9 Finish day 7 part 2 2025-06-16 13:07:41 -05:00
9f25697af4 Comment out old implementation 2025-06-16 12:59:46 -05:00
e2cb839086 Better permutation creation 2025-06-16 12:58:38 -05:00
72492db6ea Move over to using enum 2025-06-16 12:24:18 -05:00
3dff9f9bd2 Optimize set creation 2025-06-16 12:17:24 -05:00
2202a42705 Encapsulate cache locking code 2025-06-16 12:07:23 -05:00
de9edd71cc Cache operator sets 2025-06-16 11:54:01 -05:00
b0a81013bd Break day 7 into modules 2025-06-16 11:32:05 -05:00
0b6ff3a4d0 Day 7 Part 1 implementation 2025-06-16 10:54:22 -05:00
775c4a50ca Add operator set creation 2025-06-16 10:31:36 -05:00
cd1260057d Day 7 parse input 2025-06-06 10:51:04 -05:00
c474767812 Init day 7 2025-06-04 20:27:32 -05:00
cae7a32dfa Add readme 2025-06-04 11:46:46 -05:00
743f7ae763 Finish day 6 2025-06-04 11:44:42 -05:00
8e34ef72b8 Pull simulation code out into it's own function 2025-06-04 11:20:31 -05:00
050566e8d9 Finish day 6 part 1 2025-06-04 11:08:37 -05:00
8b983479e5 Pull apart return type from load_map 2025-05-31 09:23:58 -05:00
f72e5c0203 Add comment to top of day 5 and 6 2025-05-31 09:20:54 -05:00
4766956a92 Start day 6 2025-05-31 08:50:55 -05:00
80b8b3ec2f Init day 6 project 2025-05-30 14:35:27 -05:00
ae8dcc6a03 Complete Day 5 2025-05-30 08:24:13 -05:00
0a6971991e Cleanup code and store invalid pages for part 2 2025-05-30 08:07:15 -05:00
ddecce8f63 Move comment 2025-05-30 08:04:33 -05:00
82d48212cf Day 5 Part 1 2025-05-30 07:59:06 -05:00
374ffa5172 Add links to days in readmes 2025-05-29 22:04:06 -05:00
6730dd1a80 Finish day 4 2025-05-29 22:02:50 -05:00
bd64b51683 Rename select_cell to cell 2025-05-28 20:52:17 -05:00
ce72a9b3cf Day 4 part 1 complete 2025-05-28 20:45:26 -05:00
724ac02a9f Add return 2025-05-28 17:14:40 -05:00
8a524236cc Remove unused import 2025-05-28 17:10:48 -05:00
d8136c2ff4 Format code 2025-05-28 17:03:20 -05:00
ce37b21d3d Remove bad whitespace 2025-05-28 17:02:33 -05:00
465d18ea67 Implement taking strings from crossword 2025-05-28 17:01:56 -05:00
5f8eb40a8d Fix comment 2025-05-27 22:33:40 -05:00
7a9fb8546c Pull Crossword out into it's own module 2025-05-27 22:26:05 -05:00
f977975326 Start implementing day 4 2025-05-27 22:10:38 -05:00
6882164ae7 Add Cargo.lock files 2025-05-26 15:57:34 -05:00
a400730c88 Fix clippy errors 2025-05-26 15:50:22 -05:00
da92f241eb Cargo init day 4 2025-05-26 15:47:33 -05:00
37 changed files with 4122 additions and 65 deletions

2
.gitignore vendored
View File

@@ -6,7 +6,7 @@ target/
# Remove Cargo.lock from gitignore if creating an executable, leave it for libraries
# More information here https://doc.rust-lang.org/cargo/guide/cargo-toml-vs-cargo-lock.html
Cargo.lock
# Cargo.lock
# These are backup files generated by rustfmt
**/*.rs.bk

7
day_01/Cargo.lock generated Normal file
View File

@@ -0,0 +1,7 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
version = 4
[[package]]
name = "day_01"
version = "0.1.0"

View File

@@ -1,3 +1,5 @@
https://adventofcode.com/2024/day/1
# --- Day 1: Historian Hysteria ---
The Chief Historian is always present for the big Christmas sleigh launch, but nobody has seen him in months! Last anyone heard, he was visiting locations that are historically significant to the North Pole; a group of Senior Historians has asked you to accompany them as they check the places they think he was most likely to visit.

View File

@@ -20,7 +20,7 @@ fn parse_line(line: &str) -> Result<(i64, i64), Box<dyn Error>> {
// Parse and return our two elements
let first_element = split_line[0].parse::<i64>()?;
let second_element = split_line[1].parse::<i64>()?;
return Ok((first_element, second_element));
Ok((first_element, second_element))
}
/// Part 1
@@ -108,5 +108,5 @@ fn main() -> Result<(), Box<dyn Error>> {
calculate_similarity(left_list, right_list)
);
return Ok(());
Ok(())
}

7
day_02/Cargo.lock generated Normal file
View File

@@ -0,0 +1,7 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
version = 4
[[package]]
name = "day_02"
version = "0.1.0"

View File

@@ -1,3 +1,5 @@
https://adventofcode.com/2024/day/2
# --- Day 2: Red-Nosed Reports ---
Fortunately, the first location The Historians want to search isn't a long walk from the Chief Historian's office.

View File

@@ -65,11 +65,11 @@ fn compare_levels(curr_level: i64, next_level: i64) -> LevelTransition {
TransitionDirection::Desc
};
return LevelTransition { state, direction };
LevelTransition { state, direction }
}
/// Tests if a report is safe
fn is_report_safe_no_dampening(report: &Vec<i64>) -> bool {
fn is_report_safe_no_dampening(report: &[i64]) -> bool {
// Turn the report into a bunch of states for each adjacent pair in the report
let report: Vec<LevelTransition> = report
.windows(2)
@@ -98,13 +98,14 @@ fn is_report_safe_no_dampening(report: &Vec<i64>) -> bool {
// Setup for next iteration
prev_transition = level_transition;
}
return true;
true
}
/// Tests if a report is safe or code be made safe if you remove a single
/// level from the report
fn is_report_safe_with_dampening_brute_force(report: &Vec<i64>) -> bool {
if is_report_safe_no_dampening(&report) {
fn is_report_safe_with_dampening_brute_force(report: &[i64]) -> bool {
if is_report_safe_no_dampening(report) {
return true;
}
@@ -115,7 +116,8 @@ fn is_report_safe_with_dampening_brute_force(report: &Vec<i64>) -> bool {
return true;
}
}
return false;
false
}
// fn compare_levels_3(prev_level: i64, curr_level: i64, next_level: i64) -> LevelTransition {

7
day_03/Cargo.lock generated Normal file
View File

@@ -0,0 +1,7 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
version = 4
[[package]]
name = "day_03"
version = "0.1.0"

View File

@@ -1,3 +1,5 @@
https://adventofcode.com/2024/day/3
# --- Day 3: Mull It Over ---
"Our computers are having issues, so I have no idea if we have any Chief Historians in stock! You're welcome to check the warehouse, though," says the mildly flustered shopkeeper at the North Pole Toboggan Rental Shop. The Historians head out to take a look.

View File

@@ -4,18 +4,13 @@ use crate::tokenizer::Token;
use std::iter::Peekable;
fn is_mul_text_token(text_token: &str) -> bool {
if text_token.ends_with("mul") {
true
} else {
false
}
text_token.ends_with("mul")
}
fn parse_mul<'a>(token_iter: &mut Peekable<impl Iterator<Item = &'a Token>>) -> Option<MulOp> {
// Take OpenParenthesis or return None
if !token_iter.next_if_eq(&&Token::OpenParenthesis).is_some() {
return None;
}
token_iter.next_if_eq(&&Token::OpenParenthesis)?;
// Take Number or return None
let lhs =
if let Some(Token::Number(lhs)) = token_iter.next_if(|v| matches!(v, Token::Number(_))) {
@@ -23,10 +18,10 @@ fn parse_mul<'a>(token_iter: &mut Peekable<impl Iterator<Item = &'a Token>>) ->
} else {
return None;
};
// Take Comma or return None
if !token_iter.next_if_eq(&&Token::Comma).is_some() {
return None;
}
token_iter.next_if_eq(&&Token::Comma)?;
// Take Number or return None
let rhs = if let Some(Token::Number(rhs)) =
token_iter.next_if(|v: &&Token| matches!(v, Token::Number(_)))
@@ -35,60 +30,47 @@ fn parse_mul<'a>(token_iter: &mut Peekable<impl Iterator<Item = &'a Token>>) ->
} else {
return None;
};
// Take CloseParenthesis or return None
if !token_iter.next_if_eq(&&Token::CloseParenthesis).is_some() {
return None;
}
token_iter.next_if_eq(&&Token::CloseParenthesis)?;
Some(MulOp::new(lhs, rhs))
}
fn is_do_text_token(text_token: &str) -> bool {
if text_token.ends_with("do") {
true
} else {
false
}
text_token.ends_with("do")
}
fn parse_do<'a>(token_iter: &mut Peekable<impl Iterator<Item = &'a Token>>) -> Option<DoOp> {
// Take OpenParenthesis or return None
if !token_iter.next_if_eq(&&Token::OpenParenthesis).is_some() {
return None;
}
token_iter.next_if_eq(&&Token::OpenParenthesis)?;
// Take CloseParenthesis or return None
if !token_iter.next_if_eq(&&Token::CloseParenthesis).is_some() {
return None;
}
token_iter.next_if_eq(&&Token::CloseParenthesis)?;
Some(DoOp::new())
}
fn is_dont_text_token(text_token: &str) -> bool {
if text_token.ends_with("don't") {
true
} else {
false
}
text_token.ends_with("don't")
}
fn parse_dont<'a>(token_iter: &mut Peekable<impl Iterator<Item = &'a Token>>) -> Option<DontOp> {
// Take OpenParenthesis or return None
if !token_iter.next_if_eq(&&Token::OpenParenthesis).is_some() {
return None;
}
token_iter.next_if_eq(&&Token::OpenParenthesis)?;
// Take CloseParenthesis or return None
if !token_iter.next_if_eq(&&Token::CloseParenthesis).is_some() {
return None;
}
token_iter.next_if_eq(&&Token::CloseParenthesis)?;
Some(DontOp::new())
}
/// Parse all tokens into Ops
pub fn parse_tokens(tokens: &Vec<Token>) -> Vec<Ops> {
pub fn parse_tokens(tokens: &[Token]) -> Vec<Ops> {
let mut tokens = tokens.iter().peekable();
let mut muls: Vec<Ops> = Vec::new();
while let Some(token) = tokens.next() {
match token {
Token::Text(t) => {
if let Token::Text(t) = token {
if is_mul_text_token(t) {
let op = parse_mul(tokens.by_ref());
if let Some(op) = op {
@@ -106,8 +88,6 @@ pub fn parse_tokens(tokens: &Vec<Token>) -> Vec<Ops> {
}
}
}
_ => (),
}
}
muls
}

7
day_04/Cargo.lock generated Normal file
View File

@@ -0,0 +1,7 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
version = 4
[[package]]
name = "day_04"
version = "0.1.0"

6
day_04/Cargo.toml Normal file
View File

@@ -0,0 +1,6 @@
[package]
name = "day_04"
version = "0.1.0"
edition = "2024"
[dependencies]

87
day_04/README.md Normal file
View File

@@ -0,0 +1,87 @@
https://adventofcode.com/2024/day/4
# --- Day 4: Ceres Search ---
"Looks like the Chief's not here. Next!" One of The Historians pulls out a device and pushes the only button on it. After a brief flash, you recognize the interior of the Ceres monitoring station!
As the search for the Chief continues, a small Elf who lives on the station tugs on your shirt; she'd like to know if you could help her with her word search (your puzzle input). She only has to find one word: `XMAS`.
This word search allows words to be horizontal, vertical, diagonal, written backwards, or even overlapping other words. It's a little unusual, though, as you don't merely need to find one instance of `XMAS` - you need to find all of them. Here are a few ways `XMAS` might appear, where irrelevant characters have been replaced with `.`:
```
..X...
.SAMX.
.A..A.
XMAS.S
.X....
```
The actual word search will be full of letters instead. For example:
```
MMMSXXMASM
MSAMXMSMSA
AMXSXMAAMM
MSAMASMSMX
XMASAMXAMM
XXAMMXXAMA
SMSMSASXSS
SAXAMASAAA
MAMMMXMMMM
MXMXAXMASX
```
In this word search, XMAS occurs a total of 18 times; here's the same word search again, but where letters not involved in any XMAS have been replaced with .:
```
....XXMAS.
.SAMXMS...
...S..A...
..A.A.MS.X
XMASAMX.MM
X.....XA.A
S.S.S.S.SS
.A.A.A.A.A
..M.M.M.MM
.X.X.XMASX
```
Take a look at the little Elf's word search. How many times does XMAS appear?
Your puzzle answer was 2524.
# --- Part Two ---
The Elf looks quizzically at you. Did you misunderstand the assignment?
Looking for the instructions, you flip over the word search to find that this isn't actually an XMAS puzzle; it's an X-MAS puzzle in which you're supposed to find two MAS in the shape of an X. One way to achieve that is like this:
```
M.S
.A.
M.S
```
Irrelevant characters have again been replaced with . in the above diagram. Within the X, each MAS can be written forwards or backwards.
Here's the same example from before, but this time all of the X-MASes have been kept instead:
```
.M.S......
..A..MSMS.
.M.S.MAA..
..A.ASMSM.
.M.S.M....
..........
S.S.S.S.S.
.A.A.A.A..
M.M.M.M.M.
..........
```
In this example, an X-MAS appears 9 times.
Flip the word search from the instructions back over to the word search side and try again. How many times does an X-MAS appear?
Your puzzle answer was 1873.
Both parts of this puzzle are complete! They provide two gold stars: **

140
day_04/input.txt Normal file
View File

@@ -0,0 +1,140 @@
SAMSXXMAXAMXSMXMMMSMSSSSMASMMAMMSMMMMMMMMSMSMSSXMAMXXXMSXSXSMSSMAMMXMSMMXSASMAXASMSMXMASMMMMSAMXXMAXXMMXAMAMXMSMMMMMMMMMMXSSMASMXXXXXMASXXAX
SAASMMASAXMAXMAMXAMSAMXMXASASMXAAAAAMSSMMAAAAXAAMASXSAMXMMAMXMAMMXSASAAAAMMAMMMMXAAMMSAMXSAMMASMSAMMAMXXXSXMAXAAASXAAASAMXMASASMSSSMMAMXMASX
SMMSXSAXMSMSXSASMSMMMSMSMMSAMMMSSSMSMAAASMSMSMSMMAAMSXMAAMAMASMXSASXSSMMXSAMXSAAMXMMAMASAMXSXXMAMXMASMMSMMAMMXXXMXSSSMSASXSMMMMXAXAMAASAMXMX
XMASAMASXXAAAMASAAXAXAAAAXMMAXXMAMAAMSSMMXAAAAMXMXXAMXSXMSXSAMXXMASAMMMSAMXXASASMSXSSXXMASASXMSXMAMAAAASAXAASXSMSAMXXASAMASXMASMMSMMSXSMMASM
SASMAMSMMMMMSMAMXMMMSMMMSXMSSMMMAMMMXAMMMSMSMMMAMMMSMMMSMXAMMSMAMMMMMAAMAMSMAXAMAAMXASAXXMMSAMAMXAMSSMMSSMSMMAAMMASAMXMMXXMAMAMAXXAAMMXAXAXM
ASMSMMMAAMMAMMAMMSSMAXAMXXXAAAMMASAXMASMASAMAXSAMSXMAAAAMMSMAAAMXMASMMSXAMXXMMMMMMSMAAMSXSMSXMAXSAMXXMXMMXXAMMMMSSMXSXAMSMSSMSSMMSMMSSSXMSSS
MAXAMAMMMSMAMMASAAASASMSXSMSMMMSAXMXSMMMXMASAMSMAMMSSMSMSAXMSSXMAXSXXSMXXSXAMXMXMAMMXMAAAMMMAMAMSAMSMMAXMAXAXAAAXAXSMXSMAAAMMAAAAXXAXMXAXAAA
XMSMSAXMXXMSXSASMSXMXSAMAXXAASAMAXSAMASMSMXMAMXMMMAMAXMAMXSAMAMSSMMMXAAMXMMAXAMMMSSMMXSMXMAXMMSXSAMAXXMSMMSMSSSSMMSMAAMSSMMXMSSMXMMMXMSSMMSM
XMAMAAMMMMXXXMAMAMAASMAMXMASXMASAXMASAAAASMSMMXMASXSXMMAMMAMXAXXMASAMMMMMMXMXAXMAMAAMAXXASMSXMXXXXMXSMXMXAAAMMAAAXAMMMMAXXXXMAXMASASAAAMAXAA
SSSMSMMAAXASMMSMXMMMXSAMAXXMAMAMMSSMMMSAMXXAASXMAMXXMAMAXSMSSMSAXMAXXMXAXSASXSSMMMSMMMMXXXXAMMMMSMSMSAAXMSMSMMSSMSXSSSMMSMSMMASMMSASASMSAMXA
AAAMAASXMMMSAAXMAAXXAXMSMSASMSSXMAMXMXMXXMMMMMAMAMAMXSSXXAAXXASXMXAMSMMMXMAXAAAXMAMASMSMSXAMAXAAAAAASXMMXAXAXXAXXXMXAAAASAXAMAMAXMAMXMMMAMXM
MMMMMXMAAXASMMMXXMMMMMMAMXAAAAXAMXSXSMMAXAAXXSASAMSAXXAMSMMMMMMMSSXMAAASMMSMMSMMMMSAMAAAAMSXMSMSSSMMMSSXXXSMSMMSMMMSMSMMSSSXMXSAMMMMXMXSAMAX
XMXAXMASMMASMMMMMASMSASXSMXMXMSXMXMXAAXXMMXSMMASAXMAMMAMMAAMXAAAAAASMSMXAAXAXMASAXMXMSMSMAMAMSMAMAXXAMXSAMAMAAXAAAAAXXXXXASXMASAXMSMMMAMAXXX
AASMSMMAMXAMAMAASXMAMMMAXAXMXXMASAMSSMMMAXMMMMXMXMASAMXMMSMSXSSMMSMMAMXSMMSSMSAMXMAMMAAMXXXAMXMASAMMXMAXMSSSSSSSSMSSSMMSMXMXMASXMMAAMMSXMMSA
SMMAAXSXAMSSMMSXSAMXMSXMMSMAAMSAMXXAAAASXSMAAXAASXAXASMSAMXSXAXAXXMASXMASMAMMMXSSMMASXMMASMMSXSASMXSAMMSXMAAAAXXMAMAAXAASAMXMASAMSSSMAMAMAXA
XXMMMMMASAXAXXMXXXMMAMAXAXAXMXMSSXMSXSMSAXMAMXASMMMSAMAMXMASMMXSMXXSXMXSXMASAMMAMAXMXAAMXMAAMAMMSXAMAMASAMMMMMMSMXSSMMSXSXSAMXSXMAAAMASXMSSS
SASXSXSAMXSXMASXSSMSASXMMSSMXAXMMMXMAMAMXMXMSXMAXXXMAMXSAMMMAXSXMXSMSAXXASAXAMMASMMXMSMMMMMMMMMASMMSSMASAMMSAAAXAAXAMXMASMSASMMAMMSMMMSAAMAM
SAMASXMASASMMASMAAAXXMAAXMAASXSAXMAMAMXAAMAAMAMXAMMSXMXAXMAMSMAASXAAAXXSAMMSSXSMSAAXAXAMMASXSSMASAAAAMMXXMAXMXXMMMXAMSAMXAMXMXMASAAAAASMMMAM
MAMAMAXAMASAXAMMSMMMSSSMMMMMXAMMAMASAMXSXSASXSMSASAAASAMXSASMXSAMSMMMSAMAMAAAMXAMXMMMMAMSASAAAMASMMMMSASMSSSMSMSAMXMMMASMXMAXSMASMSMMXXMAMAM
XSMAMXMSMMSAMXSAMAMSAAASXSSMSMXSXSASASAXAAAXAAASMMMSXSAMASXSXAXMASXAXMASMMMSSSSXMASXXXXMMASMSSMMMMSXAMASAAXAAAASMMAAMSAMAMSXMXMAXXAMSSSSSSSS
XXSSSMMAAMXMAXMMMAMMMSMMXXAAXXXXMMASAMXSMMAMSMMMXSAMAXAMAXAMMSSMMXMXXSAMXAAAAAMASAXXMASXSXXMAXMMAAXAMXXMMMSMMMXMASMXMMASMMXAXMMSSMMSAAMAXAXX
XMAXXAXSMMASXSXSXSXXMAMMXSMMMSMSAMAMXMAMXSXMXMAXXMASMXSMSSXSAAAMXMASXMXSXMMMSASMMMMXMASAMXMMMSMSMMXSXMAXXAAXXMSMMMAASXXMXXXMMXAMAXXMMXMMMMMM
AMXMSSMMXSMMMAAXAXXXSAMXAXAAAAAXMMXSASXAAXAMSMSMSMMMXAMAXAAAMMSMSMAXASAMXSXXMAMXAAAXMAMAMAMXAAXXASXXASXMMMSMMMSAAMMMSASMXSASAMXSMMSMMSMXSXAA
MMXMAAXAASAXMMMMXMAXMAMMXMSMSXXXMSXMAXXMXSAMAAAAXAAAXXMAMMSMMSMXMMMSXMAXAAAXMSMXMXSXMASMSASMSSXSAMMXXMSAAAXASASXMXSASAMXAMAMXSAMMAAAMAMAMMMX
MSMMSSMMMMAMXAAXMSMXSAMXMMMMMMMSMAAMMMSMASAXMSMMSXMSSMSXSAXXMAMMXAXXXMXMSSMSAMASXMMMSXSASASAXAMMSMXMSAXSMXSMMXSAMAMASMSSSMSMAMASMSSSMAMASXSS
XAAMAMXXSXAASXMSAAAXSAMXSAAAAASASXXMAAXMAXMMAAAXSMXXAAAAMXSMSSSMSSSMSSSMXAXMAMAMAAAASAMXMAMMMXMMXSAAMAMASAMXSXSAMXMMMMMAAAXMXMSMAMXXXXSAAXAA
SSXMAMMASXMXSAAAMMSMXAMASMSMSSSMMSASMSSMSSSSSXSASAMXMXMMMAAXAXAAXMAMXAAMSMMMXMAMXMMMMXXAMXMASMMXAXMMMMSAMSXMSASXMMXMAAMSMMMXMMMMXMASMXSMMMSM
AAXXSSMMSASMXMSMXXAXXXMXMAMXMAXXXSXSAMXAMAAAMXMMXASXMAXASMSMSSMMMSXMMSMMAXAXMMASAMXMSMSMSASMMASMMSMXSAMXSMSAMAMMXAAMSXXMXSSSMASXAMXMMASAXAMX
SSSXAAMASAMMAXMAASMSAXSMMAMAMMMMXXMMMMMAMMMMMXAMMAMASMMASAAAAXXAMXMMMMASXMMSASASAMSXAAAASXXAXSASAAMAMAXXAAXMAXMMSSSMXMAMAAAAAAMXXSASMASMMXSA
AAXMSMMMMMMSASMMMMASMMSASMSMXMASXMXAAAMAMAAAASASXSSMASMXMMMMMSSMSAAAASMMSAASMMAMAXXSMSMXMMSMMMMXMAXXSSMSMSMXSAAXAAXAXSXMSMSMMMSXXMASMASAMASA
MASAXAMXMMAMXXAMXMMMXASMMAMAAXXSAAMSSSXMSSSSMSASAMXMAXMXSMMXXXAASXSSXSXAMMMMAMXSMMMXMXXAXMASASXMSSXXAMASXXMAXSMMMSMMMSMAXAAMXAXAAMAMMXMAMXXA
XAAXMAMXSSSSMMMMMXMXMMSMSAMSMSAMMSMMAMMMAMXAAMXMXMSMMSSMAAASMMMMMAXXXXMMXSASAMXAAAXAMXMMMSASXXAXAASMAMAMMSAMXAXXXMXMASMAMMMMMXSMSMXMSASMMSSS
MMXXSAMXXAAXAASAMMXAAXMASXXXAAMSXAMSAMXMASMMMMSMXXSAAAASXMMAAAAXMSMSMMMAXSAXAMXMXMSMSSSMAMASMSMMMSMSMMASAMAXSXMASMAMSSMASAMXSMMXAXMXSMSXAAAX
AAAXAMXMMMMMSMXASASMSMMAMMMMSMXXAMXSAMXSAMMAAAAMSMSMMXAMXMAXSMSMMAAAMAMXXMSMSSSMSAAMAAAMMMXMAAMXSXMSMSXSXXSMMMMAAMXMAMMAMASASASMMMMAMXSMMMMM
MMXSASAMAXAAXXSSMMMMAMMXSXXAAXMMXMASAMAMAXSXMSMSAAXMXMSXMASAXMAXSMMMXSSXSAMXMAAAMSMMXSMMXSAMSMXXAXAXAXASMMMAXAMSSSXMXSMSMMMASAMAXASMMMSASXSM
AMAMMSMSSMMMSAMAAXXSAMSMXAMMMMAAMSXMAMXSXMMMAXMMMSMSXXMASAMXAXMAXMASAAMXMXMAMMMMMMXMXXXAASMMMMSAMMMMMMMMAAXXMMXAAMXMXAMMASMMMMMSSMXAXASXMAAS
SMXSAMXAAXAAAAMSMMASASAASMSSMMSSMAASMSXMMMAAMSAMXXASMASAMXXMXASXXSAMAMXAXASXXAXAXMASMSMMXSXMAASMXAXAAAASXMSMSMMMMMAMXMASAMXAAXMXAXSMMMSAMSMS
XAMMMMMSMMMSMSMMAXMSMMAMMAXMAXAAMSMMASXSXSASXMMMMAAXSMMASXMSMXMAAMASMXSMSAXMASXMSXMAAAASAMASXMXMASMXSSXXAAAXXXXAASAMAXAMAMXMASMSMMAAAASMMAAM
MSMSAXMMMSMXAMASMMXMXSMMMXMXSMMXMAAMAMAXAXSXMAAMXMSMXMSXMXAAXAMMMMAMMAAAMMMXAXXMAXAMMMXMSSMMAXMASXAXMXMSMSMSAMMSMSASMSMSXASXXSAAAMSSMXMAMMSM
MMAMASMAAAAMAMAMSAAXMXAAXXMAMASXSSSMSSMMMMMXXXMSXMMAAXMMMMSMSMSSXMASMMMMSMSMMMAMASXXSMSAMXAMXMAXAMMMMAMAAAXAAMXMAMXMXAXXMMMMXMXMMMAXMASMXMAM
MMSMAXXAMMMMXMAXMSXXASXMSSMXSAMXAAXAXSXAXASMXSXMASXSMXAAAAAAAXAMXMAXAAXXSAAASMSMAMAMAMMMMSXSSSXSMXSAAAMMSMSSXMAMAMSMSXMMAAASXSASMMSSSXSXASAS
MAAMXMMMSSSMASMXMASXMMASAAMAMAMMMMMMMXSSMMXAMSASAMMXMASXSSMSMMMSAMMSSMMAMXMSMAMMXMSAAMMSAMXAASAAXAMMSMSAMXXMXMASMMAAAMAASMSAAMAMSAXAMASMMSAS
MSSSXMASAAASASAXMASMAMSMXSMAXAMXXXAAXMXMASMSMSAMXMXMXXMAAXAMXMXMXSAAXXMASMXXMAMXMMMSXSAMASMMSMMMMMXAAAMXMXAXAMMMMSMSMSMMMXMMMMMMMMMAMAMXXMMM
AAXXXMMMMXMMMMXMMSMXSMAASXMSSMASMSXXSAXSMMAMAMMMSSSSMSMXMXXMAAASAMMSMXMSAMSAMXSAAAAXMMMSAAAXAXXXASMMMSMMSMMSXSAAAAXAXAMXMXMMXASAAASAMXSMMSAS
MMSMMXSAMASAXMSXMXAAXXMXAXXMAXMXAMXSAMXSXMAMMMMAMAAAAMAAXAMSMSMMSXXMAXSAMXXAMXMMSSSSMXAMXSSMMAXMASMXMXXMAAMSASMSSSSXSMSAAMXAXAXMSASAMXAAAXAM
XAAAMASASASASAMAXMMMSXXMXMSSMXMMSMMMAXXXASAMXAMASMXMMMSMSAAAAXXAMMSMSXMAMMSAMXSAXMAMMAMSAXMXXMMSAMXASMSSXSMMAMAMAXMMMMSMSSSSSXSAMAMXMSMMMMXM
MSMXMASAMXSXSASXMXSXSXXASXAAXXXAMAASMMMSAMXMSXSASMXSAMXXXXSMSMMSMASXXASXMAXASAMXSMAMXMSAMXAXMXAXAXSMXAXMAXAMSMSMSXXAAASXXAAASAAXMMSMMMXAXSAS
MASAMXSMSMMASMMAMASXMAXSAMSSMMMSXSMSAAAMAMAAAAMAMXAMXMAMSXXAMXAAMMMAXMMAMSSXMASXSMXSAMAMSMSMMMSXMMSMMSMSMSAMXAXAXAMMMXMMMMSMMXMXMAAXAAXSXSAS
SAXMSMMAAAMMMMSAMAMAASXMMXAXAAAMAMMSXMXSASXMMMMMMSMMMSAAXXAMXMSSMXMSMSAXMAMXXAMXMAMMASAMXAMXMAAASASMMXAMASMMMSMAMASMMSMSAXAMSSXMMSSSMSSMAMAM
MXSXMAXSSSMAAXMAMSXXMMAAXMMSSMXSAMASMMXSASXSMSASXAXAASMSMSSSSXAMXMAMASMXSASMMSSMMAMSXSXSXMMAMMSSMASMAMMMXMMAMAMASXMAAAASXSAMAMAMXMXMXMAMMMSM
XSAXMXMAAXXMSSSXMAASMSXMMAAMAMAMAMAMAXAXMSMAAXAXAMMMXSAAASAAAMAXSMAXAMSXSAXXMXAASXMMAXASXASXSMMAMSMMASXMMSXMSXSASMSMMMMMMMAMASAMAMAMASAMXAXA
MXAAXAMMSMMSAAMAMXMXAASXMMXSAMASAMMSMMMSASAMSMSMXXAMAMXMMMMMMXSASXAMMSXXMMMMXSSMMSAMXMMMSXMXSXMAMAASASASMMMXMAMASAXAXXSMMSMMXSXXXXXSASAXMSSM
AMXMXXSAMAMMMAMXMSSMMMMMASMSXSASASAMXAXMAMSAXAXAMXXMAXMSXAXASAXASMSSXAXAMXAXAMXMAMXAAAXXMMXXMMSMSSXMASMXAXXAMXMAMMMMMMMMAAAXMMMXSAMAMSAMXAAM
SASXSSMMXSXAXAXAMSAMMASMSMAMAMAMAMAXMMMMMMMMMMMSSMSSMSAMSMMXAAMAMAASAMSMAXSMMMAMMSSSXXXMSAXXSAAAAMAMXMMSMMSMSMMASXMSAXAMSSSMAAAAMXMAMMMAMSSM
XXMXMXASAMSSSXSMXSAMXAXMXMAMSMSMSMSXMMXAXAXAAMXMAMXAAMAMAMSAMXMMMMMMMXAXSMXAASXSAAMXMMSMMMXMASMSMMXSXMAAXAAXAAMASAASMSXXAAMXSMMXMAXXSXXSMAXA
SMMSSSXMAXAXSXAXASXMMSSSXMSAMAAAAAXAXSSSSMSSMSASAMMMMMAMAMXXXXXXXMAMMXMAMASXMMAMMXMAAAAAAAASAMXXXMMMASXMMSSSSSMMSMMSMXMSMAMAXAXASMXSAMXAMMMA
MAAAAXAMSMMMXXMAXSAMAMMMAXAAMSMSMSMMMMAAAMAAMSASASMSXSSXMXSXSAMASMSSXAXAMMMAMMSMMSAMSSSXMSMSASXXAAAMAMASAAAAAXAXXMAXXXXXAMMMSMMXAAXMAXXXSSSX
SMMSMSSMMAAMXAXMASXMASAMMMSSMXXXXAMAAMSMSMMSMMMSXMAAAMAASMMAAMSAMAAAXMMXXXMXMMMAAMAMMXXMMXMSAMASXSXSASAMMSMXMSMMAMXMMMSMSMAMAXSMMSMSSXMSAAMS
XXAXXMMAXMASXMSSXMMSXSAAMXAXMMSXSSSMSXXAXMAXAXXSAMXMXMXMMAMMMXMAMMXMASMMMSXXSASMMSSMXMMXSAMMAMAXAMXAXMASMAXSXSXSXMAAAMAAAMXMSAXAAXAMAASAMXMX
XMAXASMSMSMXMAAMMAXSXSXMAMMMXAMXMXAAXMMMMSASAMXXAMMSASAXXAMXXMASMXMXAAXSASMMSAMSAAMAXAMASXMSXMASMSASASAMMMXSAMMSASXSSSMSMSMSAMSMMMSSMMMMXAAM
AMXSMMAMAASAMMMSSSMMAMXMAAMSMXSASMMMMAXSAMXSMXXMAMXXASMMSSSXMASASAAMSSXSSMXAMXMMMXSMSSMASMXXMXMAMAAXMMASMMAMSMAMAMXMAXAAMAXAMMMXXAAMAXXXXMXX
XXXAXMAMSMSMSMSAAAAMMMASMXAAAXSMSAMXSXMMMSMMMXMMMSSMMMXAXMAXAMXASXSAMXMMASMSSXXXXXAMAAMXMASMSAXMASMMXMXMAMXMXSSMSMMMAMXMSXSMXMXSMMXSSMMMAMMS
AXMMMMSXXXMMAMMMSSSMASXSAASMSXMASAMXXXMMASAAMAMSAAXAAAMMSXAXMSMAMAXXXMASAMXAAXMASMMMSSMMMMMASMSXMAMMXMMSXMXMMAMAMXXMMSMMMAMXSXAXAXMAXAASASAA
SMSXMXMASXXMASXXMMXMASAMXMMAMMXAMAMSMAAMXSMMXAXXMMSSMSAASMMSXSMMMMMXMMAMMSMMXSAMXAXMAXMASAMXMAMMMAMSAMAMAMAXMAMMMSMXAXAASMSAMMMMSMXSMMMSASXM
MAAASAMSMMASXSMXXMAMAMXSXMMXMAXXSXXAAAXSASXSSMSXXXXXMMMXSAMAMXAXXMSAMMXXAAAMASAMSMMMAXMASMMAMXMASAXSAXSXXMAMXSMAAAAMMXSMSAMMSAMXAMXMSMMMMMAX
MAMMMMMMAXMSASXSMMSMSMMMASXMASXMAMXASAXMASAXAAAXXMXMXXAAMAMAAXSMMASASXMMSMSMMSXMASXMXSXXMASMMMSASMXMMMMAXMSSMAXMXXSASAXXMXMASAMMMMAMASXAMSSM
MMMSAXASXMXMAMMSXAASAAASAMAAXAXAAMSXMASMXMASMMMMMMAMAXMSMMMXSAAXAMMMMMAAMAAMXSXSMASMAMAMAMAAXXXMXMMMMAXSMMAAMMXSMMXAXASXAXMASXMASMXSASXSMAAM
MAASMMMMAMSMSMAXMMMSSSMMXSMSMMMSMMAMXXAMAMXMAAXAASASXSMMASXAMMMMSXAAASMMSSXSAMMMMAXMASAMAAMMMMAMMAAAMMXMAXXMXXAMAMMAMSAMXMMXSXMASAXMAMAXMXSM
SMXXMAXXMSAAAMXMXSAMXXASASXXAAMAMAMAMMMSAMAMSMSSXSMXAAASAMMXMASXMSSMMSXXXXXMASAAMASMMSMMXSXMASAMXSSSSSMSAMXXMMMSAMMSMAAMAAAAXMXAXMSMSMMMMAMA
XMSMSASAMXMSMXSAMMAMXSXMAMASXMMMXAXMXAXMMMMXMXXMASAMSMMMSXMXSMSAAMMMMMMXMMXMASXXSAMXXXMMMMMSAMAXXAMXAAXMAMSMMMASASAXSMMSSSMMSAMMAAAAXAMAMMSM
SXAAXMAXXAMXAAMAMSMMXXXMAMMMASAMSSSMMSMXSAMAXMXMAMMMXAXAXMSMMXSMMMAAAMAAMAMMXSXMMMSMMAXXAAXMAXSMSASXMMMSSMMAAMMSAMXMAXMAMXAAAMASMSMSMMSMXXAM
XSMSMSSSMMAMMMSMMXAXMSMSAXAXXMAMAAAXAMXASASASXXMMSXMSSMMXXAXXAMAMSSSMMSMMSASAMXXXASAMXMSMSSSMSMAMXSAXXAAMASXMSMMAMSAMXMASMMMMSMXAXXAMXAMXMAS
MMSMAMAAAXSXAXAXAXXMMAMMSXSSSSXMMSMMMSMMSAMXMAAXMAXAAXAAMSMSMSSSMAXMAXAMXMMSAMASAASMMSAMAMAXMAMMMMSAMMSMSAMAAXXXAMXXAXMMMMXXXSAMXMSSMSASXSMM
XSAMAMSSMMMMSSSSSMMASASAXMAMXAAXXMAAXSAMMMMSMSSMSAXMXSMSMAAXXAAMMMMSMSASAMXSAMASMAMAAMAMXMAMSASXAASAMAMXMXXMMMXSASXMAXXAAMMSXSAMXMXMXMXMAAXS
MSMMXMMXMASAXAAAAAAMSASASXSSSMMMSSMMXMASXAAXMAAXMMSXAMXAMMSSMMXMXMASXSASMSXSMMXSXMMMMSSMAMSMSMSMMMSAMXSSMSMSAAAAXMMMASMSMSAAAXMMXSAMSSXMXMMS
ASXSSSMMSASMMMMSSMMMXMMAMAAAASAXMAMXMXAMMMMSMSSMAMXAMXMSSXAAAAMSMMASXMASXSMMMSMMASAAXAMMXMAMXAMXMASAMAMXAAXSAMMMAAXMASXMASMMSMSAXMASAXXMMMAX
MMMMAAAMMMSMAXAMXMXSXMXXMMMMMSXSSXSMXSASXSXSAAXMAAXMXAAMAMSSMMMAAMMSXMXMAXAAAAAXAMAMMMSMASASMSMSMXSSMXSMSMMMMSMXMAXMMMAMXMAXXAMASXXMMMXXAMSX
SASMSMMMAXXXMSMMMMAXMMMMMMAMXSXMMMMAMSXMASAMMMSSSSSMASXXAMMXASMSSMAMXSMMSMSMSSSMSSXMASAMAMAXAMAMXXMXXXAAMXSMAAXXSMSMSMXMASAMMSMMMMAMXAXSMSXS
SASXXMXSXMXMMAMAAMMXSAAAAMMSASASAAMSMMAMXMMMMXXAAAXMAMASMMXMASAAXMAXXSXMAAAAAAXAXAASXSMMMSSMMMAMSASAMSMMMASMSSSXSAAAAMMSMSASXAXAXMXMMSMAXAMX
MAMAXSASMSAXMAMXXAXAMMMSXSAMASASMSSMAMSSXSMAMMMMMMMMMMMAMXSMAMMMMSMSMXASMMMMMSAMXXMMXXXXMAXAASAMXMMAXXAAMAMXMXMAMSMSMSAAAXAMMMSMSAMXMAAMMSSS
XSAMXMASAMASMXSMSSMMMSAAXMXMAMAMXMAMAMXAAMSAMAXXAAMAAMXMXMMMASASMSAAASMMSMXMXMAMSAXXXMMSMXSSMSAXXXXXMXSAMSSMMAMXMMMMMMXMXMSMMAAAAXAMSXSXMMAM
AMAMXMSMMMSMXAAASMAMAMMSMMMMXMAMASXMMSMMMMSMXSASMSSMXSAXAASMMMASAMSMMXMASMXMASAMXAMXAAMAMXAAASAMMXSAAXAXAAAASAXSMXAAAMXSXXMAMSSSMXSAMMMAMMAM
XXAMMXXMAXAAMMMMMASMXSAMASAAAXXSAXAAAAXAMAXMAXMAXMAMASASXSMASMXMXMXMAXMAMSAMMSAMMSSSMSAMXMXMAMASAAXMMMMMMSSMMXXAXSSSMSASMMSAMXAAAXMXSAXAMSAM
MSSSSMXSSSMXMASXSSXMXMASAMMSMMAMXXSMSSSSMMSMMSSXMSSMMMMAMAMAMAMMMMSMMXSMXSXSXMAMAAAAAAXXSAMXXSXMMSMXAAXAXMAMAXMMMMMAAMXMAMAMXXXMXMXMMMSMMSSX
AXAAMAXAMAMXMMMAXMASMMAMXMXAMASXSMMAXAMAAXMAMAMAMXMAXXXMSSMMSAAMAAAAXAMXMXMXMSSMMSSMMMMMMSASMMMSAMXSSXMAXSAMMSAXAXMSMMMMMMSSSSMSSSMSAAAMMMXS
SMMSMSMXMXXMMAMMMMMMMMSSMSSSSMXAMXMXMMMXSMMSMMSXMAMXMXMXMAAXSXSSMXSSMMSAAAAAMMAAMAMXXXAAAXSAAAAXXXXXAAASAMXSAMMSMSXAXSXXMAMAAXAAAAASMSMSAMSA
XSMAAASAMMMMSASXMASXXAXAAXAAMXMSMXSXMASAMAAXMXMMSMSXSAAASMMMMXMAMMAMAASXSASXXMAMMSSMSXSSSSMSSMSSMSAMMSMXASMMAMXAAMAMXMAXMAMMMMMMMMMMXAMMASXX
SMSMSMSXXAAMMASMSASAMXSMSMSMXSMAMXMASAMXSMMSMAMAAAAASASASMMAMXMAXMASMMXMMXMASAAMAXMASAMXMAAAXMXMAAAMAAXMXMASAMSMSMAXAMAXSXMXMAXSXSXSMSSSSMMS
AAAXAMXMMSMSXASAMASXAAAAXAXMAXMASASAMASXSXMAMMSSMMMMMXMMXXXAMXMSXSAMAXXAMAXAMMMMXSMAMAMASAMXSXAXMSMMXSXSXMXMXXSAXMASXXAXMASMSSXMASAAAMAMXAMX
MSMSMSAMXMAMMMMAMAMXSSSMMMMMSSSMSAMMSAMMSASXSMAXXSMSSMMXSSSMXSAMAMAMAMMSMMMMMMAXXMMASAMMMXSSSMMSAAXSAMAAXMSSMSMMMMMSMMSXSAMXAAMMSMSMMMMMSXMS
XMAMASXMAMAMMXSSMASAMMAMMMAMAAMAMXMAMASASAMXXMASAXAMAAXXAAAAMMAMMSSMASXMAMXXAXXXXMSASMSAMXSAMXMAMMSMAMAMXXAAMMAAAAAMMAAAXMSMMMMMAAMXXSXAMMMA
MMAMMSAMMXXMXAMASXMAXSAMXSMSMSMSMSMMSAMAMSAXMSAMXMSSSMMMMSMMMMSMXAAMAMXSMMXMMXMMAXMASMXMASMAXXMMSMXMXMSMSMSSMSSMSMSXMMSSSMMMXAAXMAMAMMMMSAXM
XSXSASMMSSXMMMMAMSSMXMASAMASMMAAAMAXMXSAXXMXXMXMXMAXAAMAXXMASXMAMMMMASXMXASXSAAXXMSXMAXXXXMMMSMMMXMMSXXASAAAXXAAMAXMMXAMXAASMSMSMXMAMSAMXXAX
XAAMASXAASAMASMMSAXMASXMAMAMAMSMSMSSSXMMMMSMSMSMXMASXXMSMMMMSASXMSASAXAAMXMAMXXAAXMASMMMXMAAMXMASMMASXMAMMMSMSMMMAMAMMASXMMSAXAXXMMAXMASMAXM
SMXMXMMMSSXMASAMMMXXASMSAMASXMAXXAAAXXXAMXAAMAAMSXMMAMXAXASMSAMAASAMMMMMMAMSMAMSXMSAMAXSASMMMAXMSAMASXMAMAXAMXXMMMSXMSAMXMMMMMSMMMSMXSAMXAAA
XMAMAXSXMMMSXSMMMXSMXMMSASXSMSSSMMMSMSSXMAMSMMMSMASMMSSXSXMAMXMXMMMMAAXASXSAMXMMAXMASAMMAMXASXXXSXMAMAMASMSSSXSXAAAXXMMXMAAAXAXAXMAMAMXSASMS
XXAMMSMASAAXXMASMAXXAMASAMAMXXAMXXMAAMAMXXXAMXMMXAMAAMMMMXMSMSSSSSMMSMSAXXSMSXMSXMSXMASMAMXMASAMXAMSSSSXSAAAXAASMMSSMAMASXSSMSXXMMAXXSSMAMAA
MSMSMAMAMMXSMXXAMXSSMSAMAMMMMSMMMSMMMMAXAMASMSMMMSSMMSAAXSXAAAXAXAAMAMMMMASXSMXMAMSMXAMMAMMXAMXMSXMAAMMMSMMXMMMMXMAAXAMMXAAXAXSSMSXSAMXMAMSM
AAAAXAAMXSMAXSMMSAMMAMASAMAAAAAAAAAXSSMMXSAMAMAMAMAMAMMXMXXMSMMMMMMXAMAAMXMAMAAMMXMAMASXXSAMSMAXXXMMMMSAMAMSMMAXSMMSMXXXSSMMSMMMAAAMMMXAXMXS
SMSMSXSMASXSMSAXMASMAMASASXMSSSMSMSMAAXSAMXSXSAMXSAMMSMSMSMMAMAXSXMMMMSMMXMXMSSMMAXAMXAXMXMMXMXMXAMXXAMASXMASMMSMAXXMSAAAAXAAAAMMMMMXAXSXMAX
AXAXAXMMMSAMASXMSMMXMSMXXMMAMAAAAMMMXSAMXSAMMSASMSAXAAMAAAASMSSSMAAAAAXMSAMAAXAASMSSSXSXSAXSXAAAXMSAMXMXMASAMXMAMMMSAMMMXXMMSSMSMMSSMMMMAMAM
SAMMMXSAMMMMXMMMMMAAXAAMSSMAMXMASXSAMXAMAMASASXMASAMSSSMSMMXXAMAXXMXMSSMSASMSMSMMAAAXAXAMXSXASMSMMAXXXASMXMASASXMSAMXMXMMXSXXMAAMXXMAAAMAMAX
XAXMAAXASXXMMXSXAMSSSXMXAASMXAXMXMMMMSAMXSAMMSSXXMAMAAXXMXSSMSSSMSSXMXAXSASAMXXXXMMMMMMSMSMMMMMXAMAMXMXXAXSMMMMMAMMXAMAAXMMMAMSMSMXMSMSSMSMS
SXMMMMSAMMSXAAAXMXAAMASAXMMSSSSSXSXMAMAMXMMSAMASXSSMMSMXSAMAAAAXAAAAMSMMMMMASAMXMXSASAAAMAAAMAXSSMAMXSMSAMXAAXAMXMXSAMXMMAMAMXAMAAAMAAXXAAXA
XAXXAAMAMAASMMSAMMMAMMMSAAXXXMAXAMSMXSXXXMAMASMAXSAMXAAAMAXMMMSMMMSSMAMAMAMSMMSSMMSASMSMSSSMMMMAMMSMMAASMXXSXXMSAAXXMSASMSSMXSASXSSSMSMMSMSM
SXMMSXSAMSMAXAXMXAMMMAAXSMMMAAAMXMAXMAXMAMASXMXMMXSXSMSMSSMSAXXAAXAMMASXSSXMAMAMMAMAMXAAXAAXASAMMAMASMMMXSMMXSAMMXMAXSAXAAAMMMXMXAAAAAAAAXAX
SAMAXXMXXASMMSSMSSSXSMMXXXASXMXMXMAXSAMMAMMSAMAASAMXMAXXAMMSAMMXAMXXMXXAAXMXAMASXSMSMMMSMSMMMSASMAMAMXMAMXAAAMXMAXMMMMAMSMMXSMASMMMMXMMSXSXS
SAMAMSSXSASXAMAXAAMAXMMMASMSXMASAMAMMAMSSMAMASXMMAXXMASMMSAXAMSASMSXMMMMMMXSXMMAAXAXAAAAXMXMXMAMMSMSMSMAMSMMSXXMAMMAXMAMXAXAXSASAASAMAXXASMS
SAMMSMAAMAMXMXAMMSMMMSAMXAMXASASASXXMXMAXMAXMMAXSAMSMMMAXMASAMXAMAMXAAXAAXAAXMMXMMXSMMXXMMASAMAMMXAXAMSAMXASXXSSXXSSSSSSXMMSMMSSMMSAMXMSAMAS
SMMMAMMMMMMSMXSMAAAAAXXXXMASXMAMXMAMMMMMSSXSSSMMMMSXAASXMAMXAXMMMSMSSMSSMSSMMXMAXXXMASXSMSASXSMSMMAMXMMMSSMMMAXAAMAAXMASAXAXAMASAXSAMSAMAMAM
XXMMMSXMAMASAAMMXSSMSSMSXSASMSMMSSMMAAAMXMXMXAXXAXSMSMMSAXXSMMMSAMXXXXMAMAMXAASMXMAMMSAAAMASAMXAXMXMSMSMAAXAMMMMSSMAMMXSMMXSXMASMMMAMSSSSMSS
MXSAMXXXMXMMMMSAXAXAXXAAAMAMAAMMAAASMSSMASMMSMMAMXMAXXMASMMAMAXAASMMSAMXMSSSMMXAASXMAMMMMMSMMMSMSSMXMAAMMSSSSXXXAAMXSMMMAMXMMMASXMSSXMASAAXM
AAMXXMMSXSAAXMMMMAXXMMSMSMSMSMSMSMMMXAAXAMMAXAAXSSMSMMXMAXSAMXSMXMXAAAASAMMMAAMSMMAMXSXSXXXMXMAAAXAAMXMXXAAMXMMMSSMASAASAMAMAMAMAMAMAMXMMXMM
SMXXAAXAAMXMMXAMMXMMSAMAXAMMAMXXXMXMMXMMMSMASMSMAAAMAXSXMXSXMAAXMASXXSMMASASMMMMASXMXSAMXMMMASMXMSSMSAASMMSMSSMXAAMAMMMSMSASXMMSMMASAMXXXMAS
XXAMSXMMSMSMXSAXMAAMASMAMMMXMASXMASMXSMMASMMMAAMSMMSXMXAMAXMMMSMMMASXMXSSMASMMSXMASXAMXMAAASASXAMXMAXMSMAAAMXAMMSMMMSSMMMSMSXXMAMSASASMSXMAS
XMMXMAXAAAAAXSXMSXSAMXMXMSXMASAMXAMAAAASASAMXSXMXAASMSSMMAMAAAAMAMXSXMASMMXMAAMAMAMMMMAXXXMAASMAMAMXMSMMMMMMMMMAXSAXAAAAXSMSAXMAMMASAMAMMMMM
XAXASAMMSSMSMMMMMMXMXMASMMASXMXMMSSMMSMMASMMMMAMSMMSAXXXAMASXSMSMSMMMMMMXMAMMMXAMAMASXMSSMXMXMASXAMXMAXXMSASAXMASASMXSMMMSASAMSSMMAMAMSMASAS
MMSAXSAMAMXMAMSAMAASAMXSASAMSMAMAMAXMAXMXMXAAMXMAXXMXMSSSSMMAAAXAAAAXAASXMASXSSMSAXAMAMAXMASAMMXSSSSSMMMXSASXXMXXMXMXMASXMMMAMAMAMXSAMASXSAS
MAMXMXMAXXASAMSASXMSXMASMMMMAXXMASAMSMMSMSSSSSMMXSXAXXXAASAMSMMMSMSMXASAMXMAAXAXSAMSSMMSSSMSXSMAAXAAXMASMMAMAMSSSXAMASAXMSSSSMASXMAXASAMXMXM
MXSXMAAMMSMSAMMAMMAMXMAXXAAMMMXSMMMXXAASXMAAMAASAMMSMMMMMMXMXXMMMAAXMSMMXAMMMSMMSAMXAAXMAAASAMMMMMMMMSMSAMAMMMAAASMSAMXMAXXXASASMSSSXMASMMSM
SAMASAXSMAMMXMMAMMMMSMMXSXXSAXMAMXXMMMMSAXMMSSMMASAAAXAAAMSMMAMAMMMMXMASMXXSAMXASAMSXMMMSMMMAMMMMMXSASASMMAMAMMSMAMMXSAASMMSMMXSAAAMASAMAAAS
MAXMMMMMXAXMAMXASASXSASMSAASAMSAMSASAXASXMXXAAAMAMMSXSXMMXAASXMASAXSASXMASMMMXMXXAMMASAMAXXSXMAAAMMMAXXSMSSSMSAMXXXAAXASAAAAXAAMMMSMXMMSMSMS
SAMSASASMSMSAXSAMASAMAMAMMMMMMMMMSASAXAMXMASXXMMSSXXASXMSSSXXMSASXASAXXAXXSAAMSSXSMMXMASMMXMXSSSSSSMSMXMAXXAXAMXAAMMSSSXMMSSMMXSAXAAAMAMAAXM
MAASAMASAMAMAMMXMXMXMAMXMXAMXAAAXMMMXAAAASMMSAMAXAMMXMASAAMAAMMASXMMSMSSSXSMXMAAAXXSMSAMXSAMMXXXAAXAASXMAMMSMSXSXAXAAXMAMMAMMSASXSMSMXAMSXSA
SSMMAMAMMMXMSMMASAAMMXMSSXMSMMSXXAAAASAMXXAASXMMSMXAAXXMMSMMXMMAMMXMAMAAAAMXSSMMXMAXXAMXAXAXAXMMMMMXMXMASMXAAMAMMMMMSMSAMMASASXSXSAAXSXMAAMA
AXMMAMXXMXSAMAXAMMXMMXMMSAXAAXAXXSMXXAMXMSMMSXSXAXMSMSMMAXMSMAMMSXXSSMMSMAMAMAXAAMMMMMXMMSSMMMXAAXMMXASXAXSMSMSMAMAAAMAMXXMMMSAMAMSMMAMMSSMA
SMMSASXAMAMAMSMSSXSASMAASXMAMSAMXMAMXXMAMAMMMXMXSXMAXAAMASAASAMSXMAXAMXMXMMXSAMSMXAAXXMXMAXXXAMSMSAMMXMMMXXMAAXASMMXSASMSSSMXMMMAMAMSMXAAAXA
AAAAAMXXMASAMAXMAMSAXMMMMMXSMAMMAMAMASXSSXSASXSAMASASMSMSMMMSXSXAXSSMMAMASAAAAXXAASXMAXXMASMXSXAASAMMMMAXMASMSMMMMMAMXAAAAAMXXAMASAMXXMMSSMS
MSMMMMXMSXSASXSMSMMSMSSSXAAXMASMXXSMAMSAMXSASAMASMSXXAXXAASXXXXXXMAAXMXSAMMSSXMXMAXAASMXSAMXMAMMXSAMMAMMMSAMXMAMAAMXMAMMMSMMSMXXXXXAMXXXXMAM
XXXAAXMAAASAMASAXMAMMXAAXMMSSMSAXMMMMSAMMAMMMMMMMXMAMSMMMAMAMASXMSXMMMXMASAMMMMXXAMMMMAMXMSAAAXMASAMSXMSAMXSXMASMSXMMMMMMAMAMASMSSMSMMMAAMAM
SMSSXMAMXMMMMMMAMMSSSMMMSXAAAMXMXASAMXMXMAXAAXAMXAMXMAAAXMAMMAXXAXAXAXMXAMMMAAXAMXSAMXMMAXXXSMSMXMAMAMXMASXAXMASXXXSAAAXAAMAMSMAAAAAAMSMMMAM
XAAAAXSSMMAXMMMSMAXAXAAAXMMXSMAXXMMASMXAXSSSSSMSSSSMSSSMSMSSMXSMSMMSMXSMXSAMSMSMSASASXMSXSMMXXAMSSMMMAAAXXMASXMSAMASMSMSSXSAXAMMMMMMXMAASXXS
MSMSMMXAASAMXAAAMXSSSMMMSXAAMMMSSXSAMXSXMXAMXMAMAAAAAAMAMXAAMAXAAAXAAXSAMMXXAAMMMASAMAASASMASMSMAAASXSXSMMAAAAMMXMAMXMAMMASMSMXXAXASXMMSXAAA
XAAAMXSSMMXMSMXSSMXXXAAAXMMMSAASAAMMMASXMSAMXMAMMMMMMSMAMMSSMAMSXSSSSXSASMSSMSMAMXMMMMMMAXMXSAXMMSMMAMAAAXSSSSMASMSMMSSMMMXXAXMSSMMMAXXAXMAX
XMMMMAMAXMAMASMMAMSMMSMSSMSASMMXMXMAMASAMXMMASMSMMASAXXMXXXXAMMMAMAMAMSMMMAAAAMMSSMAMXXMMMXAMAMXMAMMAMSMMMMAAXMXSAXMMAAASAMMXXXAAASMMMSAMXMA
XSMXMXXAMXXSASMSAMASXAXMAXMXSXXMSMSXSXSMMAXXASAAASAMMSMSAMXMASAMXMAMAAXSSMSMMMAMAASASMMAAXMMMMMASAMXXMAXAASMSMSAMXMMMMSMMAMXAAMMMMMAMXMMAAMA
XSASMSMSXXXMAXXMASAXMASMXSXAMMSAAAMAMAMXSSSMAMMMMMAXXAAXMAMSAMASXSSSSMSASAXMSXSMSXSXSASXMMMXAXXXSASAXSASMMSAMAMXSSXMAXAXMMMSMSXAXMSMMASMSAMX
MMAMAAAAMSXMSMXSAMAMXMAMAMMAMXMMMSMAMAMXAAXMXMXSSSSMSMSMMSMMASMMMSAMAXMAMMMMMAAAXASXSMMASMMMSSMASAMMMMMMMAMAMSMSXMASXSSXSAAAAAMMSAAASXMXMASA
AMAMSXMASMAAXAAMXMMAASXMASXSMXMASXMXSXSMMXMXAXXXAAXAAAXXAAASAMMAMXAMSAMXMXAAMXMMMAMXMASAXXAAASMAMXMXAAAAMXMXMAXMASAMAAAASMSMSAAAAMSMMAXXMASX
SSXMXASMXMMMMSMXXMASMSXSSSXASXSXSAMXSMXXXXASASMMMMMSMSSMSSMMSSSXXSAMXMASMSSXSAXXMXMMSMMMSSMSSMMSSXSXSSSSSXMASXXSAMSSMMMMMXXAMXMASXMXSSMMMXSA

10
day_04/small_input.txt Normal file
View File

@@ -0,0 +1,10 @@
MMMSXXMASM
MSAMXMSMSA
AMXSXMAAMM
MSAMASMSMX
XMASAMXAMM
XXAMMXXAMA
SMSMSASXSS
SAXAMASAAA
MAMMMXMMMM
MXMXAXMASX

343
day_04/src/crossword.rs Normal file
View File

@@ -0,0 +1,343 @@
use std::error::Error;
use std::fmt::Display;
use std::fs::File;
use std::io::{BufReader, prelude::*};
#[derive(Debug)]
pub struct Crossword {
data: Vec<Vec<char>>,
width: usize,
height: usize,
}
pub struct CrosswordCell<'a> {
x: usize,
y: usize,
crossword: &'a Crossword,
}
impl<'a> CrosswordCell<'a> {
fn value_by_index(&self, x: usize, y: usize) -> char {
// x and y are reverse because we store by row
//
// data[ROW][COLUMN]
self.crossword.data[y][x]
}
pub fn value(&self) -> char {
self.value_by_index(self.x, self.y)
}
fn take(&self, num_of_letters: usize, direction: (isize, isize), start: isize) -> String {
let mut word = String::new();
let end = start + num_of_letters as isize;
for i in start..end {
let x = self.x as isize + (i * direction.1);
let y = self.y as isize + (i * direction.0);
if x < 0
|| x >= self.crossword.width as isize
|| y < 0
|| y >= self.crossword.height as isize
{
if i < 0 {
continue;
} else {
break;
}
}
word.push(self.value_by_index(x as usize, y as usize));
}
word
}
const DIRECTION_N: (isize, isize) = (-1, 0);
pub fn n(&self, num_of_letters: usize) -> String {
self.take(num_of_letters, CrosswordCell::DIRECTION_N, 0)
}
pub fn n2(&self, num_of_letters: usize, start: isize) -> String {
self.take(num_of_letters, CrosswordCell::DIRECTION_N, start)
}
const DIRECTION_NE: (isize, isize) = (-1, 1);
pub fn ne(&self, num_of_letters: usize) -> String {
self.take(num_of_letters, CrosswordCell::DIRECTION_NE, 0)
}
pub fn ne2(&self, num_of_letters: usize, start: isize) -> String {
self.take(num_of_letters, CrosswordCell::DIRECTION_NE, start)
}
const DIRECTION_E: (isize, isize) = (0, 1);
pub fn e(&self, num_of_letters: usize) -> String {
self.take(num_of_letters, CrosswordCell::DIRECTION_E, 0)
}
pub fn e2(&self, num_of_letters: usize, start: isize) -> String {
self.take(num_of_letters, CrosswordCell::DIRECTION_E, start)
}
const DIRECTION_SE: (isize, isize) = (1, 1);
pub fn se(&self, num_of_letters: usize) -> String {
self.take(num_of_letters, CrosswordCell::DIRECTION_SE, 0)
}
pub fn se2(&self, num_of_letters: usize, start: isize) -> String {
self.take(num_of_letters, CrosswordCell::DIRECTION_SE, start)
}
const DIRECTION_S: (isize, isize) = (1, 0);
pub fn s(&self, num_of_letters: usize) -> String {
self.take(num_of_letters, CrosswordCell::DIRECTION_S, 0)
}
pub fn s2(&self, num_of_letters: usize, start: isize) -> String {
self.take(num_of_letters, CrosswordCell::DIRECTION_S, start)
}
const DIRECTION_SW: (isize, isize) = (1, -1);
pub fn sw(&self, num_of_letters: usize) -> String {
self.take(num_of_letters, CrosswordCell::DIRECTION_SW, 0)
}
pub fn sw2(&self, num_of_letters: usize, start: isize) -> String {
self.take(num_of_letters, CrosswordCell::DIRECTION_SW, start)
}
const DIRECTION_W: (isize, isize) = (0, -1);
pub fn w(&self, num_of_letters: usize) -> String {
self.take(num_of_letters, CrosswordCell::DIRECTION_W, 0)
}
pub fn w2(&self, num_of_letters: usize, start: isize) -> String {
self.take(num_of_letters, CrosswordCell::DIRECTION_W, start)
}
const DIRECTION_NW: (isize, isize) = (-1, -1);
pub fn nw(&self, num_of_letters: usize) -> String {
self.take(num_of_letters, CrosswordCell::DIRECTION_NW, 0)
}
pub fn nw2(&self, num_of_letters: usize, start: isize) -> String {
self.take(num_of_letters, CrosswordCell::DIRECTION_NW, start)
}
}
pub struct CrosswordIterator<'a> {
crossword: &'a Crossword,
position: usize,
}
impl<'a> Iterator for CrosswordIterator<'a> {
type Item = CrosswordCell<'a>;
fn next(&mut self) -> Option<Self::Item> {
let y = self.position / self.crossword.width;
let x = self.position - y * self.crossword.width;
self.position += 1;
if x < self.crossword.width && y < self.crossword.height {
Some(CrosswordCell {
x,
y,
crossword: self.crossword,
})
} else {
None
}
}
}
impl Crossword {
pub fn new(file: File) -> Result<Crossword, Box<dyn Error>> {
let mut input_buffer = BufReader::new(file);
let mut data: Vec<Vec<char>> = Vec::new();
let mut first_line = String::new();
input_buffer.read_line(&mut first_line)?;
let first_line = first_line.trim_end().to_owned();
let width = first_line.len();
data.push(first_line.chars().collect());
for line in input_buffer.lines() {
let line = line?;
if line.len() != width {
println!("{}", line);
Err("Line length of input are not consistent")?;
}
data.push(line.chars().collect());
}
let height = data.len();
Ok(Crossword {
data,
width,
height,
})
}
fn from_data(data: Vec<Vec<char>>) -> Crossword {
let height = data.len();
let width = data[0].len();
Crossword {
data,
width,
height,
}
}
pub fn width(&self) -> usize {
self.width
}
pub fn height(&self) -> usize {
self.height
}
pub fn iter_cells(&self) -> CrosswordIterator {
CrosswordIterator {
crossword: self,
position: 0,
}
}
pub fn cell(&self, x: usize, y: usize) -> CrosswordCell {
CrosswordCell {
x,
y,
crossword: self,
}
}
}
impl Display for Crossword {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
for row in &self.data {
let row = String::from_iter(row.iter());
writeln!(f, "{}", row)?;
}
Ok(())
}
}
#[cfg(test)]
mod tests {
// Note this useful idiom: importing names from outer (for mod tests) scope.
use super::*;
fn small_test_crossword() -> Crossword {
Crossword::from_data(vec![
vec!['1', '2', '3'],
vec!['4', '5', '6'],
vec!['7', '8', '9'],
])
}
#[test]
fn test_north() {
let crossword = small_test_crossword();
assert_eq!(crossword.cell(1, 1).n(0), "");
assert_eq!(crossword.cell(1, 1).n(1), "5");
assert_eq!(crossword.cell(1, 1).n(2), "52");
assert_eq!(crossword.cell(1, 1).n(3), "52");
assert_eq!(crossword.cell(1, 1).n2(3, 1), "2");
assert_eq!(crossword.cell(1, 1).n2(3, 0), "52");
assert_eq!(crossword.cell(1, 1).n2(3, -1), "852");
assert_eq!(crossword.cell(1, 1).n2(3, -2), "85");
}
#[test]
fn test_northeast() {
let crossword = small_test_crossword();
assert_eq!(crossword.cell(1, 1).ne(0), "");
assert_eq!(crossword.cell(1, 1).ne(1), "5");
assert_eq!(crossword.cell(1, 1).ne(2), "53");
assert_eq!(crossword.cell(1, 1).ne(3), "53");
assert_eq!(crossword.cell(1, 1).ne2(3, 1), "3");
assert_eq!(crossword.cell(1, 1).ne2(3, 0), "53");
assert_eq!(crossword.cell(1, 1).ne2(3, -1), "753");
assert_eq!(crossword.cell(1, 1).ne2(3, -2), "75");
}
#[test]
fn test_east() {
let crossword = small_test_crossword();
assert_eq!(crossword.cell(1, 1).e(0), "");
assert_eq!(crossword.cell(1, 1).e(1), "5");
assert_eq!(crossword.cell(1, 1).e(2), "56");
assert_eq!(crossword.cell(1, 1).e(3), "56");
assert_eq!(crossword.cell(1, 1).e2(3, 1), "6");
assert_eq!(crossword.cell(1, 1).e2(3, 0), "56");
assert_eq!(crossword.cell(1, 1).e2(3, -1), "456");
assert_eq!(crossword.cell(1, 1).e2(3, -2), "45");
}
#[test]
fn test_southeast() {
let crossword = small_test_crossword();
assert_eq!(crossword.cell(1, 1).se(0), "");
assert_eq!(crossword.cell(1, 1).se(1), "5");
assert_eq!(crossword.cell(1, 1).se(2), "59");
assert_eq!(crossword.cell(1, 1).se(3), "59");
assert_eq!(crossword.cell(1, 1).se2(3, 1), "9");
assert_eq!(crossword.cell(1, 1).se2(3, 0), "59");
assert_eq!(crossword.cell(1, 1).se2(3, -1), "159");
assert_eq!(crossword.cell(1, 1).se2(3, -2), "15");
}
#[test]
fn test_south() {
let crossword = small_test_crossword();
assert_eq!(crossword.cell(1, 1).s(0), "");
assert_eq!(crossword.cell(1, 1).s(1), "5");
assert_eq!(crossword.cell(1, 1).s(2), "58");
assert_eq!(crossword.cell(1, 1).s(3), "58");
assert_eq!(crossword.cell(1, 1).s2(3, 1), "8");
assert_eq!(crossword.cell(1, 1).s2(3, 0), "58");
assert_eq!(crossword.cell(1, 1).s2(3, -1), "258");
assert_eq!(crossword.cell(1, 1).s2(3, -2), "25");
}
#[test]
fn test_southwest() {
let crossword = small_test_crossword();
assert_eq!(crossword.cell(1, 1).sw(0), "");
assert_eq!(crossword.cell(1, 1).sw(1), "5");
assert_eq!(crossword.cell(1, 1).sw(2), "57");
assert_eq!(crossword.cell(1, 1).sw(3), "57");
assert_eq!(crossword.cell(1, 1).sw2(3, 1), "7");
assert_eq!(crossword.cell(1, 1).sw2(3, 0), "57");
assert_eq!(crossword.cell(1, 1).sw2(3, -1), "357");
assert_eq!(crossword.cell(1, 1).sw2(3, -2), "35");
}
#[test]
fn test_west() {
let crossword = small_test_crossword();
assert_eq!(crossword.cell(1, 1).w(0), "");
assert_eq!(crossword.cell(1, 1).w(1), "5");
assert_eq!(crossword.cell(1, 1).w(2), "54");
assert_eq!(crossword.cell(1, 1).w(3), "54");
assert_eq!(crossword.cell(1, 1).w2(3, 1), "4");
assert_eq!(crossword.cell(1, 1).w2(3, 0), "54");
assert_eq!(crossword.cell(1, 1).w2(3, -1), "654");
assert_eq!(crossword.cell(1, 1).w2(3, -2), "65");
}
#[test]
fn test_northwest() {
let crossword = small_test_crossword();
assert_eq!(crossword.cell(1, 1).nw(0), "");
assert_eq!(crossword.cell(1, 1).nw(1), "5");
assert_eq!(crossword.cell(1, 1).nw(2), "51");
assert_eq!(crossword.cell(1, 1).nw(3), "51");
assert_eq!(crossword.cell(1, 1).nw2(3, 1), "1");
assert_eq!(crossword.cell(1, 1).nw2(3, 0), "51");
assert_eq!(crossword.cell(1, 1).nw2(3, -1), "951");
assert_eq!(crossword.cell(1, 1).nw2(3, -2), "95");
}
}

88
day_04/src/main.rs Normal file
View File

@@ -0,0 +1,88 @@
// https://adventofcode.com/2024/day/4
//
// Run command: cargo run ./input.txt
#![allow(dead_code)]
use std::env;
use std::error::Error;
use std::fs::File;
mod crossword;
use crate::crossword::Crossword;
fn main() -> Result<(), Box<dyn Error>> {
unsafe {
env::set_var("RUST_BACKTRACE", "1");
}
// Handle command input
let args: Vec<String> = env::args().collect();
if args.len() != 2 {
panic!(
"{} must be run with a single argument of files name!",
&args[0]
)
}
let input_file_string = &args[1];
let crossword = Crossword::new(File::open(input_file_string)?)?;
println!("{}", crossword);
let word_to_find = "XMAS".to_owned();
let word_to_find_rev = word_to_find.chars().rev().collect::<String>();
let word_len = word_to_find.len();
let mut count = 0;
for cell in crossword.iter_cells() {
// We only need to check forwards and down, as up and back
// will be covered by other cells. If we counted them it
// would cause double counting
// East
let word = cell.e(word_len);
if word == word_to_find || word == word_to_find_rev {
count += 1
}
// Southeast
let word = cell.se(word_len);
if word == word_to_find || word == word_to_find_rev {
count += 1
}
// South
let word = cell.s(word_len);
if word == word_to_find || word == word_to_find_rev {
count += 1
}
// Southwest
let word = cell.sw(word_len);
if word == word_to_find || word == word_to_find_rev {
count += 1
}
}
println!(
"Count of the word '{}' in crossword: {}",
word_to_find, count
);
let mas = "MAS".to_owned();
let mas_rev = mas.chars().rev().collect::<String>();
let mut count = 0;
for cell in crossword.iter_cells() {
let se_word = cell.se2(3, -1);
let sw_word = cell.sw2(3, -1);
if (se_word == mas || se_word == mas_rev) && (sw_word == mas || sw_word == mas_rev) {
count += 1;
}
}
println!("Count of the MAS Xes in crossword: {}", count);
Ok(())
}

7
day_05/Cargo.lock generated Normal file
View File

@@ -0,0 +1,7 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
version = 4
[[package]]
name = "day_05"
version = "0.1.0"

6
day_05/Cargo.toml Normal file
View File

@@ -0,0 +1,6 @@
[package]
name = "day_05"
version = "0.1.0"
edition = "2024"
[dependencies]

103
day_05/README.md Normal file
View File

@@ -0,0 +1,103 @@
https://adventofcode.com/2024/day/5
# --- Day 5: Print Queue ---
Satisfied with their search on Ceres, the squadron of scholars suggests subsequently scanning the stationery stacks of sub-basement 17.
The North Pole printing department is busier than ever this close to Christmas, and while The Historians continue their search of this historically significant facility, an Elf operating a very familiar printer beckons you over.
The Elf must recognize you, because they waste no time explaining that the new sleigh launch safety manual updates won't print correctly. Failure to update the safety manuals would be dire indeed, so you offer your services.
Safety protocols clearly indicate that new pages for the safety manuals must be printed in a very specific order. The notation X|Y means that if both page number X and page number Y are to be produced as part of an update, page number X must be printed at some point before page number Y.
The Elf has for you both the page ordering rules and the pages to produce in each update (your puzzle input), but can't figure out whether each update has the pages in the right order.
For example:
```
47|53
97|13
97|61
97|47
75|29
61|13
75|53
29|13
97|29
53|29
61|53
97|53
61|29
47|13
75|47
97|75
47|61
75|61
47|29
75|13
53|13
75,47,61,53,29
97,61,53,29,13
75,29,13
75,97,47,61,53
61,13,29
97,13,75,29,47
```
The first section specifies the page ordering rules, one per line. The first rule, 47|53, means that if an update includes both page number 47 and page number 53, then page number 47 must be printed at some point before page number 53. (47 doesn't necessarily need to be immediately before 53; other pages are allowed to be between them.)
The second section specifies the page numbers of each update. Because most safety manuals are different, the pages needed in the updates are different too. The first update, 75,47,61,53,29, means that the update consists of page numbers 75, 47, 61, 53, and 29.
To get the printers going as soon as possible, start by identifying which updates are already in the right order.
In the above example, the first update (75,47,61,53,29) is in the right order:
75 is correctly first because there are rules that put each other page after it: 75|47, 75|61, 75|53, and 75|29.
47 is correctly second because 75 must be before it (75|47) and every other page must be after it according to 47|61, 47|53, and 47|29.
61 is correctly in the middle because 75 and 47 are before it (75|61 and 47|61) and 53 and 29 are after it (61|53 and 61|29).
53 is correctly fourth because it is before page number 29 (53|29).
29 is the only page left and so is correctly last.
Because the first update does not include some page numbers, the ordering rules involving those missing page numbers are ignored.
The second and third updates are also in the correct order according to the rules. Like the first update, they also do not include every page number, and so only some of the ordering rules apply - within each update, the ordering rules that involve missing page numbers are not used.
The fourth update, 75,97,47,61,53, is not in the correct order: it would print 75 before 97, which violates the rule 97|75.
The fifth update, 61,13,29, is also not in the correct order, since it breaks the rule 29|13.
The last update, 97,13,75,29,47, is not in the correct order due to breaking several rules.
For some reason, the Elves also need to know the middle page number of each update being printed. Because you are currently only printing the correctly-ordered updates, you will need to find the middle page number of each correctly-ordered update. In the above example, the correctly-ordered updates are:
```
75,47,61,53,29
97,61,53,29,13
75,29,13
```
These have middle page numbers of 61, 53, and 29 respectively. Adding these page numbers together gives 143.
Of course, you'll need to be careful: the actual list of page ordering rules is bigger and more complicated than the above example.
Determine which updates are already in the correct order. What do you get if you add up the middle page number from those correctly-ordered updates?
Your puzzle answer was 4959.
# --- Part Two ---
While the Elves get to work printing the correctly-ordered updates, you have a little time to fix the rest of them.
For each of the incorrectly-ordered updates, use the page ordering rules to put the page numbers in the right order. For the above example, here are the three incorrectly-ordered updates and their correct orderings:
75,97,47,61,53 becomes 97,75,47,61,53.
61,13,29 becomes 61,29,13.
97,13,75,29,47 becomes 97,75,47,29,13.
After taking only the incorrectly-ordered updates and ordering them correctly, their middle page numbers are 47, 29, and 47. Adding these together produces 123.
Find the updates which are not in the correct order. What do you get if you add up the middle page numbers after correctly ordering just those updates?
Your puzzle answer was 4655.
Both parts of this puzzle are complete! They provide two gold stars: **

1368
day_05/input.txt Normal file

File diff suppressed because it is too large Load Diff

28
day_05/small_input.txt Normal file
View File

@@ -0,0 +1,28 @@
47|53
97|13
97|61
97|47
75|29
61|13
75|53
29|13
97|29
53|29
61|53
97|53
61|29
47|13
75|47
97|75
47|61
75|61
47|29
75|13
53|13
75,47,61,53,29
97,61,53,29,13
75,29,13
75,97,47,61,53
61,13,29
97,13,75,29,47

126
day_05/src/main.rs Normal file
View File

@@ -0,0 +1,126 @@
// https://adventofcode.com/2024/day/5
//
// Run command: cargo run ./input.txt
use std::{
collections::{HashMap, HashSet},
env,
error::Error,
fs::File,
io::{BufReader, prelude::*},
};
fn accumulate_middle_pages(page_updates: Vec<Vec<i64>>) -> i64 {
let mut accumulator = 0;
for update in page_updates {
let middle_page = update[update.len() / 2];
accumulator += middle_page;
}
accumulator
}
fn main() -> Result<(), Box<dyn Error>> {
// Handle command input
let args: Vec<String> = env::args().collect();
if args.len() != 2 {
panic!(
"{} must be run with a single argument of files name!",
&args[0]
)
}
let input_file = &args[1];
let buffer = BufReader::new(File::open(input_file)?);
let mut rules_stage = true;
let mut page_rules: HashMap<i64, HashSet<i64>> = HashMap::new();
let mut valid_page_updates: Vec<Vec<i64>> = Vec::new();
let mut invalid_page_updates: Vec<Vec<i64>> = Vec::new();
for line in buffer.lines() {
let line = line?;
if rules_stage {
// Stage 1: load rules
// Load rules that look like 1|1
if line.is_empty() {
// Blank line means end of rules
rules_stage = false;
// println!("Page Rules: {:?}", page_rules);
continue;
}
let split_line: Vec<&str> = line.split("|").collect();
if split_line.len() != 2 {
Err(format!("Invalid input in rules: {}", line))?;
}
// parse rule line and insert into out rule sets
let key = split_line[0].parse::<i64>()?;
let value = split_line[1].parse::<i64>()?;
match page_rules.get_mut(&key) {
Some(rule_set) => {
rule_set.insert(value);
}
None => {
let mut new_rule_set = HashSet::new();
new_rule_set.insert(value);
page_rules.insert(key, new_rule_set);
}
}
} else {
// Stage 2: check updates
let page_update: Vec<i64> = line
.split(",")
.map(|v| v.parse::<_>())
.collect::<Result<_, _>>()?;
let mut prev_pages: HashSet<i64> = HashSet::new();
let mut is_valid = true;
for page_num in page_update.iter() {
if let Some(rule_set) = page_rules.get(page_num) {
if !prev_pages.is_disjoint(rule_set) {
is_valid = false;
break;
}
prev_pages.insert(*page_num);
}
}
if is_valid {
valid_page_updates.push(page_update);
} else {
invalid_page_updates.push(page_update);
}
}
}
let accumulator = accumulate_middle_pages(valid_page_updates);
println!("Sum of middle pages from valid updates: {}", accumulator);
let mut fixed_updates = Vec::new();
for page_update in invalid_page_updates {
let mut reordered_page_update: Vec<i64> = Vec::new();
for page in page_update {
let inserted = if let Some(rule_set) = page_rules.get(&page) {
let mut inserted = false;
for (i, reordered_page) in reordered_page_update.iter().enumerate() {
if rule_set.contains(reordered_page) {
reordered_page_update.insert(i, page);
inserted = true;
break;
}
}
inserted
} else {
reordered_page_update.push(page);
true
};
if !inserted {
reordered_page_update.push(page);
}
}
fixed_updates.push(reordered_page_update);
}
let accumulator = accumulate_middle_pages(fixed_updates);
println!("Sum of middle pages from fixed updates: {}", accumulator);
Ok(())
}

7
day_06/Cargo.lock generated Normal file
View File

@@ -0,0 +1,7 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
version = 4
[[package]]
name = "day_06"
version = "0.1.0"

6
day_06/Cargo.toml Normal file
View File

@@ -0,0 +1,6 @@
[package]
name = "day_06"
version = "0.1.0"
edition = "2024"
[dependencies]

197
day_06/README.md Normal file
View File

@@ -0,0 +1,197 @@
https://adventofcode.com/2024/day/6
# --- Day 6: Guard Gallivant ---
The Historians use their fancy device again, this time to whisk you all away to the North Pole prototype suit manufacturing lab... in the year 1518! It turns out that having direct access to history is very convenient for a group of historians.
You still have to be careful of time paradoxes, and so it will be important to avoid anyone from 1518 while The Historians search for the Chief. Unfortunately, a single guard is patrolling this part of the lab.
Maybe you can work out where the guard will go ahead of time so that The Historians can search safely?
You start by making a map (your puzzle input) of the situation. For example:
....#.....
.........#
..........
..#.......
.......#..
..........
.#..^.....
........#.
#.........
......#...
The map shows the current position of the guard with ^ (to indicate the guard is currently facing up from the perspective of the map). Any obstructions - crates, desks, alchemical reactors, etc. - are shown as #.
Lab guards in 1518 follow a very strict patrol protocol which involves repeatedly following these steps:
- If there is something directly in front of you, turn right 90 degrees.
- Otherwise, take a step forward.
Following the above protocol, the guard moves up several times until she reaches an obstacle (in this case, a pile of failed suit prototypes):
....#.....
....^....#
..........
..#.......
.......#..
..........
.#........
........#.
#.........
......#...
Because there is now an obstacle in front of the guard, she turns right before continuing straight in her new facing direction:
....#.....
........>#
..........
..#.......
.......#..
..........
.#........
........#.
#.........
......#...
Reaching another obstacle (a spool of several very long polymers), she turns right again and continues downward:
....#.....
.........#
..........
..#.......
.......#..
..........
.#......v.
........#.
#.........
......#...
This process continues for a while, but the guard eventually leaves the mapped area (after walking past a tank of universal solvent):
....#.....
.........#
..........
..#.......
.......#..
..........
.#........
........#.
#.........
......#v..
By predicting the guard's route, you can determine which specific positions in the lab will be in the patrol path. Including the guard's starting position, the positions visited by the guard before leaving the area are marked with an X:
....#.....
....XXXXX#
....X...X.
..#.X...X.
..XXXXX#X.
..X.X.X.X.
.#XXXXXXX.
.XXXXXXX#.
#XXXXXXX..
......#X..
In this example, the guard will visit 41 distinct positions on your map.
Predict the path of the guard. How many distinct positions will the guard visit before leaving the mapped area?
Your puzzle answer was 5101.
# --- Part Two ---
While The Historians begin working around the guard's patrol route, you borrow their fancy device and step outside the lab. From the safety of a supply closet, you time travel through the last few months and record the nightly status of the lab's guard post on the walls of the closet.
Returning after what seems like only a few seconds to The Historians, they explain that the guard's patrol area is simply too large for them to safely search the lab without getting caught.
Fortunately, they are pretty sure that adding a single new obstruction won't cause a time paradox. They'd like to place the new obstruction in such a way that the guard will get stuck in a loop, making the rest of the lab safe to search.
To have the lowest chance of creating a time paradox, The Historians would like to know all of the possible positions for such an obstruction. The new obstruction can't be placed at the guard's starting position - the guard is there right now and would notice.
In the above example, there are only 6 different positions where a new obstruction would cause the guard to get stuck in a loop. The diagrams of these six situations use O to mark the new obstruction, | to show a position where the guard moves up/down, - to show a position where the guard moves left/right, and + to show a position where the guard moves both up/down and left/right.
Option one, put a printing press next to the guard's starting position:
....#.....
....+---+#
....|...|.
..#.|...|.
....|..#|.
....|...|.
.#.O^---+.
........#.
#.........
......#...
Option two, put a stack of failed suit prototypes in the bottom right quadrant of the mapped area:
....#.....
....+---+#
....|...|.
..#.|...|.
..+-+-+#|.
..|.|.|.|.
.#+-^-+-+.
......O.#.
#.........
......#...
Option three, put a crate of chimney-squeeze prototype fabric next to the standing desk in the bottom right quadrant:
....#.....
....+---+#
....|...|.
..#.|...|.
..+-+-+#|.
..|.|.|.|.
.#+-^-+-+.
.+----+O#.
#+----+...
......#...
Option four, put an alchemical retroencabulator near the bottom left corner:
....#.....
....+---+#
....|...|.
..#.|...|.
..+-+-+#|.
..|.|.|.|.
.#+-^-+-+.
..|...|.#.
#O+---+...
......#...
Option five, put the alchemical retroencabulator a bit to the right instead:
....#.....
....+---+#
....|...|.
..#.|...|.
..+-+-+#|.
..|.|.|.|.
.#+-^-+-+.
....|.|.#.
#..O+-+...
......#...
Option six, put a tank of sovereign glue right next to the tank of universal solvent:
....#.....
....+---+#
....|...|.
..#.|...|.
..+-+-+#|.
..|.|.|.|.
.#+-^-+-+.
.+----++#.
#+----++..
......#O..
It doesn't really matter what you choose to use as an obstacle so long as you and The Historians can put it into position without the guard noticing. The important thing is having enough options that you can find one that minimizes time paradoxes, and in this example, there are 6 different positions you could choose.
You need to get the guard stuck in a loop by adding a single new obstruction. How many different positions could you choose for this obstruction?
Your puzzle answer was 1951.
Both parts of this puzzle are complete! They provide two gold stars: **

130
day_06/input.txt Normal file
View File

@@ -0,0 +1,130 @@
...#....#................................#..........................#..........#.............#..#.................................
.......#........................#.......#......................#............#.....................................................
..#......#....................................................................................#.......#................#..........
..................#...........#...#..#............................#.........#...................#...............................#.
..#...................................................................................................................#....#......
............#.............................#......................#.......#...........#..................##..............#.........
..............................#................................................#.............................................#....
....................#.#...........#...#....#..............#.........#.........#..................#...........#.................#..
.#........................................................................#.....#.......##.....................#..................
.#........................#..................................#............................#...#..........#.......#.............#..
................................#......#...............#...........................#.............................#..#.#...#....#..
..........................................................#..........#..#.......#........#............#.................#.........
......#.......#......................................................................................#................#...........
##......#...................................................#................#............................#.......................
.....#.................................................................#.....................#...............................#...#
...........................................................................................................#......................
........#......................#..........#..#....#....................#..##...........#..#.............................#.#......#
#...#..................#.....................#...#...#.......................................................#.....#..............
#...#..................#.#....#...............#...........#...................#.....##......................................#.....
......#............................................................................................#...#.#........................
......................................................#..............#.....#.....#..#...........#..............................#..
.........................##.#..............#............#....................................................................##...
..#....................#...........................................................................................#......#.##....
..............#........#..#.......#................#.....#.......................................................................#
.........#..........................#........#..........#...............#...................................#.............#.......
...........#.....................#.....#..............#......#.........................................#..........................
.......##.............................#.........#...............#...............#..............................................#..
.......#.....#.....#...........#............................................................................#..............#.....#
....#.............................................#....#....#....#...........................................##..............##...
.#.............#.......#.....#.........#....#......#.............#............#......#............#......................#........
..................................................................................................#....#..........................
.............................................#....................#...............................#.............#.................
.........#...............#.....................#...............#......#.................................................#.........
..........#.................................................................................#..............#..............#.....#.
.........................#........#.....#............#.....................#.......................................#..............
.....................#.....................#..............................#..................................#..........#.........
........................#.....................#..............................#.#................#.................................
.....................................................#...............#.......................................................#....
.................#.......#......##..............................##.................#..........................#....#....#........#
.............................#................................#..#...........#..........#.........................................
.#...........................#........#.#...#...#....#......#......#...........#..................##.........................#....
.......................................#......................................#................................................#..
..........##......#..............................................................#.......#....................#..#......#.........
.#...............#............#....#....................................^......#.........................................#.#......
.................#....................#..#....#.......................#.............................#.....#.....#............#....
...............................................................#...............##.................#........#.#....................
...................................#..#.........#.........#...............#.........#.......................................#.....
.........................#......................................................................................#............#....
.................................#............#............#.............................#........................................
..........#.........#...........................................#..#...#..#.......................................................
.#....#....#..........................................#.....#..........................................................#..........
...#...............#......................................................................#.............................#.........
....#......................#...........#......................................#..............#...........................#........
.......................................................#...........#.......#..............................#.......................
......#............#.#...........#............#...................#..................#................................##..........
.......#..........................................................................................#.....................##........
....................................#.........#..................##....................#.#...........#......................#.....
.........................#...............................................................#....................#...................
...............................#........................................................................#....................#....
..#.#.......................................................................#..........#.........#........#.......................
....#....#.....................#.............#..#........................#.............#.....#....................................
..#............................................................................#....................#.................#.....#.#...
..............................................#........#............##.#..............#...#...................#...................
.............................#..................#..................#.................................#............................
......#................................#....#..................................#............#.....................................
#..........#...#..................#...............................................................................................
......................................#......................................#.......#....#.......................................
......................................................................#......................................#...........##.....#.
.......#.............#................................................#.....#..#......#......................................#....
..........................................#...............#...#........#..........................................................
#..#......#..........#....#.......................................................................................................
.......#..#............................................................#........#...#.#...........................................
.#....#...#..#................................................#......................#............................................
.........................#...........#..........#............#...............................#...#...#..................#.........
....#......................#......#.......#....................#..........................#...............................#.......
.........................#...............#.........................#.........#..................................#.................
...............................#......................................................#...........................................
..................................................#.........................#...................#......#..........................
...................#.##..............................#................#........#..............................#...................
.#.................#..............................#................#............................#............#................#...
............#..............#....................................#.....#.....#..........#................#.........................
...................#.............................#...........##...........................................#.......................
.#.............##...........#............##...#.........................................................................#.......#.
........#................#....................#..........#....#.......#.#..............#..............#.................#.........
............................#..#...#..........................................................#......#............................
.........#.................#......#.............................................#...##.....#.................................##...
............#..........................................................................#..........#...................#...........
....................................#.............#............#..................#....#.#.......................#...#............
......#...................................................##....................................................................#.
...............................#.............#.#...............#.......................................#.#.......................#
..........#............................#....#.#.#.#..............................................................#................
....#...#............#.#.................................................#.....................................#.#................
...........#...............................##.........#............#.....................#........................................
...................#.............................#.........#..............................................#.....#.................
.........#................#.........#.............#.............#...#...........................................................#.
.....#...........................#............##............#................#...............................#.............#..#...
................#.#.......#.................#...................................................#.........#..........##.#.........
.........................#.................#...............#...........................#............#.............#..............#
...................#......#...........................#.....#.....................................................#...............
......#...........##......#..................#......#............##................................#..............................
....................#.........#...........................................................................................#....#..
................................................#....#.....#..#........................#....................##....................
........#...........#....#.......#..........##............................................#.......#.........#...#...............#.
#.#.....#.#..............................................#...#...............#..........#................##.........#..........#.#
#........................#...#.........#........#..............................................................#..................
..................................................................................................................................
...........................................#..#..........................................#...................#....................
...................#.............#.....#..................................................#...................................#...
................#...........................................................................#.#...#...............................
........#.......#......#...........................................#....................................#......#............#.....
...............#.......#....................#.....................................................................#...............
..............##....#.............................#......................#.....#......#........................................#..
............................#.........#.....................#.....................................................................
#....................#...................##........#...#........#......#....#..........................................#.#.......#
..#............#...#...............................#.#....................#....................................#..............#...
..................#..#.......#......#.....#.......#.................#.....#...................................#.............#.....
.......................#..............#.........#............#.......#.................................................#.....#....
................#.....................................................#.#.............................#.........#...........#.....
......................#.................................##..................................#.................................#...
.......................................#........................................................................#.................
.........#...........#..............#......................#................................#..#.......................#..........
...................#..................#...#....#......................................................#...........................
..............................#.........#................................#............................#...........................
........#....#...................................................................##........#......................................
..................................#...................#...................#.#.......#.............#..............................#
.....................................#...##...............................................................................#.......
......................#.......#.............#.......................#..#.....#......................#.................#...........
.....##...........#.......#................#.................................#...##......#......#...............#.......#.#.......
.....#...#...............#......................#........#..........#..##...#...#........#..........#.............................
#...........#.............#...............................#..............................#...#.#........#.........................

10
day_06/small_input.txt Normal file
View File

@@ -0,0 +1,10 @@
....#.....
.........#
..........
..#.......
.......#..
..........
.#..^.....
........#.
#.........
......#...

266
day_06/src/main.rs Normal file
View File

@@ -0,0 +1,266 @@
// https://adventofcode.com/2024/day/6
//
// Run command: cargo run ./input.txt
use std::{
collections::HashSet,
env,
error::Error,
fmt::Display,
fs::File,
io::{BufReader, prelude::*},
};
#[derive(Debug, Clone, Copy, Hash, PartialEq, Eq)]
enum Facing {
Up,
Down,
Left,
Right,
}
#[derive(Debug, Clone, Copy, Hash, PartialEq, Eq)]
struct Position {
x: isize,
y: isize,
}
impl Position {
fn new(x: isize, y: isize) -> Position {
Position { x, y }
}
fn x(&self) -> isize {
self.x
}
fn y(&self) -> isize {
self.y
}
fn advance(&mut self, facing: Facing) {
match facing {
Facing::Up => self.y -= 1,
Facing::Down => self.y += 1,
Facing::Left => self.x -= 1,
Facing::Right => self.x += 1,
}
}
fn next_position(&self, facing: Facing) -> Position {
let mut next_position = *self;
next_position.advance(facing);
next_position
}
}
#[derive(Debug, Clone, Copy, Hash, PartialEq, Eq)]
struct Guard {
facing: Facing,
position: Position,
}
impl Guard {
pub fn new(position_x: isize, position_y: isize, facing: Facing) -> Guard {
Guard {
facing,
position: Position::new(position_x, position_y),
}
}
fn turn_clockwise(&mut self) {
match self.facing {
Facing::Up => self.facing = Facing::Right,
Facing::Down => self.facing = Facing::Left,
Facing::Left => self.facing = Facing::Up,
Facing::Right => self.facing = Facing::Down,
}
}
fn advance(&mut self) {
self.position.advance(self.facing);
}
fn position(&self) -> &Position {
&self.position
}
fn next_position(&self) -> Position {
self.position.next_position(self.facing)
}
}
#[derive(Debug, Clone)]
struct Map {
data: Vec<Vec<bool>>,
width: usize,
height: usize,
}
impl Map {
pub fn new(data: Vec<Vec<bool>>) -> Map {
let height = data.len();
let width = data[0].len();
Map {
data,
width,
height,
}
}
pub fn width(&self) -> usize {
self.width
}
pub fn height(&self) -> usize {
self.height
}
pub fn get_location(&self, x: isize, y: isize) -> Option<bool> {
if x < 0 || x >= self.width as isize || y < 0 || y >= self.height as isize {
return None;
}
Some(self.data[y as usize][x as usize])
}
pub fn get_position(&self, position: Position) -> Option<bool> {
self.get_location(position.x(), position.y())
}
pub fn add_obstruction(&mut self, position: Position) -> Option<bool> {
match self.get_position(position) {
Some(previously_obstructed) => {
self.data[position.y() as usize][position.x() as usize] = true;
Some(previously_obstructed)
}
None => {
// Outside bounds, so we do nothing and return None
None
}
}
}
}
impl Display for Map {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
writeln!(f, "Map:")?;
for row in &self.data {
write!(f, " ")?;
let row = String::from_iter(row.iter().map(|b| if *b { '#' } else { '.' }));
writeln!(f, "{}", row)?;
}
Ok(())
}
}
fn load_map(input_file: &str) -> Result<(Map, Guard), Box<dyn Error>> {
let buffer = BufReader::new(File::open(input_file)?);
let mut lines = buffer.lines().peekable();
let width = match lines.peek() {
Some(l) => match l {
Ok(li) => li.len(),
Err(_) => Err("Error reading first line of map file")?,
},
None => Err("Cannot load empty map file.")?,
};
let mut data: Vec<Vec<bool>> = Vec::new();
let mut guard_position = Guard::new(0, 0, Facing::Up);
for (y, line) in lines.enumerate() {
let line = line?;
if line.len() != width {
println!("{}", line);
Err("Line length of input are not consistent")?;
}
let parsed_data: Vec<bool> = line
.chars()
.enumerate()
.map(|(x, c)| {
if c == '^' {
guard_position = Guard::new(x as isize, y as isize, Facing::Up);
};
c == '#'
})
.collect();
data.push(parsed_data);
}
Ok((Map::new(data), guard_position))
}
fn simulate_guard_path(mut guard_position: Guard, map: &Map) -> (usize, bool) {
let mut visited_set: HashSet<Position> = HashSet::new();
visited_set.insert(*guard_position.position());
let mut guard_states_set: HashSet<Guard> = HashSet::new();
let mut infinite_loop = false;
loop {
if guard_states_set.contains(&guard_position) {
infinite_loop = true;
break;
}
let next_position = guard_position.next_position();
match map.get_position(next_position) {
Some(true) => {
guard_position.turn_clockwise();
}
Some(false) => {
guard_states_set.insert(guard_position);
guard_position.advance();
visited_set.insert(next_position);
}
None => break,
}
}
(visited_set.len(), infinite_loop)
}
fn main() -> Result<(), Box<dyn Error>> {
// Handle command input
let args: Vec<String> = env::args().collect();
if args.len() != 2 {
panic!(
"{} must be run with a single argument of file name!",
&args[0]
)
}
let input_file = &args[1];
let (map, guard_position) = load_map(input_file)?;
println!("{}", map);
println!("{:?}", guard_position);
let (locations_visited, infinite_loop) = simulate_guard_path(guard_position, &map);
println!("infinite_loop={}", infinite_loop);
println!("Number of locations visited: {}", locations_visited);
let mut count_looping_obstruction_locations = 0;
for y in 0..map.height() {
for x in 0..map.width() {
let position_to_obstruct = Position::new(x as isize, y as isize);
match map.get_position(position_to_obstruct) {
Some(currently_obstructed) => {
if position_to_obstruct != guard_position.position && !currently_obstructed {
let mut new_map = map.clone();
new_map.add_obstruction(position_to_obstruct);
let (_, infinite_loop) = simulate_guard_path(guard_position, &new_map);
if infinite_loop {
count_looping_obstruction_locations += 1;
}
}
}
None => panic!("This should never happen!"),
}
}
}
println!(
"Number places you can place obstruction to cause the guard to infinitely loop: {}",
count_looping_obstruction_locations
);
Ok(())
}

7
day_07/Cargo.lock generated Normal file
View File

@@ -0,0 +1,7 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
version = 4
[[package]]
name = "day_07"
version = "0.1.0"

6
day_07/Cargo.toml Normal file
View File

@@ -0,0 +1,6 @@
[package]
name = "day_07"
version = "0.1.0"
edition = "2024"
[dependencies]

850
day_07/input.txt Normal file
View File

@@ -0,0 +1,850 @@
82042417: 7 5 192 12 8 82 8 1 6 9 1
2580: 252 9 212 98 2
3554112: 2 515 8 4 856
127435: 7 72 6 51 1 5 222 7 6 7 7
600421542065: 241 56 478 116 52 30
18582: 5 588 3 3 826 26 3 3 6
2907: 4 726 3
1334594: 8 834 492 5 94
11464362: 5 84 98 87 57 5 78 9
6165: 6 55 20 6 38 1
743449725: 8 9 2 269 246 17 3 3 75
265518: 1 99 3 6 149
215288: 5 3 4 4 2 4 8
7272: 717 8 1 4 9
79460193082650: 9 98 89 9 930 82 650
18337280: 616 3 37 152 2 32
869638795708: 57 4 852 31 466 38
418327253: 806 6 2 634 3 963 47 5
2408091537: 70 344 91 535 1
71186: 943 8 4 882 378 8 722
509646: 5 7 7 7 89 3 94 7 3 3 36 6
65366: 9 7 9 4 54 7 879
2229016465: 6 89 237 99 25 6 465
155: 14 2 13
2116248444: 3 933 2 7 14 6 9 6
393021858: 74 8 793 663 99
27222056614: 33 197 63 82 1 4
3327312: 8 93 613 16 1 5 42 9 14
113110367: 770 254 73 7 89 17
8780457: 235 642 949 7 960
1509: 21 48 49 12 93
34641: 337 8 75 1 65
11744767: 22 58 4 9 52 619
22531: 48 1 4 9 8 4 7 77 727 6 7
5252: 8 3 178 4 12 2
1522: 33 7 4 717 2
337392518: 58 7 831 6 518
116800: 32 4 18 8 20
2233246681792: 77 3 8 57 1 2 80 96 7 86
6584995387: 6 13 392 802 84 17
111052288: 9 25 3 660 2 642 4 6 6 6
53874653: 42 9 8 4 7 3 43 8 4 4 82
2749437: 3 475 2 51 79
1003: 35 7 9 95 421 436
11931540: 5 6 93 153 8
1651: 44 5 761 417 28
1926656: 71 9 3 57 908 6
3218061121: 42 5 8 108 433 737
69028: 590 295 7 693 14 7
7988724: 83 7 5 2 3 8 9 3 81 929 9
5533444: 5 6 306 35 6 98 83
51450028: 8 4 9 4 9 2 13 9 3 3 7 4
17146971648: 81 9 4 36 3 27 4 8 752
83507688: 9 2 5 421 645 588 291
1737402116: 435 33 931 5 633 26 8
12421568663642: 77 70 845 68 6 636 42
21760: 661 8 11 8 4
39002586: 525 64 7 106 98
1668692704: 36 83 626 4 8 5 399 56
335560368: 12 3 3 97 366 13 8 682
4244333: 42 2 689 4 35 93
4311422208: 364 685 5 818 4 8 9 4 3
286270: 7 47 221 5 4 1 7 5 1 6 7 3
44451241073: 51 31 89 470 281 3
5015508: 18 5 218 94 7 564
74778098: 22 55 1 618 98
487307415: 73 9 1 7 212 7 287 565
276695: 49 968 62 4 8 8 465 6
7449846: 6 2 737 5 192 824 62
1378920140201: 5 3 321 325 9 891 9 9
1407403: 33 4 76 1 343 763
1845694633: 1 5 677 3 1 77 18 9 6 3 4
707459260: 1 28 1 8 4 21 31 8 2 6 3
547220811: 912 60 24 115 5 685 8
137301177675: 32 7 828 55 507 675
7451982902: 7 6 789 413 1 9 7 8 6 97
1646069845: 4 81 4 5 7 50 6 98 42 3
423103729: 8 47 5 1 4 9 43 38 3 29
501413058: 9 260 25 42 7 54
6766589: 254 74 90 4 29
1407127249: 5 873 8 5 2 3 8 724 6 3
22767125: 1 9 25 3 851 7 125
586463195: 8 42 6 6 3 8 385 71 85
2160452: 94 30 766 4 328
14083090: 80 33 865 41 98
187721659: 131 56 720 83 82 9
1027: 11 2 79
32: 4 3 2 10 8
263256283575: 99 954 25 62 8 3 57 5
37170: 1 582 3 5 63
377341867: 3 8 30 783 9 2 26 218
4188173044: 81 116 782 57 6
979: 6 7 877 54 6
13232: 77 7 23 835
4264: 13 371 8 369 44
16377515: 394 815 9 7 51 89
4680761405: 5 71 2 60 7 61 3 29 77
32046982: 92 8 1 8 3 6 57 9 5 74 4
357612: 723 284 355 47 68 5 7
1979: 878 580 4 275 242
4041171478: 8 7 1 2 7 2 1 76 36 9 3 23
1071675: 74 965 35 3 5
59261728680: 54 7 4 1 1 7 22 785 4 81
84516446: 60 368 87 2 14
794869179: 60 81 9 95 5 9 7 29 1
3385720: 8 266 64 571 8
946846: 879 6 61 783 64
10066: 61 6 633 7 5
9229111592: 922 7 2 110 9 6 1 1 7 5
21742576: 7 6 5 1 4 4 833 76 1 2 4 4
1880: 8 8 314 723 4 707 3 65
4974334113837: 491 1 63 3 341 1 383 7
1980: 79 6 1 607 89 810
914511: 13 9 6 451 3 70 9 2 9 4 3
12037223: 2 2 7 249 5 224 4 7 5 2 3
14566483: 75 816 876 1 8 4 82 3
858: 6 5 1 1 1 78
931135319105: 57 957 3 49 17 5 945 5
3895507111: 8 507 768 42 711 4
204523320: 8 964 35 66 5 7 6 4 1
4416: 88 96 8 3
67034: 66 964 6 5 54 5
700206: 67 9 85 358 929 5 78
745422: 94 44 428 3 439
47440: 472 6 1 1 4 1 9 8 7 3 5 9
100915823046: 2 3 9 8 4 77 794 6 3 41 6
6064691: 6 95 6 4 691
76052: 1 77 975 2
65482: 6 535 13 2
6975: 1 700 621 39 34 5
18156255: 437 4 2 674 258
4268960: 9 415 9 7 44 41 8 4
92110132224: 6 52 2 5 4 6 16 97 969 8
549947: 196 28 4 5 5 81 5 717
854444814: 3 4 6 1 295 7 8 16 13
5281757: 286 3 15 1 6 29 6 3 7 7
252349405: 6 8 15 1 8 899 73 9 385
19673804880: 65 558 54 4 45 51 59
383488: 2 1 98 9 651 56 2 4
13621: 76 51 3 1 34 985 974
38967484: 8 1 5 8 59 2 24 39 482 2
27342247: 256 3 751 3 6 247
15734: 4 4 978 6 80
1571395: 17 3 46 2 7 8 7 95
83562: 62 1 5 6 4 1 16 649 4 1 6
61624782824: 96 95 529 908 7 500
1107112: 2 601 1 51 36 4
16778202: 8 2 1 5 7 9 2 6 165 5 6 1
138664: 9 8 3 3 906 46
844009: 7 68 6 2 6 203 602 2 5
9368306308: 9 3 33 35 21 9 6 30 6
43332149: 3 4 78 2 5 8 69 55 94
854701: 11 14 11 74 2 21 1
26847296: 433 62 776 4 516
279235: 6 93 42 5 5
3486120720: 7 661 3 5 65 7 8 8 5 8 64
5054: 49 1 54
84392160: 586 6 340 3 8
354455198890: 385 277 390 1 92
156146585: 78 2 137 9 579 6
16431072: 3 648 1 5 6 8 5 29 3 9 1 7
68684: 93 8 68 4
7385614: 246 3 55 70 42
66220840: 91 81 385 708 132
441696: 6 4 594 191 9 8 16 248
1698162977: 82 5 82 3 415 78 2 2 4 1
1035271918: 2 8 667 1 6 2 97 4 3 18 8
6240240: 3 7 8 1 39 8 21 9 3 216 6
23215498: 8 9 2 8 9 9 984 9 23 4 8 7
2722917882: 228 71 7 74 64 170
132544765: 556 3 76 76 765
254959068: 55 1 68 9 96 91 83
19458: 1 66 139 1 94
26352: 376 4 142 2 8 8 8
2071416: 5 8 5 7 4 6 159 7 6 1 80 9
10006390: 7 801 4 9 344 115 3
1206452203650: 2 14 696 71 65 810
142568786242: 1 584 9 872 6 62 37 5 1
25986: 17 2 572 96 37 567
5636751122: 4 52 3 6 74 4 41 670 9
9265906: 4 8 6 8 9 45 348 21 4 58
654: 4 5 90 5 2 6 9 2 1 3 199 6
1169: 8 4 5 9 1 78 3 7 61 6 45 1
13776086: 3 6 8 1 79 565 5 1 46 5 6
36373363267: 41 82 906 96 70
2851304: 75 6 44 800 104
1591645: 83 599 421 6 785 43 5
15591: 1 864 2 1 3 6
280828: 1 3 27 118 7
47926943: 52 37 223 3 68 753
2240: 208 2 6 6 975
808084: 545 6 7 5 900 1 90 1 7
965453818: 473 9 6 1 1 7 9 892 2 34
47700: 443 34 2 10 5
60081595: 594 6 80 6 35 72 888
51765424906: 96 5 4 493 3 5 7 4 906
9732: 67 74 7 3 80 7 5 6
252517230191: 835 8 3 3 2 378 174 17
84474639541600: 4 90 4 28 483 800 769
1189017437355: 4 2 323 95 5 37 887 99
587144716: 53 17 4 7 682 2 1 831 4
27031122: 4 2 5 1 79 66 4 36 4 1 6 3
102799: 3 922 973 21 4
346500171: 2 88 55 70 170
5132997233: 56 3 7 1 58 2 901 230 3
44065984: 57 76 99 63 72 66 30 4
105159: 659 607 1 83 81
10108602: 52 7 1 6 10 3 1 9 511
184443: 41 1 143 4 46
44700: 39 54 4 5 6 2
1316022593: 6 61 782 912 1 6 592
24538370210: 24 518 15 5 370 207
3324805704: 3 4 484 8 6 7 8 6 81 99
904128000: 45 5 30 4 272 554
11628152: 6 4 88 9 6 97 3 8 6 84 76
782106380: 790 99 63 18 62
2208104: 69 70 6 74 76
1187200644: 6 2 2 54 7 1 1 96 2 2 641
51106677924: 35 2 73 667 79 10 14
171010225: 3 1 73 5 89 1 2 10 225
7008750: 252 3 590 2 6 15 25
758394873: 758 394 863 4 7
1170182: 4 975 60 3
6427825250: 79 620 74 7 350 5 71
105568282766: 897 294 4 810 827 66
441936099: 7 4 5 5 620 288 1 9 99
10286: 238 4 186 4 6
6646548: 70 63 941 257 8
342551514: 2 9 457 3 3 7 9 31 6 9 1 4
794584: 30 975 4 3 31 196
32321: 1 95 339 42 74
264538971216: 3 79 1 127 458 2 536 6
47079978: 4 4 461 987 78
39123068781: 705 68 1 1 2 77 4 5 8 2 9
7983435214: 924 9 4 3 3 39 8 1 7 1 8 2
6820: 6 62 1 8 2
801941971: 43 2 736 9 890 964 3 7
16464: 2 33 97 5 98
2056737: 3 39 2 3 9 9 37 9 9 3 90 2
63530: 6 17 824 75 5
861664: 169 5 5 66 5 108 5 7 3 4
3076568831166: 9 7 8 9 11 28 4 1 66 6 6
552769: 895 1 44 5 83 7 2 3 14 7
521743: 5 77 3 53 61 9
367950978896: 919 2 1 7 5 45 3 9 2 896
5856046: 946 29 6 6 7 7 1 88 9 6 6
271166253: 5 7 291 832 32 804 9
4183386: 7 90 39 7 67 7 5
99538988: 192 749 41 3 860 7 1
922179: 922 151 9 19
389862: 332 35 86 77 31 3 11
35131284: 9 74 829 897 84 78 6
3268318: 728 89 4 254 64
97544442: 6 2 1 93 8 437 5
2195535: 6 3 3 701 58
4851: 86 1 60 9 8 251 3 7 371
18853063359: 822 46 6 831 4 2 1 1 98
75389016612: 37 71 949 9 8 1 25 7 3 2
37529: 3 8 3 519 161
12511908: 4 524 138 375 69 36
110080572017: 72 91 41 5 6 28 17
869149: 6 79 92 99 46
1858869754: 7 4 3 419 4 20 9 9 8 5 3 1
502936: 319 4 7 56 7
45611: 152 3 10
43680: 4 16 40 4 182
599510566: 6 427 22 424 6
1866641985: 802 6 663 485 585
278576: 73 945 659 1 4
1099308900: 843 93 123 7 2 8 3 9 61
114456696: 19 95 456 6 98
7193495: 5 862 3 4 40 52 8 2 7 8 6
443284986: 92 35 2 227 83 2 3 46 6
582: 1 93 488
11761: 12 4 234 84 2 88 3 1 3 4
4845605: 48 3 34 57 2 73 331 1
1690: 99 87 909 54 24 517
55019728696: 9 33 9 7 9 8 41 3 8 2 695
10962253824: 96 90 9 81 93 8 8 218 1
15494491: 5 11 333 9 94
1563280482: 287 366 34 5 585 2 8 2
731484438: 36 4 10 3 282 521 437
1121: 7 12 32 504 9
232722: 6 91 214 21 46 7
137003592: 22 663 50 8 98 4
51876: 259 8 9 6 5 69 24 2 4 6
3863340: 5 46 11 509 8 2 3
563742422208: 60 4 649 98 96 249
90736: 906 8 5 1 31 20
4528: 60 7 2 35 902 6 40 4 60
99699: 9 6 3 69 6
1214: 9 29 4 88 1 875 210
330644788: 71 87 93 46 8
5010: 7 2 69 21 21 1
14340: 17 50 4 449 20
1445594511764: 108 38 74 326 476 4
109588: 5 3 7 7 44 9 7 2 8 7 5 747
3209365: 323 23 48 3 3 3 10
1844721: 9 1 6 91 6 9 6 2 161 8 2 1
126894624: 9 30 2 4 7 6 2 4 2 567 21
7030625: 8 64 20 83 70 14 875 5
306035: 163 1 7 3 6 32
1187: 320 51 3 1 73
18151127284: 358 76 8 66 28 9 792 4
26862096682: 9 730 1 121 32 3 681 1
131688: 20 619 6 204 100 8
584180: 78 3 9 7 1 100 2 54 1 6 8
510077: 75 68 6 1 7
6295698: 503 116 9 96 698
3708373817: 9 8 9 31 3 5 33 1 521 1 7
1780365283548: 8 9 5 5 4 566 8 3 51 5 30
1100018: 664 1 6 4 4 2 275 8 8 2 1
3789: 8 467 50 1 3
474966: 59 358 13 8
109552579: 4 978 1 55 4 3 9 509
16318811991: 3 23 4 841 3 3 6 11 9 9 1
43842584: 913 1 6 3 2 4 7 2 5 1 23 8
70010209766: 80 9 5 5 3 9 3 3 2 6 221 8
56690634117: 776 58 3 9 7 1 2 47 73
70605: 250 4 3 3 702 7 4 19 1
24992234: 4 89 702 29 6 935 67
59286529134: 21 8 408 8 84 378 3
114794780: 7 3 2 4 3 46 8 8 9 8 7 78
34225880: 718 7 37 130 52
372240: 5 72 88 3 1 1 752
92561: 3 4 7 8 908 7 8 9 97 6 8 9
1788: 40 946 802
10280: 233 2 987 603 5
1022892576: 11 1 7 44 95 6 2 6 4 6 4
18581414: 37 93 2 27 17
42933785: 6 423 32 925 860
586: 1 6 82 94
6399: 8 8 8 7 9
678687802: 2 4 8 7 87 859 7 8 40 8 4
8668343520061: 3 7 6 23 8 15 5 12 48 61
1838: 4 6 56 8 31 10 1 8 780
21041178: 612 18 6 23 2 83 3 4 6 1
19897605: 91 5 694 65 7 9
8775425450: 835 740 5 74 2 5 2 3 7 8
3871: 4 6 55 3 7
558008: 9 8 175 7 7 53 9 6 44 1
2919622388: 811 1 6 3 1 1 1 9 1 2 5 1
1059118768: 4 17 8 9 507 1 5 5 9 9 3 9
263727849491: 1 9 27 337 54 6 127 9
14381413: 1 7 4 573 9 273 796 1 3
82052628903: 5 721 8 8 5 5 448 65 9 7
333340: 3 11 24 9 3 6 4
1074564: 65 5 146 3 228
21086456116: 2 8 7 1 2 7 5 40 94 50 66
58793: 8 342 56 1 7
3461525: 41 55 15 830 425
19055232: 2 7 536 4 2 9 7 8 1 68
1383999: 2 7 40 368 1 748 10 99
14162750262: 9 7 73 5 1 3 5 755 6 8 4 8
21591892257: 790 91 178 7 17 39
152259: 3 49 99 8 126 2 49
60458946: 6 23 2 195 88 8 1 5 60
130368: 9 7 64 21 1
42810084: 1 791 72 6 35 6 9
10299: 19 71 34 7 386 225 7
630740: 9 621 366 374 1
607: 56 4 1 7
1413736709100: 918 55 596 8 6 7 5 9 2 8
898415963432: 326 84 83 2 2 58 571
1438948288006: 69 73 737 7 2 400 6
1152: 213 5 8 3 67 8 1
5714: 33 55 4 6 68 1 3 29
170131421784: 6 2 686 5 4 27 66 4 59 8
4060: 1 3 23 5 30 10
7706289: 13 4 53 838 9 943 93
336: 6 54 6 2 4
283524329545: 6 4 4 88 9 319 6 5 9 5 4 5
56777: 86 3 793 54 23
9525: 3 731 973 9 3
120152808: 8 406 9 6 2 37 76 54
271057945: 9 45 211 589 5
881144: 41 87 4 42 589 1 17
991: 7 5 3 904 6
2834614: 78 2 440 497 41
13580362: 20 679 34 8 17
36635: 4 31 85
1138576325: 71 5 805 1 2 16 5
2940716494: 49 88 96 24 3 2 296 6
4273426: 1 6 2 106 65 161 5 8
956124: 3 7 1 5 3 31 5 1 977 7 36
569155356942: 7 5 4 8 3 4 5 4 77 3 1 945
44416728: 2 3 147 466 3 5 757 36
3126568575: 9 6 4 2 1 7 38 56 857 2
2205314: 5 867 6 508 86
24302: 9 15 278 4 20
2859438598: 72 266 395 1 845 2 1
37923486: 2 4 4 4 3 8 331 62 4 14 4
14138920: 4 69 8 6 38 5 40 39 5 26
26029: 9 464 2 323 3 4
4574281: 2 852 4 8 125 5 961 5
919442: 3 2 6 9 2 12 7 622 2 269
11187126629: 1 97 9 174 3 501 7 5 1 7
1732752: 2 4 4 3 2 7 1 54 1 772 9 7
7686: 5 3 6 6 98 702 9
3031374168: 11 956 1 8 6 36 8 2 7 1 8
644520102: 925 715 3 131 102
4765080664800: 7 9 1 762 14 7 200 709
96471: 1 9 939 228 6 6 3 27 3
30985: 30 4 5 82 3
4059067834: 2 3 18 1 98 88 78 27 7
48735: 2 9 60 8 515 45
1369: 3 7 5 151 63 4 4 70 1 6
636174772137: 93 5 3 63 4 85 7 84 9 9
4851957505: 4 84 4 9 763 8 5 8 8 4 3 1
244514: 355 7 98 83 901
1405481: 1 6 5 57 6 39 7 3 3 3 71
20940131: 4 48 339 1 5 8 972 4 11
205146: 408 8 493 57 1
13543116: 4 498 5 742 1 36 3 93 1
5490888: 3 92 90 371 1 8 6
133082684295: 2 135 64 713 79 605
2965227329635: 74 7 39 6 386 1 2 572
73621: 99 1 780 8 83
561700: 4 92 5 1 386 9 2 8 82
970086174: 932 13 2 319 78 172
1911986999: 2 977 775 9 280
296273268776: 88 29 410 732 68 776
12458895913: 34 550 46 6 601 35
15665229: 296 20 294 83 18 9
2577418: 530 3 4 81 2 2 4 960
18856: 96 92 56
1419: 56 17 68 1 7
22459778: 3 2 78 8 685
119345444: 36 3 830 4 5 3 3 5 1 3 3 5
2679263061: 3 880 394 273 883
13714046195: 8 3 4 237 829 900 95
75918: 75 91 6
3233825: 5 429 6 85 7
6998621: 2 1 711 8 5 3 7 5 90 7 1 7
24840: 79 266 2 36 1
133350455172: 911 5 8 177 9 282 146
122836: 25 53 6 48 6
66638: 54 4 7 44 16 85 9
729258: 65 8 723 9 57 94 9 1 5
6443892: 50 8 4 85 562 39 2
5219221770: 988 8 9 4 4 9 6 83 3 42 7
103209182: 19 1 14 388 951 231
169488: 8 9 102 360 22
904694402: 3 9 19 3 2 9 7 1 54 20 8 2
33766336296: 9 2 55 957 588 822
135034: 18 748 30 7 87
1398: 1 74 946 293 84
185237973760: 530 78 82 665 64
3731185: 64 25 8 29 4 9 5
4751567577720: 388 521 51 569 810
28765978: 34 830 487 58 9 7 8
45629472867: 582 98 84 1 8 66
39721705915: 273 291 41 183 5
47443: 5 81 7 229 74 9
362852784: 518 9 6 138 94
34762477: 8 6 15 559 1 3 7 7 47 7 1
962208: 9 4 9 1 8 6 4 73 208 18
277488992: 6 6 776 3 21 88 4
2510205: 5 62 3 2 37 7 5 52 141 6
31693936: 3 61 5 3 5 431 77 351
1149703276: 8 499 8 36 6 4 7 9 797
8692151: 7 1 727 1 3 6 73 1 2 9 23
164112488: 1 6 7 1 9 54 67 6 2 6 5 8
136879759121: 8 8 9 9 83 903 33 44 3 6
4501841: 539 835 1 112 6 57
79965188: 50 28 96 7 23 3 332
13294611000: 129 11 150 90 694
44580515: 6 6 3 672 1 9 27 7 7 87 7
36409: 7 634 17 8 769
721870: 99 622 8 65 5
980549: 3 3 2 28 552
197065482800: 9 912 7 685 8 256 6 93
1492605: 325 7 152 615
216885264: 9 9 6 3 435 42 720 8 2 5
784513608: 98 6 5 4 6 58 2 6 4 6 79
43153004: 4 2 1 646 7 7 3 5 9 7 639
64535869440: 922 84 28 93 4 80
5921923803: 1 659 986 85 91 65
95230827: 586 18 15 4 1 641 3 6 3
659839: 417 66 86 90 839
2823500: 48 15 44 51 500
111615927768: 6 9 6 8 9 85 8 3 277 6 3 5
1233: 59 1 3 8 658 77 2
20010714: 185 63 584 863 7 12
179457: 685 86 92 817 3
1274865556: 7 182 8 655 52 4
311254962: 9 953 3 1 336 3 6 97 6
710778: 884 8 2 2 5 327 6 3 1 2 6
1009083693: 438 732 230 9 3
11899845: 82 9 78 2 976 2 1 7 905
258: 2 31 5 93
146136236: 4 510 18 2 5 3 6 767 6 6
500228: 6 343 1 1 1 1 323 6 5 7 8
4701: 9 58 70 11 1
5772: 58 8 9 127 8 4
32851085: 7 904 9 8 4 9 3 6 5 8 3 61
850168170046: 2 79 4 1 389 390 5 6 43
204708384: 9 757 3 1 2 5 6 1 667 9 9
99253310718: 281 3 3 8 7 7 6 3 7 679 4
41947138: 49 7 896 836 2
495: 8 1 55
1211838288: 561 44 208 636 59 4
3061539894: 6 7 463 63 2 6 51 49
1261471276241: 5 629 8 1 67 8 1 906 4 1
26282899: 3 6 156 4 3 195 4 9 1 7 3
59211: 648 7 31 61 9
314847: 85 2 37 253 3 2 621
225678: 1 695 43 13 3 78
55: 1 6 49
6505384491: 7 7 199 900 9 357 584
47469174312: 61 658 9 306 1 4 322 3
7426295: 6 365 31 2 47 48
622850043: 999 2 7 3 87 5 7 9 6 9 1 2
47672: 24 4 58 871 2 1 305 9 8
1013: 4 6 1 1 8 88 41 15 6 4 49
4719423039: 7 9 990 221 59
32727139: 5 5 59 52 44 84 8 31 67
18384030: 264 7 6 8 410 284 4 2 7
2348354059: 906 72 36 16 189 6
2856248987: 4 3 45 305 8 24 87 2 8 8
2953398: 808 14 2 1 58 179 77
10591944: 5 666 8 53 6
1423704: 23 7 2 84 6
52565760000: 208 2 5 81 375 832
214016947200: 420 28 89 710 288
4717682123: 31 40 5 1 6 6 6 7 4 3 8 25
3381089: 61 9 69 7 3 5 54
5508468: 868 47 7 135 63
202480566: 391 4 4 729 883 3 3 59
18954805: 6 8 4 376 5 1 8 621 7
5125: 4 4 65 4 52 5 64 636
85567207572: 771 6 4 7 55 8 7 4 2 9 14
1196283387: 8 69 5 72 31 551 38 7
143411: 35 4 6 2 279 1
8849012251: 884 90 122 5 1
23771104870: 2 248 2 7 8 474 43 5 7 1
24308: 55 7 8 48 206
154616070: 196 98 5 983 107
49352688: 987 25 807 537 2
1399167: 3 8 9 72 694 3 3 7 8 6 3 4
1746482400: 5 5 6 365 1 360 47 65 4
17442000: 66 2 36 4 7 3 764 204 9
9369297541: 4 16 413 9 2 25 38
4434524: 85 4 8 1 2 18 37 1 83
538278646: 12 9 623 6 8 4 6 4 79 9 7
25674303: 59 712 925 4 9
623352364: 1 538 579 7 9 65
4136655595: 7 2 947 4 6 1 4 202 78 7
1041: 9 31 108
1015482150: 4 9 8 2 6 41 611 2 1 50
6710: 1 7 39 8 72
16757169: 96 605 612 659 39
690976730: 2 9 1 3 8 22 811 4 3 88 6
6966: 5 4 129
666851462: 6 4 870 2 7 5 5 1 2 6 7 9
519190: 2 2 404 6 12 1 8 3 5 5 70
381850200: 9 64 6 405 4 405
5072464: 943 9 665 6 2 963 7 8
433183766518: 6 9 894 77 912 82 36
606665867: 3 4 133 2 537 620 5 82
26531: 94 2 6 46 35
1462819: 5 379 3 83 1 69 77 5 9 4
124816429: 5 1 4 9 3 4 1 895 2 4 4 31
84154546878: 2 8 468 6 7 73 8 7 8
16190100: 7 3 135 8 1 6 5 4 4 9 52 9
21573: 89 615 3 3 452
6349804023: 62 987 5 35 4 695 9 7 4
335814: 939 2 585 999 97
219004174: 94 807 6 55 7 1
5581443: 4 1 47 40 8 95 64
2491375328: 29 962 838 4 4 3 8
57538: 958 15 4 9 49
22964234: 2 1 29 63 818 416
1024849747837: 6 3 1 291 9 9 5 2 5 6 6 43
318448: 55 4 3 82 13 448
30033360700: 417 13 720 6 97
173508: 87 35 6 952 1 3 9 483
21110947: 3 465 9 8 3 5 7 8 1 11 6 1
2695000228: 28 4 7 3 22 696 92 2 74
4568231: 6 9 5 992 39 78 4
239039: 6 2 3 8 6 5 1 75 2 78 409
10096752: 276 5 9 5 7 53 114
198559200: 20 50 8 669 530
12702301242240: 6 9 940 6 6 41 408 80
175107: 1 49 92 3 205 2 8 439
39551458: 43 891 55 9 57
13285608: 26 19 10 163 1 9 31 31
405744027: 7 30 3 8 95 9 8 632 24
2997721: 92 479 16 68 9
523183: 398 3 2 652 78 201
6951812: 3 769 8 64 3 2 5 481 9
3435759673472: 844 18 949 7 6 734 7 2
124233456: 7 643 93 4 4 535 3 29 7
110606134088: 1 657 21 7 766 761 1 8
2690276461191: 372 21 66 76 813 889
1539522: 59 2 2 9 31 9 595 3 186
3634947456: 8 3 412 691 532
2105559380: 183 765 9 852 7 2 835
4690009: 66 743 330 95 46
367735534: 45 966 942 2 4
13146574: 57 3 96 4 7 78 544 8
170181372255: 15 87 855 9 779 4 994
9309567: 113 5 4 519 38 78 705
50277: 1 55 3 865 2 47 58
324895639860: 86 954 35 35 396
1361: 923 1 437
10597271: 716 148 12 2 457
816105568: 889 9 34 4 9 3 686 11 3
172116525: 69 9 1 18 9 35 5 137
62149: 13 478 2 1 9
155664243: 8 138 141 24 3
12261286139: 66 7 8 8 5 94 3 5 2 965
332109: 3 1 8 5 3 1 9 5 817 9 3 3
54259531200: 7 70 643 240 7 90 76
39489024: 547 94 768
38958: 790 777 8 450 3
8641850: 2 6 380 2 795 352 3 14
193723: 14 878 9 5 4 2 9 60 12 7
16059120: 28 50 75 2 7 3 84 605 1
29897: 4 5 6 18 999 158 4 9 8
8940153627504: 336 778 342 27 504
1965619: 61 11 91 3 19
17582495: 1 69 7 7 1 38 6 5 4 9 5 90
3747060: 745 26 9 3 180
1284121: 39 19 60 41 9
6465: 10 8 24 7 7
75352: 4 3 558 6 4
987: 97 1 5 2 7
31695169: 60 528 14 1 169
1275278: 456 972 89 433 2 7 1
6139: 2 650 9 2 8 9 79 5 9 4 1 2
2625916: 94 3 32 87 1 606
401166: 26 5 8 1 39 2 399 38 3
13159342272: 8 978 4 292 5 2 6 8 24
188587: 2 7 2 6 429 6 1 82 98 7
104092779157: 34 9 918 2 722 39 9 5 7
2785524088: 64 779 630 1 43
38869: 587 4 891 3 4
14297230: 6 97 9 8 73 6 2 2 4 8 30
49782092802: 5 14 8 9 7 507 47 544 5
97002793: 4 4 9 4 4 870 2 6 3 60 7 2
11629747: 4 692 7 6 7 4 3 5 2 920 1
54441: 67 3 270 94 77
15210: 345 83 72 7 30
185641372: 68 3 4 65 32 2 3 4
636407522647: 86 740 75 22 499 149
5931209262: 4 9 5 6 3 795 8 7 22 3
21897266: 29 55 52 323 34 74
103008144: 444 580 3 6 4
583104: 505 5 5 953 4 4 8 1 96
3097084: 86 36 919 6 159
45450: 4 54 50
822804080: 595 83 3 2 98 85
812543797144: 21 9 746 55 830 3 81
61531143092: 28 9 1 91 325 96 8 86 4
291242: 4 5 4 6 246 8 7 9 2 7 54 2
659813: 733 9 8 3 2
13703922939: 13 703 915 7 937 2
3385407968629: 8 5 490 10 396 8 629
3156: 5 493 1 372 319
2305744653: 6 1 7 45 6 7 34 35 99 3
22755422659279: 43 976 93 84 616 79
1529611: 6 4 560 97 27 4 36 75
185929: 356 4 21 1 488
10921: 8 772 13 8 2 17 754
19474: 1 7 36 3 4 9 1 4 9 7 70 1
14418986: 804 49 366 46 4
805143: 7 8 63 852 3
605682837: 60 8 1 3 8 9 9 4 8 418
3328867490: 876 38 674 63 27
9092: 30 119 61
674618845700: 663 72 343 6 6 9 763 2
873252624: 202 5 4 5 6 7 43 8 59 3 4
2234424: 46 39 82 23 471
67994313730: 7 6 53 9 6 19 1 6 521 3 7
7020: 76 33 584 9 10
8490829762800: 908 116 235 495 77 9
1243674: 32 3 89 27 1 4 4 7 887
40115314: 2 21 872 670 987 2
63515106: 1 969 4 72 91 18
3642671: 36 811 63 2 4 68 4
98830: 844 13 9 6 76
2118210: 5 6 3 5 178 1 170 2 2 6
12759: 49 5 73 3 485 448
1113420: 867 737 3 8 77 3
139374: 8 48 37 331 23
94905: 3 8 21 3 1 783 7 9 204 9
37670: 4 75 79 68
120506596: 89 68 83 9 5 5 8 5 5 8 8 7
1288: 6 13 5 2 896
3957763: 74 5 5 77 6 3
32266: 240 2 19 7 9 7 39 783
940221360: 86 5 3 410 35 39 240
10564: 2 330 5 3 8 7 649
48283977: 277 7 17 372 2 202 53
251997386: 67 3 7 6 4 5 9 3 184 9 8 6
819485: 77 4 3 5 527
9913289: 23 8 1 3 4 630 1 4 8 2 4 9
12445: 78 4 6 4 2 4 3 2 6 327 8 5
38330265: 7 5 89 8 31 5 894 6 9
1888605: 4 53 30 5 40 17 64 45
752008400963: 751 98 2 8 341 59 963
290444: 7 41 1 2 506
1542226852: 83 2 8 48 2 775 7 923 5
138965442: 9 8 2 3 5 8 4 86 305 7 66
2015410: 3 46 8 9 4 4 293 498 3 4
94446951669: 98 4 6 355 9 27 483 9
2560057568: 487 69 81 938 30 76
325037568: 88 57 27 60 10 192 4
34041139: 2 9 15 997 44 139
91735876: 73 52 7 297 353 1
6681558019: 146 791 113 512 3
2377642284: 3 3 44 12 1 2 52 8 476 9
612191967542: 306 2 1 187 4 96 7 54 2
5617962: 79 5 7 9 5 1 9 5 61 9 56 7
377664: 9 6 562 1 7
351084461052: 622 2 3 85 103 182 52
24245: 7 9 51 1 7 7 5 8 1 6 240 5
421642386: 29 688 55 54 17 2 99
1711583639: 678 6 1 51 14 260 6 69
22620616: 1 705 164 26 593 23
256245692: 88 3 8 31 1 1 280 8 94
50489: 12 689 2 7 7 680 9 8 9
46104: 8 287 8 84 2
4085258167: 48 29 359 303 77 67
889: 7 2 728 56 89 7
1306: 51 6 785 4
2273: 1 9 9 2 9 66 37 256
56074716672267: 7 5 8 82 29 96 208 269
30955126672: 934 7 331 6 65 4 596
127980: 488 45 5 48 60
535484167: 617 54 266 7 1 3 2 16 7
66915820: 76 7 5 52 2 866 5
470840167808: 3 8 3 8 6 2 751 5 244 4 8
106862: 5 1 3 3 38 5 7 7 5 433 5 5
2962152: 37 8 21 52
1085092459: 640 58 7 48 87 619
9395566: 6 692 4 351
58598361138: 76 8 710 494 9 9 137
130059: 264 15 465 2 322
33555: 5 67 55
1377820190: 7 2 1 6 7 3 4 501 4 1 1 8
8424: 9 9 19 23 558
2684223: 2 6 8 3 11 741 3
22014969: 72 94 44 3 96 9
5185353762: 1 145 656 2 89 7 2 6 2 6
51226935: 573 894 62 672 1
44553: 6 627 70 243
90331578: 8 890 453 7 95 3 9 74
1170: 5 55 25 5 13
94308: 4 8 259 6 58
2000707: 490 50 8 9 2 6 5 27 3 7
158802343: 8 1 544 4 72 7 33 7
28522992: 5 501 271 208 784
415148: 6 7 99 828 441 600 8
341844522: 81 422 2 45 21
322752: 59 55 1 3 6 1 32 9 6 718
6579809: 8 35 788 7 5
2010664: 958 960 524 2 600
1306995: 9 4 168 5 76 7 19 5 37
24078: 23 4 260 6 152
855504: 115 7 6 709 457
7362818928: 64 4 3 5 3 68 2 3 4 5 28
133587328084: 38 413 665 128 84
2600: 291 229 5
82140: 2 4 9 66 221 45 2 6 48
7429: 97 65 83 43 3 6 25 4
7050943801: 14 866 62 85 90
1457: 27 543 1 790 96
39465: 20 3 638 437 748
52926628172: 2 281 5 1 5 2 85 8 2 6 22
14402304: 8 3 1 6 49 5 5 78 224 9
19161187: 5 7 77 391 9 15 186 1
46189: 4 603 6 6 93
5096011: 6 5 8 98 1 2
8337: 513 310 8 4 21
637146: 535 635 72 513
163586304: 282 3 5 2 2 24 7 276 2 6
38979: 6 42 6 9 71
4025184: 683 980 35 131 69
385600: 7 9 753 1 1 32
4204547: 5 7 513 8 4 267 270 8 1
2168: 300 956 5 903 4
897176: 9 96 43 7 866
207451: 9 3 27 979 714 261 51
9786368: 188 6 82 8 177 1 3 8 76
45647: 6 7 52 2 70 7
72049657270: 1 799 551 74 9 6 70
854299810000: 8 75 5 68 49 7 92 91
201480450: 27 707 5 3 814 4 75 6 1
1044050: 753 59 3 61 554 7
32520810: 65 7 51 7 6 637 7 1 5 6
117229532: 1 379 3 581 146
3048545: 12 254 440 9 96
1151528814: 6 3 458 5 6 49 8 6 45 1 9
1468: 21 8 82 6 738 59 5
24718953: 3 4 51 4 784 5 1 8 79 7
9624368954: 961 7 2 5 365 49 346 6
7705207125: 99 917 125 97 7
1385267: 8 12 6 82 82 25 95
329120663: 4 8 2 1 8 4 6 680 5 8 3 8
4354855: 1 6 1 1 7 82 1 6 5 2 647 6
513338599: 3 7 476 338 599
2575296: 218 9 328 288 4
153551885: 166 3 11 20 454 5
23653336: 7 15 40 36 826
1175289: 9 4 125 2 8 9
582912792: 1 5 1 9 9 59 33 5 8 1 7 99
7639418701: 7 1 629 9 1 418 65 3 48
26000388461: 500 52 388 4 6 1
11148480: 10 7 7 948 24
4375098791: 5 2 6 3 31 5 9 8 4 698 1 4
173167644: 7 7 6 1 5 27 8 5 44 8 867
4440: 3 7 2 1 5 2 5 1 2 335 91 8
79949528272: 3 740 73 9 3 3 4 827 1
268345: 44 435 2 55 7
1391: 9 37 4 1 58
719: 7 23 4 66 9
41747731344: 6 608 7 1 2 4 987 6 2 6 8
52958316813: 87 63 902 39 67
1113623: 12 3 1 3 357 8 45
66704: 28 316 372 41 1 88
13865: 231 60 4 1
22316427322: 99 51 97 9 603 9 321
794426: 785 6 3 3 2 4 4 50 9
336672: 45 35 11 5 42
3647896: 96 1 67 7 6 69 560 56
4108432021: 882 9 2 1 2 1 461 50 2 1
33172170: 1 5 4 4 10 6 2 9 9 23 4 6
3958503: 87 65 70 1 3
5605088: 3 1 4 7 8 5 119 5 8 7 4 7
1148738115: 535 7 3 68 8 333 113
2388379500: 8 827 880 86 5 650
78084: 5 6 83 66 6
1399069: 175 4 977 8 5
1784175537: 6 40 14 8 821 85 7 242
5060096: 1 9 4 7 1 54 3 9 865 8 8 8
2984239: 32 793 91 6 70
54527: 5 35 10 27 1
2625838: 142 1 528 91 5 43
11970: 78 7 4 35 70
9750784240: 9 58 7 32 41 8 4 240
3670629: 1 42 7 95 82 8 131 7 2 1
269878: 4 67 53 19 2
29729866375: 328 7 4 81 8 196 458 7
1650454: 841 809 45 4
958406: 1 1 536 894 38
15047959679: 8 27 8 9 8 5 26 243
110153: 9 9 328 35 83 45 9 9
155720: 183 46 229 18 62 5 6 1

9
day_07/small_input.txt Normal file
View File

@@ -0,0 +1,9 @@
190: 10 19
3267: 81 40 27
83: 17 5
156: 15 6
7290: 6 8 6 15
161011: 16 10 13
192: 17 8 14
21037: 9 7 18 13
292: 11 6 16 20

96
day_07/src/equation.rs Normal file
View File

@@ -0,0 +1,96 @@
mod operator_set;
use std::ops::Deref;
use operator_set::{Op, create_permutations};
#[derive(Debug)]
pub struct Equation {
answer: i64,
components: Vec<i64>,
}
impl Equation {
/// Create a new Equation from a string like:
///
/// Answer: components
/// 190: 10 19
pub fn new(equation_str: &str) -> Result<Equation, String> {
// Split answer and components
let split_equation: Vec<_> = equation_str.split(":").collect();
if split_equation.len() != 2 {
return Err(format!("Invalid equation string: {}", equation_str));
}
let answer = match split_equation[0].parse() {
Ok(a) => a,
Err(_) => {
return Err(format!(
"Error parsing answer {} in equation: {}",
split_equation[0], equation_str
));
}
};
// Parse components
let components = split_equation[1]
.split_whitespace()
.map(|c| match c.parse::<i64>() {
Ok(a) => Ok(a),
Err(_) => Err(format!(
"Error parsing component {} in equation: {}",
c, equation_str
)),
})
.collect::<Result<Vec<i64>, String>>()?;
Ok(Equation { answer, components })
}
pub fn answer(&self) -> i64 {
self.answer
}
fn compute_answer(&self, operators: &[Op]) -> i64 {
let mut accumulator = self.components[0];
for (i, op) in operators.iter().enumerate() {
match op {
Op::Multiply => accumulator *= self.components[i + 1],
Op::Add => accumulator += self.components[i + 1],
Op::Concat => {
let accumulator_string = format!("{}", accumulator);
let component_string = format!("{}", self.components[i + 1]);
accumulator = (accumulator_string + &component_string).parse().unwrap();
}
}
}
accumulator
}
const MULTIPLY_ADD_SET: [Op; 2] = [Op::Add, Op::Multiply];
pub fn solvable_multiply_add(&self) -> bool {
let op_combinations =
create_permutations(&Equation::MULTIPLY_ADD_SET, self.components.len() - 1);
for combination in op_combinations.deref() {
if self.answer == self.compute_answer(combination) {
return true;
}
}
false
}
const MULTIPLY_ADD_CONCAT_SET: [Op; 3] = [Op::Add, Op::Multiply, Op::Concat];
pub fn solvable_multiply_add_concat(&self) -> bool {
let op_combinations = create_permutations(
&Equation::MULTIPLY_ADD_CONCAT_SET,
self.components.len() - 1,
);
for combination in op_combinations.deref() {
if self.answer == self.compute_answer(combination) {
return true;
}
}
false
}
}

View File

@@ -0,0 +1,79 @@
use std::collections::HashMap;
use std::collections::HashSet;
use std::sync::{Arc, LazyLock, Mutex};
#[derive(Debug, Clone, Copy, Hash, PartialEq, Eq)]
pub enum Op {
Multiply,
Add,
Concat,
}
#[derive(Debug, Clone, Hash, PartialEq, Eq)]
struct PermutationCacheKey {
size: usize,
set: Vec<Op>,
}
impl PermutationCacheKey {
fn new(size: usize, set: Vec<Op>) -> PermutationCacheKey {
PermutationCacheKey { size, set }
}
}
type Permutation = Vec<Op>;
type OperatorCache = HashMap<PermutationCacheKey, Arc<HashSet<Permutation>>>;
static OPERATOR_SET_CACHE: LazyLock<Mutex<OperatorCache>> =
LazyLock::new(|| Mutex::new(HashMap::new()));
fn check_operator_set_cache(cache_key: &PermutationCacheKey) -> Option<Arc<HashSet<Permutation>>> {
let lock = OPERATOR_SET_CACHE.lock().unwrap();
let cache_value = lock.get(cache_key);
cache_value.cloned()
}
fn store_operator_set_in_cache(
cache_key: PermutationCacheKey,
cache_value: Arc<HashSet<Permutation>>,
) {
OPERATOR_SET_CACHE
.lock()
.unwrap()
.insert(cache_key, cache_value);
}
fn create_permutations_recurse(
values: &[Op],
len: usize,
permutations: &mut HashSet<Permutation>,
curr_permutation: Permutation,
) {
if curr_permutation.len() == len {
permutations.insert(curr_permutation);
return;
}
for v in values {
let mut next_permutation = curr_permutation.clone();
next_permutation.push(*v);
create_permutations_recurse(values, len, permutations, next_permutation);
}
}
pub fn create_permutations(set: &[Op], len: usize) -> Arc<HashSet<Permutation>> {
// Check cache
let cache_key = PermutationCacheKey::new(len, set.to_vec());
if let Some(cached_value) = check_operator_set_cache(&cache_key) {
return cached_value;
}
// Create permutations
let mut permutations = HashSet::new();
create_permutations_recurse(set, len, &mut permutations, vec![]);
// Cache and return
let permutations = Arc::new(permutations);
store_operator_set_in_cache(cache_key, permutations.clone());
permutations
}

66
day_07/src/main.rs Normal file
View File

@@ -0,0 +1,66 @@
// https://adventofcode.com/2024/day/7
//
// Run command: cargo run ./input.txt
mod equation;
use std::{
env,
error::Error,
fs::File,
io::{BufReader, prelude::*},
};
use equation::Equation;
fn main() -> Result<(), Box<dyn Error>> {
// Handle command input
let args: Vec<String> = env::args().collect();
if args.len() != 2 {
panic!(
"{} must be run with a single argument of file name!",
&args[0]
)
}
let input_file = &args[1];
let file = File::open(input_file)?;
let buffer = BufReader::new(file);
let mut equations = Vec::new();
for line in buffer.lines() {
let line = line?;
equations.push(Equation::new(&line)?)
}
let mut result_add_multiply = 0;
let mut result_add_multiply_concat = 0;
println!("Is solvable?");
println!("------------");
for equation in equations {
let solvable_add_multiply = equation.solvable_multiply_add();
let solvable_add_multiply_concat = equation.solvable_multiply_add_concat();
println!(
"{:?} => {} | {}",
equation, solvable_add_multiply, solvable_add_multiply_concat
);
if solvable_add_multiply {
result_add_multiply += equation.answer();
}
if solvable_add_multiply_concat {
result_add_multiply_concat += equation.answer();
}
}
println!(
"\n Total Calibration Result (ADD|MULTIPLY): {}",
result_add_multiply
);
println!(
"\n Total Calibration Result (ADD|MULTIPLY|CONCAT): {}",
result_add_multiply_concat
);
Ok(())
}