I'm trying to solve Problem #54 of Project Euler, which is basically evaluating poker hands. My program currently outputs 383, but the answer should be 376. My full code

#include <iostream>
#include <string>
#include <fstream>
#include <vector>
#include <sstream>
using namespace std;

//CLUBS=14;
//SPADES=15;
//HEARTS=16;
//DIAMONDS=17;
int value(char str){
    switch (str){
        case 'A':
        return 1;
        break;
        case '2':
        return 2;
        break;
        case '3':
        return 3;
        break;
        case '4':
        return 4;
        break;
        case '5':
        return 5;
        break;
        case '6':
        return 6;
        break;
        case '7':
        return 7;
        break;
        case '8':
        return 8;
        break;
        case '9':
        return 9;
        break;
        case 'T':
        return 10;
        break;
        case 'J':
        return 11;
        break;
        case 'Q':
        return 12;
        break;
        case 'K':
        return 13;
        break;
        case 'C':
        return 14;
        break;
        case 'S':
        return 15;
        break;
        case 'H':
        return 16;
        break;
        case 'D':
        return 17;
        break;
        default:
        return 0;
        break;
    }
    return 0;
}

bool royal(string str){
    int check[18];
    for (int a=0;a<18;a++)
        check[a]=false;
    for (int i=0;i<10;i++){
        check[value(str.at(i))]++;
    }
    if (check[10]==true&&check[11]==true&&check[12]==true&&check[13]==true&&check[1]==true&&(check[14]==5||check[15]==5||check[16]==5||check[17]==5))
        return true;
    else 
        return false;
}

int straightf(string str){
    int check[18];
    for (int a=0;a<18;a++)
        check[a]=false;
    for (int i=0;i<10;i++){
        check[value(str.at(i))]++;
    }
    for (int i=0;i+4<=13;i++){
        if (check[i]==true&&check[i+1]==true&&check[i+2]==true&&check[i+3]==true&&check[i+4]==true&&(check[14]==5||check[15]==5||check[16]==5||check[17]==5))
            return i+4;
    }
    return false;
}

int fourkind(string str){
    int check[18];
    for (int a=0;a<18;a++)
        check[a]=false;
    for (int i=0;i<10;i+=2){
        check[value(str.at(i))]++;
    }
    for (int i=0;i<=13;i++){
        if (check[i]==4)
        {return i;}
    }
    return false;
}

int threekind(string str){
    int check[18];
    for (int a=0;a<18;a++)
        check[a]=false;
    for (int i=0;i<10;i+=2){
        check[value(str.at(i))]++;
    }
    for (int i=0;i<=13;i++){
        if (check[i]==3)
            return i;
    }
    return false;
}

bool flush(string str){
    int check[18];
    for (int a=0;a<18;a++)
        check[a]=false;
    for (int i=1;i<10;i+=2){
        check[value(str.at(i))]++;
    }
    if (check[14]==5||check[15]==5||check[16]==5||check[17]==5)
        return true;
    else
        return false;
}

int onepair(string str){
    int check[18];
    for (int a=0;a<18;a++)
        check[a]=false;
    for (int i=0;i<10;i+=2){
        check[value(str.at(i))]++;
    }
    for (int i=0;i<=13;i++){
        if (check[i]==2)
            return i;
    }
    return false;
}

int twopair(string str){
    int check[18];
    int count=0;
    for (int a=0;a<18;a++)
        check[a]=false;
    for (int i=0;i<10;i+=2){
        check[value(str.at(i))]++;
    }
    vector<int> pairs;
    for (int i=0;i<=13;i++){
        if (check[i]==2)
            {count++;pairs.push_back(i);}
        if (pairs.size()==2){
            if (pairs[0]>pairs[1])
                return pairs[0];
            else
                return pairs[1];
        }
    }
    return false;
}

int straight(string str){
    int check[18];
    for (int a=0;a<18;a++)
        check[a]=false;
    for (int i=0;i<10;i+=2){
        check[value(str.at(i))]++;
    }
    for (int i=0;i+4<=13;i++){
        if (check[i]==true&&check[i+1]==true&&check[i+2]==true&&check[i+3]==true&&check[i+4]==true)
            return i+4;
    }
    return false;
}

int fullh(string str){
    if (onepair(str)!=0&&threekind(str)>0)
        return threekind(str);
    else
        return false;
}

int high(string str,int rank){
    vector<int> max;
    for (int i=0;i<9;i+=2){
    if (value(str.at(i))==1)
        {max.push_back(14);}
    else
        {max.push_back(value(str.at(i)));}
    }
    sort(max.begin(), max.end());
    return max[max.size()-1-rank+1];
}

