Compare commits
No commits in common. "8475909bd667cd69dafa91473c4f1b3f5b6104da" and "0dc10ff73c50241c6d35ad4d4e539c5e72fb7c8f" have entirely different histories.
8475909bd6
...
0dc10ff73c
21
Cargo.lock
generated
21
Cargo.lock
generated
|
@ -33,7 +33,6 @@ dependencies = [
|
||||||
"color-eyre",
|
"color-eyre",
|
||||||
"rayon",
|
"rayon",
|
||||||
"regex",
|
"regex",
|
||||||
"thiserror",
|
|
||||||
"tracing",
|
"tracing",
|
||||||
"tracing-subscriber",
|
"tracing-subscriber",
|
||||||
"tracing-test",
|
"tracing-test",
|
||||||
|
@ -354,26 +353,6 @@ dependencies = [
|
||||||
"unicode-ident",
|
"unicode-ident",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "thiserror"
|
|
||||||
version = "2.0.6"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "8fec2a1820ebd077e2b90c4df007bebf344cd394098a13c563957d0afc83ea47"
|
|
||||||
dependencies = [
|
|
||||||
"thiserror-impl",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "thiserror-impl"
|
|
||||||
version = "2.0.6"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "d65750cab40f4ff1929fb1ba509e9914eb756131cef4210da8d5d700d26f6312"
|
|
||||||
dependencies = [
|
|
||||||
"proc-macro2",
|
|
||||||
"quote",
|
|
||||||
"syn",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "thread_local"
|
name = "thread_local"
|
||||||
version = "1.1.8"
|
version = "1.1.8"
|
||||||
|
|
|
@ -17,8 +17,6 @@ full = [
|
||||||
"day10",
|
"day10",
|
||||||
"day11",
|
"day11",
|
||||||
"day12",
|
"day12",
|
||||||
"day13",
|
|
||||||
"day14",
|
|
||||||
]
|
]
|
||||||
default = ["full"]
|
default = ["full"]
|
||||||
day1 = []
|
day1 = []
|
||||||
|
@ -33,8 +31,6 @@ day9 = []
|
||||||
day10 = []
|
day10 = []
|
||||||
day11 = []
|
day11 = []
|
||||||
day12 = []
|
day12 = []
|
||||||
day13 = []
|
|
||||||
day14 = []
|
|
||||||
|
|
||||||
|
|
||||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
@ -43,7 +39,6 @@ day14 = []
|
||||||
color-eyre = "0.6.3"
|
color-eyre = "0.6.3"
|
||||||
rayon = "1.10.0"
|
rayon = "1.10.0"
|
||||||
regex = "1.11.1"
|
regex = "1.11.1"
|
||||||
thiserror = "2.0.6"
|
|
||||||
tracing = "0.1.41"
|
tracing = "0.1.41"
|
||||||
tracing-subscriber = "0.3.19"
|
tracing-subscriber = "0.3.19"
|
||||||
tracing-test = "0.2.5"
|
tracing-test = "0.2.5"
|
||||||
|
|
|
@ -1,15 +0,0 @@
|
||||||
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
|
|
|
@ -1,12 +0,0 @@
|
||||||
p=0,4 v=3,-3
|
|
||||||
p=6,3 v=-1,-3
|
|
||||||
p=10,3 v=-1,2
|
|
||||||
p=2,0 v=2,-1
|
|
||||||
p=0,0 v=1,3
|
|
||||||
p=3,0 v=-2,-2
|
|
||||||
p=7,6 v=-1,-3
|
|
||||||
p=3,0 v=-1,-2
|
|
||||||
p=9,3 v=2,3
|
|
||||||
p=7,3 v=-1,2
|
|
||||||
p=2,4 v=2,-3
|
|
||||||
p=9,5 v=-3,-3
|
|
186
src/day13.rs
186
src/day13.rs
|
@ -1,186 +0,0 @@
|
||||||
#![allow(
|
|
||||||
clippy::cast_sign_loss,
|
|
||||||
clippy::cast_possible_wrap,
|
|
||||||
clippy::too_many_lines,
|
|
||||||
clippy::cast_possible_truncation,
|
|
||||||
clippy::cast_precision_loss,
|
|
||||||
clippy::float_cmp
|
|
||||||
)]
|
|
||||||
use std::str::FromStr;
|
|
||||||
|
|
||||||
use color_eyre::eyre::{self, OptionExt};
|
|
||||||
|
|
||||||
struct Elem {
|
|
||||||
x: usize,
|
|
||||||
y: usize,
|
|
||||||
}
|
|
||||||
struct Machine {
|
|
||||||
button_a: Elem,
|
|
||||||
button_b: Elem,
|
|
||||||
prize: Elem,
|
|
||||||
}
|
|
||||||
|
|
||||||
fn parse_button(s: &str) -> Result<Elem, eyre::Error> {
|
|
||||||
let positions = s.split_once(", ").ok_or_eyre("Button A line malformed")?;
|
|
||||||
Ok(Elem {
|
|
||||||
x: positions
|
|
||||||
.0
|
|
||||||
.split_once('+')
|
|
||||||
.ok_or_eyre("seems to be malformed")?
|
|
||||||
.1
|
|
||||||
.parse::<usize>()?,
|
|
||||||
y: positions
|
|
||||||
.1
|
|
||||||
.split_once('+')
|
|
||||||
.ok_or_eyre("seems to be malformed")?
|
|
||||||
.1
|
|
||||||
.parse::<usize>()?,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
impl FromStr for Machine {
|
|
||||||
type Err = eyre::Error;
|
|
||||||
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
|
||||||
let lines = s.lines().collect::<Vec<_>>();
|
|
||||||
let button_a = parse_button(lines.first().ok_or_eyre("Could not find button a line")?)?;
|
|
||||||
let button_b = parse_button(lines.get(1).ok_or_eyre("could not find button b line")?)?;
|
|
||||||
let prize_line = lines.get(2).ok_or_eyre("Could not find prize line")?;
|
|
||||||
let prizes = prize_line
|
|
||||||
.split_once(", ")
|
|
||||||
.ok_or_eyre("Could not parse prize line")?;
|
|
||||||
let prize = Elem {
|
|
||||||
x: prizes
|
|
||||||
.0
|
|
||||||
.split_once('=')
|
|
||||||
.ok_or_eyre("Could not parse prize")?
|
|
||||||
.1
|
|
||||||
.parse::<usize>()?,
|
|
||||||
y: prizes
|
|
||||||
.1
|
|
||||||
.split_once('=')
|
|
||||||
.ok_or_eyre("Could not parse prize")?
|
|
||||||
.1
|
|
||||||
.parse::<usize>()?,
|
|
||||||
};
|
|
||||||
Ok(Machine {
|
|
||||||
button_a,
|
|
||||||
button_b,
|
|
||||||
prize,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Machine {
|
|
||||||
pub fn play(&self) -> Option<usize> {
|
|
||||||
let machine = self;
|
|
||||||
let determinant = machine.button_a.x as f64 * machine.button_b.y as f64
|
|
||||||
- machine.button_a.y as f64 * machine.button_b.x as f64;
|
|
||||||
let a = ((-(machine.button_b.x as f64)) * (machine.prize.y as f64)
|
|
||||||
+ machine.button_b.y as f64 * machine.prize.x as f64)
|
|
||||||
/ determinant;
|
|
||||||
let b = (machine.button_a.x as f64 * machine.prize.y as f64
|
|
||||||
- machine.button_a.y as f64 * machine.prize.x as f64)
|
|
||||||
/ determinant;
|
|
||||||
if a.floor() == a && b.floor() == b && a >= 0.0 && b >= 0.0 {
|
|
||||||
if a > 100.0 || b > 100.0 {
|
|
||||||
None
|
|
||||||
} else {
|
|
||||||
Some(a.round() as usize * 3 + b as usize)
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
None
|
|
||||||
}
|
|
||||||
}
|
|
||||||
pub fn play_without_limits(&self) -> Option<usize> {
|
|
||||||
let machine = self;
|
|
||||||
let determinant = machine.button_a.x as f64 * machine.button_b.y as f64
|
|
||||||
- machine.button_a.y as f64 * machine.button_b.x as f64;
|
|
||||||
let a = ((-(machine.button_b.x as f64)) * (machine.prize.y as f64)
|
|
||||||
+ machine.button_b.y as f64 * machine.prize.x as f64)
|
|
||||||
/ determinant;
|
|
||||||
let b = (machine.button_a.x as f64 * machine.prize.y as f64
|
|
||||||
- machine.button_a.y as f64 * machine.prize.x as f64)
|
|
||||||
/ determinant;
|
|
||||||
if a.floor() == a && b.floor() == b && a >= 0.0 && b >= 0.0 {
|
|
||||||
Some(a.round() as usize * 3 + b as usize)
|
|
||||||
} else {
|
|
||||||
None
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn pt1(input: &str) -> usize {
|
|
||||||
input
|
|
||||||
.split("\n\n")
|
|
||||||
.flat_map(Machine::from_str)
|
|
||||||
.filter_map(|m| m.play())
|
|
||||||
.sum()
|
|
||||||
}
|
|
||||||
pub fn pt2(input: &str) -> usize {
|
|
||||||
input
|
|
||||||
.split("\n\n")
|
|
||||||
.flat_map(Machine::from_str)
|
|
||||||
.map(|mut m| {
|
|
||||||
m.prize.x += 10_000_000_000_000;
|
|
||||||
m.prize.y += 10_000_000_000_000;
|
|
||||||
m
|
|
||||||
})
|
|
||||||
.filter_map(|m| m.play_without_limits())
|
|
||||||
.sum()
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(test)]
|
|
||||||
mod tests {
|
|
||||||
use tracing_test::traced_test;
|
|
||||||
|
|
||||||
use super::{pt1, pt2, Machine};
|
|
||||||
use std::fs::read_to_string;
|
|
||||||
|
|
||||||
#[traced_test]
|
|
||||||
#[test]
|
|
||||||
pub fn test_pt1() {
|
|
||||||
let input =
|
|
||||||
read_to_string("./inputs/day13/example.txt").expect("Missing example.txt for day13");
|
|
||||||
assert_eq!(pt1(&input), 480)
|
|
||||||
}
|
|
||||||
#[traced_test]
|
|
||||||
#[test]
|
|
||||||
pub fn test_machine_execution1() {
|
|
||||||
let m = Machine {
|
|
||||||
button_a: crate::day13::Elem { x: 94, y: 34 },
|
|
||||||
button_b: crate::day13::Elem { x: 22, y: 67 },
|
|
||||||
prize: crate::day13::Elem { x: 8400, y: 5400 },
|
|
||||||
};
|
|
||||||
assert_eq!(m.play(), Some(280))
|
|
||||||
}
|
|
||||||
#[traced_test]
|
|
||||||
#[test]
|
|
||||||
pub fn test_machine_execution2() {
|
|
||||||
let m = Machine {
|
|
||||||
button_a: crate::day13::Elem { x: 26, y: 66 },
|
|
||||||
button_b: crate::day13::Elem { x: 67, y: 21 },
|
|
||||||
prize: crate::day13::Elem { x: 12748, y: 12176 },
|
|
||||||
};
|
|
||||||
assert_eq!(m.play(), None)
|
|
||||||
}
|
|
||||||
#[traced_test]
|
|
||||||
#[test]
|
|
||||||
pub fn test_machine_execution3() {
|
|
||||||
let m = Machine {
|
|
||||||
button_a: crate::day13::Elem { x: 17, y: 86 },
|
|
||||||
button_b: crate::day13::Elem { x: 84, y: 37 },
|
|
||||||
prize: crate::day13::Elem { x: 7870, y: 6450 },
|
|
||||||
};
|
|
||||||
assert_eq!(m.play(), Some(200))
|
|
||||||
}
|
|
||||||
#[traced_test]
|
|
||||||
#[test]
|
|
||||||
pub fn test_machine_execution4() {
|
|
||||||
let m = Machine {
|
|
||||||
button_a: crate::day13::Elem { x: 69, y: 23 },
|
|
||||||
button_b: crate::day13::Elem { x: 27, y: 71 },
|
|
||||||
prize: crate::day13::Elem { x: 18641, y: 10279 },
|
|
||||||
};
|
|
||||||
assert_eq!(m.play(), None)
|
|
||||||
}
|
|
||||||
}
|
|
78
src/day14.rs
78
src/day14.rs
|
@ -1,78 +0,0 @@
|
||||||
#![allow(
|
|
||||||
clippy::cast_sign_loss,
|
|
||||||
clippy::cast_possible_wrap,
|
|
||||||
clippy::too_many_lines
|
|
||||||
)]
|
|
||||||
|
|
||||||
use std::str::FromStr;
|
|
||||||
|
|
||||||
use color_eyre::eyre::{self, OptionExt};
|
|
||||||
|
|
||||||
struct Robot {
|
|
||||||
x: isize,
|
|
||||||
y: isize,
|
|
||||||
vx: isize,
|
|
||||||
vy: isize,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Robot {
|
|
||||||
fn move_robot(&mut self, dims: (isize, isize)) {
|
|
||||||
self.x += self.vx;
|
|
||||||
self.y += self.vy;
|
|
||||||
if self.x >= dims.0 {
|
|
||||||
self.x -= dims.0;
|
|
||||||
}
|
|
||||||
if self.y >= dims.1 {
|
|
||||||
self.y -= dims.1;
|
|
||||||
}
|
|
||||||
if self.x < 0 {
|
|
||||||
self.x += dims.0;
|
|
||||||
}
|
|
||||||
if self.y < 0 {
|
|
||||||
self.y += dims.1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
impl FromStr for Robot {
|
|
||||||
type Err = eyre::Error;
|
|
||||||
|
|
||||||
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
|
||||||
let (pos, vel) = s.split_once(' ').ok_or_eyre("line malformed")?;
|
|
||||||
let position = pos.split_once(',').ok_or_eyre("line malformed")?;
|
|
||||||
let velocity = vel.split_once(',').ok_or_eyre("line malformed")?;
|
|
||||||
Ok(Robot {
|
|
||||||
x: position
|
|
||||||
.0
|
|
||||||
.split_once('=')
|
|
||||||
.ok_or_eyre("malformed position")?
|
|
||||||
.1
|
|
||||||
.parse()?,
|
|
||||||
y: position.1.parse()?,
|
|
||||||
vx: velocity
|
|
||||||
.0
|
|
||||||
.split_once('=')
|
|
||||||
.ok_or_eyre("malformed velocity")?
|
|
||||||
.1
|
|
||||||
.parse()?,
|
|
||||||
vy: velocity.1.parse()?,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn pt1(input: &str) -> usize {
|
|
||||||
let dims: (isize, isize) = (101, 103);
|
|
||||||
let mut robots = input.lines().flat_map(Robot::from_str).collect::<Vec<_>>();
|
|
||||||
for _ in 0..100 {
|
|
||||||
for robot in &mut robots {
|
|
||||||
robot.move_robot(dims);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
robots.iter().filter(|r| r.x < 50 && r.y < 51).count()
|
|
||||||
* robots.iter().filter(|r| r.x > 50 && r.y < 51).count()
|
|
||||||
* robots.iter().filter(|r| r.x < 50 && r.y > 51).count()
|
|
||||||
* robots.iter().filter(|r| r.x > 50 && r.y > 51).count()
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn pt2(_input: &str) -> String {
|
|
||||||
"lol no".into()
|
|
||||||
}
|
|
|
@ -27,10 +27,6 @@ mod day10;
|
||||||
mod day11;
|
mod day11;
|
||||||
#[cfg(feature = "day12")]
|
#[cfg(feature = "day12")]
|
||||||
mod day12;
|
mod day12;
|
||||||
#[cfg(feature = "day13")]
|
|
||||||
mod day13;
|
|
||||||
#[cfg(feature = "day14")]
|
|
||||||
mod day14;
|
|
||||||
|
|
||||||
fn main() -> eyre::Result<()> {
|
fn main() -> eyre::Result<()> {
|
||||||
color_eyre::install()?;
|
color_eyre::install()?;
|
||||||
|
@ -61,10 +57,6 @@ fn main() -> eyre::Result<()> {
|
||||||
solve_day(11, day11::pt1, day11::pt2);
|
solve_day(11, day11::pt1, day11::pt2);
|
||||||
#[cfg(feature = "day12")]
|
#[cfg(feature = "day12")]
|
||||||
solve_day(12, day12::pt1, day12::pt2);
|
solve_day(12, day12::pt1, day12::pt2);
|
||||||
#[cfg(feature = "day13")]
|
|
||||||
solve_day(13, day13::pt1, day13::pt2);
|
|
||||||
#[cfg(feature = "day14")]
|
|
||||||
solve_day(14, day14::pt1, day14::pt2);
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue