package main import ( "bufio" "fmt" "math" "os" //"slices" "strconv" "strings" ) var red_walls [][]int var lines map[int][][]int var columns map[int][][]int var the_map map[[2]int]byte var max_x,min_x int var max_y,min_y int func main() { fmt.Println("Advent of Code 2025 - Day 9 - Part 2") f,_:= os.Open("9/input") defer f.Close() scanner:=bufio.NewScanner(f) max_x = 0 min_x = math.MaxInt max_y = 0 min_y = math.MaxInt the_map = make(map[[2]int]byte) for scanner.Scan(){ line:= scanner.Text() line_sp := strings.Split(line, ",") x,_:= strconv.Atoi(line_sp[0]) y,_:= strconv.Atoi(line_sp[1]) max_x = max(x,max_x) min_x = min(x,min_x) max_y = max(y,max_y) min_y = min(y,min_y) red_walls = append(red_walls, []int{x,y}) the_map[[2]int{x,y}] = '#' } construct_border() //fmt.Println(len(lines)) //fmt.Println(len(columns)) construct_map() print_map() res := int64(0) for i:= range red_walls { w1:= red_walls[i] for j:= i+1; j < len(red_walls); j++{ w2:= red_walls[j] if (is_valid_area(w1,w2)){ area := calculate_area2(w1,w2) if area > res { // fmt.Println(w1,w2) res = area } } } } fmt.Println(res) } func construct_map(){ for i:= min_x; i <= max_x; i++ { for j:= min_y; j <= max_y; j++{ if the_map[[2]int{i,j}] != '#'{ if is_green_or_red([]int{i,j}) { the_map[[2]int{i,j}] = 'O' } else { the_map[[2]int{i,j}] = '.' } } } } } func print_map(){ for i := range 15 { for j:= range 15{ c,ok := the_map[[2]int{j,i}] if ok { fmt.Printf(string(c)) } else { fmt.Printf(".") } } fmt.Printf("\n") } } func construct_border() { lines = make(map[int][][]int) columns = make(map[int][][]int) for i:= 0; i < len(red_walls); i++{ px,py := red_walls[(i+1)%len(red_walls)][0], red_walls[(i+1)%len(red_walls)][1] x,y:= red_walls[i][0], red_walls[i][1] if x == px { // lines from min(y,py) to max(y,py) for ln := min(y, py); ln <= max(y, py); ln++ { new_l := true _,ok := lines[ln] if ok{ for i:= range lines[ln] { if lines[ln][i][0] <= x && x <= lines[ln][i][1] { lines[ln][i][0] = min(lines[ln][i][0], x) lines[ln][i][1] = max(lines[ln][i][1], x) new_l = false break } } } if new_l{ lines[ln] = append(lines[ln], []int{x,x}) } } // column x new_c := true a,b := min(y,py), max(y,py) _,ok := columns[x] if ok{ for i:= range columns[x] { if columns[x][i][0] <= a && a <= columns[x][i][1] { columns[x][i][0] = min(columns[x][i][0], a) columns[x][i][1] = max(columns[x][i][1], b) new_c = false break } } } if new_c{ columns[x] = append(columns[x], []int{a,b}) } } else if y == py { // line y new_l := true a,b := min(x,px), max(x,px) _,ok := lines[y] if ok{ for i:= range lines[y] { if lines[y][i][0] <= a && a <= lines[y][i][1] { lines[y][i][0] = min(lines[y][i][0], a) lines[y][i][1] = max(lines[y][i][1], b) new_l = false break } } } if new_l{ lines[y] = append(lines[y], []int{min(x,px),max(x,px)}) } // columns from min(x,px) to max(x,px) for cn := min(x, px); cn <= max(x, px); cn++ { new_c := true _,ok := columns[cn] if ok{ for i:= range columns[cn] { if columns[cn][i][0] <= y && y <= columns[cn][i][1] { columns[cn][i][0] = min(columns[cn][i][0], y) columns[cn][i][1] = max(columns[cn][i][1], y) new_c = false break } } } if new_c{ columns[cn] = append(columns[cn], []int{y,y}) } } } } } // Given a point []int{x,y} look for the border to the 4 directions (W,N,E,S) // B_W should have same y and <= x // B_E should have same y and >= x // B_N should have same x and >= y // B_S should have same x and <= y // if all borders are found then the point is a green or red wall // otherwise it's out of boundaries func is_green_or_red(w []int) bool { if is_border(w) { return true } ok_bw,ok_be := false,false ok_bn,ok_bs := false,false x,y := w[0],w[1] _,ok:= lines[y] if !ok { return false } _,ok = columns[x] if !ok { return false } // look for bordeer B_w & B_E for i:= range lines[y] { if ok_bw && ok_be{ break } if !ok_bw && (lines[y][i][0] <= x || lines[y][i][1] <= x) { ok_bw = true } if !ok_be && (lines[y][i][0] >= x || lines[y][i][1] >= x) { ok_be = true } } if !ok_bw || !ok_be{ return false } // look for bordeer B_N & B_S for i:= range columns[x] { if ok_bn && ok_bs{ break } if !ok_bn && (columns[x][i][0] >= y || columns[x][i][1] >= y) { ok_bn = true } if !ok_bs && (columns[x][i][0] <= y || columns[x][i][1] <= y) { ok_bs = true } } if !ok_bw || !ok_be{ return false } return ok_be && ok_bw && ok_bn && ok_bs } func is_valid_area(w1,w2 []int) bool{ x1,y1:=w1[0],w1[1] x2,y2:=w2[0],w2[1] start_x, end_x := min(x1,x2), max(x1,x2) // 2,11 start_y, end_y := min(y1,y2), max(y1,y2) // 1,5 for i:= start_x+1; i < end_x; i++{ if (the_map[[2]int{i,y1}] == '.'){ return false } if (the_map[[2]int{i,y2}] == '.'){ return false } } for i:= start_y+1; i < end_y; i++{ if (the_map[[2]int{x2,i}]== '.'){ return false } if (the_map[[2]int{x1,i}] == '.'){ return false } } return true } func is_border(w []int) bool { borders, ok := lines[w[1]] if ok { for i:= range borders{ if borders[i][0] <= w[0] && w[0] <= borders[i][1]{ return true } } } return false } func calculate_area2(w1,w2 []int) int64{ dx, dy := int64(math.Abs(float64(w1[0]-w2[0]))), int64(math.Abs(float64(w1[1]-w2[1]))) return (dx+1) * (dy+1) }