Compare commits
4 Commits
a08c047178
...
04eceded4f
Author | SHA1 | Date | |
---|---|---|---|
04eceded4f | |||
e1d2cb5f72 | |||
5fa40357cd | |||
756f0fa9a0 |
16
10/README.md
Normal file
16
10/README.md
Normal file
@ -0,0 +1,16 @@
|
||||
# [Day 10](https://adventofcode.com/2023/day/10)
|
||||
:gift::gift::gift::gift::gift::gift::gift::gift::gift::gift:
|
||||
|
||||
Today's language: **Rust**
|
||||
|
||||
Lines of code: **136**
|
||||
|
||||
Execution time: **0,003 s**
|
||||
|
||||
I used lots of simple bitwise operations because I might implement this solution later on my DIY 8-bit computer.
|
||||
|
||||
```shell
|
||||
rustc day10.rs
|
||||
./day10RUN
|
||||
```
|
||||
<!-- lots of bitwise operations -->
|
@ -33,8 +33,6 @@ impl std::fmt::Display for Pos {
|
||||
}
|
||||
|
||||
fn follow(tiles: &mut Vec<Vec<u8>>, start: &Pos, mut direction: u8) -> Option<usize> {
|
||||
let xlen: usize = tiles[0].len(); // assume all are same size
|
||||
let ylen: usize = tiles.len();
|
||||
let mut steps: usize = 0;
|
||||
let mut current = *start;
|
||||
// mark the start tile as loop tile and with its directions
|
||||
@ -124,12 +122,10 @@ fn main() {
|
||||
}).collect());
|
||||
}
|
||||
let mut distance: usize = 0;
|
||||
let mut num_tiles: usize = 0;
|
||||
for direction in [N, S, E, W] {
|
||||
println!("Starting at ({},{})", start_pos.x, start_pos.y);
|
||||
if let Some(steps) = follow(&mut tiles, &start_pos, direction) {
|
||||
assert!(steps % 2 == 0, "steps={} not even", steps);
|
||||
num_tiles = steps;
|
||||
distance = steps / 2;
|
||||
break;
|
||||
}
|
||||
|
13
11/README.md
Normal file
13
11/README.md
Normal file
@ -0,0 +1,13 @@
|
||||
# [Day 11](https://adventofcode.com/2023/day/11)
|
||||
:gift::gift::gift::gift::gift::gift::gift::gift::gift::gift::gift:
|
||||
|
||||
Today's language: **Rust**
|
||||
|
||||
Lines of code: **66**
|
||||
|
||||
Execution time: **0,005 s**
|
||||
|
||||
```shell
|
||||
rustc day11.rs
|
||||
./day11RUN
|
||||
```
|
22
13/README.md
Normal file
22
13/README.md
Normal file
@ -0,0 +1,22 @@
|
||||
# [Day 13](https://adventofcode.com/2023/day/13)
|
||||
:gift::gift::gift::gift::gift::gift::gift::gift::gift::gift::gift::gift::gift:
|
||||
|
||||
Today's language: **Rust**
|
||||
|
||||
Lines of code: **84**
|
||||
|
||||
Execution time: **0,002 s**
|
||||
|
||||
Once again, binary encoding is used to transform every line and every column of each pattern into one unsigned int.
|
||||
The columns and lines are stored in one vector each. This means the same function can be used to find the reflection axis for both.
|
||||
|
||||
For task 2, we don't check whether two lines are equal, but whether they differ by 0 or 1 bit.
|
||||
|
||||
This approach is super fast since it has 0 heap allocations in loops and comparing two ints is way faster than comparing two strings.
|
||||
|
||||
```shell
|
||||
rustc day13.rs
|
||||
./day13RUN
|
||||
```
|
||||
|
||||
<!-- binary encoding ftw -->
|
94
13/day13.rs
Normal file
94
13/day13.rs
Normal file
@ -0,0 +1,94 @@
|
||||
use std::io::{self, BufRead};
|
||||
|
||||
|
||||
fn get_diff_bits_count(a: u32, b: u32) -> usize { // return 0 if equal, 1 if 1 bit is different, else 2
|
||||
let diff = a ^ b;
|
||||
if diff == 0 { return 0 }
|
||||
if (diff & diff.overflowing_sub(1).0) == 0 { return 1 }
|
||||
return 2;
|
||||
}
|
||||
|
||||
fn find_reflection_axis(pattern: &Vec<u32>, has_smack: bool) -> Option<usize> {
|
||||
for i in 1..pattern.len() {
|
||||
let mut found_smack = false;
|
||||
let diff = get_diff_bits_count(pattern[i-1], pattern[i]);
|
||||
if has_smack && diff == 1 {
|
||||
found_smack = true;
|
||||
}
|
||||
if diff == 0 || found_smack { // find two identical neighbors (or differing by 1 for task 2
|
||||
let mut matching = true;
|
||||
for j in 1..i.min(pattern.len() - i) { // check top and bottom if equal (or diff by 1 bit if has_smack)
|
||||
let diff = get_diff_bits_count(pattern[i-1-j], pattern[i+j]);
|
||||
if diff == 0 { continue; }
|
||||
if has_smack && diff == 1 && !found_smack { // allow only one smack
|
||||
found_smack = true;
|
||||
continue;
|
||||
}
|
||||
matching = false;
|
||||
break;
|
||||
}
|
||||
if matching && (!has_smack || (has_smack && found_smack)) { // require smack for task 2
|
||||
return Some(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
return None;
|
||||
}
|
||||
|
||||
fn do_task(horizontal: &Vec<u32>, vertical: &Vec<u32>, has_smack: bool) -> usize {
|
||||
let mut mirror_sum: usize = 0;
|
||||
if let Some(x) = find_reflection_axis(&horizontal, has_smack) {
|
||||
mirror_sum += x * 100;
|
||||
}
|
||||
if let Some(x) = find_reflection_axis(&vertical, has_smack) {
|
||||
mirror_sum += x;
|
||||
}
|
||||
return mirror_sum;
|
||||
}
|
||||
|
||||
|
||||
|
||||
fn main() {
|
||||
// let input = "example.txt";
|
||||
let input = "input.txt";
|
||||
let lines = read_lines(&input);
|
||||
let mut horizontal: Vec<u32> = Vec::new();
|
||||
let mut vertical: Vec<u32> = Vec::new();
|
||||
horizontal.reserve(20);
|
||||
vertical.reserve(20);
|
||||
let mut mirror_sum1: usize = 0;
|
||||
let mut mirror_sum2: usize = 0;
|
||||
let convert = |c| -> u32 { if c == '#' { 1 } else { 0 } };
|
||||
for line in lines.map(|r| r.ok().unwrap()) {
|
||||
if line.len() == 0 {
|
||||
if horizontal.len() != 0 { // skip first time
|
||||
mirror_sum1 += do_task(&horizontal, &vertical, false);
|
||||
mirror_sum2 += do_task(&horizontal, &vertical, true);
|
||||
}
|
||||
horizontal.clear();
|
||||
vertical.clear();
|
||||
continue;
|
||||
}
|
||||
if horizontal.len() == 0 { // 0 for each column
|
||||
(0..line.len()).for_each(|_| vertical.push(0));
|
||||
}
|
||||
horizontal.push(0);
|
||||
for (i, n) in line.chars().map(|c| convert(c)).enumerate() {
|
||||
*horizontal.last_mut().unwrap() |= (n << i);
|
||||
vertical[i] |= (n << (horizontal.len()-1));
|
||||
}
|
||||
}
|
||||
mirror_sum1 += do_task(&horizontal, &vertical, false);
|
||||
mirror_sum2 += do_task(&horizontal, &vertical, true);
|
||||
println!("Sum: (1): {}", mirror_sum1);
|
||||
println!("Sum: (2): {}", mirror_sum2);
|
||||
}
|
||||
|
||||
fn read_lines<P>(filename: P) -> io::Lines<io::BufReader<std::fs::File>>
|
||||
where P: AsRef<std::path::Path>, {
|
||||
return match std::fs::File::open(filename) {
|
||||
Err(why) => panic!("Could not open file. {}", why),
|
||||
Ok(file) => std::io::BufReader::new(file).lines()
|
||||
};
|
||||
}
|
||||
|
@ -13,5 +13,8 @@ This is a repository for my solutions for the [advent of code 2023](https://adve
|
||||
| [07](07) | Rust | 210 | 0,007 s | not pretty, but pretty fast |
|
||||
| [08](08) | Rust | 101 | 0,039 s | |
|
||||
| [09](09) | Rust | 88 | 0,003 s | implemented triangle datatype |
|
||||
| [10](10) | Rust | 136 | 0,003 s | lots of bitwise operations |
|
||||
| [11](11) | Rust | 66 | 0,005 s | |
|
||||
| [13](13) | Rust | 84 | 0,002 s | binary encoding ftw |
|
||||
|
||||
Lines of code are without blank lines and comments
|
||||
|
@ -3,6 +3,8 @@
|
||||
|
||||
Today's language: **LANG**
|
||||
|
||||
Lines of code: **LOC**
|
||||
|
||||
Execution time: **EXECTIME**
|
||||
|
||||
```shell
|
||||
|
@ -12,29 +12,47 @@ FMT_WARN='\e[33m%s\e[0m\n'
|
||||
echo Making Readme of day $day in $readme
|
||||
|
||||
function find_lang {
|
||||
# 1: fileext, 2: lang, 3: howto
|
||||
sourcefile=$(ls $day_dir/*.$1 2> /dev/null)
|
||||
# args: 1: fileext, 2: lang, 3: howto
|
||||
sources=($(IFS=$'\n' ls $day_dir/*.$1 2> /dev/null))
|
||||
[[ $? != 0 ]] && return
|
||||
if [[ ${#sources[@]} -gt 1 ]]; then
|
||||
printf "$FMT_WARN" "Found multiple sources for language $2 (using first as main): ${sources[@]}"
|
||||
fi
|
||||
if [[ ${#sources[@]} -gt 1 ]]; then
|
||||
printf "$FMT_WARN" "Found multiple sources for language $2 (using first as main): ${sources[@]}"
|
||||
fi
|
||||
mainsource=${sources[0]}
|
||||
if [[ -z $lang ]]; then
|
||||
lang=$2
|
||||
sourcefilebase=$(basename $sourcefile)
|
||||
printf "$FMT_VAR" "Determined Langugae" "$2 ($sourcefilebase)"
|
||||
sed -i "s/LANG/$2/" $readme
|
||||
howto=$(echo "$3" | sed "s|SOURCE|$sourcefilebase|")
|
||||
sed -i "s(HOWTORUN($howto(" $readme
|
||||
loc=$(sed -r '/^\s*(#|\/\/|\/\*|;)/d;/^\s*$/d' $sourcefile | wc -l)
|
||||
sed -i "s(LOC($loc(" $readme
|
||||
else
|
||||
lang=$lang,$2
|
||||
fi
|
||||
mainsource_base=$(basename $mainsource)
|
||||
printf "$FMT_VAR" "Determined Language" "$2 ($mainsource_base)"
|
||||
if [[ -n $3 ]]; then
|
||||
howto=$(echo "$3" | sed "s|SOURCE|$mainsource_base|")
|
||||
else
|
||||
printf "$FMT_WARN" "No HOWTO provided for language $2"
|
||||
fi
|
||||
for file in ${sources[@]}; do
|
||||
loc=$(( $loc + $(sed -r '/^\s*(#|\/\/|\/\*|;)/d;/^\s*$/d' "$file" | wc -l) ))
|
||||
done
|
||||
}
|
||||
|
||||
function get_time {
|
||||
cd $day_dir
|
||||
exe=$(find . -type f -executable)
|
||||
if [[ -z $exe ]]; then
|
||||
printf "$FMT_ERR" "Found no executable for day $day"
|
||||
cd ..
|
||||
return 2
|
||||
fi
|
||||
exe=$(basename $exe)
|
||||
if [[ $(echo $exe | wc -w) != 1 ]]; then
|
||||
printf "$FMT_ERR" "Found multiple or no executables for day $day: '$exe'"
|
||||
printf "$FMT_ERR" "Found multiple executables for day $day: '$exe'"
|
||||
cd ..
|
||||
return 1
|
||||
time=Error
|
||||
else
|
||||
fi
|
||||
time=$({ time ./$exe; } 2>&1)
|
||||
if [[ $? != 0 ]]; then
|
||||
printf "$FMT_ERR" "Execution error in './$exe' in '$(pwd)'. Output:"
|
||||
@ -55,39 +73,62 @@ function get_time {
|
||||
else
|
||||
time="$sec,$msec s"
|
||||
fi
|
||||
cd ..
|
||||
# elif [[ $sec != 0 ]]; then
|
||||
# time="$sec,$msec s"
|
||||
# else
|
||||
# time="$((msec+0)) ms"
|
||||
# fi
|
||||
fi
|
||||
cd ..
|
||||
}
|
||||
|
||||
|
||||
|
||||
gifts=""
|
||||
for i in $(seq $day); do gifts+=":gift:"; done
|
||||
sed "s/DAY/$day/g" README.md.temp | sed "s/:gift:/$gifts/" > $day_dir/README.md
|
||||
sed "s/DAY/$day/g" README.md.temp | sed "s/:gift:/$gifts/" > "$readme"
|
||||
get_time
|
||||
if [[ $? == 0 ]]; then
|
||||
cd ..
|
||||
printf "$FMT_VAR" "exectime" "$time"
|
||||
sed -i "s/EXECTIME/$time/" $readme
|
||||
sed -i "s/EXECTIME/$time/" "$readme"
|
||||
else
|
||||
cd ..
|
||||
printf "$FMT_WARN" "No execution time determined"
|
||||
sed -i '/.*EXECTIME.*/d' $readme
|
||||
sed -i '/.*EXECTIME.*/d' "$readme"
|
||||
fi
|
||||
|
||||
if [[ -z $1 ]]; then
|
||||
printf "$FMT_WARN" "No comment provided"
|
||||
sed -i "/<!-- COMMENT -->/d" $readme
|
||||
sed -i '/<!-- COMMENT -->/d' "$readme" || echo "ERROR comment"
|
||||
else
|
||||
printf "$FMT_VAR" "Comment" "'$1'"
|
||||
sed -i "s|COMMENT|$1|" $readme
|
||||
sed -i "s|COMMENT|$1|" "$readme" || echo "ERROR comment2"
|
||||
fi
|
||||
|
||||
dayexec="day${day_dir}"
|
||||
loc=0
|
||||
find_lang py Python "python3 SOURCE"
|
||||
find_lang rs Rust "rustc SOURCE\n./day${day_dir}"
|
||||
find_lang cpp C++ "g++ SOURCE -o day${day_dir}\n ./day${day_dir}"
|
||||
find_lang rs Rust "rustc SOURCE\n./$dayexec"
|
||||
find_lang cpp C++ "g++ SOURCE -o ${dayexec}\n./${dayexec}"
|
||||
find_lang c C "gcc SOURCE -o ${dayexec}\n./${dayexec}"
|
||||
find_lang java Java "javac Main.java\njava Main"
|
||||
find_lang s Assembly ""
|
||||
find_lang s65 Assembly "javac Main.java\njava Main"
|
||||
find_lang awk Awk "awk -f SOURCE input.txt"
|
||||
find_lang sh Bash "./SOURCE"
|
||||
find_lang php PhP "php -S localhost:8000 -t .\nfirefox http://localhost:8000"
|
||||
find_lang js Javascript ""
|
||||
|
||||
if [[ -z $lang ]]; then
|
||||
printf "$FMT_WARN" "No languages found"
|
||||
else
|
||||
sed -i "s/LANG/$lang/" $readme
|
||||
fi
|
||||
|
||||
if [[ -n $howto ]]; then
|
||||
sed -i "s|HOWTO|$howto|" $readme
|
||||
fi
|
||||
|
||||
if [[ $loc == 0 ]]; then
|
||||
printf "$FMT_WARN" "No lines of code found"
|
||||
else
|
||||
sed -i "s(LOC($loc(" $readme
|
||||
fi
|
||||
|
@ -2,8 +2,16 @@
|
||||
|
||||
table="| Day | Language | Lines of code | Execuction time | Comment |\n"
|
||||
table+="|:---:|:---:| ---:| ---: |--- |\n"
|
||||
for day in $(seq -f "%02g" 1 25); do
|
||||
[[ ! -d "$day" ]] && continue
|
||||
maxday=$(ls -d */ | sed -r 's|0*(.*)/|\1|g' | tail -1)
|
||||
for day in $(seq -f "%02g" 1 $maxday); do
|
||||
if [[ ! -d "$day" ]]; then
|
||||
echo "Missing directory for day $day"
|
||||
continue
|
||||
fi
|
||||
if [[ ! -f "$day/README.md" ]]; then
|
||||
echo "Missing README for day $day"
|
||||
continue
|
||||
fi
|
||||
# echo $day
|
||||
lang=$(grep -E "Today's language:" $day/README.md | sed -r 's/.*\*\*(.+)\*\*.*/\1/')
|
||||
exectime=$(grep -E "Execution time:" $day/README.md | sed -r 's/.*\*\*(.+)\*\*.*/\1/')
|
||||
|
Loading…
Reference in New Issue
Block a user