Data update

This commit is contained in:
Ingy döt Net 2026-02-01 16:33:20 -08:00
parent 5150844a7d
commit 4bb20c9b71
7735 changed files with 38060 additions and 199180 deletions

View file

@ -1,53 +1,53 @@
org 100h
jmp demo
;;; HL = BC * DE
;;; BC is left column, DE is right column
emul: lxi h,0 ; HL will be the accumulator
ztest: mov a,b ; Check if the left column is zero.
ora c ; If so, stop.
rz
halve: mov a,b ; Halve BC by rotating it right.
rar ; We know the carry is zero here because of the ORA.
mov b,a ; So rotate the top half first,
mov a,c ; Then the bottom half
rar ; This leaves the old low bit in the carry flag,
mov c,a ; so this also lets us do the even/odd test in one go.
even: jnc $+4 ; If no carry, the number is even, so skip (strikethrough)
dad d ; But if odd, add the number in the right column
double: xchg ; Doubling DE is a bit easier since you can add
dad h ; HL to itself in one go, and XCHG swaps DE and HL
xchg
jmp ztest ; We want to do the whole thing again until BC is zero
;;; Demo code, print 17 * 34
demo: lxi b,17 ; Load 17 into BC (left column)
lxi d,34 ; Load 34 into DE (right column)
call emul ; Do the multiplication
print: lxi b,-10 ; Decimal output routine (not very interesting here,
lxi d,pbuf ; but without it you can't see the result)
push d
digit: lxi d,-1
dloop: inx d
dad b
jc dloop
mvi a,58
add l
pop h
dcx h
mov m,a
push h
xchg
mov a,h
ora l
jnz digit
pop d
mvi c,9
jmp 5
db '*****'
pbuf: db '$'
org 100h
jmp demo
;;; HL = BC * DE
;;; BC is left column, DE is right column
emul: lxi h,0 ; HL will be the accumulator
ztest: mov a,b ; Check if the left column is zero.
ora c ; If so, stop.
rz
halve: mov a,b ; Halve BC by rotating it right.
rar ; We know the carry is zero here because of the ORA.
mov b,a ; So rotate the top half first,
mov a,c ; Then the bottom half
rar ; This leaves the old low bit in the carry flag,
mov c,a ; so this also lets us do the even/odd test in one go.
even: jnc $+4 ; If no carry, the number is even, so skip (strikethrough)
dad d ; But if odd, add the number in the right column
double: xchg ; Doubling DE is a bit easier since you can add
dad h ; HL to itself in one go, and XCHG swaps DE and HL
xchg
jmp ztest ; We want to do the whole thing again until BC is zero
;;; Demo code, print 17 * 34
demo: lxi b,17 ; Load 17 into BC (left column)
lxi d,34 ; Load 34 into DE (right column)
call emul ; Do the multiplication
print: lxi b,-10 ; Decimal output routine (not very interesting here,
lxi d,pbuf ; but without it you can't see the result)
push d
digit: lxi d,-1
dloop: inx d
dad b
jc dloop
mvi a,58
add l
pop h
dcx h
mov m,a
push h
xchg
mov a,h
ora l
jnz digit
pop d
mvi c,9
jmp 5
db '*****'
pbuf: db '$'

View file

@ -1,31 +1,31 @@
function Divide(a:Number):Number {
return ((a-(a%2))/2);
return ((a-(a%2))/2);
}
function Multiply(a:Number):Number {
return (a *= 2);
return (a *= 2);
}
function isEven(a:Number):Boolean {
if (a%2 == 0) {
return (true);
} else {
return (false);
}
if (a%2 == 0) {
return (true);
} else {
return (false);
}
}
function Ethiopian(left:Number, right:Number) {
var r:Number = 0;
trace(left+" "+right);
while (left != 1) {
var State:String = "Keep";
if (isEven(Divide(left))) {
State = "Strike";
}
trace(Divide(left)+" "+Multiply(right)+" "+State);
left = Divide(left);
right = Multiply(right);
if (State == "Keep") {
r += right;
}
}
trace("="+" "+r);
var r:Number = 0;
trace(left+" "+right);
while (left != 1) {
var State:String = "Keep";
if (isEven(Divide(left))) {
State = "Strike";
}
trace(Divide(left)+" "+Multiply(right)+" "+State);
left = Divide(left);
right = Multiply(right);
if (State == "Keep") {
r += right;
}
}
trace("="+" "+r);
}
}

View file

@ -1,14 +0,0 @@
with ada.text_io;use ada.text_io;
procedure ethiopian is
function double (n : Natural) return Natural is (2*n);
function halve (n : Natural) return Natural is (n/2);
function is_even (n : Natural) return Boolean is (n mod 2 = 0);
function mul (l, r : Natural) return Natural is
(if l = 0 then 0 elsif l = 1 then r elsif is_even (l) then mul (halve (l),double (r))
else r + double (mul (halve (l), r)));
begin
put_line (mul (17,34)'img);
end ethiopian;

View file

@ -2,29 +2,29 @@ MsgBox % Ethiopian(17, 34) "`n" Ethiopian2(17, 34)
; func definitions:
half( x ) {
return x >> 1
return x >> 1
}
double( x ) {
return x << 1
return x << 1
}
isEven( x ) {
return x & 1 == 0
return x & 1 == 0
}
Ethiopian( a, b ) {
r := 0
While (a >= 1) {
if !isEven(a)
r += b
a := half(a)
b := double(b)
}
return r
r := 0
While (a >= 1) {
if !isEven(a)
r += b
a := half(a)
b := double(b)
}
return r
}
; or a recursive function:
Ethiopian2( a, b, r = 0 ) { ;omit r param on initial call
return a==1 ? r+b : Ethiopian2( half(a), double(b), !isEven(a) ? r+b : r )
return a==1 ? r+b : Ethiopian2( half(a), double(b), !isEven(a) ? r+b : r )
}

View file

@ -1,39 +0,0 @@
Func Halve($x)
Return Int($x/2)
EndFunc
Func Double($x)
Return ($x*2)
EndFunc
Func IsEven($x)
Return (Mod($x,2) == 0)
EndFunc
; this version also supports negative parameters
Func Ethiopian($nPlier, $nPlicand, $bTutor = True)
Local $nResult = 0
If ($nPlier < 0) Then
$nPlier =- $nPlier
$nPlicand =- $nPlicand
ElseIf ($nPlicand > 0) And ($nPlier > $nPlicand) Then
$nPlier = $nPlicand
$nPlicand = $nPlier
EndIf
If $bTutor Then _
ConsoleWrite(StringFormat("Ethiopian multiplication of %d by %d...\n", $nPlier, $nPlicand))
While ($nPlier >= 1)
If Not IsEven($nPlier) Then
$nResult += $nPlicand
If $bTutor Then ConsoleWrite(StringFormat("%d\t%d\tKeep\n", $nPlier, $nPlicand))
Else
If $bTutor Then ConsoleWrite(StringFormat("%d\t%d\tStrike\n", $nPlier, $nPlicand))
EndIf
$nPlier = Halve($nPlier)
$nPlicand = Double($nPlicand)
WEnd
If $bTutor Then ConsoleWrite(StringFormat("Answer = %d\n", $nResult))
Return $nResult
EndFunc
MsgBox(0, "Ethiopian multiplication of 17 by 34", Ethiopian(17, 34) )

View file

@ -1,35 +0,0 @@
DECLARE FUNCTION half% (a AS INTEGER)
DECLARE FUNCTION doub% (a AS INTEGER)
DECLARE FUNCTION isEven% (a AS INTEGER)
DIM x AS INTEGER, y AS INTEGER, outP AS INTEGER
x = 17
y = 34
DO
PRINT x,
IF NOT (isEven(x)) THEN
outP = outP + y
PRINT y
ELSE
PRINT
END IF
IF x < 2 THEN EXIT DO
x = half(x)
y = doub(y)
LOOP
PRINT " =", outP
FUNCTION doub% (a AS INTEGER)
doub% = a * 2
END FUNCTION
FUNCTION half% (a AS INTEGER)
half% = a \ 2
END FUNCTION
FUNCTION isEven% (a AS INTEGER)
isEven% = (a MOD 2) - 1
END FUNCTION

View file

@ -3,28 +3,28 @@ x = 17
y = 34
while True
print x + chr(09);
if not (isEven(x)) then
outP += y
print y
else
print
end if
if x < 2 then exit while
x = half(x)
y = doub(y)
print x + chr(09);
if not (isEven(x)) then
outP += y
print y
else
print
end if
if x < 2 then exit while
x = half(x)
y = doub(y)
end while
print "=" + chr(09); outP
end
function doub (a)
return a * 2
return a * 2
end function
function half (a)
return a \ 2
return a \ 2
end function
function isEven (a)
return (a mod 2) - 1
return (a mod 2) - 1
end function

View file

@ -2,19 +2,19 @@ alias halve '@ \!:1 /= 2'
alias double '@ \!:1 *= 2'
alias is_even '@ \!:1 = ! ( \!:2 % 2 )'
alias multiply eval \''set multiply_args=( \!*:q ) \\
@ multiply_plier = $multiply_args[2] \\
@ multiply_plicand = $multiply_args[3] \\
@ multiply_result = 0 \\
while ( $multiply_plier > 0 ) \\
is_even multiply_is_even $multiply_plier \\
if ( ! $multiply_is_even ) then \\
@ multiply_result += $multiply_plicand \\
endif \\
halve multiply_plier \\
double multiply_plicand \\
end \\
@ $multiply_args[1] = $multiply_result \\
alias multiply eval \''set multiply_args=( \!*:q ) \\
@ multiply_plier = $multiply_args[2] \\
@ multiply_plicand = $multiply_args[3] \\
@ multiply_result = 0 \\
while ( $multiply_plier > 0 ) \\
is_even multiply_is_even $multiply_plier \\
if ( ! $multiply_is_even ) then \\
@ multiply_result += $multiply_plicand \\
endif \\
halve multiply_plier \\
double multiply_plicand \\
end \\
@ $multiply_args[1] = $multiply_result \\
'\'
multiply p 17 34

View file

@ -3,60 +3,60 @@ using System.Linq;
namespace RosettaCode.Tasks
{
public static class EthiopianMultiplication_Task
{
public static void Test ( )
{
Console.WriteLine ( "Ethiopian Multiplication" );
int A = 17, B = 34;
Console.WriteLine ( "Recursion: {0}*{1}={2}", A, B, EM_Recursion ( A, B ) );
Console.WriteLine ( "Linq: {0}*{1}={2}", A, B, EM_Linq ( A, B ) );
Console.WriteLine ( "Loop: {0}*{1}={2}", A, B, EM_Loop ( A, B ) );
Console.WriteLine ( );
}
public static class EthiopianMultiplication_Task
{
public static void Test ( )
{
Console.WriteLine ( "Ethiopian Multiplication" );
int A = 17, B = 34;
Console.WriteLine ( "Recursion: {0}*{1}={2}", A, B, EM_Recursion ( A, B ) );
Console.WriteLine ( "Linq: {0}*{1}={2}", A, B, EM_Linq ( A, B ) );
Console.WriteLine ( "Loop: {0}*{1}={2}", A, B, EM_Loop ( A, B ) );
Console.WriteLine ( );
}
public static int Halve ( this int p_Number )
{
return p_Number >> 1;
}
public static int Double ( this int p_Number )
{
return p_Number << 1;
}
public static bool IsEven ( this int p_Number )
{
return ( p_Number % 2 ) == 0;
}
public static int Halve ( this int p_Number )
{
return p_Number >> 1;
}
public static int Double ( this int p_Number )
{
return p_Number << 1;
}
public static bool IsEven ( this int p_Number )
{
return ( p_Number % 2 ) == 0;
}
public static int EM_Recursion ( int p_NumberA, int p_NumberB )
{
// Anchor Point, Recurse to find the next row Sum it with the second number according to the rules
return p_NumberA == 1 ? p_NumberB : EM_Recursion ( p_NumberA.Halve ( ), p_NumberB.Double ( ) ) + ( p_NumberA.IsEven ( ) ? 0 : p_NumberB );
}
public static int EM_Linq ( int p_NumberA, int p_NumberB )
{
// Creating a range from 1 to x where x the number of times p_NumberA can be halved.
// This will be 2^x where 2^x <= p_NumberA. Basically, ln(p_NumberA)/ln(2).
return Enumerable.Range ( 1, Convert.ToInt32 ( Math.Log ( p_NumberA, Math.E ) / Math.Log ( 2, Math.E ) ) + 1 )
// For every item (Y) in that range, create a new list, comprising the pair (p_NumberA,p_NumberB) Y times.
.Select ( ( item ) => Enumerable.Repeat ( new { Col1 = p_NumberA, Col2 = p_NumberB }, item )
// The aggregate method iterates over every value in the target list, passing the accumulated value and the current item's value.
.Aggregate ( ( agg_pair, orig_pair ) => new { Col1 = agg_pair.Col1.Halve ( ), Col2 = agg_pair.Col2.Double ( ) } ) )
// Remove all even items
.Where ( pair => !pair.Col1.IsEven ( ) )
// And sum!
.Sum ( pair => pair.Col2 );
}
public static int EM_Loop ( int p_NumberA, int p_NumberB )
{
int RetVal = 0;
while ( p_NumberA >= 1 )
{
RetVal += p_NumberA.IsEven ( ) ? 0 : p_NumberB;
p_NumberA = p_NumberA.Halve ( );
p_NumberB = p_NumberB.Double ( );
}
return RetVal;
}
}
public static int EM_Recursion ( int p_NumberA, int p_NumberB )
{
// Anchor Point, Recurse to find the next row Sum it with the second number according to the rules
return p_NumberA == 1 ? p_NumberB : EM_Recursion ( p_NumberA.Halve ( ), p_NumberB.Double ( ) ) + ( p_NumberA.IsEven ( ) ? 0 : p_NumberB );
}
public static int EM_Linq ( int p_NumberA, int p_NumberB )
{
// Creating a range from 1 to x where x the number of times p_NumberA can be halved.
// This will be 2^x where 2^x <= p_NumberA. Basically, ln(p_NumberA)/ln(2).
return Enumerable.Range ( 1, Convert.ToInt32 ( Math.Log ( p_NumberA, Math.E ) / Math.Log ( 2, Math.E ) ) + 1 )
// For every item (Y) in that range, create a new list, comprising the pair (p_NumberA,p_NumberB) Y times.
.Select ( ( item ) => Enumerable.Repeat ( new { Col1 = p_NumberA, Col2 = p_NumberB }, item )
// The aggregate method iterates over every value in the target list, passing the accumulated value and the current item's value.
.Aggregate ( ( agg_pair, orig_pair ) => new { Col1 = agg_pair.Col1.Halve ( ), Col2 = agg_pair.Col2.Double ( ) } ) )
// Remove all even items
.Where ( pair => !pair.Col1.IsEven ( ) )
// And sum!
.Sum ( pair => pair.Col2 );
}
public static int EM_Loop ( int p_NumberA, int p_NumberB )
{
int RetVal = 0;
while ( p_NumberA >= 1 )
{
RetVal += p_NumberA.IsEven ( ) ? 0 : p_NumberB;
p_NumberA = p_NumberA.Halve ( );
p_NumberB = p_NumberB.Double ( );
}
return RetVal;
}
}
}

View file

@ -6,7 +6,7 @@ void doublit(int *x) { *x <<= 1; }
bool iseven(const int x) { return (x & 1) == 0; }
int ethiopian(int plier,
int plicand, const bool tutor)
int plicand, const bool tutor)
{
int result=0;

View file

@ -1,93 +0,0 @@
*>* Ethiopian multiplication
IDENTIFICATION DIVISION.
PROGRAM-ID. ethiopian-multiplication.
DATA DIVISION.
LOCAL-STORAGE SECTION.
01 l PICTURE 9(10) VALUE 17.
01 r PICTURE 9(10) VALUE 34.
01 ethiopian-multiply PICTURE 9(20).
01 product PICTURE 9(20).
PROCEDURE DIVISION.
CALL "ethiopian-multiply" USING
BY CONTENT l, BY CONTENT r,
BY REFERENCE ethiopian-multiply
END-CALL
DISPLAY ethiopian-multiply END-DISPLAY
MULTIPLY l BY r GIVING product END-MULTIPLY
DISPLAY product END-DISPLAY
STOP RUN.
END PROGRAM ethiopian-multiplication.
IDENTIFICATION DIVISION.
PROGRAM-ID. ethiopian-multiply.
DATA DIVISION.
LOCAL-STORAGE SECTION.
01 evenp PICTURE 9.
88 even VALUE 1.
88 odd VALUE 0.
LINKAGE SECTION.
01 l PICTURE 9(10).
01 r PICTURE 9(10).
01 product PICTURE 9(20) VALUE ZERO.
PROCEDURE DIVISION using l, r, product.
MOVE ZEROES TO product
PERFORM UNTIL l EQUAL ZERO
CALL "evenp" USING
BY CONTENT l,
BY REFERENCE evenp
END-CALL
IF odd
ADD r TO product GIVING product END-ADD
END-IF
CALL "halve" USING
BY CONTENT l,
BY REFERENCE l
END-CALL
CALL "twice" USING
BY CONTENT r,
BY REFERENCE r
END-CALL
END-PERFORM
GOBACK.
END PROGRAM ethiopian-multiply.
IDENTIFICATION DIVISION.
PROGRAM-ID. halve.
DATA DIVISION.
LOCAL-STORAGE SECTION.
LINKAGE SECTION.
01 n PICTURE 9(10).
01 m PICTURE 9(10).
PROCEDURE DIVISION USING n, m.
DIVIDE n BY 2 GIVING m END-DIVIDE
GOBACK.
END PROGRAM halve.
IDENTIFICATION DIVISION.
PROGRAM-ID. twice.
DATA DIVISION.
LOCAL-STORAGE SECTION.
LINKAGE SECTION.
01 n PICTURE 9(10).
01 m PICTURE 9(10).
PROCEDURE DIVISION USING n, m.
MULTIPLY n by 2 GIVING m END-MULTIPLY
GOBACK.
END PROGRAM twice.
IDENTIFICATION DIVISION.
PROGRAM-ID. evenp.
DATA DIVISION.
LOCAL-STORAGE SECTION.
01 q PICTURE 9(10).
LINKAGE SECTION.
01 n PICTURE 9(10).
01 m PICTURE 9(1).
88 even VALUE 1.
88 odd VALUE 0.
PROCEDURE DIVISION USING n, m.
DIVIDE n BY 2 GIVING q REMAINDER m END-DIVIDE
SUBTRACT m FROM 1 GIVING m END-SUBTRACT
GOBACK.
END PROGRAM evenp.

View file

@ -1,18 +1,18 @@
<cffunction name="double">
<cfargument name="number" type="numeric" required="true">
<cfset answer = number * 2>
<cfset answer = number * 2>
<cfreturn answer>
</cffunction>
<cffunction name="halve">
<cfargument name="number" type="numeric" required="true">
<cfset answer = int(number / 2)>
<cfset answer = int(number / 2)>
<cfreturn answer>
</cffunction>
<cffunction name="even">
<cfargument name="number" type="numeric" required="true">
<cfset answer = number mod 2>
<cfset answer = number mod 2>
<cfreturn answer>
</cffunction>

View file

@ -4,19 +4,19 @@
<cffunction name="double">
<cfargument name="number" type="numeric" required="true">
<cfset answer = number * 2>
<cfset answer = number * 2>
<cfreturn answer>
</cffunction>
<cffunction name="halve">
<cfargument name="number" type="numeric" required="true">
<cfset answer = int(number / 2)>
<cfset answer = int(number / 2)>
<cfreturn answer>
</cffunction>
<cffunction name="even">
<cfargument name="number" type="numeric" required="true">
<cfset answer = number mod 2>
<cfset answer = number mod 2>
<cfreturn answer>
</cffunction>
@ -33,10 +33,10 @@ Ethiopian multiplication of #Number_A# and #Number_B#...
<cfif even(Number_A) EQ 1>
<cfset Result = Result + Number_B>
<cfset Result = Result + Number_B>
<cfset Action = "Keep">
<cfelse>
<cfset Action = "Strike">
<cfset Action = "Strike">
</cfif>
<tr>

View file

@ -4,41 +4,41 @@ let s = 0
do
if x < 1 then
if x < 1 then
break
break
endif
endif
if s = 1 then
if s = 1 then
print x
print x
endif
endif
if s = 0 then
if s = 0 then
let s = 1
let s = 1
endif
endif
let a = x
let e = a % 2
let e = 1 - e
let a = x
let e = a % 2
let e = 1 - e
if e = 0 then
if e = 0 then
let t = t + y
print x, " ", y
let t = t + y
print x, " ", y
endif
endif
let a = x
let a = int(a / 2)
let x = a
let a = y
let a = 2 * a
let y = a
let a = x
let a = int(a / 2)
let x = a
let a = y
let a = 2 * a
let y = a
loop x >= 1

View file

@ -1,58 +1,58 @@
class
APPLICATION
APPLICATION
create
make
make
feature {NONE}
make
do
io.put_integer (ethiopian_multiplication (17, 34))
end
make
do
io.put_integer (ethiopian_multiplication (17, 34))
end
ethiopian_multiplication (a, b: INTEGER): INTEGER
-- Product of 'a' and 'b'.
require
a_positive: a > 0
b_positive: b > 0
local
x, y: INTEGER
do
x := a
y := b
from
until
x <= 0
loop
if not is_even_int (x) then
Result := Result + y
end
x := halve_int (x)
y := double_int (y)
end
ensure
Result_correct: Result = a * b
end
ethiopian_multiplication (a, b: INTEGER): INTEGER
-- Product of 'a' and 'b'.
require
a_positive: a > 0
b_positive: b > 0
local
x, y: INTEGER
do
x := a
y := b
from
until
x <= 0
loop
if not is_even_int (x) then
Result := Result + y
end
x := halve_int (x)
y := double_int (y)
end
ensure
Result_correct: Result = a * b
end
feature {NONE}
double_int (n: INTEGER): INTEGER
double_int (n: INTEGER): INTEGER
--Two times 'n'.
do
Result := n * 2
end
do
Result := n * 2
end
halve_int (n: INTEGER): INTEGER
halve_int (n: INTEGER): INTEGER
--'n' divided by two.
do
Result := n // 2
end
do
Result := n // 2
end
is_even_int (n: INTEGER): BOOLEAN
is_even_int (n: INTEGER): BOOLEAN
--Is 'n' an even integer?
do
Result := n \\ 2 = 0
end
do
Result := n \\ 2 = 0
end
end

View file

@ -1,14 +0,0 @@
(defun even-p (n)
(= (mod n 2) 0))
(defun halve (n)
(floor n 2))
(defun double (n)
(* n 2))
(defun ethiopian-multiplication (l r)
(let ((sum 0))
(while (>= l 1)
(unless (even-p l)
(setq sum (+ r sum)))
(setq l (halve l))
(setq r (double r)))
sum))

View file

@ -11,7 +11,7 @@ even(N) ->
(N rem 2) == 0.
multiply(LHS,RHS) when is_integer(Lhs) and Lhs > 0 and
is_integer(Rhs) and Rhs > 0 ->
is_integer(Rhs) and Rhs > 0 ->
multiply(LHS,RHS,0).
multiply(1,RHS,Acc) ->

View file

@ -1,31 +0,0 @@
function emHalf(integer n)
return floor(n/2)
end function
function emDouble(integer n)
return n*2
end function
function emIsEven(integer n)
return (remainder(n,2) = 0)
end function
function emMultiply(integer a, integer b)
integer sum
sum = 0
while (a) do
if (not emIsEven(a)) then sum += b end if
a = emHalf(a)
b = emDouble(b)
end while
return sum
end function
----------------------------------------------------------------
-- runtime
printf(1,"emMultiply(%d,%d) = %d\n",{17,34,emMultiply(17,34)})
printf(1,"\nPress Any Key\n",{})
while (get_key() = -1) do end while

View file

@ -1,24 +1,24 @@
var eth = {
halve : function ( n ){ return Math.floor(n/2); },
double: function ( n ){ return 2*n; },
isEven: function ( n ){ return n%2 === 0); },
mult: function ( a , b ){
var sum = 0, a = [a], b = [b];
while ( a[0] !== 1 ){
a.unshift( eth.halve( a[0] ) );
b.unshift( eth.double( b[0] ) );
}
for( var i = a.length - 1; i > 0 ; i -= 1 ){
if( !eth.isEven( a[i] ) ){
sum += b[i];
}
}
return sum + b[0];
}
halve : function ( n ){ return Math.floor(n/2); },
double: function ( n ){ return 2*n; },
isEven: function ( n ){ return n%2 === 0); },
mult: function ( a , b ){
var sum = 0, a = [a], b = [b];
while ( a[0] !== 1 ){
a.unshift( eth.halve( a[0] ) );
b.unshift( eth.double( b[0] ) );
}
for( var i = a.length - 1; i > 0 ; i -= 1 ){
if( !eth.isEven( a[i] ) ){
sum += b[i];
}
}
return sum + b[0];
}
}
// eth.mult(17,34) returns 578

