September 2017 Update
This commit is contained in:
parent
bba7bfd280
commit
ba8067c3b7
14570 changed files with 153136 additions and 63871 deletions
48
Task/Long-multiplication/Aime/long-multiplication.aime
Normal file
48
Task/Long-multiplication/Aime/long-multiplication.aime
Normal file
|
|
@ -0,0 +1,48 @@
|
|||
data b, c, v;
|
||||
integer d, i, j, s;
|
||||
|
||||
b = argv(1);
|
||||
v = argv(2);
|
||||
|
||||
b_run(c, b_length(b) + b_length(v) + 1, 0);
|
||||
|
||||
i = -b_length(b);
|
||||
while (i) {
|
||||
b[i] = b[i] - '0';
|
||||
i += 1;
|
||||
}
|
||||
|
||||
j = -1;
|
||||
while (-b_length(v) <= j) {
|
||||
d = v[j] - '0';
|
||||
|
||||
i = -1;
|
||||
s = 0;
|
||||
while (-b_length(b) <= i) {
|
||||
s += b[i] * d + c[i + j];
|
||||
c[i + j] = s % 10;
|
||||
s /= 10;
|
||||
i -= 1;
|
||||
}
|
||||
while (s) {
|
||||
s += c[i + j];
|
||||
c[i + j] = s % 10;
|
||||
s /= 10;
|
||||
i -= 1;
|
||||
}
|
||||
|
||||
j -= 1;
|
||||
}
|
||||
|
||||
b_delete(c, -1);
|
||||
if (!c[0]) {
|
||||
b_delete(c, 0);
|
||||
}
|
||||
|
||||
i = -b_length(c);
|
||||
while (i) {
|
||||
c[i] = c[i] + '0';
|
||||
i += 1;
|
||||
}
|
||||
|
||||
o_form("~\n", c);
|
||||
|
|
@ -1,37 +1,58 @@
|
|||
::Long Multiplication Task from Rosetta Code
|
||||
::Batch File Implementation
|
||||
|
||||
@echo off
|
||||
setlocal enabledelayedexpansion
|
||||
|
||||
set num1=18446744073709551616
|
||||
set num2=18446744073709551616
|
||||
|
||||
set limit_a=-1&set limit_b=-1&set length=0
|
||||
for %%A in (1,2) do for /l %%B in (0,1,9) do set num%%A=!num%%A:%%B=%%B !
|
||||
for %%. in (!num1!) do set/a limit_a+=1&set a1=%%.!a1!
|
||||
for %%. in (!num2!) do set/a limit_b+=1&set a2=%%.!a2!
|
||||
|
||||
for /l %%a in (0,1,!limit_a!) do (
|
||||
for /l %%b in (0,1,!limit_b!) do (
|
||||
set/a pos=%%a+%%b
|
||||
set/a next=!pos!+1
|
||||
set/a temp0=result!pos!
|
||||
set/a result!pos!=!a1:~%%a,1!*!a2:~%%b,1!
|
||||
if !temp0! equ 0 set/a length+=1
|
||||
if !pos! lss !length! set/a result!pos!+=!temp0!
|
||||
|
||||
set/a temp0=result!pos!
|
||||
set/a temp1=result!next!
|
||||
|
||||
if !temp0! gtr 9 (
|
||||
set/a result!next!=!temp0!/10
|
||||
set temp2=!length!
|
||||
if !temp1! equ 0 set/a length+=1
|
||||
if !next! lss !temp2! set/a result!next!+=!temp1!
|
||||
set/a result!pos!=!temp0!%%10
|
||||
)
|
||||
)
|
||||
)
|
||||
for /l %%. in (0,1,!length!) do set product=!result%%.!!product!
|
||||
echo.!product!
|
||||
echo.
|
||||
pause>nul
|
||||
call :longmul 18446744073709551616 18446744073709551616 answer
|
||||
echo(%answer%
|
||||
exit /b 0
|
||||
|
||||
rem The Hellish Procedure
|
||||
rem Syntax: call :longmul <n1> <n2> <variable to store product>
|
||||
:longmul
|
||||
setlocal enabledelayedexpansion
|
||||
|
||||
rem Define variables
|
||||
set "num1=%1"
|
||||
set "num2=%2"
|
||||
set "limit1=-1"
|
||||
set "limit2=-1"
|
||||
set "length=0"
|
||||
set "prod="
|
||||
|
||||
rem Reverse the digits of each factor
|
||||
for %%A in (1,2) do (
|
||||
for /l %%B in (0,1,9) do set "num%%A=!num%%A:%%B=%%B !"
|
||||
for %%C in (!num%%A!) do ( set /a limit%%A+=1 & set "rev%%A=%%C!rev%%A!" )
|
||||
)
|
||||
|
||||
rem Do the multiplication
|
||||
for /l %%A in (0,1,%limit1%) do (
|
||||
for /l %%B in (0,1,%limit2%) do (
|
||||
set /a iter=%%A+%%B
|
||||
set /a iternext=iter+1
|
||||
set /a iternext2=iter+2
|
||||
|
||||
set /a prev=digit!iter!
|
||||
set /a digit!iter!=!rev1:~%%A,1!*!rev2:~%%B,1!
|
||||
|
||||
rem The next line updates the length of "digits"
|
||||
if !iternext! gtr !length! set length=!iternext!
|
||||
if !iter! lss !length! set /a digit!iter!+=prev
|
||||
|
||||
set /a currdigit=digit!iter!
|
||||
if !currDigit! gtr 9 (
|
||||
set /a prev=digit!iternext!
|
||||
set /a digit!iternext!=currdigit/10
|
||||
set /a digit!iter!=currdigit%%10
|
||||
|
||||
rem The next line updates the length of "digits"
|
||||
if !iternext2! gtr !length! set length=!iternext2!
|
||||
if !iternext! lss !length! set /a digit!iternext!+=prev
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
rem Finalize product reversing the digits
|
||||
for /l %%F in (0,1,%length%) do set "prod=!digit%%F!!prod!"
|
||||
endlocal & set "%3=%prod%"
|
||||
goto :eof
|
||||
|
|
|
|||
|
|
@ -0,0 +1,95 @@
|
|||
' version 08-01-2017
|
||||
' compile with: fbc -s console
|
||||
|
||||
Const As UInteger base_ = 1000000000 ' base 1,000,000,000
|
||||
|
||||
Function multiply(a1 As String, b1 As String) As String
|
||||
|
||||
Dim As String a = a1, b = b1
|
||||
|
||||
Trim(a) : Trim(b) ' remove spaces
|
||||
If Len(a) = 0 Or Len(b) = 0 Then Return "0"
|
||||
|
||||
If Len(a) + Len(b) > 10000 Then
|
||||
Print "number(s) are to big"
|
||||
Sleep 5000,1
|
||||
Return ""
|
||||
End If
|
||||
|
||||
If Len(a) < Len(b) Then
|
||||
Swap a, b
|
||||
End If
|
||||
|
||||
Dim As ULongInt product
|
||||
Dim As UInteger carry, i, m, shift
|
||||
Dim As UInteger la = Len(a), lb = Len(b)
|
||||
Dim As UInteger la9 = la \ 9 + IIf((la Mod 9) = 0, 0, 1)
|
||||
Dim As UInteger lb9 = lb \ 9 + IIf((lb Mod 9) = 0, 0, 1)
|
||||
Dim As UInteger arr_a(la9), answer((la9 + lb9) + 2)
|
||||
Dim As Integer last = la9
|
||||
|
||||
' make length a, b a multipy of 9
|
||||
a = Right((String(9, "0") + a), la9 * 9)
|
||||
b = Right((String(9, "0") + b), lb9 * 9)
|
||||
|
||||
For i = 1 To la9
|
||||
arr_a(la9 - i +1) = Val(Mid(a, i * 9 -8, 9))
|
||||
Next
|
||||
|
||||
Do
|
||||
carry = 0
|
||||
m = Val(Mid(b, lb9 * 9 -8, 9))
|
||||
For i = 1 To la9
|
||||
product = CULngInt(arr_a(i)) * m + answer(i + shift) + carry
|
||||
carry = product \ base_
|
||||
answer(i + shift) = product - carry * base_
|
||||
Next
|
||||
If carry <> 0 Then
|
||||
last = la9 + shift +1
|
||||
answer(last) = carry
|
||||
End If
|
||||
lb9 = lb9 -1
|
||||
shift = shift +1
|
||||
Loop Until lb9 = 0
|
||||
|
||||
Dim As String tmp = Str(answer(last))
|
||||
last = last -1
|
||||
While last > 0
|
||||
tmp = tmp + Right(String(9,"0") + Str(answer(last)), 9)
|
||||
last = last -1
|
||||
Wend
|
||||
|
||||
Return tmp
|
||||
|
||||
End Function
|
||||
|
||||
' ------=< MAIN >=------
|
||||
|
||||
Dim As String a = "2", b = "2", answer
|
||||
Dim As UInteger i = 1, j
|
||||
|
||||
For j = 1 To 7
|
||||
answer = multiply(a, b)
|
||||
a = answer
|
||||
b = answer
|
||||
i = i + i
|
||||
Print using "2 ^ ### = "; i;
|
||||
Print answer
|
||||
Next
|
||||
|
||||
Print
|
||||
Print "-------------------------------------------------"
|
||||
Print
|
||||
|
||||
a = "2" : b = "1" : answer = ""
|
||||
For j = 1 To 128
|
||||
answer = multiply(a, b)
|
||||
b = answer
|
||||
Next
|
||||
Print "2 ^ 128 = "; answer
|
||||
|
||||
' empty keyboard buffer
|
||||
While InKey <> "" : Wend
|
||||
Print : Print "hit any key to end program"
|
||||
Sleep
|
||||
End
|
||||
|
|
@ -1 +0,0 @@
|
|||
println 2**64 * 2**64
|
||||
|
|
@ -1,16 +1,20 @@
|
|||
import Data.List (transpose)
|
||||
import Data.List (transpose, inits)
|
||||
import Data.Char (digitToInt)
|
||||
import Data.List (inits)
|
||||
|
||||
digits :: Integer -> [Integer]
|
||||
digits = map (fromIntegral . digitToInt) . show
|
||||
digits = fmap (fromIntegral . digitToInt) . show
|
||||
|
||||
lZZ :: [[Integer]]
|
||||
lZZ = inits $ repeat 0
|
||||
|
||||
table f = map . flip (map . f)
|
||||
table :: (Integer -> Integer -> Integer) -> [Integer] -> [Integer] -> [[Integer]]
|
||||
table f x = fmap $ flip fmap x . f
|
||||
|
||||
polymul = ((map sum . transpose . zipWith (++) lZZ) .) . table (*)
|
||||
polymul :: [Integer] -> [Integer] -> [Integer]
|
||||
polymul xs ys = fmap sum (transpose (zipWith (++) lZZ (table (*) xs ys)))
|
||||
|
||||
longmult = (foldl1 ((+) . (10 *)) .) . (. digits) . polymul . digits
|
||||
longmult :: Integer -> Integer -> Integer
|
||||
longmult x y = foldl1 ((+) . (10 *)) (polymul (digits x) (digits y))
|
||||
|
||||
main :: IO ()
|
||||
main = print $ (2 ^ 64) `longmult` (2 ^ 64)
|
||||
|
|
|
|||
|
|
@ -1,3 +0,0 @@
|
|||
procedure main()
|
||||
write(2^64*2^64)
|
||||
end
|
||||
|
|
@ -5,7 +5,6 @@
|
|||
// so this multiplication function takes and returns
|
||||
// long integer strings rather than any kind of native integer
|
||||
|
||||
|
||||
// longMult :: (String | Integer) -> (String | Integer) -> String
|
||||
function longMult(num1, num2) {
|
||||
return largeIntegerString(
|
||||
|
|
@ -13,8 +12,6 @@
|
|||
);
|
||||
}
|
||||
|
||||
|
||||
|
||||
// digitProducts :: [Int] -> [Int] -> [Int]
|
||||
function digitProducts(xs, ys) {
|
||||
return multTable(xs, ys)
|
||||
|
|
@ -37,7 +34,6 @@
|
|||
})
|
||||
}
|
||||
|
||||
|
||||
// largeIntegerString :: [Int] -> String
|
||||
function largeIntegerString(lstColumnValues) {
|
||||
var dctProduct = lstColumnValues
|
||||
|
|
@ -60,7 +56,6 @@
|
|||
) : '') + dctProduct.digits;
|
||||
}
|
||||
|
||||
|
||||
// multTables :: [Int] -> [Int] -> [[Int]]
|
||||
function multTable(xs, ys) {
|
||||
return ys.map(function (y) {
|
||||
|
|
@ -79,11 +74,9 @@
|
|||
});
|
||||
}
|
||||
|
||||
|
||||
// TEST showing that larged bounded integer inputs give only rounded results
|
||||
// whereas integer string inputs allow for full precision on this scale (2^128)
|
||||
|
||||
|
||||
return {
|
||||
fromIntegerStrings: longMult(
|
||||
'18446744073709551616',
|
||||
|
|
@ -94,5 +87,4 @@
|
|||
18446744073709551616
|
||||
)
|
||||
};
|
||||
|
||||
})();
|
||||
|
|
|
|||
|
|
@ -0,0 +1,43 @@
|
|||
1) defining user functions:
|
||||
|
||||
{require lib_lists} ;; contains list.reverse
|
||||
|
||||
{def pk {lambda {:k :p}
|
||||
{if {equal? :p nil} then nil
|
||||
else {cons {* :k {car :p}} {pk :k {cdr :p} }}}}}
|
||||
|
||||
{def p+ {lambda {:p1 :p2}
|
||||
{if {and {equal? :p1 nil} {equal? :p2 nil}} then nil
|
||||
else {if {equal? :p1 nil} then :p2
|
||||
else {if {equal? :p2 nil} then :p1
|
||||
else {cons {+ {car :p1} {car :p2}}
|
||||
{p+ {cdr :p1} {cdr :p2} }}}}}}}
|
||||
|
||||
{def p* {lambda {:p1 :p2}
|
||||
{if {or {equal? :p1 nil} {equal? :p2 nil}} then nil
|
||||
else {if {not {cons? :p1}} then {pk :p1 :p2}
|
||||
else {p+ {pk {car :p1} :p2}
|
||||
{cons 0 {p* {cdr :p1} :p2}}}}}}}
|
||||
|
||||
{def simplify
|
||||
{def simplify.rec {lambda {:p :q :r}
|
||||
{if {and {equal? :p nil} {= :r 0}} then :q
|
||||
else {if {equal? :p nil} then {cons :r :q}
|
||||
else {simplify.rec {cdr :p}
|
||||
{cons {+ {% {car :p} 10} :r} :q}
|
||||
{floor {/ {car :p} 10}} }}}}}
|
||||
{lambda {:p} {simplify.rec {list.reverse :p} nil 0} }}
|
||||
|
||||
2) computing 2^128:
|
||||
|
||||
The input is 2^64 = 18,446,744,073,709,551,616
|
||||
|
||||
2.1) creating a list:
|
||||
{def 2p64 {list 1 8 4 4 6 7 4 4 0 7 3 7 0 9 5 5 1 6 1 6}}
|
||||
|
||||
2.2) computing the product
|
||||
{def 2p128 {simplify {simplify {simplify {p* {2p64} {2p64}}}}}}
|
||||
|
||||
2.3) displaying the result:
|
||||
{list.disp {2p128}}
|
||||
-> (3 4 0 2 8 2 3 6 6 9 2 0 9 3 8 4 6 3 4 6 3 3 7 4 6 0 7 4 3 1 7 6 8 2 1 1 4 5 6)
|
||||
|
|
@ -1 +0,0 @@
|
|||
print 2^64 * 2^64
|
||||
10
Task/Long-multiplication/Zkl/long-multiplication.zkl
Normal file
10
Task/Long-multiplication/Zkl/long-multiplication.zkl
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
var BN=Import("zklBigNum");
|
||||
BN(2).pow(64) * BN(2).pow(64)
|
||||
340282366920938463463374607431768211456
|
||||
|
||||
BN(2).pow(128) : "%,d".fmt(_)
|
||||
340,282,366,920,938,463,463,374,607,431,768,211,456
|
||||
|
||||
//42!, also BN(42).factorial()
|
||||
[2..42].reduce(fcn(p,n){p*n},BN(1)) : "%,d".fmt(_)
|
||||
1,405,006,117,752,879,898,543,142,606,244,511,569,936,384,000,000,000
|
||||
Loading…
Add table
Add a link
Reference in a new issue