June 2018 Update
This commit is contained in:
parent
ba8067c3b7
commit
22f33d4004
5278 changed files with 84726 additions and 14379 deletions
88
Task/Long-multiplication/COBOL/long-multiplication.cobol
Normal file
88
Task/Long-multiplication/COBOL/long-multiplication.cobol
Normal file
|
|
@ -0,0 +1,88 @@
|
|||
identification division.
|
||||
program-id. long-mul.
|
||||
data division.
|
||||
replace ==ij-lim== by ==7== ==ir-lim== by ==14==.
|
||||
working-storage section.
|
||||
1 input-string pic x(26) value "18,446,744,073,709,551,616".
|
||||
1 a-table.
|
||||
2 a pic 999 occurs ij-lim.
|
||||
1 b-table.
|
||||
2 b pic 999 occurs ij-lim.
|
||||
1 ir-table value all "0".
|
||||
2 occurs ij-lim.
|
||||
3 ir pic 999 occurs ir-lim.
|
||||
1 s-table value all "0".
|
||||
2 s pic 999 occurs ir-lim.
|
||||
1 display.
|
||||
2 temp-result pic 9(6) value 0.
|
||||
2 carry pic 999 value 0.
|
||||
2 remain pic 999 value 0.
|
||||
1 binary.
|
||||
2 i pic 9(4) value 0.
|
||||
2 j pic 9(4) value 0.
|
||||
2 k pic 9(4) value 0.
|
||||
procedure division.
|
||||
begin.
|
||||
move 1 to j
|
||||
perform varying i from 1 by 1 until i > ij-lim
|
||||
unstring input-string delimited ","
|
||||
into a (i) with pointer j
|
||||
end-perform
|
||||
move a-table to b-table
|
||||
perform intermediate-calc
|
||||
perform sum-ir
|
||||
perform display-result
|
||||
stop run
|
||||
.
|
||||
|
||||
intermediate-calc.
|
||||
perform varying i from ij-lim by -1 until i < 1
|
||||
move 0 to carry
|
||||
perform varying j from ij-lim by -1 until j < 1
|
||||
compute temp-result = a (i) * b (j) + carry
|
||||
divide temp-result by 1000 giving carry
|
||||
remainder remain
|
||||
compute k = i + j
|
||||
move remain to ir (i k)
|
||||
end-perform
|
||||
subtract 1 from k
|
||||
move carry to ir (i k)
|
||||
end-perform
|
||||
.
|
||||
|
||||
sum-ir.
|
||||
move 0 to carry
|
||||
perform varying k from ir-lim by -1 until k < 1
|
||||
move carry to temp-result
|
||||
perform varying i from ij-lim by -1 until i < 1
|
||||
compute temp-result = temp-result + ir (i k)
|
||||
end-perform
|
||||
divide temp-result by 1000 giving carry
|
||||
remainder remain
|
||||
move remain to s (k)
|
||||
end-perform
|
||||
.
|
||||
|
||||
display-result.
|
||||
display " " input-string
|
||||
display " * " input-string
|
||||
display " = " with no advancing
|
||||
perform varying k from 1 by 1
|
||||
until k > ir-lim or s (k) not = 0
|
||||
end-perform
|
||||
if s (k) < 100
|
||||
move 1 to i
|
||||
inspect s (k) tallying i for leading "0"
|
||||
display s (k) (i:) "," with no advancing
|
||||
add 1 to k
|
||||
end-if
|
||||
perform varying k from k by 1 until k > ir-lim
|
||||
display s (k) with no advancing
|
||||
if k < ir-lim
|
||||
display "," with no advancing
|
||||
end-if
|
||||
end-perform
|
||||
display space
|
||||
.
|
||||
|
||||
end program long-mul.
|
||||
58
Task/Long-multiplication/Ceylon/long-multiplication.ceylon
Normal file
58
Task/Long-multiplication/Ceylon/long-multiplication.ceylon
Normal file
|
|
@ -0,0 +1,58 @@
|
|||
"run() is the main function of this module."
|
||||
|
||||
shared void run() {
|
||||
|
||||
function multiply(String|Integer|Integer[] top, String|Integer|Integer[] bottom, Integer base = 10) {
|
||||
|
||||
function fromString(String s) =>
|
||||
s
|
||||
.filter(not(','.equals))
|
||||
.map((char) => Integer.parse(char.string))
|
||||
.narrow<Integer>()
|
||||
.sequence()
|
||||
.reversed;
|
||||
|
||||
function toString(Integer[] ints) =>
|
||||
""
|
||||
.join(ints.interpose(',', 3))
|
||||
.reversed
|
||||
.trimLeading((char) => char in "0,");
|
||||
|
||||
function fromInteger(Integer int) => fromString(int.string);
|
||||
|
||||
function convertArg(String|Integer|Integer[] arg) =>
|
||||
switch(arg)
|
||||
case (is String) fromString(arg)
|
||||
case (is Integer) fromInteger(arg)
|
||||
case (is Integer[]) arg;
|
||||
|
||||
value a = convertArg(top);
|
||||
value b = convertArg(bottom);
|
||||
|
||||
value p = a.size;
|
||||
value q = b.size;
|
||||
value product = Array.ofSize(p + q, 0);
|
||||
|
||||
for (bIndex->bDigit in b.indexed) {
|
||||
variable value carry = 0;
|
||||
for (aIndex->aDigit in a.indexed) {
|
||||
assert (exists prodDigit = product[aIndex + bIndex]);
|
||||
value temp = prodDigit + carry + aDigit * bDigit;
|
||||
carry = temp / base;
|
||||
product[aIndex + bIndex] = temp % base;
|
||||
}
|
||||
assert (exists lastDigit = product[bIndex + p]);
|
||||
product[bIndex + p] = lastDigit + carry;
|
||||
}
|
||||
|
||||
return toString(product.sequence());
|
||||
}
|
||||
|
||||
value twoToThe64th = "18,446,744,073,709,551,616";
|
||||
value expectedResult = "340,282,366,920,938,463,463,374,607,431,768,211,456";
|
||||
value result = multiply(twoToThe64th, twoToThe64th);
|
||||
|
||||
print("The expected result is ``expectedResult``");
|
||||
print("The actual result is ``result``");
|
||||
print("Do they match? ``expectedResult == result then "Yes!" else "No!"``");
|
||||
}
|
||||
|
|
@ -20,7 +20,7 @@
|
|||
significant digit first. The digits returned by
|
||||
long-add do have the most significant bit first."
|
||||
(if (every 'endp digitses)
|
||||
(nconc (digits carry) sum)
|
||||
(nconc (number->digits carry) sum)
|
||||
(let ((column-sum (reduce '+ (mapcar #'first-digit digitses)
|
||||
:initial-value carry)))
|
||||
(multiple-value-bind (carry column-digit)
|
||||
|
|
@ -30,8 +30,8 @@
|
|||
;; get the digits of a and b (least significant bit first), and
|
||||
;; compute the zero padded rows. Then, add these rows (using
|
||||
;; long-add) and convert the digits back to a number.
|
||||
(do ((a (nreverse (digits a)))
|
||||
(b (nreverse (digits b)))
|
||||
(do ((a (nreverse (number->digits a)))
|
||||
(b (nreverse (number->digits b)))
|
||||
(prefix '() (list* 0 prefix))
|
||||
(rows '()))
|
||||
((endp b) (digits->number (long-add rows)))
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ function mult(strNum1,strNum2){
|
|||
|
||||
if ( aResult[idxIter] > 9 ) { // Carrying
|
||||
aResult[idxIter + 1] = Math.floor( aResult[idxIter] / 10 ) + ( idxIter + 1 >= aResult.length ? 0 : aResult[idxIter + 1] );
|
||||
aResult[idxIter] -= Math.floor( aResult[idxIter] / 10 ) * 10;
|
||||
aResult[idxIter] %= 10;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
45
Task/Long-multiplication/Julia/long-multiplication-1.julia
Normal file
45
Task/Long-multiplication/Julia/long-multiplication-1.julia
Normal file
|
|
@ -0,0 +1,45 @@
|
|||
module LongMultiplication
|
||||
|
||||
using Compat
|
||||
|
||||
function addwithcarry!(r, addend, addendpos)
|
||||
while true
|
||||
pad = max(0, addendpos - lastindex(r))
|
||||
append!(r, fill(0, pad))
|
||||
addendrst = addend + r[addendpos]
|
||||
addend, r[addendpos] = divrem(addendrst, 10)
|
||||
iszero(addend) && break
|
||||
addendpos += 1
|
||||
end
|
||||
return r
|
||||
end
|
||||
|
||||
function longmult(mult1::AbstractVector{T}, mult2::AbstractVector{T}) where T <: Integer
|
||||
r = T[]
|
||||
for (offset1, digit1) in enumerate(mult1), (offset2, digit2) in zip(eachindex(mult2) + offset1 - 1, mult2)
|
||||
single_multrst = digits(digit1 * digit2)
|
||||
for (addoffset, rstdigit) in zip(eachindex(single_multrst) + offset2 - 1, single_multrst)
|
||||
addwithcarry!(r, rstdigit, addoffset)
|
||||
end
|
||||
end
|
||||
return r
|
||||
end
|
||||
|
||||
function longmult(a::T, b::T)::T where T <: Integer
|
||||
mult1 = digits(a)
|
||||
mult2 = digits(b)
|
||||
r = longmult(mult1, mult2)
|
||||
return sum(d * T(10) ^ (e - 1) for (e, d) in enumerate(r))
|
||||
end
|
||||
|
||||
function longmult(a::AbstractString, b::AbstractString)
|
||||
if !ismatch(r"^\d+", a) || !ismatch(r"^\d+", b)
|
||||
throw(ArgumentError("string must contain only digits"))
|
||||
end
|
||||
mult1 = reverse(collect(Char, a) .- '0')
|
||||
mult2 = reverse(collect(Char, b) .- '0')
|
||||
r = longmult(mult1, mult2)
|
||||
return reverse(join(r))
|
||||
end
|
||||
|
||||
end # module LongMultiplication
|
||||
|
|
@ -0,0 +1,2 @@
|
|||
@show LongMultiplication.longmult(big(2) ^ 64, big(2) ^ 64)
|
||||
@show LongMultiplication.longmult("18446744073709551616", "18446744073709551616")
|
||||
|
|
@ -1,9 +1,11 @@
|
|||
> longmult := proc( a, b )
|
||||
local la, lb, digit;
|
||||
la := length(a);
|
||||
lb := length(b);
|
||||
digit := (n,i)->iquo(n,10^(i-1)) mod 10;
|
||||
add( add( digit(a,la-i+1) * digit(b,lb-j+1) *10^(la-i+lb-j), i=1..la), j=1..lb );
|
||||
longmult := proc(a::integer,b::integer)
|
||||
local A,B,m,n,i,j;
|
||||
# Note, return a*b; works in Maple for any sized integer
|
||||
A := convert(a,base,10);
|
||||
B := convert(b,base,10);
|
||||
m := numelems(A);
|
||||
n := numelems(B);
|
||||
add( add( A[i]*B[j]*10^(j-1), j=1..n )*10^(i-1), i=1..m );
|
||||
end;
|
||||
|
||||
> longmult( 2^64, 2^64 );
|
||||
|
|
|
|||
|
|
@ -16,4 +16,8 @@ sub long_multiply ( Str $x, Str $y ) {
|
|||
return groups_to_num @group_sums;
|
||||
}
|
||||
|
||||
long_multiply( '18446744073709551616', '18446744073709551616' ).say;
|
||||
my $str = '18446744073709551616';
|
||||
long_multiply( $str, $str ).say;
|
||||
|
||||
# cross-check with native implementation
|
||||
say +$str * +$str;
|
||||
|
|
|
|||
|
|
@ -1,11 +1,10 @@
|
|||
def longmult(x,y)
|
||||
digits = reverse_split_number(x)
|
||||
result = [0]
|
||||
j = 0
|
||||
reverse_split_number(y).each do |m|
|
||||
y.digits.each do |m|
|
||||
c = 0
|
||||
i = j
|
||||
digits.each do |d|
|
||||
x.digits.each do |d|
|
||||
v = result[i]
|
||||
result << 0 if v.zero?
|
||||
c, v = (v + c + d*m).divmod(10)
|
||||
|
|
@ -19,15 +18,6 @@ def longmult(x,y)
|
|||
result.reverse.inject(0) {|sum, n| 10*sum + n}
|
||||
end
|
||||
|
||||
def reverse_split_number(m)
|
||||
digits = []
|
||||
while m > 0
|
||||
m, v = m.divmod 10
|
||||
digits << v
|
||||
end
|
||||
digits
|
||||
end
|
||||
|
||||
n=2**64
|
||||
printf " %d * %d = %d\n", n, n, n*n
|
||||
printf "longmult(%d, %d) = %d\n", n, n, longmult(n,n)
|
||||
|
|
|
|||
|
|
@ -1,37 +1,37 @@
|
|||
func add_with_carry(result, addend, addendpos) {
|
||||
loop {
|
||||
while (result.len < addendpos+1) {
|
||||
result.append(0);
|
||||
};
|
||||
var addend_digits = (addend.to_i + result[addendpos].to_i -> to_chars);
|
||||
result[addendpos] = addend_digits.pop;
|
||||
addend_digits.len > 0 || break;
|
||||
addend = addend_digits.pop;
|
||||
addendpos++;
|
||||
result.append(0)
|
||||
}
|
||||
var addend_digits = (addend.to_i + result[addendpos] -> to_s.chars)
|
||||
result[addendpos] = addend_digits.pop
|
||||
addend_digits.len > 0 || break
|
||||
addend = addend_digits.pop
|
||||
addendpos++
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
func longhand_multiplication(multiplicand, multiplier) {
|
||||
|
||||
var result = [];
|
||||
var multiplicand_offset = 0;
|
||||
|
||||
|
||||
var result = []
|
||||
var multiplicand_offset = 0
|
||||
|
||||
multiplicand.reverse.each { |multiplicand_digit|
|
||||
var multiplier_offset = multiplicand_offset;
|
||||
var multiplier_offset = multiplicand_offset
|
||||
multiplier.reverse.each { |multiplier_digit|
|
||||
var multiplication_result = (multiplicand_digit.to_i * multiplier_digit.to_i -> to_s);
|
||||
|
||||
var addend_offset = multiplier_offset;
|
||||
var multiplication_result = (multiplicand_digit.to_i * multiplier_digit.to_i -> to_s)
|
||||
|
||||
var addend_offset = multiplier_offset
|
||||
multiplication_result.reverse.each { |result_digit_addend|
|
||||
add_with_carry(result, result_digit_addend, addend_offset);
|
||||
addend_offset++;
|
||||
};
|
||||
multiplier_offset++;
|
||||
};
|
||||
multiplicand_offset++;
|
||||
};
|
||||
|
||||
return result.join.reverse;
|
||||
add_with_carry(result, result_digit_addend, addend_offset)
|
||||
addend_offset++
|
||||
}
|
||||
multiplier_offset++
|
||||
}
|
||||
multiplicand_offset++
|
||||
}
|
||||
|
||||
return result.join.reverse
|
||||
}
|
||||
|
||||
say longhand_multiplication('18446744073709551616', '18446744073709551616');
|
||||
|
||||
say longhand_multiplication('18446744073709551616', '18446744073709551616')
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue