Skip to content

Commit 642adb3

Browse files
authored
refactor: update wire shuffle implementation to use array of bits (#855)
* refactor: update wire shuffle implementation to use array of bits * Remove update all
1 parent d9571e1 commit 642adb3

File tree

6 files changed

+41
-40
lines changed

6 files changed

+41
-40
lines changed

exercises/concept/bomb-defuser/.docs/hints.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,6 @@
1414

1515
## 3. Implement a wire shuffle generator
1616

17-
- You can return the last bit of a number, `n`, by computing `n % 2`
18-
- You can remove the last bit of a number, `n`, by computing `n / 2`
19-
- You need to make variable copies of function and closure parameters if you want to mutate them.
17+
- There is [a method in Swift which allows you to reverse an array][reverse].
18+
19+
[reverse]: https://developer.apple.com/documentation/swift/array/reverse()

exercises/concept/bomb-defuser/.docs/instructions.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -46,19 +46,19 @@ Implement the function:
4646
makeShuffle(
4747
flipper: @escaping ((String, String, String)) -> (String, String, String),
4848
rotator: @escaping ((String, String, String)) -> (String, String, String)
49-
) -> (UInt8, (String, String, String)) -> (String, String, String)
49+
) -> ([UInt8], (String, String, String)) -> (String, String, String)
5050
```
5151

5252
which takes as input a closure that flips two wires and a closure that rotates the three wires and returns a closure.
5353
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.
54-
This is computed as follows:
54+
The ID number is made of eight bits, and each bit will determine whether to flip or rotate the wires.
5555

5656
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.
5757
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.
5858

5959
```swift
6060
let shuffler = makeShuffle(flipper: flip, rotator: rotate)
6161
// Returns (UInt8, (String, String, String)) -> (String, String, String)
62-
shuffler(155, ("red", "yellow", "blue"))
62+
shuffler([1, 0, 0, 1, 1, 0, 1, 1], ("red", "yellow", "blue"))
6363
// Returns ("red", "blue", "yellow")
6464
```

exercises/concept/bomb-defuser/.meta/Sources/BombDefuser/BombDefuserExemplar.swift

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,29 +1,27 @@
1-
typealias RotationClosure = @Sendable ((String, String, String)) -> (String, String, String)
1+
typealias ChangeClosure = @Sendable ((String, String, String)) -> (String, String, String)
22

3-
let flip: RotationClosure = { (tuple: (String, String, String)) -> (String, String, String) in
3+
let flip: ChangeClosure = { (tuple: (String, String, String)) -> (String, String, String) in
44
let (a, b, c) = tuple
55
return (b, a, c)
66
}
77

8-
let rotate: RotationClosure = { (tuple: (String, String, String)) -> (String, String, String) in
8+
let rotate: ChangeClosure = { (tuple: (String, String, String)) -> (String, String, String) in
99
let (a, b, c) = tuple
1010
return (b, c, a)
1111
}
1212

1313
func makeShuffle(
1414
flipper: @escaping ((String, String, String)) -> (String, String, String),
1515
rotator: @escaping ((String, String, String)) -> (String, String, String)
16-
) -> (UInt8, (String, String, String)) -> (String, String, String) {
17-
{ (key: UInt8, wires: (String, String, String)) -> (String, String, String) in
18-
var bits = key
16+
) -> ([UInt8], (String, String, String)) -> (String, String, String) {
17+
{ (key: [UInt8], wires: (String, String, String)) -> (String, String, String) in
1918
var order = wires
20-
for _ in 1...8 {
21-
if bits.isMultiple(of: 2) {
19+
for keyBit in key.reversed() {
20+
if keyBit == 0 {
2221
order = flipper(order)
2322
} else {
2423
order = rotator(order)
2524
}
26-
bits /= 2
2725
}
2826
return order
2927
}

exercises/concept/bomb-defuser/Package.swift

Lines changed: 21 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -4,25 +4,25 @@
44
import PackageDescription
55

66
let package = Package(
7-
name: "BombDefuser",
8-
products: [
9-
// Products define the executables and libraries a package produces, and make them visible to other packages.
10-
.library(
11-
name: "BombDefuser",
12-
targets: ["BombDefuser"]),
13-
],
14-
dependencies: [
15-
// Dependencies declare other packages that this package depends on.
16-
// .package(url: /* package url */, from: "1.0.0"),
17-
],
18-
targets: [
19-
// Targets are the basic building blocks of a package. A target can define a module or a test suite.
20-
// Targets can depend on other targets in this package, and on products in packages this package depends on.
21-
.target(
22-
name: "BombDefuser",
23-
dependencies: []),
24-
.testTarget(
25-
name: "BombDefuserTests",
26-
dependencies: ["BombDefuser"]),
27-
]
7+
name: "BombDefuser",
8+
products: [
9+
// Products define the executables and libraries a package produces, and make them visible to other packages.
10+
.library(
11+
name: "BombDefuser",
12+
targets: ["BombDefuser"])
13+
],
14+
dependencies: [
15+
// Dependencies declare other packages that this package depends on.
16+
// .package(url: /* package url */, from: "1.0.0"),
17+
],
18+
targets: [
19+
// Targets are the basic building blocks of a package. A target can define a module or a test suite.
20+
// Targets can depend on other targets in this package, and on products in packages this package depends on.
21+
.target(
22+
name: "BombDefuser",
23+
dependencies: []),
24+
.testTarget(
25+
name: "BombDefuserTests",
26+
dependencies: ["BombDefuser"]),
27+
]
2828
)

exercises/concept/bomb-defuser/Sources/BombDefuser/BombDefuser.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,6 @@ typealias ChangeClosure = @Sendable ((String, String, String)) -> (String, Strin
88
func makeShuffle(
99
flipper: @escaping ((String, String, String)) -> (String, String, String),
1010
rotator: @escaping ((String, String, String)) -> (String, String, String)
11-
) -> (UInt8, (String, String, String)) -> (String, String, String) {
11+
) -> ([UInt8], (String, String, String)) -> (String, String, String) {
1212
fatalError("Please implement the makeShuffle(flipper:rotator:) function")
1313
}

exercises/concept/bomb-defuser/Tests/BombDefuserTests/BombDefuserTests.swift

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,8 @@ let RUNALL = Bool(ProcessInfo.processInfo.environment["RUNALL", default: "false"
3131
let wires = ("Red", "Yellow", "Black")
3232
let shuffle = makeShuffle(flipper: flip, rotator: rotate)
3333
let expected = ("Yellow", "Black", "Red")
34-
let got = shuffle(113, wires)
34+
let key: [UInt8] = [0, 1, 1, 1, 0, 0, 0, 1]
35+
let got = shuffle(key, wires)
3536
#expect(
3637
stringify(expected) == stringify(got),
3738
"shuffle(113, (\"Red\", \"Yellow\", \"Black\")): Expected \(expected), got \(got)")
@@ -42,7 +43,8 @@ let RUNALL = Bool(ProcessInfo.processInfo.environment["RUNALL", default: "false"
4243
let wires = ("Purple", "Cyan", "Marigold")
4344
let shuffle = makeShuffle(flipper: flip, rotator: rotate)
4445
let expected = ("Marigold", "Cyan", "Purple")
45-
let got = shuffle(253, wires)
46+
let key: [UInt8] = [1, 1, 1, 1, 1, 1, 0, 1]
47+
let got = shuffle(key, wires)
4648
#expect(
4749
stringify(expected) == stringify(got),
4850
"shuffle(253, (\"Purple\", \"Cyan\", \"Marigold\")): Expected \(expected), got \(got)")
@@ -53,7 +55,8 @@ let RUNALL = Bool(ProcessInfo.processInfo.environment["RUNALL", default: "false"
5355
let wires = ("Brown", "Orange", "White")
5456
let shuffle = makeShuffle(flipper: flip, rotator: rotate)
5557
let expected = ("Brown", "Orange", "White")
56-
let got = shuffle(0, wires)
58+
let key : [UInt8] = [0, 0, 0, 0, 0, 0, 0, 0]
59+
let got = shuffle(key, wires)
5760
#expect(
5861
stringify(expected) == stringify(got),
5962
"shuffle(0, (\"Brown\", \"Orange\", \"White\")): Expected \(expected), got \(got)")

0 commit comments

Comments
 (0)