Day 1 of AoC 2023

This commit is contained in:
Savanni D'Gerinel 2023-12-01 10:05:28 -05:00
parent e3bf22c10f
commit 634812126b
8 changed files with 1222 additions and 63 deletions

7
2023/Cargo.lock generated Normal file
View File

@ -0,0 +1,7 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
version = 3
[[package]]
name = "aoc-2023"
version = "0.1.0"

8
2023/Cargo.toml Normal file
View File

@ -0,0 +1,8 @@
[package]
name = "aoc-2023"
version = "0.1.0"
edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]

1000
2023/data/day1.txt Normal file

File diff suppressed because it is too large Load Diff

180
2023/src/day1.rs Normal file
View File

@ -0,0 +1,180 @@
use std::collections::HashMap;
const INPUT: &str = include_str!("../data/day1.txt");
pub fn day1a() -> String {
format!("{}", get_calibration(INPUT, calibration_line))
}
pub fn day1b() -> String {
format!("{}", get_calibration(INPUT, calibration_line_2))
}
pub(crate) fn get_calibration<F>(data: &str, parser: F) -> u32
where
F: Fn(&str) -> u32,
{
data.lines().map(parser).fold(0, |acc, val| acc + val)
}
pub(crate) fn calibration_line(data: &str) -> u32 {
let chars = data
.chars()
.filter(|c| c.is_digit(10))
.collect::<Vec<char>>();
let number_as_str = format!("{}{}", chars[0], chars[chars.len() - 1]);
number_as_str.parse::<u32>().unwrap()
}
pub(crate) fn calibration_line_2(data: &str) -> u32 {
let data = interpret_text(data);
calibration_line(&data)
}
const NAMES: [(&str, &str); 20] = [
("zero", "0"),
("one", "1"),
("two", "2"),
("three", "3"),
("four", "4"),
("five", "5"),
("six", "6"),
("seven", "7"),
("eight", "8"),
("nine", "9"),
("0", "0"),
("1", "1"),
("2", "2"),
("3", "3"),
("4", "4"),
("5", "5"),
("6", "6"),
("7", "7"),
("8", "8"),
("9", "9"),
];
fn interpret_text(data: &str) -> String {
let mut working = data.to_owned();
let mut digits = Vec::new();
while let Some((idx, digit)) = find_digit(&working) {
let _ = working.drain(..(idx + 1)).collect::<String>();
digits.push(digit);
}
/*
while let Some((idx, digit)) = find_digit(working.drain(..next_idx).collect()) {
next_idx = idx;
digits.push(digit);
}
*/
println!("interpretation {} -> {}", data, digits.join(""));
digits.join("")
}
fn find_digit(data: &str) -> Option<(usize, String)> {
let mut lowest_idx = 999;
let mut first_value = None;
for (name, value) in NAMES {
if let Some(idx) = data.find(name) {
if idx < lowest_idx {
lowest_idx = idx;
first_value = Some(value.to_owned());
}
}
}
first_value.map(|v| (lowest_idx, v))
}
/*
fn replace_first(data: String) -> (bool, String) {
let names_hash = HashMap::from(NAMES);
let mut lowest_idx = 999;
let mut first_name = None;
for (name, _) in NAMES {
if let Some(idx) = data.find(name) {
if idx < lowest_idx {
lowest_idx = idx;
first_name = Some(name);
}
}
}
if let Some(name) = first_name {
return (true, data.replace(name, names_hash[name]));
}
return (false, data);
}
*/
#[cfg(test)]
mod test {
use super::*;
const TEST_DATA1: &str = "1abc2
pqr3stu8vwx
a1b2c3d4e5f
treb7uchet";
const TEST_DATA2: &str = "two1nine
eightwothree
abcone2threexyz
xtwone3four
4nineeightseven2
zoneight234
7pqrstsixteen";
#[test]
fn test_1a() {
let test_cases = vec![
("1abc2", 12, "1abc2"),
("pqr3stu8vwx", 38, "pqr3stu8vwx"),
("a1b2c3d4e5f", 15, "a1b2c3d4e5f"),
("treb7uchet", 77, "treb7uchet"),
];
for (input, expected, message) in test_cases {
assert_eq!(calibration_line(input), expected, "{}", message);
}
assert_eq!(get_calibration(TEST_DATA1, calibration_line), 142);
}
#[test]
fn test_1b() {
let test_cases = vec![
("two1nine", 29, "two1nine"),
("eightwothree", 83, "eightwothree"),
("abcone2threexyz", 13, "abcone2threexyz"),
("xtwone3four", 24, "xtwone3four"),
("4nineeightseven2", 42, "4nineeightseven2"),
("zoneight234", 14, "zoneight234"),
("7pqrstsixteen", 76, "7pqrstsixteen,"),
];
for (input, expected, message) in test_cases {
assert_eq!(calibration_line_2(input), expected, "{}", message);
}
assert_eq!(get_calibration(TEST_DATA2, calibration_line_2), 281);
}
#[test]
fn test_interpret_text() {
let test_cases = vec![
("two1nine", "219", "two1nine"),
("eightwothree", "823", "eightwothree"),
("abcone2threexyz", "123", "abcone2threexyz"),
("xtwone3four", "2134", "xtwone3four"),
("4nineeightseven2", "49872", "4nineeightseven2"),
("zoneight234", "18234", "zoneight234"),
("7pqrstsixteen", "76", "7pqrstsixteen,"),
];
for (input, expected, message) in test_cases {
assert_eq!(interpret_text(input), expected, "{}", message);
}
}
}

