Code covered by the BSD License

# Solution to Project Euler Problem 54

### Husam Aldahiyat (view profile)

01 Jul 2009 (Updated )

How many hands did player one win in the game of poker?

euler54
```function output = euler54
% Solves Project Euler Problem 54
% numandina@gmail.com

%% Storing Hands in Cells

fid = fopen('poker.txt');
c = textscan(fid,'%c');
nz = c{1}; % in nz is one column containing all the characters

% we have 1,000 hands for each player, and nz is of length 20,000 characters.
% this is because each hand for each player will have 10 characters (5
% cards, which each card given a number and a suit).

% in the next step we will take each hand for each player and store them in
% cells (take each consecutive 20 characters, split them in half, then
% store each ten as one hand for one player). check the next loop to see this.

p1 = cell(1e3,1);
p2 = cell(1e3,1);

c = 0;

for k = 1:2:2e3

c = c + 1;

p1{c} = nz(k*10-9:k*10); % each consecutive 10 characters constitute one hand
p2{c} = nz(k*10+1:k*10+10);

end

% by now we will have two 1000-element cells (p1,p2), with each of their
% elements containing one hand for each player (i.e. p1{3} means third hand
% for player 1, which will be playing against p2{3}).

%% Formatting

s = 0; % number of hands won by player 1

for k = 1:1e3 % go through each of the 1000 hands

h1 = p1{k}; % hand for p1 as column vector
h2 = p2{k};	% hand for p2

c1 = repmat(' ',5,2); % preallocating a 5x2 matrix for each hand
c2 = repmat(' ',5,2);

% for the next loop, we already have each hand as 10 consectuve
% characters (value, suit), so take each consecutive two characters
% and store them as a row.
for j = 1:5

c1(j,:) = h1(j*2-1:j*2).'; % reshape each hand as 5x2 matrix
c2(j,:) = h2(j*2-1:j*2).';

end

% now we will have two hands, c1 and c2, with each having values for
% first column and suits for second column. Thus begin the calculations
% for each hand.

%% Main Calculations

[r1,v1] = getrank(c1); % get ranks for both hands, as well as rank values
[r2,v2] = getrank(c2);

if r1 > r2 % if p1's rank is higher than p2's rank

s = s + 1;

elseif r1 == r2 % if their ranks are equal, compare rank values

if v1 > v2 % if p1's rank value is the highest

s = s + 1;

elseif v1 == v2 % if their values are equal, compare second values, and so on...

if r1 == 7 % for example, if two four of a kinds are equal in value, compare fifth card values

% since four cards of each hand are equal, comparing sums
% is like comparing fifth card values
if sum(findv(c1)) > sum(findv(c1))

s = s + 1;

end

elseif r1 == 6 % if two full houses have the same value (for the three of a kind), compare the pair values

% since three card of each hand are equal, and the
% remaining two cards of each hand constitute a pair, then
% comparing sums is like comparing pair values
if sum(findv(c1)) > sum(findv(c1))

s = s + 1;

end

elseif r1 == 5 % if the two hands are full suits, compare second highest card of both hands, if they are equal, compare second highest cards,and so on

tc1 = sort(findv(c1));
tc2 = sort(findv(c2));

ti = 4;

% keep changing index from second bottom (since bottom is
% highest and has alread been checked) upward until we find
% an index where the two hand cards don't have the same value
while ti > 0 && tc1(ti) == tc2(ti)

ti = ti - 1;

end

if tc1(ti) > tc2(ti)

s = s + 1;

end

elseif r1 == 3 % if both values of three of a kind hands are equal

tc1 = sort(findv(c1));
tc2 = sort(findv(c2));

% set repeated three cards as 0 for each hand
tc1(tc1 == v1) = 0;
tc2(tc2 == v2) = 0;

% if max of remaining cards of hands is different
if max(tc1) > max(tc2)

s = s + 1;

% else if max of both hands is also equal, check last card
elseif max(tc1) == max(tc2)

% sums are equivalent to compairing last card values,
% since all other card values are equal for both hands
if sum(tc1) > sum(tc2)

s = s + 1;

end

end

elseif r1 == 2 % if values of two two pair hands are equal

tc1 = sort(findv(c1));
tc2 = sort(findv(c2));

% remove cards of the highest pair in each hand
tc1(tc1 == v1) = [];
tc2(tc2 == v2) = [];

% find new value of hand 1 (value of second pair)
if tc1(1) == tc1(2)

v1n = tc1(1);

else

v1n = tc1(2);

end

% find new value of hand 2 (value of second pair)
if tc2(1) == tc2(2)

v2n = tc2(1);

else

v2n = tc2(2);

end

% compare new values
if v1n > v2n

s = s + 1;

% if new values are equal too
elseif v1n == v2n

% remove the second pair from both hands
tc1(tc1 == v1n) = [];
tc2(tc2 == v2n) = [];

% now we are left with one card for each hand
if tc1 > tc2

s = s + 1;

end

end

elseif r1 == 1 % if two one pair hands are equal in value

tc1 = sort(findv(c1));
tc2 = sort(findv(c2));

% remove the cards that constitute the pair in each hand
tc1(tc1 == v1) = [];
tc2(tc2 == v2) = [];

% we are left with three different cards for each hand.
% just like we did before, we first find a max value for
% each hand that is different than the one in the other
ti = 3;

while ti > 0 && tc1(ti) == tc2(ti)

ti = ti - 1;

end

% then we compare the different max values
if tc1(ti) > tc2(ti)

s = s + 1;

end

else % if the two hands are nothing special (all cards are different)

% again, as we did before, see which max value of each hand
% is different than the one in the other hand, then compare
tc1 = sort(findv(c1));
tc2 = sort(findv(c2));

tc1(tc1 == v1) = [];
tc2(tc2 == v2) = [];

ti = 4;

while ti > 0 && tc1(ti) == tc2(ti)

ti = ti - 1;

end

if tc1(ti) > tc2(ti)

s = s + 1;

end

end

end

end

end

output = s; % semicolon at the end so you wouldn't cheat! :)
end```