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/.vscode/launch.json | 43 ++++++++++++++++++ day5/Cargo.lock | 4 ++ day5/Cargo.toml | 6 +++ day5/src/main.rs | 114 +++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 167 insertions(+) create mode 100644 day5/.vscode/launch.json create mode 100644 day5/Cargo.lock create mode 100644 day5/Cargo.toml create mode 100644 day5/src/main.rs diff --git a/day5/.vscode/launch.json b/day5/.vscode/launch.json new file mode 100644 index 0000000..ee5a08f --- /dev/null +++ b/day5/.vscode/launch.json @@ -0,0 +1,43 @@ +{ + // Use IntelliSense to learn about possible attributes. + // Hover to view descriptions of existing attributes. + // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 + "version": "0.2.0", + "configurations": [ + { + "type": "lldb", + "request": "launch", + "name": "Debug executable 'day5'", + "cargo": { + "args": [ + "build", + "--bin=day5", + "--package=day5" + ], + "filter": { + "kind": "bin" + } + }, + "args": ["input.txt"], + "cwd": "${workspaceFolder}" + }, + { + "type": "lldb", + "request": "launch", + "name": "Debug unit tests in executable 'day5'", + "cargo": { + "args": [ + "test", + "--no-run", + "--bin=day5", + "--package=day5" + ], + "filter": { + "kind": "bin" + } + }, + "args": [], + "cwd": "${workspaceFolder}" + } + ] +} \ No newline at end of file diff --git a/day5/Cargo.lock b/day5/Cargo.lock new file mode 100644 index 0000000..9b1783a --- /dev/null +++ b/day5/Cargo.lock @@ -0,0 +1,4 @@ +[[package]] +name = "day5" +version = "0.1.0" + diff --git a/day5/Cargo.toml b/day5/Cargo.toml new file mode 100644 index 0000000..122a7cb --- /dev/null +++ b/day5/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "day5" +version = "0.1.0" +authors = ["Jan Tuomi "] + +[dependencies] 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