daily pastebin goal
77%
SHARE
TWEET

Untitled

a guest Sep 14th, 2018 81 Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  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. }
RAW Paste Data
We use cookies for various purposes including analytics. By continuing to use Pastebin, you agree to our use of cookies as described in the Cookies Policy. OK, I Understand
 
Top