View file

@ -1,54 +1,54 @@
implement Ethiopian;
include "sys.m";
sys: Sys;
print: import sys;
sys: Sys;
print: import sys;
include "draw.m";
draw: Draw;
draw: Draw;
Ethiopian : module
{
init : fn(ctxt : ref Draw->Context, args : list of string);
init : fn(ctxt : ref Draw->Context, args : list of string);
};
init (ctxt: ref Draw->Context, args: list of string)
{
sys = load Sys Sys->PATH;
sys = load Sys Sys->PATH;
print("\n%d\n", ethiopian(17, 34, 0));
print("\n%d\n", ethiopian(99, 99, 1));
print("\n%d\n", ethiopian(17, 34, 0));
print("\n%d\n", ethiopian(99, 99, 1));
}
halve(n: int): int
{
return (n /2);
return (n /2);
}
double(n: int): int
{
return (n * 2);
return (n * 2);
}
iseven(n: int): int
{
return ((n%2) == 0);
return ((n%2) == 0);
}
ethiopian(a: int, b: int, tutor: int): int
{
product := 0;
if (tutor)
print("\nmultiplying %d x %d", a, b);
while (a >= 1) {
if (!(iseven(a))) {
if (tutor)
print("\n%3d %d", a, b);
product += b;
} else
if (tutor)
print("\n%3d ----", a);
a = halve(a);
b = double(b);
}
return product;
product := 0;
if (tutor)
print("\nmultiplying %d x %d", a, b);
while (a >= 1) {
if (!(iseven(a))) {
if (tutor)
print("\n%3d %d", a, b);
product += b;
} else
if (tutor)
print("\n%3d ----", a);
a = halve(a);
b = double(b);
}
return product;
}

