day 20, part 1
This commit is contained in:
parent
7a3715f1f4
commit
aa1b1f017b
2 changed files with 289 additions and 0 deletions
|
@ -26,6 +26,9 @@
|
||||||
26DD9C41258DEAC70082D4F2 /* main.swift in Sources */ = {isa = PBXBuildFile; fileRef = 26DD9C40258DEAC70082D4F2 /* main.swift */; };
|
26DD9C41258DEAC70082D4F2 /* main.swift in Sources */ = {isa = PBXBuildFile; fileRef = 26DD9C40258DEAC70082D4F2 /* main.swift */; };
|
||||||
26DD9C58258DEACF0082D4F2 /* LoadData.swift in Sources */ = {isa = PBXBuildFile; fileRef = 26E2AD3A2581713A00702405 /* LoadData.swift */; };
|
26DD9C58258DEACF0082D4F2 /* LoadData.swift in Sources */ = {isa = PBXBuildFile; fileRef = 26E2AD3A2581713A00702405 /* LoadData.swift */; };
|
||||||
26DD9C59258DEACF0082D4F2 /* Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 26E2ACE5257ED09000702405 /* Extensions.swift */; };
|
26DD9C59258DEACF0082D4F2 /* Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 26E2ACE5257ED09000702405 /* Extensions.swift */; };
|
||||||
|
26DD9C74258F2CEE0082D4F2 /* main.swift in Sources */ = {isa = PBXBuildFile; fileRef = 26DD9C73258F2CEE0082D4F2 /* main.swift */; };
|
||||||
|
26DD9C8C258F2CF80082D4F2 /* LoadData.swift in Sources */ = {isa = PBXBuildFile; fileRef = 26E2AD3A2581713A00702405 /* LoadData.swift */; };
|
||||||
|
26DD9C8D258F2CF80082D4F2 /* Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 26E2ACE5257ED09000702405 /* Extensions.swift */; };
|
||||||
26E2ACD8257ECFFA00702405 /* main.swift in Sources */ = {isa = PBXBuildFile; fileRef = 26E2ACD7257ECFFA00702405 /* main.swift */; };
|
26E2ACD8257ECFFA00702405 /* main.swift in Sources */ = {isa = PBXBuildFile; fileRef = 26E2ACD7257ECFFA00702405 /* main.swift */; };
|
||||||
26E2ACE6257ED09000702405 /* Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 26E2ACE5257ED09000702405 /* Extensions.swift */; };
|
26E2ACE6257ED09000702405 /* Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 26E2ACE5257ED09000702405 /* Extensions.swift */; };
|
||||||
26E2ACE7257ED09000702405 /* Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 26E2ACE5257ED09000702405 /* Extensions.swift */; };
|
26E2ACE7257ED09000702405 /* Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 26E2ACE5257ED09000702405 /* Extensions.swift */; };
|
||||||
|
@ -166,6 +169,15 @@
|
||||||
);
|
);
|
||||||
runOnlyForDeploymentPostprocessing = 1;
|
runOnlyForDeploymentPostprocessing = 1;
|
||||||
};
|
};
|
||||||
|
26DD9C6F258F2CEE0082D4F2 /* CopyFiles */ = {
|
||||||
|
isa = PBXCopyFilesBuildPhase;
|
||||||
|
buildActionMask = 2147483647;
|
||||||
|
dstPath = /usr/share/man/man1/;
|
||||||
|
dstSubfolderSpec = 0;
|
||||||
|
files = (
|
||||||
|
);
|
||||||
|
runOnlyForDeploymentPostprocessing = 1;
|
||||||
|
};
|
||||||
26E2ACD3257ECFFA00702405 /* CopyFiles */ = {
|
26E2ACD3257ECFFA00702405 /* CopyFiles */ = {
|
||||||
isa = PBXCopyFilesBuildPhase;
|
isa = PBXCopyFilesBuildPhase;
|
||||||
buildActionMask = 2147483647;
|
buildActionMask = 2147483647;
|
||||||
|
@ -263,6 +275,8 @@
|
||||||
26BD88A4258C818300E92A8E /* main.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = main.swift; sourceTree = "<group>"; };
|
26BD88A4258C818300E92A8E /* main.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = main.swift; sourceTree = "<group>"; };
|
||||||
26DD9C3E258DEAC70082D4F2 /* day19 */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = day19; sourceTree = BUILT_PRODUCTS_DIR; };
|
26DD9C3E258DEAC70082D4F2 /* day19 */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = day19; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||||
26DD9C40258DEAC70082D4F2 /* main.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = main.swift; sourceTree = "<group>"; };
|
26DD9C40258DEAC70082D4F2 /* main.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = main.swift; sourceTree = "<group>"; };
|
||||||
|
26DD9C71258F2CEE0082D4F2 /* day20 */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = day20; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||||
|
26DD9C73258F2CEE0082D4F2 /* main.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = main.swift; sourceTree = "<group>"; };
|
||||||
26E2ACD5257ECFFA00702405 /* day8 */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = day8; sourceTree = BUILT_PRODUCTS_DIR; };
|
26E2ACD5257ECFFA00702405 /* day8 */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = day8; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||||
26E2ACD7257ECFFA00702405 /* main.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = main.swift; sourceTree = "<group>"; };
|
26E2ACD7257ECFFA00702405 /* main.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = main.swift; sourceTree = "<group>"; };
|
||||||
26E2ACE5257ED09000702405 /* Extensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Extensions.swift; sourceTree = "<group>"; };
|
26E2ACE5257ED09000702405 /* Extensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Extensions.swift; sourceTree = "<group>"; };
|
||||||
|
@ -361,6 +375,13 @@
|
||||||
);
|
);
|
||||||
runOnlyForDeploymentPostprocessing = 0;
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
};
|
};
|
||||||
|
26DD9C6E258F2CEE0082D4F2 /* Frameworks */ = {
|
||||||
|
isa = PBXFrameworksBuildPhase;
|
||||||
|
buildActionMask = 2147483647;
|
||||||
|
files = (
|
||||||
|
);
|
||||||
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
|
};
|
||||||
26E2ACD2257ECFFA00702405 /* Frameworks */ = {
|
26E2ACD2257ECFFA00702405 /* Frameworks */ = {
|
||||||
isa = PBXFrameworksBuildPhase;
|
isa = PBXFrameworksBuildPhase;
|
||||||
buildActionMask = 2147483647;
|
buildActionMask = 2147483647;
|
||||||
|
@ -459,6 +480,7 @@
|
||||||
26BD8863258B2D5300E92A8E /* day17 */,
|
26BD8863258B2D5300E92A8E /* day17 */,
|
||||||
26BD88A3258C818300E92A8E /* day18 */,
|
26BD88A3258C818300E92A8E /* day18 */,
|
||||||
26DD9C3F258DEAC70082D4F2 /* day19 */,
|
26DD9C3F258DEAC70082D4F2 /* day19 */,
|
||||||
|
26DD9C72258F2CEE0082D4F2 /* day20 */,
|
||||||
268D953A25781DD80030EC4D /* Products */,
|
268D953A25781DD80030EC4D /* Products */,
|
||||||
);
|
);
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
|
@ -485,6 +507,7 @@
|
||||||
26BD8862258B2D5300E92A8E /* day17 */,
|
26BD8862258B2D5300E92A8E /* day17 */,
|
||||||
26BD88A2258C818300E92A8E /* day18 */,
|
26BD88A2258C818300E92A8E /* day18 */,
|
||||||
26DD9C3E258DEAC70082D4F2 /* day19 */,
|
26DD9C3E258DEAC70082D4F2 /* day19 */,
|
||||||
|
26DD9C71258F2CEE0082D4F2 /* day20 */,
|
||||||
);
|
);
|
||||||
name = Products;
|
name = Products;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
|
@ -561,6 +584,14 @@
|
||||||
path = day19;
|
path = day19;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
};
|
};
|
||||||
|
26DD9C72258F2CEE0082D4F2 /* day20 */ = {
|
||||||
|
isa = PBXGroup;
|
||||||
|
children = (
|
||||||
|
26DD9C73258F2CEE0082D4F2 /* main.swift */,
|
||||||
|
);
|
||||||
|
path = day20;
|
||||||
|
sourceTree = "<group>";
|
||||||
|
};
|
||||||
26E2ACD6257ECFFA00702405 /* day8 */ = {
|
26E2ACD6257ECFFA00702405 /* day8 */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
|
@ -824,6 +855,23 @@
|
||||||
productReference = 26DD9C3E258DEAC70082D4F2 /* day19 */;
|
productReference = 26DD9C3E258DEAC70082D4F2 /* day19 */;
|
||||||
productType = "com.apple.product-type.tool";
|
productType = "com.apple.product-type.tool";
|
||||||
};
|
};
|
||||||
|
26DD9C70258F2CEE0082D4F2 /* day20 */ = {
|
||||||
|
isa = PBXNativeTarget;
|
||||||
|
buildConfigurationList = 26DD9C77258F2CEE0082D4F2 /* Build configuration list for PBXNativeTarget "day20" */;
|
||||||
|
buildPhases = (
|
||||||
|
26DD9C6D258F2CEE0082D4F2 /* Sources */,
|
||||||
|
26DD9C6E258F2CEE0082D4F2 /* Frameworks */,
|
||||||
|
26DD9C6F258F2CEE0082D4F2 /* CopyFiles */,
|
||||||
|
);
|
||||||
|
buildRules = (
|
||||||
|
);
|
||||||
|
dependencies = (
|
||||||
|
);
|
||||||
|
name = day20;
|
||||||
|
productName = day20;
|
||||||
|
productReference = 26DD9C71258F2CEE0082D4F2 /* day20 */;
|
||||||
|
productType = "com.apple.product-type.tool";
|
||||||
|
};
|
||||||
26E2ACD4257ECFFA00702405 /* day8 */ = {
|
26E2ACD4257ECFFA00702405 /* day8 */ = {
|
||||||
isa = PBXNativeTarget;
|
isa = PBXNativeTarget;
|
||||||
buildConfigurationList = 26E2ACDB257ECFFA00702405 /* Build configuration list for PBXNativeTarget "day8" */;
|
buildConfigurationList = 26E2ACDB257ECFFA00702405 /* Build configuration list for PBXNativeTarget "day8" */;
|
||||||
|
@ -1002,6 +1050,9 @@
|
||||||
26DD9C3D258DEAC70082D4F2 = {
|
26DD9C3D258DEAC70082D4F2 = {
|
||||||
CreatedOnToolsVersion = 12.3;
|
CreatedOnToolsVersion = 12.3;
|
||||||
};
|
};
|
||||||
|
26DD9C70258F2CEE0082D4F2 = {
|
||||||
|
CreatedOnToolsVersion = 12.3;
|
||||||
|
};
|
||||||
26E2ACD4257ECFFA00702405 = {
|
26E2ACD4257ECFFA00702405 = {
|
||||||
CreatedOnToolsVersion = 12.2;
|
CreatedOnToolsVersion = 12.2;
|
||||||
};
|
};
|
||||||
|
@ -1060,6 +1111,7 @@
|
||||||
26BD8861258B2D5300E92A8E /* day17 */,
|
26BD8861258B2D5300E92A8E /* day17 */,
|
||||||
26BD88A1258C818300E92A8E /* day18 */,
|
26BD88A1258C818300E92A8E /* day18 */,
|
||||||
26DD9C3D258DEAC70082D4F2 /* day19 */,
|
26DD9C3D258DEAC70082D4F2 /* day19 */,
|
||||||
|
26DD9C70258F2CEE0082D4F2 /* day20 */,
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
/* End PBXProject section */
|
/* End PBXProject section */
|
||||||
|
@ -1175,6 +1227,16 @@
|
||||||
);
|
);
|
||||||
runOnlyForDeploymentPostprocessing = 0;
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
};
|
};
|
||||||
|
26DD9C6D258F2CEE0082D4F2 /* Sources */ = {
|
||||||
|
isa = PBXSourcesBuildPhase;
|
||||||
|
buildActionMask = 2147483647;
|
||||||
|
files = (
|
||||||
|
26DD9C74258F2CEE0082D4F2 /* main.swift in Sources */,
|
||||||
|
26DD9C8D258F2CF80082D4F2 /* Extensions.swift in Sources */,
|
||||||
|
26DD9C8C258F2CF80082D4F2 /* LoadData.swift in Sources */,
|
||||||
|
);
|
||||||
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
|
};
|
||||||
26E2ACD1257ECFFA00702405 /* Sources */ = {
|
26E2ACD1257ECFFA00702405 /* Sources */ = {
|
||||||
isa = PBXSourcesBuildPhase;
|
isa = PBXSourcesBuildPhase;
|
||||||
buildActionMask = 2147483647;
|
buildActionMask = 2147483647;
|
||||||
|
@ -1633,6 +1695,28 @@
|
||||||
};
|
};
|
||||||
name = Release;
|
name = Release;
|
||||||
};
|
};
|
||||||
|
26DD9C75258F2CEE0082D4F2 /* Debug */ = {
|
||||||
|
isa = XCBuildConfiguration;
|
||||||
|
buildSettings = {
|
||||||
|
CODE_SIGN_STYLE = Automatic;
|
||||||
|
DEVELOPMENT_TEAM = 722B335UM5;
|
||||||
|
ENABLE_HARDENED_RUNTIME = YES;
|
||||||
|
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||||
|
SWIFT_VERSION = 5.0;
|
||||||
|
};
|
||||||
|
name = Debug;
|
||||||
|
};
|
||||||
|
26DD9C76258F2CEE0082D4F2 /* Release */ = {
|
||||||
|
isa = XCBuildConfiguration;
|
||||||
|
buildSettings = {
|
||||||
|
CODE_SIGN_STYLE = Automatic;
|
||||||
|
DEVELOPMENT_TEAM = 722B335UM5;
|
||||||
|
ENABLE_HARDENED_RUNTIME = YES;
|
||||||
|
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||||
|
SWIFT_VERSION = 5.0;
|
||||||
|
};
|
||||||
|
name = Release;
|
||||||
|
};
|
||||||
26E2ACD9257ECFFA00702405 /* Debug */ = {
|
26E2ACD9257ECFFA00702405 /* Debug */ = {
|
||||||
isa = XCBuildConfiguration;
|
isa = XCBuildConfiguration;
|
||||||
buildSettings = {
|
buildSettings = {
|
||||||
|
@ -1936,6 +2020,15 @@
|
||||||
defaultConfigurationIsVisible = 0;
|
defaultConfigurationIsVisible = 0;
|
||||||
defaultConfigurationName = Release;
|
defaultConfigurationName = Release;
|
||||||
};
|
};
|
||||||
|
26DD9C77258F2CEE0082D4F2 /* Build configuration list for PBXNativeTarget "day20" */ = {
|
||||||
|
isa = XCConfigurationList;
|
||||||
|
buildConfigurations = (
|
||||||
|
26DD9C75258F2CEE0082D4F2 /* Debug */,
|
||||||
|
26DD9C76258F2CEE0082D4F2 /* Release */,
|
||||||
|
);
|
||||||
|
defaultConfigurationIsVisible = 0;
|
||||||
|
defaultConfigurationName = Release;
|
||||||
|
};
|
||||||
26E2ACDB257ECFFA00702405 /* Build configuration list for PBXNativeTarget "day8" */ = {
|
26E2ACDB257ECFFA00702405 /* Build configuration list for PBXNativeTarget "day8" */ = {
|
||||||
isa = XCConfigurationList;
|
isa = XCConfigurationList;
|
||||||
buildConfigurations = (
|
buildConfigurations = (
|
||||||
|
|
196
day20/main.swift
Normal file
196
day20/main.swift
Normal file
|
@ -0,0 +1,196 @@
|
||||||
|
import Foundation
|
||||||
|
|
||||||
|
let input = loadData(day: 20)
|
||||||
|
let scanner = Scanner(string: input)
|
||||||
|
|
||||||
|
|
||||||
|
struct Tile {
|
||||||
|
var id: Int
|
||||||
|
var imageData: [Bool]
|
||||||
|
var size: Int
|
||||||
|
|
||||||
|
subscript (_ x: Int, _ y: Int) -> Bool {
|
||||||
|
get { imageData[x + y * size] }
|
||||||
|
set { imageData[x + y * size] = newValue }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
extension Scanner {
|
||||||
|
func tile() -> Tile? {
|
||||||
|
guard string("Tile"),
|
||||||
|
let id = scanInt(),
|
||||||
|
string(":"),
|
||||||
|
let (image, size) = imageData()
|
||||||
|
else { return nil }
|
||||||
|
return Tile(id: id, imageData: image, size: size)
|
||||||
|
}
|
||||||
|
|
||||||
|
func imageData() -> ([Bool], Int)? {
|
||||||
|
var result: [Bool] = []
|
||||||
|
let set = CharacterSet(charactersIn: "#.")
|
||||||
|
var width: Int? = nil
|
||||||
|
while let line = scanCharacters(from: set) {
|
||||||
|
assert(width == nil || line.count == width)
|
||||||
|
width = line.count
|
||||||
|
result.append(contentsOf: line.map { $0 == "#" })
|
||||||
|
}
|
||||||
|
|
||||||
|
guard let w = width else { return nil }
|
||||||
|
|
||||||
|
return (result, w)
|
||||||
|
}
|
||||||
|
|
||||||
|
func tileSet() -> [Int: Tile]? {
|
||||||
|
var result: [Int: Tile] = [:]
|
||||||
|
while !isAtEnd {
|
||||||
|
guard let tile = self.tile() else { return nil }
|
||||||
|
result[tile.id] = tile
|
||||||
|
}
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let tilesById = scanner.tileSet()!
|
||||||
|
|
||||||
|
struct TileReference: Hashable {
|
||||||
|
enum Rotation: CaseIterable {
|
||||||
|
case rotate0, rotate90, rotate180, rotate270
|
||||||
|
}
|
||||||
|
|
||||||
|
var id: Int
|
||||||
|
var flipped: Bool
|
||||||
|
var rotation: Rotation
|
||||||
|
|
||||||
|
subscript (x: Int, y: Int) -> Bool {
|
||||||
|
get {
|
||||||
|
let tile = tilesById[id]!
|
||||||
|
|
||||||
|
var coord = flipped ? (x: tile.size - 1 - x, y: y) : (x: x, y: y)
|
||||||
|
coord = rotation.get(x: coord.x, y: coord.y, size: tile.size)
|
||||||
|
|
||||||
|
return tile[coord.x, coord.y]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var end: Int { tilesById[id]!.size - 1 }
|
||||||
|
}
|
||||||
|
|
||||||
|
extension TileReference.Rotation {
|
||||||
|
func get(x: Int, y: Int, size: Int) -> (x: Int, y: Int) {
|
||||||
|
let e = size - 1
|
||||||
|
switch self {
|
||||||
|
case .rotate0: return (x, y)
|
||||||
|
case .rotate90: return (y, e - x)
|
||||||
|
case .rotate180: return (x, e - y)
|
||||||
|
case .rotate270: return (e - y, x)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct Board {
|
||||||
|
struct Cell {
|
||||||
|
var possible: Array<TileReference>
|
||||||
|
}
|
||||||
|
|
||||||
|
var size: Int
|
||||||
|
var cells: [Cell]
|
||||||
|
|
||||||
|
init<T>(tiles: T) where T: Sequence, T.Element == Int {
|
||||||
|
let orientations = [true, false].flatMap { flipped in TileReference.Rotation.allCases.map { (flipped, $0) } }
|
||||||
|
let allOptions = tiles.flatMap { id in orientations.map { TileReference(id: id, flipped: $0.0, rotation: $0.1 ) } }
|
||||||
|
size = Int(sqrt(Double(tilesById.count)))
|
||||||
|
cells = Array(repeating: Cell(possible: allOptions), count: size*size)
|
||||||
|
assert(size * size == tilesById.count)
|
||||||
|
}
|
||||||
|
|
||||||
|
subscript(x: Int, y: Int) -> Cell {
|
||||||
|
get { cells[x + y * size] }
|
||||||
|
set { cells[x + y * size] = newValue }
|
||||||
|
}
|
||||||
|
|
||||||
|
func coordinate(_ cell: Int) -> (x: Int, y: Int) {
|
||||||
|
let (y, x) = cell.quotientAndRemainder(dividingBy: size)
|
||||||
|
return (x, y)
|
||||||
|
}
|
||||||
|
|
||||||
|
func solve(startingAt: Int = 0) -> Board? {
|
||||||
|
if startingAt >= cells.count { return self }
|
||||||
|
|
||||||
|
let coord = coordinate(startingAt)
|
||||||
|
let left = coord.x > 0 ? self[coord.x - 1, coord.y].chosen! : nil
|
||||||
|
let above = coord.y > 0 ? self[coord.x, coord.y - 1].chosen! : nil
|
||||||
|
|
||||||
|
func matchLeft(_ ref: TileReference) -> Bool {
|
||||||
|
guard let left = left else { return true }
|
||||||
|
return (0...ref.end).allSatisfy { left[left.end, $0] == ref[0, $0] }
|
||||||
|
}
|
||||||
|
|
||||||
|
func matchAbove(_ ref: TileReference) -> Bool {
|
||||||
|
guard let above = above else { return true }
|
||||||
|
return (0...ref.end).allSatisfy { above[$0, above.end] == ref[$0, 0] }
|
||||||
|
}
|
||||||
|
|
||||||
|
for option in cells[startingAt].possible.lazy.filter({ matchLeft($0) && matchAbove($0) }) {
|
||||||
|
var result = self
|
||||||
|
result.cells[startingAt].possible = [option]
|
||||||
|
|
||||||
|
let next = startingAt + 1
|
||||||
|
|
||||||
|
for cell in next..<cells.count {
|
||||||
|
result.cells[cell].possible = result.cells[cell].possible.filter {
|
||||||
|
return $0.id != option.id
|
||||||
|
}
|
||||||
|
|
||||||
|
if result.cells[cell].possible.isEmpty {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if let solution = result.solve(startingAt: next) {
|
||||||
|
return solution
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
extension Board.Cell {
|
||||||
|
var chosen: TileReference? {
|
||||||
|
guard let result = possible.first, possible.count == 1 else {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
guard let solution = Board(tiles: tilesById.keys).solve() else { fatalError() }
|
||||||
|
|
||||||
|
let e = solution.size - 1
|
||||||
|
let ts = tilesById.first!.value.size
|
||||||
|
|
||||||
|
for y in 0...e {
|
||||||
|
for l in 0..<ts {
|
||||||
|
for x in 0...e {
|
||||||
|
let tile = solution[x, y].chosen!
|
||||||
|
for c in 0..<ts {
|
||||||
|
print(tile[c,l] ? "#" : ".", terminator: "")
|
||||||
|
}
|
||||||
|
print(terminator: " ")
|
||||||
|
}
|
||||||
|
print()
|
||||||
|
}
|
||||||
|
print()
|
||||||
|
}
|
||||||
|
|
||||||
|
print()
|
||||||
|
|
||||||
|
print(
|
||||||
|
solution[0,0].chosen!.id *
|
||||||
|
solution[e,0].chosen!.id *
|
||||||
|
solution[0,e].chosen!.id *
|
||||||
|
solution[e,e].chosen!.id
|
||||||
|
)
|
Loading…
Add table
Reference in a new issue