DEV Community

Discussion on: Real world Javascript map/reduce, solving the Poker Hand problem

Collapse
 
miketalbot profile image
Mike Talbot ⭐ • Edited

The original challenge specified no low straights from the Ace, but it jarred with me and this routine is easily adjustable to support it. We just have to worry about sort orders during straights and to recognise the straight in the first place. The following updated version of getHandDetails() manages both of these:

const order = "23456789TJQKA"
function getHandDetails(hand) {
    const cards = hand.split(" ")
    const faces = cards.map(a => String.fromCharCode([77 - order.indexOf(a[0])])).sort()
    const suits = cards.map(a => a[1]).sort()
    const counts = faces.reduce(count, {})
    const duplicates = Object.values(counts).reduce(count, {})
    const flush = suits[0] === suits[4]
    const first = faces[0].charCodeAt(0)
    //Also handle low straight
    const lowStraight = faces.join("") === "AJKLM"
    faces[0] = lowStraight ? "N" : faces[0]
    const straight = lowStraight || faces.every((f, index) => f.charCodeAt(0) - first === index)
    let rank =
        (flush && straight && 1) ||
        (duplicates[4] && 2) ||
        (duplicates[3] && duplicates[2] && 3) ||
        (flush && 4) ||
        (straight && 5) ||
        (duplicates[3] && 6) ||
        (duplicates[2] > 1 && 7) ||
        (duplicates[2] && 8) ||
        9

    return { rank, value: faces.sort(byCountFirst).join("") }

    function byCountFirst(a, b) {
        //Counts are in reverse order - bigger is better
        const countDiff = counts[b] - counts[a]
        if (countDiff) return countDiff // If counts don't match return
        return b > a ? -1 : b === a ? 0 : 1
    }
    function count(c, a) {
        c[a] = (c[a] || 0) + 1
        return c
    }
}

We perform a simple string check for the low straight and then switch the order of 'A' to 'N' for aces in this circumstance.