DEV Community

Cover image for Real world Javascript map/reduce, solving the Poker Hand problem

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

Mike Talbot ⭐ on June 16, 2020

You, like me, may have a play at solving some of the daily challenges here on DEV. Usually if the answer is more than one or two lines of some fan...
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.

Collapse
 
gollyjer profile image
Jeremy Gollehon

Love this. Thanks! It's a really good problem to show off "modern" javascript.

Only piece of feedback... the nested ternary in byCountFirst is probably too terse.

Collapse
 
miketalbot profile image
Mike Talbot ⭐

Thanks! Yeah that's fair on the ternary. I'll adjust it.

Collapse
 
miketalbot profile image
Mike Talbot ⭐

Yes, that's in the article list of hands picture and in the solution.

Collapse
 
valemak_com profile image
Макаров Валерий

To take into account the "steel wheel" (straight 5432A) you need to add an imaginary face value of 1:

const order = "123456789TJQKA"

And if the input contains 2, 3, 4, 5 and A, then make the replacement of A by 1:

function SteelWheel(str) { if((str.indexOf('2') + 1) && (str.indexOf('3') + 1) && (str.indexOf('4') + 1) && str.indexOf('5') + 1) && (str.indexOf('A') + 1)) { return str.replace('A', '1') } else { return str } }

Collapse
Collapse
 
julianpugliese profile image
JulianPugliese • Edited

The topic of gambling is very interesting and exciting for me, so I often study similar JavaScript map/reduce. Thanks for your post, I really liked it, as I'm getting ready to launch my project. Now I play a lot in online casinos in my free time, I study various content of sites, and I recommend you a useful source aussiebestcasinos.com/paysafecard-... where you can study a useful review at the best Australian online casino that accept PaySafe 2021, which will help you make a choice and to you.

Collapse
 
wdrfree profile image
wdrfree

Thanks!! I learn about min-max algo!!

Collapse
 
shopalino1 profile image
shopalino

Wow nice post dev.to/miketalbot

Collapse
 
aminacollier profile image
AminaCollier • Edited

Hey there! I totally get where you're coming from with the daily challenges on DEV - sometimes they can be a bit too time-consuming. By the way, I'm new to this forum, but I wanted to chime in and say that I've been having a blast trying out different coding challenges and learning new things. And speaking of new things, have you tried out any Gratis Casino Spielautomaten ohne Anmeldung in Österreich? I've been getting into online slots lately and it's been a fun way to unwind after a long day of coding. Anyway, thanks for sharing your experience with solving the poker hand problem - it's always cool to see how different people approach the same challenge. And thanks for the tip about js-coroutines - I'll have to check it out!