1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83
fn solution(input_string: &str, part1: bool) -> Result<usize, String> { const MAX_DELAY: usize = 10_000_000; let layers = input_string.lines().count(); let mut scanner_ranges = vec![0; layers]; for (line_index, line) in input_string.lines().enumerate() { let error_message = || { format!( "Invalid input at line {}: Not '${{NUMBER}}: ${{NUMBER}}", line_index + 1 ) }; let parts: Vec<&str> = line.split(": ").collect(); if parts.len() != 2 { return Err(error_message()); } let depth = parts[0].parse::<usize>().map_err(|_| error_message())?; let range = parts[1].parse::<usize>().map_err(|_| error_message())?; if scanner_ranges.len() <= depth { scanner_ranges.resize(depth * 2, 0); } scanner_ranges[depth] = range; } 'delay: for delay in if part1 { 0..1 } else { 0..MAX_DELAY } { let mut trip_severity = 0; for (position, ¤t_range) in scanner_ranges.iter().enumerate() { if current_range != 0 { let time = delay + position; let caught = time % (2 * (current_range - 1)) == 0; if caught { if part1 { trip_severity += position * current_range; } else { continue 'delay; } } } } return Ok(if part1 { trip_severity } else { delay }); } Err("No solution found".to_string()) } pub fn part1(input_string: &str) -> Result<usize, String> { solution(input_string, true) } pub fn part2(input_string: &str) -> Result<usize, String> { solution(input_string, false) } #[test] fn test_part1() { assert_eq!( Ok(24), part1( "0: 3 1: 2 4: 4 6: 4" ) ); assert_eq!(Ok(748), part1(include_str!("day13_input.txt"))); } #[test] fn test_part2() { assert_eq!( Ok(10), part2( "0: 3 1: 2 4: 4 6: 4" ) ); assert_eq!(Ok(3873662), part2(include_str!("day13_input.txt"))); }