package day14 import ( "adventofcode2024/utils" grid "adventofcode2024/utils/grid2d" "fmt" "regexp" "strings" ) type Robot struct { velocity [2]int } const SIZE_X = 101 const SIZE_Y = 103 func Part1(input string) int { grid := grid.NewGrid(SIZE_X, SIZE_Y, []Robot{}) pattern := `p=(-?\d+),(-?\d+) v=(-?\d+),(-?\d+)` re := regexp.MustCompile(pattern) lines := strings.Split(input, "\n") for _, line := range lines { matches := re.FindStringSubmatch(line) fmt.Println(matches) x := utils.MustAtoi(matches[1]) y := utils.MustAtoi(matches[2]) x1 := utils.MustAtoi(matches[3]) y1 := utils.MustAtoi(matches[4]) robots := grid.Get(x, y) grid.Set(x, y, append(robots, Robot{velocity: [2]int{x1, y1}})) } fmt.Println(grid.StringWithFormatter(formatter)) ng := ticks(grid, 100) fmt.Println(ng.StringWithFormatter(formatter)) return get_saftey(ng) } func Part2(input string) int { min_safe := 240096000 min_i := 0 max_safe := 0 max_i := 0 grid := grid.NewGrid(SIZE_X, SIZE_Y, []Robot{}) pattern := `p=(-?\d+),(-?\d+) v=(-?\d+),(-?\d+)` re := regexp.MustCompile(pattern) lines := strings.Split(input, "\n") for _, line := range lines { matches := re.FindStringSubmatch(line) fmt.Println(matches) x := utils.MustAtoi(matches[1]) y := utils.MustAtoi(matches[2]) x1 := utils.MustAtoi(matches[3]) y1 := utils.MustAtoi(matches[4]) robots := grid.Get(x, y) grid.Set(x, y, append(robots, Robot{velocity: [2]int{x1, y1}})) } fmt.Println(grid.StringWithFormatter(formatter)) max_safe = get_saftey(grid) for i:=0;i<7380;i++ { ng := ticks(grid, 1) safe := get_saftey(ng) if safe > max_safe { max_safe = safe max_i = i } if safe < min_safe { min_safe = safe min_i = i } grid = ng } for i:=7380;i<7390;i++{ ng := ticks(grid, 1) fmt.Println(ng.StringWithFormatter(formatter)) grid = ng } fmt.Println(grid.StringWithFormatter(formatter)) fmt.Printf("max_safe: %d max_i: %d min_safe: %d min_i:%d", max_safe, max_i, min_safe, min_i) return get_saftey(grid) } func formatter(robots []Robot, x int, y int) string { if len(robots) == 0 { return " " } return "*" } func ticks(g *grid.Grid[[]Robot], seconds int) *grid.Grid[[]Robot] { ng := grid.NewGrid(SIZE_X, SIZE_Y, []Robot{}) for y := 0; y < g.SizeY(); y++ { for x := 0; x < g.SizeX(); x++ { for _, robot := range g.Get(x, y) { nx := x + ((robot.velocity[0] * seconds) % SIZE_X) if nx < 0 { nx = g.SizeX() + nx } if nx >= g.SizeX() { nx = nx - g.SizeX() } ny := y + ((robot.velocity[1] * seconds) % SIZE_Y) if ny < 0 { ny = g.SizeY() + ny } if ny >= g.SizeY() { ny = ny - g.SizeY() } robots := ng.Get(nx, ny) ng.Set(nx, ny, append(robots, robot)) } } } return ng } func get_saftey(grid *grid.Grid[[]Robot]) int { robots := 0 val := 1 for y := 0; y < grid.SizeY()/2; y++ { for x := 0; x < grid.SizeX()/2; x++ { robots += len(grid.Get(x, y)) } } val *= robots robots = 0 for y := 0; y < grid.SizeY()/2; y++ { for x := grid.SizeX()/2 + 1; x < grid.SizeX(); x++ { robots += len(grid.Get(x, y)) } } val *= robots robots = 0 for y := grid.SizeY()/2 + 1; y < grid.SizeY(); y++ { for x := grid.SizeX()/2 + 1; x < grid.SizeX(); x++ { robots += len(grid.Get(x, y)) } } val *= robots robots = 0 for y := grid.SizeY()/2 + 1; y < grid.SizeY(); y++ { for x := 0; x < grid.SizeX()/2; x++ { robots += len(grid.Get(x, y)) } } val *= robots return val }