summaryrefslogtreecommitdiff
path: root/2023/day10.rs
blob: 919223cb6c2329abfb198338ebaa7db15b8c684c (plain)
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
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
#![allow(dead_code)]
#![allow(unused_variables)]
#![allow(unused_mut)]
use num::complex::Complex as c;
use num::Complex;
use std::fs::File;
use std::io::Read;

#[derive(Debug, PartialEq, Clone, Copy)]
enum Dir {
    Start,
    UD,
    LR,
    UR,
    UL,
    DL,
    DR,
    Ground,
}

const LUT: [(Dir, Complex<i32>, Complex<i32>, char, char); 8] = [
    (Dir::UD, c::new(0, 1), c::new(0, -1), '|', '│'),
    (Dir::LR, c::new(1, 0), c::new(-1, 0), '-', '─'),
    (Dir::UR, c::new(0, -1), c::new(1, 0), 'L', '└'),
    (Dir::UL, c::new(0, -1), c::new(-1, 0), 'J', '┘'),
    (Dir::DL, c::new(0, 1), c::new(-1, 0), '7', '┐'),
    (Dir::DR, c::new(0, 1), c::new(1, 0), 'F', '┌'),
    (Dir::Start, c::new(0, 0), c::new(0, 0), 'S', 'S'),
    (Dir::Ground, c::new(0, 0), c::new(0, 0), '.', ' '),
];

fn lookup(d: Dir) -> (Dir, Complex<i32>, Complex<i32>, char, char) {
    for i in 0..LUT.len() {
        if d == LUT[i].0 {
            return LUT[i].clone();
        }
    }
    panic!();
}

fn print_m(m: &Vec<Vec<Dir>>) {
    for i in 0..m.len() {
        for j in 0..m[0].len() {
            print!("{}", lookup(m[i][j]).4);
        }
        println!();
    }
    println!();
}

fn find_start(m: &Vec<Vec<Dir>>) -> Complex<i32> {
    for x in 0..m.len() {
        for y in 0..m[0].len() {
            if m[y][x] == Dir::Start {
                return (x as i32) + (y as i32) * c::i();
            }
        }
    }
    panic!();
}

fn next(
    mut pos: Complex<i32>,
    mut dir: Complex<i32>,
    m: &Vec<Vec<Dir>>,
) -> (Complex<i32>, Complex<i32>) {
    pos += dir;

    let (_, a, b, _, _) = lookup(m[pos.im as usize][pos.re as usize]);

    dir *= -1;

    if dir == a {
        dir = b;
    } else if dir == b {
        dir = a;
    } else {
        // panic!();
    }
    (pos, dir)
}

fn main() {
    // let filename = "in/day10.ref";
    let filename = "in/day10.pzl";

    let mut f = File::open(filename).expect("cannot open file");
    let mut content = String::new();
    f.read_to_string(&mut content).expect("cannot read file");
    let lines = content.trim_end().split('\n');

    let mut m: Vec<Vec<Dir>> = Vec::new();
    for line in lines {
        let mut r = Vec::new();
        for c in line.chars() {
            for m in LUT {
                if m.3 == c {
                    r.push(m.0);
                }
            }
        }
        m.push(r);
    }

    let mut res1 = 0;
    let mut res2 = 0;

    print_m(&m);
    let start = find_start(&m);

    let mut pos = start;
    let mut dir = c::new(1, 0);

    (pos, dir) = next(pos, dir, &m);
    res1 += 1;

    while pos != start {
        (pos, dir) = next(pos, dir, &m);
        res1 += 1;
    }
    res1 /= 2;
    println!("{} {}", pos, dir);

    println!("res1: {}", res1);
    println!("res2: {}", res2);
}