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

#[derive(Debug, PartialEq, Clone, Copy)]
struct State {
    a: i64,
    b: i64,
    c: i64,
    pc: usize,
}

fn opcode(mut s: State, prog: &Vec<i64>, out: &mut Vec<i64>) -> State {
    let op = prog[s.pc];
    let arg = prog[s.pc + 1];

    let combo = match arg {
        0 => 0,
        1 => 1,
        2 => 2,
        3 => 3,
        4 => s.a,
        5 => s.b,
        6 => s.c,
        7 => panic!(),
        _ => panic!(),
    };

    let mut jump = false;
    match op {
        0 => s.a = s.a / (1 << combo),
        1 => s.b ^= arg,
        2 => s.b = combo % 8,
        3 => {
            if s.a != 0 {
                jump = true;
                s.pc = arg as usize;
            }
        }
        4 => s.b ^= s.c,
        5 => out.push(combo % 8),
        6 => s.b = s.a / (1 << combo),
        7 => s.c = s.a / (1 << combo),
        _ => panic!(),
    }

    if jump == false {
        s.pc += 2;
    }

    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").collect::<Vec<_>>();

    let (l, r) = lines[0].split_once(": ").unwrap();
    let mut a: i64 = r.parse().unwrap();
    let (l, r) = lines[1].split_once(": ").unwrap();
    let mut b: i64 = r.parse().unwrap();
    let (l, r) = lines[2].split_once(": ").unwrap();
    let mut c: i64 = r.parse().unwrap();

    let (l, r) = lines[4].split_once(": ").unwrap();
    let prog: Vec<i64> = r.split(",").map(|x| x.parse().unwrap()).collect();

    let mut s = State {
        a: a,
        b: b,
        c: c,
        pc: 0,
    };

    let mut out: Vec<i64> = Vec::new();
    loop {
        //println!("{:?} {:?}", s, out);
        if s.pc + 1 >= prog.len() {
            break;
        }
        s = opcode(s, &prog, &mut out);
    }
    //println!("{:?}", out);

    let res1 = out
        .iter()
        .map(|x| x.to_string())
        .collect::<Vec<_>>()
        .join(",");

    let mut res2 = 0;

    println!("res1: {}", res1);
    println!("res2: {}", res2);
    assert_eq!(res1, "6,2,7,2,3,1,6,0,5");
    //assert_eq!(res2, );
}