Ethiopian multiplication: Difference between revisions

Content added Content deleted
m (→‎{{header|Ruby}}: move tests for clarity)
m (Fixed lang tags.)
Line 106: Line 106:


<!-- {{does not work with|ELLA ALGOL 68|Any (with appropriate job cards) - tested with release 1.8.8d.fc9.i386 - missing printf and FORMAT}} -->
<!-- {{does not work with|ELLA ALGOL 68|Any (with appropriate job cards) - tested with release 1.8.8d.fc9.i386 - missing printf and FORMAT}} -->
<lang algol68>PROC halve = (REF INT x)VOID: x := ABS(BIN x SHR 1);
<lang algol>
PROC halve = (REF INT x)VOID: x := ABS(BIN x SHR 1);
PROC doublit = (REF INT x)VOID: x := ABS(BIN x SHL 1);
PROC doublit = (REF INT x)VOID: x := ABS(BIN x SHL 1);
PROC iseven = (#CONST# INT x)BOOL: NOT ODD x;
PROC iseven = (#CONST# INT x)BOOL: NOT ODD x;
Line 135: Line 134:
(
(
printf(($g(0)l$, ethiopian(17, 34, TRUE)))
printf(($g(0)l$, ethiopian(17, 34, TRUE)))
)</lang>
)
</lang>
Output:
Output:
<pre>
<pre>
Line 254: Line 252:
Here is such an implementation without tutor, since there is no mechanism in C++ to output
Here is such an implementation without tutor, since there is no mechanism in C++ to output
messages during program compilation.
messages during program compilation.
<lang cpp>
<lang cpp>template<int N>
template<int N>
struct Half
struct Half
{
{
Line 308: Line 305:
std::cout << EthiopianMultiplication<17, 54>::Result << std::endl;
std::cout << EthiopianMultiplication<17, 54>::Result << std::endl;
return 0;
return 0;
}</lang>
}
</lang>


=={{header|C sharp|C#}}==
=={{header|C sharp|C#}}==
<lang csharp>
<lang csharp>static void Main(string[] args)
static void Main(string[] args)
{
{
EthopianMultiplication(17, 34);
EthopianMultiplication(17, 34);
Line 357: Line 352:
Version with as a function of functions:
Version with as a function of functions:


<lang cfm><cffunction name="double">
<lang ColdFusion>
<cffunction name="double">
<cfargument name="number" type="numeric" required="true">
<cfargument name="number" type="numeric" required="true">
<cfset answer = number * 2>
<cfset answer = number * 2>
Line 392: Line 386:




<cfoutput>#ethiopian(17,34)#</cfoutput>
<cfoutput>#ethiopian(17,34)#</cfoutput></lang>
</lang>


Version with display pizza:
Version with display pizza:


<lang ColdFusion>
<lang cfm><cfset Number_A = 17>
<cfset Number_A = 17>
<cfset Number_B = 34>
<cfset Number_B = 34>
<cfset Result = 0>
<cfset Result = 0>
Line 454: Line 446:
...equals #Result#
...equals #Result#


</cfoutput>
</cfoutput></lang>
</lang>


Sample output:
Sample output:
Line 470: Line 461:


=={{header|Clojure}}==
=={{header|Clojure}}==
<lang clojure>
<lang lisp>(defn halve [n]
(defn halve [n]
(bit-shift-right n 1))
(bit-shift-right n 1))


Line 495: Line 485:
(if (even a)
(if (even a)
(recur (halve a) (twice b) r)
(recur (halve a) (twice b) r)
(recur (halve a) (twice b) (+ r b))))))
(recur (halve a) (twice b) (+ r b))))))</lang>
</lang>


=={{header|Common Lisp}}==
=={{header|Common Lisp}}==
Line 512: Line 501:


=={{header|D}}==
=={{header|D}}==
<lang d>
<lang d>import std.stdio;
import std.stdio;
int dub(int num) { return num << 1; }
int dub(int num) { return num << 1; }
int halve(int num) { return num >> 1; }
int halve(int num) { return num >> 1; }
Line 531: Line 519:
writefln("17 ethiopian 34 is %d", ethiopian(17, 34));
writefln("17 ethiopian 34 is %d", ethiopian(17, 34));
return 0;
return 0;
}</lang>
}
</lang>


=={{header|E}}==
=={{header|E}}==
Line 550: Line 537:


=={{header|FALSE}}==
=={{header|FALSE}}==
<lang false>
<lang false>[2/]h:
[2/]h:
[2*]d:
[2*]d:
[1&]o:
[1&]o:
Line 650: Line 636:


'''Solution''':
'''Solution''':
double =: 2&* NB. or the primitive +:
<lang j>double =: 2&* NB. or the primitive +:
halve =: %&2 NB. or the primitive -:
halve =: %&2 NB. or the primitive -:
even =: 2&|
even =: 2&|


