diff --git a/.aoc_tiles/tiles/2025/06.png b/.aoc_tiles/tiles/2025/06.png
new file mode 100644
index 0000000..e8d999c
Binary files /dev/null and b/.aoc_tiles/tiles/2025/06.png differ
diff --git a/README.md b/README.md
index 676e8aa..05149de 100644
--- a/README.md
+++ b/README.md
@@ -1,6 +1,6 @@
- 2025 - 10 ⭐ - Rust
+ 2025 - 12 ⭐ - Rust
@@ -17,4 +17,7 @@
+
+
+
diff --git a/src/day6.rs b/src/day6.rs
new file mode 100644
index 0000000..264f7b0
--- /dev/null
+++ b/src/day6.rs
@@ -0,0 +1,176 @@
+use aoc_runner_derive::{aoc, aoc_generator};
+use grid::Grid;
+use itertools::Itertools;
+use std::{
+ fmt::{Display, Write},
+ iter::repeat_n,
+};
+
+#[repr(u8)]
+enum Op {
+ Add = b'+',
+ Mul = b'*',
+}
+
+impl From<&str> for Op {
+ fn from(value: &str) -> Self {
+ match value {
+ "+" => Op::Add,
+ "*" => Op::Mul,
+ c => panic!("Invalid op `{c}`"),
+ }
+ }
+}
+
+impl Display for Op {
+ fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+ match self {
+ Op::Add => f.write_char('+'),
+ Op::Mul => f.write_char('*'),
+ }
+ }
+}
+
+impl Op {
+ fn f(&self, lhs: u64, rhs: u64) -> u64 {
+ match self {
+ Op::Add => lhs + rhs,
+ Op::Mul => lhs * rhs,
+ }
+ }
+}
+
+#[aoc_generator(day6, part1)]
+fn parse(input: &str) -> (Grid, Vec) {
+ let mut rows = input
+ .lines()
+ .map(|l| l.split_ascii_whitespace().collect_vec())
+ .collect_vec();
+
+ let ops = rows
+ .pop()
+ .unwrap()
+ .iter()
+ .map(|op| Op::from(*op))
+ .collect_vec();
+ let mut grid = Grid::with_shape(rows[0].len(), rows.len(), 0);
+
+ for (y, r) in rows.iter().enumerate() {
+ for (x, v) in r.iter().enumerate() {
+ grid.set(&(x, y), v.parse().unwrap());
+ }
+ }
+
+ (grid, ops)
+}
+
+#[aoc(day6, part1)]
+fn part1((grid, ops): &(Grid, Vec)) -> u64 {
+ (0..grid.width())
+ .map(|x| {
+ grid.col_iter(x as i64)
+ .unwrap()
+ .cloned()
+ .reduce(|l, r| ops[x].f(l, r))
+ .unwrap()
+ })
+ .sum()
+}
+
+// fn split_digits(x: &u64) -> Vec {
+// let n_digits = x.ilog10() as usize;
+// (0..=n_digits)
+// .rev()
+// .map(|n| ((x / POW10[n]) % 10) as u8)
+// .collect()
+// }
+
+#[aoc_generator(day6, part2)]
+fn parse2(input: &str) -> (Grid>, Vec) {
+ let mut rows = input.lines().collect_vec();
+ let ops = rows.pop().unwrap();
+
+ let col_starts = ops
+ .chars()
+ .enumerate()
+ .filter(|(_i, c)| *c == '+' || *c == '*')
+ .map(|(i, _c)| i)
+ .collect_vec();
+
+ let col_lengths = col_starts
+ .iter()
+ .tuple_windows()
+ .map(|(l, r)| r - l - 1)
+ .collect_vec();
+
+ let split_rows = rows
+ .iter()
+ .map(|r| {
+ col_starts
+ .iter()
+ .zip(col_lengths.iter())
+ .map(|(s, l)| &r[*s..s + l])
+ .chain(repeat_n(&r[*col_starts.last().unwrap()..], 1))
+ .collect_vec()
+ })
+ .collect_vec();
+
+ let ops = ops.split_ascii_whitespace().map(Op::from).collect_vec();
+ let mut grid = Grid::with_shape(split_rows[0].len(), split_rows.len(), Vec::new());
+ for (y, r) in split_rows.iter().enumerate() {
+ for (x, v) in r.iter().enumerate() {
+ grid.set(&(x, y), v.chars().collect_vec());
+ }
+ }
+
+ (grid, ops)
+}
+
+#[aoc(day6, part2)]
+fn part2((grid, ops): &(Grid>, Vec)) -> u64 {
+ let mut columns = Vec::new();
+ for col in 0..grid.width() {
+ let mut digit = 0;
+ let mut col_values = Vec::new();
+ loop {
+ let val = grid
+ .col_iter(col as i64)
+ .unwrap()
+ .filter_map(|s| s.get(digit))
+ .filter(|c| !c.is_ascii_whitespace())
+ .map(|v| v.to_digit(10).unwrap() as u64)
+ .fold(0, |acc, n| acc * 10 + n);
+ if val == 0 {
+ columns.push(col_values);
+ break;
+ }
+ col_values.push(val);
+ digit += 1;
+ }
+ }
+ columns
+ .iter()
+ .enumerate()
+ .map(|(col, v)| v.iter().cloned().reduce(|l, r| ops[col].f(l, r)).unwrap())
+ .sum::()
+}
+
+#[cfg(test)]
+mod tests {
+ use super::*;
+
+ const EXAMPLE: &str = r"123 328 51 64
+ 45 64 387 23
+ 6 98 215 314
+* + * + ";
+
+ #[test]
+ fn part1_example() {
+ assert_eq!(part1(&parse(EXAMPLE)), 4277556);
+ }
+
+ #[test]
+ fn part2_example() {
+ assert_eq!(part2(&parse2(EXAMPLE)), 3263827);
+ }
+}
diff --git a/src/lib.rs b/src/lib.rs
index 1bb311f..fb58f07 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -3,6 +3,7 @@ mod day2;
mod day3;
mod day4;
mod day5;
+mod day6;
use aoc_runner_derive::aoc_lib;