Day 11 (Golang)
This commit is contained in:
parent
fe3aee042f
commit
7b435c3e05
6 changed files with 299 additions and 26 deletions
52
.github/README.md
vendored
52
.github/README.md
vendored
|
@ -14,33 +14,33 @@ Puzzle inputs and descriptions are not included in this repository. You'll have
|
|||
|
||||
<!-- PARSE START -->
|
||||
|
||||
| Day | | Python | Go |
|
||||
| --------------------------- | ------------------------------ | ------------------------------------- | --------------------------------- |
|
||||
| [1](/01-reportRepair) | ![Completed][check] | [Link](/01-reportRepair/python) | [Link](/01-reportRepair/go) |
|
||||
| [2](/02-passwordPhilosophy) | ![Completed][check] | [Link](/02-passwordPhilosophy/python) | [Link](/02-passwordPhilosophy/go) |
|
||||
| [3](/03-tobogganTrajectory) | ![Completed][check] | [Link](/03-tobogganTrajectory/python) | [Link](/03-tobogganTrajectory/go) |
|
||||
| [4](/04-passportProcessing) | ![Completed][check] | [Link](/04-passportProcessing/python) | [Link](/04-passportProcessing/go) |
|
||||
| [5](/05-binaryBoarding) | ![Completed][check] | [Link](/05-binaryBoarding/python) | [Link](/05-binaryBoarding/go) |
|
||||
| [6](/06-customCustoms) | ![Completed][check] | [Link](/06-customCustoms/python) | [Link](/06-customCustoms/go) |
|
||||
| [7](/07-handyHaversacks) | ![Completed][check] | [Link](/07-handyHaversacks/python) | [Link](/07-handyHaversacks/go) |
|
||||
| [8](/08-handheldHalting) | ![Completed][check] | [Link](/08-handheldHalting/python) | [Link](/08-handheldHalting/go) |
|
||||
| [9](/09-encodingError) | ![Completed][check] | [Link](/09-encodingError/python) | [Link](/09-encodingError/go) |
|
||||
| [10](/10-adapterArray) | ![Completed][check] | [Link](/10-adapterArray/python) | [Link](/10-adapterArray/go) |
|
||||
| [11](/11-seatingSystem) \* | ![Partially complete][partial] | [Link](/11-seatingSystem/python) | |
|
||||
| Day | | Python | Go |
|
||||
| --------------------------- | ------------------- | ------------------------------------- | --------------------------------- |
|
||||
| [1](/01-reportRepair) | ![Completed][check] | [Link](/01-reportRepair/python) | [Link](/01-reportRepair/go) |
|
||||
| [2](/02-passwordPhilosophy) | ![Completed][check] | [Link](/02-passwordPhilosophy/python) | [Link](/02-passwordPhilosophy/go) |
|
||||
| [3](/03-tobogganTrajectory) | ![Completed][check] | [Link](/03-tobogganTrajectory/python) | [Link](/03-tobogganTrajectory/go) |
|
||||
| [4](/04-passportProcessing) | ![Completed][check] | [Link](/04-passportProcessing/python) | [Link](/04-passportProcessing/go) |
|
||||
| [5](/05-binaryBoarding) | ![Completed][check] | [Link](/05-binaryBoarding/python) | [Link](/05-binaryBoarding/go) |
|
||||
| [6](/06-customCustoms) | ![Completed][check] | [Link](/06-customCustoms/python) | [Link](/06-customCustoms/go) |
|
||||
| [7](/07-handyHaversacks) | ![Completed][check] | [Link](/07-handyHaversacks/python) | [Link](/07-handyHaversacks/go) |
|
||||
| [8](/08-handheldHalting) | ![Completed][check] | [Link](/08-handheldHalting/python) | [Link](/08-handheldHalting/go) |
|
||||
| [9](/09-encodingError) | ![Completed][check] | [Link](/09-encodingError/python) | [Link](/09-encodingError/go) |
|
||||
| [10](/10-adapterArray) | ![Completed][check] | [Link](/10-adapterArray/python) | [Link](/10-adapterArray/go) |
|
||||
| [11](/11-seatingSystem) \* | ![Completed][check] | [Link](/11-seatingSystem/python) | [Link](/11-seatingSystem/python) |
|
||||
| [12](/12-rainRisk) | ![Partially complete][partial] | [Link](/12-rainRisk/python) | |
|
||||
| 13 | | | |
|
||||
| 14 | | | |
|
||||
| 15 | | | |
|
||||
| 16 | | | |
|
||||
| 17 | | | |
|
||||
| 18 | | | |
|
||||
| 19 | | | |
|
||||
| 20 | | | |
|
||||
| 21 | | | |
|
||||
| 22 | | | |
|
||||
| 23 | | | |
|
||||
| 24 | | | |
|
||||
| 25 | | | |
|
||||
| 13 | | | |
|
||||
| 14 | | | |
|
||||
| 15 | | | |
|
||||
| 16 | | | |
|
||||
| 17 | | | |
|
||||
| 18 | | | |
|
||||
| 19 | | | |
|
||||
| 20 | | | |
|
||||
| 21 | | | |
|
||||
| 22 | | | |
|
||||
| 23 | | | |
|
||||
| 24 | | | |
|
||||
| 25 | | | |
|
||||
|
||||
<!-- PARSE END -->
|
||||
|
||||
|
|
|
@ -24,6 +24,18 @@ Test cases
|
|||
1.1 pass
|
||||
2.1 pass
|
||||
|
||||
Answers
|
||||
Part 1: 2283
|
||||
Part 2: 2054
|
||||
|
||||
❯ go run .\go\
|
||||
AoC 2020: day 11 - Seating System
|
||||
Go go1.15.2
|
||||
|
||||
Test cases
|
||||
1.1 pass
|
||||
2.1 pass
|
||||
|
||||
Answers
|
||||
Part 1: 2283
|
||||
Part 2: 2054
|
||||
|
|
85
11-seatingSystem/go/challenge/common.go
Normal file
85
11-seatingSystem/go/challenge/common.go
Normal file
|
@ -0,0 +1,85 @@
|
|||
package challenge
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
"strings"
|
||||
)
|
||||
|
||||
const (
|
||||
openSeat = 'L'
|
||||
filledSeat = '#'
|
||||
noSeat = '.'
|
||||
)
|
||||
|
||||
var (
|
||||
lookupPositions = [][2]int{
|
||||
{0, 1},
|
||||
{1, 1},
|
||||
{1, 0},
|
||||
{1, -1},
|
||||
{0, -1},
|
||||
{-1, -1},
|
||||
{-1, 0},
|
||||
{-1, 1},
|
||||
}
|
||||
)
|
||||
|
||||
func parse(instr string) (o [][]rune) {
|
||||
for _, x := range strings.Split(strings.TrimSpace(instr), "\n") {
|
||||
o = append(o, []rune(x))
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func iterate(currentHall [][]rune, neighbourCounter func([][]rune, [2]int, [2]int) int, getNewState func(int, rune) rune) [][]rune {
|
||||
// Copy hall
|
||||
nextHall := make([][]rune, len(currentHall))
|
||||
for i, lc := range currentHall {
|
||||
nextHall[i] = make([]rune, len(lc))
|
||||
copy(nextHall[i], lc)
|
||||
}
|
||||
|
||||
hallSize := [2]int{len(nextHall[0]), len(nextHall)}
|
||||
|
||||
// iterate each chair space
|
||||
for col := 0; col < hallSize[0]; col += 1 {
|
||||
for row := 0; row < hallSize[1]; row += 1 {
|
||||
currentPos := currentHall[row][col]
|
||||
|
||||
// It it's the floor, there's nothing we can do with this spot
|
||||
if currentPos == noSeat {
|
||||
continue
|
||||
}
|
||||
|
||||
// Count number of adjacent seats
|
||||
numNeighbours := neighbourCounter(currentHall, [2]int{row, col}, hallSize)
|
||||
|
||||
// Execute rules on copied list based on that count
|
||||
nextHall[row][col] = getNewState(numNeighbours, nextHall[row][col])
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
return nextHall
|
||||
}
|
||||
|
||||
func run(currentState [][]rune, neighbourCounter func([][]rune, [2]int, [2]int) int, getNewState func(int, rune) rune) int {
|
||||
lastState := make([][]rune, 0)
|
||||
|
||||
for !reflect.DeepEqual(currentState, lastState) {
|
||||
lastState = currentState
|
||||
currentState = iterate(currentState, neighbourCounter, getNewState)
|
||||
}
|
||||
|
||||
totalOccupied := 0
|
||||
for _, a := range currentState {
|
||||
for _, b := range a {
|
||||
if b == filledSeat {
|
||||
totalOccupied += 1
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return totalOccupied
|
||||
|
||||
}
|
33
11-seatingSystem/go/challenge/partOne.go
Normal file
33
11-seatingSystem/go/challenge/partOne.go
Normal file
|
@ -0,0 +1,33 @@
|
|||
package challenge
|
||||
|
||||
|
||||
func getNewStateOne(numNeighbours int, oldState rune) rune {
|
||||
if numNeighbours == 0 {
|
||||
return filledSeat
|
||||
} else if numNeighbours >= 4 && oldState == filledSeat {
|
||||
return openSeat
|
||||
}
|
||||
return oldState
|
||||
}
|
||||
|
||||
func countNeighboursOne(hall [][]rune, currentPos [2]int, hallSize [2]int) (numNeighbours int) {
|
||||
row := currentPos[0]
|
||||
col := currentPos[1]
|
||||
|
||||
for _, position := range lookupPositions {
|
||||
test_x_pos := position[0] + col
|
||||
test_y_pos := position[1] + row
|
||||
|
||||
if 0 <= test_x_pos && test_x_pos < hallSize[0] && 0 <= test_y_pos && test_y_pos < hallSize[1] {
|
||||
if hall[test_y_pos][test_x_pos] == filledSeat {
|
||||
numNeighbours += 1
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
func PartOne(instr string) int {
|
||||
return run(parse(instr), countNeighboursOne, getNewStateOne)
|
||||
}
|
43
11-seatingSystem/go/challenge/partTwo.go
Normal file
43
11-seatingSystem/go/challenge/partTwo.go
Normal file
|
@ -0,0 +1,43 @@
|
|||
package challenge
|
||||
|
||||
func getNewStateTwo(numNeighbours int, oldState rune) rune {
|
||||
if numNeighbours == 0 {
|
||||
return filledSeat
|
||||
} else if numNeighbours >= 5 && oldState == filledSeat {
|
||||
return openSeat
|
||||
}
|
||||
return oldState
|
||||
}
|
||||
|
||||
func countNeighboursTwo(hall [][]rune, currentPos [2]int, hallSize [2]int) (numNeighbours int) {
|
||||
row := currentPos[0]
|
||||
col := currentPos[1]
|
||||
|
||||
for _, position := range lookupPositions {
|
||||
test_x_pos := position[0] + col
|
||||
test_y_pos := position[1] + row
|
||||
|
||||
for 0 <= test_x_pos && test_x_pos < hallSize[0] && 0 <= test_y_pos && test_y_pos < hallSize[1] {
|
||||
|
||||
testLocation := hall[test_y_pos][test_x_pos]
|
||||
|
||||
if testLocation == filledSeat {
|
||||
numNeighbours += 1
|
||||
}
|
||||
|
||||
if testLocation == openSeat || testLocation == filledSeat {
|
||||
break
|
||||
}
|
||||
|
||||
test_x_pos += position[0]
|
||||
test_y_pos += position[1]
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
func PartTwo(instr string) int {
|
||||
return run(parse(instr), countNeighboursTwo, getNewStateTwo)
|
||||
}
|
100
11-seatingSystem/go/main.go
Normal file
100
11-seatingSystem/go/main.go
Normal file
|
@ -0,0 +1,100 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"adventOfCode/11-seatingSystem/go/challenge"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"runtime"
|
||||
"strconv"
|
||||
|
||||
"github.com/fatih/color"
|
||||
)
|
||||
|
||||
func main() {
|
||||
var infoStruct info
|
||||
{
|
||||
inb, err := ioutil.ReadFile("info.json")
|
||||
if err != nil {
|
||||
fmt.Println("Error: could not open info.json")
|
||||
os.Exit(-1)
|
||||
}
|
||||
err = json.Unmarshal(inb, &infoStruct)
|
||||
if err != nil {
|
||||
fmt.Println("Error: could not parse info.json")
|
||||
os.Exit(-1)
|
||||
}
|
||||
}
|
||||
|
||||
var (
|
||||
year = infoStruct.Year
|
||||
day = infoStruct.Day
|
||||
title = infoStruct.Title
|
||||
)
|
||||
|
||||
fmt.Fprintf(color.Output, "%s: day %s - %s\n", color.YellowString("AoC "+year), color.BlueString(day), title)
|
||||
fmt.Fprintf(color.Output, "Go %s\n\n", color.BlueString(runtime.Version()))
|
||||
|
||||
var challengeInput string
|
||||
{
|
||||
inb, err := ioutil.ReadFile("input.txt")
|
||||
if err != nil {
|
||||
fmt.Println("Error: could not open input.txt")
|
||||
os.Exit(-1)
|
||||
}
|
||||
challengeInput = string(inb)
|
||||
}
|
||||
|
||||
runTests(infoStruct)
|
||||
|
||||
fmt.Println("Answers")
|
||||
fmt.Fprintf(color.Output, "Part %s: %s\n", color.BlueString("1"), color.BlueString(strconv.Itoa(challenge.PartOne(challengeInput))))
|
||||
fmt.Fprintf(color.Output, "Part %s: %s\n", color.BlueString("2"), color.BlueString(strconv.Itoa(challenge.PartTwo(challengeInput))))
|
||||
|
||||
}
|
||||
|
||||
type tc struct {
|
||||
Input string `json:"input"`
|
||||
Expected int `json:"expected"`
|
||||
}
|
||||
|
||||
type info struct {
|
||||
Year string `json:"year"`
|
||||
Day string `json:"day"`
|
||||
Title string `json:"title"`
|
||||
TestCases struct {
|
||||
One []tc `json:"one"`
|
||||
Two []tc `json:"two"`
|
||||
} `json:"testCases"`
|
||||
}
|
||||
|
||||
func runTests(infoStruct info) {
|
||||
|
||||
if len(infoStruct.TestCases.One) == 0 && len(infoStruct.TestCases.Two) == 0 {
|
||||
fmt.Println("Info: no test cases specified. Skipping tests")
|
||||
fmt.Println()
|
||||
return
|
||||
}
|
||||
|
||||
fmt.Println("Test cases")
|
||||
|
||||
rt := func(tcs []tc, f func(string) int, n string) {
|
||||
for i, tc := range tcs {
|
||||
fmt.Fprintf(color.Output, "%s ", color.BlueString(n+"."+strconv.Itoa(i+1)))
|
||||
result := f(tc.Input)
|
||||
if result == tc.Expected {
|
||||
fmt.Fprintf(color.Output, "%s", color.GreenString("pass"))
|
||||
} else {
|
||||
fmt.Fprintf(color.Output, "%s (got %s, expected %s)", color.RedString("fail"), color.BlueString(strconv.Itoa(result)), color.BlueString(strconv.Itoa(tc.Expected)))
|
||||
}
|
||||
fmt.Println()
|
||||
}
|
||||
}
|
||||
|
||||
rt(infoStruct.TestCases.One, challenge.PartOne, "1")
|
||||
rt(infoStruct.TestCases.Two, challenge.PartTwo, "2")
|
||||
|
||||
fmt.Println()
|
||||
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue