123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143 |
- package main
- import (
- "bufio"
- "fmt"
- "log"
- "os"
- )
- type move struct {
- direction byte
- steps int
- }
- func readInput(file *os.File) []move {
- scanner := bufio.NewScanner(file)
- var moves []move
- for scanner.Scan() {
- line := scanner.Text()
- if line == "" {
- continue
- }
- var current move
- n, err := fmt.Sscanf(line, "%c %d", ¤t.direction, ¤t.steps)
- if n != 2 || err != nil {
- log.Fatal("Can't parse cd:", err)
- }
- moves = append(moves, current)
- }
- return moves
- }
- func moveRight(x int, y int, trail [][]byte, steps int) (int, int, [][]byte) {
- x += steps
- edge := len(trail[y]) - 1
- if x > edge {
- trail[y] = append(trail[y], make([]byte, x-edge)...)
- }
- for i := x - 1; i > x-steps; i-- {
- trail[y][i] = '#'
- }
- return x, y, trail
- }
- func moveLeft(x int, y int, trail [][]byte, steps int) (int, int, [][]byte) {
- x -= steps
- for i := x + 1; i < x+steps; i++ {
- trail[y][i] = '#'
- }
- return x, y, trail
- }
- func moveUp(x int, y int, trail [][]byte, steps int) (int, int, [][]byte) {
- width := len(trail[y])
- y += steps
- edge := len(trail) - 1
- if y > edge {
- for i := 0; i < y-edge; i++ {
- trail = append(trail, make([]byte, width))
- }
- }
- for i := y - steps + 1; i < y; i++ {
- trail[i][x] = '#'
- }
- return x, y, trail
- }
- func moveDown(x int, y int, trail [][]byte, steps int) (int, int, [][]byte) {
- y -= steps
- for i := y - 1; i > y-steps; i-- {
- trail[i][x] = '#'
- }
- return x, y, trail
- }
- func drawTail(x int, y int, action move, trail [][]byte) (int, int, [][]byte) {
- switch action.direction {
- case 'R':
- return moveRight(x, y, trail, action.steps)
- case 'L':
- return moveLeft(x, y, trail, action.steps)
- case 'U':
- return moveUp(x, y, trail, action.steps)
- case 'D':
- return moveDown(x, y, trail, action.steps)
- }
- return x, y, trail
- }
- func calculate(trail [][]byte) int {
- count := 0
- for i := range trail {
- for j := range trail[i] {
- if trail[i][j] == '#' {
- count++
- }
- }
- }
- return count
- }
- func part1(moves []move) int {
- trail := [][]byte{make([]byte, 1)}
- x := 0
- y := 0
- for i := range moves {
- x, y, trail = drawTail(x, y, moves[i], trail)
- }
- return calculate(trail)
- }
- func main() {
- if len(os.Args) < 2 {
- log.Fatal("You need to specify a file!")
- }
- filePath := os.Args[1]
- file, err := os.Open(filePath)
- if err != nil {
- log.Fatalf("Failed to open %s!\n", filePath)
- }
- moves := readInput(file)
- fmt.Println("Part1:", part1(moves))
- }
|