bool todeath(string str){
    int i=1;
    string one=str.substr(0,10);
    string two=str.substr(10,10);
    for(i=1;;i++){
        if (high(one,i)>high(two,i))
            return 0;
        else if (high(one,i)<high(two,i))
            return 1;
    }
    return 0;
}
bool win(string str){
    //Different hands ranked from 0 to 9
    int rank1,rank2;
    string one=str.substr(0,10);
    string two=str.substr(10,10);
    //give ranking for one.
    if (royal(one))
        rank1=9;
    else if (straightf(one)>0)
        rank1=8;
    else if (fourkind(one)>0)
        rank1=7;
    else if (fullh(one)>0)
        rank1=6;
    else if (flush(one)>0)
        rank1=5;
    else if (straight(one)>0)
        rank1=4;
    else if (threekind(one)>0)
        rank1=3;
    else if (twopair(one)>0)
        rank1=2;
    else if (onepair(one)>0)
        rank1=1;
    else
        rank1=0;
    //give ranking for two.
    if (royal(two))
        rank2=9;
    else if (straightf(two)>0)
        rank2=8;
    else if (fourkind(two)>0)
        rank2=7;
    else if (fullh(two)>0)
        rank2=6;
    else if (flush(two)>0)
        rank2=5;
    else if (straight(two)>0)
        rank2=4;
    else if (threekind(two)>0)
        rank2=3;
    else if (twopair(two)>0)
        rank2=2;
    else if (onepair(two)>0)
        rank2=1;
    else
        rank2=0;
    if (rank1>rank2)
        return 0;
    else if (rank2>rank1)
        return 1;
    else if (rank1==rank2){
        if (rank1==8){
            if (straightf(one)>straightf(two))
                return 0;
            else if (straightf(one)<straightf(two))
                return 1;
            else
                return todeath(str);
        }
        else if (rank1==7){
            if (fourkind(one)>fourkind(two))
                return 0;
            else if (fourkind(two)>fourkind(one))
                return 1;
            else 
                return todeath(str);
        }
        else if (rank1==6){
            if (fullh(one)>fullh(two))
                return 0;
            else if (fullh(one)>fullh(two))
                return 1;
            else
                return todeath(str);
        }
        else if (rank1==5)
            return todeath(str);
        else if (rank1==4){
            if (straight(one)>straight(two))
                return 0;
            else if (straight(one)<straight(two))
                return 1;
            else 
                return todeath(str);}
        else if (rank1==3){
            if (threekind(one)>threekind(two))
                return 0;
            else if (threekind(one)<threekind(two))
                return 1;
            else 
                return todeath(str);
        }
        else if (rank1==2){
            if (twopair(one)>twopair(two))
                return 0;
            else if (twopair(one)<twopair(two))
                return 1;
            else
                return todeath(str);
        }
        else if (rank1==1){
            if (onepair(one)>onepair(two))
                return 0;
            else if (onepair(one)<onepair(two))
                return 1;
            else
                return todeath(str);
        }
        else if (rank1==0)
            return todeath(str);
    }
    return 0;
}

int main(){
    vector<string> raw;  
    string temp;
    //get data
    ifstream file ("Problem54.txt");
    if (file.is_open()){
        while(file.good()){
            getline(file,temp);
            raw.push_back(temp);
        }
        file.close();
    }
    vector<string> second(raw.size(),"");
    //remove spaces from everything
    for (unsigned i=0;i<raw.size()-1;i++){
        string a;
        stringstream ss(raw[i]);
        while (getline(ss,a,' ')){
            second[i].append(a);
        }}
        int count=0,count2=0;
        for (unsigned i=0;i<second.size()-1;i++){
            if (win(second[i])==0 )
                {count++;}
        }
        cout<<count<<endl<<count2<<endl;}

Basically, it just creates a function to check for different types of hands and one last function to consolidate all of this. It works with all the examples on the Project Euler site and I just can't get my head around why I isn't working. Thanks in advance.

I also noticed that many of the hands are ranked at the high card. Not sure if it even means anything. Just a side note.

TrustyTony commented: Two days without reading replies -3

Recommended Answers

All 2 Replies

Are you checking for straights
1 2 3 4 5 and
10 J Q K A

How your code separates hands with same highest card but different second highest?

Please use Code from editor, do not link to code out of the site.

I have lost my Python code for the task in hard disc crash, but I recoded it today. I could check your list of line numbers of wins against mine, and post the hands which you get wrong. I also had one stupid mistake with not having needed parenthesis in one of the type of hand before I got it right

For me your code crashes for sort as you have not

#include <algorithm>

After putting it in, your code gives me 'memory can not be read' error in CodeBlocks, maybe uninstantiated pointer?

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.