Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions exercises/concept/bomb-defuser/.docs/hints.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,6 @@

## 3. Implement a wire shuffle generator

- You can return the last bit of a number, `n`, by computing `n % 2`
- You can remove the last bit of a number, `n`, by computing `n / 2`
- You need to make variable copies of function and closure parameters if you want to mutate them.
- There is [a method in Swift which allows you to reverse an array][reverse].

[reverse]: https://developer.apple.com/documentation/swift/array/reverse()
6 changes: 3 additions & 3 deletions exercises/concept/bomb-defuser/.docs/instructions.md
Original file line number Diff line number Diff line change
Expand Up @@ -46,19 +46,19 @@ Implement the function:
makeShuffle(
flipper: @escaping ((String, String, String)) -> (String, String, String),
rotator: @escaping ((String, String, String)) -> (String, String, String)
) -> (UInt8, (String, String, String)) -> (String, String, String)
) -> ([UInt8], (String, String, String)) -> (String, String, String)
```

which takes as input a closure that flips two wires and a closure that rotates the three wires and returns a closure.
This returned closure takes the ID number of the stink-bomb and the order of the three wires, and then computes the order the wires need to be cut.
This is computed as follows:
The ID number is made of eight bits, and each bit will determine whether to flip or rotate the wires.

For each bit in the ID number, starting with the rightmost bit, you will apply the `flipper` closure to the wires tuple if the bit is a 0 and you will apply the `rotator` closure if it is a 1 giving the new state of the wires.
After the appropriate closures have been applied for all eight bits of the ID, the final state of the wires is the order they need to be cut in.

```swift
let shuffler = makeShuffle(flipper: flip, rotator: rotate)
// Returns (UInt8, (String, String, String)) -> (String, String, String)
shuffler(155, ("red", "yellow", "blue"))
shuffler([1, 0, 0, 1, 1, 0, 1, 1], ("red", "yellow", "blue"))
// Returns ("red", "blue", "yellow")
```
Original file line number Diff line number Diff line change
@@ -1,29 +1,27 @@
typealias RotationClosure = @Sendable ((String, String, String)) -> (String, String, String)
typealias ChangeClosure = @Sendable ((String, String, String)) -> (String, String, String)

let flip: RotationClosure = { (tuple: (String, String, String)) -> (String, String, String) in
let flip: ChangeClosure = { (tuple: (String, String, String)) -> (String, String, String) in
let (a, b, c) = tuple
return (b, a, c)
}

let rotate: RotationClosure = { (tuple: (String, String, String)) -> (String, String, String) in
let rotate: ChangeClosure = { (tuple: (String, String, String)) -> (String, String, String) in
let (a, b, c) = tuple
return (b, c, a)
}

func makeShuffle(
flipper: @escaping ((String, String, String)) -> (String, String, String),
rotator: @escaping ((String, String, String)) -> (String, String, String)
) -> (UInt8, (String, String, String)) -> (String, String, String) {
{ (key: UInt8, wires: (String, String, String)) -> (String, String, String) in
var bits = key
) -> ([UInt8], (String, String, String)) -> (String, String, String) {
{ (key: [UInt8], wires: (String, String, String)) -> (String, String, String) in
var order = wires
for _ in 1...8 {
if bits.isMultiple(of: 2) {
for keyBit in key.reversed() {
if keyBit == 0 {
order = flipper(order)
} else {
order = rotator(order)
}
bits /= 2
}
return order
}
Expand Down
42 changes: 21 additions & 21 deletions exercises/concept/bomb-defuser/Package.swift
Original file line number Diff line number Diff line change
Expand Up @@ -4,25 +4,25 @@
import PackageDescription

let package = Package(
name: "BombDefuser",
products: [
// Products define the executables and libraries a package produces, and make them visible to other packages.
.library(
name: "BombDefuser",
targets: ["BombDefuser"]),
],
dependencies: [
// Dependencies declare other packages that this package depends on.
// .package(url: /* package url */, from: "1.0.0"),
],
targets: [
// Targets are the basic building blocks of a package. A target can define a module or a test suite.
// Targets can depend on other targets in this package, and on products in packages this package depends on.
.target(
name: "BombDefuser",
dependencies: []),
.testTarget(
name: "BombDefuserTests",
dependencies: ["BombDefuser"]),
]
name: "BombDefuser",
products: [
// Products define the executables and libraries a package produces, and make them visible to other packages.
.library(
name: "BombDefuser",
targets: ["BombDefuser"])
],
dependencies: [
// Dependencies declare other packages that this package depends on.
// .package(url: /* package url */, from: "1.0.0"),
],
targets: [
// Targets are the basic building blocks of a package. A target can define a module or a test suite.
// Targets can depend on other targets in this package, and on products in packages this package depends on.
.target(
name: "BombDefuser",
dependencies: []),
.testTarget(
name: "BombDefuserTests",
dependencies: ["BombDefuser"]),
]
)
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,6 @@ typealias ChangeClosure = @Sendable ((String, String, String)) -> (String, Strin
func makeShuffle(
flipper: @escaping ((String, String, String)) -> (String, String, String),
rotator: @escaping ((String, String, String)) -> (String, String, String)
) -> (UInt8, (String, String, String)) -> (String, String, String) {
) -> ([UInt8], (String, String, String)) -> (String, String, String) {
fatalError("Please implement the makeShuffle(flipper:rotator:) function")
}
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,8 @@ let RUNALL = Bool(ProcessInfo.processInfo.environment["RUNALL", default: "false"
let wires = ("Red", "Yellow", "Black")
let shuffle = makeShuffle(flipper: flip, rotator: rotate)
let expected = ("Yellow", "Black", "Red")
let got = shuffle(113, wires)
let key: [UInt8] = [0, 1, 1, 1, 0, 0, 0, 1]
let got = shuffle(key, wires)
#expect(
stringify(expected) == stringify(got),
"shuffle(113, (\"Red\", \"Yellow\", \"Black\")): Expected \(expected), got \(got)")
Expand All @@ -42,7 +43,8 @@ let RUNALL = Bool(ProcessInfo.processInfo.environment["RUNALL", default: "false"
let wires = ("Purple", "Cyan", "Marigold")
let shuffle = makeShuffle(flipper: flip, rotator: rotate)
let expected = ("Marigold", "Cyan", "Purple")
let got = shuffle(253, wires)
let key: [UInt8] = [1, 1, 1, 1, 1, 1, 0, 1]
let got = shuffle(key, wires)
#expect(
stringify(expected) == stringify(got),
"shuffle(253, (\"Purple\", \"Cyan\", \"Marigold\")): Expected \(expected), got \(got)")
Expand All @@ -53,7 +55,8 @@ let RUNALL = Bool(ProcessInfo.processInfo.environment["RUNALL", default: "false"
let wires = ("Brown", "Orange", "White")
let shuffle = makeShuffle(flipper: flip, rotator: rotate)
let expected = ("Brown", "Orange", "White")
let got = shuffle(0, wires)
let key : [UInt8] = [0, 0, 0, 0, 0, 0, 0, 0]
let got = shuffle(key, wires)
#expect(
stringify(expected) == stringify(got),
"shuffle(0, (\"Brown\", \"Orange\", \"White\")): Expected \(expected), got \(got)")
Expand Down