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
|
struct GameSet {
red: u32,
green: u32,
blue: u32
}
impl GameSet {
fn is_valid(&self) -> bool {
self.red <= 12 && self.green <= 13 && self.blue <= 14
}
}
struct Game {
id: u32,
sets: Vec<GameSet>
}
fn main() {
let input = include_str!("./input.txt");
let output: u32 = input
.lines()
.map(|line| {
process_line(line)
})
.filter(|game| {
game.sets.iter().all(|set: &GameSet| set.is_valid())
})
.map(|game| {
game.id
}).sum();
println!("Result {output}")
}
fn gameset_from_pairs(pairs: Vec<(&str, u32)>) -> GameSet {
let mut red: u32 = 0;
let mut green: u32 = 0;
let mut blue: u32 = 0;
for pair in pairs {
match pair {
("red", x) => { red = x },
("green", x) => { green = x },
("blue", x) => { blue = x },
what => panic!("Unknown pair {:?}", what)
}
}
GameSet { red, green, blue }
}
/// Progrss a line
fn process_line(string: &str) -> Game {
let game_split: Vec<&str> = string.splitn(2, ": ").collect();
// Get game Id from string "Game 1"
let game_id = game_split[0].split(" ").last().expect("Expected id").parse::<u32>().expect("Cant parse game id");
let sets: Vec<_> = game_split[1]
.split("; ")
.map(|set_line| {
set_line.split(", ").collect()
})
.map(|gameset: Vec<&str>| {
let pairs: Vec<(&str, u32)> = gameset.into_iter().map(|s| {
let split: Vec<&str> = s.split_whitespace().collect();
(split[1], split[0].parse::<u32>().expect("Cant parse"))
}).collect();
gameset_from_pairs(pairs)
})
.collect();
Game {
id: game_id,
sets
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_process_simple() {
let game = process_line("Game 1: 3 blue, 4 red; 1 red, 2 green, 6 blue; 2 green");
assert_eq!(game.id, 1);
}
#[test]
fn test_input() {
let input = "Game 1: 3 blue, 4 red; 1 red, 2 green, 6 blue; 2 green
Game 2: 1 blue, 2 green; 3 green, 4 blue, 1 red; 1 green, 1 blue
Game 3: 8 green, 6 blue, 20 red; 5 blue, 4 red, 13 green; 5 green, 1 red
Game 4: 1 green, 3 red, 6 blue; 3 green, 6 red; 3 green, 15 blue, 14 red
Game 5: 6 red, 1 blue, 3 green; 2 blue, 1 red, 2 green";
let output: u32 = input.lines().map(|line| {
process_line(line)
})
.filter(|game| {
game.sets.iter().all(|set: &GameSet| set.is_valid())
})
.map(|game| {
game.id
}).sum();
assert_eq!(output, 8);
}
}
|