aboutsummaryrefslogtreecommitdiffstats
path: root/AoC2022/02/solver.rs
blob: 2fd1e62cf2f00d40eaae2331bc2e3769e5f3d469 (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
use std::fs;
use std::io::{self, BufRead};

#[derive(Debug, PartialEq, Clone)]
enum Hand {
    Rock,
    Paper,
    Scissors,
}

fn translate(play: &str) -> Hand {
    match play {
        "A" | "X" => Hand::Rock,
        "B" | "Y" => Hand::Paper,
        "C" | "Z" => Hand::Scissors,
        &_ => panic!(),
    }
}

fn weight(play: Hand) -> u32 {
    match play {
        Hand::Rock => 1,
        Hand::Paper => 2,
        Hand::Scissors => 3,
    }
}

enum Conclusion {
    Loose,
    Draw,
    Win,
}

fn strategy(play: &str) -> Conclusion {
    match play {
        "X" => Conclusion::Loose,
        "Y" => Conclusion::Draw,
        "Z" => Conclusion::Win,
        &_ => panic!("Invalid input"),
    }
}
fn wins(play: Hand) -> Hand {
    match play {
        Hand::Rock => Hand::Scissors,
        Hand::Scissors => Hand::Paper,
        Hand::Paper => Hand::Rock,
    }
}
fn looses(play: Hand) -> Hand {
    match play {
        Hand::Scissors => Hand::Rock,
        Hand::Paper => Hand::Scissors,
        Hand::Rock => Hand::Paper,
    }
}

fn pick_move(strategy: Conclusion, other: Hand) -> Hand {
    match strategy {
        Conclusion::Draw => other,
        Conclusion::Win => looses(other),
        Conclusion::Loose => wins(other),
    }
}

fn fight(my: Hand, other: Hand) -> u32 {
    match (my, other) {
        (a, b) if a == b => 3,
        (a, b) => {
            if wins(a) == b {
                6
            } else {
                0
            }
        }
    }
}

fn fixed_plays(my: &str, _oponent: Hand) -> Hand {
    translate(my)
}

fn reactive_plays(my: &str, oponent: Hand) -> Hand {
    pick_move(strategy(my), oponent)
}

fn solver(strategy: &dyn Fn(&str, Hand) -> Hand) -> u32 {
    let file = fs::File::open("input").unwrap();
    let lines = io::BufReader::new(file).lines();
    lines.fold(0, |acc, line| {
        if let [ot, my] = line.unwrap().split_whitespace().collect::<Vec<_>>()[..] {
            let opo = translate(ot);
            let my_hand = strategy(my, opo.clone());
            acc + fight(my_hand.clone(), opo) + weight(my_hand)
        } else {
            panic!("Wrong line")
        }
    })
}

fn main() {
    assert_eq!(12535, solver(&fixed_plays));
    assert_eq!(15457, solver(&reactive_plays));
    println!("All test passed.")
}