@@ -2,7 +2,6 @@ package main
22
33import (
44 _ "embed"
5- "image"
65 "os"
76)
87
@@ -12,8 +11,6 @@ var input string
1211//go:embed input_test.txt
1312var inputTest string
1413
15- type PipeMap map [image.Point ]rune
16-
1714func main () {
1815 // Check argv if we use test input or not
1916 if len (os .Args ) > 1 && os .Args [1 ] == "test" {
@@ -27,66 +24,147 @@ func main() {
2724 println (answer )
2825}
2926
30- func getPointsInLoop (mapper PipeMap , startpoint image.Point ) []image.Point {
31- PointsInLoop := []image.Point {startpoint }
32- P := startpoint
33- Dir := '>'
27+ type Point struct {
28+ x , y int
29+ }
30+
31+ var (
32+ grid []string
33+ width int
34+ height int
35+ startX int
36+ startY int
37+ loopPath []Point
38+ inLoop map [Point ]bool
39+ )
40+
41+ func parseInput (input string ) {
42+ grid = make ([]string , 0 , 140 )
43+
44+ i := 0
45+ for i < len (input ) {
46+ if input [i ] == '\n' || input [i ] == '\r' {
47+ i ++
48+ continue
49+ }
50+
51+ start := i
52+ for i < len (input ) && input [i ] != '\n' && input [i ] != '\r' {
53+ i ++
54+ }
55+ line := input [start :i ]
56+ grid = append (grid , line )
57+
58+ // Find start position
59+ for x := 0 ; x < len (line ); x ++ {
60+ if line [x ] == 'S' {
61+ startX = x
62+ startY = len (grid ) - 1
63+ }
64+ }
65+ }
66+
67+ height = len (grid )
68+ width = len (grid [0 ])
69+ }
70+
71+ func traceLoop () {
72+ loopPath = make ([]Point , 0 , 20000 )
73+ inLoop = make (map [Point ]bool , 20000 )
74+
75+ x , y := startX , startY
76+ loopPath = append (loopPath , Point {x , y })
77+ inLoop [Point {x , y }] = true
78+
79+ // Determine initial direction from S
80+ dir := byte ('>' )
81+ x ++
82+
3483 for {
35- var NP image.Point
36- switch mapper [P ] {
37- case 'S' : // this is the start point.
38- NP = P .Add (image.Point {1 , 0 })
39- case '|' : // Vertical Pipe
40- if Dir == 'U' {
41- NP = P .Add (image.Point {0 , - 1 })
84+ loopPath = append (loopPath , Point {x , y })
85+ inLoop [Point {x , y }] = true
86+
87+ pipe := grid [y ][x ]
88+ if pipe == 'S' {
89+ break
90+ }
91+
92+ switch pipe {
93+ case '|' :
94+ if dir == 'U' {
95+ y --
4296 } else {
43- NP = P . Add (image. Point { 0 , 1 })
97+ y ++
4498 }
45- case '-' : // Horizontal Pipe
46- if Dir == '>' {
47- NP = P . Add (image. Point { 1 , 0 })
99+ case '-' :
100+ if dir == '>' {
101+ x ++
48102 } else {
49- NP = P . Add (image. Point { - 1 , 0 })
103+ x --
50104 }
51- case 'L' : // North to East
52- if Dir == 'D' {
53- NP = P . Add (image. Point { 1 , 0 })
54- Dir = '>'
105+ case 'L' :
106+ if dir == 'D' {
107+ x ++
108+ dir = '>'
55109 } else {
56- NP = P . Add (image. Point { 0 , - 1 })
57- Dir = 'U'
110+ y --
111+ dir = 'U'
58112 }
59- case 'J' : // North to West
60- if Dir == 'D' {
61- NP = P . Add (image. Point { - 1 , 0 })
62- Dir = '<'
113+ case 'J' :
114+ if dir == 'D' {
115+ x --
116+ dir = '<'
63117 } else {
64- NP = P . Add (image. Point { 0 , - 1 })
65- Dir = 'U'
118+ y --
119+ dir = 'U'
66120 }
67- case '7' : // South to West
68- if Dir == 'U' {
69- NP = P . Add (image. Point { - 1 , 0 })
70- Dir = '<'
121+ case '7' :
122+ if dir == 'U' {
123+ x --
124+ dir = '<'
71125 } else {
72- NP = P . Add (image. Point { 0 , 1 })
73- Dir = 'D'
126+ y ++
127+ dir = 'D'
74128 }
75- case 'F' : // South to East
76- if Dir == '<' {
77- NP = P . Add (image. Point { 0 , 1 })
78- Dir = 'D'
129+ case 'F' :
130+ if dir == '<' {
131+ y ++
132+ dir = 'D'
79133 } else {
80- NP = P . Add (image. Point { 1 , 0 })
81- Dir = '>'
134+ x ++
135+ dir = '>'
82136 }
83- case '.' : // Ground, no pipe
84137 }
85- if NP == startpoint {
86- break
138+ }
139+ }
140+
141+ func pointInPolygon (px , py int ) bool {
142+ // Ray casting algorithm - count intersections with edges
143+ count := 0
144+ n := len (loopPath )
145+
146+ for i := 0 ; i < n - 1 ; i ++ {
147+ p1 := loopPath [i ]
148+ p2 := loopPath [i + 1 ]
149+
150+ if p1 .y <= py {
151+ if p2 .y > py {
152+ // Upward crossing
153+ cross := (p2 .x - p1 .x )* (py - p1 .y ) - (px - p1 .x )* (p2 .y - p1 .y )
154+ if cross > 0 {
155+ count ++
156+ }
157+ }
158+ } else {
159+ if p2 .y <= py {
160+ // Downward crossing
161+ cross := (p2 .x - p1 .x )* (py - p1 .y ) - (px - p1 .x )* (p2 .y - p1 .y )
162+ if cross < 0 {
163+ count --
164+ }
165+ }
87166 }
88- P = NP
89- PointsInLoop = append (PointsInLoop , P )
90167 }
91- return PointsInLoop
168+
169+ return count != 0
92170}
0 commit comments