Did the LCD thing, but not happy about it. refactored to answers with u64

This commit is contained in:
Dennis Brentjes 2023-12-11 18:02:22 +01:00
parent c2722a35fc
commit f98edf5161
11 changed files with 154 additions and 64 deletions

83
Cargo.lock generated
View File

@ -7,8 +7,15 @@ name = "advent_2023"
version = "0.1.0" version = "0.1.0"
dependencies = [ dependencies = [
"itertools", "itertools",
"num",
] ]
[[package]]
name = "autocfg"
version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa"
[[package]] [[package]]
name = "either" name = "either"
version = "1.9.0" version = "1.9.0"
@ -23,3 +30,79 @@ checksum = "25db6b064527c5d482d0423354fcd07a89a2dfe07b67892e62411946db7f07b0"
dependencies = [ dependencies = [
"either", "either",
] ]
[[package]]
name = "num"
version = "0.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b05180d69e3da0e530ba2a1dae5110317e49e3b7f3d41be227dc5f92e49ee7af"
dependencies = [
"num-bigint",
"num-complex",
"num-integer",
"num-iter",
"num-rational",
"num-traits",
]
[[package]]
name = "num-bigint"
version = "0.4.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "608e7659b5c3d7cba262d894801b9ec9d00de989e8a82bd4bef91d08da45cdc0"
dependencies = [
"autocfg",
"num-integer",
"num-traits",
]
[[package]]
name = "num-complex"
version = "0.4.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1ba157ca0885411de85d6ca030ba7e2a83a28636056c7c699b07c8b6f7383214"
dependencies = [
"num-traits",
]
[[package]]
name = "num-integer"
version = "0.1.45"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "225d3389fb3509a24c93f5c29eb6bde2586b98d9f016636dff58d7c6f7569cd9"
dependencies = [
"autocfg",
"num-traits",
]
[[package]]
name = "num-iter"
version = "0.1.43"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7d03e6c028c5dc5cac6e2dec0efda81fc887605bb3d884578bb6d6bf7514e252"
dependencies = [
"autocfg",
"num-integer",
"num-traits",
]
[[package]]
name = "num-rational"
version = "0.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0638a1c9d0a3c0914158145bc76cff373a75a627e6ecbfb71cbe6f453a5a19b0"
dependencies = [
"autocfg",
"num-bigint",
"num-integer",
"num-traits",
]
[[package]]
name = "num-traits"
version = "0.2.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "39e3200413f237f41ab11ad6d161bc7239c84dcb631773ccd7de3dfe4b5c267c"
dependencies = [
"autocfg",
]

View File

@ -7,3 +7,4 @@ edition = "2021"
[dependencies] [dependencies]
itertools = "0.12.0" itertools = "0.12.0"
num = "0.4.1"

View File

