Compare commits

...

2 Commits

Author SHA1 Message Date
David 9244b2e178 day 11 ended up being a _lot_ of code 2020-12-11 21:33:00 -05:00
David 56cd171588 day ten, part one works, part two doesn't 2020-12-11 17:30:31 -05:00
2 changed files with 415 additions and 0 deletions

117
10/main.go Normal file
View File

@ -0,0 +1,117 @@
package main
import (
"bufio"
"fmt"
"os"
"sort"
"strconv"
)
func main() {
partOne()
partTwo()
}
// Find a chain that uses all of your adapters to connect the charging outlet to your device's built-in adapter
// and count the joltage differences between the charging outlet, the adapters, and your device.
// What is the number of 1-jolt differences multiplied by the number of 3-jolt differences?
func partOne() {
f, _ := os.Open("input")
reader := bufio.NewReader(f)
scanner := bufio.NewScanner(reader)
// wall
adapters := []int{0}
// load
for scanner.Scan() {
line := scanner.Text()
i, _ := strconv.Atoi(line)
adapters = append(adapters, i)
}
// sort
sort.Slice(adapters, func(i, j int) bool {
return adapters[i] < adapters[j]
})
// device
adapters = append(adapters, adapters[len(adapters)-1]+3)
one := 0
three := 0
// count gaps
for i, j := range adapters {
if i < len(adapters)-1 {
if adapters[i+1]-j == 3 {
three = three + 1
} else if adapters[i+1]-j == 1 {
one = one + 1
}
}
}
fmt.Println(three * one)
}
// You glance back down at your bag and try to remember why you brought so many adapters; there must be more than a trillion valid ways to arrange them!
// Surely, there must be an efficient way to count the arrangements.
// What is the total number of distinct ways you can arrange the adapters to connect the charging outlet to your device?
func partTwo() {
f, _ := os.Open("input")
reader := bufio.NewReader(f)
scanner := bufio.NewScanner(reader)
// wall
adapters := []int{0}
for scanner.Scan() {
line := scanner.Text()
i, _ := strconv.Atoi(line)
adapters = append(adapters, i)
}
// sort
sort.Slice(adapters, func(i, j int) bool {
return adapters[i] < adapters[j]
})
// device
adapters = append(adapters, adapters[len(adapters)-1]+3)
combinations := 1
ones := 0
three := 0
// count gaps
for i, j := range adapters {
if i < len(adapters)-1 {
if adapters[i+1]-j == 1 {
// small steps...
ones = ones + 1
} else if adapters[i+1]-j == 3 {
combinations = combinations + 1
if ones == 2 {
combinations = combinations * 1
}
if ones == 3 {
combinations = combinations * 2
}
if ones == 4 {
combinations = combinations * 4
}
if ones == 5 {
combinations = combinations * 7
}
ones = 0
three = three + 1
}
}
}
fmt.Println(adapters, combinations)
}

298
11/main.go Normal file
View File

@ -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
}
}