2021-12-10 06:08:34 +00:00
|
|
|
//
|
|
|
|
// File.swift
|
|
|
|
//
|
|
|
|
//
|
|
|
|
// Created by Max Nuding on 05.12.21.
|
|
|
|
//
|
|
|
|
|
|
|
|
import Foundation
|
|
|
|
import Runner
|
|
|
|
import Collections
|
|
|
|
|
2021-12-10 06:40:47 +00:00
|
|
|
|
2021-12-10 06:08:34 +00:00
|
|
|
struct Day10: Runnable {
|
|
|
|
let inputPath: String
|
|
|
|
|
|
|
|
public func run() {
|
|
|
|
let input = try! String(contentsOfFile: inputPath)
|
|
|
|
let lines = input
|
|
|
|
.trimmingCharacters(in: .newlines)
|
|
|
|
.components(separatedBy: .newlines)
|
|
|
|
var s = Deque<String.Element>()
|
|
|
|
var illegalCharacters = [String.Element]()
|
2021-12-10 06:47:04 +00:00
|
|
|
var syntaxScore = 0
|
2021-12-10 06:33:51 +00:00
|
|
|
var autocompleteScores = [Int]()
|
2021-12-10 06:40:47 +00:00
|
|
|
for line in lines {
|
2021-12-10 06:33:51 +00:00
|
|
|
s = Deque<String.Element>()
|
|
|
|
var isIllegalLine = false
|
2021-12-10 06:08:34 +00:00
|
|
|
for char in line {
|
|
|
|
if char.isClosing {
|
2021-12-10 06:33:51 +00:00
|
|
|
guard let popped = s.popFirst() else {
|
|
|
|
fatalError()
|
2021-12-10 06:08:34 +00:00
|
|
|
}
|
2021-12-10 06:33:51 +00:00
|
|
|
guard let shouldBeClosedBy = popped.closedBy else {
|
|
|
|
fatalError()
|
|
|
|
}
|
|
|
|
if shouldBeClosedBy == char {
|
|
|
|
continue // Valid chunk
|
|
|
|
}
|
|
|
|
//print("Line: \(lineNumber): Expected \(shouldBeClosedBy), but found \(char) instead")
|
2021-12-10 06:47:04 +00:00
|
|
|
syntaxScore += char.score!
|
2021-12-10 06:33:51 +00:00
|
|
|
isIllegalLine = true
|
|
|
|
break
|
2021-12-10 06:08:34 +00:00
|
|
|
}
|
|
|
|
s.prepend(char)
|
|
|
|
}
|
2021-12-10 06:33:51 +00:00
|
|
|
if !isIllegalLine {
|
|
|
|
var lineScore = 0
|
2021-12-10 06:43:23 +00:00
|
|
|
while let last = s.popFirst() {
|
2021-12-10 06:33:51 +00:00
|
|
|
let charValue = last.closedBy!.autocompleteScore!
|
|
|
|
lineScore = lineScore * 5 + charValue
|
|
|
|
}
|
|
|
|
autocompleteScores.append(lineScore)
|
|
|
|
}
|
2021-12-10 06:08:34 +00:00
|
|
|
}
|
2021-12-10 06:47:04 +00:00
|
|
|
print(syntaxScore)
|
2021-12-10 06:33:51 +00:00
|
|
|
print(autocompleteScores.sorted()[autocompleteScores.count / 2])
|
2021-12-10 06:08:34 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
extension String.Element {
|
|
|
|
var isClosing: Bool { self == "]" || self == ")" || self == ">" || self == "}" }
|
|
|
|
var closedBy: String.Element? {
|
|
|
|
switch self {
|
|
|
|
case "[":
|
|
|
|
return "]"
|
|
|
|
case "(":
|
|
|
|
return ")"
|
|
|
|
case "{":
|
|
|
|
return "}"
|
|
|
|
case "<":
|
|
|
|
return ">"
|
|
|
|
default:
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
var score: Int? {
|
|
|
|
switch self {
|
|
|
|
case ")":
|
|
|
|
return 3
|
|
|
|
case "]":
|
|
|
|
return 57
|
|
|
|
case "}":
|
|
|
|
return 1197
|
|
|
|
case ">":
|
|
|
|
return 25137
|
|
|
|
default:
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
}
|
2021-12-10 06:33:51 +00:00
|
|
|
|
|
|
|
var autocompleteScore: Int? {
|
|
|
|
switch self {
|
|
|
|
case ")":
|
|
|
|
return 1
|
|
|
|
case "]":
|
|
|
|
return 2
|
|
|
|
case "}":
|
|
|
|
return 3
|
|
|
|
case ">":
|
|
|
|
return 4
|
|
|
|
default:
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
}
|
2021-12-10 06:08:34 +00:00
|
|
|
}
|