Day 24 (Slooow)

This commit is contained in:
Sven Weidauer 2021-12-25 16:10:40 +01:00
parent ba6cee935a
commit 2a68c5ff26
2 changed files with 552 additions and 0 deletions

View file

@ -9,6 +9,8 @@
/* Begin PBXBuildFile section */
26132D372774C886004F0228 /* day23.swift in Sources */ = {isa = PBXBuildFile; fileRef = 26132D2B2774C871004F0228 /* day23.swift */; };
26132D382774C886004F0228 /* common.swift in Sources */ = {isa = PBXBuildFile; fileRef = 269BE5CB2762A08800871C85 /* common.swift */; };
26132D482775D6A5004F0228 /* day24.swift in Sources */ = {isa = PBXBuildFile; fileRef = 26132D472775D6A5004F0228 /* day24.swift */; };
26132D492775D6AC004F0228 /* common.swift in Sources */ = {isa = PBXBuildFile; fileRef = 269BE5CB2762A08800871C85 /* common.swift */; };
2615545A276A6C2C00374D18 /* day14.swift in Sources */ = {isa = PBXBuildFile; fileRef = 26155459276A6C2C00374D18 /* day14.swift */; };
2615545B276A6C3200374D18 /* common.swift in Sources */ = {isa = PBXBuildFile; fileRef = 269BE5CB2762A08800871C85 /* common.swift */; };
26155468276A6D0A00374D18 /* day15.swift in Sources */ = {isa = PBXBuildFile; fileRef = 26155467276A6D0A00374D18 /* day15.swift */; };
@ -55,6 +57,15 @@
);
runOnlyForDeploymentPostprocessing = 1;
};
26132D3E2775D68D004F0228 /* CopyFiles */ = {
isa = PBXCopyFilesBuildPhase;
buildActionMask = 2147483647;
dstPath = /usr/share/man/man1/;
dstSubfolderSpec = 0;
files = (
);
runOnlyForDeploymentPostprocessing = 1;
};
26155450276A6C1C00374D18 /* CopyFiles */ = {
isa = PBXCopyFilesBuildPhase;
buildActionMask = 2147483647;
@ -213,6 +224,8 @@
/* Begin PBXFileReference section */
26132D2B2774C871004F0228 /* day23.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = day23.swift; sourceTree = "<group>"; };
26132D302774C87D004F0228 /* Day23 */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = Day23; sourceTree = BUILT_PRODUCTS_DIR; };
26132D402775D68D004F0228 /* Day24 */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = Day24; sourceTree = BUILT_PRODUCTS_DIR; };
26132D472775D6A5004F0228 /* day24.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = day24.swift; sourceTree = "<group>"; };
26155452276A6C1C00374D18 /* Day14 */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = Day14; sourceTree = BUILT_PRODUCTS_DIR; };
26155459276A6C2C00374D18 /* day14.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = day14.swift; sourceTree = "<group>"; };
26155460276A6CF700374D18 /* Day15 */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = Day15; sourceTree = BUILT_PRODUCTS_DIR; };
@ -258,6 +271,13 @@
);
runOnlyForDeploymentPostprocessing = 0;
};
26132D3D2775D68D004F0228 /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
);
runOnlyForDeploymentPostprocessing = 0;
};
2615544F276A6C1C00374D18 /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
@ -383,6 +403,7 @@
263BA594275E974800839C92 = {
isa = PBXGroup;
children = (
26132D472775D6A5004F0228 /* day24.swift */,
26132D2B2774C871004F0228 /* day23.swift */,
2680ECFB27732A9400CAB23C /* day22.swift */,
2680ECE22771D82400CAB23C /* day21.swift */,
@ -427,6 +448,7 @@
2680ECE72771D82F00CAB23C /* Day21 */,
2680ECF427732A8300CAB23C /* Day22 */,
26132D302774C87D004F0228 /* Day23 */,
26132D402775D68D004F0228 /* Day24 */,
);
name = Products;
sourceTree = "<group>";
@ -451,6 +473,23 @@
productReference = 26132D302774C87D004F0228 /* Day23 */;
productType = "com.apple.product-type.tool";
};
26132D3F2775D68D004F0228 /* Day24 */ = {
isa = PBXNativeTarget;
buildConfigurationList = 26132D462775D68D004F0228 /* Build configuration list for PBXNativeTarget "Day24" */;
buildPhases = (
26132D3C2775D68D004F0228 /* Sources */,
26132D3D2775D68D004F0228 /* Frameworks */,
26132D3E2775D68D004F0228 /* CopyFiles */,
);
buildRules = (
);
dependencies = (
);
name = Day24;
productName = Day24;
productReference = 26132D402775D68D004F0228 /* Day24 */;
productType = "com.apple.product-type.tool";
};
26155451276A6C1C00374D18 /* Day14 */ = {
isa = PBXNativeTarget;
buildConfigurationList = 26155458276A6C1C00374D18 /* Build configuration list for PBXNativeTarget "Day14" */;
@ -754,6 +793,10 @@
26132D2F2774C87D004F0228 = {
CreatedOnToolsVersion = 13.2.1;
};
26132D3F2775D68D004F0228 = {
CreatedOnToolsVersion = 13.2.1;
LastSwiftMigration = 1320;
};
26155451276A6C1C00374D18 = {
CreatedOnToolsVersion = 13.1;
LastSwiftMigration = 1310;
@ -849,6 +892,7 @@
2680ECE62771D82F00CAB23C /* Day21 */,
2680ECF327732A8300CAB23C /* Day22 */,
26132D2F2774C87D004F0228 /* Day23 */,
26132D3F2775D68D004F0228 /* Day24 */,
);
};
/* End PBXProject section */
@ -863,6 +907,15 @@
);
runOnlyForDeploymentPostprocessing = 0;
};
26132D3C2775D68D004F0228 /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
26132D492775D6AC004F0228 /* common.swift in Sources */,
26132D482775D6A5004F0228 /* day24.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
2615544E276A6C1C00374D18 /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
@ -1043,6 +1096,43 @@
};
name = Release;
};
26132D442775D68D004F0228 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
CLANG_ENABLE_MODULES = YES;
CODE_SIGN_STYLE = Automatic;
DEVELOPMENT_TEAM = 722B335UM5;
ENABLE_HARDENED_RUNTIME = YES;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/../Frameworks",
"@loader_path/../Frameworks",
);
MACOSX_DEPLOYMENT_TARGET = 12.1;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
SWIFT_VERSION = 5.0;
};
name = Debug;
};
26132D452775D68D004F0228 /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
CLANG_ENABLE_MODULES = YES;
CODE_SIGN_STYLE = Automatic;
DEVELOPMENT_TEAM = 722B335UM5;
ENABLE_HARDENED_RUNTIME = YES;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/../Frameworks",
"@loader_path/../Frameworks",
);
MACOSX_DEPLOYMENT_TARGET = 12.1;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_VERSION = 5.0;
};
name = Release;
};
26155456276A6C1C00374D18 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
@ -1701,6 +1791,15 @@
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
26132D462775D68D004F0228 /* Build configuration list for PBXNativeTarget "Day24" */ = {
isa = XCConfigurationList;
buildConfigurations = (
26132D442775D68D004F0228 /* Debug */,
26132D452775D68D004F0228 /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
26155458276A6C1C00374D18 /* Build configuration list for PBXNativeTarget "Day14" */ = {
isa = XCConfigurationList;
buildConfigurations = (

453
day24.swift Normal file
View file

@ -0,0 +1,453 @@
import Foundation
@main
struct Day24: Puzzle {
func run() {
let program = readInput()
var alus: [(Alu, min: Int, max: Int)] = [(Alu(), 0, 0)]
for instruction in program {
if case .inp(let register) = instruction {
buildNextAlus(&alus, register: register)
} else {
for index in alus.indices {
alus[index].0.run(instruction)
}
}
}
let serialNumbers = alus
.lazy
.filter { $0.0[Alu.resultRegister] == 0 }
print("Part 1:", serialNumbers.map(\.max).max()!)
print("Part 2:", serialNumbers.map(\.min).min()!)
}
func buildNextAlus(_ alus: inout [(Alu, min: Int, max: Int)], register: RegisterId) {
var table: [Alu: Int] = [:]
var newAlus: [(Alu, Int, Int)] = []
for digit: Alu.Register in 1...9 {
for (alu, oldMin, oldMax) in alus {
var alu = alu
alu[register] = digit
let newMin = oldMin * 10 + Int(digit)
let newMax = oldMax * 10 + Int(digit)
if let index = table[alu] {
newAlus[index].1 = min(newAlus[index].1, newMin)
newAlus[index].2 = max(newAlus[index].2, newMax)
} else {
table[alu] = newAlus.count
newAlus.append((alu, newMin, newMax))
}
}
}
print("Alu count", newAlus.count)
alus = newAlus
}
func readInput() -> [Instruction] {
let scanner = Scanner(string: input)
var program: [Instruction] = []
while !scanner.isAtEnd {
program.append(scanner.instruction())
}
return program
}
}
struct Alu: Hashable {
static let resultRegister: RegisterId = 3
typealias Register = Int
var w: Register = 0
var x: Register = 0
var y: Register = 0
var z: Register = 0
func getValue(_ operand: Operand) -> Register {
switch operand {
case .register(let registerId):
return self[registerId]
case .number(let int):
return Register(int)
}
}
subscript(register: RegisterId) -> Register {
_read {
switch register {
case 0: yield w
case 1: yield x
case 2: yield y
case 3: yield z
default: fatalError()
}
}
_modify {
switch register {
case 0: yield &w
case 1: yield &x
case 2: yield &y
case 3: yield &z
default: fatalError()
}
}
}
mutating func run(_ instruction: Instruction) {
switch instruction {
case .inp:
break
case .add(let registerId, let operand):
self[registerId] += getValue(operand)
case .mul(let registerId, let operand):
self[registerId] *= getValue(operand)
case .div(let registerId, let operand):
self[registerId] /= getValue(operand)
case .mod(let registerId, let operand):
self[registerId] %= getValue(operand)
case .eql(let registerId, let operand):
self[registerId] = (self[registerId] == getValue(operand)) ? 1 : 0
}
}
}
typealias RegisterId = Int
enum Operand {
case register(RegisterId)
case number(Int)
}
enum Instruction {
case inp(RegisterId)
case add(RegisterId, Operand)
case mul(RegisterId, Operand)
case div(RegisterId, Operand)
case mod(RegisterId, Operand)
case eql(RegisterId, Operand)
}
extension Scanner {
func register() -> RegisterId? {
if scanString("w") != nil {
return 0
}
if scanString("x") != nil {
return 1
}
if scanString("y") != nil {
return 2
}
if scanString("z") != nil {
return 3
}
return nil
}
func operand() -> Operand {
if let register = register() {
return .register(register)
}
if let int = scanInt() {
return .number(int)
}
fatalError()
}
func instruction() -> Instruction {
guard let command = scanUpToCharacters(from: .whitespaces),
let target = register()
else {
fatalError()
}
switch command {
case "inp": return .inp(target)
case "add": return .add(target, operand())
case "mul": return .mul(target, operand())
case "div": return .div(target, operand())
case "mod": return .mod(target, operand())
case "eql": return .eql(target, operand())
default: fatalError()
}
}
}
let input = """
inp w
mul x 0
add x z
mod x 26
div z 1
add x 14
eql x w
eql x 0
mul y 0
add y 25
mul y x
add y 1
mul z y
mul y 0
add y w
add y 8
mul y x
add z y
inp w
mul x 0
add x z
mod x 26
div z 1
add x 15
eql x w
eql x 0
mul y 0
add y 25
mul y x
add y 1
mul z y
mul y 0
add y w
add y 11
mul y x
add z y
inp w
mul x 0
add x z
mod x 26
div z 1
add x 13
eql x w
eql x 0
mul y 0
add y 25
mul y x
add y 1
mul z y
mul y 0
add y w
add y 2
mul y x
add z y
inp w
mul x 0
add x z
mod x 26
div z 26
add x -10
eql x w
eql x 0
mul y 0
add y 25
mul y x
add y 1
mul z y
mul y 0
add y w
add y 11
mul y x
add z y
inp w
mul x 0
add x z
mod x 26
div z 1
add x 14
eql x w
eql x 0
mul y 0
add y 25
mul y x
add y 1
mul z y
mul y 0
add y w
add y 1
mul y x
add z y
inp w
mul x 0
add x z
mod x 26
div z 26
add x -3
eql x w
eql x 0
mul y 0
add y 25
mul y x
add y 1
mul z y
mul y 0
add y w
add y 5
mul y x
add z y
inp w
mul x 0
add x z
mod x 26
div z 26
add x -14
eql x w
eql x 0
mul y 0
add y 25
mul y x
add y 1
mul z y
mul y 0
add y w
add y 10
mul y x
add z y
inp w
mul x 0
add x z
mod x 26
div z 1
add x 12
eql x w
eql x 0
mul y 0
add y 25
mul y x
add y 1
mul z y
mul y 0
add y w
add y 6
mul y x
add z y
inp w
mul x 0
add x z
mod x 26
div z 1
add x 14
eql x w
eql x 0
mul y 0
add y 25
mul y x
add y 1
mul z y
mul y 0
add y w
add y 1
mul y x
add z y
inp w
mul x 0
add x z
mod x 26
div z 1
add x 12
eql x w
eql x 0
mul y 0
add y 25
mul y x
add y 1
mul z y
mul y 0
add y w
add y 11
mul y x
add z y
inp w
mul x 0
add x z
mod x 26
div z 26
add x -6
eql x w
eql x 0
mul y 0
add y 25
mul y x
add y 1
mul z y
mul y 0
add y w
add y 9
mul y x
add z y
inp w
mul x 0
add x z
mod x 26
div z 26
add x -6
eql x w
eql x 0
mul y 0
add y 25
mul y x
add y 1
mul z y
mul y 0
add y w
add y 14
mul y x
add z y
inp w
mul x 0
add x z
mod x 26
div z 26
add x -2
eql x w
eql x 0
mul y 0
add y 25
mul y x
add y 1
mul z y
mul y 0
add y w
add y 11
mul y x
add z y
inp w
mul x 0
add x z
mod x 26
div z 26
add x -9
eql x w
eql x 0
mul y 0
add y 25
mul y x
add y 1
mul z y
mul y 0
add y w
add y 2
mul y x
add z y
"""