Nimber arithmetic: Difference between revisions
Content added Content deleted
(Added C++ solution) |
SqrtNegInf (talk | contribs) (Added Perl) |
||
Line 775: | Line 775: | ||
</pre> |
</pre> |
||
=={{header|Perl}}== |
|||
{{trans|Raku}} |
|||
<lang perl>use strict; |
|||
use warnings; |
|||
use feature 'say'; |
|||
use Math::AnyNum qw(:overload); |
|||
sub msb { |
|||
my($n, $base) = (shift, 0); |
|||
$base++ while $n >>= 1; |
|||
$base; |
|||
} |
|||
sub lsb { |
|||
my $n = shift; |
|||
msb($n & -$n); |
|||
} |
|||
sub nim_sum { |
|||
my($x,$y) = @_; |
|||
$x ^ $y |
|||
} |
|||
sub nim_prod { |
|||
no warnings qw(recursion); |
|||
my($x,$y) = @_; |
|||
return $x * $y if $x < 2 or $y < 2; |
|||
my $h = 2 ** lsb($x); |
|||
return nim_sum( nim_prod($h, $y), nim_prod(nim_sum($x,$h), $y)) if $x > $h; |
|||
return nim_prod($y,$x) if lsb($y) < msb($y); |
|||
return $x * $y unless my $comp = lsb($x) & lsb($y); |
|||
$h = 2 ** lsb($comp); |
|||
nim_prod(nim_prod(($x >> $h),($y >> $h)), (3 << ($h - 1))); |
|||
} |
|||
my $upto = 15; |
|||
for (['+', \&nim_sum], ['*', \&nim_prod]) { |
|||
my($op, $f) = @$_; |
|||
print " $op |"; printf '%3d', $_ for 0..$upto; |
|||
say "\n───┼" . ('────' x ($upto-3)); |
|||
for my $r (0..$upto) { |
|||
printf('%2s |', $r); |
|||
printf '%3s', &$f($r, $_) for 0..$upto; |
|||
print "\n"; |
|||
} |
|||
print "\n"; |
|||
} |
|||
say nim_sum(21508, 42689); |
|||
say nim_prod(21508, 42689); |
|||
say nim_sum(2150821508215082150821508, 4268942689426894268942689); |
|||
say nim_prod(2150821508215082150821508, 4268942689426894268942689); # pretty slow</lang> |
|||
{{out}} |
|||
<pre> + │ 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
|||
───┼──────────────────────────────────────────────── |
|||
0 │ 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
|||
1 │ 1 0 3 2 5 4 7 6 9 8 11 10 13 12 15 14 |
|||
2 │ 2 3 0 1 6 7 4 5 10 11 8 9 14 15 12 13 |
|||
3 │ 3 2 1 0 7 6 5 4 11 10 9 8 15 14 13 12 |
|||
4 │ 4 5 6 7 0 1 2 3 12 13 14 15 8 9 10 11 |
|||
5 │ 5 4 7 6 1 0 3 2 13 12 15 14 9 8 11 10 |
|||
6 │ 6 7 4 5 2 3 0 1 14 15 12 13 10 11 8 9 |
|||
7 │ 7 6 5 4 3 2 1 0 15 14 13 12 11 10 9 8 |
|||
8 │ 8 9 10 11 12 13 14 15 0 1 2 3 4 5 6 7 |
|||
9 │ 9 8 11 10 13 12 15 14 1 0 3 2 5 4 7 6 |
|||
10 │ 10 11 8 9 14 15 12 13 2 3 0 1 6 7 4 5 |
|||
11 │ 11 10 9 8 15 14 13 12 3 2 1 0 7 6 5 4 |
|||
12 │ 12 13 14 15 8 9 10 11 4 5 6 7 0 1 2 3 |
|||
13 │ 13 12 15 14 9 8 11 10 5 4 7 6 1 0 3 2 |
|||
14 │ 14 15 12 13 10 11 8 9 6 7 4 5 2 3 0 1 |
|||
15 │ 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 |
|||
* │ 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
|||
───┼──────────────────────────────────────────────── |
|||
0 │ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 |
|||
1 │ 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
|||
2 │ 0 2 3 1 8 10 11 9 12 14 15 13 4 6 7 5 |
|||
3 │ 0 3 1 2 12 15 13 14 4 7 5 6 8 11 9 10 |
|||
4 │ 0 4 8 12 6 2 14 10 11 15 3 7 13 9 5 1 |
|||
5 │ 0 5 10 15 2 7 8 13 3 6 9 12 1 4 11 14 |
|||
6 │ 0 6 11 13 14 8 5 3 7 1 12 10 9 15 2 4 |
|||
7 │ 0 7 9 14 10 13 3 4 15 8 6 1 5 2 12 11 |
|||
8 │ 0 8 12 4 11 3 7 15 13 5 1 9 6 14 10 2 |
|||
9 │ 0 9 14 7 15 6 1 8 5 12 11 2 10 3 4 13 |
|||
10 │ 0 10 15 5 3 9 12 6 1 11 14 4 2 8 13 7 |
|||
11 │ 0 11 13 6 7 12 10 1 9 2 4 15 14 5 3 8 |
|||
12 │ 0 12 4 8 13 1 9 5 6 10 2 14 11 7 15 3 |
|||
13 │ 0 13 6 11 9 4 15 2 14 3 8 5 7 10 1 12 |
|||
14 │ 0 14 7 9 5 11 2 12 10 4 13 3 15 1 8 6 |
|||
15 │ 0 15 5 10 1 14 4 11 2 13 7 8 3 12 6 9 |
|||
62149 |
|||
35202 |
|||
2722732241575131661744101 |
|||
221974472829844568827862736061997038065</pre> |
|||
=={{header|Phix}}== |
=={{header|Phix}}== |