Files

97 lines
2.1 KiB
Go
Raw Permalink Normal View History

2024-12-14 14:41:12 +01:00
package main
import ("os"; "strings"; "fmt"; "strconv"; "regexp")
type Board struct {
width uint8
height uint8
}
type Robot struct {
x uint8
y uint8
vx int8
vy int8
}
func (r Robot) Step(b Board, n uint) Robot {
pos_vx := int(r.vx)
pos_vy := int(r.vy)
if pos_vx < 0 { pos_vx = int(b.width) + pos_vx }
if pos_vy < 0 { pos_vy = int(b.height) + pos_vy }
new_x := uint( uint(r.x) + uint(pos_vx) * n ) % uint(b.width)
new_y := uint( uint(r.y) + uint(pos_vy) * n ) % uint(b.height)
return Robot{uint8(new_x), uint8(new_y), r.vx, r.vy}
}
func check(e error) {
if e != nil {
panic(e)
}
}
func abs(n int) uint {
if n < 0 { return uint(-n) }
return uint(n)
}
func NewRobot(line string) Robot {
pattern := regexp.MustCompile(`-?\d+`)
matches := pattern.FindAllString(line, -1)
numbers := [4]int{}
for i, match := range matches {
num, err := strconv.Atoi(match)
check(err)
numbers[i] = num
}
return Robot{uint8(numbers[0]), uint8(numbers[1]), int8(numbers[2]), int8(numbers[3])}
}
func print_board(rs []Robot, b Board) {
num_fields := int(b.width) * int(b.height)
str := make([]byte, 0, num_fields + int(b.height) + 1)
for i := range num_fields + int(b.height) {
switch {
case (i + 1) % (int(b.width) + 1) == 0: str = append(str, '\n')
default: str = append(str, '.')
}
}
str = append(str, 0)
for _, r := range rs {
offset := int(r.y) * int(b.width + 1) + int(r.x)
str[offset] = '#'
}
fmt.Println(string(str))
}
func main() {
dat, err := os.ReadFile("data.txt")
check(err)
lines := strings.Split(strings.TrimSpace(string(dat)), "\n")
board := Board{width: 101, height: 103}
robots := make([]Robot, 0, 100)
for _, line := range lines {
robots = append(robots, NewRobot(line))
}
// run simulation
for i := range 10000 {
for j := range robots {
robots[j] = robots[j].Step(board, 1)
}
fmt.Println("------------\nafter", i, "seconds")
print_board(robots, board)
}
}