Skip to content

Commit

Permalink
day 13
Browse files Browse the repository at this point in the history
  • Loading branch information
JamesPatrickGill committed Dec 17, 2024
1 parent 9f2a9a2 commit 7c28d94
Show file tree
Hide file tree
Showing 3 changed files with 151 additions and 1 deletion.
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ Solutions for [Advent of Code](https://adventofcode.com/) in [Rust](https://www.
| [Day 10](./src/bin/10.rs) | `464.5µs` | `28.4µs` |
| [Day 11](./src/bin/11.rs) | `179.0µs` | `9.2ms` |
| [Day 12](./src/bin/12.rs) | `2.5ms` | `4.7ms` |
| [Day 13](./src/bin/13.rs) | `63.4µs` | `60.9µs` |

**Total: 310.93ms**
**Total: 311.05ms**
<!--- benchmarking table --->
15 changes: 15 additions & 0 deletions data/examples/13.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
Button A: X+94, Y+34
Button B: X+22, Y+67
Prize: X=8400, Y=5400

Button A: X+26, Y+66
Button B: X+67, Y+21
Prize: X=12748, Y=12176

Button A: X+17, Y+86
Button B: X+84, Y+37
Prize: X=7870, Y=6450

Button A: X+69, Y+23
Button B: X+27, Y+71
Prize: X=18641, Y=10279
134 changes: 134 additions & 0 deletions src/bin/13.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,134 @@
use std::ops::Rem;

use itertools::Itertools;

advent_of_code::solution!(13);

#[derive(Debug, Eq, Hash, PartialEq, Clone, Copy)]
struct Pos(i64, i64);

#[derive(Debug, Eq, Hash, PartialEq, Clone, Copy)]
struct Machine {
a: Pos,
b: Pos,
prize: Pos,
}

pub fn part_one(input: &str) -> Option<i64> {
let machines = input
.split("\n\n")
.map(|maching_def| {
let lines = maching_def.trim().lines().collect_vec();

let ax_idx = lines[0].find("X+").unwrap();
let ax: i64 = lines[0][ax_idx + 2..ax_idx + 4].parse().unwrap();
let ay_idx = lines[0].find("Y+").unwrap();
let ay: i64 = lines[0][ay_idx + 2..ay_idx + 4].parse().unwrap();

let bx_idx = lines[1].find("X+").unwrap();
let bx: i64 = lines[1][bx_idx + 2..bx_idx + 4].parse().unwrap();
let by_idx = lines[1].find("Y+").unwrap();
let by: i64 = lines[1][by_idx + 2..by_idx + 4].parse().unwrap();

let px_idx = lines[2].find("X=").unwrap();
let pxc_idx = lines[2].find(",").unwrap();
let px: i64 = lines[2][px_idx + 2..pxc_idx].parse().unwrap();
let py_idx = lines[2].find("Y=").unwrap();
let py: i64 = lines[2][py_idx + 2..].parse().unwrap();

Machine {
a: Pos(ax, ay),
b: Pos(bx, by),
prize: Pos(px, py),
}
})
.collect_vec();

let mut res = 0;
for mach in machines {
if let Some(sol) = solve(mach) {
res += sol
};
}

Some(res)
}

fn solve(mach: Machine) -> Option<i64> {
let determinant = mach.a.0 * mach.b.1 - mach.a.1 * mach.b.0;
if determinant == 0 {
return None;
}

if (mach.b.1 * mach.prize.0 - mach.b.0 * mach.prize.1).rem(determinant) != 0
|| (mach.a.0 * mach.prize.1 - mach.a.1 * mach.prize.0).rem(determinant) != 0
{
return None;
}

let a_clicks = (mach.b.1 * mach.prize.0 - mach.b.0 * mach.prize.1).checked_div(determinant);
let b_clicks = (mach.a.0 * mach.prize.1 - mach.a.1 * mach.prize.0).checked_div(determinant);

if let (Some(a), Some(b)) = (a_clicks, b_clicks) {
Some(a * 3 + b)
} else {
None
}
}

pub fn part_two(input: &str) -> Option<i64> {
let machines = input
.split("\n\n")
.map(|maching_def| {
let lines = maching_def.trim().lines().collect_vec();

let ax_idx = lines[0].find("X+").unwrap();
let ax: i64 = lines[0][ax_idx + 2..ax_idx + 4].parse().unwrap();
let ay_idx = lines[0].find("Y+").unwrap();
let ay: i64 = lines[0][ay_idx + 2..ay_idx + 4].parse().unwrap();

let bx_idx = lines[1].find("X+").unwrap();
let bx: i64 = lines[1][bx_idx + 2..bx_idx + 4].parse().unwrap();
let by_idx = lines[1].find("Y+").unwrap();
let by: i64 = lines[1][by_idx + 2..by_idx + 4].parse().unwrap();

let px_idx = lines[2].find("X=").unwrap();
let pxc_idx = lines[2].find(",").unwrap();
let px: i64 = lines[2][px_idx + 2..pxc_idx].parse().unwrap();
let py_idx = lines[2].find("Y=").unwrap();
let py: i64 = lines[2][py_idx + 2..].parse().unwrap();

Machine {
a: Pos(ax, ay),
b: Pos(bx, by),
prize: Pos(px + 10000000000000, py + 10000000000000),
}
})
.collect_vec();

let mut res = 0;
for mach in machines {
if let Some(sol) = solve(mach) {
res += sol
};
}

Some(res)
}

#[cfg(test)]
mod tests {
use super::*;

#[test]
fn test_part_one() {
let result = part_one(&advent_of_code::template::read_file("examples", DAY));
assert_eq!(result, None);
}

#[test]
fn test_part_two() {
let result = part_two(&advent_of_code::template::read_file("examples", DAY));
assert_eq!(result, None);
}
}

0 comments on commit 7c28d94

Please sign in to comment.