From 75cb2d755dfa2e177158939c30b7f87edce366f9 Mon Sep 17 00:00:00 2001 From: oabrivard Date: Mon, 11 Dec 2023 20:44:26 +0100 Subject: [PATCH] Completed both parts of Day 11 puzzle --- day10/day10.go | 1 + day11/day11.go | 221 ++++++++++++++++++++++++++++++++++++++++++++ day11/day11_test.go | 137 +++++++++++++++++++++++++++ day11/input.txt | 140 ++++++++++++++++++++++++++++ start_day.sh | 18 ++++ utils/utils.go | 8 ++ 6 files changed, 525 insertions(+) create mode 100644 day11/day11.go create mode 100644 day11/day11_test.go create mode 100644 day11/input.txt create mode 100755 start_day.sh diff --git a/day10/day10.go b/day10/day10.go index a66429a..d131068 100644 --- a/day10/day10.go +++ b/day10/day10.go @@ -149,6 +149,7 @@ func FindDistance(lines []string) int { } } +// Point in Polygon algorithm func isInPolygon(row int, col int, lines [][]rune) bool { count := 0 last := rune(0) diff --git a/day11/day11.go b/day11/day11.go new file mode 100644 index 0000000..abeded7 --- /dev/null +++ b/day11/day11.go @@ -0,0 +1,221 @@ +package day11 + +import ( + "gitea.paas.celticinfo.fr/oabrivard/aoc2023/utils" +) + +type Coord struct { + row int + col int +} + +func expandUniverse(lines []string) [][]byte { + height := len(lines) + width := len(lines[0]) + isRowEmpty := make([]bool, height) + isColEmpty := make([]bool, width) + emptyColCount := 0 + emptyRowCount := 0 + + for row, l := range lines { + isRowEmpty[row] = true + emptyRowCount++ + for _, c := range l { + if c == '#' { + isRowEmpty[row] = false + emptyRowCount-- + break + } + } + } + + for col := 0; col < width; col++ { + isColEmpty[col] = true + emptyColCount++ + for row := 0; row < height; row++ { + if lines[row][col] == '#' { + isColEmpty[col] = false + emptyColCount-- + break + } + } + } + + result := make([][]byte, height+emptyRowCount) + destRow := 0 + + for row, l := range lines { + destCol := 0 + result[destRow] = make([]byte, width+emptyColCount) + if isRowEmpty[row] { + result[destRow+1] = make([]byte, width+emptyColCount) + for destCol := range result[destRow] { + result[destRow][destCol] = '.' + result[destRow+1][destCol] = '.' + } + destRow += 2 + } else { + for col := range l { + result[destRow][destCol] = lines[row][col] + destCol++ + if isColEmpty[col] { + result[destRow][destCol] = lines[row][col] + destCol++ + } + } + destRow++ + } + } + + return result +} + +func getUniverseAsInt(universe [][]byte) ([][]int, []Coord) { + height := len(universe) + width := len(universe[0]) + result := make([][]int, height) + coords := []Coord{} + galaxyID := 0 + + for row, line := range universe { + result[row] = make([]int, width) + + for col, c := range line { + if c == '#' { + result[row][col] = galaxyID + coords = append(coords, Coord{row, col}) + galaxyID++ + } else { + result[row][col] = -1 + } + } + } + + return result, coords +} + +func SumLengths(lines []string) int { + result := 0 + _, coords := getUniverseAsInt(expandUniverse(lines)) + galaxyCount := len(coords) - 1 + + for i := 0; i < galaxyCount; i++ { + for j := i + 1; j <= galaxyCount; j++ { + r1_c1 := coords[i] + r2_c2 := coords[j] + dist := 0 + //dist2 := float64(0) + ab := r2_c2.row - r1_c1.row + if ab == 0 { + dist = utils.AbsInt(r2_c2.col - r1_c1.col) + } else { + bc := r2_c2.col - r1_c1.col + if bc == 0 { + dist = utils.AbsInt(r2_c2.row - r1_c1.row) + } else { + //dist2 = math.Sqrt(float64(utils.IntPow(ab, 2) + utils.IntPow(bc, 2))) // euclidian distance + dist = utils.AbsInt(r2_c2.row-r1_c1.row) + utils.AbsInt(r2_c2.col-r1_c1.col) // Manhattan distance + } + } + result += dist + //fmt.Printf("(%d,%d) = %d, %v\n", i, j, dist, dist2) + } + } + + return result +} + +func getEmptyLines(lines []string) ([]bool, []bool) { + height := len(lines) + width := len(lines[0]) + isRowEmpty := make([]bool, height) + isColEmpty := make([]bool, width) + emptyColCount := 0 + emptyRowCount := 0 + + for row, l := range lines { + isRowEmpty[row] = true + emptyRowCount++ + for _, c := range l { + if c == '#' { + isRowEmpty[row] = false + emptyRowCount-- + break + } + } + } + + for col := 0; col < width; col++ { + isColEmpty[col] = true + emptyColCount++ + for row := 0; row < height; row++ { + if lines[row][col] == '#' { + isColEmpty[col] = false + emptyColCount-- + break + } + } + } + + return isRowEmpty, isColEmpty +} + +func getCoords(universe []string, expansion int) []Coord { + coords := []Coord{} + galaxyID := 0 + deltaRow := 0 + + isRowEmpty, isColEmpty := getEmptyLines(universe) + + for row, line := range universe { + deltaCol := 0 + + if isRowEmpty[row] { + deltaRow += expansion + } else { + for col, c := range line { + if isColEmpty[col] { + deltaCol += expansion + } else { + if c == '#' { + coords = append(coords, Coord{row + deltaRow, col + deltaCol}) + galaxyID++ + } + } + } + } + } + + return coords +} + +func SumLengths2(lines []string, expansion int) int { + result := 0 + + coords := getCoords(lines, expansion) + galaxyCount := len(coords) - 1 + + for i := 0; i < galaxyCount; i++ { + for j := i + 1; j <= galaxyCount; j++ { + r1_c1 := coords[i] + r2_c2 := coords[j] + dist := 0 + ab := r2_c2.row - r1_c1.row + if ab == 0 { + dist = utils.AbsInt(r2_c2.col - r1_c1.col) + } else { + bc := r2_c2.col - r1_c1.col + if bc == 0 { + dist = utils.AbsInt(r2_c2.row - r1_c1.row) + } else { + //dist2 = math.Sqrt(float64(utils.IntPow(ab, 2) + utils.IntPow(bc, 2))) // euclidian distance + dist = utils.AbsInt(r2_c2.row-r1_c1.row) + utils.AbsInt(r2_c2.col-r1_c1.col) // Manhattan distance + } + } + result += dist + //fmt.Printf("(%d,%d) = %d, %v\n", i, j, dist, dist2) + } + } + + return result +} diff --git a/day11/day11_test.go b/day11/day11_test.go new file mode 100644 index 0000000..b88f9d7 --- /dev/null +++ b/day11/day11_test.go @@ -0,0 +1,137 @@ +package day11 + +import ( + "fmt" + "testing" + + "gitea.paas.celticinfo.fr/oabrivard/aoc2023/utils" +) + +func TestExpandUniverse(t *testing.T) { + lines := []string{ + "...#......", + ".......#..", + "#.........", + "..........", + "......#...", + ".#........", + ".........#", + "..........", + ".......#..", + "#...#.....", + } + + result := expandUniverse(lines) + + for _, l := range result { + fmt.Println(string(l)) + } +} + +func TestGetUniverseAsInt(t *testing.T) { + lines := []string{ + "...#......", + ".......#..", + "#.........", + "..........", + "......#...", + ".#........", + ".........#", + "..........", + ".......#..", + "#...#.....", + } + + result, coords := getUniverseAsInt(expandUniverse(lines)) + + fmt.Println("Number of galaxies:", len(coords)) + for _, l := range result { + fmt.Println(l) + } +} + +func TestSumLengths(t *testing.T) { + lines := []string{ + "...#......", + ".......#..", + "#.........", + "..........", + "......#...", + ".#........", + ".........#", + "..........", + ".......#..", + "#...#.....", + } + + result := SumLengths(lines) + + if result != 374 { + t.Fatalf("expected 374, got %v", result) + } +} + +func TestSumLengthsWithInput(t *testing.T) { + lines := utils.ReadLines("input.txt") + + result := SumLengths(lines) + + if result != 10077850 { + t.Fatalf("expected 10077850, got %v", result) + } +} + +func TestSumLengths2(t *testing.T) { + lines := []string{ + "...#......", + ".......#..", + "#.........", + "..........", + "......#...", + ".#........", + ".........#", + "..........", + ".......#..", + "#...#.....", + } + + result := SumLengths2(lines, 1) + + if result != 374 { + t.Fatalf("expected 374, got %v", result) + } + + result = SumLengths2(lines, 10-1) + + if result != 1030 { + t.Fatalf("expected 1030, got %v", result) + } + + result = SumLengths2(lines, 100-1) + + if result != 8410 { + t.Fatalf("expected 8410, got %v", result) + } + + result = SumLengths2(lines, 1000000-1) + + if result != 82000210 { + t.Fatalf("expected 82000210, got %v", result) + } +} + +func TestSumLengths2WithInput(t *testing.T) { + lines := utils.ReadLines("input.txt") + + result := SumLengths2(lines, 1) + + if result != 10077850 { + t.Fatalf("expected 10077850, got %v", result) + } + + result = SumLengths2(lines, 1000000-1) + + if result != 504715068438 { + t.Fatalf("expected 504715068438, got %v", result) + } +} diff --git a/day11/input.txt b/day11/input.txt new file mode 100644 index 0000000..bc3192f --- /dev/null +++ b/day11/input.txt @@ -0,0 +1,140 @@ +...................#.....#...............#......................#......................#...................#...........................#.... +..................................................#................................................#..............#......................... +......#.....#.................#..............................................................#.............................................. +......................................................#..................#.....#............................................................ +.....................................................................................#.....................................#................ +.#............................................................................................................#............................. +..................#......................#............................#..............................................................#.....# +......................................................................................................#.............#....................... +..............................................#........#........................#................................................#.......... +.....#......................#......................................#.....#...................#.............................................. +.........................................................................................................#.................................. +......................#...............#............#........................................................................................ +..................................................................................................#......................................... +..........#..................................................................................................#..............#..........#.... +....#...........................#..........................#..............................#................................................. +........................................#............................................#.................................#.........#.......... +...................................................................#...........#..........................#................................. +............................................................................................................................................ +............................................#............................................................................................... +....................#.................................#................................................................................#.... +............................................................................................#............................................... +............................................................................#........#.........................................#............ +...#...................#..........................#...............#......................................................#.................. +..............................#........#.................................................................................................... +................#................................................................................#.......................................#.. +......#..............................................................#...................#.................................................. +.#.........................................#..........#.........#..............#........................#............#...................... +............................................................................................................................................ +...........#...................................#...............................................................#.............#.............. +........................#........#........................................#..........#..................................................#... +....#.....................................................#.................................#......................................#........ +...............................................................#...................................#....................#................... +#.............................................................................#..................................#.............#............ +.............................#..........#.............................#...................................#................................. +........................................................#................................................................................... +.............#........................................................................................................#................#.... +...#.............................................#..................................#......#.....#.......................................... +................................#..............................#............................................................................ +...................#........................................................#............................................................... +#..........................#.........................................................................#......#...........#................... +.......#...........................#.....#..............#.................................................................................#. +......................#.........................#........................................................................................... +.....................................................................................................................#.......#......#....... +.............................................................#....................#...............#......................................... +.........#.................................................................................................................................. +...............................#............#....................#.....#...............#..................#................................. +....#...........#.........#.........................#..............................................................#..................#..... +.....................#.......................................................................#.............................................. +....................................................................................................#....................................... +.....................................#..........#...............................#...........................#..........#..........#.......#. +..........................................................................................#................................................. +.#..........................................#.............................#................................................................. +.................#...........#............................#.............................................#......................#............ +.........#...........................................................#..............#....................................................... +..................................................................................................#.............#.......#................... +.............................................................................#.......................................................#...... +......#.............#...........#..........#........#...........#...........................................#............................... +.........................................................................#.................................................................. +........................................................#...........#...........#................................................#.......... +........................................#....................#..........................................#.............#..................... +..........#...................#................................................................#..........................................#. +..................#.................................................................................#..........#............................ +..........................................................................................#................................................. +..........................................................#...............#................................................................. +............#................................#......................#..........#.........................................#......#........... +..#.......................#..................................................................................#.....#........................ +.................................................#...........................................#.............................................. +.........#........#..................#...........................#.....................#...............#.............................#...... +......................................................................#..........................#.....................#.................... +............................................................................................................................................ +........................#.....................................................................................#............#............#... +..............#............................#.................................#......#....................................................... +........#..........#........................................................................................................................ +............................#............................................#..........................#....................................... +.......................................................#......#.........................................................#......#............ +.........................................................................................#.....#..................#......................... +.......................#................#.......................................#............................#.......................#...... +............................................................................................................................................ +.........#.......................................................................................................................#.......... +...#..........#................................#...........#......#.....................................................................#... +....................................................................................#....................................................... +.............................#.....................................................................................#.....#.................. +...................................#.....................................................#.............#.................................... +.....#.............#................................#......................................................................................# +.............#............................................#...................#.................#.....................#.....#......#........ +#...............................#.........#..........................................#...................................................... +.........................#...............................................#.................................................................. +.................................................................................#......................................................#... +....#...........#..................................#......................................................#................................. +..............................................#.....................#.......................#...........................#................... +..............................#.........................#.............................................#.........#........................... +.........................................#.....................................#...............................................#............ +.#.........#..................................................#..........................#...........................#...................... +............................................................................................................................................ +.........................................................................................................................................#.. +.......#..........................................#.......................#................................................#........#....... +............................................................................................................................................ +.................#.........#.........................................#.........................#.....#......#............................... +............................................#..........#......................#......#...................................................... +....................................#.............................................................................#......................... +...........................................................#................................................................................ +.................................................................................#........#...............#..............................#.. +.......#...........#..............................#......................................................................................... +..#...............................................................................................#.................#............#.......... +..............................................#..........#...............#.................................................................. +..................................#.....#.....................#.......................#...............#......#.............#................ +..........................#................................................................................................................. +....................................................#..................................................................#.................... +...........................................................................#..............#.....#........................................... +#...................#...........................................................#........................................................... +...........................................#....................#....................................................................#...... +.......#.....#........................................#....................................................#................................ +..............................#...................................................................#......................................... +.............................................................................#.......................................#...................... +.....................#....................................................................................................................#. +.................................#....................................#........................#............................................ +......#...........................................#......................................................................................... +...........................................#................................................................................#......#........ +..........#...............#.........................................................#....................................................... +..................#...........................................................#............................................................. +...............................................................#............................................#.......#....................... +....#........#...................................................................................#.......................................... +......................#...................................................#...........#................#.................................... +........#..............................................#...................................#....................#........................... +..................................................#.......................................................................#..........#...... +.#...................................#..........................................................................................#........... +..........................................#........................................#...............#........................................ +..........................#.....#........................................................................................................#.. +..................#...........................#..........#...........................................................#...................... +...................................................#......................#...................................................#............. +.........#................................................................................#................................................. +..............#................................................................#............................................................ +...........................#.........#..............................#...................................#..........#....................#... +..................................................................................................#.............................#........... +..#..............................................#.......................................................................................... +.................#.....................................................#.................#.................................................. +.................................#.........#...................................................#......#.........#........................... +..........#.........................................#.....#......................#.......................................................... +....................#..........................#................#...........................................................#......#........ +#........................#.............#..................................#.................................#............................... diff --git a/start_day.sh b/start_day.sh new file mode 100755 index 0000000..422a006 --- /dev/null +++ b/start_day.sh @@ -0,0 +1,18 @@ +#!/bin/bash + +if [[ -z "$1" ]]; then + echo "start_day.sh [day_number]" + exit 1 +fi + +if [ -d "./day$1" ]; then + echo "Directory ./day$1/ already exists" + exit 2 +fi + +mkdir "./day$1" +echo "package day$1" > "./day$1/day$1.go" +echo "package day$1" > "./day$1/day$1_test.go" +touch "./day$1/input.txt" + +echo "./day$1 created. Ready to start!" diff --git a/utils/utils.go b/utils/utils.go index 69f46ff..071e6b8 100644 --- a/utils/utils.go +++ b/utils/utils.go @@ -111,3 +111,11 @@ func Fold[A any, T any](a A, s []T, f func(A, T) A) A { } return a } + +func AbsInt(x int) int { + if x >= 0 { + return x + } else { + return -x + } +}