View file

@ -1,23 +1,23 @@
Function ethiopian(mr as long long, md as long long) {
def even()=number mod 2&&
def div2()=number div 2&&
def mul2()=number * 2&&
result=0&&
while mr>=1
if even(mr) then result+=md
mr=div2(mr)
md=mul2(md)
end while
=result
def even()=number mod 2&&
def div2()=number div 2&&
def mul2()=number * 2&&
result=0&&
while mr>=1
if even(mr) then result+=md
mr=div2(mr)
md=mul2(md)
end while
=result
}
Print ethiopian(17, 34)=578
Function ethiopian(mr as long long, md as long long) {
result=0&&
while mr>=1
if mr mod 2 then result+=md
mr|div 2&
md*=2&
end while
=result
result=0&&
while mr>=1
if mr mod 2 then result+=md
mr|div 2&
md*=2&
end while
=result
}
Print ethiopian(17, 34)=578

View file

@ -1,51 +1,51 @@
A IS 17
B IS 34
A IS 17
B IS 34
pliar IS $255 % designating main registers
pliand GREG
acc GREG
str IS pliar % reuse reg $255 for printing
pliar IS $255 % designating main registers
pliand GREG
acc GREG
str IS pliar % reuse reg $255 for printing
LOC Data_Segment
GREG @
BUF OCTA #3030303030303030 % reserve a buffer that is big enough to hold
OCTA #3030303030303030 % a max (signed) 64 bit integer:
OCTA #3030300a00000000 % 2^63 - 1 = 9223372036854775807
% string is terminated with NL, 0
LOC Data_Segment
GREG @
BUF OCTA #3030303030303030 % reserve a buffer that is big enough to hold
OCTA #3030303030303030 % a max (signed) 64 bit integer:
OCTA #3030300a00000000 % 2^63 - 1 = 9223372036854775807
% string is terminated with NL, 0
LOC #1000 % locate program at address
GREG @
halve SR pliar,pliar,1
GO $127,$127,0
LOC #1000 % locate program at address
GREG @
halve SR pliar,pliar,1
GO $127,$127,0
double SL pliand,pliand,1
GO $127,$127,0
double SL pliand,pliand,1
GO $127,$127,0
odd DIV $77,pliar,2
GET $78,rR
GO $127,$127,0
odd DIV $77,pliar,2
GET $78,rR
GO $127,$127,0
% Main is the entry point of the program
Main SET pliar,A % initialize registers for calculation
SET pliand,B
SET acc,0
1H GO $127,odd
BZ $78,2F % if pliar is even skip incr. acc with pliand
ADD acc,acc,pliand %
2H GO $127,halve % halve pliar
GO $127,double % and double pliand
PBNZ pliar,1B % repeat from 1H while pliar > 0
% Main is the entry point of the program
Main SET pliar,A % initialize registers for calculation
SET pliand,B
SET acc,0
1H GO $127,odd
BZ $78,2F % if pliar is even skip incr. acc with pliand
ADD acc,acc,pliand %
2H GO $127,halve % halve pliar
GO $127,double % and double pliand
PBNZ pliar,1B % repeat from 1H while pliar > 0
// result: acc = 17 x 34
// next: print result --> stdout
// $0 is a temp register
LDA str,BUF+19 % points after the end of the string
2H SUB str,str,1 % update buffer pointer
DIV acc,acc,10 % do a divide and mod
GET $0,rR % get digit from special purpose reg. rR
% containing the remainder of the division
INCL $0,'0' % convert to ascii
STBU $0,str % place digit in buffer
PBNZ acc,2B % next
% 'str' points to the start of the result
TRAP 0,Fputs,StdOut % output answer to stdout
TRAP 0,Halt,0 % exit
LDA str,BUF+19 % points after the end of the string
2H SUB str,str,1 % update buffer pointer
DIV acc,acc,10 % do a divide and mod
GET $0,rR % get digit from special purpose reg. rR
% containing the remainder of the division
INCL $0,'0' % convert to ascii
STBU $0,str % place digit in buffer
PBNZ acc,2B % next
% 'str' points to the start of the result
TRAP 0,Fputs,StdOut % output answer to stdout
TRAP 0,Halt,0 % exit

View file

@ -18,12 +18,12 @@ function r = ethiopicmult(plier, plicand, tutor=false)
while(plier >= 1)
if ( iseven(plier) )
if (tutor)
printf("%4d %6d struck\n", plier, plicand);
printf("%4d %6d struck\n", plier, plicand);
endif
else
r = r + plicand;
if (tutor)
printf("%4d %6d kept\n", plier, plicand);
printf("%4d %6d kept\n", plier, plicand);
endif
endif
plier = halve(plier);

View file

@ -10,9 +10,9 @@ declare
L in X; L>0; {Halve L} %% C-like iterator: "Init; While; Next"
R in Y; true; {Double R}
collect:Collect
do
{Collect L#R}
end
do
{Collect L#R}
end
OddRows = {Filter Rows LeftIsOdd}
RightColumn = {Map OddRows SelectRight}

View file

@ -1,34 +0,0 @@
program EthiopianMultiplication;
{$IFDEF FPC}
{$MODE DELPHI}
{$ENDIF}
function Double(Number: Integer): Integer;
begin
Result := Number * 2
end;
function Halve(Number: Integer): Integer;
begin
Result := Number div 2
end;
function Even(Number: Integer): Boolean;
begin
Result := Number mod 2 = 0
end;
function Ethiopian(NumberA, NumberB: Integer): Integer;
begin
Result := 0;
while NumberA >= 1 do
begin
if not Even(NumberA) then
Result := Result + NumberB;
NumberA := Halve(NumberA);
NumberB := Double(NumberB)
end
end;
begin
Write(Ethiopian(17, 34))
end.

View file

@ -11,12 +11,12 @@ sub ethiopicmult
my $r = 0;
while ($plier >= 1)
{
$r += $plicand unless iseven($plier);
if ($tutor) {
print "$plier, $plicand ", (iseven($plier) ? " struck" : " kept"), "\n";
}
$plier = halve($plier);
$plicand = double($plicand);
$r += $plicand unless iseven($plier);
if ($tutor) {
print "$plier, $plicand ", (iseven($plier) ? " struck" : " kept"), "\n";
}
$plier = halve($plier);
$plicand = double($plicand);
}
return $r;
}

View file

@ -1,35 +0,0 @@
function isEven {
param ([int]$value)
return [bool]($value % 2 -eq 0)
}
function doubleValue {
param ([int]$value)
return [int]($value * 2)
}
function halveValue {
param ([int]$value)
return [int]($value / 2)
}
function multiplyValues {
param (
[int]$plier,
[int]$plicand,
[int]$temp = 0
)
while ($plier -ge 1)
{
if (!(isEven $plier)) {
$temp += $plicand
}
$plier = halveValue $plier
$plicand = doubleValue $plicand
}
return $temp
}
multiplyValues 17 34

View file

@ -1,29 +0,0 @@
function halveInt( [int] $rhs )
{
[math]::floor( $rhs / 2 )
}
function doubleInt( [int] $rhs )
{
$rhs*2
}
function isEven( [int] $rhs )
{
-not ( $_ % 2 )
}
function Ethiopian( [int] $lhs , [int] $rhs )
{
$scratch = @{}
1..[math]::floor( [math]::log( $lhs , 2 ) + 1 ) |
ForEach-Object {
$scratch[$lhs] = $rhs
$lhs
$lhs = halveInt( $lhs )
$rhs = doubleInt( $rhs ) } |
Where-Object { -not ( isEven $_ ) } |
ForEach-Object { $sum = 0 } { $sum += $scratch[$_] } { $sum }
}
Ethiopian 17 34

View file

@ -11,13 +11,13 @@ public function long wf_ethiopianmultiplication (long al_multiplicand, long al_m
long ll_product
DO WHILE al_multiplicand >= 1
IF wf_iseven(al_multiplicand) THEN
// do nothing
ELSE
ll_product += al_multiplier
END IF
al_multiplicand = wf_halve(al_multiplicand)
al_multiplier = wf_double(al_multiplier)
IF wf_iseven(al_multiplicand) THEN
// do nothing
ELSE
ll_product += al_multiplier
END IF
al_multiplicand = wf_halve(al_multiplicand)
al_multiplier = wf_double(al_multiplier)
LOOP
return ll_product

View file

@ -3,13 +3,13 @@ double <- function(a) a*2
iseven <- function(a) (a%%2)==0
ethiopicmult<-function(x,y){
res<-ifelse(iseven(y),0,x)
while(!y==1){
x<-double(x)
y<-halve(y)
if(!iseven(y)) res<-res+x
}
return(res)
res<-ifelse(iseven(y),0,x)
while(!y==1){
x<-double(x)
y<-halve(y)
if(!iseven(y)) res<-res+x
}
return(res)
}
print(ethiopicmult(17,34))

View file

@ -5,9 +5,9 @@ sub even (Int $n --> Bool) { $n %% 2 }
sub ethiopic-mult (Int $a is copy, Int $b is copy --> Int) {
my Int $r = 0;
while $a {
even $a or $r += $b;
halve $a;
double $b;
even $a or $r += $b;
halve $a;
double $b;
}
return $r;
}

View file

@ -7,12 +7,12 @@ public int double(int n) = n*2;
public bool uneven(int n) = (n % 2) != 0);
public int ethiopianMul(int n, int m) {
result = 0;
while(n >= 1) {
if(uneven(n))
result += m;
n = halve(n);
m = double(m);
}
return result;
result = 0;
while(n >= 1) {
if(uneven(n))
result += m;
n = halve(n);
m = double(m);
}
return result;
}

View file

@ -1,21 +1,21 @@
define('halve(num)') :(halve_end)
halve eq(num,1) :s(freturn)
halve = num / 2 :(return)
define('halve(num)') :(halve_end)
halve eq(num,1) :s(freturn)
halve = num / 2 :(return)
halve_end
define('double(num)') :(double_end)
double double = num * 2 :(return)
define('double(num)') :(double_end)
double double = num * 2 :(return)
double_end
define('odd(num)') :(odd_end)
odd eq(num,1) :s(return)
eq(num,double(halve(num))) :s(freturn)f(return)
define('odd(num)') :(odd_end)
odd eq(num,1) :s(return)
eq(num,double(halve(num))) :s(freturn)f(return)
odd_end l = trim(input)
r = trim(input)
s = 0
next s = odd(l) s + r
r = double(r)
l = halve(l) :s(next)
stop output = s
odd_end l = trim(input)
r = trim(input)
s = 0
next s = odd(l) s + r
r = double(r)
l = halve(l) :s(next)
stop output = s
end

View file

@ -20,7 +20,7 @@ Number extend [
ifTrue: [
tutor ifTrue: [
('%1, %2 struck' % { multiplier. multiplicand })
displayNl
displayNl
]
].
multiplier := multiplier halve.

View file

@ -9,22 +9,22 @@ function even n {($n & 1) == 0}
function mult {a b} {
$a < 1 ? 0 :
even($a) ? [logmult STRUCK] + mult(halve($a), double($b))
: [logmult KEPT] + mult(halve($a), double($b)) + $b
: [logmult KEPT] + mult(halve($a), double($b)) + $b
}
# Wrapper to set up the logging
proc ethiopianMultiply {a b {tutor false}} {
if {$tutor} {
set wa [expr {[string length $a]+1}]
set wb [expr {$wa+[string length $b]-1}]
puts stderr "Ethiopian multiplication of $a and $b"
interp alias {} logmult {} apply {{wa wb msg} {
upvar 1 a a b b
puts stderr [format "%*d %*d %s" $wa $a $wb $b $msg]
return 0
}} $wa $wb
set wa [expr {[string length $a]+1}]
set wb [expr {$wa+[string length $b]-1}]
puts stderr "Ethiopian multiplication of $a and $b"
interp alias {} logmult {} apply {{wa wb msg} {
upvar 1 a a b b
puts stderr [format "%*d %*d %s" $wa $a $wb $b $msg]
return 0
}} $wa $wb
} else {
proc logmult args {return 0}
proc logmult args {return 0}
}
return [expr {mult($a,$b)}]
}

View file

@ -1,29 +1,29 @@
!RosettaCode: Ethiopian Multiplication
! True BASIC v6.007
PROGRAM EthiopianMultiplication
DECLARE DEF FNdouble
DECLARE DEF FNhalve
DECLARE DEF FNeven
LET x = 17
LET y = 34
DO
IF FNeven(x) = 0 THEN
LET p = p + y
PRINT x,y
ELSE
PRINT x," ---"
END IF
LET x = FNhalve(x)
LET y = FNdouble(y)
LOOP UNTIL x = 0
PRINT " ", " ==="
PRINT " ", p
GET KEY done
DEF FNdouble(A) = A * 2
DEF FNhalve(A) = INT(A / 2)
DEF FNeven(A) = MOD(A+1,2)
DECLARE DEF FNdouble
DECLARE DEF FNhalve
DECLARE DEF FNeven
LET x = 17
LET y = 34
DO
IF FNeven(x) = 0 THEN
LET p = p + y
PRINT x,y
ELSE
PRINT x," ---"
END IF
LET x = FNhalve(x)
LET y = FNdouble(y)
LOOP UNTIL x = 0
PRINT " ", " ==="
PRINT " ", p
GET KEY done
DEF FNdouble(A) = A * 2
DEF FNhalve(A) = INT(A / 2)
DEF FNeven(A) = MOD(A+1,2)
END

View file

@ -19,9 +19,9 @@ ethiopicmult()
plicand=$2
r=0
while [ "$plier" -ge 1 ]; do
is_even "$plier" || r=`expr $r + "$plicand"`
plier=`halve "$plier"`
plicand=`double "$plicand"`
is_even "$plier" || r=`expr $r + "$plicand"`
plier=`halve "$plier"`
plicand=`double "$plicand"`
done
echo $r
}

View file

@ -1,89 +0,0 @@
option explicit
class List
private theList
private nOccupiable
private nTop
sub class_initialize
nTop = 0
nOccupiable = 100
redim theList( nOccupiable )
end sub
public sub store( x )
if nTop >= nOccupiable then
nOccupiable = nOccupiable + 100
redim preserve theList( nOccupiable )
end if
theList( nTop ) = x
nTop = nTop + 1
end sub
public function recall( n )
if n >= 0 and n <= nOccupiable then
recall = theList( n )
else
err.raise vbObjectError + 1000,,"Recall bounds error"
end if
end function
public sub replace( n, x )
if n >= 0 and n <= nOccupiable then
theList( n ) = x
else
err.raise vbObjectError + 1001,,"Replace bounds error"
end if
end sub
public property get listCount
listCount = nTop
end property
end class
function halve( n )
halve = int( n / 2 )
end function
function twice( n )
twice = int( n * 2 )
end function
function iseven( n )
iseven = ( ( n mod 2 ) = 0 )
end function
function multiply( n1, n2 )
dim LL
set LL = new List
dim RR
set RR = new List
LL.store n1
RR.store n2
do while n1 <> 1
n1 = halve( n1 )
LL.store n1
n2 = twice( n2 )
RR.store n2
loop
dim i
for i = 0 to LL.listCount
if iseven( LL.recall( i ) ) then
RR.replace i, 0
end if
next
dim total
total = 0
for i = 0 to RR.listCount
total = total + RR.recall( i )
next
multiply = total
end function

View file

@ -1 +0,0 @@
wscript.echo multiply(17,34)

View file

@ -1,109 +1,109 @@
extern printf
global main
extern printf
global main
section .text
section .text
halve
shr ebx, 1
ret
shr ebx, 1
ret
double
shl ebx, 1
ret
shl ebx, 1
ret
iseven
and ebx, 1
cmp ebx, 0
ret ; ret preserves flags
and ebx, 1
cmp ebx, 0
ret ; ret preserves flags
main
push 1 ; tutor = true
push 34 ; 2nd operand
push 17 ; 1st operand
call ethiopicmult
add esp, 12
push 1 ; tutor = true
push 34 ; 2nd operand
push 17 ; 1st operand
call ethiopicmult
add esp, 12
push eax ; result of 17*34
push fmt
call printf
add esp, 8
push eax ; result of 17*34
push fmt
call printf
add esp, 8
ret
ret
%define plier 8
%define plicand 12
%define tutor 16
ethiopicmult
enter 0, 0
cmp dword [ebp + tutor], 0
je .notut0
push dword [ebp + plicand]
push dword [ebp + plier]
push preamblefmt
call printf
add esp, 12
enter 0, 0
cmp dword [ebp + tutor], 0
je .notut0
push dword [ebp + plicand]
push dword [ebp + plier]
push preamblefmt
call printf
add esp, 12
.notut0
xor eax, eax ; eax -> result
mov ecx, [ebp + plier] ; ecx -> plier
mov edx, [ebp + plicand] ; edx -> plicand
xor eax, eax ; eax -> result
mov ecx, [ebp + plier] ; ecx -> plier
mov edx, [ebp + plicand] ; edx -> plicand
.whileloop
cmp ecx, 1
jl .multend
cmp dword [ebp + tutor], 0
je .notut1
call tutorme
cmp ecx, 1
jl .multend
cmp dword [ebp + tutor], 0
je .notut1
call tutorme
.notut1
mov ebx, ecx
call iseven
je .iseven
add eax, edx ; result += plicand
mov ebx, ecx
call iseven
je .iseven
add eax, edx ; result += plicand
.iseven
mov ebx, ecx ; plier >>= 1
call halve
mov ecx, ebx
mov ebx, ecx ; plier >>= 1
call halve
mov ecx, ebx
mov ebx, edx ; plicand <<= 1
call double
mov edx, ebx
jmp .whileloop
mov ebx, edx ; plicand <<= 1
call double
mov edx, ebx
jmp .whileloop
.multend
leave
ret
leave
ret
tutorme
push eax
push strucktxt
mov ebx, ecx
call iseven
je .nostruck
mov dword [esp], kepttxt
push eax
push strucktxt
mov ebx, ecx
call iseven
je .nostruck
mov dword [esp], kepttxt
.nostruck
push edx
push ecx
push tutorfmt
call printf
add esp, 4
pop ecx
pop edx
add esp, 4
pop eax
ret
push edx
push ecx
push tutorfmt
call printf
add esp, 4
pop ecx
pop edx
add esp, 4
pop eax
ret
section .data
section .data
fmt
db "%d", 10, 0
db "%d", 10, 0
preamblefmt
db "ethiopic multiplication of %d and %d", 10, 0
db "ethiopic multiplication of %d and %d", 10, 0
tutorfmt
db "%4d %6d %s", 10, 0
db "%4d %6d %s", 10, 0
strucktxt
db "struck", 0
db "struck", 0
kepttxt
db "kept", 0
db "kept", 0

View file

@ -3,28 +3,28 @@ x = 17
y = 34
do
print x, chr$(09);
if not (isEven(x)) then
outP = outP + y
print y
else
print
fi
if x < 2 break
x = half(x)
y = doub(y)
print x, chr$(09);
if not (isEven(x)) then
outP = outP + y
print y
else
print
fi
if x < 2 break
x = half(x)
y = doub(y)
loop
print "=", chr$(09), outP
end
sub doub (a)
return a * 2
return a * 2
end sub
sub half (a)
return int(a / 2)
return int(a / 2)
end sub
sub isEven (a)
return mod(a, 2) - 1
return mod(a, 2) - 1
end sub

View file

@ -1,114 +1,114 @@
org &8000
org &8000
ld hl,17
call Halve_Until_1
push bc
ld hl,34
call Double_Until_1
pop bc
call SumOddEntries
;returns Ethiopian product in IX.
call NewLine
call Primm
byte "0x",0
push ix
pop hl
ld a,H
call ShowHex
;Output should be in decimal but hex is easier.
ld a,L
call ShowHex
ret
ld hl,17
call Halve_Until_1
push bc
ld hl,34
call Double_Until_1
pop bc
call SumOddEntries
;returns Ethiopian product in IX.
call NewLine
call Primm
byte "0x",0
push ix
pop hl
ld a,H
call ShowHex
;Output should be in decimal but hex is easier.
ld a,L
call ShowHex
ret
Halve_Until_1:
;input: HL = number you wish to halve. HL is unsigned.
ld de,Column_1
ld a,1
ld (Column_1),HL
inc de
inc de
;input: HL = number you wish to halve. HL is unsigned.
ld de,Column_1
ld a,1
ld (Column_1),HL
inc de
inc de
loop_HalveUntil_1:
SRL H
RR L
inc b
push af
ld a,L
ld (de),a
inc de
ld a,H
ld (de),a
inc de
pop af
CP L
jr nz,loop_HalveUntil_1
;b tracks how many times to double the second factor.
ret
SRL H
RR L
inc b
push af
ld a,L
ld (de),a
inc de
ld a,H
ld (de),a
inc de
pop af
CP L
jr nz,loop_HalveUntil_1
;b tracks how many times to double the second factor.
ret
Double_Until_1:
;doubles second factor B times. B is calculated by Halve_until_1
ld de,Column_2
ld (Column_2),HL
inc de
inc de
;doubles second factor B times. B is calculated by Halve_until_1
ld de,Column_2
ld (Column_2),HL
inc de
inc de
loop_double_until_1:
SLA L
RL H
PUSH AF
LD A,L
LD (DE),A
INC DE
LD A,H
LD (DE),A
INC DE
POP AF
DJNZ loop_double_until_1
ret
SLA L
RL H
PUSH AF
LD A,L
LD (DE),A
INC DE
LD A,H
LD (DE),A
INC DE
POP AF
DJNZ loop_double_until_1
ret
SumOddEntries:
sla b ;double loop counter, this is also the offset to the "last" entry of
;each table
ld h,>Column_1
ld d,>Column_2 ;aligning the tables lets us get away with this.
ld l,b
ld e,b
ld ix,0
sla b ;double loop counter, this is also the offset to the "last" entry of
;each table
ld h,>Column_1
ld d,>Column_2 ;aligning the tables lets us get away with this.
ld l,b
ld e,b
ld ix,0
loop:
ld a,(hl)
rrca ;we only need the result of the odd/even test.
jr nc,skipEven
push hl
push de
ld a,(de)
ld L,a
inc de
ld a,(de)
ld H,a
ex de,hl
add ix,de
pop de
pop hl
ld a,(hl)
rrca ;we only need the result of the odd/even test.
jr nc,skipEven
push hl
push de
ld a,(de)
ld L,a
inc de
ld a,(de)
ld H,a
ex de,hl
add ix,de
pop de
pop hl
skipEven:
dec de
dec de
dec hl
dec hl
djnz loop
ret ;ix should contain the answer
dec de
dec de
dec hl
dec hl
djnz loop
ret ;ix should contain the answer
align 8 ;aligns Column_1 to the nearest 256 byte boundary. This makes offsetting easier.
align 8 ;aligns Column_1 to the nearest 256 byte boundary. This makes offsetting easier.
Column_1:
ds 16,0
align 8 ;aligns Column_2 to the nearest 256 byte boundary. This makes offsetting easier.
ds 16,0
align 8 ;aligns Column_2 to the nearest 256 byte boundary. This makes offsetting easier.
Column_2:
ds 16,0
ds 16,0