Day 4 WIP parsing lines
This commit is contained in:
parent
a3abcbf107
commit
ac311a1b1c
66
Cargo.lock
generated
66
Cargo.lock
generated
@ -2,6 +2,7 @@
|
||||
name = "advent-of-code-2018"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"chrono 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"regex 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
@ -18,6 +19,16 @@ name = "cfg-if"
|
||||
version = "0.1.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "chrono"
|
||||
version = "0.4.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"num-integer 0.1.39 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"num-traits 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"time 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "lazy_static"
|
||||
version = "1.2.0"
|
||||
@ -38,6 +49,24 @@ dependencies = [
|
||||
"version_check 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num-integer"
|
||||
version = "0.1.39"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"num-traits 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num-traits"
|
||||
version = "0.2.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "redox_syscall"
|
||||
version = "0.1.44"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "regex"
|
||||
version = "1.1.0"
|
||||
@ -66,6 +95,16 @@ dependencies = [
|
||||
"lazy_static 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "time"
|
||||
version = "0.1.41"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"libc 0.2.45 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"redox_syscall 0.1.44 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ucd-util"
|
||||
version = "0.1.3"
|
||||
@ -81,15 +120,42 @@ name = "version_check"
|
||||
version = "0.1.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "winapi"
|
||||
version = "0.3.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "winapi-i686-pc-windows-gnu"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "winapi-x86_64-pc-windows-gnu"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[metadata]
|
||||
"checksum aho-corasick 0.6.9 (registry+https://github.com/rust-lang/crates.io-index)" = "1e9a933f4e58658d7b12defcf96dc5c720f20832deebe3e0a19efd3b6aaeeb9e"
|
||||
"checksum cfg-if 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "082bb9b28e00d3c9d39cc03e64ce4cea0f1bb9b3fde493f0cbc008472d22bdf4"
|
||||
"checksum chrono 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)" = "45912881121cb26fad7c38c17ba7daa18764771836b34fab7d3fbd93ed633878"
|
||||
"checksum lazy_static 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a374c89b9db55895453a74c1e38861d9deec0b01b405a82516e9d5de4820dea1"
|
||||
"checksum libc 0.2.45 (registry+https://github.com/rust-lang/crates.io-index)" = "2d2857ec59fadc0773853c664d2d18e7198e83883e7060b63c924cb077bd5c74"
|
||||
"checksum memchr 2.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "db4c41318937f6e76648f42826b1d9ade5c09cafb5aef7e351240a70f39206e9"
|
||||
"checksum num-integer 0.1.39 (registry+https://github.com/rust-lang/crates.io-index)" = "e83d528d2677f0518c570baf2b7abdcf0cd2d248860b68507bdcb3e91d4c0cea"
|
||||
"checksum num-traits 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "0b3a5d7cc97d6d30d8b9bc8fa19bf45349ffe46241e8816f50f62f6d6aaabee1"
|
||||
"checksum redox_syscall 0.1.44 (registry+https://github.com/rust-lang/crates.io-index)" = "a84bcd297b87a545980a2d25a0beb72a1f490c31f0a9fde52fca35bfbb1ceb70"
|
||||
"checksum regex 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "37e7cbbd370869ce2e8dff25c7018702d10b21a20ef7135316f8daecd6c25b7f"
|
||||
"checksum regex-syntax 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)" = "4e47a2ed29da7a9e1960e1639e7a982e6edc6d49be308a3b02daf511504a16d1"
|
||||
"checksum thread_local 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "c6b53e329000edc2b34dbe8545fd20e55a333362d0a321909685a19bd28c3f1b"
|
||||
"checksum time 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)" = "847da467bf0db05882a9e2375934a8a55cffdc9db0d128af1518200260ba1f6c"
|
||||
"checksum ucd-util 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "535c204ee4d8434478593480b8f86ab45ec9aae0e83c568ca81abf0fd0e88f86"
|
||||
"checksum utf8-ranges 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "796f7e48bef87609f7ade7e06495a87d5cd06c7866e6a5cbfceffc558a243737"
|
||||
"checksum version_check 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "914b1a6776c4c929a602fafd8bc742e06365d4bcbe48c30f9cca5824f70dc9dd"
|
||||
"checksum winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "92c1eb33641e276cfa214a0522acad57be5c56b10cb348b3c5117db75f3ac4b0"
|
||||
"checksum winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
|
||||
"checksum winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
|
||||
|
@ -5,4 +5,5 @@ authors = ["Tyler Hallada <tyler@hallada.net>"]
|
||||
edition = "2018"
|
||||
|
||||
[dependencies]
|
||||
chrono = "0.4"
|
||||
regex = "1"
|
||||
|
17
inputs/4_test.txt
Normal file
17
inputs/4_test.txt
Normal file
@ -0,0 +1,17 @@
|
||||
[1518-11-01 00:00] Guard #10 begins shift
|
||||
[1518-11-01 00:05] falls asleep
|
||||
[1518-11-01 00:25] wakes up
|
||||
[1518-11-01 00:30] falls asleep
|
||||
[1518-11-01 00:55] wakes up
|
||||
[1518-11-01 23:58] Guard #99 begins shift
|
||||
[1518-11-02 00:40] falls asleep
|
||||
[1518-11-02 00:50] wakes up
|
||||
[1518-11-03 00:05] Guard #10 begins shift
|
||||
[1518-11-03 00:24] falls asleep
|
||||
[1518-11-03 00:29] wakes up
|
||||
[1518-11-04 00:02] Guard #99 begins shift
|
||||
[1518-11-04 00:36] falls asleep
|
||||
[1518-11-04 00:46] wakes up
|
||||
[1518-11-05 00:03] Guard #99 begins shift
|
||||
[1518-11-05 00:45] falls asleep
|
||||
[1518-11-05 00:55] wakes up
|
5
inputs/4_test_malformed.txt
Normal file
5
inputs/4_test_malformed.txt
Normal file
@ -0,0 +1,5 @@
|
||||
[1518-11-01 00:00] Guard #10 begins shift
|
||||
[1518-11-01 00:05] falls asleep
|
||||
[1518-11-01 00:25] wakes up
|
||||
[1518-11-01 00:30] falls asleep
|
||||
[1518-11-01 00:55] dies
|
206
src/day4.rs
Normal file
206
src/day4.rs
Normal file
@ -0,0 +1,206 @@
|
||||
extern crate chrono;
|
||||
extern crate regex;
|
||||
|
||||
use std::error::Error;
|
||||
use std::fs::File;
|
||||
use std::io::{BufRead, BufReader};
|
||||
use std::fmt;
|
||||
use std::collections::{HashMap, HashSet};
|
||||
use std::iter::FromIterator;
|
||||
|
||||
use chrono::prelude::*;
|
||||
use regex::{Regex, Captures};
|
||||
|
||||
const INPUT: &str = "inputs/4.txt";
|
||||
|
||||
#[derive(Debug, PartialEq)]
|
||||
enum Record {
|
||||
Start {
|
||||
time: NaiveDateTime,
|
||||
guard_id: u32,
|
||||
},
|
||||
Sleep {
|
||||
time: NaiveDateTime,
|
||||
},
|
||||
Wake {
|
||||
time: NaiveDateTime,
|
||||
},
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq)]
|
||||
struct MalformedRecord {
|
||||
details: String
|
||||
}
|
||||
|
||||
impl MalformedRecord {
|
||||
fn new(msg: &str) -> MalformedRecord {
|
||||
MalformedRecord{ details: msg.to_string() }
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for MalformedRecord {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(f, "{}", self.details)
|
||||
}
|
||||
}
|
||||
|
||||
impl Error for MalformedRecord {
|
||||
fn description(&self) -> &str {
|
||||
&self.details
|
||||
}
|
||||
}
|
||||
|
||||
fn read_records(filename: &str) -> Result<Vec<Record>, Box<Error>> {
|
||||
let mut records: Vec<Record> = Vec::new();
|
||||
let record_regex =
|
||||
Regex::new(r"\[(?P<timestamp>\d{4}-\d{2}-\d{2}\s\d{2}:\d{2})\]\s(?:(?P<start>Guard #(?P<guard_id>\d+) begins shift)|(?P<sleep>falls asleep)|(?P<wake>wakes up))")?;
|
||||
let file = File::open(filename)?;
|
||||
for line in BufReader::new(file).lines() {
|
||||
match record_regex.captures(&line?) {
|
||||
Some(captures) => {
|
||||
println!("{:?}", NaiveDateTime::parse_from_str(
|
||||
&get_captured_field(&captures, "timestamp")?,
|
||||
"%Y-%m-%d %H:%M")?);
|
||||
if has_captured_field(&captures, "start")? {
|
||||
records.push(Record::Start {
|
||||
time: NaiveDateTime::parse_from_str(
|
||||
&get_captured_field(&captures, "timestamp")?,
|
||||
"%Y-%m-%d %H:%M")?,
|
||||
guard_id: get_captured_field(&captures, "guard_id")?.parse()?,
|
||||
});
|
||||
} else if has_captured_field(&captures, "sleep")? {
|
||||
records.push(Record::Sleep {
|
||||
time: NaiveDateTime::parse_from_str(
|
||||
&get_captured_field(&captures, "timestamp")?,
|
||||
"%Y-%m-%d %H:%M")?,
|
||||
});
|
||||
} else {
|
||||
records.push(Record::Wake {
|
||||
time: NaiveDateTime::parse_from_str(
|
||||
&get_captured_field(&captures, "timestamp")?,
|
||||
"%Y-%m-%d %H:%M")?,
|
||||
});
|
||||
}
|
||||
},
|
||||
None => return Err(Box::new(MalformedRecord {
|
||||
details: "Malformed record line, no fields could be found".to_string()
|
||||
})),
|
||||
};
|
||||
}
|
||||
Ok(records)
|
||||
}
|
||||
|
||||
fn get_captured_field(captures: &Captures, field: &str) -> Result<String, Box<Error>> {
|
||||
match captures.name(field) {
|
||||
Some(capture) => Ok(String::from(capture.as_str())),
|
||||
None => return Err(Box::new(MalformedRecord {
|
||||
details: format!("Malformed record line, field {} could not be found", field)
|
||||
}))
|
||||
}
|
||||
}
|
||||
|
||||
fn has_captured_field(captures: &Captures, field: &str) -> Result<bool, Box<Error>> {
|
||||
match captures.name(field) {
|
||||
Some(_) => Ok(true),
|
||||
None => Ok(false)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
const TEST_INPUT: &str = "inputs/4_test.txt";
|
||||
const TEST_INPUT_MALFORMED: &str = "inputs/4_test_malformed.txt";
|
||||
|
||||
#[test]
|
||||
fn reads_records_file() {
|
||||
assert_eq!(read_records(TEST_INPUT).unwrap(), vec![
|
||||
Record::Start {
|
||||
time: NaiveDateTime::parse_from_str(
|
||||
"1518-11-01 00:00", "%Y-%m-%d %H:%M").unwrap(),
|
||||
guard_id: 10,
|
||||
},
|
||||
Record::Sleep {
|
||||
time: NaiveDateTime::parse_from_str(
|
||||
"1518-11-01 00:05", "%Y-%m-%d %H:%M").unwrap(),
|
||||
},
|
||||
Record::Wake {
|
||||
time: NaiveDateTime::parse_from_str(
|
||||
"1518-11-01 00:25", "%Y-%m-%d %H:%M").unwrap(),
|
||||
},
|
||||
Record::Sleep {
|
||||
time: NaiveDateTime::parse_from_str(
|
||||
"1518-11-01 00:30", "%Y-%m-%d %H:%M").unwrap(),
|
||||
},
|
||||
Record::Wake {
|
||||
time: NaiveDateTime::parse_from_str(
|
||||
"1518-11-01 00:55", "%Y-%m-%d %H:%M").unwrap(),
|
||||
},
|
||||
Record::Start {
|
||||
time: NaiveDateTime::parse_from_str(
|
||||
"1518-11-01 23:58", "%Y-%m-%d %H:%M").unwrap(),
|
||||
guard_id: 99,
|
||||
},
|
||||
Record::Sleep {
|
||||
time: NaiveDateTime::parse_from_str(
|
||||
"1518-11-02 00:40", "%Y-%m-%d %H:%M").unwrap(),
|
||||
},
|
||||
Record::Wake {
|
||||
time: NaiveDateTime::parse_from_str(
|
||||
"1518-11-02 00:50", "%Y-%m-%d %H:%M").unwrap(),
|
||||
},
|
||||
Record::Start {
|
||||
time: NaiveDateTime::parse_from_str(
|
||||
"1518-11-03 00:05", "%Y-%m-%d %H:%M").unwrap(),
|
||||
guard_id: 10,
|
||||
},
|
||||
Record::Sleep {
|
||||
time: NaiveDateTime::parse_from_str(
|
||||
"1518-11-03 00:24", "%Y-%m-%d %H:%M").unwrap(),
|
||||
},
|
||||
Record::Wake {
|
||||
time: NaiveDateTime::parse_from_str(
|
||||
"1518-11-03 00:29", "%Y-%m-%d %H:%M").unwrap(),
|
||||
},
|
||||
Record::Start {
|
||||
time: NaiveDateTime::parse_from_str(
|
||||
"1518-11-04 00:02", "%Y-%m-%d %H:%M").unwrap(),
|
||||
guard_id: 99,
|
||||
},
|
||||
Record::Sleep {
|
||||
time: NaiveDateTime::parse_from_str(
|
||||
"1518-11-04 00:36", "%Y-%m-%d %H:%M").unwrap(),
|
||||
},
|
||||
Record::Wake {
|
||||
time: NaiveDateTime::parse_from_str(
|
||||
"1518-11-04 00:46", "%Y-%m-%d %H:%M").unwrap(),
|
||||
},
|
||||
Record::Start {
|
||||
time: NaiveDateTime::parse_from_str(
|
||||
"1518-11-05 00:03", "%Y-%m-%d %H:%M").unwrap(),
|
||||
guard_id: 99,
|
||||
},
|
||||
Record::Sleep {
|
||||
time: NaiveDateTime::parse_from_str(
|
||||
"1518-11-05 00:45", "%Y-%m-%d %H:%M").unwrap(),
|
||||
},
|
||||
Record::Wake {
|
||||
time: NaiveDateTime::parse_from_str(
|
||||
"1518-11-05 00:55", "%Y-%m-%d %H:%M").unwrap(),
|
||||
},
|
||||
]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn errors_on_malformed_records_file() {
|
||||
match read_records(TEST_INPUT_MALFORMED) {
|
||||
Ok(_) => assert!(false, "read_records should have returned an error"),
|
||||
Err(err) => assert_eq!(
|
||||
(*err).description(),
|
||||
"Malformed record line, no fields could be found".to_string(),
|
||||
),
|
||||
}
|
||||
}
|
||||
}
|
@ -1,6 +1,7 @@
|
||||
mod day1;
|
||||
mod day2;
|
||||
mod day3;
|
||||
mod day4;
|
||||
|
||||
fn main() {
|
||||
println!("Day 1:");
|
||||
|
Loading…
Reference in New Issue
Block a user