Last active
August 29, 2015 14:24
-
-
Save vladkorotnev/2b0f131d7059e809d119 to your computer and use it in GitHub Desktop.
Пьяница — доказательство неразрешимости игры в случае неслучайного и одинакового порядка взятия карт со стола в ротацию
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// | |
// main.m | |
// Drunk | |
// | |
// Created by Akasaka Ryuunosuke on 08/07/15. | |
// Copyright (c) 2015 Akasaka Ryuunosuke. All rights reserved. | |
// | |
#import <Foundation/Foundation.h> | |
#import "NSArray+pull.h" | |
int main(int argc, const char * argv[]) { | |
NSArray *cards = @[@6,@7,@8,@9,@10,@1000,@1001,@1002,@1003]; | |
NSArray *trans = @[@"J",@"Q",@"K",@"A"]; | |
@autoreleasepool { | |
// insert code | |
if (argc == 1) { | |
// show help | |
printf("%s version 1.0\n", argv[0]); | |
printf("--random - use random deck\n"); | |
printf("--verbose - print all moves\n"); | |
printf("--debug - print decks after all moves and wait for enter to confirm\n"); | |
printf("--reverse - reverse desk when taking cards back into deck\n"); | |
printf("--shuffle-desk - reverse desk when taking cards back into deck\n"); | |
printf("--deck 6/7/8/9/10/J/Q/K/A,... 6/7/8/9/10/J/Q/K/A,... - define custom deck per player\n"); | |
return 1; | |
} | |
NSMutableArray * deck1 = [NSMutableArray new]; | |
NSMutableArray * deck2 = [NSMutableArray new]; | |
bool verbose = false, debug=false, shuffle=false, reverse=false; | |
#define VERBOSE_OUT if(verbose) | |
#define DEBUG_OUT if(debug) | |
for (int i = 0; i < argc; i++) { | |
if ([[NSString stringWithUTF8String:argv[i]]isEqualToString:@"--verbose"]) { | |
verbose=true; | |
} | |
else if ([[NSString stringWithUTF8String:argv[i]]isEqualToString:@"--debug"]) { | |
verbose=true; debug=true; | |
} | |
else if ([[NSString stringWithUTF8String:argv[i]]isEqualToString:@"--shuffle-desk"]) { | |
shuffle=true; | |
} else if ([[NSString stringWithUTF8String:argv[i]]isEqualToString:@"--reverse"]) { | |
reverse=true; | |
} | |
} | |
if (argc >= 2 && [[NSString stringWithUTF8String:argv[1]]isEqualToString:@"--random"]) { | |
if ([[NSString stringWithUTF8String:argv[1]]isEqualToString:@"--random"]) { | |
NSMutableArray *c = cards.mutableCopy; | |
[c addObjectsFromArray:cards]; | |
[c addObjectsFromArray:cards]; | |
[c addObjectsFromArray:cards]; | |
[c shuffle]; | |
for(int i=0; i < c.count; i++ ) { | |
NSNumber *n = c[i]; | |
if (i % 2 == 0) { | |
[deck1 addObject:n]; | |
} else { | |
[deck2 addObject:n]; | |
} | |
} | |
} else { | |
printf("wrong arg %s", argv[1]); | |
return 1; | |
} | |
} else if (argc>= 4 && [[NSString stringWithUTF8String:argv[1]]isEqualToString:@"--deck"]) { | |
NSArray*deckArg = [[[[[[NSString stringWithUTF8String:argv[2]].uppercaseString | |
stringByReplacingOccurrencesOfString:@"J" | |
withString:@"1000"] | |
stringByReplacingOccurrencesOfString:@"Q" | |
withString:@"1001"] | |
stringByReplacingOccurrencesOfString:@"K" | |
withString:@"1002"] | |
stringByReplacingOccurrencesOfString:@"A" | |
withString:@"1003"] | |
componentsSeparatedByString:@","]; | |
NSArray*deckArg2 = [[[[[[NSString stringWithUTF8String:argv[3]].uppercaseString | |
stringByReplacingOccurrencesOfString:@"J" | |
withString:@"1000"] | |
stringByReplacingOccurrencesOfString:@"Q" | |
withString:@"1001"] | |
stringByReplacingOccurrencesOfString:@"K" | |
withString:@"1002"] | |
stringByReplacingOccurrencesOfString:@"A" | |
withString:@"1003"] | |
componentsSeparatedByString:@","]; | |
if (deckArg.count != 18) { | |
printf("invalid deck1 length\n"); | |
return 2; | |
} | |
if (deckArg2.count != 18) { | |
printf("invalid deck2 length\n"); | |
return 2; | |
} | |
for (NSNumber *n in cards) { | |
if ([deckArg countItemsEqualTo:[NSString stringWithFormat:@"%i", n.intValue]] + [deckArg2 countItemsEqualTo:[NSString stringWithFormat:@"%i", n.intValue]] > 4) { | |
printf("too much cards of type: %i", n.intValue); | |
return 2; | |
} | |
} | |
for (NSString*component in deckArg) { | |
[deck1 addObject:[NSNumber numberWithInt:component.intValue]]; | |
} | |
for (NSString*component in deckArg2) { | |
[deck2 addObject:[NSNumber numberWithInt:component.intValue]]; | |
} | |
} | |
// finish filling arrays | |
printf("Deck 1: "); | |
for (NSNumber *number in deck1) { | |
if (number.intValue >= 1000) { | |
printf("%s ", ((NSString*)trans[number.unsignedIntegerValue-1000]).UTF8String); | |
} else { | |
printf("%i ", number.intValue); | |
} | |
} | |
printf("\nDeck 2: "); | |
for (NSNumber *number in deck2) { | |
if (number.intValue >= 1000) { | |
printf("%s ", ((NSString*)trans[number.unsignedIntegerValue-1000]).UTF8String); | |
} else { | |
printf("%i ", number.intValue); | |
} | |
} | |
printf("\n\n"); | |
// begin solution | |
VERBOSE_OUT printf("P1 P2\n"); | |
NSMutableArray * desk = [NSMutableArray new]; | |
unsigned int steps=0; | |
while (deck1.count > 0 && deck2.count > 0) { | |
@autoreleasepool { | |
[desk addObject:[deck1 pull]]; | |
[desk addObject:[deck2 pull]]; | |
VERBOSE_OUT printf("%lu %lu : ",((NSNumber*)desk[desk.count - 2]).unsignedIntegerValue,((NSNumber*)desk[desk.count-1]).unsignedIntegerValue); | |
while (((NSNumber*)desk[desk.count-1]).unsignedIntegerValue == ((NSNumber*)desk[desk.count - 2]).unsignedIntegerValue) { | |
VERBOSE_OUT printf("DRAW\n"); | |
if (deck1.count == 0 || deck2.count == 0) { | |
break; | |
} | |
[desk addObject:[deck1 pull]]; | |
[desk addObject:[deck2 pull]]; | |
VERBOSE_OUT printf("%lu %lu : ",((NSNumber*)desk[desk.count - 2]).unsignedIntegerValue,((NSNumber*)desk[desk.count-1]).unsignedIntegerValue); | |
} | |
if (((NSNumber*)desk[desk.count-1]).unsignedIntegerValue > ((NSNumber*)desk[desk.count - 2]).unsignedIntegerValue) { | |
// player 2 won | |
VERBOSE_OUT printf("P2\n"); | |
if (reverse) { | |
desk = [desk reverseObjectEnumerator].allObjects.mutableCopy; | |
} | |
if (shuffle) { | |
[desk shuffle]; | |
} | |
[deck2 addObjectsFromArray:desk]; | |
} else { | |
VERBOSE_OUT printf("P1\n"); | |
if (reverse) { | |
desk = [desk reverseObjectEnumerator].allObjects.mutableCopy; | |
} | |
if (shuffle) { | |
[desk shuffle]; | |
} | |
[deck1 addObjectsFromArray:desk]; | |
} | |
desk=nil;desk = [NSMutableArray new]; | |
steps++; | |
DEBUG_OUT { | |
printf("Deck 1: "); | |
for (NSNumber *number in deck1) { | |
if (number.intValue >= 1000) { | |
printf("%s ", ((NSString*)trans[number.unsignedIntegerValue-1000]).UTF8String); | |
} else { | |
printf("%i ", number.intValue); | |
} | |
} | |
printf("\nDeck 2: "); | |
for (NSNumber *number in deck2) { | |
if (number.intValue >= 1000) { | |
printf("%s ", ((NSString*)trans[number.unsignedIntegerValue-1000]).UTF8String); | |
} else { | |
printf("%i ", number.intValue); | |
} | |
} | |
getchar(); | |
} | |
} | |
} | |
printf("Game over.\n%s won\nTook %u steps.\n", (deck1.count == 0 ? "P2" : "P1"),steps); | |
printf("Deck 1: "); | |
for (NSNumber *number in deck1) { | |
if (number.intValue >= 1000) { | |
printf("%s ", ((NSString*)trans[number.unsignedIntegerValue-1000]).UTF8String); | |
} else { | |
printf("%i ", number.intValue); | |
} | |
} | |
printf("\nDeck 2: "); | |
for (NSNumber *number in deck2) { | |
if (number.intValue >= 1000) { | |
printf("%s ", ((NSString*)trans[number.unsignedIntegerValue-1000]).UTF8String); | |
} else { | |
printf("%i ", number.intValue); | |
} | |
} | |
printf("\n\n"); | |
} | |
return 0; | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// | |
// NSArray+pull.h | |
// Drunk | |
// | |
// Created by Akasaka Ryuunosuke on 08/07/15. | |
// Copyright (c) 2015 Akasaka Ryuunosuke. All rights reserved. | |
// | |
#ifndef Drunk_NSArray_pull_h | |
#define Drunk_NSArray_pull_h | |
#import <Foundation/Foundation.h> | |
@interface NSMutableArray (pull) | |
- (id) pull; | |
- (void) shuffle; | |
@end | |
@implementation NSMutableArray (pull) | |
- (id) pull { | |
id __strong temp = [self objectAtIndex:0]; | |
[self removeObjectAtIndex:0]; | |
return temp; | |
} | |
- (void)shuffle | |
{ | |
NSUInteger count = [self count]; | |
for (NSUInteger i = 0; i < count; ++i) { | |
NSInteger remainingCount = count - i; | |
NSInteger exchangeIndex = i + arc4random_uniform((u_int32_t )remainingCount); | |
[self exchangeObjectAtIndex:i withObjectAtIndex:exchangeIndex]; | |
} | |
} | |
@end | |
@interface NSArray (CountItemsEqualTo) | |
- (NSUInteger) countItemsEqualTo:(id)equalTo; | |
@end | |
@implementation NSArray (CountItemsEqualTo) | |
- (NSUInteger) countItemsEqualTo:(id)equalTo { | |
@autoreleasepool { | |
NSArray * sorted = [self filteredArrayUsingPredicate:[NSPredicate predicateWithBlock:^BOOL(id evaluatedObject, NSDictionary *bindings) { | |
return [evaluatedObject isEqual:equalTo]; | |
}]]; | |
return sorted.count; | |
} | |
} | |
@end | |
#endif |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment