03b
This commit is contained in:
parent
8072d84a5a
commit
b0609897df
@ -16,15 +16,15 @@ struct Day03 {
|
|||||||
let commands = input
|
let commands = input
|
||||||
.components(separatedBy: .newlines)
|
.components(separatedBy: .newlines)
|
||||||
.filter { !$0.isEmpty }
|
.filter { !$0.isEmpty }
|
||||||
//.compactMap { MoveCommand(line: $0) }
|
|
||||||
runA(commands)
|
runA(commands)
|
||||||
//runB(commands)
|
runB(commands)
|
||||||
}
|
}
|
||||||
|
|
||||||
func runA(_ commands: [String]) {
|
func runA(_ commands: [String]) {
|
||||||
let neededForMajority = commands.count / 2
|
let neededForMajority = commands.count / 2
|
||||||
let lastBitIndex = commands.first!.count
|
let lastBitIndex = commands.first!.count
|
||||||
var countsOnes = [Int](repeating: 0, count: lastBitIndex)
|
var countsOnes = [Int](repeating: 0, count: lastBitIndex)
|
||||||
|
// There's probably some clever bitwise operation to solve this
|
||||||
for command in commands {
|
for command in commands {
|
||||||
let m = command.map { Bool.init(digit: $0)! }.map { $0 ? 1 : 0 }
|
let m = command.map { Bool.init(digit: $0)! }.map { $0 ? 1 : 0 }
|
||||||
countsOnes.enumerated().forEach { (idx, elem) in
|
countsOnes.enumerated().forEach { (idx, elem) in
|
||||||
@ -42,11 +42,81 @@ struct Day03 {
|
|||||||
}
|
}
|
||||||
return (gamma, episolon)
|
return (gamma, episolon)
|
||||||
})
|
})
|
||||||
print(dec.episolon * dec.gamma)<
|
print(dec.episolon * dec.gamma)
|
||||||
}
|
}
|
||||||
|
|
||||||
func runB(_ commands: [String]) {
|
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