hi,
glad to hear you've figured this out, and yes, it will be slow with lots of jokers. there are just a lot of loops to run and a lot of possibilities to check, although those loops are hidden in the recursion rather than writing them directly.
for what it's worth, i did hack out something in Obj-C that somewhat mirrors what i wrote earlier in Swift -- and i also added in a check to be sure to not duplicate any regular card (integer in 1...52) in the process. this is what i got (it's very clunky):
#import <Foundation/Foundation.h>
// this is the function that should evaluate a hand that has no jokers
// the value should be non-negative, with higher return values meaning
// better hands
int nonJokerValue(NSArray* handOfCards) {
return 1;
}
int valueHelper(NSArray* part1, NSArray* part2) {
// if part2 is empty, then part1 is all non-jokers, so evaluate it here.
// for now, print it (to see we get all possibilities) and return
// its nonJokerValue
if ([part2 count] == 0) {
NSLog(@"%@", part1);
return nonJokerValue(part1);
}
// otherwise, get first element of part2
NSObject* firstObj = [part2 firstObject];
// form a new part2 with the first object removed
NSMutableArray* newPart2 = [[NSMutableArray alloc] initWithArray: part2];
[newPart2 removeObjectAtIndex:0];
// what we do now depends on the first card in part2. if it's a regular card
// in the deck (a number 1...52), just append it to the newFirstPart
// and make the recursive call
if (![firstObj isEqual: @53]) {
// get a mutable version of the first part
NSMutableArray* newPart1 = [[NSMutableArray alloc] initWithArray: part1];
[newPart1 addObject: firstObj];
return valueHelper(newPart1,newPart2);
}
// no look through all possible substitutions for the joker moving forward
// with a regular card and and use the largest value ever seen
int maxValue = 0;
for (int i = 1; i <= 52; i++) {
// copy the first part
NSMutableArray* newPart1 = [[NSMutableArray alloc] initWithArray: part1];
// skip over the case of repeating a regular card that's already there
if ([newPart1 containsObject: [NSNumber numberWithInt: i]]) {
continue;
}
// append next number to try with the first part
[newPart1 addObject: [NSNumber numberWithInt: i]];
// get the value for this new part1/part2 pair, and update
// maxValue if it's larger
int v = valueHelper(newPart1,newPart2);
if (v>maxValue) {
maxValue = v;
}
}
return maxValue;
}
// main entry point to evaluating a hand of cards
int value(NSArray* someArray) {
return valueHelper(@[], someArray);
}
int main(int argc, const char * argv[]) {
@autoreleasepool {
NSLog(@"%i", value(@[@2, @3, @53, @5, @53]));
}
return 0;
}
feel free to use or ignore, as you wish.
good luck,
DMG