Reputation: 12314
Looking to optimise my code to get even more speed. Currently the code detects any poker hand and takes ~350ms to do 32000 iterations. The function to detect straights, however seems to be taking the biggest individual chunk of time at about 160ms so looking if any way to optimise it further.
The whole code was originally written in php since that is what I'm most familiar with but despite php 7's speed boost it still seems to be slower than javascript. What I found when translating to javascript though is that many of php's built in functions are not present in javascript which caused unforeseen slowdowns. It is still faster overall than the original php code though but I'm looking to see if it can be optimised more. Perhaps the answer is no, but I thought I'd check anyway.
I have written the functions range
and arrays_equal
since these are either missing from javascript or don't quite work properly.
function straight(handval) {
if (arrays_equal(handval.slice(0, 4),[2, 3, 4, 5]) && handval[handval.length-1] == 14) {//if is Ace 2345
return [4,14];
}
else {//if normal straight
for (let i = handval.length - 5; i >= 0; i--) {
let subhand = handval.slice(i, i + 5);
if (arrays_equal(subhand, range(subhand[0], subhand[subhand.length-1]))) {
return [4,subhand[4]];
}
} return [0]
}
}
function arrays_equal(a,b) { return !!a && !!b && !(a<b || b<a); }
function range(start, end) {
let arr = [];
for (let i = start; i <= end; i++) {
arr.push(i);
}
return arr;
}
Handval comes in as a simple array of 5-7 elements of numbers from 2-14 representing the cards So for example it could be [6,8,4,11,13,2]
or [8,4,13,8,10]
.
EDIT: The function is called and sorted at the same time with this code:
straight(handval.slice(0).sort(sortNumber));
function sortNumber(a,b) { return a - b; }
Upvotes: 0
Views: 291
Reputation: 138267
You could just go from right to left and count the number of sequential numbers:
function straight(handval) {
if([2, 3, 4, 5].every((el, i) => handval[i] === el) && handval[handval.length-1] === 14)
return [4, 14];
let count = 1;
for(let i = handval.length - 1; i >= 1; i -= 1) {
if(handval[i] === handval[i - 1] + 1) {
count += 1;
if(count === 5) return [ 4, handval[i + 3] ];
} else {
count = 1;
}
}
return [0];
}
That is way faster as it:
1) does not create intermediate arrays on every iteration, which you did with range
and slice
2) does not compare arrays as strings, which requires a typecast and a string comparison, which is way slower than comparing two numbers against each other
3) It does not check all 3 ranges on its own (1 - 5, 2 - 6, 3 - 7), but does all that in one run, so it only iterates 5 positions instead of 3 x 5.
Upvotes: 1