Compare commits

..

2 Commits

Author SHA1 Message Date
Matej Janezic 00000180c1
solution: day 8 2023-12-08 08:01:10 +01:00
Matej Janezic 0000017058
feat: add read_file_part 2023-12-08 08:00:44 +01:00
5 changed files with 145 additions and 0 deletions

5
data/examples/08-1.txt Normal file
View File

@ -0,0 +1,5 @@
LLR
AAA = (BBB, BBB)
BBB = (AAA, ZZZ)
ZZZ = (ZZZ, ZZZ)

10
data/examples/08-2.txt Normal file
View File

@ -0,0 +1,10 @@
LR
11A = (11B, XXX)
11B = (XXX, 11Z)
11Z = (11B, XXX)
22A = (22B, XXX)
22B = (22C, 22C)
22C = (22Z, 22Z)
22Z = (22B, 22B)
XXX = (XXX, XXX)

95
src/bin/08.rs Normal file
View File

@ -0,0 +1,95 @@
use std::collections::HashMap;
use aoc::lcm;
pub fn part_one(input: &str) -> Option<u32> {
let mut map = HashMap::new();
let (directions, map_data) = input.split_once("\n\n")?;
for line in map_data.lines() {
let (k, v) = line.split_once(" = ")?;
let v = v.strip_prefix('(')?;
let v = v.strip_suffix(')')?;
let (l, r) = v.split_once(", ")?;
*map.entry(k).or_default() = (l, r);
}
let mut counter = 0;
let mut loc = "AAA";
for d in directions.chars().cycle() {
if loc == "ZZZ" {
break;
}
counter += 1;
let (l, r) = map[loc];
match d {
'L' => loc = l,
'R' => loc = r,
_ => unimplemented!(),
}
}
Some(counter)
}
pub fn part_two(input: &str) -> Option<u64> {
let mut map = HashMap::new();
let (directions, map_data) = input.split_once("\n\n")?;
for line in map_data.lines() {
let (k, v) = line.split_once(" = ")?;
let v = v.strip_prefix('(')?;
let v = v.strip_suffix(')')?;
let (l, r) = v.split_once(", ")?;
*map.entry(k).or_default() = (l, r);
}
let mut res = 1;
for k in map.keys().filter(|x| x.ends_with('A')) {
let mut location = *k;
for (i, d) in directions.chars().cycle().enumerate() {
let (l, r) = map[location];
location = match d {
'L' => l,
'R' => r,
_ => unimplemented!(),
};
if location.ends_with('Z') {
res = lcm(res, i + 1);
break;
}
}
}
Some(res as u64)
}
aoc::solution!(8);
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_part_one() {
assert_eq!(
part_one(&aoc::template::read_file_part("examples", 8, 1)),
Some(6)
);
}
#[test]
fn test_part_two() {
assert_eq!(
part_two(&aoc::template::read_file_part("examples", 8, 2)),
Some(6)
);
}
}

View File

@ -1,4 +1,28 @@
#![feature(pattern)]
use std::mem::swap;
pub mod parsers;
pub mod template;
pub fn lcm(first: usize, second: usize) -> usize {
first * second / gcd(first, second)
}
pub fn gcd(first: usize, second: usize) -> usize {
let mut max = first;
let mut min = second;
if min > max {
swap(&mut min, &mut max)
}
loop {
let res = max % min;
if res == 0 {
return min;
}
max = min;
min = res;
}
}

View File

@ -54,3 +54,14 @@ pub fn read_file(folder: &str, day: u8) -> String {
let f = fs::read_to_string(filepath);
f.expect("could not open input file").trim().to_string()
}
#[must_use]
pub fn read_file_part(folder: &str, day: u8, part: u8) -> String {
let cwd = env::current_dir().unwrap();
let filepath = cwd
.join("data")
.join(folder)
.join(format!("{day:02}-{part}.txt"));
let f = fs::read_to_string(filepath);
f.expect("could not open input file").trim().to_string()
}