@@ -40,45 +40,40 @@ struct Beam: Hashable {
40
40
41
41
func energized( by beam: Beam ) -> Int {
42
42
var visited = Set < Beam > ( )
43
- var next = [ beam]
44
- var bt = beam
45
-
46
- while var beam = next. popLast ( ) {
47
- if visited. contains ( beam) {
48
- continue
49
- }
50
-
51
- while isInBounds ( beam) {
52
- visited. insert ( beam)
43
+ trace ( beam: beam, visited: & visited)
44
+ return Set ( visited. map ( { [ $0. x, $0. y] } ) ) . count
45
+ }
53
46
54
- switch item ( at: beam) {
55
- case . vbar where beam. isHorizontal:
56
- ( beam, bt) = beam. vsplit
57
- next. append ( bt)
58
- case . hbar where beam. isVertical:
59
- ( beam, bt) = beam. hsplit
60
- next. append ( bt)
61
- case . fslash:
62
- switch ( beam. dx, beam. dy) {
63
- case ( - 1 , 0 ) : beam = beam. reflectD
64
- case ( + 1 , 0 ) : beam = beam. reflectU
65
- case ( 0 , - 1 ) : beam = beam. reflectR
66
- default : beam = beam. reflectL
67
- }
68
- case . bslash:
69
- switch ( beam. dx, beam. dy) {
70
- case ( - 1 , 0 ) : beam = beam. reflectU
71
- case ( + 1 , 0 ) : beam = beam. reflectD
72
- case ( 0 , - 1 ) : beam = beam. reflectL
73
- default : beam = beam. reflectR
74
- }
75
- default :
76
- beam = beam. step
47
+ func trace( beam: Beam , visited: inout Set < Beam > ) {
48
+ var ( beam, bt) = ( beam, beam)
49
+ while isInBounds ( beam) && !visited. contains ( beam) {
50
+ visited. insert ( beam)
51
+
52
+ switch item ( at: beam) {
53
+ case . vbar where beam. isHorizontal:
54
+ ( beam, bt) = beam. vsplit
55
+ trace ( beam: bt, visited: & visited)
56
+ case . hbar where beam. isVertical:
57
+ ( beam, bt) = beam. hsplit
58
+ trace ( beam: bt, visited: & visited)
59
+ case . fslash:
60
+ switch ( beam. dx, beam. dy) {
61
+ case ( - 1 , 0 ) : beam = beam. reflectD
62
+ case ( + 1 , 0 ) : beam = beam. reflectU
63
+ case ( 0 , - 1 ) : beam = beam. reflectR
64
+ default : beam = beam. reflectL
65
+ }
66
+ case . bslash:
67
+ switch ( beam. dx, beam. dy) {
68
+ case ( - 1 , 0 ) : beam = beam. reflectU
69
+ case ( + 1 , 0 ) : beam = beam. reflectD
70
+ case ( 0 , - 1 ) : beam = beam. reflectL
71
+ default : beam = beam. reflectR
77
72
}
73
+ default :
74
+ beam = beam. step
78
75
}
79
76
}
80
-
81
- return Set ( visited. map ( { [ $0. x, $0. y] } ) ) . count
82
77
}
83
78
84
79
func isInBounds( _ beam: Beam ) -> Bool {
0 commit comments