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 coord struct { x int y int } func moveNextKnot(parent, child *coord) { if parent.y-child.y == 2 { child.y++ if parent.x-child.x == 2 { child.x++ } else if child.x-parent.x == 2 { child.x-- } else { child.x = parent.x } } if child.y-parent.y == 2 { child.y-- if parent.x-child.x == 2 { child.x++ } else if child.x-parent.x == 2 { child.x-- } else { child.x = parent.x } } if parent.x-child.x == 2 { child.x++ if parent.y-child.y == 2 { child.y++ } else if child.y-parent.y == 2 { child.y-- } else { child.y = parent.y } } if child.x-parent.x == 2 { child.x-- if parent.y-child.y == 2 { child.y++ } else if child.y-parent.y == 2 { child.y-- } else { child.y = parent.y } } } func displayGrid(rope []coord) { for x := 0; x < 10; x++ { for y := 0; y < 10; y++ { printed := false for k, c := range rope { if c.x == x && c.y == y && !printed { printed = true if k == 0 { fmt.Print("H") } else { fmt.Print(k) } } } if !printed { fmt.Print(".") } } fmt.Println() } } func partOne() { scanner := makeScanner(false) grid := map[coord]bool{{x: 0, y: 0}: true} head := coord{x: 0, y: 0} tail := coord{x: 0, y: 0} for scanner.Scan() { line := scanner.Text() l := strings.Split(line, " ") direction, steps := l[0], mustAtoi(l[1]) for i := 0; i < steps; i++ { switch direction { case "U": head.y++ case "D": head.y-- case "L": head.x-- case "R": head.x++ default: panic("oh no") } moveNextKnot(&head, &tail) grid[tail] = true } } fmt.Println(len(grid)) } func partTwo() { scanner := makeScanner(false) grid := map[coord]bool{{x: 0, y: 0}: true} rope := []coord{ {x: 0, y: 0}, {x: 0, y: 0}, {x: 0, y: 0}, {x: 0, y: 0}, {x: 0, y: 0}, {x: 0, y: 0}, {x: 0, y: 0}, {x: 0, y: 0}, {x: 0, y: 0}, {x: 0, y: 0}, } for scanner.Scan() { line := scanner.Text() l := strings.Split(line, " ") direction, steps := l[0], mustAtoi(l[1]) for i := 0; i < steps; i++ { switch direction { case "U": rope[0].y++ case "D": rope[0].y-- case "L": rope[0].x-- case "R": rope[0].x++ default: panic("oh no") } for i := 0; i < 9; i++ { moveNextKnot(&rope[i], &rope[i+1]) } grid[rope[9]] = true } } fmt.Println(len(grid)) }