feat: day 2

thecoded.prof 8d554a58 6357a178

verified
Changed files
+179 -82
2025
+1
2025/src/days/mod.rs
··· 1 1 pub mod one; 2 + pub mod two;
+79 -1
2025/src/days/one/mod.rs
··· 1 - pub mod secret_entrance; 1 + use atoi_simd::parse as parse_i32; 2 + 3 + pub fn main() -> anyhow::Result<()> { 4 + crate::run("Secret Entrance", "inputs/day1.txt", parse, part_a, part_b) 5 + } 6 + 7 + fn parse(input: &[u8]) -> Vec<i32> { 8 + let mut out = Vec::with_capacity(input.iter().filter(|&b| *b == b'\n').count()); 9 + let mut start = 0; 10 + 11 + while start < input.len() { 12 + let end = match memchr::memchr(b'\n', &input[start..]) { 13 + Some(index) => start + index, 14 + None => input.len(), 15 + }; 16 + let line = &input[start..end]; 17 + 18 + if !line.is_empty() { 19 + let mut buf = [0u8; 4]; 20 + let mut len = 0usize; 21 + let mut seen_digit = false; 22 + 23 + for &b in line { 24 + match b { 25 + b'L' => { 26 + if len == 0 { 27 + buf[len] = b'-'; 28 + len += 1; 29 + } 30 + } 31 + b'0'..=b'9' => { 32 + seen_digit = true; 33 + buf[len] = b; 34 + len += 1; 35 + } 36 + _ => { 37 + len = 0; 38 + break; 39 + } 40 + } 41 + } 42 + if seen_digit && len > 0 { 43 + if let Ok(num) = parse_i32(&buf[..len]) { 44 + out.push(num); 45 + } 46 + } 47 + } 48 + 49 + start = end + 1; 50 + } 51 + 52 + out 53 + } 54 + 55 + fn part_a(input: Vec<i32>) -> usize { 56 + input 57 + .iter() 58 + .scan(50, |state, &rotation| { 59 + *state += rotation; 60 + Some(*state) 61 + }) 62 + .filter(|&state| state % 100 == 0) 63 + .count() 64 + } 65 + 66 + fn part_b(input: Vec<i32>) -> usize { 67 + input 68 + .iter() 69 + .scan(50, |state, &rotation| { 70 + let mut passes = (rotation / 100).abs() as usize; 71 + let turn = rotation % 100; 72 + if *state + turn <= 0 && *state != 0 || 99 < *state + turn { 73 + passes += 1; 74 + } 75 + *state = (*state + turn).rem_euclid(100); 76 + Some(passes) 77 + }) 78 + .sum() 79 + }
-79
2025/src/days/one/secret_entrance.rs
··· 1 - use atoi_simd::parse as parse_i32; 2 - 3 - pub fn main() -> anyhow::Result<()> { 4 - crate::run("Secret Entrance", "inputs/day1.txt", parse, part_a, part_b) 5 - } 6 - 7 - fn parse(input: &[u8]) -> Vec<i32> { 8 - let mut out = Vec::with_capacity(4503); 9 - let mut start = 0; 10 - 11 - while start < input.len() { 12 - let end = match memchr::memchr(b'\n', &input[start..]) { 13 - Some(index) => start + index, 14 - None => input.len(), 15 - }; 16 - let line = &input[start..end]; 17 - 18 - if !line.is_empty() { 19 - let mut buf = [0u8; 4]; 20 - let mut len = 0usize; 21 - let mut seen_digit = false; 22 - 23 - for &b in line { 24 - match b { 25 - b'L' => { 26 - if len == 0 { 27 - buf[len] = b'-'; 28 - len += 1; 29 - } 30 - } 31 - b'0'..=b'9' => { 32 - seen_digit = true; 33 - buf[len] = b; 34 - len += 1; 35 - } 36 - _ => { 37 - len = 0; 38 - break; 39 - } 40 - } 41 - } 42 - if seen_digit && len > 0 { 43 - if let Ok(num) = parse_i32(&buf[..len]) { 44 - out.push(num); 45 - } 46 - } 47 - } 48 - 49 - start = end + 1; 50 - } 51 - 52 - out 53 - } 54 - 55 - fn part_a(input: Vec<i32>) -> usize { 56 - input 57 - .iter() 58 - .scan(50, |state, &rotation| { 59 - *state += rotation; 60 - Some(*state) 61 - }) 62 - .filter(|&state| state % 100 == 0) 63 - .count() 64 - } 65 - 66 - fn part_b(input: Vec<i32>) -> usize { 67 - input 68 - .iter() 69 - .scan(50, |state, &rotation| { 70 - let mut passes = (rotation / 100).abs() as usize; 71 - let turn = rotation % 100; 72 - if *state + turn <= 0 && *state != 0 || 99 < *state + turn { 73 - passes += 1; 74 - } 75 - *state = (*state + turn).rem_euclid(100); 76 - Some(passes) 77 - }) 78 - .sum() 79 - }
+92
2025/src/days/two/mod.rs
··· 1 + use atoi_simd::parse as parse_u64; 2 + 3 + pub fn main() -> anyhow::Result<()> { 4 + crate::run("Gift Shop", "inputs/day2.txt", parse, part_a, part_b) 5 + } 6 + 7 + fn parse(input: &[u8]) -> Vec<u64> { 8 + let mut out = Vec::new(); 9 + let mut start = 0; 10 + 11 + while start < input.len() { 12 + let end = match memchr::memchr2(b',', b'\n', &input[start..]) { 13 + Some(index) => start + index, 14 + None => input.len(), 15 + }; 16 + let range = &input[start..end]; 17 + 18 + let [min, max, ..] = range 19 + .split(|&b| b == b'-') 20 + .map(|s| parse_u64::<u64>(s).unwrap()) 21 + .collect::<Vec<_>>()[..] 22 + else { 23 + panic!("invalid input") 24 + }; 25 + 26 + for i in min.clone()..=max.clone() { 27 + out.push(i); 28 + } 29 + start += range.len() + 1; 30 + } 31 + 32 + out 33 + } 34 + 35 + fn part_a(input: Vec<u64>) -> usize { 36 + println!("{}", input.len()); 37 + input.iter().fold(0, |acc, x| { 38 + acc + if is_valid_id_a(x.clone()) { 39 + 0usize 40 + } else { 41 + *x as usize 42 + } 43 + }) 44 + } 45 + 46 + fn is_valid_id_a(id: u64) -> bool { 47 + // invalid ID's are identifiable due to them being made up from some sequences being repeated 48 + // eg: 11 -> [1, 1] invalid 49 + // eg: 123123 -> [123, 123] invalid 50 + // eg: 123456 -> [123456] valid 51 + let id_str = id.to_string(); 52 + let id_len = id_str.len(); 53 + 54 + let (left, right) = id_str.split_at(id_len / 2); 55 + left != right 56 + } 57 + 58 + fn is_valid_id_b(id: &u64) -> bool { 59 + // invalid ID's are identifiable due to them being made up from some sequences being repeated 60 + // eg: 11 -> [1, 1] invalid 61 + // eg: 123123 -> [123, 123] invalid 62 + // eg: 121212 -> [12, 12, 12] invalid 63 + // eg: 111 -> [1, 1, 1] invalid 64 + // eg: 123456 -> [123456] valid 65 + let id_str = id.to_string(); 66 + let id_len = id_str.len(); 67 + let mut needle = id_str.chars().next().unwrap().to_string(); 68 + 69 + while needle.len() != id_str.len() { 70 + if id_len % needle.len() != 0 { 71 + needle.push(id_str.chars().nth(needle.len()).unwrap()); 72 + continue; 73 + }; 74 + let count = id_str.matches(&needle).count(); 75 + if count * needle.len() == id_len { 76 + return false; 77 + }; 78 + needle.push(id_str.chars().nth(needle.len()).unwrap()); 79 + } 80 + 81 + true 82 + } 83 + 84 + fn part_b(input: Vec<u64>) -> usize { 85 + input.iter().fold(0, |acc, x| { 86 + acc + if is_valid_id_b(x) { 87 + 0usize 88 + } else { 89 + *x as usize 90 + } 91 + }) 92 + }
+7 -2
2025/src/main.rs
··· 2 2 extern crate test; 3 3 4 4 fn main() -> anyhow::Result<()> { 5 - aoc2025::days::one::secret_entrance::main()?; 5 + aoc2025::days::two::main()?; 6 6 Ok(()) 7 7 } 8 8 ··· 13 13 14 14 #[bench] 15 15 fn day1(b: &mut Bencher) { 16 - b.iter(|| days::one::secret_entrance::main()) 16 + b.iter(|| days::one::main()) 17 + } 18 + 19 + #[bench] 20 + fn day2(b: &mut Bencher) { 21 + b.iter(|| days::two::main()) 17 22 } 18 23 }