first two days

main
Inga 🏳‍🌈 3 years ago
parent baf74f24dd
commit c1bfd5fd5d
  1. 7
      .gitignore
  2. 9
      day01-hard/Cargo.toml
  3. 34
      day01-hard/src/main.rs
  4. 9
      day01/Cargo.toml
  5. 20
      day01/src/main.rs
  6. 11
      day02/Cargo.toml
  7. 61
      day02/src/main.rs

7
.gitignore vendored

@ -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

@ -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]

@ -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::<u32>().unwrap())
.collect();
source_numbers.sort();
source_numbers.reverse();
check(&source_numbers, 3, 2020, 1);
}

@ -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]

@ -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::<u32>().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));
}
}

@ -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"

@ -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<dyn Error>;
fn from_str(s: &str) -> Result<Self, Self::Err> {
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::<LineInfo>().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);
}
}
Loading…
Cancel
Save