summaryrefslogtreecommitdiff
path: root/2024/day20.rs
blob: a0549ef1e94ef4d4e9d41ae8f05dd1cd9ac5da42 (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
#![allow(dead_code)]
#![allow(unused_variables)]
#![allow(unused_mut)]
use std::cmp::min;
use std::collections::HashMap;
use std::env;
use std::fs::File;
use std::io::Read;

fn dfs(
    mut score: i64,
    sx: i64,
    sy: i64,
    ex: i64,
    ey: i64,
    m: &Vec<Vec<bool>>,
    lut: &mut HashMap<(i64, i64), i64>,
) -> i64 {
    if sx == ex && sy == ey {
        return score;
    }

    if let Some(val) = lut.get(&(sx, sy)) {
        if *val < score {
            return 99999999999;
        }
    }
    lut.insert((sx, sy), score);

    let mut s = 99999999999;

    for (dx, dy) in [(1, 0), (-1, 0), (0, 1), (0, -1)] {
        let mut x = sx + dx;
        let mut y = sy + dy;
        if m[y as usize][x as usize] {
            let a = dfs(score + 1, x, y, ex, ey, &m, lut);
            s = min(s, a);
        }
    }

    return s;
}

fn main() {
    let args: Vec<String> = env::args().collect();
    let filename = if args.len() == 1 {
        "in/".to_owned() + args[0].split('/').last().unwrap() + ".pzl"
    } else {
        args[1].clone()
    };
    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 sx = 0;
    let mut sy = 0;
    let mut ex = 0;
    let mut ey = 0;
    let mut m: Vec<Vec<bool>> = Vec::new();
    for (y, line) in lines.enumerate() {
        let mut l: Vec<bool> = Vec::new();
        for (x, c) in line.chars().enumerate() {
            if c == '#' {
                l.push(false);
            } else {
                l.push(true);
            }
            if c == 'S' {
                sx = x as i64;
                sy = y as i64;
            } else if c == 'E' {
                ex = x as i64;
                ey = y as i64;
            }
        }
        //println!("{:?}", l);
        m.push(l);
    }
    let width = m.len();
    let height = m[0].len();
    println!("{} {}", width, height);

    let mut lut: HashMap<(i64, i64), i64> = HashMap::new();
    let ref_score = dfs(0, sx, sy, ex, ey, &m, &mut lut);

    let mut res1 = 0;
    for y in 1..height - 1 {
        for x in 1..width - 1 {
            if m[y][x] == true {
                continue;
            }
            let mut mc = m.clone();
            mc[y][x] = true;
            lut.clear();
            let score = dfs(0, sx, sy, ex, ey, &mc, &mut lut);
            if score + 100 <= ref_score {
                res1 += 1;
            }
            println!("{}", score);
        }
    }

    //print(&m, &hs);
    let mut res2 = 0;

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