--- /dev/null
+use std::io::Read;
+use std::error::Error;
+use std::fs::File;
+
+use regex::Regex;
+
+pub fn run(input_file: &str) -> Result<(), Box<dyn Error>> {
+ let mut f = File::open(input_file)?;
+ let mut input = String::new();
+ f.read_to_string(&mut input)?;
+
+ let res = run_part1(&input)?;
+ println!("{res}");
+
+ let res = run_part2(&input)?;
+ println!("{res}");
+
+ Ok(())
+}
+
+// Hypothèses:
+// * N_red = 12
+// * N_green = 13
+// * N_blue = 14
+//
+// chercher les numéros de jeu qui peuvent correspondre
+// les additionner
+//
+// pour chaque tirage de chaque jeu, extraire le nombre de cube de chaque couleur
+//
+fn run_part1(input: &str) -> Result<i32, Box<dyn Error>> {
+ println!("Running day02 - part 1");
+
+ // [ red, green, blue ]
+ let limits = [ 12, 13, 14 ];
+ let regex = [
+ Regex::new(r"(\d+) red").unwrap(),
+ Regex::new(r"(\d+) green").unwrap(),
+ Regex::new(r"(\d+) blue").unwrap(),
+ ];
+
+ let a: Vec<(i32, &str)> = input.lines()
+ .map(|l| {
+ let game: Vec<&str> = l.split(':').collect();
+ let game_number: i32 = game[0].split(' ').last().unwrap().parse().unwrap();
+ (game_number, game[1])
+ })
+ .filter(|(g, l)| {
+ // vecteur qui contient true/false selon si le tirage est correct ou non
+ let mut result: Vec<bool> = Vec::new();
+ l.split(';')
+ .for_each(|draw| {
+ // vecteur qui contient un true/false selon si le nombre de cubes
+ // est inférieur/supérieur à la limite définie
+ // vecteur de 3 éléments [ bool_red, bool_green, bool_blue ]
+ let mut res_draw: Vec<bool> = Vec::new();
+ regex.iter().zip(limits) // (re, limit)
+ .for_each(|(re, l)| {
+ let caps = re.captures(draw);
+ //println!("caps: {:?}", caps);
+ if caps.is_some() {
+ let n = caps.unwrap().get(1);
+ if n.is_some() {
+ let n: i32 = n.unwrap().as_str().parse().unwrap();
+ //println!("{l}: {n}");
+ res_draw.push( n <= l );
+ return;
+ }
+ }
+ res_draw.push(true);
+ });
+ //println!("collect foreach draw: {:?}", res_draw);
+ result.push( ! res_draw.contains(&false) );
+ });
+ //println!("result per game {:?}", result);
+ !result.contains(&false)
+ })
+ .collect();
+ //println!("a: {:?}", a);
+ let res: i32 = a.iter().map(|(g,_)| g).sum();
+ Ok(res)
+}
+
+fn run_part2(input: &str) -> Result<String, Box<dyn Error>> {
+ println!("Running day02 - part 2");
+ Ok(input.to_string())
+}
+
+#[cfg(test)]
+mod tests {
+ use super::*;
+
+ #[test]
+ fn day02_part1() {
+ 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 res = run_part1(&input);
+ assert_eq!(8, res.unwrap());
+ }
+
+ #[test]
+ fn day02_part2() {
+ let input = "";
+ let res = run_part2(&input);
+ assert_eq!("", res.unwrap());
+ }
+}