Skip to content

Instantly share code, notes, and snippets.

@aero aero/josephus2.pl

Created Apr 3, 2010
Embed
What would you like to do?
package Person;
use parent 'Class::Accessor::Fast';
__PACKAGE__->mk_accessors(qw/position alive succ/);
# Create a new, living Person with the given position
sub new {
my ($class, $args) = @_;
return $class->SUPER::new( { %{$args}, alive => 1 } );
}
# Create a chain of people
sub createChain {
my ($self, $n) = @_;
return $self unless $n > 0;
my $succ = Person->new( { position => $self->position+1 } );
$self->succ($succ);
$succ->createChain($n-1)
}
# Pass on the killing message
sub kill {
my ($self, $pos, $n, $remaining) = @_;
return $self->succ->kill($pos, $n, $remaining) if !$self->alive;
return $self if $remaining == 1;
if ($pos == $n) {
$self->alive(0);
$pos = 0;
$remaining--;
}
$self->succ->kill($pos+1, $n, $remaining)
}
# Print descriptive information
sub to_s{
my $self = shift;
"Person #".$self->position.", ".($self->alive ? "alive" : "dead")
}
#--------------------------------------------------------------------
package main;
use strict;
use warnings;
# Circle of $n people, kill every one out of every $m
my $m = 3;
my $n = 40;
my $first = Person->new( { position => 1 } );
my $last = $first->createChain($n-1);
$last->succ($first);
my $winner = $first->kill(1,$m,$n);
print "Winner: ", $winner->to_s, "\n";
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.