diff --git a/day4/example.txt b/day4/example.txt new file mode 100644 index 0000000..8209399 --- /dev/null +++ b/day4/example.txt @@ -0,0 +1,10 @@ +..@@.@@@@. +@@@.@.@.@@ +@@@@@.@.@@ +@.@@@@..@. +@@.@@@@.@@ +.@@@@@@@.@ +.@.@.@.@@@ +@.@@@.@@@@ +.@@@@@@@@. +@.@.@@@.@. diff --git a/day4/main.go b/day4/main.go new file mode 100644 index 0000000..7d063bb --- /dev/null +++ b/day4/main.go @@ -0,0 +1,100 @@ +package main + +import ( + "bufio" + "fmt" + "io" + "log" + "os" +) + +func main() { + f := os.Stdin + if len(os.Args) > 1 && os.Args[1] != "-" { + var err error + f, err = os.Open(os.Args[1]) + if err != nil { + log.Fatal(err) + } + defer f.Close() + } + + grid, err := readDiagram(f) + if err != nil { + log.Fatal(err) + } + + var total int + for i := 1; ; i++ { + removed := removePapers(grid) + total += removed + fmt.Printf("%2d: removed %d\n", i, removed) + if removed == 0 { + break + } + } + fmt.Printf("total %d\n", total) +} + +func removePapers(grid [][]bool) (removed int) { + type position struct { + x, y int + } + var toRemove []position + for y, row := range grid { + for x, b := range row { + if !b { + continue + } + if countAdjacent(grid, x, y) < 4 { + toRemove = append(toRemove, position{ + x: x, + y: y, + }) + } + } + } + for _, pos := range toRemove { + grid[pos.y][pos.x] = false + } + return len(toRemove) +} + +func countAdjacent(grid [][]bool, x, y int) int { + var count int + xFrom := max(x-1, 0) + yFrom := max(y-1, 0) + yTo := min(y+1, len(grid)-1) + + for yi := yFrom; yi <= yTo; yi++ { + xTo := min(x+1, len(grid[yi])-1) + + for xi := xFrom; xi <= xTo; xi++ { + if xi == x && yi == y { + continue + } + if grid[yi][xi] { + count++ + } + } + } + return count +} + +func readDiagram(r io.Reader) ([][]bool, error) { + var grid [][]bool + sc := bufio.NewScanner(r) + for sc.Scan() { + var row []bool + for _, b := range sc.Bytes() { + switch b { + case '@', '.': + row = append(row, b == '@') + default: + return nil, fmt.Errorf("read diagram: unexpected character: %q", sc.Bytes()) + } + } + grid = append(grid, row) + } + return grid, sc.Err() +}