Rain Risk


Fork me on GitHub
2020-12-12

Day 12: Rain Risk

Description:
--- Day 12: Rain Risk ---

Your ferry made decent progress toward the island, but the storm came in faster than anyone expected. The ferry needs to take evasive actions!

Unfortunately, the ship's navigation computer seems to be malfunctioning; rather than giving a route directly to safety, it produced extremely circuitous instructions. When the captain uses the PA system to ask if anyone can help, you quickly volunteer.

The navigation instructions (your puzzle input) consists of a sequence of single-character actions paired with integer input values. After staring at them for a few minutes, you work out what they probably mean:

Action N means to move north by the given value.
Action S means to move south by the given value.
Action E means to move east by the given value.
Action W means to move west by the given value.
Action L means to turn left the given number of degrees.
Action R means to turn right the given number of degrees.
Action F means to move forward by the given value in the direction the ship is currently facing.

The ship starts by facing east. Only the L and R actions change the direction the ship is facing. (That is, if the ship is facing east and the next instruction is N10, the ship would move north 10 units, but would still move east if the following action were F.)

For example:

F10
N3
F7
R90
F11

These instructions would be handled as follows:

F10 would move the ship 10 units east (because the ship starts by facing east) to east 10, north 0.
N3 would move the ship 3 units north to east 10, north 3.
F7 would move the ship another 7 units east (because the ship is still facing east) to east 17, north 3.
R90 would cause the ship to turn right by 90 degrees and face south; it remains at east 17, north 3.
F11 would move the ship 11 units south to east 17, south 8.

At the end of these instructions, the ship's Manhattan distance (sum of the absolute values of its east/west position and its north/south position) from its starting position is 17 + 8 = 25.

Figure out where the navigation instructions lead. What is the Manhattan distance between that location and the ship's starting position?

--- Part Two ---

Before you can give the destination to the captain, you realize that the actual action meanings were printed on the back of the instructions the whole time.

Almost all of the actions indicate how to move a waypoint which is relative to the ship's position:

Action N means to move the waypoint north by the given value.
Action S means to move the waypoint south by the given value.
Action E means to move the waypoint east by the given value.
Action W means to move the waypoint west by the given value.
Action L means to rotate the waypoint around the ship left (counter-clockwise) the given number of degrees.
Action R means to rotate the waypoint around the ship right (clockwise) the given number of degrees.
Action F means to move forward to the waypoint a number of times equal to the given value.

The waypoint starts 10 units east and 1 unit north relative to the ship. The waypoint is relative to the ship; that is, if the ship moves, the waypoint moves with it.

For example, using the same instructions as above:

F10 moves the ship to the waypoint 10 times (a total of 100 units east and 10 units north), leaving the ship at east 100, north 10. The waypoint stays 10 units east and 1 unit north of the ship.
N3 moves the waypoint 3 units north to 10 units east and 4 units north of the ship. The ship remains at east 100, north 10.
F7 moves the ship to the waypoint 7 times (a total of 70 units east and 28 units north), leaving the ship at east 170, north 38. The waypoint stays 10 units east and 4 units north of the ship.
R90 rotates the waypoint around the ship clockwise 90 degrees, moving it to 4 units east and 10 units south of the ship. The ship remains at east 170, north 38.
F11 moves the ship to the waypoint 11 times (a total of 44 units east and 110 units south), leaving the ship at east 214, south 72. The waypoint stays 4 units east and 10 units south of the ship.

After these operations, the ship's Manhattan distance from its starting position is 214 + 72 = 286.

Figure out where the navigation instructions actually lead. What is the Manhattan distance between that location and the ship's starting position?

