Created
June 14, 2020 00:01
-
-
Save rayfix/9053908eccfad6cb744dc6048fa2b8dc to your computer and use it in GitHub Desktop.
SetCard abstraction
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
func combinations<S1: Sequence, S2: Sequence>(_ sequence1: S1, _ sequence2: S2) -> AnySequence<(S1.Element, S2.Element)> { | |
AnySequence( | |
sequence1.lazy.flatMap { element1 in | |
sequence2.lazy.map { element2 in | |
(element1, element2) | |
} | |
} | |
) | |
} | |
func combinations<S1: Sequence, S2: Sequence, S3: Sequence>(_ sequence1: S1, _ sequence2: S2, _ sequence3: S3) -> AnySequence<(S1.Element, S2.Element, S3.Element)> { | |
AnySequence ( | |
combinations(combinations(sequence1, sequence2), sequence3).lazy.map { ($0.0.0, $0.0.1, $0.1)} | |
) | |
} | |
/// Produce all of the combinations of elements in each sequence. | |
/// - Note: | |
/// - Complexity: O(1) | |
/// - Parameters: | |
/// - sequence1: Input sequence. | |
/// - sequence2: Input sequence. | |
/// - sequence3: Input sequence. | |
/// - sequence4: Input sequence. | |
/// - Returns: All of the combinations. | |
func combinations<S1: Sequence, S2: Sequence, S3: Sequence, S4: Sequence>(_ sequence1: S1, _ sequence2: S2, _ sequence3: S3, _ sequence4: S4) -> AnySequence<(S1.Element, S2.Element, S3.Element, S4.Element)> { | |
AnySequence ( | |
combinations(combinations(sequence1, sequence2, sequence3), sequence4).lazy.map { ($0.0.0, $0.0.1, $0.0.2, $0.1)} | |
) | |
} | |
struct SetCard: Hashable { | |
enum Number: CaseIterable, Hashable { | |
case one, two, three | |
} | |
enum Shape: CaseIterable, Hashable { | |
case diamond, squiggle, oval | |
} | |
enum Shading: CaseIterable, Hashable { | |
case solid, stripped, open | |
} | |
enum Color: CaseIterable, Hashable { | |
case red, green, purple | |
} | |
var number: Number | |
var shape: Shape | |
var shading: Shading | |
var color: Color | |
} | |
extension SetCard { | |
static func makeDeck() -> [SetCard] { | |
combinations(Number.allCases, Shape.allCases, | |
Shading.allCases, Color.allCases).map(Self.init) | |
} | |
} | |
extension SetCard { | |
private static func pickAttribute<A: CaseIterable & Hashable>(_ a: A, _ b: A) -> A { | |
a == b ? a : A.allCases.filter { $0 != a && $0 != b }.first! | |
} | |
static func complete(_ a: SetCard, _ b: SetCard) -> SetCard { | |
SetCard(number: pickAttribute(a.number, b.number), | |
shape: pickAttribute(a.shape, b.shape), | |
shading: pickAttribute(a.shading, b.shading), | |
color: pickAttribute(a.color, b.color)) | |
} | |
} | |
extension Collection where Element == SetCard { | |
private func attributeIsSet<A: Hashable>(accessor: (SetCard) -> A) -> Bool { | |
let attributes = self.reduce(into: Set<A>()) { $0.insert(accessor($1)) } | |
return attributes.count == 1 || attributes.count == 3 | |
} | |
func isSet() -> Bool { | |
attributeIsSet(accessor: \.number) && | |
attributeIsSet(accessor: \.shape) && | |
attributeIsSet(accessor: \.shading) && | |
attributeIsSet(accessor: \.color) | |
} | |
} | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment