From 9244b2e178615c2b569f4d2561bc85778f986a71 Mon Sep 17 00:00:00 2001 From: David Ashby Date: Fri, 11 Dec 2020 21:33:00 -0500 Subject: [PATCH] day 11 ended up being a _lot_ of code --- 11/main.go | 298 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 298 insertions(+) create mode 100644 11/main.go diff --git a/11/main.go b/11/main.go new file mode 100644 index 0000000..2fb419b --- /dev/null +++ b/11/main.go @@ -0,0 +1,298 @@ +package main + +import ( + "bufio" + "fmt" + "os" +) + +func main() { + partOne() + partTwo() +} + +type cell struct { + taken int // 1: someone there; 0: empty + seat bool // t: seat available; f: open floor +} + +type waitingRoom struct { + seats [][]cell + maxCol int + maxRow int +} + +func (w *waitingRoom) parseRow(s string) { + row := []cell{} + + for _, r := range s { + switch { + case r == 'L': + row = append(row, cell{taken: 0, seat: true}) + case r == '.': + row = append(row, cell{taken: 0, seat: false}) + } + } + w.seats = append(w.seats, row) +} + +func (w *waitingRoom) countNeighborsPartOne(row, col int) int { + c := 0 + if row-1 > -1 { + c = c + w.seats[row-1][col].taken // north + if col-1 > -1 { + c = c + w.seats[row-1][col-1].taken // northwest + } + if col+1 < w.maxCol { + c = c + w.seats[row-1][col+1].taken // northheast + } + } + if row+1 < w.maxRow { + c = c + w.seats[row+1][col].taken // south + if col+1 < w.maxCol { + c = c + w.seats[row+1][col+1].taken // southeast + } + if col-1 > -1 { + c = c + w.seats[row+1][col-1].taken // southwest + } + } + if col-1 > -1 { + c = c + w.seats[row][col-1].taken // west + } + if col+1 < w.maxCol { + c = c + w.seats[row][col+1].taken // east + } + return c +} + +func (w *waitingRoom) makeNextStepPartOne() *waitingRoom { + newRoom := &waitingRoom{ + seats: make([][]cell, w.maxRow), + maxCol: w.maxCol, + maxRow: w.maxRow, + } + + for r := range w.seats { + newRoom.seats[r] = make([]cell, newRoom.maxCol) + for c := range w.seats[r] { + if w.seats[r][c].seat && w.seats[r][c].taken == 0 && w.countNeighborsPartOne(r, c) == 0 { + newRoom.seats[r][c].seat = w.seats[r][c].seat + newRoom.seats[r][c].taken = 1 + } else if w.seats[r][c].seat && w.seats[r][c].taken == 1 && w.countNeighborsPartOne(r, c) >= 4 { + newRoom.seats[r][c].seat = w.seats[r][c].seat + newRoom.seats[r][c].taken = 0 + } else { + newRoom.seats[r][c].seat = w.seats[r][c].seat + newRoom.seats[r][c].taken = w.seats[r][c].taken + } + } + } + + return newRoom +} + +func (w *waitingRoom) countNeighborsPartTwo(row, col int) int { + c := 0 + trow := row + tcol := col + + // south + for trow < w.maxRow-1 { + trow = trow + 1 + if w.seats[trow][col].seat { + c = c + w.seats[trow][col].taken + break + } + } + trow = row + + // north + for trow > 0 { + trow = trow - 1 + if w.seats[trow][col].seat { + c = c + w.seats[trow][col].taken + break + } + } + trow = row + + // west + for tcol > 0 { + tcol = tcol - 1 + if w.seats[row][tcol].seat { + c = c + w.seats[row][tcol].taken + break + } + } + tcol = col + + // east + for tcol < w.maxCol-1 { + tcol = tcol + 1 + if w.seats[row][tcol].seat { + c = c + w.seats[row][tcol].taken + break + } + } + tcol = col + + // southeast + for trow < w.maxRow-1 && tcol < w.maxCol-1 { + trow = trow + 1 + tcol = tcol + 1 + if w.seats[trow][tcol].seat { + c = c + w.seats[trow][tcol].taken + break + } + } + trow = row + tcol = col + + // southwest + for trow < w.maxRow-1 && tcol > 0 { + trow = trow + 1 + tcol = tcol - 1 + if w.seats[trow][tcol].seat { + c = c + w.seats[trow][tcol].taken + break + } + } + trow = row + tcol = col + + // northeast + for trow > 0 && tcol < w.maxCol-1 { + trow = trow - 1 + tcol = tcol + 1 + if w.seats[trow][tcol].seat { + c = c + w.seats[trow][tcol].taken + break + } + } + trow = row + tcol = col + + // northwest + for trow > 0 && tcol > 0 { + trow = trow - 1 + tcol = tcol - 1 + if w.seats[trow][tcol].seat { + c = c + w.seats[trow][tcol].taken + break + } + } + + return c +} + +func (w *waitingRoom) makeNextStepPartTwo() *waitingRoom { + newRoom := &waitingRoom{ + seats: make([][]cell, w.maxRow), + maxCol: w.maxCol, + maxRow: w.maxRow, + } + + for r := range w.seats { + newRoom.seats[r] = make([]cell, newRoom.maxCol) + for c := range w.seats[r] { + if w.seats[r][c].seat && w.seats[r][c].taken == 0 && w.countNeighborsPartTwo(r, c) == 0 { + newRoom.seats[r][c].seat = w.seats[r][c].seat + newRoom.seats[r][c].taken = 1 + } else if w.seats[r][c].seat && w.seats[r][c].taken == 1 && w.countNeighborsPartTwo(r, c) >= 5 { + newRoom.seats[r][c].seat = w.seats[r][c].seat + newRoom.seats[r][c].taken = 0 + } else { + newRoom.seats[r][c].seat = w.seats[r][c].seat + newRoom.seats[r][c].taken = w.seats[r][c].taken + } + } + } + + return newRoom +} + +func (w *waitingRoom) countFilledSeats() int { + count := 0 + for r := range w.seats { + for c := range w.seats[r] { + count = count + w.seats[r][c].taken + } + } + return count +} + +func (w *waitingRoom) print() { + for r := range w.seats { + s := "" + for c := range w.seats[r] { + if !w.seats[r][c].seat { + s = s + "." + } else if w.seats[r][c].taken == 0 { + s = s + "L" + } else if w.seats[r][c].taken == 1 { + s = s + "#" + } + } + fmt.Println(s) + } +} + +func checkStasis(old, new *waitingRoom) bool { + for r := range old.seats { + for c := range old.seats[r] { + if old.seats[r][c].seat && old.seats[r][c].taken != new.seats[r][c].taken { + return false + } + } + } + return true +} + +func partOne() { + f, _ := os.Open("input") + reader := bufio.NewReader(f) + scanner := bufio.NewScanner(reader) + + oldRoom := &waitingRoom{} + + for scanner.Scan() { + line := scanner.Text() + oldRoom.parseRow(line) + } + + oldRoom.maxCol = len(oldRoom.seats[0]) + oldRoom.maxRow = len(oldRoom.seats) + + for { + newRoom := oldRoom.makeNextStepPartOne() + if checkStasis(newRoom, oldRoom) { + fmt.Println(newRoom.countFilledSeats()) + return + } + oldRoom = newRoom + } +} + +func partTwo() { + f, _ := os.Open("input") + reader := bufio.NewReader(f) + scanner := bufio.NewScanner(reader) + oldRoom := &waitingRoom{} + + for scanner.Scan() { + line := scanner.Text() + oldRoom.parseRow(line) + } + + oldRoom.maxCol = len(oldRoom.seats[0]) + oldRoom.maxRow = len(oldRoom.seats) + + for { + newRoom := oldRoom.makeNextStepPartTwo() + if checkStasis(newRoom, oldRoom) { + fmt.Println(newRoom.countFilledSeats()) + return + } + oldRoom = newRoom + } +}