Input:
N5
W1
F61
W2
R90
F50
N2
F40
E4
F48
R180
F17
W4
N5
F3
W3
F1
R90
S2
F23
L90
S3
W3
S4
E4
L90
W3
S3
E4
N2
F28
S2
W2
L180
E3
R90
E3
F83
W5
S4
W3
N2
W5
F90
N2
F82
N2
F2
S4
L90
N3
L90
S2
F12
S3
F40
L90
F56
N1
F29
W2
S2
R270
S4
F14
E4
R90
E2
S2
E2
F82
L90
N3
R180
R90
S1
W1
L90
S2
F78
W2
F52
N4
W5
F38
L90
W2
S2
L90
F66
R90
F62
E3
S5
L90
F99
F2
E4
R90
N3
W4
N1
F71
E2
N3
N2
R90
E2
F66
S4
R90
E5
F29
E5
L90
W2
N2
E3
F18
L180
F17
W1
R90
W3
S5
R90
S3
R180
N5
F69
W1
W3
L180
F72
W5
N1
R180
W3
W4
F85
W4
L90
E4
N5
F73
R90
F70
E4
F79
S5
R180
E2
F35
E4
L270
W2
L90
N5
R90
N4
F64
W2
R270
F33
N5
E4
F94
W1
N1
R90
F79
F46
E1
R180
S3
W3
F72
E1
W4
F95
W2
L90
N3
L90
F85
W3
W1
F54
N3
E1
N4
E5
L90
F61
W2
F7
L180
F87
N4
W1
F87
F3
E3
F63
R90
S4
R180
S4
R180
R90
R90
E5
N4
E2
F86
S3
F98
N4
F70
L90
E4
F26
W4
F19
L90
S4
W4
F84
N1
E4
L180
S2
F74
S1
F86
R90
S2
F78
N4
S2
W1
N5
E2
F38
W4
N1
F75
S1
E1
N3
S1
F54
N3
F88
N5
L180
F15
S2
S2
E2
N3
F97
S3
N3
E3
N5
E3
R90
F87
L90
F15
L90
E5
R90
F70
N3
W2
F47
W2
W3
F17
R90
F95
E4
F28
W4
R90
E2
R180
N4
R180
W4
R270
F73
W1
N2
L90
S1
F65
E1
F42
N2
F74
R90
F21
W5
S1
N5
R90
E4
N5
S5
F99
W4
L180
W1
F83
N2
W2
F87
E2
S3
W1
L180
F89
S1
W2
E2
L90
S2
W1
S5
R180
E5
N1
F82
S3
F7
L90
F31
L90
N3
F84
W3
N4
F100
N1
E2
R90
F90
N3
F43
R90
F2
W4
L90
F87
L90
E3
F71
L180
N1
L90
E4
N3
F31
W1
F80
R270
N1
E4
N1
F22
N4
E1
F57
R90
N3
W2
L180
N3
L180
W4
F59
S4
F10
N5
L90
S3
L90
E1
F96
E4
N3
F54
L180
F47
W1
N4
E1
S4
R180
L90
N1
R90
N3
R90
N4
R90
S3
F59
N5
L90
E4
F72
W4
F76
R90
E3
F70
L180
N3
W2
R90
F65
L90
F71
S3
F43
R90
W2
N2
R90
W1
R90
S4
R180
S1
E3
F72
L90
F61
L90
F75
S1
S5
F15
R90
E3
N2
L270
F48
N1
R180
W2
F69
E4
R90
R90
W1
S5
W5
R90
S4
S3
F51
F43
E2
N5
L180
F89
W1
R90
F59
R90
E2
F51
R90
F91
W4
S5
E4
L90
S5
R90
F44
F47
E4
W1
F77
S5
R90
N2
F87
N4
R90
W5
R90
W5
F89
L90
F61
E2
F29
N4
R90
F31
S1
L90
E5
N2
F7
L180
S4
F63
W4
N5
S2
N1
E5
F87
S5
R180
F14
W4
R180
E1
L90
F67
E2
L90
E5
S2
L90
W2
R90
F94
W4
R90
W3
S3
R90
N5
F55
L90
F43
L90
N5
F16
E4
N2
L270
W3
E1
N2
R180
F51
N5
N1
F36
W4
F38
N5
W1
F29
R180
L90
N1
W3
E1
F78
E1
N1
E2
F57
E4
F83
W5
F32
N3
W4
F36
N2
E3
F74
N4
F54
W5
L90
S1
F42
W4
S5
E3
F64
W2
R180
S2
E1
N2
R90
W3
F36
N3
R90
S2
F53
W2
F85
E5
N2
F9
E1
F83
L90
E5
F44
L90
F92
W5
R270
E4
S1
F6
L90
F96
R90
N1
E4
N1
W3
S2
S4
F39
E1
S1
F82
S3
F78
L90
N4
E1
N2
R90
F63
S3
L180
F52
W2
F49
W2
L270
N1
R180
E3
F79
F73
N1
R90
N3
R180
S2
F35
S1
F43
S1
R90
S4
W4
F12
S1
F2
N3
E4
L90
F51
R90
N4
F90
R90
F99
E3
N1
R90
S3
L270
W5
L90
R270
F50
N5
F33
S3
F18
L90
E4
L180
W4
R90
F21
W4
F24
W2
E5
N3
W1
R90
W3
S3
F82
W1
S1
F12
N3
L90
F37
R180
F36
F27
E3
S3
F36
W4
S1
F6
R90
F59
S1
E1
R180
S2
W3
L90
F45
R90
E1
F29
S5
W3
S5
W4
L270
S2
F13
E4
F28
R90
F80
S4
E1
S2
F62
R90
F26
L180
F19
W2
L180
W5
F15
N1
F68
E4
F75
S2
F58
S4
R180
E3
N1
L90
S2
F12
R90
E5
S5
W4
N5
W1
R180
S1
F70
R90
F97
L90
E3
S3
L270
E1
F51
N4
L180
N1
R90
F42

use crate::common::AdventOfCodeDay;

#[derive(Debug)]
enum CType {
    North,
    East,
    South,
    West,
    TurnRight,
    TurnLeft,
    Forward,
}

#[derive(Debug)]
pub struct Day12 {
    input: Vec<(CType, i32)>,
}

impl Day12 {
    pub fn new() -> Self {
        let input_bytes = include_bytes!("../res/12_input.txt");
        let input_str = String::from_utf8_lossy(input_bytes);
        
        let data = input_str
                        .lines()
                        .map(Day12::parse_cmd)
                        .collect::<Vec<(CType, i32)>>();

        Self {
            input: data
        }
    }

    fn parse_cmd(line: &str) -> (CType, i32) {
        (match &line[0..1] {
            "N" => CType::North,
            "E" => CType::East,
            "S" => CType::South,
            "W" => CType::West,
            "L" => CType::TurnLeft,
            "R" => CType::TurnRight,
            "F" => CType::Forward,
            _   => panic!(),
        }, line[1..].parse::<i32>().unwrap())
    }
}

impl AdventOfCodeDay for Day12 {

    fn task_1(&self) -> String {
        if is_verbose!() {
            for e in &self.input { verboseln!("{:?}", e); }
            verboseln!();
            verboseln!();
        }

        let deltas: [(i32,i32); 4] = [(1,0),(0,1),(-1,0),(0,-1)];

        let mut x: i32 = 0;
        let mut y: i32 = 0;
        let mut d: i32 = 0;

        for cmd in &self.input {
            
            match cmd.0 {
                CType::North     => { y -= cmd.1; },
                CType::East      => { x += cmd.1; },
                CType::South     => { y += cmd.1; },
                CType::West      => { x -= cmd.1; },
                CType::TurnLeft  => { d = (d + 16 - (cmd.1 / 90)) % 4 },
                CType::TurnRight => { d = (d + 16 + (cmd.1 / 90)) % 4 },
                CType::Forward   => { x += deltas[d as usize].0 * cmd.1; y += deltas[d as usize].1 * cmd.1; },
            }

            verboseln!("[{},{}|{}] {:?}", x, y, d, cmd);
        }

        return (x.abs() + y.abs()).to_string();
    }

    fn task_2(&self) -> String  {
        
        let mut ship_x: i32 = 0;
        let mut ship_y: i32 = 0;
        let mut wp_x: i32 = 10;
        let mut wp_y: i32 = 1;

        verboseln!("Ship:[{},{}] WP:[{},{}]", ship_x, ship_y, wp_x, wp_y);
        for cmd in &self.input {
            
            match cmd.0 {
                CType::North     => { wp_y += cmd.1; },
                CType::East      => { wp_x += cmd.1; },
                CType::South     => { wp_y -= cmd.1; },
                CType::West      => { wp_x -= cmd.1; },
                
                CType::TurnLeft  => { for _ in 0..(cmd.1/90) { (wp_x, wp_y) = (-wp_y,  wp_x); } },
                CType::TurnRight => { for _ in 0..(cmd.1/90) { (wp_x, wp_y) = ( wp_y, -wp_x); } },

                CType::Forward   => { ship_x = ship_x + wp_x*cmd.1; ship_y = ship_y + wp_y*cmd.1; },
            }

            verboseln!("Ship:[{},{}] WP:[{},{}] {:?}", ship_x, ship_y, wp_x, wp_y, cmd);
        }

        return (ship_x.abs() + ship_y.abs()).to_string();
    }
}
Result Part 1: 2270
Result Part 2: 138669


made with vanilla PHP and MySQL, no frameworks, no bootstrap, no unnecessary* javascript