// Copyright 2023 Christian Ulrich // // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program. If not, see . use std::io; pub struct Game { id: u32, red: Vec, green: Vec, blue: Vec, } pub struct Games { inner: Vec, } impl Game { pub fn from_str(input: &str) -> Result { let (id_part, data) = input.split_once(':').ok_or("syntax error 1")?; let id = id_part .split_once(' ') .ok_or("syntax error 2")? .1 .parse() .map_err(|_| "syntax error 3")?; let mut result = Self { id: id, red: Vec::new(), green: Vec::new(), blue: Vec::new(), }; for drawing in data.split(';') { for color in drawing.split(',').map(str::trim) { let (count, name) = color.split_once(' ').ok_or("syntax error 4")?; match name { "red" => result .red .push(count.parse().map_err(|_| "syntax error 5")?), "green" => result .green .push(count.parse().map_err(|_| "syntax error")?), "blue" => result .blue .push(count.parse().map_err(|_| "syntax error 6")?), _ => return Err("syntax error"), } } } Ok(result) } pub fn id(&self) -> u32 { self.id } pub fn red_count(&self) -> u32 { *self.red.iter().max().unwrap_or(&0) } pub fn green_count(&self) -> u32 { *self.green.iter().max().unwrap_or(&0) } pub fn blue_count(&self) -> u32 { *self.blue.iter().max().unwrap_or(&0) } } impl Games { pub fn from_stdin() -> Result { let mut games = Vec::new(); for line in io::stdin().lines() { let line = line.unwrap(); if line.len() > 0 { games.push(Game::from_str(&line)?); } } Ok(Self { inner: games }) } pub fn iter(&mut self) -> std::slice::Iter<'_, Game> { self.inner.iter() } }