Something went wrong. Try again.
:)
Something went wrong. Try again.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269pub mod day1 { fn day1_preprocess(input: &str) -> Vec<i16> { input .lines() .map(|line| { ( line.starts_with('L'), line.chars() .skip(1) .collect::<String>() .parse::<i16>() .unwrap(), ) }) .map(|(is_left, distance)| if is_left { -distance } else { distance }) .collect() } pub fn day1_part1(input: &str) -> String { let rotations = day1_preprocess(input); let mut popcnt = 0; let mut pointing_at = 50; for rotation in rotations { pointing_at += rotation; pointing_at %= 100; if pointing_at == 0 { popcnt += 1; } } popcnt.to_string() } pub fn day1_part2(input: &str) -> String { let rotations = day1_preprocess(input); let mut popcnt = 0; let mut pointing_at = 50; for mut rotation in rotations { while rotation != 0 { if rotation < 0 { let distance = rotation.max(-(if pointing_at != 0 { pointing_at } else { 100 })); pointing_at += distance; rotation -= distance; } else if rotation > 0 { let distance = rotation.min(100 - pointing_at); pointing_at += distance; rotation -= distance; } pointing_at %= 100; if pointing_at < 0 { pointing_at += 100; } else if pointing_at == 0 { popcnt += 1; } } } popcnt.to_string() }}
pub mod day2 { use std::ops::RangeInclusive;
pub fn day2_part1(input: &str) -> String { let ranges = parse(input); let invalid = ranges .into_iter() .flatten() .filter(|&id| !is_id_valid(id, true)); let invalid_sum: u64 = invalid.sum(); invalid_sum.to_string() } pub fn day2_part2(input: &str) -> String { let ranges = parse(input); let invalid = ranges .into_iter() .flatten() .filter(|&id| !is_id_valid(id, false)); let invalid_sum: u64 = invalid.sum(); invalid_sum.to_string() } fn parse(input: &str) -> Vec<RangeInclusive<u64>> { input .split(',') .map(|range| range.split_once('-').unwrap()) .map(|(from, to)| from.parse().unwrap()..=to.parse().unwrap()) .collect() } fn is_id_valid(id: u64, max_two_chunks: bool) -> bool { let charnum = id.ilog10() as usize + 1; for chunk_count in 2..=if max_two_chunks { 2 } else { charnum } { if !charnum.is_multiple_of(chunk_count) { continue; } let chunk_size = charnum / chunk_count; let mut equal = true; 'chunking: for intra_chunk_index in 0..chunk_size { let first_digit = index(id, intra_chunk_index); for inter_chunk_index in 1..chunk_count { let digit_under_test = index(id, inter_chunk_index * chunk_size + intra_chunk_index); if digit_under_test != first_digit { equal = false; break 'chunking; } } } if equal { return false; } } true } #[inline] fn index(id: u64, index: usize) -> u64 { (id / 10u64.pow(index as u32)) % 10 }}
pub mod day3;pub mod day4;pub mod day5;pub mod day6;pub mod day7;pub mod day8;pub mod day9;mod spatial;mod union_find;
#[cfg(test)]mod tests { use super::*;
#[test] fn day9_part1_test() { let test_result = day9::day9_part1(include_str!("../input/day9.test.txt")); assert_eq!(test_result, "50"); let result = day9::day9_part1(include_str!("../input/day9.txt")); assert_eq!(result, "4760959496"); } #[test] fn day9_part2_test() { let test_result = day9::day9_part2(include_str!("../input/day9.test.txt")); assert_eq!(test_result, "24"); let result = day9::day9_part2(include_str!("../input/day9.txt")); assert_eq!(result, "1343576598"); }
#[test] fn day8_part1_test() { let test_result = day8::day8_part1(include_str!("../input/day8.test.txt"), 10); assert_eq!(test_result, "40"); let result = day8::day8_part1(include_str!("../input/day8.txt"), 1000); assert_eq!(result, "90036"); } #[test] fn day8_part2_test() { let test_result = day8::day8_part2(include_str!("../input/day8.test.txt"), 1_000_000); assert_eq!(test_result, "25272"); let result = day8::day8_part2(include_str!("../input/day8.txt"), 1_000_000); assert_eq!(result, "6083499488"); }
#[test] fn day7_part1_test() { let test_result = day7::day7_part1(include_str!("../input/day7.test.txt")); assert_eq!(test_result, "21"); let result = day7::day7_part1(include_str!("../input/day7.txt")); assert_eq!(result, "1490"); } #[test] fn day7_part2_test() { let test_result = day7::day7_part2(include_str!("../input/day7.test.txt")); assert_eq!(test_result, "40"); let result = day7::day7_part2(include_str!("../input/day7.txt")); assert_eq!(result, "3806264447357"); }
#[test] fn day6_part1_test() { let test_result = day6::day6_part1(include_str!("../input/day6.test.txt")); assert_eq!(test_result, "4277556"); let result = day6::day6_part1(include_str!("../input/day6.txt")); assert_eq!(result, "4951502530386"); } #[test] fn day6_part2_test() { let test_result = day6::day6_part2(include_str!("../input/day6.test.txt")); assert_eq!(test_result, "3263827"); let result = day6::day6_part2(include_str!("../input/day6.txt")); assert_eq!(result, "8486156119946"); }
#[test] fn day5_part1_test() { let test_result = day5::day5_part1(include_str!("../input/day5.test.txt")); assert_eq!(test_result, "3"); let result = day5::day5_part1(include_str!("../input/day5.txt")); assert_eq!(result, "885"); } #[test] fn day5_part2_test() { let test_result = day5::day5_part2(include_str!("../input/day5.test.txt")); assert_eq!(test_result, "14"); let result = day5::day5_part2(include_str!("../input/day5.txt")); assert_eq!(result, "348115621205535"); }
#[test] fn day4_part1_test() { let test_result = day4::day4_part1(include_str!("../input/day4.test.txt")); assert_eq!(test_result, "13"); let result = day4::day4_part1(include_str!("../input/day4.txt")); assert_eq!(result, "1372"); } #[test] fn day4_part2_test() { let test_result = day4::day4_part2(include_str!("../input/day4.test.txt")); assert_eq!(test_result, "43"); let result = day4::day4_part2(include_str!("../input/day4.txt")); assert_eq!(result, "7922"); }
#[test] fn day3_part1_test() { let test_result = day3::day3_part1(include_str!("../input/day3.test.txt")); assert_eq!(test_result, "357"); let result = day3::day3_part1(include_str!("../input/day3.txt")); assert_eq!(result, "17613"); } #[test] fn day3_part2_test() { let test_result = day3::day3_part2(include_str!("../input/day3.test.txt")); assert_eq!(test_result, "3121910778619"); let result = day3::day3_part2(include_str!("../input/day3.txt")); assert_eq!(result, "175304218462560"); }
#[test] fn day2_part1_test() { let test_result = day2::day2_part1(include_str!("../input/day2.test.txt")); assert_eq!(test_result, "1227775554"); let result = day2::day2_part1(include_str!("../input/day2.txt")); assert_eq!(result, "38158151648"); } #[test] fn day2_part2_test() { let test_result = day2::day2_part2(include_str!("../input/day2.test.txt")); assert_eq!(test_result, "4174379265"); let result = day2::day2_part2(include_str!("../input/day2.txt")); assert_eq!(result, "45283684555"); }
#[test] fn day1_part1_test() { let test_result = day1::day1_part1(include_str!("../input/day1.test.txt")); assert_eq!(test_result, "3"); let result = day1::day1_part1(include_str!("../input/day1.txt")); assert_eq!(result, "1021"); }
#[test] fn day1_part2_test() { let test_result = day1::day1_part2(include_str!("../input/day1.test.txt")); assert_eq!(test_result, "6"); let result = day1::day1_part2(include_str!("../input/day1.txt")); assert_eq!(result, "5933"); }}