Nimber arithmetic: Difference between revisions

Content added Content deleted
(See talk page)
(Added Delphi example)
Line 336: Line 336:
21508 * 42689 = 35202
21508 * 42689 = 35202
</pre>
</pre>
=={{header|Delphi}}==
{{libheader| System.SysUtils}}
{{libheader| System.Math}}
{{Trans|Go}}
<lang Delphi>
program Nimber_arithmetic;


uses
System.SysUtils, System.Math;

Type
TFnop = record
fn: TFunc<Cardinal, Cardinal, Cardinal>;
op: string;
end;

// Highest power of two that divides a given number.
function hpo2(n: Cardinal): Cardinal;
begin
Result := n and (-n)
end;

// Base 2 logarithm of the highest power of 2 dividing a given number.
function lhpo2(n: Cardinal): Cardinal;
var
m: Cardinal;

begin
Result := 0;
m := hpo2(n);

while m mod 2 = 0 do
begin
m := m shr 1;
inc(Result);
end;
end;

// nim-sum of two numbers.
function nimsum(x, y: Cardinal): Cardinal;
begin
Result := x xor y;
end;

function nimprod(x, y: Cardinal): Cardinal;
var
h, xp, yp, comp: Cardinal;

begin
if (x < 2) or (y < 2) then
exit(x * y);

h := hpo2(x);

if x > h then
exit((nimprod(h, y) xor nimprod((x xor h), y)));

if hpo2(y) < y then
exit(nimprod(y, x)); // break y into powers of 2 by flipping operands

xp := lhpo2(x);
yp := lhpo2(y);
comp := xp and yp;

if comp = 0 then
exit(x * y); // no Fermat power in common

h := hpo2(comp);

// a Fermat number square is its sequimultiple
Result := nimprod(nimprod(x shr h, y shr h), 3 shl (h - 1));

end;

var
fnop: array [0 .. 1] of TFnop;
f: TFnop;
i, j, a, b: Cardinal;

begin
with fnop[0] do
begin
fn := nimsum;
op := '+';
end;

with fnop[1] do
begin
fn := nimprod;
op := '*';
end;

for f in fnop do
begin
write(' ', f.op, ' |');
for i := 0 to 15 do
Write(i:3);
Writeln;
Writeln('--- ', string.Create('-', 48));

for i := 0 to 15 do
begin
write(i:2, ' |');
for j := 0 to 15 do
write(f.fn(i, j):3);
Writeln;
end;
Writeln;
end;

a := 21508;
b := 42689;

Writeln(Format('%d + %d = %d', [a, b, nimsum(a, b)]));

Writeln(Format('%d * %d = %d', [a, b, nimprod(a, b)]));

readln;

end.</lang>
=={{header|Factor}}==
=={{header|Factor}}==
{{trans|FreeBASIC}}
{{trans|FreeBASIC}}