summaryrefslogtreecommitdiff
path: root/2024_rust/src
diff options
context:
space:
mode:
authorGuillermo Ramos2024-12-13 17:38:53 +0100
committerGuillermo Ramos2024-12-13 17:38:53 +0100
commit9e3f932e990eb2922b535fdf758791a5ee94774f (patch)
tree6952ca31223bffe72592f03fa8659dde0092d532 /2024_rust/src
parentca02218365f8fcb05e29c312ba5ede515bbc5310 (diff)
downloadAoC-9e3f932e990eb2922b535fdf758791a5ee94774f.tar.gz
2024.13
Diffstat (limited to '2024_rust/src')
-rw-r--r--2024_rust/src/bin/day13.rs129
1 files changed, 129 insertions, 0 deletions
diff --git a/2024_rust/src/bin/day13.rs b/2024_rust/src/bin/day13.rs
new file mode 100644
index 0000000..92d7039
--- /dev/null
+++ b/2024_rust/src/bin/day13.rs
@@ -0,0 +1,129 @@
+use regex::Regex;
+
+#[derive(Debug)]
+struct Machine1 {
+ a: (u32, u32),
+ b: (u32, u32),
+ prize: (u32, u32),
+}
+
+impl Machine1 {
+ fn parse(input: &str) -> Vec<Self> {
+ let mut result: Vec<_> = vec![];
+ let re = Regex::new(
+ r"Button A: X\+([0-9]+), Y\+([0-9]+)
+Button B: X\+([0-9]+), Y\+([0-9]+)
+Prize: X=([0-9]+), Y=([0-9]+)",
+ )
+ .unwrap();
+ for (_, [ax, ay, bx, by, x, y]) in re.captures_iter(input).map(|c| c.extract()) {
+ result.push(Machine1 {
+ a: (ax.parse().unwrap(), ay.parse().unwrap()),
+ b: (bx.parse().unwrap(), by.parse().unwrap()),
+ prize: (x.parse().unwrap(), y.parse().unwrap()),
+ });
+ }
+ // println!("Result: {result:?}");
+ result
+ }
+
+ fn solve(&self) -> Option<(u32, u32)> {
+ for pushesb in (0..100).rev() {
+ for pushesa in 0..100 {
+ if self.prize.0 == self.a.0 * pushesa + self.b.0 * pushesb
+ && self.prize.1 == self.a.1 * pushesa + self.b.1 * pushesb
+ {
+ // println!("{self:?} solved with {pushesa} {pushesb} pushes!");
+ return Some((pushesa, pushesb));
+ }
+ }
+ }
+ None
+ }
+}
+
+fn p1(input: &str) -> String {
+ let result: u32 = Machine1::parse(input)
+ .iter()
+ .filter_map(Machine1::solve)
+ .map(|(nx, ny)| nx * 3 + ny)
+ .sum();
+
+ result.to_string()
+}
+
+#[derive(Debug)]
+struct Machine2 {
+ a: (i64, i64),
+ b: (i64, i64),
+ prize: (i64, i64),
+}
+
+fn intdiv(x: i64, y: i64) -> Option<i64> {
+ if x % y == 0 {
+ Some(x / y)
+ } else {
+ None
+ }
+}
+
+impl Machine2 {
+ fn parse(input: &str) -> Vec<Self> {
+ let mut result: Vec<_> = vec![];
+ let re = Regex::new(
+ r"Button A: X\+([0-9]+), Y\+([0-9]+)
+Button B: X\+([0-9]+), Y\+([0-9]+)
+Prize: X=([0-9]+), Y=([0-9]+)",
+ )
+ .unwrap();
+ for (_, [ax, ay, bx, by, x, y]) in re.captures_iter(input).map(|c| c.extract()) {
+ result.push(Machine2 {
+ a: (ax.parse().unwrap(), ay.parse().unwrap()),
+ b: (bx.parse().unwrap(), by.parse().unwrap()),
+ prize: (
+ x.parse::<i64>().unwrap() + 10000000000000,
+ y.parse::<i64>().unwrap() + 10000000000000,
+ ),
+ });
+ }
+ result
+ }
+
+ fn solve(&self) -> Option<(i64, i64)> {
+ let pa = intdiv(
+ self.prize.0 * self.b.1 - self.prize.1 * self.b.0,
+ self.a.0 * self.b.1 - self.a.1 * self.b.0,
+ )?;
+ let pb = intdiv(self.prize.0 - (pa * self.a.0), self.b.0)?;
+ Some((pa, pb))
+ }
+}
+
+fn p2(input: &str) -> String {
+ let result: i64 = Machine2::parse(input)
+ .iter()
+ .filter_map(Machine2::solve)
+ .map(|(nx, ny)| nx * 3 + ny)
+ .sum();
+
+ result.to_string()
+}
+
+fn main() {
+ aoc2024::run_day("13", p1, p2);
+}
+
+#[cfg(test)]
+mod tests {
+ use super::{p1, p2};
+
+ #[test]
+ fn day13_p1() {
+ assert_eq!(p1(&aoc2024::read_input("13")), "39290");
+ }
+
+ #[test]
+ fn day13_p2() {
+ assert_eq!(p2(&aoc2024::read_input("13")), "73458657399094");
+ }
+}