From 7c7d772ff54f259fe7ec760b6a064cec892abb5b Mon Sep 17 00:00:00 2001 From: Sven Weidauer Date: Sat, 19 Dec 2020 13:17:41 +0100 Subject: [PATCH] day 19 part 2 solved --- day19/main.swift | 49 +++++++++++++++++++----------------------------- 1 file changed, 19 insertions(+), 30 deletions(-) diff --git a/day19/main.swift b/day19/main.swift index 3275a09..38a6a7f 100644 --- a/day19/main.swift +++ b/day19/main.swift @@ -75,40 +75,30 @@ extension Scanner { let rules = scanner.parseRuleSet() extension Rule { - func matches(rules: RuleSet, index: Int, _ s: Substring) -> Substring? { + func matches(rules: RuleSet, index: Int, _ s: Substring) -> Set { switch self { case .character(let ch): if s.first == ch { - return s.dropFirst() + return [s.dropFirst()] } - return nil + return [] case let .sequence(first, second): - if let firstMatch = first.matches(rules: rules, index: index, s), let secondMatch = second.matches(rules: rules, index: index, firstMatch) { - return secondMatch - } + let firstMatches = first.matches(rules: rules, index: index, s) + let result = Set(firstMatches.flatMap { x -> Set in + let part = second.matches(rules: rules, index: index, x) + return part + }) - return nil + return result - case .alternative(let a, .sequence(let b, .reference(index))) where a == b: - var rest = s - while let match = a.matches(rules: rules, index: index, rest) { - rest = match - } - guard rest != s else { return nil } - return rest - case let .alternative(first, second): - if let firstMatch = first.matches(rules: rules, index: index, s) { - return firstMatch - } + let firstMatch = first.matches(rules: rules, index: index, s) + let secondMatch = second.matches(rules: rules, index: index, s) - if let secondMatch = second.matches(rules: rules, index: index, s) { - return secondMatch - } - - return nil + let result = firstMatch.union(secondMatch) + return result case .reference(let index): return rules[index]!.matches(rules: rules, index: index, s) @@ -116,11 +106,8 @@ extension Rule { } func matches(rules: RuleSet, index: Int, _ s: String) -> Bool { - if let result = matches(rules: rules, index: index, s[...]), result.isEmpty { - return true - } - - return false + let result = matches(rules: rules, index: index, s[...]) + return result.contains("") } } @@ -146,7 +133,9 @@ extension Scanner { let messages = scanner.readLines() -print("part 1", messages.lazy.filter { rules[0]!.matches(rules: rules,index: 0, $0) }.count) +let start = Rule.reference(0) + +print("part 1:", messages.lazy.filter { start.matches(rules: rules,index: 0, $0) }.count) let changedRules = """ 8: 42 | 42 8 @@ -161,4 +150,4 @@ let ruleUpdates = changeScanner.parseRuleSet() let newRules = rules.merging(ruleUpdates) { $1 } -print("part 2", messages.lazy.filter { rules[0]!.matches(rules: newRules, index: 0, $0) }.count) +print("part 2:", messages.filter { start.matches(rules: newRules, index: 0, $0) }.count)