@ -1,10 +1,12 @@
use std::{path::Path, vec}; use std::{path::Path, vec};
use itertools::Itertools;
use crate::{input::read_into_vec, error::AdventError}; use crate::{input::read_into_vec, error::AdventError};
fn process(lines: Vec::<String>) -> Result<u32, AdventError> { fn process(lines: Vec::<String>) -> Result<u64, AdventError> {
let calibrations: Vec<u32> = lines.iter().map(|v| { let calibrations = lines.iter().map(|v| {
let first_digit = v.as_bytes() let first_digit = v.as_bytes()
.iter() .iter()
.skip_while(|i| { .skip_while(|i| {
@ -18,14 +20,14 @@ fn process(lines: Vec::<String>) -> Result<u32, AdventError> {
.skip_while(|i| { **i < 48u8 || **i > 57u8 }) .skip_while(|i| { **i < 48u8 || **i > 57u8 })
.take(1).collect::<Vec::<&u8>>()[0]; .take(1).collect::<Vec::<&u8>>()[0];
(*first_digit - 48) as u32 * 10 + (*last_digit - 48) as u32 (*first_digit - 48) as u64 * 10 + (*last_digit - 48) as u64
}).collect(); }).collect_vec();
Ok(calibrations.iter().sum::<u32>()) Ok(calibrations.iter().sum())
} }
pub fn one() -> Result<u32, AdventError> { pub fn one() -> Result<u64, AdventError> {
let lines: Vec<String> = read_into_vec::<String>(Path::new("resources/input1.txt"))?; let lines: Vec<String> = read_into_vec::<String>(Path::new("resources/input1.txt"))?;
Ok(process(lines)?) Ok(process(lines)?)
} }
@ -33,7 +35,7 @@ pub fn one() -> Result<u32, AdventError> {
struct Mutation(usize, char); struct Mutation(usize, char);
struct Pattern(&'static str, char); struct Pattern(&'static str, char);
pub fn two() -> Result<u32, AdventError> { pub fn two() -> Result<u64, AdventError> {
let mut lines = read_into_vec(Path::new("resources/input1.txt"))?; let mut lines = read_into_vec(Path::new("resources/input1.txt"))?;
let mut mutations = Vec::<Mutation>::new(); let mut mutations = Vec::<Mutation>::new();

View File

@ -20,7 +20,7 @@ impl FromStr for Group {
fn from_str(s: &str) -> Result<Self, Self::Err> { fn from_str(s: &str) -> Result<Self, Self::Err> {
let split = s.split(' ').collect::<Vec<&str>>(); let split = s.split(' ').collect::<Vec<&str>>();
Ok(Group{count: u32::from_str(split[0])?, color: Color::from_str(split[1])?}) Ok(Group{count: u64::from_str(split[0])?, color: Color::from_str(split[1])?})
} }
} }
@ -42,7 +42,7 @@ impl FromStr for Game {
fn from_str(s: &str) -> Result<Self, Self::Err> { fn from_str(s: &str) -> Result<Self, Self::Err> {
let split = s.split(':').collect::<Vec<&str>>(); let split = s.split(':').collect::<Vec<&str>>();
let id = u32::from_str(split[0].split(' ').collect::<Vec<&str>>()[1])?; let id = u64::from_str(split[0].split(' ').collect::<Vec<&str>>()[1])?;
let pulls = split[1]; let pulls = split[1];
let mut res = Vec::<Pull>::new(); let mut res = Vec::<Pull>::new();
for pull in pulls.split(',') { for pull in pulls.split(',') {
@ -62,7 +62,7 @@ enum Color {
#[derive(Debug)] #[derive(Debug)]
struct Group { struct Group {
count: u32, count: u64,
color: Color, color: Color,
} }
@ -73,14 +73,14 @@ struct Pull {
#[derive(Debug)] #[derive(Debug)]
struct Game { struct Game {
id: u32, id: u64,
pulls: Vec<Pull> pulls: Vec<Pull>
} }
pub fn one() -> Result<u32, AdventError> { pub fn one() -> Result<u64, AdventError> {
let games: Vec<Game> = read_into_vec(Path::new("resources/input2.txt"))?; let games: Vec<Game> = read_into_vec(Path::new("resources/input2.txt"))?;
let mut sum: u32 = 0; let mut sum: u64 = 0;
let max_red = 12; let max_red = 12;
let max_green = 13; let max_green = 13;
@ -103,14 +103,14 @@ pub fn one() -> Result<u32, AdventError> {
Ok(sum) Ok(sum)
} }
pub fn two() -> Result<u32, AdventError> { pub fn two() -> Result<u64, AdventError> {
let games: Vec<Game> = read_into_vec(Path::new("resources/input2.txt"))?; let games: Vec<Game> = read_into_vec(Path::new("resources/input2.txt"))?;
let mut power: u32 = 0; let mut power: u64 = 0;
for game in games.iter() { for game in games.iter() {
let mut max_nr_red = 0; let mut max_nr_red = 0u64;
let mut max_nr_green = 0; let mut max_nr_green = 0u64;
let mut max_nr_blue = 0; let mut max_nr_blue = 0u64;
for pull in game.pulls.iter() { for pull in game.pulls.iter() {
for group in pull.groups.iter() { for group in pull.groups.iter() {
match group.color { match group.color {

View File

@ -6,7 +6,7 @@ use crate::{input::read_into_vec, error::AdventError};
#[derive(Debug, Clone, PartialEq, Eq, Hash)] #[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub struct Number { pub struct Number {
value: u32, value: u64,
position: u8, position: u8,
length: u8 length: u8
} }
@ -179,9 +179,9 @@ fn filter_gears(rows: &mut Vec<RowInfo>) -> &mut Vec<RowInfo> {
rows rows
} }
pub fn one() -> Result<u32, AdventError> { pub fn one() -> Result<u64, AdventError> {
let rows = read_into_vec::<RowInfo>(Path::new("resources/input3.txt"))?; let rows = read_into_vec::<RowInfo>(Path::new("resources/input3.txt"))?;
let mut sum: u32 = 0; let mut sum: u64 = 0;
for (i, row) in rows.iter().enumerate() { for (i, row) in rows.iter().enumerate() {
for number in row.numbers.iter() { for number in row.numbers.iter() {
let coords = gen_coords_number(i, number); let coords = gen_coords_number(i, number);
@ -199,10 +199,10 @@ pub fn one() -> Result<u32, AdventError> {
Ok(sum) Ok(sum)
} }
pub fn two() -> Result<u32, AdventError> { pub fn two() -> Result<u64, AdventError> {
let mut rows = read_into_vec::<RowInfo>(Path::new("resources/input3.txt"))?; let mut rows = read_into_vec::<RowInfo>(Path::new("resources/input3.txt"))?;
rows = filter_gears(&mut rows).clone(); rows = filter_gears(&mut rows).clone();
let mut sum: u32 = 0; let mut sum: u64 = 0;
for (i, row) in rows.iter().enumerate() { for (i, row) in rows.iter().enumerate() {
for symbol in row.symbols.iter() { for symbol in row.symbols.iter() {
let coords = gen_coords_symbol(i, symbol); let coords = gen_coords_symbol(i, symbol);

View File

@ -32,7 +32,7 @@ struct ScratchGame {
winning_numbers: HashSet<i32> winning_numbers: HashSet<i32>
} }
pub fn one() -> Result<u32, AdventError> { pub fn one() -> Result<u64, AdventError> {
let games = read_into_vec::<ScratchGame>(Path::new("resources/input4.txt"))?; let games = read_into_vec::<ScratchGame>(Path::new("resources/input4.txt"))?;
Ok(games.into_iter().fold(Ok(0), |acc: Result<u64, AdventError>, game: ScratchGame| { Ok(games.into_iter().fold(Ok(0), |acc: Result<u64, AdventError>, game: ScratchGame| {
let acc = acc?; let acc = acc?;
@ -41,12 +41,12 @@ pub fn one() -> Result<u32, AdventError> {
0 => 0, 0 => 0,
x => (2 as u64).pow((x-1).try_into()?) x => (2 as u64).pow((x-1).try_into()?)
}) })
})? as u32) })? as u64)
} }
pub fn two() -> Result<u32, AdventError> { pub fn two() -> Result<u64, AdventError> {
let games = read_into_vec::<ScratchGame>(Path::new("resources/input4.txt"))?; let games = read_into_vec::<ScratchGame>(Path::new("resources/input4.txt"))?;
let mut vec = Vec::<u32>::new(); let mut vec = Vec::<u64>::new();
vec.resize(games.len(), 1); vec.resize(games.len(), 1);
Ok(games.into_iter().fold(0, | acc, game | { Ok(games.into_iter().fold(0, | acc, game | {

View File

@ -214,15 +214,15 @@ impl FromStr for Almanac {
} }
} }
pub fn one() -> Result<u32, AdventError> pub fn one() -> Result<u64, AdventError>
{ {
let almanac = read_into::<Almanac>(Path::new("resources/input5.txt".into()))?; let almanac = read_into::<Almanac>(Path::new("resources/input5.txt".into()))?;
Ok(almanac.find_closest(true)?) Ok(almanac.find_closest(true)? as u64)
} }
pub fn two() -> Result<u32, AdventError> pub fn two() -> Result<u64, AdventError>
{ {
let mut almanac = read_into::<Almanac>(Path::new("resources/input5.txt".into()))?; let mut almanac = read_into::<Almanac>(Path::new("resources/input5.txt".into()))?;
almanac.interpret_range(); almanac.interpret_range();
Ok(almanac.find_closest(false)?) Ok(almanac.find_closest(false)? as u64)
} }

View File

@ -87,14 +87,14 @@ pub fn number_of_record_beating_chances(max_time: i128, record: i128) -> u32 {
(answer2.ceil() - answer1.ceil()) as u32 (answer2.ceil() - answer1.ceil()) as u32
} }
pub fn one() -> Result<u32, AdventError> { pub fn one() -> Result<u64, AdventError> {
let overview = read_into::<RecordsOverview>(Path::new("resources/input6.txt"))?; let overview = read_into::<RecordsOverview>(Path::new("resources/input6.txt"))?;
Ok(overview.records.iter().fold(1, |acc, record| { Ok(overview.records.iter().fold(1, |acc, record| {
acc * number_of_record_beating_chances(record.time.into(), record.distance.into()) acc * number_of_record_beating_chances(record.time.into(), record.distance.into())
})) }) as u64)
} }
pub fn two() -> Result<u32, AdventError> { pub fn two() -> Result<u64, AdventError> {
let record = read_into::<Record>(Path::new("resources/input6.txt"))?; let record = read_into::<Record>(Path::new("resources/input6.txt"))?;
Ok(number_of_record_beating_chances(record.time.into(), record.distance.into())) Ok(number_of_record_beating_chances(record.time.into(), record.distance.into()) as u64)
} }

View File

@ -421,18 +421,18 @@ impl FromStr for LineTwo {
} }
} }
pub fn one() -> Result<u32, AdventError> { pub fn one() -> Result<u64, AdventError> {
let mut lines = read_into_vec::<LineOne>(Path::new("resources/input7.txt".into()))?; let mut lines = read_into_vec::<LineOne>(Path::new("resources/input7.txt".into()))?;
lines.sort(); lines.sort();
Ok(lines.iter().enumerate().fold(0, |acc, (rank, hand)| { Ok(lines.iter().enumerate().fold(0, |acc, (rank, hand)| {
acc + (rank as u32 + 1) * hand.bid acc + (rank as u32 + 1) * hand.bid
})) }) as u64)
} }
pub fn two() -> Result<u32, AdventError> { pub fn two() -> Result<u64, AdventError> {
let mut lines = read_into_vec::<LineTwo>(Path::new("resources/input7.txt".into()))?; let mut lines = read_into_vec::<LineTwo>(Path::new("resources/input7.txt".into()))?;
lines.sort(); lines.sort();
Ok(lines.iter().enumerate().fold(0, |acc, (rank, hand)| { Ok(lines.iter().enumerate().fold(0, |acc, (rank, hand)| {
acc + (rank as u32 + 1) * hand.bid acc + (rank as u32 + 1) * hand.bid
})) }) as u64)
} }

View File

@ -1,6 +1,7 @@
use std::{path::Path, str::FromStr, collections::HashMap}; use std::{path::Path, str::FromStr, collections::HashMap};
use itertools::Itertools; use itertools::Itertools;
use num::integer::gcd;
use crate::{error::AdventError, input::read_into}; use crate::{error::AdventError, input::read_into};
@ -105,35 +106,38 @@ fn is_end1(node: &String) -> bool {
node == &"ZZZ".to_string() node == &"ZZZ".to_string()
} }
fn is_end2(nodes: &Vec<String>) -> bool { fn is_end2(node: &String) -> bool {
nodes.iter().all(|x| { node.ends_with('Z')
x.ends_with('Z')
})
} }
pub fn one() -> Result<u32, AdventError> { pub fn one() -> Result<u64, AdventError> {
let map = read_into::<Map1>(Path::new("resources/input8.txt"))?.0; let map = read_into::<Map1>(Path::new("resources/input8.txt"))?.0;
let mut node = map.start[0].clone(); let mut node = map.start[0].clone();
for (i, direction) in map.directions.iter().cycle().enumerate() { for (i, direction) in map.directions.iter().cycle().enumerate() {
node = map.take_step(&node, direction)?; node = map.take_step(&node, direction)?;
if is_end1(&node) { if is_end1(&node) {
return Ok(i as u32 +1); return Ok(i as u64 + 1);
} }
} }
panic!("Cycle iterator should never terminate") panic!("Cycle iterator should never terminate")
} }
pub fn two() -> Result<u32, AdventError> { pub fn two() -> Result<u64, AdventError> {
let map = read_into::<Map2>(Path::new("resources/input8.txt"))?.0; let map = read_into::<Map2>(Path::new("resources/input8.txt"))?.0;
let mut nodes = map.start.clone(); let mut nodes = map.start.clone();
for (i, direction) in map.directions.iter().cycle().enumerate() { let iterations = nodes.iter_mut().map(|current| {
nodes = nodes.iter().map(|current| { for (i, direction) in map.directions.iter().cycle().enumerate() {
map.take_step(&current, direction) current.clone_from(&map.take_step(current, direction)?);
}).collect::<Result<Vec<String>,AdventError>>()?.iter().unique().map(|x| x.clone()).collect_vec(); if is_end2(&current) {
return Ok((i + 1) as u64);
if is_end2(&nodes) { }
return Ok(i as u32 +1);
} }
} panic!("Cycle iterator should never terminate")
panic!("Cycle iterator should never terminate") }).collect::<Result<Vec<u64>, AdventError>>()?;
let mut iter = iterations.into_iter();
let acc = iter.next().unwrap() as u64;
Ok(iter.fold(Ok(acc), |acc, i| -> Result<u64, AdventError> {
let accumulator = acc?;
return Ok(i * accumulator / gcd(i, accumulator));
})?)
} }

View File

@ -11,14 +11,14 @@ use crate::error::AdventError;
fn main() -> Result<(), AdventError> { fn main() -> Result<(), AdventError> {
let days = vec![ let days = vec![
(day1::one as fn() -> Result<u32, AdventError>, day1::two as fn() -> Result<u32, AdventError>), (day1::one as fn() -> Result<u64, AdventError>, day1::two as fn() -> Result<u64, AdventError>),
(day2::one as fn() -> Result<u32, AdventError>, day2::two as fn() -> Result<u32, AdventError>), (day2::one as fn() -> Result<u64, AdventError>, day2::two as fn() -> Result<u64, AdventError>),
(day3::one as fn() -> Result<u32, AdventError>, day3::two as fn() -> Result<u32, AdventError>), (day3::one as fn() -> Result<u64, AdventError>, day3::two as fn() -> Result<u64, AdventError>),
(day4::one as fn() -> Result<u32, AdventError>, day4::two as fn() -> Result<u32, AdventError>), (day4::one as fn() -> Result<u64, AdventError>, day4::two as fn() -> Result<u64, AdventError>),
(day5::one as fn() -> Result<u32, AdventError>, day5::two as fn() -> Result<u32, AdventError>), (day5::one as fn() -> Result<u64, AdventError>, day5::two as fn() -> Result<u64, AdventError>),
(day6::one as fn() -> Result<u32, AdventError>, day6::two as fn() -> Result<u32, AdventError>), (day6::one as fn() -> Result<u64, AdventError>, day6::two as fn() -> Result<u64, AdventError>),
(day7::one as fn() -> Result<u32, AdventError>, day7::two as fn() -> Result<u32, AdventError>), (day7::one as fn() -> Result<u64, AdventError>, day7::two as fn() -> Result<u64, AdventError>),
(day8::one as fn() -> Result<u32, AdventError>, day8::two as fn() -> Result<u32, AdventError>), (day8::one as fn() -> Result<u64, AdventError>, day8::two as fn() -> Result<u64, AdventError>),
]; ];
if env::args().len() == 1 { if env::args().len() == 1 {
@ -26,7 +26,7 @@ fn main() -> Result<(), AdventError> {
let one_result = one()?; let one_result = one()?;
let two_result = two()?; let two_result = two()?;
Ok((one_result, two_result)) Ok((one_result, two_result))
}).enumerate().map(|(index, r): (usize, Result<(u32, u32), AdventError>)| { }).enumerate().map(|(index, r): (usize, Result<(u64, u64), AdventError>)| {
match r { match r {
Ok((res1, res2)) => println!("{}: ({}, {})", index + 1, res1, res2), Ok((res1, res2)) => println!("{}: ({}, {})", index + 1, res1, res2),
Err(e) => println!("Error: {}", e.0) Err(e) => println!("Error: {}", e.0)