From d7ed7cb411329c15e2c5457b3b1c48aa9dba22c8 Mon Sep 17 00:00:00 2001 From: Jan Tuomi Date: Thu, 6 Dec 2018 16:13:16 +0200 Subject: Solve day5 --- day5/src/main.rs | 114 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 114 insertions(+) create mode 100644 day5/src/main.rs (limited to 'day5/src') diff --git a/day5/src/main.rs b/day5/src/main.rs new file mode 100644 index 0000000..4b2b0bc --- /dev/null +++ b/day5/src/main.rs @@ -0,0 +1,114 @@ +use std::env; +use std::io::BufReader; +use std::io::BufRead; +use std::fs::File; +use std::process; + +static ASCII_LOWER: [char; 26] = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', + 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', + 's', 't', 'u', 'v', 'w', 'x', 'y', 'z']; + +fn same_unit(a: &char, b: &char) -> bool { + a.to_lowercase().to_string() == b.to_lowercase().to_string() +} + +fn same_polarity(a: &char, b: &char) -> bool { + (a.is_lowercase() && b.is_lowercase()) || (a.is_uppercase() && b.is_uppercase()) +} + +fn find_removable_indices(chars: &Vec) -> Option<(usize, usize)> { + let mut res: Option<(usize, usize)> = None; + for (i, cur) in chars.iter().enumerate() { + if i == chars.len() - 1 { // last element + break; + } + + let next = chars[i + 1]; + if same_unit(&cur, &next) && !same_polarity(&cur, &next) { + res = Some((i, i + 1)); + break; + } + } + + res +} + +fn react_polymer(line: &String) -> String { + let mut string: Vec = line.trim().chars().collect(); + loop { + let indices = find_removable_indices(&string); + let (rem_i1, rem_i2): (usize, usize); + match indices { + Some((i1, i2)) => { + rem_i1 = i1; + rem_i2 = i2; + + let s = &mut string; + s.remove(rem_i2); + s.remove(rem_i1); + + continue; + } + None => { + break; + } + }; + } + + string.into_iter().collect() +} + +fn react_polymer_without_char(line: &String, ch: &char) -> String { + let line_ref: &str = line.as_ref(); + let a = *ch; + let b_str = a.to_uppercase().to_string(); + let b: &str = b_str.as_ref(); + let replaced_line = line_ref.replace(*ch, "").replace(a, "").replace(b, ""); + let res = react_polymer(&replaced_line); + res +} + +fn main() { + let args: Vec = env::args().collect(); + if args.len() != 2 { + println!("Wrong number of arguments. Provide just a file name."); + process::exit(1); + } + let filename = &args[1]; + println!("Using file {} as input.", filename); + let f = match File::open(filename) { + Ok(file) => file, + Err(e) => { + println!("Failed to open file {}. {:?}", filename, e); + process::exit(1); + } + }; + let file = BufReader::new(&f); + let mut lines: Vec = file.lines() + .map(|line| line.expect("Could not parse line.")) + .collect(); + &lines.sort(); + assert_eq!(lines.len(), 1); + let line = &lines[0]; + + // exercise 1 + println!("Solving 1..."); + let result = react_polymer(&line); + + // println!("1. Result: {}", result); + println!("1. Length: {}", result.len()); + + // exercise 2 + println!("Solving 2..."); + let mut best = line.len(); + for ch in &ASCII_LOWER { + let result = react_polymer_without_char(&line, ch); + let len = result.len(); + println!("Debug: ch: {}, len: {}", &ch, &len); + if len < best { + best = len; + println!("Debug: new best: {}", &len); + } + } + println!("2. Length: {}", best); +} \ No newline at end of file -- cgit v1.3