Guest User

Untitled

a guest
Sep 14th, 2018
110
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 3.61 KB | None | 0 0
  1. package PokerNim;
  2. use strict;
  3. use warnings;
  4. use Data::Dumper;
  5.  
  6. sub new {
  7. my $class = shift;
  8. my $self = {};
  9.  
  10. bless($self, $class);
  11.  
  12. $self->{heaps} = shift;
  13.  
  14. return $self;
  15. }
  16.  
  17. sub solve {
  18. my $self = shift;
  19. my $nim_sum = undef;
  20.  
  21. foreach my $heap (@{$self->{heaps}}) {
  22. $nim_sum ^= $heap;
  23. }
  24.  
  25. return get_winner_from_nim_sum($nim_sum);
  26. }
  27.  
  28. sub get_winner_from_nim_sum {
  29. my $nim_sum = shift;
  30.  
  31. return $nim_sum ? 'First': 'Second';
  32. }
  33.  
  34. 1;
  35.  
  36. use strict;
  37. use warnings;
  38. use Test::More;
  39. use Data::Dumper;
  40.  
  41. my $TESTING = 0;
  42.  
  43. use constant {
  44. MIN_VALUE => 1,
  45. MAX_VALUE => 100,
  46. MAX_HEAP_VALUE => 1_000_000_000,
  47. };
  48.  
  49. run_tests() if ($TESTING);
  50. solve_from_input() if (!$TESTING);
  51.  
  52. sub run_tests {
  53. # player who removes the last chip wins the game
  54. my $pn = new PokerNim([1]);
  55. is($pn->solve(), 'First');
  56.  
  57. $pn = new PokerNim([MAX_HEAP_VALUE]);
  58. is($pn->solve(), 'First');
  59.  
  60. $pn = new PokerNim([1, 1]);
  61. is($pn->solve(), 'Second');
  62.  
  63. # 1 1 1
  64. # 1 1 First removes 1
  65. # 1 Second removes 1
  66. # First removes 1
  67. $pn = new PokerNim([1, 1, 1]);
  68. is($pn->solve(), 'First');
  69.  
  70. $pn = new PokerNim([1, 1, 1, 1]);
  71. is($pn->solve(), 'Second');
  72.  
  73. $pn = new PokerNim([1, 1, 1, 1, 1]);
  74. is($pn->solve(), 'First');
  75.  
  76. $pn = new PokerNim([1, 1, 1, 1, 1, 1]);
  77. is($pn->solve(), 'Second');
  78.  
  79. # 2
  80. # 1 First removes 2
  81. $pn = new PokerNim([2]);
  82. is($pn->solve(), 'First');
  83.  
  84. # 1 2
  85. # 1 1 First removes 1
  86. # 1 Second removes 1
  87. # First removes 1
  88. $pn = new PokerNim([1, 2]);
  89. is($pn->solve(), 'First');
  90.  
  91. # 1 3
  92. # 1 2 First removes 1
  93. # 1 Second removes 1
  94. # First removes 1
  95. $pn = new PokerNim([1, 3]);
  96. is($pn->solve(), 'First');
  97.  
  98. # A B C
  99. # 1 2 2
  100. # 0 2 2 First removes 1A
  101. # 0 1 2 Second removes 1B
  102. # 0 1 1 First removes 1C
  103. # 0 0 1 Second removes 1B
  104. # 0 0 0 First removes 1
  105. $pn = new PokerNim([1, 2, 2]);
  106. is($pn->solve(), 'First');
  107.  
  108. $pn = new PokerNim([2, 1, 3]);
  109. is($pn->solve(), 'Second');
  110.  
  111. # any even number in place of MAX_VALUE is auto-win Second
  112. my @MAX_BASIC = (1) x MAX_VALUE;
  113. $pn = new PokerNim(\@MAX_BASIC);
  114. is($pn->solve(), 'Second');
  115.  
  116. my @MAX_MAX = (MAX_HEAP_VALUE) x 1;
  117. $pn = new PokerNim(\@MAX_MAX);
  118. is($pn->solve(), 'First');
  119.  
  120. done_testing();
  121. }
  122.  
  123. sub solve_from_input {
  124. my $game_count = <>;
  125. chomp($game_count);
  126. validate_count($game_count);
  127.  
  128. foreach (1 .. $game_count) {
  129. my ($pile_count, $max_pile_interacts) = split(" ", <>);
  130. validate_count($pile_count);
  131. validate_count($max_pile_interacts);
  132.  
  133. my @heaps = split(" ", <>);
  134. validate_heaps(\@heaps);
  135.  
  136. my $pn = new PokerNim(\@heaps);
  137. my $winner = $pn->solve();
  138. print("$winner\n");
  139. }
  140. }
  141.  
  142. sub validate_count {
  143. my $game_count = shift;
  144.  
  145. if (!($game_count =~ /^\d+$/)) {
  146. die "Not a whole number";
  147. }
  148.  
  149. if ($game_count < MIN_VALUE || $game_count > MAX_VALUE) {
  150. die "Number must be between " . MIN_VALUE . " and " . MAX_VALUE . ", inclusive";
  151. }
  152. }
  153.  
  154. sub validate_heaps {
  155. my $heaps = shift;
  156.  
  157. die "Heaps is not an array" if (ref($heaps) ne 'ARRAY');
  158.  
  159. if (scalar(@{$heaps}) < MIN_VALUE || scalar(@{$heaps}) > MAX_VALUE) {
  160. die "Heap count must be between " . MIN_VALUE . " and " . MAX_VALUE . ", inclusive";
  161. }
  162.  
  163. foreach my $heap (@{$heaps}) {
  164. if ($heap < 1 || $heap > 1_000_000_000) {
  165. die "Each heap size must be between "
  166. . MIN_VALUE . " and "
  167. . MAX_HEAP_VALUE . ", inclusive";
  168. }
  169. }
  170. }
Add Comment
Please, Sign In to add comment