From: Grégory Burri Date: Wed, 18 Dec 2019 08:47:35 +0000 (+0100) Subject: Day 16 & day 17 part 1 X-Git-Url: https://git.euphorik.ch/?a=commitdiff_plain;h=3a065f163f4ddc9d737a66729fa0ed350f2ad8cc;p=advent_of_code_2019.git Day 16 & day 17 part 1 --- diff --git a/day17.txt b/day17.txt new file mode 100644 index 0000000..396303c --- /dev/null +++ b/day17.txt @@ -0,0 +1,43 @@ +..........................#####.................. +..........................#...#.................. +..........................#...#.................. +..........................#...#.................. +..........................#...#.................. +..........................#...#.................. +..........................#######................ +..............................#.#................ +............................###########.......... +............................#.#.#.....#.......... +..................#############.#.....#.......... +..................#.........#...#.....#.......... +..................#.........#######...#.......... +..................#.............#.#...#.......... +..................#.............#.#...#.......... +..................#.............#.#...#.......... +......#############.............#.#...#.......... +......#.........................#.#...#.......... +###########.....................#######.......... +#.....#...#.......................#.............. +#.....#...#.......................#...#######.... +#.....#...#.......................#...#.....#.... +#######...#.......................#...#.....#.... +..........#.......................#...#.....#.... +..........#.......................###########.... +..........#...........................#.......... +..........#...........................#...####### +..........#...........................#...#.....# +..........#.........................#####.#.....# +..........#.........................#.#.#.#.....# +..........#######...................#.########### +................#...................#...#.#...... +................#.............#############...... +................#.............#.....#...#........ +................#.............#.....#...#........ +................#.............#.........#........ +................#.............#.........#........ +................#.............#.........#........ +................#.............###########........ +................#................................ +................#................................ +................#................................ +................######^.......................... \ No newline at end of file diff --git a/src/day16.rs b/src/day16.rs new file mode 100644 index 0000000..2112c0e --- /dev/null +++ b/src/day16.rs @@ -0,0 +1,104 @@ +use std::iter::FromIterator; + +pub fn parse(input: &str) -> Vec { + input.chars().map(|c| c.to_digit(10).unwrap() as i32).collect() +} + +pub fn fft(signal: &[i32], pattern: &[i32], nb_phases: i32, offset: usize, length: usize, nb_signal_repeated: usize) -> Vec { + + let l = signal.len(); + let pattern_l = pattern.len(); + + let mut output = Vec::from_iter(signal.iter().cycle().take(l * nb_signal_repeated).copied()); + + for _ in 0 .. nb_phases { + let cloned_output = output.clone(); + for i in 0 .. output.len() { + output[i] = + cloned_output.iter().enumerate().fold( + 0, + |sum, (j, value)| { + sum + value * pattern[(j + 1) / (i + 1) % pattern_l] + } + ).abs() % 10; + } + } + + Vec::from(&output[offset .. offset + length]) +} + +pub fn digits_as_string(signal: &[i32]) -> String { + signal.iter().fold(String::new(), |result, digit| result + &digit.to_string()) +} + +// Part 2 is from 'https://github.com/mkeeter/advent-of-code/blob/master/2019/16/src/main.rs'. + +fn cumsum(input: &[i32]) -> Vec { + let mut output = vec![0; input.len() + 1]; + for (i, v) in input.iter().enumerate() { + output[i + 1] = output[i] + v; + } + output +} + +fn dft(scale: usize, csum: &[i32]) -> i32 { + use std::cmp::min; + + assert!(scale > 0); + let mut i = scale; + let mut sign = true; + let mut out = 0; + while i < csum.len() { + let d = csum[min(csum.len() - 1, i + scale - 1)] - csum[i - 1]; + if sign { + out += d; + } else { + out -= d; + } + sign = !sign; + i += scale * 2; + } + out.abs() % 10 +} + +pub fn part2(input: &[i32]) -> Vec { + let size = input.len(); + let mut input = Vec::from_iter(input.iter().cycle().take(size * 10_000).copied()); + + let offset = input[..7].iter().fold(0, |acc, i| acc * 10 + i) as usize; + + for _ in 0..100 { + let csum = cumsum(&input); + input = (0..input.len()) + .map(|i| dft(i + 1, &csum)) + .collect::>(); + } + + Vec::from(&input[offset..(offset + 8)]) +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn part1_sample_1() { + let signal = parse("80871224585914546619083218645595"); + let output = fft(&signal, &[0, 1, 0, -1], 100, 0, 8, 1); + assert_eq!(digits_as_string(&output), "24176176"); + } + + #[test] + fn part1_sample_2() { + let signal = parse("19617804207202209144916044189917"); + let output = fft(&signal, &[0, 1, 0, -1], 100, 0, 8, 1); + assert_eq!(digits_as_string(&output), "73745418"); + } + + #[test] + fn part1_sample_3() { + let signal = parse("69317163492948606335995924319873"); + let output = fft(&signal, &[0, 1, 0, -1], 100, 0, 8, 1); + assert_eq!(digits_as_string(&output), "52432133"); + } +} \ No newline at end of file diff --git a/src/day17.rs b/src/day17.rs new file mode 100644 index 0000000..15bd825 --- /dev/null +++ b/src/day17.rs @@ -0,0 +1,74 @@ +use super::intcode; +use std::collections::HashSet; + +pub fn scaffold_intersections(code: &[i64]) -> i32 { + let output = intcode::execute_op_code(code, &[]); + let mut board = Vec::>::new(); + let mut current_line = Vec::::new(); + + let (mut x, mut y) = (0i32, 0i32); + let mut dir = '^'; + + let mut current_x = 0; + for c in output { + if c == 10 { + board.push(current_line); + current_line = Vec::::new(); + current_x = 0; + //println!(""); + } else { + let c = (c as u8) as char; + if let '^' | '<' | 'v' | '>' = c { + x = current_x; + y = board.len() as i32; + dir = c; + } + //print!("{}", c); + current_line.push(c); + current_x += 1; + } + } + + let get = |x: i32, y: i32| -> Option { + if x < board[0].len() as i32 && x >= 0 && y < board.len() as i32 && y >= 0 { + Some(board[y as usize][x as usize]) + } else { + None + } + }; + + let mut visited_locations = HashSet::<(i32, i32)>::new(); + let mut crosses = Vec::<(i32, i32)>::new(); + visited_locations.insert((x, y)); + + 'main: loop { + let positions = [('^', (x, y - 1)), ('<', (x - 1, y)), ('>', (x + 1, y)), ('v', (x, y + 1))]; + + let next_position = positions.iter().find(|(d, _)| *d == dir).unwrap().1; + //match dir { '^' => positions[0], '<' => positions[1], '>' => positions[2], 'v' | _ => positions[3] }; + + // If the robot can continue straightforward. + if get(next_position.0, next_position.1) == Some('#') { + if !visited_locations.insert(next_position) { + crosses.push(next_position); + } + x = next_position.0; + y = next_position.1; + continue; + } + + for (d, p) in &positions { + if get(p.0, p.1) == Some('#') && !visited_locations.contains(p) { + visited_locations.insert(*p); + dir = *d; + x = p.0; + y = p.1; + continue 'main; + } + } + + break; + } + + crosses.iter().fold(0, |sum, cross| sum + cross.0 * cross.1) +} \ No newline at end of file diff --git a/src/main.rs b/src/main.rs index 491ee5c..4788102 100644 --- a/src/main.rs +++ b/src/main.rs @@ -16,6 +16,8 @@ mod day12; mod day13; mod day14; mod day15; +mod day16; +mod day17; fn day01() -> String { let masses = common::read_list_of_numbers("data/day01.input", "\n"); @@ -117,6 +119,21 @@ fn day15() -> String { format!("part1: {}, part2: {}", n, day15::time_to_flood_the_area(&dts)) } +fn day16() -> String { + let signal_raw = fs::read_to_string("data/day16.input").unwrap(); + let signal = day16::parse(&signal_raw); + let output_part_1 = day16::fft(&signal, &[0, 1, 0, -1], 100, 0, 8, 1); + //let output_part_2 = day16::part2(&signal); + format!("part1: {}, part2: {}", day16::digits_as_string(&output_part_1), /*day16::digits_as_string(&output_part_2)*/ "") +} + +fn day17() -> String { + let code = common::read_list_of_numbers("data/day17.input", ","); + let n = day17::scaffold_intersections(&code); + format!("part1: {}, part2: {}", n, "") + +} + fn format_micros(t: u128) -> String { if t < 10_000 { format!("{} μs", t) @@ -151,6 +168,8 @@ fn main() { day13, day14, day15, + day16, + day17, ); let args: Vec = env::args().skip(1).collect();