Nimber arithmetic: Difference between revisions

Add Factor
(Added Swift solution)
(Add Factor)
Line 131:
21508 + 42689 = 62149
21508 * 42689 = 35202
</pre>
 
=={{header|Factor}}==
{{trans|FreeBASIC}}
{{works with|Factor|0.99 2020-07-03}}
<lang factor>USING: combinators formatting io kernel locals math sequences ;
 
! highest power of 2 that divides a given number
: hpo2 ( n -- n ) dup neg bitand ;
 
! base 2 logarithm of the highest power of 2 dividing a given number
: lhpo2 ( n -- n )
hpo2 0 swap [ dup even? ] [ -1 shift [ 1 + ] dip ] while drop ;
 
! nim sum of two numbers
ALIAS: nim-sum bitxor
 
! nim product of two numbers
:: nim-prod ( x y -- prod )
x hpo2 :> h!
0 :> comp!
{
{ [ x 2 < y 2 < or ] [ x y * ] }
{ [ x h > ] [ h y nim-prod x h bitxor y nim-prod bitxor ] } ! recursively break x into its powers of 2
{ [ y hpo2 y < ] [ y x nim-prod ] } ! recursively break y into its powers of 2 by flipping the operands
{ [ x y [ lhpo2 ] bi@ bitand comp! comp zero? ] [ x y * ] } ! we have no fermat power in common
[
comp hpo2 h! ! a fermat number square is its sequimultiple
x h neg shift y h neg shift nim-prod
3 h 1 - shift nim-prod
]
} cond ;
 
! words for printing tables
: dashes ( n -- ) [ CHAR: - ] "" replicate-as write ;
: top1 ( str -- ) " %s |" printf 16 <iota> [ "%3d" printf ] each nl ;
: top2 ( -- ) 3 dashes bl 49 dashes nl ;
 
: row ( n quot -- )
over "%2d |" printf curry 16 <iota> swap
[ call "%3d" printf ] curry each ; inline
 
: table ( quot str -- )
top1 top2 16 <iota> swap [ row nl ] curry each ; inline
 
! task
[ nim-sum ] "+" table nl
[ nim-prod ] "*" table nl
33333 77777
[ 2dup nim-sum "%d + %d = %d\n" printf ]
[ 2dup nim-prod "%d * %d = %d\n" printf ] 2bi</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
 
33333 + 77777 = 110052
33333 * 77777 = 2184564070
</pre>
 
1,827

edits