From dc25ae1ea710ff19cdfd3af47770c5377b3dc772 Mon Sep 17 00:00:00 2001 From: Sven Weidauer Date: Tue, 22 Dec 2020 07:46:50 +0100 Subject: [PATCH] Day 22 --- AdventOfCode2020.xcodeproj/project.pbxproj | 93 ++++++++++++++++++++++ day22/main.swift | 87 ++++++++++++++++++++ 2 files changed, 180 insertions(+) create mode 100644 day22/main.swift diff --git a/AdventOfCode2020.xcodeproj/project.pbxproj b/AdventOfCode2020.xcodeproj/project.pbxproj index 250548a..2b1ebd7 100644 --- a/AdventOfCode2020.xcodeproj/project.pbxproj +++ b/AdventOfCode2020.xcodeproj/project.pbxproj @@ -32,6 +32,9 @@ 26DD9CA92590759B0082D4F2 /* main.swift in Sources */ = {isa = PBXBuildFile; fileRef = 26DD9CA82590759B0082D4F2 /* main.swift */; }; 26DD9CC2259075A50082D4F2 /* LoadData.swift in Sources */ = {isa = PBXBuildFile; fileRef = 26E2AD3A2581713A00702405 /* LoadData.swift */; }; 26DD9CD82590767F0082D4F2 /* Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 26E2ACE5257ED09000702405 /* Extensions.swift */; }; + 26DD9CF52591C4000082D4F2 /* main.swift in Sources */ = {isa = PBXBuildFile; fileRef = 26DD9CF42591C4000082D4F2 /* main.swift */; }; + 26DD9D0F2591C40C0082D4F2 /* Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 26E2ACE5257ED09000702405 /* Extensions.swift */; }; + 26DD9D102591C40C0082D4F2 /* LoadData.swift in Sources */ = {isa = PBXBuildFile; fileRef = 26E2AD3A2581713A00702405 /* LoadData.swift */; }; 26E2ACD8257ECFFA00702405 /* main.swift in Sources */ = {isa = PBXBuildFile; fileRef = 26E2ACD7257ECFFA00702405 /* main.swift */; }; 26E2ACE6257ED09000702405 /* Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 26E2ACE5257ED09000702405 /* Extensions.swift */; }; 26E2ACE7257ED09000702405 /* Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 26E2ACE5257ED09000702405 /* Extensions.swift */; }; @@ -190,6 +193,15 @@ ); runOnlyForDeploymentPostprocessing = 1; }; + 26DD9CF02591C4000082D4F2 /* CopyFiles */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = /usr/share/man/man1/; + dstSubfolderSpec = 0; + files = ( + ); + runOnlyForDeploymentPostprocessing = 1; + }; 26E2ACD3257ECFFA00702405 /* CopyFiles */ = { isa = PBXCopyFilesBuildPhase; buildActionMask = 2147483647; @@ -291,6 +303,8 @@ 26DD9C73258F2CEE0082D4F2 /* main.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = main.swift; sourceTree = ""; }; 26DD9CA62590759B0082D4F2 /* day21 */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = day21; sourceTree = BUILT_PRODUCTS_DIR; }; 26DD9CA82590759B0082D4F2 /* main.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = main.swift; sourceTree = ""; }; + 26DD9CF22591C4000082D4F2 /* day22 */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = day22; sourceTree = BUILT_PRODUCTS_DIR; }; + 26DD9CF42591C4000082D4F2 /* main.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = main.swift; sourceTree = ""; }; 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 = ""; }; 26E2ACE5257ED09000702405 /* Extensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Extensions.swift; sourceTree = ""; }; @@ -403,6 +417,13 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + 26DD9CEF2591C4000082D4F2 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; 26E2ACD2257ECFFA00702405 /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; @@ -503,6 +524,7 @@ 26DD9C3F258DEAC70082D4F2 /* day19 */, 26DD9C72258F2CEE0082D4F2 /* day20 */, 26DD9CA72590759B0082D4F2 /* day21 */, + 26DD9CF32591C4000082D4F2 /* day22 */, 268D953A25781DD80030EC4D /* Products */, ); sourceTree = ""; @@ -531,6 +553,7 @@ 26DD9C3E258DEAC70082D4F2 /* day19 */, 26DD9C71258F2CEE0082D4F2 /* day20 */, 26DD9CA62590759B0082D4F2 /* day21 */, + 26DD9CF22591C4000082D4F2 /* day22 */, ); name = Products; sourceTree = ""; @@ -623,6 +646,14 @@ path = day21; sourceTree = ""; }; + 26DD9CF32591C4000082D4F2 /* day22 */ = { + isa = PBXGroup; + children = ( + 26DD9CF42591C4000082D4F2 /* main.swift */, + ); + path = day22; + sourceTree = ""; + }; 26E2ACD6257ECFFA00702405 /* day8 */ = { isa = PBXGroup; children = ( @@ -920,6 +951,23 @@ productReference = 26DD9CA62590759B0082D4F2 /* day21 */; productType = "com.apple.product-type.tool"; }; + 26DD9CF12591C4000082D4F2 /* day22 */ = { + isa = PBXNativeTarget; + buildConfigurationList = 26DD9CF82591C4000082D4F2 /* Build configuration list for PBXNativeTarget "day22" */; + buildPhases = ( + 26DD9CEE2591C4000082D4F2 /* Sources */, + 26DD9CEF2591C4000082D4F2 /* Frameworks */, + 26DD9CF02591C4000082D4F2 /* CopyFiles */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = day22; + productName = day22; + productReference = 26DD9CF22591C4000082D4F2 /* day22 */; + productType = "com.apple.product-type.tool"; + }; 26E2ACD4257ECFFA00702405 /* day8 */ = { isa = PBXNativeTarget; buildConfigurationList = 26E2ACDB257ECFFA00702405 /* Build configuration list for PBXNativeTarget "day8" */; @@ -1104,6 +1152,9 @@ 26DD9CA52590759B0082D4F2 = { CreatedOnToolsVersion = 12.3; }; + 26DD9CF12591C4000082D4F2 = { + CreatedOnToolsVersion = 12.3; + }; 26E2ACD4257ECFFA00702405 = { CreatedOnToolsVersion = 12.2; }; @@ -1164,6 +1215,7 @@ 26DD9C3D258DEAC70082D4F2 /* day19 */, 26DD9C70258F2CEE0082D4F2 /* day20 */, 26DD9CA52590759B0082D4F2 /* day21 */, + 26DD9CF12591C4000082D4F2 /* day22 */, ); }; /* End PBXProject section */ @@ -1299,6 +1351,16 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + 26DD9CEE2591C4000082D4F2 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 26DD9CF52591C4000082D4F2 /* main.swift in Sources */, + 26DD9D0F2591C40C0082D4F2 /* Extensions.swift in Sources */, + 26DD9D102591C40C0082D4F2 /* LoadData.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; 26E2ACD1257ECFFA00702405 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; @@ -1801,6 +1863,28 @@ }; name = Release; }; + 26DD9CF62591C4000082D4F2 /* 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; + }; + 26DD9CF72591C4000082D4F2 /* 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 */ = { isa = XCBuildConfiguration; buildSettings = { @@ -2122,6 +2206,15 @@ defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; + 26DD9CF82591C4000082D4F2 /* Build configuration list for PBXNativeTarget "day22" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 26DD9CF62591C4000082D4F2 /* Debug */, + 26DD9CF72591C4000082D4F2 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; 26E2ACDB257ECFFA00702405 /* Build configuration list for PBXNativeTarget "day8" */ = { isa = XCConfigurationList; buildConfigurations = ( diff --git a/day22/main.swift b/day22/main.swift new file mode 100644 index 0000000..580adb7 --- /dev/null +++ b/day22/main.swift @@ -0,0 +1,87 @@ +import Foundation +let data = loadData(day: 22) +let scanner = Scanner(string: data) + + +guard scanner.string("Player 1:") else { fatalError() } +let p1 = scanner.integers() +var player1Deck = p1 + +guard scanner.string("Player 2:") else { fatalError() } +let p2 = scanner.integers() +var player2Deck = p2 + +assert(player1Deck.count == player2Deck.count) + +while !player1Deck.isEmpty && !player2Deck.isEmpty { + let a = player1Deck.removeFirst() + let b = player2Deck.removeFirst() + + if a > b { + player1Deck.append(contentsOf: [a, b]) + } else { + player2Deck.append(contentsOf: [b, a]) + } +} + +func calculateScore(_ deck: [Int]) -> Int { + deck.reversed().enumerated().reduce(0) { $0 + $1.element * ($1.offset + 1) } +} + +if player2Deck.isEmpty { + print("Player 1 wins", calculateScore(player1Deck)) +} else { + print("Player 2 wins", calculateScore(player2Deck)) +} + +struct PlayedDeck: Hashable { + let player1: [Int] + let player2: [Int] +} +var playedDecks: Set = [] + + +func playGame(deck1: [Int], deck2: [Int]) -> (winner: Bool, score: Int) { + var deck1 = deck1 + var deck2 = deck2 + var playedDecks: Set = [] + + while !deck1.isEmpty && !deck2.isEmpty { + if !playedDecks.insert(PlayedDeck(player1: deck1, player2: deck2)).inserted { + return (true, calculateScore(deck1)) + } + playRound(deck1: &deck1, deck2: &deck2) + } + + let winner = deck2.isEmpty + return (winner, winner ? calculateScore(deck1) : calculateScore(deck2)) +} + +func playRound(deck1: inout [Int], deck2: inout [Int]) { + let a = deck1.removeFirst() + let b = deck2.removeFirst() + + let winner: Bool + if a <= deck1.count && b <= deck2.count { + winner = playGame(deck1: Array(deck1[0.. b + } + + if winner { + deck1.append(contentsOf: [a, b]) + } else { + deck2.append(contentsOf: [b, a]) + } +} + + +player1Deck = p1 +player2Deck = p2 + + let (winner, score) = playGame(deck1: p1, deck2: p2) + if winner { + print("Player 1 wins", score) + } else { + print("Player 2 wins", score) + }