diff options
Diffstat (limited to '2021')
| -rw-r--r-- | 2021/Cargo.toml | 11 | ||||
| -rw-r--r-- | 2021/asm/day01.asm | 65 | ||||
| -rw-r--r-- | 2021/build.rs | 29 | ||||
| -rwxr-xr-x | 2021/prepare | 7 | ||||
| -rw-r--r-- | 2021/src/day01.rs | 39 | ||||
| -rw-r--r-- | 2021/src/day02.rs | 67 | ||||
| -rw-r--r-- | 2021/src/main.rs | 22 |
7 files changed, 240 insertions, 0 deletions
diff --git a/2021/Cargo.toml b/2021/Cargo.toml new file mode 100644 index 0000000..136bfa6 --- /dev/null +++ b/2021/Cargo.toml @@ -0,0 +1,11 @@ +[package] +name = "aoc2021" +version = "0.1.0" +edition = "2018" + +[dependencies] + +[profile.release] +lto = true +panic = "abort" +codegen-units = 1 diff --git a/2021/asm/day01.asm b/2021/asm/day01.asm new file mode 100644 index 0000000..b4f73e7 --- /dev/null +++ b/2021/asm/day01.asm @@ -0,0 +1,65 @@ +%include "unistd.asm" +%include "utils.asm" + +stdout equ 1 + +global _start + +section .text +_start: + mov rcx, [rsp] ; Get number of arguments + mov rdi, [rsp + rcx * 8] ; Get last argument + + mov rax, SYS_access ; Check if file exists and is readable + mov esi, R_OK + syscall + test rax, rax + jnz .exit_err + + mov rax, SYS_open + xor esi, esi + xor edx, edx + syscall + + mov r8d, eax ; Move fd into r8 + mov rax, SYS_mmap + xor edi, edi ; Let the kernel choose the address + mov rsi, 12288 + mov rdx, PROT_READ + mov r10d, MAP_PRIVATE + xor r9d, r9d + syscall + + cmp rax, -1 ; Exit on error + je .exit_err + + xor r13d, r13d + mov r12d, ~0 + mov rdi, rax +.loop: + call atoi + cmp eax, r12d + jna .na + inc r13d +.na: + mov r12d, eax + + cmp byte [rdi], 0 + je .exit + inc rdi + cmp byte [rdi], 0 + jne .loop + +.exit: + mov edi, stdout + mov esi, r13d + call write_ulong + + mov rax, SYS_exit + xor edi, edi + syscall + +.exit_err: + mov rax, SYS_exit + mov edi, 1 + syscall diff --git a/2021/build.rs b/2021/build.rs new file mode 100644 index 0000000..adbcf87 --- /dev/null +++ b/2021/build.rs @@ -0,0 +1,29 @@ +use std::env; +use std::error::Error; + +fn main() -> Result<(), Box<dyn Error>> { + println!("cargo:rerun-if-env-changed=AOCDAY"); + println!("cargo:rerun-if-env-changed=AOCPART"); + + if let Ok(version) = env::var("AOCDAY") { + let version = version.parse::<u32>()?; + match version { + 1..=2 => println!("cargo:rustc-cfg=day{:02}", version), + _ => panic!("Not a valid day") + }; + } else { + panic!("No date specified"); + } + + if let Ok(version) = env::var("AOCPART") { + let version = version.parse::<u32>()?; + match version { + 1..=2 => println!("cargo:rustc-cfg=part{}", version), + _ => panic!("Not a valid part") + }; + } else { + panic!("No part specified"); + } + + Ok(()) +} diff --git a/2021/prepare b/2021/prepare new file mode 100755 index 0000000..decb322 --- /dev/null +++ b/2021/prepare @@ -0,0 +1,7 @@ +#!/bin/sh + +set -ef + +AOCDAY="$1" AOCPART="$2" RUSTFLAGS="-C target-cpu=native" cargo build --release +cp "$(pwd)/target/release/aoc2021" "$(pwd)/run" +strip run diff --git a/2021/src/day01.rs b/2021/src/day01.rs new file mode 100644 index 0000000..7b1e6a9 --- /dev/null +++ b/2021/src/day01.rs @@ -0,0 +1,39 @@ +use std::error::Error; +use std::fs; +use std::path::Path; + +fn get_input(path: &Path) -> Result<Vec<u16>, Box<dyn Error>> { + let data = fs::read_to_string(path)?; + Ok(data.lines().filter_map(|x| x.parse::<u16>().ok()).collect()) +} + +#[cfg(part1)] +pub fn solve(path: &Path) -> Result<(), Box<dyn Error>> { + let values = get_input(path)?; + let mut last = u16::MAX; + let mut larger = 0; + for v in values { + if v > last { + larger += 1; + } + + last = v; + } + + println!("{}", larger); + Ok(()) +} + +#[cfg(part2)] +pub fn solve(path: &Path) -> Result<(), Box<dyn Error>> { + let values = get_input(path)?; + let mut increase = 0; + for i in 0..(values.len() - 3) { + if values[i] < values[i + 3] { + increase += 1; + } + } + + println!("{}", increase); + Ok(()) +} diff --git a/2021/src/day02.rs b/2021/src/day02.rs new file mode 100644 index 0000000..e64d2e9 --- /dev/null +++ b/2021/src/day02.rs @@ -0,0 +1,67 @@ +use std::str::FromStr; +use std::error::Error; +use std::fs; +use std::path::Path; + +#[derive(PartialEq, Debug)] +enum Command { + Forward(i32), + Down(i32), + Up(i32) +} + +#[derive(Debug)] +struct ParseCommandError; + +impl FromStr for Command { + type Err = ParseCommandError; + + fn from_str(s: &str) -> Result<Self, Self::Err> { + let i = s.find(' ').ok_or(ParseCommandError)?; + let num = s[i + 1..].parse::<i32>().map_err(|_| ParseCommandError)?; + match &s[..i] { + "forward" => Ok(Command::Forward(num)), + "down" => Ok(Command::Down(num)), + "up" => Ok(Command::Up(num)), + _ => Err(ParseCommandError) + } + } +} + +#[cfg(part1)] +pub fn solve(path: &Path) -> Result<(), Box<dyn Error>> { + let data = fs::read_to_string(path)?; + let mut hor = 0; + let mut depth = 0; + for command in data.lines().filter_map(|x| x.parse::<Command>().ok()) { + match command { + Command::Forward(v) => hor += v, + Command::Down(v) => depth += v, + Command::Up(v) => depth -= v + } + } + + println!("{}", hor * depth); + Ok(()) +} + +#[cfg(part2)] +pub fn solve(path: &Path) -> Result<(), Box<dyn Error>> { + let data = fs::read_to_string(path)?; + let mut aim = 0; + let mut hor = 0; + let mut depth = 0; + for command in data.lines().filter_map(|x| x.parse::<Command>().ok()) { + match command { + Command::Forward(v) => { + hor += v; + depth += aim * v; + }, + Command::Down(v) => aim += v, + Command::Up(v) => aim -= v + } + } + + println!("{}", hor * depth); + Ok(()) +} diff --git a/2021/src/main.rs b/2021/src/main.rs new file mode 100644 index 0000000..ae5f8f2 --- /dev/null +++ b/2021/src/main.rs @@ -0,0 +1,22 @@ +use std::env; +use std::error::Error; +use std::path::Path; + +#[cfg(day01)] +use day01::solve; + +#[cfg(day02)] +use day02::solve; + +#[cfg(day01)] +mod day01; + +#[cfg(day02)] +mod day02; + +fn main() -> Result<(), Box<dyn Error>> { + let args = env::args().last().unwrap(); + let path = Path::new(&args); + + solve(path) +} |
