198 lines
3.1 KiB
Go
198 lines
3.1 KiB
Go
package main
|
|
|
|
import (
|
|
"bufio"
|
|
"fmt"
|
|
"log"
|
|
"os"
|
|
"strconv"
|
|
"strings"
|
|
"time"
|
|
)
|
|
|
|
const (
|
|
MAX_INT = int(^uint(0) >> 1)
|
|
MIN_INT = -MAX_INT - 1
|
|
CLEAR_SCREEN = "\033[H\033[2J"
|
|
DEBUG = true
|
|
SLOW_IT_DOWN = true
|
|
|
|
FLOW_NO = iota
|
|
FLOW_D
|
|
FLOW_LR
|
|
FLOW_L
|
|
FLOW_R
|
|
FLOW_ERR
|
|
)
|
|
|
|
func main() {
|
|
input := stdinToStringSlice()
|
|
part1(input)
|
|
//part2(input)
|
|
}
|
|
|
|
var scan [2000][2000]byte
|
|
var minX, maxX int = MAX_INT, MIN_INT
|
|
var minY, maxY int = MAX_INT, MIN_INT
|
|
|
|
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++ {
|
|
if y < 50 && x > 450 && x < 550 {
|
|
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++ {
|
|
if y < 50 && x > 450 && x < 550 {
|
|
minmax(x, y)
|
|
scan[x][y] = '#'
|
|
}
|
|
}
|
|
}
|
|
}
|
|
// The water starts at 500, 0
|
|
for {
|
|
printScan()
|
|
if SLOW_IT_DOWN {
|
|
time.Sleep(time.Millisecond * 250)
|
|
}
|
|
if !fillSpot(500, 1) {
|
|
break
|
|
}
|
|
}
|
|
printScan()
|
|
}
|
|
|
|
func part2(input []string) {
|
|
}
|
|
|
|
func fillSpot(x, y int) bool {
|
|
if y > maxY {
|
|
return false
|
|
} else if !canFill(x, y) {
|
|
return false
|
|
}
|
|
|
|
if scan[x][y] == 0 {
|
|
scan[x][y] = '|'
|
|
return true
|
|
}
|
|
|
|
if canFill(x, y+1) {
|
|
return fillSpot(x, y+1)
|
|
} else if canFill(x-1, y) && canFill(x+1, y) {
|
|
return fillLeft(x-1, y) || fillRight(x+1, y)
|
|
} else if canFill(x-1, y) {
|
|
return fillLeft(x-1, y)
|
|
} else if canFill(x+1, y) {
|
|
return fillRight(x+1, y)
|
|
}
|
|
|
|
scan[x][y] = '~'
|
|
return true
|
|
}
|
|
|
|
func fillLeft(x, y int) bool {
|
|
if !canFill(x, y) {
|
|
return false
|
|
}
|
|
|
|
if scan[x][y] == 0 {
|
|
scan[x][y] = '|'
|
|
return true
|
|
}
|
|
|
|
if canFill(x, y+1) {
|
|
return fillSpot(x, y+1)
|
|
} else if canFill(x-1, y) {
|
|
return fillLeft(x-1, y)
|
|
}
|
|
|
|
scan[x][y] = '~'
|
|
return true
|
|
}
|
|
|
|
func fillRight(x, y int) bool {
|
|
if !canFill(x, y) {
|
|
return false
|
|
}
|
|
|
|
if scan[x][y] == 0 {
|
|
scan[x][y] = '|'
|
|
return true
|
|
}
|
|
|
|
if canFill(x, y+1) {
|
|
return fillSpot(x, y+1)
|
|
} else if canFill(x+1, y) {
|
|
return fillRight(x+1, y)
|
|
}
|
|
|
|
scan[x][y] = '~'
|
|
return true
|
|
}
|
|
|
|
func gud(x, y int) bool {
|
|
return x != MIN_INT && y != MIN_INT
|
|
}
|
|
|
|
func printScan() {
|
|
fmt.Print(CLEAR_SCREEN)
|
|
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
|
|
}
|