From c1bfd5fd5d052a5a7664ca9accf3a2d14d0a49f4 Mon Sep 17 00:00:00 2001 From: inga-lovinde <52715130+inga-lovinde@users.noreply.github.com> Date: Tue, 8 Dec 2020 21:44:45 +0100 Subject: [PATCH] first two days --- .gitignore | 7 +++-- day01-hard/Cargo.toml | 9 +++++++ day01-hard/src/main.rs | 34 +++++++++++++++++++++++ day01/Cargo.toml | 9 +++++++ day01/src/main.rs | 20 ++++++++++++++ day02/Cargo.toml | 11 ++++++++ day02/src/main.rs | 61 ++++++++++++++++++++++++++++++++++++++++++ 7 files changed, 149 insertions(+), 2 deletions(-) create mode 100644 day01-hard/Cargo.toml create mode 100644 day01-hard/src/main.rs create mode 100644 day01/Cargo.toml create mode 100644 day01/src/main.rs create mode 100644 day02/Cargo.toml create mode 100644 day02/src/main.rs diff --git a/.gitignore b/.gitignore index 088ba6b..53c8c00 100644 --- a/.gitignore +++ b/.gitignore @@ -1,10 +1,13 @@ # Generated by Cargo # will have compiled files and executables -/target/ +*/target/ # Remove Cargo.lock from gitignore if creating an executable, leave it for libraries # More information here https://doc.rust-lang.org/cargo/guide/cargo-toml-vs-cargo-lock.html -Cargo.lock +*/Cargo.lock # These are backup files generated by rustfmt **/*.rs.bk + +*.in +*.out diff --git a/day01-hard/Cargo.toml b/day01-hard/Cargo.toml new file mode 100644 index 0000000..92caec5 --- /dev/null +++ b/day01-hard/Cargo.toml @@ -0,0 +1,9 @@ +[package] +name = "day01-hard" +version = "0.1.0" +authors = ["inga-lovinde <52715130+inga-lovinde@users.noreply.github.com>"] +edition = "2018" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] diff --git a/day01-hard/src/main.rs b/day01-hard/src/main.rs new file mode 100644 index 0000000..865745a --- /dev/null +++ b/day01-hard/src/main.rs @@ -0,0 +1,34 @@ +use std::io::{self, BufRead}; + +// non-negative numbers are presorted, largest first +fn check(numbers: &[u32], remaining_count: u32, remaining_sum: u32, current_product: u64) -> () { + if remaining_count == 0 { + if remaining_sum == 0 { + println!("{}", current_product); + } + + return; + } + + for (i, &number) in numbers.iter().enumerate() { + if number * remaining_count < remaining_sum { + return; + } + + if number <= remaining_sum { + check(&numbers[i..], remaining_count - 1, remaining_sum - number, current_product * (number as u64)); + } + } +} + +fn main() { + let stdin = io::stdin(); + let mut source_numbers: Vec<_> = stdin.lock().lines().into_iter() + .map(|line| line.unwrap().parse::().unwrap()) + .collect(); + + source_numbers.sort(); + source_numbers.reverse(); + + check(&source_numbers, 3, 2020, 1); +} diff --git a/day01/Cargo.toml b/day01/Cargo.toml new file mode 100644 index 0000000..db4e24d --- /dev/null +++ b/day01/Cargo.toml @@ -0,0 +1,9 @@ +[package] +name = "day01" +version = "0.1.0" +authors = ["inga-lovinde <52715130+inga-lovinde@users.noreply.github.com>"] +edition = "2018" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] diff --git a/day01/src/main.rs b/day01/src/main.rs new file mode 100644 index 0000000..8bdec29 --- /dev/null +++ b/day01/src/main.rs @@ -0,0 +1,20 @@ +use std::collections::HashSet; +use std::io::{self, BufRead}; + +// Could be solved in O(n) +// (sort two copies of the list and walk it from the opposite ends to find a match) +// But O(n*log(n)) solution is much simpler. +fn main() { + let stdin = io::stdin(); + let source_numbers: Vec<_> = stdin.lock().lines().into_iter() + .map(|line| line.unwrap().parse::().unwrap()) + .collect(); + + let first_set: HashSet<_> = source_numbers.iter().map(|&number| number).collect(); + let second_set: HashSet<_> = source_numbers.iter().map(|&number| 2020-number).collect(); + + let result = first_set.intersection(&second_set); + for value in result { + println!("{}", value * (2020-value)); + } +} diff --git a/day02/Cargo.toml b/day02/Cargo.toml new file mode 100644 index 0000000..34cc9ce --- /dev/null +++ b/day02/Cargo.toml @@ -0,0 +1,11 @@ +[package] +name = "day02" +version = "0.1.0" +authors = ["inga-lovinde <52715130+inga-lovinde@users.noreply.github.com>"] +edition = "2018" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +lazy_static = "1.4.0" +regex = "1" diff --git a/day02/src/main.rs b/day02/src/main.rs new file mode 100644 index 0000000..672f49c --- /dev/null +++ b/day02/src/main.rs @@ -0,0 +1,61 @@ +use std::io::{self, BufRead}; +use std::error::Error; +use std::str::FromStr; + +#[macro_use] extern crate lazy_static; +use regex::Regex; + +struct LineInfo { + first_number: usize, + second_number: usize, + ch: char, + password: String, +} + +impl LineInfo { + fn is_valid_easy(&self) -> bool { + let count = self.password.chars().filter(|&password_char| password_char == self.ch).count(); + return self.first_number <= count && count <= self.second_number; + } + + fn is_valid_hard(&self) -> bool { + let chars: Vec<_> = self.password.chars().collect(); + return (chars[self.first_number-1] == self.ch) ^ (chars[self.second_number-1] == self.ch); + } +} + +impl FromStr for LineInfo { + type Err = Box; + + fn from_str(s: &str) -> Result { + lazy_static! { + static ref LINE_RE: Regex = Regex::new(r"^(\d+)-(\d+)\s+([\S]):\s(.*)$").unwrap(); + } + + match LINE_RE.captures(s) { + Some(captures) => { + Ok(LineInfo { + first_number: captures[1].parse()?, + second_number: captures[2].parse()?, + ch: captures[3].chars().next().unwrap(), + password: captures[4].to_owned(), + }) + }, + _ => Err(Box::from("wrong string format")) + } + } +} + +fn main() { + let stdin = io::stdin(); + let lines: Vec<_> = stdin.lock().lines().into_iter() + .map(|line| line.unwrap().parse::().unwrap()) + .collect(); + + println!("{}", lines.iter().filter(|line_info| line_info.is_valid_easy()).count()); + println!("{}", lines.iter().filter(|line_info| line_info.is_valid_hard()).count()); + + for line_info in lines { + println!("easy {}, hard {}: {}-{} {}: {}", line_info.is_valid_easy(), line_info.is_valid_hard(), line_info.first_number, line_info.second_number, line_info.ch, line_info.password); + } +}