summaryrefslogtreecommitdiff
path: root/src/day2.rs
blob: 15a99de76079c32b7511717bd5498b278125d1bd (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
// Accumulator structure... 
// parse each line

use simple_error::{SimpleError,bail};

#[derive(PartialEq)]
enum Move{ Rock, Paper, Scissors }
enum Res { Win, Draw, Loss }

fn parse_m1(c: char) -> Result<Move, SimpleError> {
    match c {
        'A' => Ok(Move::Rock),
        'B' => Ok(Move::Paper),
        'C' => Ok(Move::Scissors),
        _ => bail!("invalid character {}", c)
    }
}
// fn parse_m2(c: char) -> Result<Move, SimpleError> {
//     match c {
//         'X' => Ok(Move::Rock),
//         'Y' => Ok(Move::Paper),
//         'Z' => Ok(Move::Scissors),
//        _ => bail!("invalid character {}", c)
//     }
// }
fn parse_req_res(c: char) -> Result<Res, SimpleError> {
    match c {
        'X' => Ok(Res::Loss),
        'Y' => Ok(Res::Draw),
        'Z' => Ok(Res::Win),
        _ => bail!("invalid character {}", c)
    }
}
// fn win(opp: Move, you: Move) -> Res {
//     match opp {
//         Move::Rock => match you {
//             Move::Rock => Res::Draw,
//             Move::Paper => Res::Win,
//             Move::Scissors => Res::Loss,
//         },
//         Move::Paper => match you {
//             Move::Rock => Res::Loss,
//             Move::Paper => Res::Draw,
//             Move::Scissors => Res::Win,
//         },
//         Move::Scissors => match you {
//             Move::Rock => Res::Win,
//             Move::Paper => Res::Loss,
//             Move::Scissors => Res::Draw,
//         }
//     }
// }
fn calc_req_move(opp: Move, req_res: Res) -> Move {
    match req_res {
        Res::Win => match opp {
            Move::Rock => Move::Paper,
            Move::Paper => Move::Scissors,
            Move::Scissors => Move::Rock
        }
        Res::Draw => opp,
        Res::Loss => match opp {
            Move::Rock => Move::Scissors,
            Move::Paper => Move::Rock,
            Move::Scissors => Move::Paper   
        }
    }
}

// fn score(opp: Move, you: Move) -> u32 {
//     let ms: u32 = match you {
//         Move::Rock => 1,
//         Move::Paper => 2,
//         Move::Scissors => 3,
//     };
//     let ws: u32 = match win(opp, you) {
//         Res::Win => 6,
//         Res::Draw => 3,
//         Res::Loss => 0,
//     };
//     return ms+ws;
// }
fn score(opp: Move, req_res: Res) -> u32 {
    let ws: u32 = match req_res {
        Res::Win => 6,
        Res::Draw => 3,
        Res::Loss => 0,
    };
    let mm = calc_req_move(opp, req_res);
    let ms: u32 = match mm {
        Move::Rock => 1,
        Move::Paper => 2,
        Move::Scissors => 3,
    };
    return ms+ws;
}

// fn parse_turn(line: &str) -> Result<(Move, Move), SimpleError> {
//     let mut lc = line.chars();
//     let e1: SimpleError = SimpleError::new("not enough characters in input!");
//     let c1 = lc.next().ok_or(e1.clone())?;
//     lc.next().ok_or(e1.clone())?;
//     let c2 = lc.next().ok_or(e1.clone())?;
//     let m_opp = parse_m1(c1)?;
//     let m_you = parse_m2(c2)?;
//     Ok((m_opp, m_you))
// }
fn parse_turn(line: &str) -> Result<(Move, Res), SimpleError> {
    let mut lc = line.chars();
    let e1: SimpleError = SimpleError::new("not enough characters in input!");
    let c1 = lc.next().ok_or(e1.clone())?;
    lc.next().ok_or(e1.clone())?;
    let c2 = lc.next().ok_or(e1.clone())?;
    let m_opp = parse_m1(c1)?;
    let req_res = parse_req_res(c2)?;
    Ok((m_opp, req_res))
}

pub fn run(input: String) {
    let score: u32 = input.lines().map(|line| {
        let (m_opp, m_you) = parse_turn(line).expect("invalid input line!");
        score(m_opp, m_you)
    }).sum::<u32>();
    println!("day 2: {}", score);
}