From 12f4fbedb8f3c8971cf3728b089a6fd443ba490d Mon Sep 17 00:00:00 2001 From: Evie Litherland-Smith Date: Fri, 29 Dec 2023 08:11:41 +0000 Subject: [PATCH] Initial commit Move current solutions (2023) over and organise using cargo workspaces to be a bit cleaner to work with --- .envrc | 1 + .github/workflows/build_nix.yml | 13 ++++ .gitignore | 2 + .pre-commit-config.yaml | 15 ++++ Cargo.lock | 66 ++++++++++++++++ Cargo.toml | 3 + day1/Cargo.toml | 9 +++ day1/src/main.rs | 5 ++ day1/src/part1.rs | 52 +++++++++++++ day2/Cargo.toml | 8 ++ day2/src/main.rs | 3 + day2/src/part1.rs | 129 ++++++++++++++++++++++++++++++++ day2/src/part1_new.rs | 61 +++++++++++++++ day3/Cargo.toml | 8 ++ day3/src/main.rs | 3 + day3/src/part1.rs | 73 ++++++++++++++++++ day4/Cargo.toml | 8 ++ day4/src/main.rs | 3 + day4/src/part1.rs | 3 + default.nix | 7 ++ flake.lock | 93 +++++++++++++++++++++++ flake.nix | 22 ++++++ shell.nix | 7 ++ 23 files changed, 594 insertions(+) create mode 100644 .envrc create mode 100644 .github/workflows/build_nix.yml create mode 100644 .gitignore create mode 100644 .pre-commit-config.yaml create mode 100644 Cargo.lock create mode 100644 Cargo.toml create mode 100644 day1/Cargo.toml create mode 100644 day1/src/main.rs create mode 100644 day1/src/part1.rs create mode 100644 day2/Cargo.toml create mode 100644 day2/src/main.rs create mode 100644 day2/src/part1.rs create mode 100644 day2/src/part1_new.rs create mode 100644 day3/Cargo.toml create mode 100644 day3/src/main.rs create mode 100644 day3/src/part1.rs create mode 100644 day4/Cargo.toml create mode 100644 day4/src/main.rs create mode 100644 day4/src/part1.rs create mode 100644 default.nix create mode 100644 flake.lock create mode 100644 flake.nix create mode 100644 shell.nix diff --git a/.envrc b/.envrc new file mode 100644 index 0000000..3550a30 --- /dev/null +++ b/.envrc @@ -0,0 +1 @@ +use flake diff --git a/.github/workflows/build_nix.yml b/.github/workflows/build_nix.yml new file mode 100644 index 0000000..2f684e1 --- /dev/null +++ b/.github/workflows/build_nix.yml @@ -0,0 +1,13 @@ +name: "Build legacy Nix package on Ubuntu" + +on: + push: + +jobs: + build: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + - uses: cachix/install-nix-action@v12 + - name: Building package + run: nix-build . -A defaultPackage.x86_64-linux diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..d0160f2 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +/target +/.direnv/ diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml new file mode 100644 index 0000000..335396f --- /dev/null +++ b/.pre-commit-config.yaml @@ -0,0 +1,15 @@ +# See https://pre-commit.com for more information +# See https://pre-commit.com/hooks.html for more hooks +repos: +- repo: https://github.com/pre-commit/pre-commit-hooks + rev: v4.5.0 + hooks: + - id: trailing-whitespace + - id: end-of-file-fixer + - id: check-yaml + - id: check-added-large-files +- repo: https://github.com/doublify/pre-commit-rust + rev: v1.0 + hooks: + - id: fmt + - id: cargo-check diff --git a/Cargo.lock b/Cargo.lock new file mode 100644 index 0000000..e294d10 --- /dev/null +++ b/Cargo.lock @@ -0,0 +1,66 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "aho-corasick" +version = "1.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b2969dcb958b36655471fc61f7e416fa76033bdd4bfed0678d8fee1e2d07a1f0" +dependencies = [ + "memchr", +] + +[[package]] +name = "day1" +version = "0.1.0" +dependencies = [ + "regex", +] + +[[package]] +name = "day2" +version = "0.1.0" + +[[package]] +name = "day3" +version = "0.1.0" + +[[package]] +name = "day4" +version = "0.1.0" + +[[package]] +name = "memchr" +version = "2.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "523dc4f511e55ab87b694dc30d0f820d60906ef06413f93d4d7a1385599cc149" + +[[package]] +name = "regex" +version = "1.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "380b951a9c5e80ddfd6136919eef32310721aa4aacd4889a8d39124b026ab343" +dependencies = [ + "aho-corasick", + "memchr", + "regex-automata", + "regex-syntax", +] + +[[package]] +name = "regex-automata" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5f804c7828047e88b2d32e2d7fe5a105da8ee3264f01902f796c8e067dc2483f" +dependencies = [ + "aho-corasick", + "memchr", + "regex-syntax", +] + +[[package]] +name = "regex-syntax" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c08c74e62047bb2de4ff487b251e4a92e24f48745648451635cec7d591162d9f" diff --git a/Cargo.toml b/Cargo.toml new file mode 100644 index 0000000..a6c366c --- /dev/null +++ b/Cargo.toml @@ -0,0 +1,3 @@ +[workspace] +resolver = "2" +members = [ "day1", "day2", "day3", "day4" ] diff --git a/day1/Cargo.toml b/day1/Cargo.toml new file mode 100644 index 0000000..6f98620 --- /dev/null +++ b/day1/Cargo.toml @@ -0,0 +1,9 @@ +[package] +name = "day1" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +regex = "1.10.2" diff --git a/day1/src/main.rs b/day1/src/main.rs new file mode 100644 index 0000000..aeb53de --- /dev/null +++ b/day1/src/main.rs @@ -0,0 +1,5 @@ +mod part1; + +fn main() { + println!("Hello, world!"); +} diff --git a/day1/src/part1.rs b/day1/src/part1.rs new file mode 100644 index 0000000..23239f6 --- /dev/null +++ b/day1/src/part1.rs @@ -0,0 +1,52 @@ +use regex::Regex; +use std::{fs::read_to_string, path::Path}; + +fn parse(file: &str, parse_words: bool) -> i32 { + read_to_string(Path::new(file)) + .unwrap() + .lines() + .map(|m| calibration_values(num_from_line(m, parse_words))) + .sum() +} + +fn num_from_line(line: &str, parse_words: bool) -> Vec { + let rstring = if parse_words { + r"(\d|one|two|three|four|five|six|seven|eight|nine){1}" + } else { + r"(\d){1}" + }; + Regex::new(rstring) + .unwrap() + .find_iter(line) + .map(|m| -> i32 { + match m.as_str().parse::() { + Ok(val) => val, + Err(_) => match m.as_str().to_lowercase().as_ref() { + "one" => 1, + "two" => 2, + "three" => 3, + "four" => 4, + "five" => 5, + "six" => 6, + "seven" => 7, + "eight" => 8, + "nine" => 9, + _ => panic!("Shouldn't get here due to rstring {}", &rstring), + }, + } + }) + .collect() +} + +fn calibration_values(num_vec: Vec) -> i32 { + ([num_vec[0], num_vec[num_vec.len() - 1]]) + .iter() + .fold(String::new(), |a, b| a + &b.to_string()) + .parse::() + .unwrap() +} + +pub(crate) fn main() { + println!("{:?}", parse("inputs/2023/day1_1.txt", false)); + println!("{:?}", parse("inputs/2023/test1_2.txt", true)); +} diff --git a/day2/Cargo.toml b/day2/Cargo.toml new file mode 100644 index 0000000..8aa34bb --- /dev/null +++ b/day2/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "day2" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] diff --git a/day2/src/main.rs b/day2/src/main.rs new file mode 100644 index 0000000..e7a11a9 --- /dev/null +++ b/day2/src/main.rs @@ -0,0 +1,3 @@ +fn main() { + println!("Hello, world!"); +} diff --git a/day2/src/part1.rs b/day2/src/part1.rs new file mode 100644 index 0000000..bbbf130 --- /dev/null +++ b/day2/src/part1.rs @@ -0,0 +1,129 @@ +use rayon::prelude::*; +use regex::{Match, Regex}; +use std::fs; + +struct Games { + games: Vec, +} + +impl Games { + fn new(file: &str, bag: Contents) -> Self { + Self { + games: fs::read_to_string(file) + .unwrap() + .lines() + .map(|m| Game::new(m.to_owned(), bag.clone())) + .collect(), + } + } + fn valid_games(self) -> Vec { + self.games + .par_iter() + .filter(|m| m.valid()) + .map(|m| m.id) + .collect() + } + fn valid_sum(self) -> i32 { + self.valid_games().par_iter().sum() + } +} + +#[derive(Debug, Clone)] +struct Game { + bag: Contents, + id: i32, + draws: Vec, +} + +impl Game { + fn new(line: String, bag: Contents) -> Self { + Self { + bag: bag.clone(), + id: line + .split(':') + .next() + .unwrap() + .split(' ') + .last() + .expect("Must have game ID") + .parse::() + .expect("Game ID must be integer value"), + draws: Game::get_draws(line.split(':').last().unwrap()), + } + } + + fn get_draws(line: &str) -> Vec { + line.split(':') + .next() + .unwrap() + .split(';') + .map(|m| -> Contents { Contents::new(m) }) + .collect() + } + fn valid(&self) -> bool { + self.draws.par_iter().all(|m| self.bag.valid(m)) + } +} + +#[derive(Debug, Clone)] +struct Contents { + blue: i32, + green: i32, + red: i32, +} + +impl Contents { + fn new(line: &str) -> Self { + Self { + red: Self::get_red(line), + blue: Self::get_blue(line), + green: Self::get_green(line), + } + } + fn valid(self: &Contents, hand: &Contents) -> bool { + self.red.gt(&hand.red) & self.blue.gt(&hand.blue) & self.green.gt(&hand.green) + } + fn get_value(slice: &str) -> i32 { + Regex::new(r"(\d)+") + .unwrap() + .find(slice) + .unwrap() + .as_str() + .parse() + .unwrap() + } + fn get_slice<'a>(line: &'a str, rstring: &'a str) -> Option> { + Regex::new(rstring).unwrap().find(line) + } + fn get_red(line: &str) -> i32 { + let rstring = r"((\d)+ red)"; + match Self::get_slice(line, rstring) { + Some(slice) => Self::get_value(slice.as_str()), + None => 0, + } + } + fn get_blue(line: &str) -> i32 { + let rstring = r"((\d)+ blue)"; + match Self::get_slice(line, rstring) { + Some(slice) => Self::get_value(slice.as_str()), + None => 0, + } + } + fn get_green(line: &str) -> i32 { + let rstring = r"((\d)+ green)"; + match Self::get_slice(line, rstring) { + Some(slice) => Self::get_value(slice.as_str()), + None => 0, + } + } +} + +pub(crate) fn main() { + let bag = Contents { + red: 12, + green: 13, + blue: 14, + }; + let games = Games::new("inputs/2023/day2_1.txt", bag); + println!("{}", games.valid_sum()); +} diff --git a/day2/src/part1_new.rs b/day2/src/part1_new.rs new file mode 100644 index 0000000..856df35 --- /dev/null +++ b/day2/src/part1_new.rs @@ -0,0 +1,61 @@ +use std::fs; + +use regex::Regex; + +pub(crate) fn main() { + let input = String::from("inputs/2023/day2_1.txt"); + println!( + "{:?}", + Game::from(fs::read_to_string(input).unwrap().lines().next()) + ) +} + +#[derive(Debug)] +struct Game { + id: u32, + draws: Vec, +} + +impl TryFrom<&str> for Game { + type Error = String; + + fn try_from(value: &str) -> Result { + let re = Regex::new(r"^Game [\d]+: ([\d]+ (red|blue|green){1}(;)?)+$").unwrap(); + println!("{:?}", re.captures(value).unwrap()); + Ok(Self { + id: 1, + draws: vec![Draw { + red: 1, + green: 1, + blue: 1, + }], + }) + } +} + +#[derive(Debug)] +struct Draw { + red: i32, + green: i32, + blue: i32, +} + +impl TryFrom<&str> for Draw { + type Error = String; + + fn try_from(value: &str) -> Result { + todo!() + } +} + +impl Draw { + fn is_valid(&self, bag: &Bag) -> bool { + self.red < bag.red && self.green < bag.green && self.blue < bag.blue + } +} + +struct Bag { + red: i32, + green: i32, + blue: i32, +} diff --git a/day3/Cargo.toml b/day3/Cargo.toml new file mode 100644 index 0000000..898e70d --- /dev/null +++ b/day3/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "day3" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] diff --git a/day3/src/main.rs b/day3/src/main.rs new file mode 100644 index 0000000..e7a11a9 --- /dev/null +++ b/day3/src/main.rs @@ -0,0 +1,3 @@ +fn main() { + println!("Hello, world!"); +} diff --git a/day3/src/part1.rs b/day3/src/part1.rs new file mode 100644 index 0000000..b3870dc --- /dev/null +++ b/day3/src/part1.rs @@ -0,0 +1,73 @@ +use regex::{Match, Regex}; + +#[derive(Debug)] +enum Engine { + Number { + value: u32, + line: usize, + start: usize, + end: usize, + }, + Symbol { + value: char, + line: usize, + pos: usize, + }, +} + +fn get_numbers(input: String) -> Vec { + todo!() +} + +fn get_symbols(input: String) -> Vec { + todo!() +} + +pub(crate) fn main() { + for (i, line) in test_input().split('\n').enumerate() { + let numbers: Vec = Regex::new(r"\d+") + .unwrap() + .find_iter(line) + .filter_map(|m| match m.as_str().parse() { + Ok(value) => Some(Engine::Number { + value, + line: i, + start: m.start(), + end: m.end(), + }), + _ => None, + }) + .collect(); + let symbols: Vec = line + .chars() + .enumerate() + .filter_map(|(j, m)| { + if !m.is_ascii_digit() && m != '.' { + Some(Engine::Symbol { + value: m, + line: i, + pos: j, + }) + } else { + None + } + }) + .collect(); + println!("{:?}, {:?}", numbers, symbols) + } +} + +pub(crate) fn test_input() -> String { + "467..114.. +...*...... +..35..633. +......#... +617*...... +.....+.58. +..592..... +......755. +...$.*.... +.664.598.. +" + .to_string() +} diff --git a/day4/Cargo.toml b/day4/Cargo.toml new file mode 100644 index 0000000..8842130 --- /dev/null +++ b/day4/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "day4" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] diff --git a/day4/src/main.rs b/day4/src/main.rs new file mode 100644 index 0000000..e7a11a9 --- /dev/null +++ b/day4/src/main.rs @@ -0,0 +1,3 @@ +fn main() { + println!("Hello, world!"); +} diff --git a/day4/src/part1.rs b/day4/src/part1.rs new file mode 100644 index 0000000..37515c9 --- /dev/null +++ b/day4/src/part1.rs @@ -0,0 +1,3 @@ +pub(crate) fn main() { + todo!() +} diff --git a/default.nix b/default.nix new file mode 100644 index 0000000..39bacff --- /dev/null +++ b/default.nix @@ -0,0 +1,7 @@ +(import ( + fetchTarball { + url = "https://github.com/edolstra/flake-compat/archive/99f1c2157fba4bfe6211a321fd0ee43199025dbf.tar.gz"; + sha256 = "0x2jn3vrawwv9xp15674wjz9pixwjyj3j771izayl962zziivbx2"; } +) { + src = ./.; +}).defaultNix diff --git a/flake.lock b/flake.lock new file mode 100644 index 0000000..67e8bb2 --- /dev/null +++ b/flake.lock @@ -0,0 +1,93 @@ +{ + "nodes": { + "naersk": { + "inputs": { + "nixpkgs": "nixpkgs" + }, + "locked": { + "lastModified": 1698420672, + "narHash": "sha256-/TdeHMPRjjdJub7p7+w55vyABrsJlt5QkznPYy55vKA=", + "owner": "nix-community", + "repo": "naersk", + "rev": "aeb58d5e8faead8980a807c840232697982d47b9", + "type": "github" + }, + "original": { + "owner": "nix-community", + "ref": "master", + "repo": "naersk", + "type": "github" + } + }, + "nixpkgs": { + "locked": { + "lastModified": 1, + "narHash": "sha256-9VAt19t6yQa7pHZLDbil/QctAgVsA66DLnzdRGqDisg=", + "path": "/nix/store/0bdivsk6qss6xbsrimypdghjbgjci0gp-nn17kpb3mlp3kdhi4vm1m71w0m68f1gk-source", + "type": "path" + }, + "original": { + "id": "nixpkgs", + "type": "indirect" + } + }, + "nixpkgs_2": { + "locked": { + "lastModified": 1703499205, + "narHash": "sha256-lF9rK5mSUfIZJgZxC3ge40tp1gmyyOXZ+lRY3P8bfbg=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "e1fa12d4f6c6fe19ccb59cac54b5b3f25e160870", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "nixpkgs-unstable", + "repo": "nixpkgs", + "type": "github" + } + }, + "root": { + "inputs": { + "naersk": "naersk", + "nixpkgs": "nixpkgs_2", + "utils": "utils" + } + }, + "systems": { + "locked": { + "lastModified": 1681028828, + "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", + "owner": "nix-systems", + "repo": "default", + "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", + "type": "github" + }, + "original": { + "owner": "nix-systems", + "repo": "default", + "type": "github" + } + }, + "utils": { + "inputs": { + "systems": "systems" + }, + "locked": { + "lastModified": 1701680307, + "narHash": "sha256-kAuep2h5ajznlPMD9rnQyffWG8EM/C73lejGofXvdM8=", + "owner": "numtide", + "repo": "flake-utils", + "rev": "4022d587cbbfd70fe950c1e2083a02621806a725", + "type": "github" + }, + "original": { + "owner": "numtide", + "repo": "flake-utils", + "type": "github" + } + } + }, + "root": "root", + "version": 7 +} diff --git a/flake.nix b/flake.nix new file mode 100644 index 0000000..e80429d --- /dev/null +++ b/flake.nix @@ -0,0 +1,22 @@ +{ + inputs = { + naersk.url = "github:nix-community/naersk/master"; + nixpkgs.url = "github:NixOS/nixpkgs/nixpkgs-unstable"; + utils.url = "github:numtide/flake-utils"; + }; + + outputs = { self, nixpkgs, utils, naersk }: + utils.lib.eachDefaultSystem (system: + let + pkgs = import nixpkgs { inherit system; }; + naersk-lib = pkgs.callPackage naersk { }; + in { + defaultPackage = naersk-lib.buildPackage ./.; + devShell = with pkgs; + mkShell { + buildInputs = + [ cargo rustc rustfmt pre-commit rustPackages.clippy ]; + RUST_SRC_PATH = rustPlatform.rustLibSrc; + }; + }); +} diff --git a/shell.nix b/shell.nix new file mode 100644 index 0000000..77db547 --- /dev/null +++ b/shell.nix @@ -0,0 +1,7 @@ +(import ( + fetchTarball { + url = "https://github.com/edolstra/flake-compat/archive/99f1c2157fba4bfe6211a321fd0ee43199025dbf.tar.gz"; + sha256 = "0x2jn3vrawwv9xp15674wjz9pixwjyj3j771izayl962zziivbx2"; } +) { + src = ./.; +}).shellNix