Counting the total value of Card instances given I am trying to write a function called countHand() that takes in an array of Card instances and counts the total value of the cards given.

The requirements are as follows:


The function returns the value of the cards in the hand as an Int.  It does not use loops or nested functions.
The card values are as follows:

Any Ace preceded by 5 of Diamonds is worth 100 points.
Any odd numeric card (3, 5, 7, 9) of any suit's worth the double of its rank value in points when immediately preceded in the hand by any card of the Hearts. 



Examples:


The hand 3♥, 7♣ has total value of 14. 
The hand 3♣, 7♥ has total value of 0.


Brevity/using one statement functions/closures/case statements are prefered.

Here is the current solution:

enum Suit {
    case Clubs, Diamonds, Hearts, Spades
}

enum Rank {
    case Jack, Queen, King, Ace
    case Num(Int)
}

struct Card {
    let suit: Suit
    let rank: Rank
}


/*
- Generate an array of tuples of 2 card subsequences by zipping the hand array with itself (minus the first element)
- Map over the array examining each pair for value-contributing combinations in a switch statement
- Sum all resulting values
*/
func countHand(hand: [Card]) -&gt; Int {
    return Array(Zip2(hand, dropFirst(hand))).map{(card1: Card, card2: Card)-&gt;Int in
        switch (card1.suit, card1.rank, card2.rank) {
        case (.Hearts, _, .Num(let numRank)) where numRank % 2 == 1:
            return 2 * numRank
        case (.Diamonds, .Num(5), .Ace):
            return 100
        default:
            return 0
        }}.reduce(0, +)
}


countHand([
    Card(suit:.Hearts, rank:.Num(10)),
    Card(suit:.Hearts, rank:.Num(6)),
    Card(suit:.Diamonds, rank:.Num(5)),
    Card(suit:.Clubs, rank:.Ace),
    Card(suit:.Diamonds, rank:.Jack)
    ])// --&gt; prints 110


I am wondering if there is room for improvement of this code, whether it would be brevity/execution speed/memory usage/CPU (extreme cases could be considered i.e a hand with a big number of cards).
First a minor note. It is less efficient to create a temporary Array from the result of Zip2. You can use the function map instead of the method map:

map(Zip2(hand, dropFirst(hand))) { ... }.reduce(0, +)


Second, I believe that having such a complex comment describing what your method does, is a sign that your code can be much more understandable. Usually a good replacement for a comment is a well named function. This is how I would implement your function:

func countHand(hand: [Card]) -&gt; Int {
    func iterateTwoCardsAtATime(hand: [Card], block: (first: Card, second: Card) -&gt; ()) {
        for (first, second) in Zip2(hand, dropFirst(hand)) {
            block(first: first, second: second)
        }
    }

    func scoreForConsecutiveCards(first: Card, second: Card) -&gt; Int {
        switch(first.suit, first.rank, second.rank) {
            case (.Hearts, _, .Num(let numRank)) where numRank % 2 == 1:
                return 2 * numRank
            case (.Diamonds, .Num(5), .Ace):
                return 100
            default:
                return 0
        }
    }

    var sum = 0
    iterateTwoCardsAtATime(hand) { (first, second) in
        sum += scoreForConsecutiveCards(first, second)
    }
    return sum
}


Yes, this is definitely more verbose, but the code is much more clear and doesn't require a comment.

First, a new developer looks at the method and sees that there is a function called iterateTwoCardsAtATime. If they want to verify that it works as expected, they can, but most can assume it works and skip that implementation.

Then they get to scoreForConsecutiveCards. This contains all of the complicated scoring logic which is probably the biggest concern when evaluating this method. It is well contained and distinct from the other logic of the method. The other logic is very utilitarian while this logic is important business logic.

Finally, there is a simple understandable block of code written in English like language to sum up the results of all of the scores.

With modern IDEs with features like code folding, clarity is way more important than brevity.