Created
December 19, 2020 16:15
-
-
Save felix-larsen/f1f35600cb56703dcafe35683f8c0d35 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import Foundation | |
struct Rule { | |
let condition1: [Int]? | |
let condition2: [Int]? | |
let char: Character? | |
} | |
let filename = "/Users/felix/xCodeProjects/AdventOfCode2020.playground/Resources/december19.txt" | |
let contents = try! String(contentsOfFile: filename) | |
let lines = contents.components(separatedBy: CharacterSet.newlines).filter { !$0.isEmpty} | |
let rules = lines.filter { $0.contains(":") }.map { line -> (Int, Rule) in | |
let parts = line.components(separatedBy: ": ") | |
let ruleNumber = Int(parts[0])! | |
let rule = parts[1] | |
var char: Character? = nil | |
var condition1: [Int]? = nil | |
var condition2: [Int]? = nil | |
if rule.contains("\"") { | |
char = rule[rule.index(rule.startIndex, offsetBy: 1)] | |
} else if rule.contains("|") { | |
let rulePair = rule.components(separatedBy: " | ") | |
let t = rulePair[0].components(separatedBy: " ") | |
condition1 = t.map { Int($0)! } | |
condition2 = rulePair[1].components(separatedBy: " ").map { Int($0)! } | |
} else { | |
condition1 = rule.components(separatedBy: " ").map { Int($0)! } | |
} | |
return (ruleNumber, Rule(condition1: condition1, condition2: condition2, char: char)) | |
} | |
let rulesDict = Dictionary(uniqueKeysWithValues: rules) | |
let expressions = lines | |
.filter { !$0.contains(":") } | |
.map { line in | |
ruleMatches([line], ruleNumber: 0, rulesDict: rulesDict) | |
} | |
print(expressions) | |
print(expressions.filter { $0?.contains("") == true }.count) | |
func ruleMatches(_ exs: [String], ruleNumber: Int, rulesDict: [Int: Rule]) -> [String]? { | |
let rule = rulesDict[ruleNumber] | |
if let char = rule?.char { | |
return exs.compactMap { ex in | |
if ex.first == char { | |
return String(ex[ex.index(ex.startIndex, offsetBy: 1)..<ex.endIndex]) | |
} else { | |
return nil | |
} | |
} | |
} | |
var condition1Matches = [String]() | |
if let condition1 = rule?.condition1 { | |
for ex in exs { | |
if ex != "" { | |
var leftovers: [String]? = [ex] | |
for ruleNumber in condition1 { | |
if let leftoversNN = leftovers { | |
leftovers = ruleMatches(leftoversNN, ruleNumber: ruleNumber, rulesDict: rulesDict) | |
} | |
} | |
if let leftoversNN = leftovers { | |
condition1Matches.append(contentsOf: leftoversNN) | |
} | |
} | |
} | |
} | |
var condition2Matches = [String]() | |
if let condition2 = rule?.condition2 { | |
for ex in exs { | |
if ex != "" { | |
var leftovers: [String]? = [ex] | |
for ruleNumber in condition2 { | |
if let leftoversNN = leftovers { | |
leftovers = ruleMatches(leftoversNN, ruleNumber: ruleNumber, rulesDict: rulesDict) | |
} | |
} | |
if let leftoversNN = leftovers { | |
condition2Matches.append(contentsOf: leftoversNN) | |
} | |
} | |
} | |
} | |
return condition1Matches + condition2Matches | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment