Skip to content

Commit 844d51b

Browse files
author
Matthew Judy
committed
Complete challenge 2023-03.
1 parent 60aff9c commit 844d51b

File tree

1 file changed

+64
-20
lines changed

1 file changed

+64
-20
lines changed

Sources/2023/03/GearRatios.swift

Lines changed: 64 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -61,26 +61,51 @@ import Shared
6161
/// Of course, the actual engine schematic is much larger. **What is the sum of
6262
/// all of the part numbers in the engine schematic?**
6363
///
64+
/// # Part Two
65+
///
66+
/// The engineer finds the missing part and installs it in the engine! As the
67+
/// engine springs to life, you jump in the closest gondola, finally ready to
68+
/// ascend to the water source.
69+
///
70+
/// You don't seem to be going very fast, though. Maybe something is still
71+
/// wrong? Fortunately, the gondola has a phone labeled "help", so you pick it
72+
/// up and the engineer answers.
73+
///
74+
/// Before you can explain the situation, she suggests that you look out the
75+
/// window. There stands the engineer, holding a phone in one hand and waving
76+
/// with the other. You're going so slowly that you haven't even left the
77+
/// station. You exit the gondola.
78+
///
79+
/// The missing part wasn't the only issue - one of the gears in the engine is
80+
/// wrong. A **gear** is any `*` symbol that is adjacent to **exactly two part
81+
/// numbers**. Its **gear ratio** is the result of multiplying those two
82+
/// numbers together.
83+
///
84+
/// This time, you need to find the gear ratio of every gear and add them all
85+
/// up so that the engineer can figure out which gear needs to be replaced.
86+
///
87+
/// Consider the above engine schematic again. In this schematic, there are
88+
/// **two** gears. The first is in the top left; it has part numbers
89+
/// `467` and `35`, so its gear ratio is `16345`. The second gear is in the
90+
/// lower right; its gear ratio is `451490`. (The `*` adjacent to 617 is not a
91+
/// gear because it is only adjacent to one part number.) Adding up all of the
92+
/// gear ratios produces **`467835`**.
93+
///
94+
/// **What is the sum of all of the gear ratios in your engine schematic?**
6495
///
6596
@main
6697
struct GearRatios: AsyncParsableCommand
6798
{
68-
// /// Adds a `--mode` option to the command, which allows the command's logic
69-
// /// to branch and handle requirements of either "Part One" or "Part Two".
70-
// /// The option must be followed by a value from this enumeration.
71-
// enum Mode: String, ExpressibleByArgument, CaseIterable
72-
// {
73-
// case <#modeA#>
74-
// case <#modeB#>
75-
// }
76-
// @Option(help: "'<#modeA#>' or '<#modeB#>'")
77-
// var mode: Mode
78-
79-
// /// Adds a flag to the command, named for the behavioral difference in
80-
// /// "Part Two." This allows the command's logic to branch and handle the
81-
// /// requirements of either "Part One" or "Part Two".
82-
// @Flag(help: "Search for both cardinal values ('one', 'two', ...) and integers.")
83-
// var <#partTwoDifference#>: Bool = false
99+
/// Adds a "sub-command" argument to the command, which allows the logic
100+
/// to branch and handle requirements of either "Part One" or "Part Two".
101+
/// The argument must be a value from this enumeration.
102+
enum Mode: String, ExpressibleByArgument, CaseIterable
103+
{
104+
case partNumberSum
105+
case gearRatioSum
106+
}
107+
108+
@Argument var mode: Mode
84109
}
85110

86111

@@ -95,6 +120,11 @@ struct Part
95120
var description : String { "(L:\(self.line), C:\(self.column)" }
96121
}
97122

123+
enum Glossary: Character
124+
{
125+
case gear = "*"
126+
}
127+
98128
let character : Character
99129
let location : Location
100130
}
@@ -113,6 +143,8 @@ struct Part
113143
self.symbol = symbol
114144
self.numbers = identifiers.map(\.number)
115145
}
146+
147+
var isGear: Bool { (self.symbol.character == Symbol.Glossary.gear.rawValue) && (self.numbers.count == 2) }
116148
}
117149

118150

@@ -122,7 +154,7 @@ extension GearRatios
122154
{
123155
mutating func run() async throws
124156
{
125-
let input: AsyncLineSequence = URL.homeDirectory.appending(path: "Desktop/input.txt").lines
157+
let input: AsyncLineSequence = FileHandle.standardInput.bytes.lines
126158
let lines = try await input.reduce(into: [])
127159
{
128160
$0.append($1)
@@ -174,9 +206,21 @@ extension GearRatios
174206
)
175207
}
176208

177-
let partNumberSum: Int = parts.flatMap(\.numbers).reduce(0, +)
178-
179-
print(partNumberSum)
209+
switch self.mode
210+
{
211+
case .partNumberSum:
212+
let partNumberSum = parts.reduce(0) { $0 + $1.numbers.reduce(0, +) }
213+
print(partNumberSum)
214+
215+
216+
case .gearRatioSum:
217+
let gearRatioSum = parts.reduce(0)
218+
{
219+
return if ($1.isGear == false) { $0 }
220+
else { ($0 + $1.numbers.reduce(1, *)) }
221+
}
222+
print(gearRatioSum)
223+
}
180224
}
181225
}
182226

0 commit comments

Comments
 (0)