diff options
author | Jesse Luehrs <doy@tozt.net> | 2022-12-01 04:21:57 -0500 |
---|---|---|
committer | Jesse Luehrs <doy@tozt.net> | 2022-12-01 04:47:05 -0500 |
commit | 18cab4c9209996aeaa29a88f8ac98e91dcfdede9 (patch) | |
tree | dbf156a4a8951facc32fefaaa83a4ea6ff38db24 | |
parent | 3cdefe9564d7d13ce0c643c1b4433f21f2d2e839 (diff) | |
download | advent-of-code-18cab4c9209996aeaa29a88f8ac98e91dcfdede9.tar.gz advent-of-code-18cab4c9209996aeaa29a88f8ac98e91dcfdede9.zip |
simplify
-rw-r--r-- | src/2020/4/mod.rs | 31 | ||||
-rw-r--r-- | src/2021/19/mod.rs | 29 | ||||
-rw-r--r-- | src/2021/4/mod.rs | 16 | ||||
-rw-r--r-- | src/2022/1/mod.rs | 15 | ||||
-rw-r--r-- | src/parse.rs | 37 |
5 files changed, 71 insertions, 57 deletions
diff --git a/src/2020/4/mod.rs b/src/2020/4/mod.rs index 98a35fb..b198c31 100644 --- a/src/2020/4/mod.rs +++ b/src/2020/4/mod.rs @@ -6,23 +6,22 @@ const REQUIRED_KEYS: &[&str] = pub fn parse(fh: File) -> Result<Vec<HashMap<String, String>>> { let mut res = vec![]; let mut cur = HashMap::new(); - for line in parse::lines(fh) { - if line.is_empty() { - res.push(cur); - cur = HashMap::new(); - continue; - } - - for field in line.split(' ') { - let mut parts = field.split(':'); - let key = parts.next().with_context(|| { - format!("failed to parse field '{}'", field) - })?; - let value = parts.next().with_context(|| { - format!("failed to parse field '{}'", field) - })?; - cur.insert(key.to_string(), value.to_string()); + let mut lines = parse::lines(fh).peekable(); + while lines.peek().is_some() { + for line in parse::chunk(&mut lines) { + for field in line.split(' ') { + let mut parts = field.split(':'); + let key = parts.next().with_context(|| { + format!("failed to parse field '{}'", field) + })?; + let value = parts.next().with_context(|| { + format!("failed to parse field '{}'", field) + })?; + cur.insert(key.to_string(), value.to_string()); + } } + res.push(cur); + cur = HashMap::new(); } if !cur.is_empty() { res.push(cur); diff --git a/src/2021/19/mod.rs b/src/2021/19/mod.rs index 7468ccc..6a9b66a 100644 --- a/src/2021/19/mod.rs +++ b/src/2021/19/mod.rs @@ -93,23 +93,16 @@ struct Scanner { } impl Scanner { - fn parse(lines: &mut impl Iterator<Item = String>) -> Option<Self> { - if lines.next().is_some() { - let mut beacons = vec![]; - for line in lines { - if line.is_empty() { - break; - } - let mut parts = line.split(',').map(|i| i.parse().unwrap()); - let x = parts.next().unwrap(); - let y = parts.next().unwrap(); - let z = parts.next().unwrap(); - beacons.push(Point::new(x, y, z)) - } - Some(Self { beacons }) - } else { - None + fn parse(lines: impl Iterator<Item = String>) -> Self { + let mut beacons = vec![]; + for line in lines { + let mut parts = line.split(',').map(|i| i.parse().unwrap()); + let x = parts.next().unwrap(); + let y = parts.next().unwrap(); + let z = parts.next().unwrap(); + beacons.push(Point::new(x, y, z)) } + Self { beacons } } fn matches(&self, other: &HashSet<Point>) -> Option<(usize, Point)> { @@ -166,8 +159,8 @@ pub struct Scan { impl Scan { fn parse(mut lines: impl Iterator<Item = String>) -> Self { let mut scanners = vec![]; - while let Some(scanner) = Scanner::parse(lines.by_ref()) { - scanners.push(scanner); + while lines.next().is_some() { + scanners.push(Scanner::parse(parse::chunk(&mut lines))); } Self { scanners } } diff --git a/src/2021/4/mod.rs b/src/2021/4/mod.rs index ff6d061..c1b0cd2 100644 --- a/src/2021/4/mod.rs +++ b/src/2021/4/mod.rs @@ -58,24 +58,20 @@ pub struct Game { impl Game { fn parse<T: std::io::Read>(input: T) -> Result<Self> { - let mut input = std::io::BufReader::new(input); - let mut line = String::new(); - input.read_line(&mut line)?; + let mut lines = parse::lines(input).peekable(); + + let line = lines.next().ok_or_else(|| anyhow!("missing line"))?; let inputs = line .trim() .split(',') .map(|s| s.parse()) .collect::<Result<Vec<u8>, _>>()?; + lines.next(); let mut boards = vec![]; - loop { - if let Ok(0) = input.read_line(&mut line) { - break; - } + while lines.peek().is_some() { let mut numbers = vec![]; - for _ in 0..5 { - line.clear(); - input.read_line(&mut line)?; + for line in parse::chunk(&mut lines) { numbers.extend( line.split_whitespace() .map(|s| s.parse()) diff --git a/src/2022/1/mod.rs b/src/2022/1/mod.rs index 4f644d6..d3088b6 100644 --- a/src/2022/1/mod.rs +++ b/src/2022/1/mod.rs @@ -5,17 +5,14 @@ use crate::prelude::*; pub fn parse(fh: File) -> Result<Vec<i64>> { let mut elves = vec![]; - let mut cur = 0; - for line in parse::lines(fh) { - let line = line.trim(); - if line.is_empty() { - elves.push(cur); - cur = 0; - } else { - cur += line.parse::<i64>()?; + let mut lines = parse::lines(fh).peekable(); + while lines.peek().is_some() { + let mut calories = 0; + for line in parse::chunk(&mut lines) { + calories += line.parse::<i64>()?; } + elves.push(calories); } - elves.push(cur); Ok(elves) } diff --git a/src/parse.rs b/src/parse.rs index 3674a25..3222bf0 100644 --- a/src/parse.rs +++ b/src/parse.rs @@ -4,12 +4,41 @@ pub fn data(year: u16, day: u16) -> Result<File> { File::open(format!("data/{}/{}.txt", year, day)).map_err(|e| anyhow!(e)) } -pub fn lines(fh: File) -> impl Iterator<Item = String> { +pub fn lines<R: std::io::Read>(fh: R) -> impl Iterator<Item = String> { let fh = std::io::BufReader::new(fh); fh.lines().map(|res| res.unwrap()) } -pub fn split(fh: File, sep: u8) -> impl Iterator<Item = String> { +pub struct Chunk<'a, I: Iterator<Item = String>> { + it: &'a mut I, +} + +impl<'a, I: Iterator<Item = String>> Iterator for Chunk<'a, I> { + type Item = String; + + fn next(&mut self) -> Option<Self::Item> { + if let Some(line) = self.it.next() { + if line.is_empty() { + return None; + } else { + return Some(line); + } + } + None + } +} + +pub fn chunk<I>(it: &mut I) -> Chunk<'_, I> +where + I: Iterator<Item = String>, +{ + Chunk { it } +} + +pub fn split<R: std::io::Read>( + fh: R, + sep: u8, +) -> impl Iterator<Item = String> { let fh = std::io::BufReader::new(fh); fh.split(sep) .map(|res| String::from_utf8(res.unwrap()).unwrap()) @@ -19,11 +48,11 @@ pub fn ints(iter: impl Iterator<Item = String>) -> impl Iterator<Item = i64> { iter.map(|s| s.trim().parse().unwrap()) } -pub fn bytes(fh: File) -> impl Iterator<Item = u8> { +pub fn bytes<R: std::io::Read>(fh: R) -> impl Iterator<Item = u8> { fh.bytes().map(|res| res.unwrap()) } -pub fn string(fh: File) -> String { +pub fn string<R: std::io::Read>(fh: R) -> String { let bytes: Vec<_> = bytes(fh).collect(); String::from_utf8(bytes).unwrap() } |