summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJesse Luehrs <doy@tozt.net>2022-12-01 04:21:57 -0500
committerJesse Luehrs <doy@tozt.net>2022-12-01 04:47:05 -0500
commit18cab4c9209996aeaa29a88f8ac98e91dcfdede9 (patch)
treedbf156a4a8951facc32fefaaa83a4ea6ff38db24
parent3cdefe9564d7d13ce0c643c1b4433f21f2d2e839 (diff)
downloadadvent-of-code-18cab4c9209996aeaa29a88f8ac98e91dcfdede9.tar.gz
advent-of-code-18cab4c9209996aeaa29a88f8ac98e91dcfdede9.zip
simplify
-rw-r--r--src/2020/4/mod.rs31
-rw-r--r--src/2021/19/mod.rs29
-rw-r--r--src/2021/4/mod.rs16
-rw-r--r--src/2022/1/mod.rs15
-rw-r--r--src/parse.rs37
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()
}