@@ -95,6 +95,23 @@ func show(_ canvas: Set<Point>, _ block: Block) -> String {
95
95
return String ( result)
96
96
}
97
97
98
+ func show( _ canvas: Set < Point > ) -> String {
99
+ let maxY = canvas. reduce ( 0 ) { max ( $0, $1. y) }
100
+ var result = [ Character] ( )
101
+ for y in ( - 1 * maxY) ... 0 {
102
+ for x in 0 ... 6 {
103
+ let p = Point ( x: x, y: - 1 * y)
104
+ if canvas. contains ( p) {
105
+ result. append ( " # " )
106
+ } else {
107
+ result. append ( " . " )
108
+ }
109
+ }
110
+ result. append ( " \n " )
111
+ }
112
+ return String ( result)
113
+ }
114
+
98
115
public func part1( ) -> Int {
99
116
let wind = stringsFromFile ( ) [ 0 ] . compactMap { Direction ( rawValue: $0) }
100
117
func shape( _ i: Int ) -> Shape {
@@ -119,3 +136,37 @@ public func part1() -> Int {
119
136
return 1 + canvas. reduce ( 0 ) { max ( $0, $1. y) }
120
137
}
121
138
139
+ public func part2( ) -> Int {
140
+ let wind = stringsFromFile ( ) [ 0 ] . compactMap { Direction ( rawValue: $0) }
141
+ func shape( _ i: Int ) -> Shape {
142
+ Shape . allCases [ i % 5 ]
143
+ }
144
+ var cache = Dictionary < Int , ( Int , Int ) > ( )
145
+ var height = 0
146
+ var canvas = Set < Point > ( )
147
+ var y = 3
148
+ var w = 0
149
+ for s in 0 ..< 1_000_000 {
150
+ var block = Block ( coord: Point ( x: 2 , y: y) , shape: shape ( s) )
151
+ let key = ( s% 5 ) + ( w << 3 )
152
+ if s > 2022 , let cached = cache [ key] {
153
+ let ( q, r) = ( 1_000_000_000_000 - s) . quotientAndRemainder ( dividingBy: s - cached. 0 )
154
+ if r == 0 {
155
+ return height + q * ( height - cached. 1 )
156
+ }
157
+ }
158
+ cache [ key] = ( s, height)
159
+ while true {
160
+ block. push ( wind [ w] , in: canvas)
161
+ w = ( w + 1 ) % wind. count
162
+ if !block. fall ( in: canvas) {
163
+ let points = block. points
164
+ canvas. formUnion ( points)
165
+ y = 4 + canvas. reduce ( 0 ) { max ( $0, $1. y) }
166
+ break
167
+ }
168
+ }
169
+ height = 1 + canvas. reduce ( 0 , { max ( $0, $1. y) } )
170
+ }
171
+ return - 1
172
+ }
0 commit comments