Addition chains: Difference between revisions

Content added Content deleted
(added Perl 6)
Line 1,179: Line 1,179:
Brauer example : [1, 2, 3, 4, 7, 10, 17, 27, 44, 88, 176, 203, 379]
Brauer example : [1, 2, 3, 4, 7, 10, 17, 27, 44, 88, 176, 203, 379]
Non-Brauer analysis suppressed
Non-Brauer analysis suppressed
</pre>

=={{header|Perl 6}}==
{{trans|Kotlin}}
<lang perl6>#!/usr/bin/env perl6

use v6;

my @Example = ();

sub checkSeq($pos is copy, @seq is copy, $n is copy, $minLen is copy) {
if ($pos > $minLen || @seq[0] > $n) {
return $minLen, 0;
} elsif (@seq[0] == $n) {
@Example = @seq;
return $pos, 1;
} elsif ($pos < $minLen) {
return tryPerm 0, $pos, @seq, $n, $minLen;
} else {
return $minLen, 0;
}
}
sub tryPerm($i is copy, $pos is copy, @seq is copy, $n is copy, $minLen is copy) {
return $minLen, 0 if $i > $pos;
my @res1 = checkSeq $pos+1, (@seq[0]+@seq[$i],@seq).flat, $n, $minLen;
my @res2 = tryPerm $i+1, $pos, @seq, $n, @res1[0];
if (@res2[0] < @res1[0]) {
return @res2[0], @res2[1];
} elsif (@res2[0] == @res1[0]) {
return @res2[0], @res1[1]+@res2[1];
} else {
say "Error in tryPerm";
return 0, 0;
}
}
sub initTryPerm($x is copy, $minLen is copy) {
return tryPerm 0, 0, [1], $x, $minLen ;
}
sub findBrauer($num is copy, $minLen is copy, $nbLimit is copy) {
my ($actualMin, $brauer) = initTryPerm $num, $minLen ;
say "\nN = ", $num;
say "Minimum length of chains : L($num) = $actualMin" ;
say "Number of minimum length Brauer chains : ", $brauer ;
say "Brauer example : ", @Example.reverse if $brauer > 0 ;
@Example = ();
if ($num = $nbLimit) {
my $nonBrauer = findNonBrauer $num, $actualMin+1, $brauer ;
say "Number of minimum length non-Brauer chains : ", $nonBrauer ;
say "Non-Brauer example : ", @Example if $nonBrauer > 0 ;
@Example = ();
} else {
say "Non-Brauer analysis suppressed";
}
}
sub isAdditionChain(@a is copy --> Bool) {
for (2 .. @a.end) -> $i {
return False if @a[$i] > @a[$i-1]*2 ;
my $ok = False;
JLOOP: for ($i-1 … 0) -> $j {
for ($j … 0) -> $k {
if (@a[$j]+@a[$k] == @a[$i]) {
$ok = True;
last JLOOP;
}
}
}
return False unless $ok;
}

if (!isBrauer(@a) and !@Example.Bool) {
@Example = @a;
}
return True;
}
sub isBrauer(@a is copy --> Bool) {
for (2 .. @a.end) -> $i {
my $ok = False;
ILOOP: for ($i-1 … 0) -> $j {
if (@a[$i-1]+@a[$j] == @a[$i]) {
$ok = True;
last ILOOP;
}
}
return False unless $ok;
}
return True;
}
sub findNonBrauer($num is copy, $len is copy, $brauer is copy) {
my @seq = (1 .. $len-1, $num).flat;
my $count = isAdditionChain(@seq) ?? 1 !! 0;

sub nextChains($index is copy) {
loop {
nextChains($index+1) if $index < $len-1;
return if (@seq[$index]+$len-1-$index = @seq[$len-1]);
@seq[$index]++;
for ($index^..^$len-1) { @seq[$^i] = @seq[$^i-1] + 1;}
$count++ if isAdditionChain(@seq);
}
}

nextChains(2);
return $count - $brauer;
}

my @nums = (7, 14, 21, 29, 32, 42, 64); # unlock below for extra credits,
# 47, 79, 191, 382, 379, 379, 12509);
say "Searching for Brauer chains up to a minimum length of 12:";
for @nums { findBrauer $^i, 12, 79 } ;
</lang>

{{out}}
<pre>Searching for Brauer chains up to a minimum length of 12:

N = 7
Minimum length of chains : L(7) = 4
Number of minimum length Brauer chains : 5
Brauer example : (1 2 3 4 7)
Number of minimum length non-Brauer chains : 0

N = 14
Minimum length of chains : L(14) = 5
Number of minimum length Brauer chains : 14
Brauer example : (1 2 3 4 7 14)
Number of minimum length non-Brauer chains : 0

N = 21
Minimum length of chains : L(21) = 6
Number of minimum length Brauer chains : 26
Brauer example : (1 2 3 4 7 14 21)
Number of minimum length non-Brauer chains : 3
Non-Brauer example : [1 2 4 5 8 13 21]

N = 29
Minimum length of chains : L(29) = 7
Number of minimum length Brauer chains : 114
Brauer example : (1 2 3 4 7 11 18 29)
Number of minimum length non-Brauer chains : 18
Non-Brauer example : [1 2 3 6 9 11 18 29]

N = 32
Minimum length of chains : L(32) = 5
Number of minimum length Brauer chains : 1
Brauer example : (1 2 4 8 16 32)
Number of minimum length non-Brauer chains : 0

N = 42
Minimum length of chains : L(42) = 7
Number of minimum length Brauer chains : 78
Brauer example : (1 2 3 4 7 14 21 42)
Number of minimum length non-Brauer chains : 6
Non-Brauer example : [1 2 4 5 8 13 21 42]

N = 64
Minimum length of chains : L(64) = 6
Number of minimum length Brauer chains : 1
Brauer example : (1 2 4 8 16 32 64)
Number of minimum length non-Brauer chains : 0
</pre>
</pre>