2016/09
This commit is contained in:
4
2016/09/Cargo.lock
generated
Normal file
4
2016/09/Cargo.lock
generated
Normal file
@@ -0,0 +1,4 @@
|
||||
[root]
|
||||
name = "09"
|
||||
version = "0.1.0"
|
||||
|
||||
6
2016/09/Cargo.toml
Normal file
6
2016/09/Cargo.toml
Normal file
@@ -0,0 +1,6 @@
|
||||
[package]
|
||||
name = "09"
|
||||
version = "0.1.0"
|
||||
authors = ["logaritmisk <anders.e.olsson@gmail.com>"]
|
||||
|
||||
[dependencies]
|
||||
1
2016/09/input.txt
Normal file
1
2016/09/input.txt
Normal file
File diff suppressed because one or more lines are too long
204
2016/09/src/main.rs
Normal file
204
2016/09/src/main.rs
Normal file
@@ -0,0 +1,204 @@
|
||||
use std::io::{self, BufRead};
|
||||
|
||||
|
||||
#[derive(Debug)]
|
||||
enum MachineState {
|
||||
Normal,
|
||||
MarkerRange(String),
|
||||
MarkerRepeat(usize, String),
|
||||
Sequence(usize, usize, String),
|
||||
}
|
||||
|
||||
|
||||
fn decompressed_length_v1(input: &str) -> usize {
|
||||
let mut length: usize = 0;
|
||||
|
||||
let mut state = MachineState::Normal;
|
||||
|
||||
for c in input.chars() {
|
||||
state = match (c, state) {
|
||||
// Normal.
|
||||
('(', MachineState::Normal) => {
|
||||
MachineState::MarkerRange(String::new())
|
||||
}
|
||||
(_, MachineState::Normal) => {
|
||||
length += 1;
|
||||
|
||||
MachineState::Normal
|
||||
}
|
||||
|
||||
// Marker range.
|
||||
('x', MachineState::MarkerRange(buf)) => {
|
||||
let range = buf.parse::<usize>().unwrap();
|
||||
|
||||
MachineState::MarkerRepeat(range, String::new())
|
||||
}
|
||||
(c @ _, MachineState::MarkerRange(mut buf)) => {
|
||||
buf.push(c);
|
||||
|
||||
MachineState::MarkerRange(buf)
|
||||
}
|
||||
|
||||
// Marker repeat.
|
||||
(')', MachineState::MarkerRepeat(range, buf)) => {
|
||||
let repeat = buf.parse::<usize>().unwrap();
|
||||
|
||||
MachineState::Sequence(range, repeat, String::new())
|
||||
}
|
||||
(c @ _, MachineState::MarkerRepeat(range, mut buf)) => {
|
||||
buf.push(c);
|
||||
|
||||
MachineState::MarkerRepeat(range, buf)
|
||||
}
|
||||
|
||||
// Sequence.
|
||||
(c @ _, MachineState::Sequence(range, repeat, mut buf)) => {
|
||||
buf.push(c);
|
||||
|
||||
if buf.len() == range {
|
||||
length += buf.len() * repeat;
|
||||
|
||||
MachineState::Normal
|
||||
} else {
|
||||
MachineState::Sequence(range, repeat, buf)
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
length
|
||||
}
|
||||
|
||||
fn decompressed_length_v2(input: &str) -> usize {
|
||||
let mut length: usize = 0;
|
||||
|
||||
let mut state = MachineState::Normal;
|
||||
|
||||
for c in input.chars() {
|
||||
state = match (c, state) {
|
||||
// Normal.
|
||||
('(', MachineState::Normal) => {
|
||||
MachineState::MarkerRange(String::new())
|
||||
}
|
||||
(_, MachineState::Normal) => {
|
||||
length += 1;
|
||||
|
||||
MachineState::Normal
|
||||
}
|
||||
|
||||
// Marker range.
|
||||
('x', MachineState::MarkerRange(buf)) => {
|
||||
let range = buf.parse::<usize>().unwrap();
|
||||
|
||||
MachineState::MarkerRepeat(range, String::new())
|
||||
}
|
||||
(c @ _, MachineState::MarkerRange(mut buf)) => {
|
||||
buf.push(c);
|
||||
|
||||
MachineState::MarkerRange(buf)
|
||||
}
|
||||
|
||||
// Marker repeat.
|
||||
(')', MachineState::MarkerRepeat(range, buf)) => {
|
||||
let repeat = buf.parse::<usize>().unwrap();
|
||||
|
||||
MachineState::Sequence(range, repeat, String::new())
|
||||
}
|
||||
(c @ _, MachineState::MarkerRepeat(range, mut buf)) => {
|
||||
buf.push(c);
|
||||
|
||||
MachineState::MarkerRepeat(range, buf)
|
||||
}
|
||||
|
||||
// Sequence.
|
||||
(_, MachineState::Sequence(range, repeat, mut buf)) => {
|
||||
buf.push(c);
|
||||
|
||||
if buf.len() == range {
|
||||
length += decompressed_length_v2(&buf) * repeat;
|
||||
|
||||
MachineState::Normal
|
||||
} else {
|
||||
MachineState::Sequence(range, repeat, buf)
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
length
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let stdin = io::stdin();
|
||||
|
||||
let lines = stdin.lock().lines()
|
||||
.filter_map(|line| line.ok())
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
let length_v1: usize = lines.iter()
|
||||
.map(|line| decompressed_length_v1(&line))
|
||||
.sum();
|
||||
|
||||
let length_v2: usize = lines.iter()
|
||||
.map(|line| decompressed_length_v2(&line))
|
||||
.sum();
|
||||
|
||||
println!("length_v1={}", length_v1);
|
||||
println!("length_v2={}", length_v2);
|
||||
}
|
||||
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::{decompressed_length_v1, decompressed_length_v2};
|
||||
|
||||
#[test]
|
||||
fn example_01() {
|
||||
assert_eq!(6, decompressed_length_v1("ADVENT"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn example_02() {
|
||||
assert_eq!(7, decompressed_length_v1("A(1x5)BC"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn example_03() {
|
||||
assert_eq!(9, decompressed_length_v1("(3x3)XYZ"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn example_04() {
|
||||
assert_eq!(11, decompressed_length_v1("A(2x2)BCD(2x2)EFG"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn example_05() {
|
||||
assert_eq!(6, decompressed_length_v1("(6x1)(1x3)A"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn example_06() {
|
||||
assert_eq!(18, decompressed_length_v1("X(8x2)(3x3)ABCY"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn example_07() {
|
||||
assert_eq!(9, decompressed_length_v2("(3x3)XYZ"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn example_08() {
|
||||
assert_eq!(20, decompressed_length_v2("X(8x2)(3x3)ABCY"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn example_09() {
|
||||
assert_eq!(241920, decompressed_length_v2("(27x12)(20x12)(13x14)(7x10)(1x12)A"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn example_10() {
|
||||
assert_eq!(445, decompressed_length_v2("(25x3)(3x3)ABC(2x3)XY(5x2)PQRSTX(18x9)(3x2)TWO(5x7)SEVEN"));
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user