13
2023/src/main.rs Normal file
View File

@ -0,0 +1,13 @@
mod day1;
fn main() {
let day = std::env::args().skip(1).next();
let result = match day.as_ref().map(|v| v.as_ref()) {
Some("1a") => day1::day1a(),
Some("1b") => day1::day1b(),
_ => panic!("unrecognized day"),
};
println!("[{}] {}", day.unwrap(), result);
}

View File

@ -1,70 +1,23 @@
{ {
"nodes": { "nodes": {
"flake-utils": {
"locked": {
"lastModified": 1659877975,
"narHash": "sha256-zllb8aq3YO3h8B/U0/J1WBgAL8EX5yWf5pMj3G0NAmc=",
"owner": "numtide",
"repo": "flake-utils",
"rev": "c0e246b9b83f637f4681389ecabcb2681b4f3af0",
"type": "github"
},
"original": {
"owner": "numtide",
"repo": "flake-utils",
"type": "github"
}
},
"nixpkgs": { "nixpkgs": {
"locked": { "locked": {
"lastModified": 1669764884, "lastModified": 1700794826,
"narHash": "sha256-1qWR/5+WtqxSedrFbUbM3zPMO7Ec2CGWaxtK4z4DdvY=", "narHash": "sha256-RyJTnTNKhO0yqRpDISk03I/4A67/dp96YRxc86YOPgU=",
"owner": "NixOS", "owner": "NixOS",
"repo": "nixpkgs", "repo": "nixpkgs",
"rev": "0244e143dc943bcf661fdaf581f01eb0f5000fcf", "rev": "5a09cb4b393d58f9ed0d9ca1555016a8543c2ac8",
"type": "github" "type": "github"
}, },
"original": { "original": {
"id": "nixpkgs", "id": "nixpkgs",
"ref": "nixos-22.05", "ref": "nixos-unstable",
"type": "indirect" "type": "indirect"
} }
}, },
"nixpkgs_2": {
"locked": {
"lastModified": 1665296151,
"narHash": "sha256-uOB0oxqxN9K7XGF1hcnY+PQnlQJ+3bP2vCn/+Ru/bbc=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "14ccaaedd95a488dd7ae142757884d8e125b3363",
"type": "github"
},
"original": {
"owner": "NixOS",
"ref": "nixpkgs-unstable",
"repo": "nixpkgs",
"type": "github"
}
},
"oxalica": {
"inputs": {
"flake-utils": "flake-utils",
"nixpkgs": "nixpkgs_2"
},
"locked": {
"narHash": "sha256-/ar+cbAKAxd2Ng9b7EhrIMz9CP353RbmLecvyOidyUM=",
"type": "tarball",
"url": "https://github.com/oxalica/rust-overlay/archive/master.tar.gz"
},
"original": {
"type": "tarball",
"url": "https://github.com/oxalica/rust-overlay/archive/master.tar.gz"
}
},
"root": { "root": {
"inputs": { "inputs": {
"nixpkgs": "nixpkgs", "nixpkgs": "nixpkgs"
"oxalica": "oxalica"
} }
} }
}, },

View File

@ -2,11 +2,10 @@
description = "Advent of Code"; description = "Advent of Code";
inputs = { inputs = {
nixpkgs.url = "nixpkgs/nixos-22.05"; nixpkgs.url = "nixpkgs/nixos-unstable";
oxalica.url = "https://github.com/oxalica/rust-overlay/archive/master.tar.gz";
}; };
outputs = { self, nixpkgs, oxalica }: outputs = { self, nixpkgs }:
let let
version = builtins.string 0 8 self.lastModifiedDate; version = builtins.string 0 8 self.lastModifiedDate;
supportedSystems = [ "x86_64-linux" ]; supportedSystems = [ "x86_64-linux" ];
@ -14,18 +13,14 @@
{ {
devShell."x86_64-linux" = devShell."x86_64-linux" =
let let
rust_overlay = import oxalica; pkgs = import nixpkgs { system = "x86_64-linux"; };
pkgs = import nixpkgs { system = "x86_64-linux"; overlays = [ rust_overlay ]; };
rust = pkgs.rust-bin.stable."1.65.0".default.override {
extensions = [ "rust-src" ];
};
in in
pkgs.mkShell { pkgs.mkShell {
name = "aoc-devshell"; name = "aoc-devshell";
buildInputs = [ buildInputs = [
pkgs.pkg-config # pkgs.pkg-config
pkgs.openssl # pkgs.openssl
rust pkgs.rustup
]; ];
}; };
}; };

3
rust-toolchain Normal file
View File

@ -0,0 +1,3 @@
[toolchain]
channel = "1.73.0"
targets = [ "wasm32-unknown-unknown" ]