ethiop =: +/@(even@] # (double~ <@#)) (1>.<.@halve)^:a:
ethiop =: +/@(even@] # (double~ <@#)) (1>.<.@halve)^:a:</lang>


'''Example''':
'''Example''':
17 ethiop 34
<lang j> 17 ethiop 34
578
578</lang>


Note: this could be implemented more concisely as <tt>#.@(*#:)</tt>, which abides by the letter of the task, but [http://www.jsoftware.com/pipermail/programming/2009-July/015507.html evades its spirit].
Note: this could be implemented more concisely as <tt>#.@(*#:)</tt>, which abides by the letter of the task, but [http://www.jsoftware.com/pipermail/programming/2009-July/015507.html evades its spirit].
Line 702: Line 688:
}</lang>
}</lang>
An optimised variant using the three helper functions from the other example.
An optimised variant using the three helper functions from the other example.
<lang java5>
<lang java5>/**
* This method will use ethiopian styled multiplication.
/**
* @param a Any non-negative integer.
* This method will use ethiopian styled multiplication.
* @param a Any non-negative integer.
* @param b Any integer.
* @result a multiplied by b
* @param b Any integer.
*/
* @result a multiplied by b
public static int ethiopianMultiply(int a, int b) {
*/
if(a==0 || b==0) {
public static int ethiopianMultiply(int a, int b) {
if(a==0 || b==0) {
return 0;
}
return 0;
int result = 0;
while(a>=1) {
if(!isEven(a)) {
result+=b;
}
}
int result = 0;
b = doubleInt(b);
while(a>=1) {
a = halveInt(a);
if(!isEven(a)) {
result+=b;
}
b = doubleInt(b);
a = halveInt(a);
}
return result;
}
}
return result;
}


/**
/**
* This method is an improved version that will use
* This method is an improved version that will use
* ethiopian styled multiplication, but can fully
* ethiopian styled multiplication, but can fully
* support negative parameters.
* support negative parameters.
* @param a Any integer.
* @param a Any integer.
* @param b Any integer.
* @param b Any integer.
* @result a multiplied by b
* @result a multiplied by b
*/
*/
public static int ethiopianMultiplyWithImprovement(int a, int b) {
public static int ethiopianMultiplyWithImprovement(int a, int b) {
if(a==0 || b==0) {
if(a==0 || b==0) {
return 0;
return 0;
}
}
if(a<0) {
if(a<0) {
a=-a;
a=-a;
b=-b;
b=-b;
} else if(b>0 && a>b) {
} else if(b>0 && a>b) {
int tmp = a;
int tmp = a;
a = b;
a = b;
b = tmp;
b = tmp;
}
int result = 0;
while(a>=1) {
if(!isEven(a)) {
result+=b;
}
}
int result = 0;
b = doubleInt(b);
while(a>=1) {
a = halveInt(a);
if(!isEven(a)) {
result+=b;
}
b = doubleInt(b);
a = halveInt(a);
}
return result;
}
}
return result;
</lang>
}</lang>


== {{header|JavaScript}} ==
== {{header|JavaScript}} ==


<lang javascript>
<lang javascript>var eth = {
var eth = {
halve : function ( n ){ return Math.floor(n/2); },
halve : function ( n ){ return Math.floor(n/2); },
Line 787: Line 770:
}
}


// eth.mult(17,34) returns 578
// eth.mult(17,34) returns 578</lang>
</lang>


=={{header|Logo}}==
=={{header|Logo}}==
<lang logo>
<lang logo>to double :x
to double :x
output ashift :x 1
output ashift :x 1
end
end
Line 806: Line 787:
[output eproduct halve :x double :y] ~
[output eproduct halve :x double :y] ~
[output :y + eproduct halve :x double :y]
[output :y + eproduct halve :x double :y]
end
end</lang>
</lang>


=={{header|Metafont}}==
=={{header|Metafont}}==
Line 1,111: Line 1,091:
=={{header|PL/SQL}}==
=={{header|PL/SQL}}==
This code was taken from the ADA example above - very minor differences.
This code was taken from the ADA example above - very minor differences.
<lang plsql>
<lang plsql>create or replace package ethiopian is
create or replace package ethiopian is


function multiply
function multiply
Line 1,171: Line 1,150:
dbms_output.put_line(ethiopian.multiply(17, 34));
dbms_output.put_line(ethiopian.multiply(17, 34));
end;
end;
/</lang>
/
</lang>




Line 1,180: Line 1,158:
Everything encapsulated in one function.
Everything encapsulated in one function.


