summaryrefslogtreecommitdiff
path: root/src/day10.rs
blob: 9e638023d64bdf2036e6a13114c7a520b656a1dc (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
use std::ops::Add;

fn cycles(op: &str) -> usize {
    match op {
        "noop" => 1,
        "addx" => 2,
        unk => panic!("unknown op {}", unk)
    }
}

fn op_and_args(instruction: &str) -> (&str, Option<i32>) {
    let mut toks = instruction.split_whitespace();
    let op = toks.next().expect("expected an operator!");
    let arg = match op {
        "noop" => None,
        "addx" => {
            let arg1: i32 = toks.next().expect("expected one arg for addx").parse().expect("arg for addx must be i32");
            Some(arg1)
        },
        unk => panic!("unknown op {}", unk)
    };
    (op,arg)
}

fn apply(op: &str, arg: Option<i32>, x: i32) -> i32 {
    match op {
        "noop" => x,
        "addx" => x + arg.expect("addx had no argument!"),
        unk => panic!("unknown op {}", unk) 
    }
}

pub fn run(input: String) {
    let mut lines = input.lines().into_iter();
    // our (single) register
    let mut x = 1;
    let mut tick = 1;
    let first_instruction: &str = lines.next().expect("expected a first instruction!");
    let (mut op, mut arg) = op_and_args(first_instruction);
    let mut circ = cycles(op);
    //let mut sss = 0;
    let mut screen = "".to_owned();
    loop {
        // Start of cycle, Load next instruction
        if circ == 0 {
            if let Some(next_inst) = lines.next() {
                (op, arg)= op_and_args(next_inst);
                circ = cycles(op);    
            } else {
                break;
            }
        }
        // Time passes....
        circ -= 1;

        // Pt1, signal strength
        // if (tick + 20) % 40 == 0 {
        //     let ss = tick*x;
        //     //println!("tick {} x {} ss {}", tick, x, ss);
        //     sss += ss;
        // }

        // Pt2, Draw pixels! note crt_col is one less(!) than tick
        let crt_col = (tick-1) % 40;
        //println!("tick {} x {} crt_col {}", tick, x, crt_col);
        screen = screen.add(if crt_col >= (x-1) && crt_col <= (x+1) {
            "#"
        } else {
            "."
        });
        if crt_col == 39 {
            screen = screen.add("\n");
        }

        // End of cycle, apply instruction
        if circ == 0 {
            x = apply(op, arg, x);
        }
        // increase cycle counter
        tick += 1;
    }
    //println!("Day 10: {}",sss);
    println!("Day 10:");
    print!("{}", screen);
}