11import Algorithms
22
3- struct Rule {
4- var before : Int
5- var after : Int
6-
7- }
8- extension Rule {
9- init ( data: Substring ) {
10- let parts = data. split ( separator: " | " )
11- before = Int ( parts [ 0 ] ) ?? 0
12- after = Int ( parts [ 1 ] ) ?? 0
13- }
14- }
15-
163struct Day05 : AdventDay {
174 var rules : [ Int : [ Int ] ]
185 var updates : [ [ Int ] ]
196
7+ func middlePage( _ update: [ Int ] ) -> Int {
8+ update [ update. count / 2 ]
9+ }
10+
2011 init ( data: String ) {
2112 let parts = data. split ( separator: " \n \n " )
2213 rules = [ Int: [ Int] ] ( )
@@ -29,22 +20,44 @@ struct Day05: AdventDay {
2920 updates = parts [ 1 ] . lines ( ) . map { $0. integers ( separator: " , " ) }
3021 }
3122
23+ func isCorrect( _ update: [ Int ] ) -> Bool {
24+ for (idx, page) in update. enumerated ( ) {
25+ let rulesForPage = rules [ page, default: [ Int] ( ) ]
26+ let brokenRules = rulesForPage. map { update [ idx + 1 ..< update. count] . contains ( $0) } . count {
27+ $0 == true
28+ }
29+ if brokenRules > 0 {
30+ return false
31+ }
32+ }
33+ return true
34+ }
35+
3236 func part1( ) -> Int {
33- updates. filter { update in
34- for (idx, page) in update. enumerated ( ) {
35- let rulesForPage = rules [ page, default: [ Int] ( ) ]
36- let brokenRules = rulesForPage. map { update [ idx + 1 ..< update. count] . contains ( $0) } . count {
37- $0 == true
38- }
39- if brokenRules > 0 {
40- return false
37+ updates. filter { isCorrect ( $0) } . map { middlePage ( $0) } . sum
38+ }
39+
40+ func fixOrder( _ update: [ Int ] ) -> [ Int ] {
41+ var fixedUpdate = update
42+ for (idx, page) in update. enumerated ( ) {
43+ let rulesForPage = rules [ page, default: [ Int] ( ) ]
44+ let brokenRules = rulesForPage. map { update [ idx + 1 ..< update. count] . contains ( $0) }
45+ for (isBroken, infringingPage) in zip ( brokenRules, rulesForPage) {
46+ if isBroken {
47+ if let infringingIndex = fixedUpdate. firstIndex ( of: infringingPage) {
48+ let value = fixedUpdate. remove ( at: infringingIndex)
49+ fixedUpdate. insert ( value, at: idx)
50+ }
4151 }
4252 }
43- return true
44- } . map { update in update [ update. count / 2 ] } . sum
53+ }
54+ if !isCorrect( fixedUpdate) {
55+ fixedUpdate = fixOrder ( fixedUpdate)
56+ }
57+ return fixedUpdate
4558 }
4659
4760 func part2( ) -> Int {
48- 0
61+ updates . filter { !isCorrect ( $0 ) } . map { middlePage ( fixOrder ( $0 ) ) } . sum
4962 }
5063}
0 commit comments