<lang plpgsql>CREATE OR REPLACE FUNCTION ethiopian_multiplication(multiplier int, multiplicant int) RETURNS int AS $BODY$
<lang plpgsql>
CREATE OR REPLACE FUNCTION ethiopian_multiplication(multiplier int, multiplicant int) RETURNS int AS $BODY$
-- works at least on PostgreSQL 8.3, should work in older versions as well
-- works at least on PostgreSQL 8.3, should work in older versions as well
DECLARE
DECLARE
Line 1,216: Line 1,193:
RETURN sum;
RETURN sum;
END;
END;
$BODY$ LANGUAGE 'plpgsql';
$BODY$ LANGUAGE 'plpgsql';</lang>
</lang>


<lang plpgsql>SELECT ethiopian_multiplication(17, 34);</lang>
<lang sql>
SELECT ethiopian_multiplication(17, 34);
</lang>


<lang text>
<lang plpgsql>NOTICE: 17, 34 KEEP
NOTICE: 17, 34 KEEP
NOTICE: 8, 68 STRIKE
NOTICE: 8, 68 STRIKE
NOTICE: 4, 136 STRIKE
NOTICE: 4, 136 STRIKE
Line 1,232: Line 1,205:
--------------------------
--------------------------
578
578
(1 row)
(1 row)</lang>
</lang>


=={{header|PowerShell}}==
=={{header|PowerShell}}==
<lang PowerShell>
<lang PowerShell>function isEven {
function isEven {
param ([int]$value)
param ([int]$value)
return [bool]($value % 2 -eq 0)
return [bool]($value % 2 -eq 0)
Line 1,271: Line 1,242:
}
}


multiplyValues 17 34
multiplyValues 17 34</lang>
</lang>


=={{header|Python}}==
=={{header|Python}}==
<lang python>
<lang python>tutor = True
tutor = True


def halve(x):
def halve(x):
Line 1,303: Line 1,272:
multiplicand = double(multiplicand)
multiplicand = double(multiplicand)
if tutor: print()
if tutor: print()
return result
return result</lang>
</lang>


Sample output
Sample output
Line 1,322: Line 1,290:
Without the tutorial code, and taking advantage of Python's lambda:
Without the tutorial code, and taking advantage of Python's lambda:


<lang python>
<lang python>halve = lambda x: x // 2
halve = lambda x: x // 2
double = lambda x: x*2
double = lambda x: x*2
even = lambda x : not x % 2
even = lambda x : not x % 2
Line 1,336: Line 1,303:
multiplicand = double(multiplicand)
multiplicand = double(multiplicand)


return result
return result</lang>
</lang>


=={{header|R}}==
=={{header|R}}==
Line 1,511: Line 1,477:
=={{header|SNUSP}}==
=={{header|SNUSP}}==


<lang snusp>
<lang snusp> /==!/==atoi==@@@-@-----#
/==!/==atoi==@@@-@-----#
| | /-\ /recurse\ #/?\ zero
| | /-\ /recurse\ #/?\ zero
$>,@/>,@/?\<=zero=!\?/<=print==!\@\>?!\@/<@\.!\-/
$>,@/>,@/?\<=zero=!\?/<=print==!\@\>?!\@/<@\.!\-/
Line 1,522: Line 1,487:
\>+<-/ | \=<<<!/====?\=\ | double
\>+<-/ | \=<<<!/====?\=\ | double
! # | \<++>-/ | |
! # | \<++>-/ | |
\=======\!@>============/!/
\=======\!@>============/!/</lang>
</lang>


This is possibly the smallest multiply routine so far discovered for SNUSP.
This is possibly the smallest multiply routine so far discovered for SNUSP.
Line 1,608: Line 1,572:
functions are normally imported from the nat library but defined here explicitly for
functions are normally imported from the nat library but defined here explicitly for
the sake of completeness.
the sake of completeness.
<lang Ursala>
<lang Ursala>odd = ~&ihB
odd = ~&ihB
double = ~&iNiCB
double = ~&iNiCB
half = ~&itB
half = ~&itB</lang>
</lang>
The functions above are defined in terms of bit manipulations exploiting the concrete representations
The functions above are defined in terms of bit manipulations exploiting the concrete representations
of natural numbers. The remaining code treats natural numbers instead as abstract types by way of the library API, and uses the operators for distribution (*-), triangular iteration (|\),
of natural numbers. The remaining code treats natural numbers instead as abstract types by way of the library API, and uses the operators for distribution (*-), triangular iteration (|\),
and filtering (*~) among others.
and filtering (*~) among others.
<lang Ursala>
<lang Ursala>#import nat
#import nat


emul = sum:-0@rS+ odd@l*~+ ^|(~&,double)|\+ *-^|\~& @iNC ~&h~=0->tx :^/half@h ~&
emul = sum:-0@rS+ odd@l*~+ ^|(~&,double)|\+ *-^|\~& @iNC ~&h~=0->tx :^/half@h ~&</lang>
</lang>


test program:
test program:
<lang Ursala>
<lang Ursala>#cast %n
#cast %n


test = emul(34,17)
test = emul(34,17)</lang>
</lang>
output:
output:
<pre>
<pre>