From 27aa5a27b503bf933434be9308d2c0bc8b6467d1 Mon Sep 17 00:00:00 2001 From: James Tomasino Date: Sat, 14 Dec 2024 19:18:51 +0000 Subject: [PATCH 1/5] adds alternate solve for difficult day --- 2024/12/jamestomasinon.v | 142 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 142 insertions(+) create mode 100644 2024/12/jamestomasinon.v diff --git a/2024/12/jamestomasinon.v b/2024/12/jamestomasinon.v new file mode 100644 index 0000000..6ea0559 --- /dev/null +++ b/2024/12/jamestomasinon.v @@ -0,0 +1,142 @@ +import os + +struct Region { + id rune +mut: + area i64 + perimiter []Perimiter + sides []Perimiter + plots [][]int +} + +struct Perimiter { + p Point + d Vector +} + +struct Point { + x int + y int +} + +struct Vector { + dx int + dy int +} + +fn is_valid_move(row int, col int, max_y int, max_x int) bool { + return row >= 0 && row < max_y && col >= 0 && col < max_x +} + +fn check_cell(mut region &Region, mut visited [][]bool, grid []string, row int, col int, max_y int, max_x int) { + directions := [[0, 1], [0, -1], [1, 0], [-1, 0]] + for dir in directions { + new_row := row + dir[0] + new_col := col + dir[1] + // Is the new position on the grid + if is_valid_move(new_row, new_col, max_y, max_x) { + // Does new direction match our grid id + runes := grid[new_row].runes() + if runes[new_col] == region.id { + // Have we visited this before + if !visited[new_row][new_col] { + // add to region size + region.area += 1 + region.plots << [new_row, new_col] + // mark as visited + visited[new_row][new_col] = true + // recursive directional search + check_cell(mut region, mut visited, grid, new_row, new_col, max_y, + max_x) + } + } else { + // edge detected + region.perimiter << Perimiter{ + p: Point{ + y: row + x: col + } + d: Vector{ + dy: dir[0] + dx: dir[1] + } + } + } + } else { + // grid border, add to perimiter + region.perimiter << Perimiter{ + p: Point{ + y: row + x: col + } + d: Vector{ + dy: dir[0] + dx: dir[1] + } + } + } + } +} + +fn main() { + grid := os.read_lines('puzzle.input')! + + max_y := grid.len + max_x := grid[0].len + + // initialize a 2D array to keep track of grid and visited elements + mut visited := [][]bool{len: max_y, init: []bool{len: max_x}} + + // transverse grid + mut regions := []Region{} + for row in 0 .. max_y { + for col in 0 .. max_x { + // if element is unvisited: + if !visited[row][col] { + // identify new region and give it an identifier (char value) + visited[row][col] = true + runes := grid[row].runes() + mut region := &Region{ + id: runes[col] + area: 1 + } + region.plots << [row, col] + // check for each direction to see if 0) valid 1) unvisited and 2) matching id + check_cell(mut region, mut visited, grid, row, col, max_y, max_x) + regions << region + } + } + } + + mut price := i64(0) + mut price2 := i64(0) + for mut r in regions { + price += r.area * r.perimiter.len + + mut new_set := []Perimiter{} + for per in r.perimiter { + new_set << Perimiter{ + p: Point{ + y: per.p.y - per.d.dx + x: per.p.x + per.d.dy + } + d: per.d + } + } + r.sides = set_subtract(r.perimiter, new_set) + price2 += r.area * r.sides.len + // println('Region: ${r.id} (Area ${r.area}, Perimiter ${r.perimiter.len}, Sides ${r.sides.len})') + } + println('Part 1 total price: ${price}') + println('Part 2 total price: ${price2}') +} + +fn set_subtract[T](set1 []T, set2 []T) []T { + mut result := []T{} + for item in set1 { + if !set2.contains(item) { + result << item + } + } + return result +} From d101c15d6abc2bbd46dd425812299e84ad508484 Mon Sep 17 00:00:00 2001 From: James Tomasino Date: Sat, 14 Dec 2024 19:22:23 +0000 Subject: [PATCH 2/5] removing plots. redundant with new perimiters array --- 2024/12/jamestomasinon.v | 3 --- 1 file changed, 3 deletions(-) diff --git a/2024/12/jamestomasinon.v b/2024/12/jamestomasinon.v index 6ea0559..f3d5ff0 100644 --- a/2024/12/jamestomasinon.v +++ b/2024/12/jamestomasinon.v @@ -6,7 +6,6 @@ mut: area i64 perimiter []Perimiter sides []Perimiter - plots [][]int } struct Perimiter { @@ -42,7 +41,6 @@ fn check_cell(mut region &Region, mut visited [][]bool, grid []string, row int, if !visited[new_row][new_col] { // add to region size region.area += 1 - region.plots << [new_row, new_col] // mark as visited visited[new_row][new_col] = true // recursive directional search @@ -100,7 +98,6 @@ fn main() { id: runes[col] area: 1 } - region.plots << [row, col] // check for each direction to see if 0) valid 1) unvisited and 2) matching id check_cell(mut region, mut visited, grid, row, col, max_y, max_x) regions << region From 2d3f16aa546471071d8448492def49cb74b0c281 Mon Sep 17 00:00:00 2001 From: James Tomasino Date: Sat, 14 Dec 2024 19:24:34 +0000 Subject: [PATCH 3/5] fixing misspelled perimeter --- 2024/12/jamestomasinon.v | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/2024/12/jamestomasinon.v b/2024/12/jamestomasinon.v index f3d5ff0..fc9f875 100644 --- a/2024/12/jamestomasinon.v +++ b/2024/12/jamestomasinon.v @@ -4,11 +4,11 @@ struct Region { id rune mut: area i64 - perimiter []Perimiter - sides []Perimiter + perimeter []Perimeter + sides []Perimeter } -struct Perimiter { +struct Perimeter { p Point d Vector } @@ -49,7 +49,7 @@ fn check_cell(mut region &Region, mut visited [][]bool, grid []string, row int, } } else { // edge detected - region.perimiter << Perimiter{ + region.perimeter << Perimeter{ p: Point{ y: row x: col @@ -61,8 +61,8 @@ fn check_cell(mut region &Region, mut visited [][]bool, grid []string, row int, } } } else { - // grid border, add to perimiter - region.perimiter << Perimiter{ + // grid border, add to perimeter + region.perimeter << Perimeter{ p: Point{ y: row x: col @@ -108,11 +108,11 @@ fn main() { mut price := i64(0) mut price2 := i64(0) for mut r in regions { - price += r.area * r.perimiter.len + price += r.area * r.perimeter.len - mut new_set := []Perimiter{} - for per in r.perimiter { - new_set << Perimiter{ + mut new_set := []Perimeter{} + for per in r.perimeter { + new_set << Perimeter{ p: Point{ y: per.p.y - per.d.dx x: per.p.x + per.d.dy @@ -120,9 +120,9 @@ fn main() { d: per.d } } - r.sides = set_subtract(r.perimiter, new_set) + r.sides = set_subtract(r.perimeter, new_set) price2 += r.area * r.sides.len - // println('Region: ${r.id} (Area ${r.area}, Perimiter ${r.perimiter.len}, Sides ${r.sides.len})') + // println('Region: ${r.id} (Area ${r.area}, Perimeter ${r.perimeter.len}, Sides ${r.sides.len})') } println('Part 1 total price: ${price}') println('Part 2 total price: ${price2}') From 33e933b03e3c1e59bd3751e6ba750fdb1a901000 Mon Sep 17 00:00:00 2001 From: James Tomasino Date: Sat, 14 Dec 2024 19:36:31 +0000 Subject: [PATCH 4/5] updated input file to use drakeervs example --- 2024/12/jamestomasinon.v | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/2024/12/jamestomasinon.v b/2024/12/jamestomasinon.v index fc9f875..f752016 100644 --- a/2024/12/jamestomasinon.v +++ b/2024/12/jamestomasinon.v @@ -77,7 +77,7 @@ fn check_cell(mut region &Region, mut visited [][]bool, grid []string, row int, } fn main() { - grid := os.read_lines('puzzle.input')! + grid := os.read_lines('garden.input')! max_y := grid.len max_x := grid[0].len From 19d6c103130d2320fd44bb0e395fc15191b15fbd Mon Sep 17 00:00:00 2001 From: James Tomasino Date: Sat, 14 Dec 2024 19:57:13 +0000 Subject: [PATCH 5/5] adding the known output too? not sure how verify.v is validating in the action. passes local --- 2024/12/{jamestomasinon.v => jamestomasino.v} | 0 known/2024/12/jamestomasino.out | 2 ++ 2 files changed, 2 insertions(+) rename 2024/12/{jamestomasinon.v => jamestomasino.v} (100%) create mode 100644 known/2024/12/jamestomasino.out diff --git a/2024/12/jamestomasinon.v b/2024/12/jamestomasino.v similarity index 100% rename from 2024/12/jamestomasinon.v rename to 2024/12/jamestomasino.v diff --git a/known/2024/12/jamestomasino.out b/known/2024/12/jamestomasino.out new file mode 100644 index 0000000..1b9a88a --- /dev/null +++ b/known/2024/12/jamestomasino.out @@ -0,0 +1,2 @@ +Part 1 total price: 1930 +Part 2 total price: 1206