Day 16 & day 17 part 1
authorGrégory Burri <gregory.burri@matisa.ch>
Wed, 18 Dec 2019 08:47:35 +0000 (09:47 +0100)
committerGrégory Burri <gregory.burri@matisa.ch>
Wed, 18 Dec 2019 08:47:35 +0000 (09:47 +0100)
day17.txt [new file with mode: 0644]
src/day16.rs [new file with mode: 0644]
src/day17.rs [new file with mode: 0644]
src/main.rs

diff --git a/day17.txt b/day17.txt
new file mode 100644 (file)
index 0000000..396303c
--- /dev/null
+++ b/day17.txt
@@ -0,0 +1,43 @@
+..........................#####..................\r
+..........................#...#..................\r
+..........................#...#..................\r
+..........................#...#..................\r
+..........................#...#..................\r
+..........................#...#..................\r
+..........................#######................\r
+..............................#.#................\r
+............................###########..........\r
+............................#.#.#.....#..........\r
+..................#############.#.....#..........\r
+..................#.........#...#.....#..........\r
+..................#.........#######...#..........\r
+..................#.............#.#...#..........\r
+..................#.............#.#...#..........\r
+..................#.............#.#...#..........\r
+......#############.............#.#...#..........\r
+......#.........................#.#...#..........\r
+###########.....................#######..........\r
+#.....#...#.......................#..............\r
+#.....#...#.......................#...#######....\r
+#.....#...#.......................#...#.....#....\r
+#######...#.......................#...#.....#....\r
+..........#.......................#...#.....#....\r
+..........#.......................###########....\r
+..........#...........................#..........\r
+..........#...........................#...#######\r
+..........#...........................#...#.....#\r
+..........#.........................#####.#.....#\r
+..........#.........................#.#.#.#.....#\r
+..........#######...................#.###########\r
+................#...................#...#.#......\r
+................#.............#############......\r
+................#.............#.....#...#........\r
+................#.............#.....#...#........\r
+................#.............#.........#........\r
+................#.............#.........#........\r
+................#.............#.........#........\r
+................#.............###########........\r
+................#................................\r
+................#................................\r
+................#................................\r
+................######^..........................
\ No newline at end of file
diff --git a/src/day16.rs b/src/day16.rs
new file mode 100644 (file)
index 0000000..2112c0e
--- /dev/null
@@ -0,0 +1,104 @@
+use std::iter::FromIterator;\r
+\r
+pub fn parse(input: &str) -> Vec<i32> {\r
+    input.chars().map(|c| c.to_digit(10).unwrap() as i32).collect()\r
+}\r
+\r
+pub fn fft(signal: &[i32], pattern: &[i32], nb_phases: i32, offset: usize, length: usize, nb_signal_repeated: usize) -> Vec<i32> {\r
+\r
+    let l = signal.len();\r
+    let pattern_l = pattern.len();\r
+\r
+    let mut output = Vec::from_iter(signal.iter().cycle().take(l * nb_signal_repeated).copied());\r
+\r
+    for _ in 0 .. nb_phases {\r
+        let cloned_output = output.clone();\r
+        for i in 0 .. output.len() {\r
+            output[i] =\r
+                cloned_output.iter().enumerate().fold(\r
+                    0,\r
+                    |sum, (j, value)| {\r
+                        sum + value * pattern[(j + 1) / (i + 1) % pattern_l]\r
+                    }\r
+                ).abs() % 10;\r
+        }\r
+    }\r
+\r
+    Vec::from(&output[offset .. offset + length])\r
+}\r
+\r
+pub fn digits_as_string(signal: &[i32]) -> String {\r
+    signal.iter().fold(String::new(), |result, digit| result + &digit.to_string())\r
+}\r
+\r
+// Part 2 is from 'https://github.com/mkeeter/advent-of-code/blob/master/2019/16/src/main.rs'.\r
+\r
+fn cumsum(input: &[i32]) -> Vec<i32> {\r
+    let mut output = vec![0; input.len() + 1];\r
+    for (i, v) in input.iter().enumerate() {\r
+        output[i + 1] = output[i] + v;\r
+    }\r
+    output\r
+}\r
+\r
+fn dft(scale: usize, csum: &[i32]) -> i32 {\r
+    use std::cmp::min;\r
+\r
+    assert!(scale > 0);\r
+    let mut i = scale;\r
+    let mut sign = true;\r
+    let mut out = 0;\r
+    while i < csum.len() {\r
+        let d = csum[min(csum.len() - 1, i + scale - 1)] - csum[i - 1];\r
+        if sign {\r
+            out += d;\r
+        } else {\r
+            out -= d;\r
+        }\r
+        sign = !sign;\r
+        i += scale * 2;\r
+    }\r
+    out.abs() % 10\r
+}\r
+\r
+pub fn part2(input: &[i32]) -> Vec<i32> {\r
+    let size = input.len();\r
+    let mut input = Vec::from_iter(input.iter().cycle().take(size * 10_000).copied());\r
+\r
+    let offset = input[..7].iter().fold(0, |acc, i| acc * 10 + i) as usize;\r
+\r
+    for _ in 0..100 {\r
+        let csum = cumsum(&input);\r
+        input = (0..input.len())\r
+            .map(|i| dft(i + 1, &csum))\r
+            .collect::<Vec<i32>>();\r
+    }\r
+\r
+    Vec::from(&input[offset..(offset + 8)])\r
+}\r
+\r
+#[cfg(test)]\r
+mod tests {\r
+    use super::*;\r
+\r
+    #[test]\r
+    fn part1_sample_1() {\r
+        let signal = parse("80871224585914546619083218645595");\r
+        let output = fft(&signal, &[0, 1, 0, -1], 100, 0, 8, 1);\r
+        assert_eq!(digits_as_string(&output), "24176176");\r
+    }\r
+\r
+    #[test]\r
+    fn part1_sample_2() {\r
+        let signal = parse("19617804207202209144916044189917");\r
+        let output = fft(&signal, &[0, 1, 0, -1], 100, 0, 8, 1);\r
+        assert_eq!(digits_as_string(&output), "73745418");\r
+    }\r
+\r
+    #[test]\r
+    fn part1_sample_3() {\r
+        let signal = parse("69317163492948606335995924319873");\r
+        let output = fft(&signal, &[0, 1, 0, -1], 100, 0, 8, 1);\r
+        assert_eq!(digits_as_string(&output), "52432133");\r
+    }\r
+}
\ No newline at end of file
diff --git a/src/day17.rs b/src/day17.rs
new file mode 100644 (file)
index 0000000..15bd825
--- /dev/null
@@ -0,0 +1,74 @@
+use super::intcode;\r
+use std::collections::HashSet;\r
+\r
+pub fn scaffold_intersections(code: &[i64]) -> i32 {\r
+    let output = intcode::execute_op_code(code, &[]);\r
+    let mut board = Vec::<Vec<char>>::new();\r
+    let mut current_line = Vec::<char>::new();\r
+\r
+    let (mut x, mut y) = (0i32, 0i32);\r
+    let mut dir = '^';\r
+\r
+    let mut current_x = 0;\r
+    for c in output {\r
+        if c == 10 {\r
+            board.push(current_line);\r
+            current_line = Vec::<char>::new();\r
+            current_x = 0;\r
+            //println!("");\r
+        } else {\r
+            let c = (c as u8) as char;\r
+            if let '^' | '<' | 'v' | '>' = c {\r
+                x = current_x;\r
+                y = board.len() as i32;\r
+                dir = c;\r
+            }\r
+            //print!("{}", c);\r
+            current_line.push(c);\r
+            current_x += 1;\r
+        }\r
+    }\r
+\r
+    let get = |x: i32, y: i32| -> Option<char> {\r
+        if x < board[0].len() as i32 && x >= 0 && y < board.len() as i32 && y >= 0 {\r
+            Some(board[y as usize][x as usize])\r
+        } else {\r
+            None\r
+        }\r
+    };\r
+\r
+    let mut visited_locations = HashSet::<(i32, i32)>::new();\r
+    let mut crosses = Vec::<(i32, i32)>::new();\r
+    visited_locations.insert((x, y));\r
+\r
+    'main: loop {\r
+        let positions = [('^', (x, y - 1)), ('<', (x - 1, y)), ('>', (x + 1, y)), ('v', (x, y + 1))];\r
+\r
+        let next_position = positions.iter().find(|(d, _)| *d == dir).unwrap().1;\r
+            //match dir { '^' => positions[0], '<' => positions[1], '>' => positions[2], 'v' | _ => positions[3] };\r
+\r
+        // If the robot can continue straightforward.\r
+        if get(next_position.0, next_position.1) == Some('#') {\r
+            if !visited_locations.insert(next_position) {\r
+                crosses.push(next_position);\r
+            }\r
+            x = next_position.0;\r
+            y = next_position.1;\r
+            continue;\r
+        }\r
+\r
+        for (d, p) in &positions {\r
+            if get(p.0, p.1) == Some('#') && !visited_locations.contains(p) {\r
+                visited_locations.insert(*p);\r
+                dir = *d;\r
+                x = p.0;\r
+                y = p.1;\r
+                continue 'main;\r
+            }\r
+        }\r
+\r
+        break;\r
+    }\r
+\r
+    crosses.iter().fold(0, |sum, cross| sum + cross.0 * cross.1)\r
+}
\ No newline at end of file
index 491ee5c..4788102 100644 (file)
@@ -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)*/ "<skipped: take too long>")
+}
+
+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<String> = env::args().skip(1).collect();