I have tried to write yangyanzhan's solution of the raku-riddle-contest in raku OOP. Raku class system is very intuitive, and everything work as a charm till I came across a recursive function. This is a version of the code for the class and the function:
class Encounters {
has $.tigers;
has @!encounters;
method encounters {
if @!encounters.elems eq $.tigers {
return [@!encounters, ];
}
my @total_encounters = [] ;
for 1..$.tigers -> $tiger {
if ($tiger / 2) eq ($tiger / 2).round {
@!encounters = ( @!encounters, [$tiger]).flat ;
my @encounter_events = Encounters.new( tigers => $.tigers, encounters => @!encounters ).encounters;
@total_encounters.append: @encounter_events;
}
}
return @total_encounters;
}
}
sub encounters($tigers, @encounters) {
if @encounters.elems eq $tigers {
return [@encounters, ];
}
my @total_encounters = [] ;
for 1..$tigers -> $tiger {
if ($tiger / 2) eq ($tiger / 2).round {
my $sig = ( @encounters, [$tiger] ).flat;
my @encounter_events = encounters( $tigers, $sig );
@total_encounters.append: @encounter_events;
}
}
return @total_encounters;
}
sub MAIN( $tigers ) {
(encounters $tigers, [] ).say;
Encounters.new( tigers => $tigers ).encounters.say;
}
For $tigers = 4, the function gives:
[(2 2 2 2) (2 2 2 4) (2 2 4 2) (2 2 4 4) (2 4 2 2) (2 4 2 4) (2 4 4 2) (2 4 4 4) (4 2 2 2) (4 2 2 4) (4 2 4 2) (4 2 4 4) (4 4 2 2) (4 4 2 4) (4 4 4 2) (4 4 4 4)]
The class, on the other hand, always gets trapped in an infinite loop. I believe the difference between the function and the class lies in this line of code:
@!encounters = ( @!encounters, [$tiger]).flat;
my $sig = ( @encounters, [$tiger] ).flat;
It is unclear to me if this is because of a malformed recursion syntax or the difference in type constrains between functions and classes.
eqinstead of a numeric one==?($tiger / 2) eq ($tiger / 2).roundseems like a very round-about way to write$tiger %% 2