Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #!/usr/bin/perl
- use strict;
- use warnings;
- $| = 1;
- $/ = '';
- my $Game = 0;
- # Read decks:
- my @deck;
- foreach my $p (0 .. 1) {
- $_ = <>;
- $deck[$p]->@* = split( "\n" );
- shift @{$deck[$p]};
- }
- sub score_deck {
- my $score = 0;
- my $i = 1;
- while (@_) {
- $score += ($i * pop @_);
- $i++;
- }
- return ($score);
- }
- sub make_state {
- my ($pd0, $pd1) = @_;
- return (join( ',', @$pd0 ) . ':' . join( ',', @$pd1 ));
- }
- sub recurse_game {
- my ($depth, $d0, $d1 ) = @_;
- my %state;
- $Game++;
- print "Starting game #$Game at depth $depth\r" if ($Game % 100 == 0);
- while (@$d0 && @$d1) {
- # loop detection:
- my $curr_state = &make_state( $d0, $d1 );
- if (exists $state{$curr_state}) {
- return (($depth > 0) ? 0 : &score_deck( @$d0 ));
- }
- $state{$curr_state}++;
- # draw cards:
- my ($c0, $c1) = (shift @$d0, shift @$d1);
- my $winner;
- if ($c0 <= scalar(@$d0) && $c1 <= scalar(@$d1)) {
- my @new_d0 = map { $d0->[$_] } (0 .. $c0 - 1);
- my @new_d1 = map { $d1->[$_] } (0 .. $c1 - 1);
- $winner = &recurse_game( $depth + 1, \@new_d0, \@new_d1 );
- } elsif ($c0 > $c1) {
- $winner = 0;
- } else {
- $winner = 1;
- }
- # winner takes cards
- if ($winner == 0) {
- push( @$d0, ($c0, $c1) );
- } else {
- push( @$d1, ($c1, $c0) );
- }
- }
- # sub games return winner, main game returns score
- if ($depth > 0) {
- return ((@$d0) ? 0 : 1);
- } else {
- return (&score_deck( @$d0 || @$d1 ));
- }
- }
- print "\nPart 2: ", &recurse_game( 0, $deck[0], $deck[1] ), "\n";
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement