y2015d19 I should look at the input more
This commit is contained in:
parent
16ed2a8cae
commit
261a2e89c9
45
y2015/resources/19_input.txt
Normal file
45
y2015/resources/19_input.txt
Normal file
@ -0,0 +1,45 @@
|
||||
Al => ThF
|
||||
Al => ThRnFAr
|
||||
B => BCa
|
||||
B => TiB
|
||||
B => TiRnFAr
|
||||
Ca => CaCa
|
||||
Ca => PB
|
||||
Ca => PRnFAr
|
||||
Ca => SiRnFYFAr
|
||||
Ca => SiRnMgAr
|
||||
Ca => SiTh
|
||||
F => CaF
|
||||
F => PMg
|
||||
F => SiAl
|
||||
H => CRnAlAr
|
||||
H => CRnFYFYFAr
|
||||
H => CRnFYMgAr
|
||||
H => CRnMgYFAr
|
||||
H => HCa
|
||||
H => NRnFYFAr
|
||||
H => NRnMgAr
|
||||
H => NTh
|
||||
H => OB
|
||||
H => ORnFAr
|
||||
Mg => BF
|
||||
Mg => TiMg
|
||||
N => CRnFAr
|
||||
N => HSi
|
||||
O => CRnFYFAr
|
||||
O => CRnMgAr
|
||||
O => HP
|
||||
O => NRnFAr
|
||||
O => OTi
|
||||
P => CaP
|
||||
P => PTi
|
||||
P => SiRnFAr
|
||||
Si => CaSi
|
||||
Th => ThCa
|
||||
Ti => BP
|
||||
Ti => TiTi
|
||||
e => HF
|
||||
e => NAl
|
||||
e => OMg
|
||||
|
||||
CRnCaSiRnBSiRnFArTiBPTiTiBFArPBCaSiThSiRnTiBPBPMgArCaSiRnTiMgArCaSiThCaSiRnFArRnSiRnFArTiTiBFArCaCaSiRnSiThCaCaSiRnMgArFYSiRnFYCaFArSiThCaSiThPBPTiMgArCaPRnSiAlArPBCaCaSiRnFYSiThCaRnFArArCaCaSiRnPBSiRnFArMgYCaCaCaCaSiThCaCaSiAlArCaCaSiRnPBSiAlArBCaCaCaCaSiThCaPBSiThPBPBCaSiRnFYFArSiThCaSiRnFArBCaCaSiRnFYFArSiThCaPBSiThCaSiRnPMgArRnFArPTiBCaPRnFArCaCaCaCaSiRnCaCaSiRnFYFArFArBCaSiThFArThSiThSiRnTiRnPMgArFArCaSiThCaPBCaSiRnBFArCaCaPRnCaCaPMgArSiRnFYFArCaSiThRnPBPMgAr
|
20
y2015/src/bin/d19.rs
Normal file
20
y2015/src/bin/d19.rs
Normal file
@ -0,0 +1,20 @@
|
||||
use std::fs;
|
||||
|
||||
use y2015::days::d19;
|
||||
|
||||
fn main() {
|
||||
part1();
|
||||
part2();
|
||||
}
|
||||
|
||||
fn part1() {
|
||||
let root = env!("CARGO_MANIFEST_DIR");
|
||||
let content = fs::read_to_string(format!("{root}/resources/19_input.txt")).unwrap();
|
||||
println!("{}", d19::process_part1(&content));
|
||||
}
|
||||
|
||||
fn part2() {
|
||||
let root = env!("CARGO_MANIFEST_DIR");
|
||||
let content = fs::read_to_string(format!("{root}/resources/19_input.txt")).unwrap();
|
||||
println!("{}", d19::process_part2(&content));
|
||||
}
|
110
y2015/src/days/d19.rs
Normal file
110
y2015/src/days/d19.rs
Normal file
@ -0,0 +1,110 @@
|
||||
use std::collections::HashSet;
|
||||
|
||||
pub fn process_part1(input: &str) -> u32 {
|
||||
let (replacements_str, molecule) = input.split_once("\n\n").unwrap();
|
||||
let mut replacements = Vec::new();
|
||||
replacements_str.lines().for_each(|line| {
|
||||
let (from, to) = line.split_once(" => ").unwrap();
|
||||
replacements.push((from, to));
|
||||
});
|
||||
let mut possible = HashSet::new();
|
||||
for (from, to) in replacements {
|
||||
molecule.match_indices(from).for_each(|(idx, _)| {
|
||||
let mut new_possible = molecule.to_string();
|
||||
new_possible.replace_range(idx..(idx + from.len()), to);
|
||||
possible.insert(new_possible);
|
||||
});
|
||||
}
|
||||
possible.len() as u32
|
||||
}
|
||||
|
||||
// https://www.reddit.com/r/adventofcode/comments/3xflz8/comment/cy4etju/
|
||||
// broken test
|
||||
//First insight
|
||||
//
|
||||
//There are only two types of productions:
|
||||
//
|
||||
// e => XX and X => XX (X is not Rn, Y, or Ar)
|
||||
//
|
||||
// X => X Rn X Ar | X Rn X Y X Ar | X Rn X Y X Y X Ar
|
||||
//
|
||||
//Second insight
|
||||
//
|
||||
//You can think of Rn Y Ar as the characters ( , ):
|
||||
//
|
||||
//X => X(X) | X(X,X) | X(X,X,X)
|
||||
//
|
||||
//Whenever there are two adjacent "elements" in your "molecule", you apply the first production. This reduces your molecule length by 1 each time.
|
||||
//
|
||||
//And whenever you have T(T) T(T,T) or T(T,T,T) (T is a literal token such as "Mg", i.e. not a nonterminal like "TiTiCaCa"), you apply the second production. This reduces your molecule length by 3, 5, or 7.
|
||||
//Third insight
|
||||
//
|
||||
//Repeatedly applying X => XX until you arrive at a single token takes count(tokens) - 1 steps:
|
||||
//
|
||||
//ABCDE => XCDE => XDE => XE => X
|
||||
//count("ABCDE") = 5
|
||||
//5 - 1 = 4 steps
|
||||
//
|
||||
//Applying X => X(X) is similar to X => XX, except you get the () for free. This can be expressed as count(tokens) - count("(" or ")") - 1.
|
||||
//
|
||||
//A(B(C(D(E)))) => A(B(C(X))) => A(B(X)) => A(X) => X
|
||||
//count("A(B(C(D(E))))") = 13
|
||||
//count("(((())))") = 8
|
||||
//13 - 8 - 1 = 4 steps
|
||||
//
|
||||
//You can generalize to X => X(X,X) by noting that each , reduces the length by two (,X). The new formula is count(tokens) - count("(" or ")") - 2*count(",") - 1.
|
||||
//
|
||||
//A(B(C,D),E(F,G)) => A(B(C,D),X) => A(X,X) => X
|
||||
//count("A(B(C,D),E(F,G))") = 16
|
||||
//count("(()())") = 6
|
||||
//count(",,,") = 3
|
||||
//16 - 6 - 2*3 - 1 = 3 steps
|
||||
//
|
||||
//This final formula works for all of the production types (for X => XX, the (,) counts are zero by definition.)
|
||||
pub fn process_part2(input: &str) -> u32 {
|
||||
let (_replacements_str, molecule) = input.split_once("\n\n").unwrap();
|
||||
// An element is always at least an uppercase character and possibly an additional lowercase
|
||||
// character
|
||||
let total_elements = molecule.chars().filter(|char| char.is_uppercase()).count();
|
||||
let num_rn = molecule.matches("Rn").count();
|
||||
let num_ar = molecule.matches("Ar").count();
|
||||
let num_y = molecule.matches("Y").count();
|
||||
(total_elements - (num_rn + num_ar) - 2 * num_y - 1) as u32
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
const INPUT1: &str = "H => HO
|
||||
H => OH
|
||||
O => HH
|
||||
e => H
|
||||
e => O
|
||||
|
||||
HOH";
|
||||
|
||||
const INPUT2: &str = "H => HO
|
||||
H => OH
|
||||
O => HH
|
||||
e => H
|
||||
e => O
|
||||
|
||||
HOHOHO";
|
||||
|
||||
#[test]
|
||||
fn part1() {
|
||||
let result = process_part1(INPUT1);
|
||||
assert_eq!(result, 4);
|
||||
let result = process_part1(INPUT2);
|
||||
assert_eq!(result, 7);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn part2() {
|
||||
let result = process_part2(INPUT1);
|
||||
assert_eq!(result, 3);
|
||||
let result = process_part2(INPUT2);
|
||||
assert_eq!(result, 6);
|
||||
}
|
||||
}
|
@ -16,3 +16,5 @@ pub mod d6;
|
||||
pub mod d7;
|
||||
pub mod d8;
|
||||
pub mod d9;
|
||||
|
||||
pub mod d19;
|
||||
|
Loading…
Reference in New Issue
Block a user