aoc2021/Sources/08/08.swift

90 lines
2.7 KiB
Swift
Raw Permalink Normal View History

2021-12-08 20:22:44 +00:00
//
// File.swift
//
//
// Created by Max Nuding on 05.12.21.
//
import Foundation
import Runner
import Collections
struct Day08: Runnable {
let inputPath: String
func run() {
let input = try! String(contentsOfFile: inputPath)
let entries = input
.trimmingCharacters(in: .newlines)
.components(separatedBy: .newlines)
.map { $0.components(separatedBy: " | ") }
let lines = entries.reduce(into: [String:String](), { $0[$1.first!] = $1[1] })
runA(lines: lines)
print(lines.map { runB(line: $0) }.reduce(0, +))
}
func runA(lines: [String : String]) {
let outputSignals = lines.values
.flatMap { $0.components(separatedBy: .whitespaces) }
let uniqueOutputSignals = outputSignals
.filter { $0.count == 2 || $0.count == 3 || $0.count == 4 || $0.count == 7 }
.count
print(uniqueOutputSignals)
}
func runB(line: Dictionary<String,String>.Element) -> Int {
let uniqueInputSignalDict = line.key
.components(separatedBy: .whitespaces)
.reduce(into: [Int:String](), {
switch $1.count {
case 2:
$0[1] = $1
case 3:
$0[7] = $1
case 4:
$0[4] = $1
case 7:
$0[8] = $1
default:
break
}
})
let outputSignals = line.value.components(separatedBy: .whitespaces)
let len = Double(outputSignals.count - 1)
return outputSignals.enumerated()
.map { Int(pow(10.0, len - Double($0.offset))) * guessDigit(inputSignals: uniqueInputSignalDict, outputSignal: $0.element)! }
.reduce(0, +)
}
func guessDigit(inputSignals: [Int:String], outputSignal: String) -> Int? {
switch outputSignal.count {
case 2:
return 1
case 3:
return 7
case 4:
return 4
case 5:
if inputSignals[1]!.allSatisfy({ outputSignal.contains($0) }) {
return 3
}
let isTwo = inputSignals[8]!
.filter { !inputSignals[4]!.contains($0) }
.allSatisfy { outputSignal.contains($0) }
return isTwo ? 2 : 5
case 6:
if inputSignals[4]!.allSatisfy({ outputSignal.contains($0) }) {
return 9
}
let isZero = inputSignals[7]!.allSatisfy { outputSignal.contains($0) }
return isZero ? 0 : 6
case 7:
return 8
default:
print("Invalid output signal: \(outputSignal)")
return nil
}
}
}