diff --git a/09/main.go b/09/main.go new file mode 100644 index 0000000..0f8d55d --- /dev/null +++ b/09/main.go @@ -0,0 +1,140 @@ +package main + +import ( + "bufio" + "fmt" + "os" + "strconv" + "strings" + "time" +) + +func mustAtoi(line string) int { + i, _ := strconv.Atoi(line) + return i +} + +func main() { + start := time.Now() + partOne() + duration := time.Since(start) + partTwo() + duration2 := time.Since(start) + fmt.Printf("p1: %s, p2: %s\n", duration, duration2-duration) +} + +func makeScanner(test bool) *bufio.Scanner { + var f *os.File + if test { + f, _ = os.Open("inputs/testinput") + } else { + f, _ = os.Open("inputs/input") + } + reader := bufio.NewReader(f) + return bufio.NewScanner(reader) +} + +type floor []int + +func partOne() { + scanner := makeScanner(false) + width := 100 + height := 100 + + caveFloor := make([]int, width*height) + i := 0 + for scanner.Scan() { + row := strings.Split(scanner.Text(), "") + for j, v := range row { + caveFloor[j+(width*i)] = mustAtoi(v) + } + i++ + } + // find low points + points := 0 + for row := 0; row < i; row++ { + for col := 0; col < width; col++ { + islow := 0 + curr := caveFloor[col+(width*row)] + if col == 0 || curr < caveFloor[(col-1)+(width*row)] { // check left edge + islow++ + } + if col+1 == width || curr < caveFloor[(col+1)+(width*row)] { // check right edge + islow++ + } + if row == 0 || curr < caveFloor[col+(width*(row-1))] { // top + islow++ + } + if row+1 == i || curr < caveFloor[col+(width*(row+1))] { // bottom + islow++ + } + if islow == 4 { + points += curr + 1 + } + } + } + fmt.Println(points) +} + +func downhill(caveFloor []int, width int, col, row int) (int, int) { + curr := caveFloor[col+(width*row)] + nextcol := col + nextrow := row + if col > 0 && curr > caveFloor[(col-1)+(width*row)] { // check left edge + nextcol = (col - 1) + nextrow = row + } + if col < width-1 && curr > caveFloor[(col+1)+(width*row)] { // check right edge + nextcol = (col + 1) + nextrow = row + } + if row > 0 && curr > caveFloor[col+(width*(row-1))] { // top + nextcol = col + nextrow = row - 1 + } + if col+(width*(row+1)) < len(caveFloor) && curr > caveFloor[col+(width*(row+1))] { // bottom + nextcol = col + nextrow = row + 1 + } + if nextcol == col && nextrow == row { // found our low point + return col, row + } + return downhill(caveFloor, width, nextcol, nextrow) +} + +func partTwo() { + scanner := makeScanner(false) + width := 100 + height := 100 + + caveFloor := make([]int, width*height) + i := 0 + for scanner.Scan() { + row := strings.Split(scanner.Text(), "") + for j, v := range row { + caveFloor[j+(width*i)] = mustAtoi(v) + } + i++ + } + + basins := map[int]int{} // map from low-point location to size of basin + for row := 0; row < height; row++ { + for col := 0; col < width; col++ { + if caveFloor[col+row*width] < 9 { + lowcol, lowrow := downhill(caveFloor, width, col, row) + basins[lowcol+lowrow*width]++ + } + } + } + one, two, three := 0, 0, 0 + for _, v := range basins { + if v >= one { + one, two, three = v, one, two + } else if v >= two { + two, three = v, two + } else if v >= three { + three = v + } + } + fmt.Println(one * two * three) +} diff --git a/main.go.tmpl b/main.go.tmpl index 5173fd4..191337d 100644 --- a/main.go.tmpl +++ b/main.go.tmpl @@ -4,9 +4,15 @@ import ( "bufio" "fmt" "os" + "strconv" "time" ) +func mustAtoi(line string) int { + i, _ := strconv.Atoi(line) + return i +} + func main() { start := time.Now() partOne()