03b
This commit is contained in:
parent
8072d84a5a
commit
b0609897df
@ -16,15 +16,15 @@ struct Day03 {
|
||||
let commands = input
|
||||
.components(separatedBy: .newlines)
|
||||
.filter { !$0.isEmpty }
|
||||
//.compactMap { MoveCommand(line: $0) }
|
||||
runA(commands)
|
||||
//runB(commands)
|
||||
runB(commands)
|
||||
}
|
||||
|
||||
func runA(_ commands: [String]) {
|
||||
let neededForMajority = commands.count / 2
|
||||
let lastBitIndex = commands.first!.count
|
||||
var countsOnes = [Int](repeating: 0, count: lastBitIndex)
|
||||
// There's probably some clever bitwise operation to solve this
|
||||
for command in commands {
|
||||
let m = command.map { Bool.init(digit: $0)! }.map { $0 ? 1 : 0 }
|
||||
countsOnes.enumerated().forEach { (idx, elem) in
|
||||
@ -42,11 +42,81 @@ struct Day03 {
|
||||
}
|
||||
return (gamma, episolon)
|
||||
})
|
||||
print(dec.episolon * dec.gamma)<
|
||||
print(dec.episolon * dec.gamma)
|
||||
}
|
||||
|
||||
func runB(_ commands: [String]) {
|
||||
// Incredibly naive, iterates through the list many, many times
|
||||
// Still runs plenty fast (~70ms on my machine)
|
||||
// Too tired to optimize this
|
||||
|
||||
let lastBitIndex = commands.first!.count
|
||||
var countsOnes = [Int](repeating: 0, count: lastBitIndex)
|
||||
for command in commands {
|
||||
let m = command.map { Bool.init(digit: $0)! }.map { $0 ? 1 : 0 }
|
||||
countsOnes.enumerated().forEach { (idx, elem) in
|
||||
countsOnes[idx] += m[idx]
|
||||
}
|
||||
}
|
||||
|
||||
var oxygenCommands = commands
|
||||
var scrubberCommands = commands
|
||||
for pos in 0..<lastBitIndex {
|
||||
var countsOnesOxygen = [Int](repeating: 0, count: lastBitIndex)
|
||||
for command in oxygenCommands {
|
||||
let m = command.map { Bool.init(digit: $0)! }.map { $0 ? 1 : 0 }
|
||||
countsOnesOxygen.enumerated().forEach { (idx, elem) in
|
||||
countsOnesOxygen[idx] += m[idx]
|
||||
}
|
||||
}
|
||||
|
||||
var countsOnesScrubber = [Int](repeating: 0, count: lastBitIndex)
|
||||
for command in scrubberCommands {
|
||||
let m = command.map { Bool.init(digit: $0)! }.map { $0 ? 1 : 0 }
|
||||
countsOnesScrubber.enumerated().forEach { (idx, elem) in
|
||||
countsOnesScrubber[idx] += m[idx]
|
||||
}
|
||||
}
|
||||
let neededForMajorityOxygen = Int(ceil(Double(oxygenCommands.count) / 2.0))
|
||||
for command in oxygenCommands {
|
||||
let idx = command.index(command.startIndex, offsetBy: pos)
|
||||
let isMostCommon = countsOnesOxygen[pos] >= neededForMajorityOxygen
|
||||
let digit = Bool(digit: command[idx])
|
||||
let keepOxygen = digit == isMostCommon
|
||||
if !keepOxygen, oxygenCommands.count > 1, let coi = oxygenCommands.firstIndex(of: command){
|
||||
oxygenCommands.remove(at: coi)
|
||||
}
|
||||
}
|
||||
|
||||
let neededForMajorityScrubber = Int(ceil(Double(scrubberCommands.count) / 2.0))
|
||||
for command in scrubberCommands {
|
||||
let idx = command.index(command.startIndex, offsetBy: pos)
|
||||
let isLeastCommon = countsOnesScrubber[pos] < neededForMajorityScrubber
|
||||
let digit = Bool(digit: command[idx])
|
||||
let keepScrubber = digit == isLeastCommon
|
||||
if !keepScrubber, scrubberCommands.count > 1, let ci = scrubberCommands.firstIndex(of: command) {
|
||||
scrubberCommands.remove(at: ci)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
let finalOxygenNumber = oxygenCommands.first!
|
||||
let finalScruberNumber = scrubberCommands.first!
|
||||
|
||||
print(ToDecimal(num: finalOxygenNumber) * ToDecimal(num: finalScruberNumber))
|
||||
}
|
||||
|
||||
private func ToDecimal(num: String) -> Int {
|
||||
var pot = -1
|
||||
var val = 0
|
||||
for c in num.reversed() {
|
||||
pot += 1
|
||||
if c == "0" {
|
||||
continue
|
||||
}
|
||||
val += Int(truncating: NSDecimalNumber(decimal: pow(2, pot)))
|
||||
}
|
||||
return val
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user