diff --git a/.gitea/workflows/build_and_run.yml b/.gitea/workflows/build_and_run.yml index 43e3f1c..96dd0ff 100644 --- a/.gitea/workflows/build_and_run.yml +++ b/.gitea/workflows/build_and_run.yml @@ -11,7 +11,7 @@ jobs: name: Challenge for day strategy: matrix: - day_number: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12] + day_number: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13] runs-on: rust-bookworm steps: - name: Check out repository code diff --git a/day13/Cargo.toml b/day13/Cargo.toml new file mode 100644 index 0000000..adb45f4 --- /dev/null +++ b/day13/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "day13" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/day13/src/main.rs b/day13/src/main.rs new file mode 100644 index 0000000..990e1dd --- /dev/null +++ b/day13/src/main.rs @@ -0,0 +1,80 @@ +use std::{env, fs}; + +fn read_input(path: &str) -> String { + fs::read_to_string(path).expect("Cannot read file.") +} + +fn parse_input(input: &str) -> Vec<((i64, i64, i64), (i64, i64, i64))> { + let mut equations = Vec::new(); + let mut equation = ((0, 0, 0), (0, 0, 0)); + for (row, line) in input.lines().filter(|line| !line.is_empty()).enumerate() { + let pos = row % 3; + let tuple; + if pos == 0 || pos == 1 { + tuple = line[12..].split_once(", Y+").unwrap(); + } else { + tuple = line[9..].split_once(", Y=").unwrap(); + } + + match pos { + 0 => { + equation.0 .0 = tuple.0.parse().unwrap(); + equation.1 .0 = tuple.1.parse().unwrap(); + } + 1 => { + equation.0 .1 = tuple.0.parse().unwrap(); + equation.1 .1 = tuple.1.parse().unwrap(); + } + _ => { + equation.0 .2 = tuple.0.parse().unwrap(); + equation.1 .2 = tuple.1.parse().unwrap(); + } + } + if pos == 2 { + equations.push(equation); + equation = ((0, 0, 0), (0, 0, 0)); + } + } + + equations +} + +fn compute_price(equations: &Vec<((i64, i64, i64), (i64, i64, i64))>, offset: i64, allow_hundreds: bool) -> i64 { + let mut sum = 0; + for equation in equations { + let ((x1, x2, mut x_res), (y1, y2, mut y_res)) = equation; + x_res += offset; + y_res += offset; + let determinant = x1 * y2 - x2 * y1; + if determinant != 0 { + let x = (y2 * x_res - x2 * y_res) / determinant; + let x_remain = (y2 * x_res - x2 * y_res) % determinant; + let y = (x1 * y_res - y1 * x_res) / determinant; + let y_remain = (x1 * y_res - y1 * x_res) % determinant; + if x_remain == 0 && (allow_hundreds || (0..=100).contains(&x) && y_remain == 0 && (0..=100).contains(&y)) { + sum += 3 * x + y; + } + } + } + + sum +} + +fn part_1(equations: &Vec<((i64, i64, i64), (i64, i64, i64))>) -> i64 { + compute_price(&equations, 0, false) +} + +fn part_2(equations: &Vec<((i64, i64, i64), (i64, i64, i64))>) -> i64 { + compute_price(&equations, 10000000000000, true) +} + +fn main() { + let args: Vec = env::args().collect(); + for arg in args.iter().skip(1) { + let input = read_input(&arg); + let equations = parse_input(&input); + println!("[{}]", &arg); + println!("\t[Part 1] => Answer is '{}'.", part_1(&equations)); + println!("\t[Part 2] => Answer is '{}'.", part_2(&equations)); + } +}