package main import ( "bufio" "fmt" "log" "os" "strconv" "strings" "time" ) const ( MaxInt = int(^uint(0) >> 1) MinInt = -MaxInt - 1 ClearScreen = "\033[H\033[2J" ) func main() { input := stdinToStringSlice() part1(input) //part2(input) } var scan [1000][1000]byte var minX, maxX int = MaxInt, MinInt var minY, maxY int = MaxInt, MinInt func part1(input []string) { for _, v := range input { pts := strings.Split(v, ", ") fst := strings.Split(pts[0], "=") scd := strings.Split(pts[1], "=") scdRange := strings.Split(scd[1], "..") var x, y int if fst[0] == "x" { x = Atoi(fst[1]) for y = Atoi(scdRange[0]); y <= Atoi(scdRange[1]); y++ { minmax(x, y) scan[x][y] = '#' } } else if fst[0] == "y" { y = Atoi(fst[1]) for x := Atoi(scdRange[0]); x <= Atoi(scdRange[1]); x++ { minmax(x, y) scan[x][y] = '#' } } } printScan() // The water starts at 500, 0 fillDown(500, 0) } func part2(input []string) { } // The 'fill' functions return the x, y that was filled // or MinInt, MinInt, if x, y can't be filled // fillDown will check down, then left, then right func fillDown(x, y int) (int, int) { fx, fy := fillSpot(x, y) if !gud(fx, fy) { return fx, fy } // Try to fill the spot below it dx, dy := fillDown(x, y+1) if dx == MinInt && dy == MinInt { // We couldn't go down lx, ly := fillLeft(x-1, y) // left? rx, ry := fillRight(x+1, y) // right? if !gud(lx, ly) || !gud(rx, ry) { return MinInt, MinInt // Off to infinity } if ly == y && ry == y { scan[lx][y] = '~' scan[rx][y] = '~' } } return dx, dy } func fillLeft(x, y int) (int, int) { fx, fy := fillSpot(x, y) if !gud(fx, fy) { return fx, fy } // This spot can be filled, try to go down rx, ry := fillDown(fx, fy+1) if gud(rx, ry) { return rx, ry } // Couldn't go down, try to go left rx, ry = fillLeft(fx-1, y) if gud(rx, ry) { return rx, ry } return x, y } func fillRight(x, y int) (int, int) { fx, fy := fillSpot(x, y) if !gud(fx, fy) { return fx, fy } // This spot can be filled, try to go down rx, ry := fillDown(fx, fy+1) if gud(rx, ry) { return rx, ry } // Couldn't go down, try to go left rx, ry = fillRight(fx+1, y) if gud(rx, ry) { return rx, ry } return x, y } func fillSpot(x, y int) (int, int) { time.Sleep(time.Millisecond * 250) printScan() if y > maxY || !canFill(x, y) { return MinInt, MinInt } scan[x][y] = '|' return x, y } func gud(x, y int) bool { return x != MinInt && y != MinInt } func printScan() { fmt.Print(ClearScreen) for y := minY; y <= maxY; y++ { for x := minX; x <= maxX; x++ { if scan[x][y] == 0 { fmt.Print(".") } else { fmt.Print(string(scan[x][y])) } } fmt.Println() } } func canFill(x, y int) bool { return scan[x][y] == 0 || scan[x][y] == '|' } func minmax(x, y int) { if x < minX { minX = x } if x > maxX { maxX = x } if y < minY { minY = y } if y > maxY { maxY = y } } func stdinToStringSlice() []string { var input []string scanner := bufio.NewScanner(os.Stdin) for scanner.Scan() { input = append(input, scanner.Text()) } return input } func Atoi(i string) int { var ret int var err error if ret, err = strconv.Atoi(i); err != nil { log.Fatal("Invalid Atoi: " + i) } return ret }