diff --git a/2019/3/README.md b/2019/3/README.md
new file mode 100644
index 0000000..05d834a
--- /dev/null
+++ b/2019/3/README.md
@@ -0,0 +1,11 @@
+# 3
+
+Description
+
+
+ Solutions
+
+ - 1
+ - 2
+
+
diff --git a/2019/3/python/main.py b/2019/3/python/main.py
new file mode 100644
index 0000000..7e713f8
--- /dev/null
+++ b/2019/3/python/main.py
@@ -0,0 +1,96 @@
+#!/usr/bin/env python
+
+from os.path import join, dirname
+
+# Day 3
+
+# Common
+
+
+def read_input(filename):
+ data = join(dirname(__file__), '..', filename)
+ with open(data) as f:
+ return f.read().strip()
+
+
+test = read_input('test.txt')
+data = read_input('input.txt')
+
+# Running
+
+Point = tuple[int, int]
+
+class Line:
+ def __init__(self, start:Point, end: Point) -> None:
+ pass
+
+class Wire:
+ def __init__(self, points: list[Point]) -> None:
+ self.points = points
+
+ def __iter__(self):
+ self.i = 0
+ self.max = len(self.points) - 1
+ return self
+
+ def __next__(self):
+ if self.i >= self.max:
+ raise StopIteration
+ value = (self.points[self.i], self.points[self.i +1])
+ self.i += 1
+ return value
+
+ def __str__(self) -> str:
+ return ', '.join([f'({x}, {y})' for x, y in self.points])
+
+ def find_intersections(self, other: Line) -> list[Point]:
+ matches: list[Point] = []
+ for a in self:
+ for b in other:
+ if a[0][0] < b[0]
+ # if a[0] == b[0] and a[1] == b[1]:
+ # matches.append(a[0])
+ return matches
+
+ @staticmethod
+ def parse(raw: str):
+ commands = raw.split(',')
+ current: Point = (0, 0)
+ points: list[Point] = [current]
+ for command in commands:
+ direction = command[0]
+ length = int(command[1:])
+ match direction:
+ case 'L':
+ current = (current[0] - length, current[1])
+ case 'R':
+ current = (current[0] + length, current[1])
+ case 'U':
+ current = (current[0], current[1] + length)
+ case 'D':
+ current = (current[0], current[1] - length)
+ points.append(current)
+ return Wire(points)
+
+
+class Panel():
+ def __init__(self, wires: list[Wire]) -> None:
+ self.wires = wires
+
+ def find_closes(self):
+ matches = self.wires[0].find_intersections(self.wires[1].line)
+ distances = [abs(x)+abs(y) for x, y in matches]
+ return min(distances)
+
+ @staticmethod
+ def parse(raw: str):
+ return Panel(wires=[Wire.parse(line) for line in raw.splitlines()])
+
+
+p = Panel.parse(test)
+# print([str(w) for w in p.wires])
+for wire in p.wires:
+ print(wire)
+ for line in wire:
+ print(line)
+# print(p.find_closes())
diff --git a/2022/01/rust/main.rs b/2022/01/rust/main.rs
index af4212b..2b67203 100644
--- a/2022/01/rust/main.rs
+++ b/2022/01/rust/main.rs
@@ -5,16 +5,16 @@ extern crate test;
#[cfg(test)]
mod tests {
use super::*;
- use test::Bencher;
+ use test::{black_box, Bencher};
#[bench]
fn bench_a(b: &mut Bencher) {
- b.iter(|| part_a(INPUT));
+ b.iter(|| black_box(part_a(INPUT)));
}
#[bench]
fn bench_b(b: &mut Bencher) {
- b.iter(|| part_b(INPUT));
+ b.iter(|| black_box(part_b(INPUT)));
}
}
diff --git a/2023/01/rust/main.rs b/2023/01/rust/main.rs
new file mode 100644
index 0000000..a75b6c6
--- /dev/null
+++ b/2023/01/rust/main.rs
@@ -0,0 +1,103 @@
+#![feature(test)]
+
+extern crate test;
+
+#[cfg(test)]
+mod tests {
+ use super::*;
+ use test::Bencher;
+
+ #[bench]
+ fn bench_a(b: &mut Bencher) {
+ b.iter(|| part_a(INPUT));
+ }
+
+ #[bench]
+ fn bench_b(b: &mut Bencher) {
+ b.iter(|| part_b(INPUT));
+ }
+}
+
+const INPUT: &str = include_str!("../input.txt");
+const TEST: &str = include_str!("../test.txt");
+
+fn part_a(input: &str) {
+ let result = input
+ .trim()
+ .split("\n")
+ .map(|line| {
+ let mut first: u16 = 0;
+ for char in line.chars() {
+ if first != 0 {
+ break;
+ }
+ match char {
+ '1' => first = 1,
+ '2' => first = 2,
+ '3' => first = 3,
+ '4' => first = 4,
+ '5' => first = 5,
+ '6' => first = 6,
+ '7' => first = 7,
+ '8' => first = 8,
+ '9' => first = 9,
+ _ => continue,
+ }
+ }
+ let mut last: u16 = 0;
+ for char in line.chars().rev() {
+ if last != 0 {
+ break;
+ }
+ match char {
+ '1' => last = 1,
+ '2' => last = 2,
+ '3' => last = 3,
+ '4' => last = 4,
+ '5' => last = 5,
+ '6' => last = 6,
+ '7' => last = 7,
+ '8' => last = 8,
+ '9' => last = 9,
+ _ => continue,
+ }
+ }
+ return first * 10 + last;
+ })
+ .sum::();
+ println!("{}", result);
+}
+
+fn part_b(input: &str) {
+ let result = input
+ .trim()
+ .split("\n")
+ .map(|line| {
+ let mut first: usize = 0;
+ let nums = [
+ "1", "2", "3", "4", "5", "6", "7", "8", "9", "one", "two", "three", "four", "five",
+ "six", "seven", "eight", "nine",
+ ];
+ for (i, s) in nums.iter().enumerate() {
+ if line.starts_with(s) {
+ first = if i < 9 { i + 1 } else { i - 8 };
+ break;
+ }
+ line.split_at(mid)
+ }
+ let mut last = 0 as usize;
+ return first * 10 + last;
+ })
+ .sum::();
+ println!("{}", result);
+}
+
+fn main() {
+ println!("Part A:");
+ part_a(TEST);
+ part_a(INPUT);
+
+ println!("\nPart B:");
+ part_b(TEST);
+ // part_b(INPUT);
+}
diff --git a/2023/03/README.md b/2023/03/README.md
new file mode 100644
index 0000000..a555884
--- /dev/null
+++ b/2023/03/README.md
@@ -0,0 +1,11 @@
+# 03
+
+Description
+
+
+ Solutions
+
+ - 1
+ - 2
+
+
diff --git a/2023/03/rust/main.rs b/2023/03/rust/main.rs
new file mode 100644
index 0000000..7fe2bac
--- /dev/null
+++ b/2023/03/rust/main.rs
@@ -0,0 +1,64 @@
+#![feature(test)]
+
+extern crate test;
+
+#[cfg(test)]
+mod tests {
+ use super::*;
+ use test::Bencher;
+
+ #[bench]
+ fn bench_a(b: &mut Bencher) {
+ b.iter(|| part_a(INPUT));
+ }
+
+ #[bench]
+ fn bench_b(b: &mut Bencher) {
+ b.iter(|| part_b(INPUT));
+ }
+}
+
+const INPUT: &str = include_str!("../input.txt");
+const TEST: &str = include_str!("../test.txt");
+
+struct Point {
+ x: usize,
+ y: usize,
+}
+
+fn part_a(input: &str) {
+ let result = input.trim();
+
+ let lines = result.split("\n").collect::>();
+
+ let mut symbols: Vec> = Vec::new();
+ for _ in [0..lines.len()] {
+ symbols.push(vec![0; 0]);
+ }
+
+ for (y, line) in result.split("\n").enumerate() {
+ for (x, char) in line.chars().enumerate() {
+ match char {
+ '*' | '&' | '+' | '#' | '$' => symbols[y].push(x),
+ _ => {}
+ }
+ }
+ }
+
+ println!("{:?}", symbols);
+}
+
+fn part_b(input: &str) {
+ let result = input.trim();
+ println!("{}", result);
+}
+
+fn main() {
+ println!("Part A:");
+ part_a(TEST);
+ // part_a(INPUT);
+
+ println!("\nPart B:");
+ // part_b(TEST);
+ // part_b(INPUT);
+}
diff --git a/2023/04/README.md b/2023/04/README.md
new file mode 100644
index 0000000..9c53258
--- /dev/null
+++ b/2023/04/README.md
@@ -0,0 +1,11 @@
+# 04
+
+Description
+
+
+ Solutions
+
+ - 1
+ - 2
+
+
diff --git a/2023/04/rust/main.rs b/2023/04/rust/main.rs
new file mode 100644
index 0000000..bec82ae
--- /dev/null
+++ b/2023/04/rust/main.rs
@@ -0,0 +1,127 @@
+#![feature(test)]
+
+use std::collections::HashMap;
+
+extern crate test;
+
+#[cfg(test)]
+mod tests {
+ use super::*;
+ use test::Bencher;
+
+ #[bench]
+ fn bench_a(b: &mut Bencher) {
+ b.iter(|| part_a(INPUT));
+ }
+
+ #[bench]
+ fn bench_b(b: &mut Bencher) {
+ b.iter(|| part_b(INPUT));
+ }
+}
+
+const INPUT: &str = include_str!("../input.txt");
+const TEST: &str = include_str!("../test.txt");
+
+fn get_matches_per_card(input: &str) -> Vec {
+ input
+ .trim()
+ .split("\n")
+ .map(|line| {
+ let splitted: Vec<&str> = line.split(":").collect();
+ let body = splitted[1]
+ .split("|")
+ .map(|part| {
+ let mut numbers = part
+ .trim()
+ .split(" ")
+ .filter(|x| x.len() > 0)
+ .map(|s| s.parse::().expect("not a number"))
+ .collect::>();
+ numbers.sort();
+ numbers
+ })
+ .collect::>>();
+
+ let numbers = &body[0];
+ let winning = &body[1];
+
+ let mut matches = 0_usize;
+ for number in numbers {
+ match winning.binary_search(number) {
+ Err(_) => {}
+ Ok(_) => matches += 1,
+ }
+ }
+
+ matches
+ })
+ .collect()
+}
+
+fn part_a(input: &str) {
+ let matches = get_matches_per_card(input);
+ let total: usize = matches
+ .iter()
+ .map(|matches| {
+ if *matches > 0 {
+ 2_usize.pow(*matches as u32 - 1)
+ } else {
+ 0
+ }
+ })
+ .sum();
+
+ println!("{total}");
+}
+
+fn add_points(matches: &Vec, cache: &mut HashMap, number: usize) -> usize {
+ let cached = cache.get(&number);
+ match cached {
+ Some(x) => *x,
+ None => {
+ let m = matches[number];
+ if m == 0 {
+ return 0;
+ }
+ let mut total = 0;
+ for n in number + 1..(number + m) {
+ total += add_points(matches, cache, n);
+ }
+ cache.insert(number, total);
+ total
+ }
+ }
+}
+
+fn part_b(input: &str) {
+ let matches = get_matches_per_card(input);
+ let mut cache: HashMap = HashMap::new();
+ let mut scores = vec![0, matches.len()];
+ let mut total: usize = 0;
+ for m in matches {
+ // total += add_points(&matches, &mut cache, m);
+ }
+ // let total: usize = matches
+ // .iter()
+ // .map(|matches| {
+ // if *matches > 0 {
+ // 2_usize.pow(matches - 1)
+ // } else {
+ // 0
+ // }
+ // })
+ // .sum();
+
+ // println!("{total}");
+}
+
+fn main() {
+ println!("Part A:");
+ part_a(TEST);
+ part_a(INPUT);
+
+ println!("\nPart B:");
+ part_b(TEST);
+ // part_b(INPUT);
+}
diff --git a/Cargo.toml b/Cargo.toml
index 037100b..f6fe0cf 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -14,4 +14,24 @@ path = "./2022/01/rust/main.rs"
name = "2022-02"
path = "./2022/02/rust/main.rs"
+[[bin]]
+name = "2022-03"
+path = "./2022/03/rust/main.rs"
+
+[[bin]]
+name = "2023-01"
+path = "./2023/01/rust/main.rs"
+
+[[bin]]
+name = "2023-02"
+path = "./2023/02/rust/main.rs"
+
+[[bin]]
+name = "2023-03"
+path = "./2023/03/rust/main.rs"
+
+[[bin]]
+name = "2023-04"
+path = "./2023/04/rust/main.rs"
+
# INJECT HERE