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> {
|
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 steps: usize = 0;
|
||||||
let mut current = *start;
|
let mut current = *start;
|
||||||
// mark the start tile as loop tile and with its directions
|
// mark the start tile as loop tile and with its directions
|
||||||
@ -124,12 +122,10 @@ fn main() {
|
|||||||
}).collect());
|
}).collect());
|
||||||
}
|
}
|
||||||
let mut distance: usize = 0;
|
let mut distance: usize = 0;
|
||||||
let mut num_tiles: usize = 0;
|
|
||||||
for direction in [N, S, E, W] {
|
for direction in [N, S, E, W] {
|
||||||
println!("Starting at ({},{})", start_pos.x, start_pos.y);
|
println!("Starting at ({},{})", start_pos.x, start_pos.y);
|
||||||
if let Some(steps) = follow(&mut tiles, &start_pos, direction) {
|
if let Some(steps) = follow(&mut tiles, &start_pos, direction) {
|
||||||
assert!(steps % 2 == 0, "steps={} not even", steps);
|
assert!(steps % 2 == 0, "steps={} not even", steps);
|
||||||
num_tiles = steps;
|
|
||||||
distance = steps / 2;
|
distance = steps / 2;
|
||||||
break;
|
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 |
|
| [07](07) | Rust | 210 | 0,007 s | not pretty, but pretty fast |
|
||||||
| [08](08) | Rust | 101 | 0,039 s | |
|
| [08](08) | Rust | 101 | 0,039 s | |
|
||||||
| [09](09) | Rust | 88 | 0,003 s | implemented triangle datatype |
|
| [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
|
Lines of code are without blank lines and comments
|
||||||
|
@ -3,6 +3,8 @@
|
|||||||
|
|
||||||
Today's language: **LANG**
|
Today's language: **LANG**
|
||||||
|
|
||||||
|
Lines of code: **LOC**
|
||||||
|
|
||||||
Execution time: **EXECTIME**
|
Execution time: **EXECTIME**
|
||||||
|
|
||||||
```shell
|
```shell
|
||||||
|
@ -12,82 +12,123 @@ FMT_WARN='\e[33m%s\e[0m\n'
|
|||||||
echo Making Readme of day $day in $readme
|
echo Making Readme of day $day in $readme
|
||||||
|
|
||||||
function find_lang {
|
function find_lang {
|
||||||
# 1: fileext, 2: lang, 3: howto
|
# args: 1: fileext, 2: lang, 3: howto
|
||||||
sourcefile=$(ls $day_dir/*.$1 2> /dev/null)
|
sources=($(IFS=$'\n' ls $day_dir/*.$1 2> /dev/null))
|
||||||
[[ $? != 0 ]] && return
|
[[ $? != 0 ]] && return
|
||||||
lang=$2
|
if [[ ${#sources[@]} -gt 1 ]]; then
|
||||||
sourcefilebase=$(basename $sourcefile)
|
printf "$FMT_WARN" "Found multiple sources for language $2 (using first as main): ${sources[@]}"
|
||||||
printf "$FMT_VAR" "Determined Langugae" "$2 ($sourcefilebase)"
|
fi
|
||||||
sed -i "s/LANG/$2/" $readme
|
if [[ ${#sources[@]} -gt 1 ]]; then
|
||||||
howto=$(echo "$3" | sed "s|SOURCE|$sourcefilebase|")
|
printf "$FMT_WARN" "Found multiple sources for language $2 (using first as main): ${sources[@]}"
|
||||||
sed -i "s(HOWTORUN($howto(" $readme
|
fi
|
||||||
loc=$(sed -r '/^\s*(#|\/\/|\/\*|;)/d;/^\s*$/d' $sourcefile | wc -l)
|
mainsource=${sources[0]}
|
||||||
sed -i "s(LOC($loc(" $readme
|
if [[ -z $lang ]]; then
|
||||||
|
lang=$2
|
||||||
|
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 {
|
function get_time {
|
||||||
cd $day_dir
|
cd $day_dir
|
||||||
exe=$(find . -type f -executable)
|
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)
|
exe=$(basename $exe)
|
||||||
if [[ $(echo $exe | wc -w) != 1 ]]; then
|
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 ..
|
cd ..
|
||||||
return 1
|
return 1
|
||||||
time=Error
|
|
||||||
else
|
|
||||||
time=$({ time ./$exe; } 2>&1)
|
|
||||||
if [[ $? != 0 ]]; then
|
|
||||||
printf "$FMT_ERR" "Execution error in './$exe' in '$(pwd)'. Output:"
|
|
||||||
printf "\e[34m"
|
|
||||||
echo -e "$time"
|
|
||||||
printf "\e[0m"
|
|
||||||
cd ..
|
|
||||||
return 1
|
|
||||||
fi
|
|
||||||
time=$(echo -e "$time" | tail -3 | head -1 | awk '{print $2}')
|
|
||||||
re='([[:digit:]]+)m([[:digit:]]+),([[:digit:]]+)s'
|
|
||||||
[[ $time =~ $re ]]
|
|
||||||
min=${BASH_REMATCH[1]}
|
|
||||||
sec=${BASH_REMATCH[2]}
|
|
||||||
msec=${BASH_REMATCH[3]}
|
|
||||||
if [[ $min != 0 ]]; then
|
|
||||||
time="$min m $sec,$msec s"
|
|
||||||
else
|
|
||||||
time="$sec,$msec s"
|
|
||||||
fi
|
|
||||||
cd ..
|
|
||||||
# elif [[ $sec != 0 ]]; then
|
|
||||||
# time="$sec,$msec s"
|
|
||||||
# else
|
|
||||||
# time="$((msec+0)) ms"
|
|
||||||
# fi
|
|
||||||
fi
|
fi
|
||||||
|
time=$({ time ./$exe; } 2>&1)
|
||||||
|
if [[ $? != 0 ]]; then
|
||||||
|
printf "$FMT_ERR" "Execution error in './$exe' in '$(pwd)'. Output:"
|
||||||
|
printf "\e[34m"
|
||||||
|
echo -e "$time"
|
||||||
|
printf "\e[0m"
|
||||||
|
cd ..
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
time=$(echo -e "$time" | tail -3 | head -1 | awk '{print $2}')
|
||||||
|
re='([[:digit:]]+)m([[:digit:]]+),([[:digit:]]+)s'
|
||||||
|
[[ $time =~ $re ]]
|
||||||
|
min=${BASH_REMATCH[1]}
|
||||||
|
sec=${BASH_REMATCH[2]}
|
||||||
|
msec=${BASH_REMATCH[3]}
|
||||||
|
if [[ $min != 0 ]]; then
|
||||||
|
time="$min m $sec,$msec s"
|
||||||
|
else
|
||||||
|
time="$sec,$msec s"
|
||||||
|
fi
|
||||||
|
# elif [[ $sec != 0 ]]; then
|
||||||
|
# time="$sec,$msec s"
|
||||||
|
# else
|
||||||
|
# time="$((msec+0)) ms"
|
||||||
|
# fi
|
||||||
|
cd ..
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
gifts=""
|
gifts=""
|
||||||
for i in $(seq $day); do gifts+=":gift:"; done
|
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
|
get_time
|
||||||
if [[ $? == 0 ]]; then
|
if [[ $? == 0 ]]; then
|
||||||
cd ..
|
|
||||||
printf "$FMT_VAR" "exectime" "$time"
|
printf "$FMT_VAR" "exectime" "$time"
|
||||||
sed -i "s/EXECTIME/$time/" $readme
|
sed -i "s/EXECTIME/$time/" "$readme"
|
||||||
else
|
else
|
||||||
cd ..
|
|
||||||
printf "$FMT_WARN" "No execution time determined"
|
printf "$FMT_WARN" "No execution time determined"
|
||||||
sed -i '/.*EXECTIME.*/d' $readme
|
sed -i '/.*EXECTIME.*/d' "$readme"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [[ -z $1 ]]; then
|
if [[ -z $1 ]]; then
|
||||||
printf "$FMT_WARN" "No comment provided"
|
printf "$FMT_WARN" "No comment provided"
|
||||||
sed -i "/<!-- COMMENT -->/d" $readme
|
sed -i '/<!-- COMMENT -->/d' "$readme" || echo "ERROR comment"
|
||||||
else
|
else
|
||||||
printf "$FMT_VAR" "Comment" "'$1'"
|
printf "$FMT_VAR" "Comment" "'$1'"
|
||||||
sed -i "s|COMMENT|$1|" $readme
|
sed -i "s|COMMENT|$1|" "$readme" || echo "ERROR comment2"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
dayexec="day${day_dir}"
|
||||||
|
loc=0
|
||||||
find_lang py Python "python3 SOURCE"
|
find_lang py Python "python3 SOURCE"
|
||||||
find_lang rs Rust "rustc SOURCE\n./day${day_dir}"
|
find_lang rs Rust "rustc SOURCE\n./$dayexec"
|
||||||
find_lang cpp C++ "g++ SOURCE -o day${day_dir}\n ./day${day_dir}"
|
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="| Day | Language | Lines of code | Execuction time | Comment |\n"
|
||||||
table+="|:---:|:---:| ---:| ---: |--- |\n"
|
table+="|:---:|:---:| ---:| ---: |--- |\n"
|
||||||
for day in $(seq -f "%02g" 1 25); do
|
maxday=$(ls -d */ | sed -r 's|0*(.*)/|\1|g' | tail -1)
|
||||||
[[ ! -d "$day" ]] && continue
|
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
|
# echo $day
|
||||||
lang=$(grep -E "Today's language:" $day/README.md | sed -r 's/.*\*\*(.+)\*\*.*/\1/')
|
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/')
|
exectime=$(grep -E "Execution time:" $day/README.md | sed -r 's/.*\*\*(.+)\*\*.*/\1/')
|
||||||
|
Loading…
Reference in New Issue
Block a user