# Russian Peasant Multiplication

This is my quick hack using VBScript.

I don't feel it fully implements the algorithm (no "maintaining two columns"), or is as efficient as it could be.... but, it's a start of what your code should NOT end up like...

Function Mult( a, b )
While a > 1
a = a \ 2 ' Surprise: "\" is Int division!
b = b * 2
If a Mod 2 = 1 Then Mult = Mult + b
Wend
End Function
• Tim 2009-07-22 08:20
```int Multiply(int a, int b)
{
int c = 0;
do
{
if (a & 1)
c += b;
a >>= 1;
b <<= 1;
} while (a > 0);
return c;
}
```

Untested, might not work for negative numbers.
• Tim 2009-07-22 08:22
Actually not sure why I did do..while instead of just while... Oh well.
Cheeky Java solution..

private int multiple(int a, int b) {

int rtn = 0;
while (a > 0) {

if (a % 2 != 0) {
rtn += b;
}

a = a / 2;
b = b * 2;
}

return rtn;
}

:-)
• Jay 2009-07-22 08:23
public static int multiply(int first, int second){
if(first == 1){
return second;
}

int result = 0;

if(first%2 != 0){
result += second;
}
result += multiply(first/2, second * 2);
return result;
}
• The Wolf 2009-07-22 08:24
And in PHP:

```<?php

function russian(\$x, \$y) {
\$left = array();
\$right = array();

while (\$x > 1) {
\$left[] = \$x;
\$right[] = \$y;

\$x = floor(\$x / 2);
\$y *= 2;
}

\$left[] = \$x;
\$right[] = \$y;
\$result = 0;

foreach (\$left as \$index => \$x) if (\$x % 2) {
\$result += \$right[\$index];
}

return \$result;
}

echo russian(41238, 193625);

?>```
• The Dopefish 2009-07-22 08:25
A recursive C# solution:

static int Multiply(int a, int b)
{
if (a < 2)
return (a == 1 ? b : 0);
if (a % 2 == 1)
return b + Multiply(a / 2, b * 2);
return Multiply(a / 2, b * 2);
}
• ath 2009-07-22 08:26
Same thing in python:
```def is_odd(n):
return (n % 2) != 0

def rmul(x, y):
s = 0
while(x != 1):
if is_odd(x):
s += y
x /= 2
y *= 2
return y + s
```

• snoofle 2009-07-22 08:26
Waiting for a solution in brainfuck...
• mat 2009-07-22 08:26
This is my implementation of the algorithm using standard *nix bash script (with the addition of awk):

#!/bin/bash

X="\$1"
Y="\$2"

if [ \$X -lt 0 ]
then
SIGN=-1
X=\$(( X * -1 ))
else
SIGN=1
fi

LEFT="\$X"
RIGHT="\$Y"

while [ "\$X" -ne 1 ]
do
X=\$(( X / 2 ))
Y=\$(( Y * 2 ))
LEFT="\$LEFT \$X"
RIGHT="\$RIGHT \$Y"
done

L=`echo \$LEFT | wc -w`
RESULT=0
for I in `seq 1 \$L`
do
X=`echo \$LEFT | awk "{print \$"\$I"}"`
Y=`echo \$RIGHT | awk "{print \$"\$I"}"`
if [ \$(( X % 2 )) -ne 0 ]
then
RESULT=\$(( RESULT + Y ))
fi
done

RESULT=\$(( RESULT * SIGN ))

echo "\$1 x \$2 = \$RESULT"
• hydrus 2009-07-22 08:34
Obligatory Clojure entry:

```(defn rmult
([x y] (rmult x y 0))
([x y p]
(if (= x 1)
(+ y p)
(recur (quot x 2) (* y 2) (if (odd? x) (+ p y) p)))))
```
• Dascandy 2009-07-22 08:37
X86:
```; assumption: eax contains arg1, ebx contains arg2
mov edx, eax
next:
shr ebx, 1
cmovc ecx, edx
cmovnc ecx, 0
jz end
lea eax, [eax*2 + ecx]
jmp next

end:
ret
```

ARM:
```	mov r2, r0
next    test r1, 1
mov r1, #0, r1 shr 1
movz pc, lr
b next
```

• ParkinT 2009-07-22 08:39
Wow!
I had not time to submit a solution.
Everyone was too busy Russian to provide an answer!
• SQLDork 2009-07-22 08:39
And a SQL implementation...

create function wtf.RussianMultiply(@m1 bigint, @m2 bigint)
returns bigint
as
begin
declare @out bigint
set @out =0
while @m1 > 1
select @m1 = @m1 / 2,
@m2 = @m2 * 2,
@out = @out + case when @m1 & 1 = 1 then @m2 else 0 end
return(@out)
end
go
• Z 2009-07-22 08:40
function ruM (left, right) {
var route = '', remainder = 0;
while (left>1) {
if (left % 2 != 0) {
remainder += right;
left -= 1;
//route += 'remainder: ' + remainder + '\n';
}
left /= 2;
right *= 2;
//route += left + 'x' + right + '\n';
}
return right + remainder;
}
• Erin 2009-07-22 08:40
A simpler PHP version:

<?php

function in_mother_russia(\$x, \$y)
{
\$z = 0;

while (\$x)
{
if (\$x % 2) \$z += \$y;

\$x = floor(\$x / 2);
\$y *= 2;
}

return \$z;
}

echo 'In mother Russia, 18 x 23 = '.in_mother_russia(18, 23);
• Larry H. 2009-07-22 08:41
```unsigned russian(unsigned a, unsigned b)
{
return ((a & 1) ? b : 0) + ((a & ~1) ? russian(a>>1, b<<1) : 0);
}```

Not tested.
• The Wolf 2009-07-22 08:41
Not sure why I used that array bullcrap, too used to string manipulation I guess. Here's a better version for PHP:

```<?php

function russian(\$x, \$y) {
\$result = 0;

while (\$x > 1) {
if (\$x % 2) \$result += \$y;

\$x = floor(\$x / 2);
\$y *= 2;
}

return \$y + \$result;
}

echo russian(41238, 193625);

?>```
• dv 2009-07-22 08:41
using ABAP (only a bit esoteric:-))

```FORM multiply USING   a TYPE I
b TYPE I
CHANGING c TYPE I.
CLEAR c.
WHILE a GT 0.
IF ( a MOD 2 EQ 1 ).
ENDIF.
DIVIDE a BY 2.
MULTIPLY b BY 2.
ENDWHILE.
ENDFORM.
```
• Paula 2009-07-22 08:42
public class Paula extends WTF {
public static string Paulabean = "brillant!";
}
• Mat Rantell 2009-07-22 08:42
A short recursive Java version:

public static long multiply( long left, long right ) {
return ( ( left % 2 ) == 0 ? 0 : right
+ ( left == 1 ? 0 : multiply( left / 2, right * 2 ) );
}
• Kees 2009-07-22 08:43
Function Diederick ( Jan, Piet )
While Jan > 1
Jan = Jan \ 2
Piet = Piet * 2
If Jan Mod 2 = 1 Then Diederick = Diederick + Piet
Wend
End Function
• Bosshog 2009-07-22 08:44
```	;  6502 Assembler (4-bit operands only)
;  \$0001 should contain operand 1 (not preserved)
;  \$0002 should contain operand 2 (not preserved)

LDA #0
LDX #0
loop:
CPX \$02
BEQ done
CLC
LSR \$02
BCC skip
CLC
skip:
ASL \$01
JMP loop

done:
STA \$00
```
• ath 2009-07-22 08:48
Another Python version. This time it handles zero and negative numbers properly... Floats works as second arg but not as first. Seems like too much work to fix it though...

```def is_odd(n):
return (n % 2) != 0

def rmul(x, y):
if(x < 0):
sgn = -1
x = -x
else:
sgn = 1

s = 0
while(x >= 1):
if is_odd(x):
s += y
x /= 2
y *= 2
return sgn*s
```
• Me 2009-07-22 08:49
Bah to all your bloaty solutions. Perlmongers do it in one line :P

sub m(){my(\$a,\$b)=@_;my \$t;while(\$a){\$t+=\$b if (\$a&1);\$a>>=1;\$b<<=1;}return \$t;}
• Anonymous 2009-07-22 08:49
Win!
• Bombe 2009-07-22 08:51
In Soviet Russia, peasants multiply you.
• phihag 2009-07-22 08:53
Various iterative solutions in python:

```# python3 only, one-liner!
def mul3(a,b):
return sum(b << i if (a>>i)&1 else 0 for i in range(a.bit_length()))

def bits(value):
while value > 0:
yield value & 1
value = value // 2

def mul1(a,b):
res = 0
for a in bits(a):
if a:
res += b
b *= 2

return res

def mul2(a,b):
return sum(b << i if abit else 0 for i,abit in enumerate(bits(a)))

try:
mul = mul3
except AttributeError:
mul = mul2
```
• Brettm 2009-07-22 08:54
Ta for the teaser, well back to my reports :(

```        static void Main(string[] args)
{
Console.WriteLine(RM(18, 23, 0));
}

public static int RM(int val1, int val2, int rem)
{
int mod = val1 % 2;
int _rem = (mod * val2) + rem;
int _v1 = val1 / 2;
int _v2 = val2 * 2;
if (val1 != 1)
{
return RM(_v1, _v2, _rem);
}
return _v1 + _rem;
}
```

Condensed version:
```        public static int RM(int val1, int val2, int rem)
{
if (val1 != 1)
{
return RM((val1 / 2), val2 * 2, ((val1 % 2) * val2) + rem);
}
return (val1 / 2) + ((val1 % 2) * val2) + rem;
}
```
• Stefan 2009-07-22 08:55
simple c with a little optimization
```unsigned int mul(unsigned int x, unsigned int y)
{
unsigned int r = 0;
unsigned int t;
if (y > x)
{
t = y;
y = x;
x = t;
}
while(x)
{
if (x & 1)
r += y;
x >>= 1;
y <<= 1;
}
return r;
}
```
• Takis 2009-07-22 08:55
VB.Net

```Private Function Russiply(ByVal a As Long, ByVal b As Long) As Long

Do
If (a And 1) = 1 Then Russiply += b
a = a >> 1
b = b << 1
Loop Until a <= 1

If (a And 1) = 1 Then Russiply += b

End Function
```
• Zombywuf 2009-07-22 08:56
```template<int x, int y, int accum, int mutliple>
struct multiply_ {
static const int value = multiply_<x / 2, y * 2, accum, (x / 2) & 1>::value;
};

template<int x, int y, int accum>
struct multiply_<x, y, accum, 1> {
static const int value = multiply_<x / 2, y * 2, accum + y, (x / 2) & 1>::value;
};

template<int y, int accum>
struct multiply_<0, y, accum, 0> {
static const int value = accum;
};

template<int x, int y>
struct multiply : multiply_<x, y, 0, x & 1> {};
```
• KnowOracle 2009-07-22 08:57
Oracle SQL version:

```14:55:42 SQL> set echo on
SQL> @russian_mult 18 23
SQL> select sum(b)
2  from (select floor(a / power(2, rn)) as a,
3               b * power(2, rn) as b
4        from (select &1 as a,
5                     &2 as b,
6                     rownum as rn
7              from dual
8              connect by level < log(2, 18)))
9  where mod(a, 2) <> 0
10  /
old   4:       from (select &1 as a,
new   4:       from (select 18 as a,
old   5:                    &2 as b,
new   5:                    23 as b,

SUM(B)
----------
414

1 row selected.
```
• Captain Obvious 2009-07-22 08:59
I haven't done APL in a LONG time...

```     Z <- A RUSSIAN B
[1]  Z <- 0
[2] TOP:
[3]  Z <- Z + A * 0 = 2 | B
[4]  A <- |_ A (divide) 2
[5]  B <- B x 2
[6]  -> (A>0) / TOP
```
• phihag 2009-07-22 08:59
An addition to my solution (see above): The python3 version is not only one line, but only one statement! Is there any other language where you can implement it in one statement without recursion?
• freakpants 2009-07-22 08:59
seems like you killed esolangs :D
• SR 2009-07-22 09:00
Bah. Looks like we've bost the esolangs.org server.

esolangs.org:
Esolang has a problem

Sorry! This site is experiencing technical difficulties.

(Can't contact the database server: Can't connect to local MySQL server through socket '/tmp/mysql.sock' (61) (localhost))

Anyone know if ColdFusion was on there? ;o)
• KnowOracle 2009-07-22 09:00
log(2, 18) should read log (1, &1)
• Fenris 2009-07-22 09:01
Handle Negs
>>> def mult(a,b):
... neg = (a < 0)
... if neg:
... a *= -1
... res = 0
... while a >= 1:
... if a % 2 != 0:
... res += b
... a /= 2
... b *= 2
... if neg:
... return res * -1
... else:
... return res
...
• KnowOracle 2009-07-22 09:01
Correct Oracle SQL

```select sum(b)
from (select floor(a / power(2, rn)) as a,
b * power(2, rn) as b
from (select &1 as a,
&2 as b,
rownum as rn
from dual
connect by level < log(2, &1)))
where mod(a, 2) <> 0
/
```
• arnemart 2009-07-22 09:04
Here's a recursive version in Ruby:

```class Integer
def russianmultiply num
return num if self == 1
return num + (self/2).russianmultiply(num*2) if self%2 == 1
(self/2).russianmultiply(num*2)
end
end

puts 18.russianmultiply(23)```
• Herman 2009-07-22 09:05
As this is the exact implementation of the multiply function on binary computing hardware, a simple

```int Mult(int a, int b)
{
return a * b;
}```

should do for most platforms :)
• Matthew Verleger 2009-07-22 09:05
int RussianSum( int A, int B ){
return A ? RussianSum(A>>2,B<<2) + (!!(A&1))*(B): 0;
}
• ruckc 2009-07-22 09:05

```public static int russianMultiplication(int left, int right) {
int result = 0;

while(left > 1) {
result += left%2==1?right:0;

left /= 2;
right *= 2;
}
return result + right;
}
```
• Mike Dotterer 2009-07-22 09:05
A ruby version:

def russian_peasant_multiply(numerator, denomenator)
table = [[numerator, denomenator]]
while table.last[0] != 1
(n, d) = table.last
table << [n / 2, d * 2]
end
table.reject { |r| r[0] % 2 != 1 }.
inject(0) { |sum, r| sum + r[1]}
end
• gosse 2009-07-22 09:06
// todo: implement russian algorithm
#define multiply(a, b) ((a)*(b))
• Will 2009-07-22 09:06
Java

public int mult(int a, int b){
return (b*(a%2)) + (a==1?0:mult(a/2,b*2));
}
• darkwraith 2009-07-22 09:07
My solutions with unit testing goodness:

#include <iostream>

using namespace std;

void assert_equals(unsigned long a, unsigned long b)
{
if (a != b)
{
cerr << a << " != " << b << endl;
exit(1);
}
}

unsigned long russianMult(unsigned a, unsigned b)
{
unsigned long ret = 0;
while (a > 0)
{
if (a % 2)
ret += b;
a >>= 1;
b <<= 1;
}
return ret;
}

int main()
{
assert_equals(414, russianMult(18, 23));
assert_equals(0, russianMult(0, 2));
assert_equals(0, russianMult(2, 0));

return 0;
}
• mverleg1 2009-07-22 09:08
Matthew Verleger:
int RussianSum( int A, int B ){
return A ? RussianSum(A>>2,B<<2) + (!!(A&1))*(B): 0;
}

Whoops... Shoulda logged in first. :)
• Dan 2009-07-22 09:09
Non-recursive C#:

public int PeasantMul(int i, int j)
{
int accum = 0;

while (i != 0)
{
accum += (i / Math.Abs(i)) * ((0 - (i & 1)) & j);
i /= 2;
j *= 2;
}

return accum;
}
Nice one for a golf challenge.
• Chris Hunt 2009-07-22 09:11
Recursive approach using ORACLE PL/SQL:

```CREATE OR REPLACE FUNCTION russian_mult (pleft IN NUMBER,
pright IN NUMBER)
RETURN NUMBER IS
newleft NUMBER;
BEGIN
-- Sanity checking: pleft has to be an integer
IF pleft != TRUNC(pleft) THEN
RAISE VALUE_ERROR;
END IF;

newleft := TRUNC(pleft/2);

-- tests for 0 and negative numbers added for completeness
IF pleft < 0 THEN
RETURN - russian_mult(-pleft,pright);
ELSIF pleft = 0 THEN
RETURN 0;
-- the main bit starts here!
ELSIF pleft = 1 THEN
RETURN pright;
ELSIF pleft/2 = newleft THEN  -- even number
RETURN russian_mult(newleft,pright*2);
ELSE -- odd number
RETURN russian_mult(newleft,pright*2) + pright;
END IF;
END;
/
SQL> SELECT russian_mult(18,23) FROM dual

RUSSIAN_MULT(18,23)
-------------------
414
```
• Azeroth 2009-07-22 09:11
You and your prmature optimizations! I made my code follow the instructions (in Pascal implementation of SCAR)

```program PhilBewig;

type
TNumberLine = record
LeftColumn: Integer;
RightColumn: Integer;
CrossedOut: Boolean;
end;

TNumberLineSheet = array of TNumberLine;

function MultiplyNumbers(a, b: Integer): Integer;
var
Sheet: TNumberLineSheet;
i: Integer;
begin
//They start by writing the two numbers to be multiplied at the head of two columns
i:= 0;
SetArrayLength(Sheet, i + 1);
Sheet[i].CrossedOut:= False;
Sheet[i].LeftColumn:= a;
Sheet[i].RightColumn:= b;

//Then they repeatedly .. until the number in the left column is one
while(Sheet[i].LeftColumn > 1)do
begin
//writing the two new numbers immediately below their predecessors
i:= i + 1;
SetArrayLength(Sheet, i + 1);
Sheet[i].CrossedOut:= False;
//divide the number in the left column by two (dropping any remainder)
Sheet[i].LeftColumn:= Sheet[i - 1].LeftColumn div 2;
//double the number in the right column
Sheet[i].RightColumn:= Sheet[i - 1].RightColumn * 2;
end;

//Then they cross out all rows where the number in the left column is even
for i:= 0 to GetArrayLength(Sheet) - 1 do
begin
if(Sheet[i].LeftColumn mod 2 = 0)then
Sheet[i].CrossedOut:= True;
end;

//and add the remaining numbers in the right column, which is the desired product
Result:= 0;
for i:= 0 to GetArrayLength(Sheet) - 1 do
begin
if(not Sheet[i].CrossedOut)then
Result:= Result + Sheet[i].RightColumn;
end;
end;

begin
Writeln(IntToStr(MultiplyNumbers(18, 23)));
end.
```
• freako 2009-07-22 09:11
What, no Haskell? Oh you sorry bunch of infidels...

mlt :: Int -> Int -> Int
mlt 1 y = y
mlt x y = (if x `mod` 2 == 0 then 0 else y) + mlt (x `div` 2) (y * 2)
• Dave Ingram 2009-07-22 09:13

```peasant :: Int -> Int -> Int
peasant x y = sum (map (\(_, z) -> z) (filter (\(x, _) -> mod x 2 == 1) (peasantnums x y)))
where peasantnums 1 b = [ (1, b) ]
peasantnums a b = (a, b) : peasantnums (div a 2) (b*2)```
• Bonce 2009-07-22 09:13
A few people have missed a bug in their code when the first value equals 1.
• Russian Peasant 2009-07-22 09:13
Bah. Looks like me hearing of this method for the first time. In Soviet Russia we just multiply it by electronic calculators. Or by abacus. Or by slide rule. Whatever appropriate.
• RayS 2009-07-22 09:13
Quick and dirty (just how I like it!) and hopefully stays true to the manual working process, not being naughty and skipping a few steps. When run in a suitable VBA host (e.g. Excel) will even show the working table.

```Public Function RussianMultiply(x As Long, y As Long) As Long
Dim vals() As Long
ReDim vals(1 To Round(Sqr(x), 0) + 1, 1 To 2) As Long
Dim i As Long, j As Long, c As Long, Msg As String
i = 1
Do Until x = 0
vals(i, 1) = x
vals(i, 2) = y
i = i + 1
x = x \ 2
y = y * 2
Loop
For j = 1 To i - 1
If vals(j, 1) / 2 = vals(j, 1) \ 2 Then
Msg = " X"
Else
c = c + vals(j, 2)
Msg = vals(j, 2)
End If
Debug.Print vals(j, 1) & vbTab & vals(j, 2) & vbTab & Msg
Next
Debug.Print vbCrLf & "=" & vbTab & c
RussianMultiply = c
End Function```

Sample output:
```>RussianMultiply 18,23
18  23   X
9   46  46
4   92   X
2   184  X
1   368 368

=   414```

Oops, posted the +ve numbers only version. Replace Sqr(x) with Sqr(Abs(x))), add a new long s, where s = Sgn(x) * Sgn(y), and amend the output as required
• Damien 2009-07-22 09:15
C# (I normally do VB, but wanted simple iterator support):

static void Main(string[] args)
{
Int32 total = 0;
foreach (NumPair p in GetColumns(Int32.Parse(args[0]), Int32.Parse(args[1])))
{
if (p.First % 2 == 1)
{
total = total + p.Second;
}
}
Console.WriteLine(total);
}

private struct NumPair
{
public Int32 First;
public Int32 Second;
}

private static IEnumerable<NumPair> GetColumns(Int32 Num1, Int32 Num2)
{
NumPair current = new NumPair();
current.First = Num1;
current.Second = Num2;
while (current.First > 0)
{
yield return current;
current.Second = current.Second * 2;
current.First = Convert.ToInt32(Math.Floor(current.First / 2.0));
}
yield break;
}
• Drew 2009-07-22 09:15
Java. Untested and recursive.

public void int multiply(int x, int y) {
if(x == 1) {
return y;
} else if(x%2 == 1) {
return y + multiply(x/2, y*2);
} else {
return multiply(x/2, y*2);
}
}
• Me 2009-07-22 09:16
I was concerned my entry was too long and too legible. So I've shaved 11 bytes off it :)

sub m(){my(\$a,\$b)=@_;my\$t;while(\$a){\$t+=\$b if\$a&1;\$a>>=1;\$b<<=1;}\$t;}
• Dave Ingram 2009-07-22 09:16
You got there a couple of minutes before me... and more concisely. In my defence, it has been about 5 years since I last wrote any Haskell... but I share your sentiment ;)
• Anon 2009-07-22 09:17
TRWTF is the animated gif
• lemon 2009-07-22 09:17
int russianPeasantMultiply(int a, int b)
{
// Russian peasant just optimized his code
return a * b;
}
• epv 2009-07-22 09:18
Perl solution. Obeys strict pragma and has error checking.

```use strict;

main:
{
my \$arg1 = shift;
my \$arg2 = shift;

my \$russian = russianMultiply(\$arg1, \$arg2);
my \$real    = \$arg1 * \$arg2;

print "Russian Method: \$russian\nNormal Method: \$real\n";
\$russian==\$real?print "Success, same result\n":print "Failure, different results\n";
}

sub russianMultiply
{
use integer;

my \$leftArg;
my \$rightArg;
my \$product;

(\$leftArg, \$rightArg) = @_;

for(;
\$leftArg >= 1;
\$leftArg /= 2 and \$rightArg *= 2)
{
if(\$leftArg%2)
{
\$product += \$rightArg;
}
}

return \$product;
}
```
• KimmoS 2009-07-22 09:20
simple non-WTF C++ template version:
-----

template <typename T>
T russian_multiply(T paula, T bean)
{
T brillant = 0;
for(;;) {
if( paula & 1 ) brillant += bean;
paula /= 2;
if( paula == 0 ) return brillant;
bean *= 2;
}
}

#include <iostream>

int main()
{
long a, b;
std::cin >> a >> b;
std::cout << a << "*" << b << "=" << russian_multiply(a,b) << std::endl;
}
• KnoNoth 2009-07-22 09:20
//Not really important part :)
#define and ,int
#define lets int
#define be =
#define is =
#define jack_is_alive (jack>1){
#define jack_is_not_even (jack%2)
#define plus +
#define divided /
#define multiplied *
#define begin_action {
#define end_action }

//The code itself
lets multiple(lets jack and john)
begin_action
lets bill be 0;
while jack_is_alive
if jack_is_not_even
bill is bill plus john;
jack is jack divided 2;
john is john multiplied 2;
end_action
return bill plus john;
end_action

//You can call function like that multiple(int num1, int num2). It's written in C of course
• Jeff Kemp 2009-07-22 09:21
I've just learned Python so I just had to contribute... this version doesn't actually use the * or / operators, which I think defeats the purpose somewhat. Works with all integers, positive or negative.

```def rusky_mult (left, right):
"""multiply
In Russia, peasants multiply You!
"""
if left < 0 and right < 0:
left, right = -left, -right
# left must be positive
elif left < 0:
left, right = right, left
product = 0
while left >= 1:
if left & 1:
product = product + right
left = left >> 1
right = right << 1
return product```
• freako 2009-07-22 09:21
Dave Ingram:
You got there a couple of minutes before me... and more concisely. In my defence, it has been about 5 years since I last wrote any Haskell... but I share your sentiment ;)

Ah, but yours is truer to the spirit of the algorithm provided. Mind, I'm a mere dabbler in the high mysteries of Haskell.
• Stefan 2009-07-22 09:21
Lua

```function russian(a, b)
local s = 0;
if a < 0 then s = s + 1; end
if b < 0 then s = s + 1; end
a, b = math.abs(a), math.abs(b);
if b > a then a, b = b, a; end
if s == 1 then b = -b; end
local r = 0;
while(a > 0) do
if (a % 2) > 0 then r = r + b; end
a, b = math.floor(a / 2), b * 2;
end
return r;
end
```
• arnemart 2009-07-22 09:22
New and improved recursive ruby version:

```class Fixnum
def * num
self == 1 ? num : (self/2) * (num+num) + (self%2 == 1 ? num : 0)
end
end

puts 7 * 7
```

• Dan 2009-07-22 09:23
C# again, but without that stinky Math.Abs():

public int PeasantMul(int i, int j)
{
int accum = 0;

while (i != 0)
{
accum += ((i >> 31) | 1) * ((0 - (i & 1)) & j);
i /= 2;
j *= 2;
}

return accum;
}
• db2 2009-07-22 09:24
In UserRPL, as I've got my HP 48 handy, and I'm in the mood for the unconventional approach.

<< 0 3 ROLLD WHILE OVER 0 > REPEAT IF OVER 2 MOD THEN ROT OVER + 3 ROLLD END 2 * SWAP 2 / FLOOR SWAP END DROP2 >>
• Clark S 2009-07-22 09:24
The Wolf:
And in PHP:
```<?php

function russian(\$x, \$y) {
\$left = array();
\$right = array();

while (\$x > 1) {
\$left[] = \$x;
\$right[] = \$y;

\$x = floor(\$x / 2);
\$y *= 2;
}

\$left[] = \$x;
\$right[] = \$y;
\$result = 0;

foreach (\$left as \$index => \$x) if (\$x % 2) {
\$result += \$right[\$index];
}

return \$result;
}

echo russian(41238, 193625);

?>```
I'll see that and raise you:
```<?php
function russkiply(\$a, \$b) {
\$product = 0;
while (\$a >= 1) {
if (\$a % 2)
\$product += \$b;
\$a = floor((float)\$a /= 2);
\$b *= 2;
}
return \$product;
}```
• arnemart 2009-07-22 09:25
KimmoS:
simple non-WTF C++ template version

Oxymoron!
• malach 2009-07-22 09:27
In Delphi:

function RussianPeasantMultiply(a,b: Integer);
begin
result := 0;
while a>0 do begin
if (a AND 1) = 1 then
result := result + b;
a := a div 2;
b := b * 2;
end;
end;
• newlisp.org 2009-07-22 09:27
in newLISP:

```(define (rmul x y , s)
(until (= x 1)
(unless (zero? (% x 2))
(inc s y))
(setq x (>> x) y (<< y)))
(+ y s)
)
```

• Dave Ingram 2009-07-22 09:28
Since I got beaten to the punch with the Haskell version, here's one for vimscript:

```:fun Peasant(n1, n2)
:  if a:n1 == 1
:    retu a:n2
:  elsei a:n1 % 2 == 1
:    retu a:n2 + Peasant(float2nr(a:n1/2), a:n2*2)
:  el
:    retu Peasant(float2nr(a:n1/2), a:n2*2)
:  en
:endf```

To use: save to ~/peasant.vim, :source ~/peasant.vim, then
`i<C-R>=Peasant(42,71)<CR>`
will insert the result of 42 × 71. Maybe if I have some time later, I'll make it print out the workings too ;)
• Ryan 2009-07-22 09:28
Here's a PHP version that displays the process sequentially, like the example:
```<html>
<body>
<style type="text/css">
.result {
margin-right: 10px;
float: left;
}
h3 {
clear: both;
}
table {
text-align: right;
}
.final .strike {
text-decoration: line-through;
}
</style>
<?php

\$left = \$_GET['left'];
\$right = \$_GET['right'];
if (\$left && \$right && preg_match('/^[0-9]+\$/', \$left) && preg_match('/^[0-9]+\$/', \$right)) {

function mult(\$lefts, \$rights) {
echo '<div class="result"><table>';
if (\$lefts[count(\$lefts) - 1] == 1) {
echo '<tbody class="final">';
} else {
echo '<tbody>';
}

for (\$i = 0; \$i < count(\$lefts); \$i++) {
echo '<tr'.(!(\$lefts[\$i] % 2) ? ' class="strike"' : '')."><td>\$lefts[\$i]</td><td>".(!\$i ? 'x' : '')."</td><td>\$rights[\$i]</td></tr>";
}
echo '</tbody></table></div>';

\$i--;
if (\$lefts[\$i] == 1) return array_combine(\$lefts, \$rights);
\$lefts[] = floor(\$lefts[\$i] / 2);
\$rights[] = \$rights[\$i] * 2;
return mult(\$lefts, \$rights);
}

\$result = 0;
\$dispResult = '';
foreach (mult(array(\$left), array(\$right)) as \$l=>\$r) {
if (\$l % 2) {
\$result += \$r;
\$dispResult .= \$r.' + ';
}
}

echo '<h3>Result is: '.substr(\$dispResult, 0, strlen(\$dispResult) - 2).'= '.number_format(\$result).'</h3>';
}

?>
<form method="get" action="wtf.php">
<div>Left Number: <input type="text" name="left" value="<?php echo \$left; ?>"/></div>
<div>Right Number: <input type="text" name="right" value="<?php echo \$right; ?>"/></div>
<input type="submit" value="Go!"/>
</form>
</body>
</html>```

Working demo at http://sandbox.secularcoding.com/wtf.php?left=18&right=23
• pjt33 2009-07-22 09:29
Herman:
As this is the exact implementation of the multiply function on binary computing hardware, a simple

```int Mult(int a, int b)
{
return a * b;
}```

should do for most platforms :)

That's what I was going to say, so since you beat me to it here's a more long-winded implementation in SML:

fun mult_inner(x, y, accum) =
if (x = 0) then accum
else if (x mod 2 = 1) then mult_inner(x div 2, y * 2, accum + y)
else mult_inner(x div 2, y * 2, accum);
fun mult(x, y) = mult_inner(x, y, 0);

I think this is the first recursive implementation in the comments to be truly tail-recursive (and hence use a fixed amount of memory with a non-braindead compiler).
• Whatever 2009-07-22 09:30
Java. Untested and recursive.

Every good WTF starts with these words.
• Bob 2009-07-22 09:31
Someone straighten me out here but I think the peasant don't know math for crap.

May be I'm doing it wrong but when I Multiply 45 x 76, I get 3420

Peasants get:
```45   x  76
22	152	0
11	304	304
5	608	608
2	1216	0
1	2432	2432
======================
3344

Flip the numbers and you get the right answer
76	45
38	90	0
19	180	180
9	360	360
4	720	0
2	1440	0
1	2880	2880
=====================
3420
```

Peasant math apparently only works if one of the number is even and in the first column.

This must be why they remain peasants.
• Felix Ungman 2009-07-22 09:31
C#, with yield return, of course!

static class Program
{
public static bool IsOdd(this int value) { return (value % 2) != 0; }

public static IEnumerable<KeyValuePair<int, int>> RussianPeasantSequence(int a, int b)
{
while (a > 0)
{
yield return new KeyValuePair<int, int>(a, b);
a /= 2;
b *= 2;
}
}

static void Main()
{
System.Diagnostics.Debug.WriteLine(
RussianPeasantSequence(18, 23)
.Where(x => x.Key.IsOdd())
.Select(x => x.Value)
.Sum());
}
}

• baka0815 2009-07-22 09:31
Well, here is a version in Pascal.

```function RussianMultiply(Left, Right: Integer): Integer;
begin
if (Left = 1) then
begin
Result := Right;
Exit;
end;

Result := 0;
while Left <> 1 do
begin
Left := Left div 2;
Right := Right * 2;

if ((Left mod 2) <> 0) then Inc(Result, Right);
end;
end;```

Anyone noticed this only works if the left number is even?!

18*23 works fine (414), bit 23*18 would be 396.
• phihag 2009-07-22 09:31
code golf: Python 3, 1 statement, 1 line, 70 characters:

`m=lambda a,b:sum(b<<i if a&1<<i else 0 for i in range(a.bit_length()))`
• Sebastian Paaske Tørholm 2009-07-22 09:32
Oh hey, I did this in my first algorithms class lecture a while back.

```import Data.Bits (shiftL, shiftR)

x :: Integer -> Integer -> Integer
1 `x` b             = b
a `x` b | a > b     = b `x` a
| otherwise = (if a `mod` 2 == 0 then 0 else b) +
((a `shiftR` 1) `x` (b `shiftL` 1))```
• MP 2009-07-22 09:33
LISP

((defun russianpeasant ("They start by writing the two numbers to be multiplied at the head of two columns.) (Then they repeatedly divide the number in the left column by (two
) (dropping any remainder) and ((double) the number in the right column), writing the (two new numbers) immediately below their predecessors, until the number in the left column is one.) ((Then they) (cross out all rows) where the number in the left column is even), and (((add the remaining numbers) in the right column), which is the desired product)). (For instance, the product eighteen times twenty-three is found like this.")))))
• Clark S 2009-07-22 09:33
Clark S:
I'll see that and raise you:
```<?php
function russkiply(\$a, \$b) {
\$product = 0;
while (\$a >= 1) {
if (\$a % 2)
\$product += \$b;
\$a = floor((float)\$a /= 2);
\$b *= 2;
}
return \$product;
}```
Actually, I just realized that my function doesn't take into account negatives. In order to be functionally complete I must do this:
```<?php
function russkiply(\$a, \$b) {
\$product = 0;
if (\$a < 0) {
\$a = -\$a;
\$b = -\$b;
}
while (\$a >= 1) {
if (\$a % 2)
\$product += \$b;
\$a = floor((float)\$a /= 2);
\$b *= 2;
}
return \$product;
}```
The new check at the beginning will reverse the signs if the first part is less than 0; That way, if just \$a is negative, it switches \$b to the negative, and if both are negative, they both switch to positive.

CAPTCHA: appellatio -- sounds like a dirty fruit fetish
• whileloopsareugly 2009-07-22 09:34
int mul(unsigned a, unsigned b)
{
for (int s=0; a; a>>=1, b<<=1) s+=a&0x1?b:0;
return s;
}
• Jeff Kemp 2009-07-22 09:34
Bob:

Peasants get:[code]
45 x 76
22 152 0
11 304 304
5 608 608
2 1216 0
1 2432 2432
======================
3344

You forgot to add the initial 76: 45 is odd.
• Tempura 2009-07-22 09:35
```In [23]: def russia_peasants(x, y):
....:     x, y = float(x), float(y)
....:     if x <= 1:
....:         return 0
....:     elif (x%2) == 1:
....:         return (x*y) + russia_peasants(x/2, y*2)
....:     else:
....:         return russia_peasants(x/2, y*2)

In [24]: russia_peasants(18, 23)
Out[24]: 414.0
```
• TerraNova 2009-07-22 09:36
```#define F(name, op)\
int name(int num) {\
int i, j = 0;\
for (i = 0; i < 32; ++i) {\
op;\
}\
return j;\
}

#define _BUFFER_SIZE 16
long b[_BUFFER_SIZE]; // long to avoid integer overflow

F(explode, j = 1; i[b] = num & j << i; i[b] >>= i)
F(implode, i[b] *= num << i)
F(deplode, j+= i[b])

#include <stdio.h>

void main(int argc, char *argv[]) {
if (argc != 3) return 1; // TODO: Display help text

int i;

printf("%d\n", (explode(atoi(argv[1])), implode(atoi(argv[2])), deplode(0)));
}
```

"Features":

* Uses the , operator
* buffer overflow (which passes valgrind!)
* The ever-popular TODO - commenting on the one piece of verification code
* Macros
* arrays-as-pointer - need i say more?
* Does not implement the actual algorithm, just something deceptively similar to what the requirements talk about
* Violates the language standard for no good reason
• baka0815 2009-07-22 09:38
Ok, screw that about the left number needing to be even. Just forgot to use that one, too.

Well, guess it goes with my name. ;)

```function RussianMultiply(Left, Right: Integer): Integer;
begin
if (Left = 1) then
begin
Result := Right;
Exit;
end;

Result := 0;

// Check if the first one is odd and add it
if ((Left mod 2) <> 0) then Inc(Result, Right);

while Left <> 1 do
begin

Left := Left div 2;
Right := Right * 2;
if ((Left mod 2) <> 0) then Inc(Result, Right);
end;
end;```
• HypocriteWorld 2009-07-22 09:38
Better Haskell version: (this one pretty much follows the algorithm given part by part).
```peasant :: Integer -> Integer -> Integer
peasant = curry (sum . map snd . filter (odd . fst) . unfoldr gen)
where gen (0, _) = Nothing
gen (x, y) = ((x, y), (x `div` 2, y * 2))
```

Sometimes the unfoldr function feels silly.

And to satisfy your craze for testing:
```import Test.QuickCheck
prop_peasant x y = (x > 0 && y > 0) ==> peasant x y == x * y
```
• Arjan 2009-07-22 09:39
Recursive Java version. Also works with negative and zero.

```public class Russian {
public static long multiply(long a,long b){long r=multiply(a>0?a:-a,b>0?b:-b,0);return a<0^b<0?-r:r;}
private static long multiply(long a,long b,long r){if(a%2==1)r+=b; return a<=1?r:multiply(a>>1,b<<1,r);}
}
```
• Stalin 2009-07-22 09:39
```def inSovietRussiaIntegerMultipliesYou(
a: "foul capitalist pig",
) -> "glorious empowerment of the proletariat for the motherland":
assert isinstance(a, int) and a > -1 and\
isinstance(b, int) and b > -1
al = [a]
bl = [b]
while 1 not in al:
al.append(al[-1]//2)
bl.append(bl[-1]*2)
return sum(b for a, b in zip(al, bl) if a%2)```

Only works under Python 3.x
• leppie 2009-07-22 09:39
#!r6rs ;Scheme (for Phil :)

(define (russian* x y)
(cond
[(zero? x) 0]
[else
(let-values (((d m) (div-and-mod x 2)))
(+ (if (zero? m) 0 y)
(russian* d (bitwise-arithmetic-shift-left y 1))))]))
• Zishan 2009-07-22 09:40
```function ruM (input) {
var left=0,right=0,remainder=0,sum=0,num;
input = input.replace(/\s+/g, '').replace(/x/g,'*');
if (input.indexOf('*')) num = input.split('*');
if (num) for (var i=1; i<num.length; i++) {
left = (i==1 ? parseInt(num[i-1], 10) : sum);
right = parseInt(num[i], 10);
while (left>1) {
if (left % 2 != 0) {
remainder += right;
left -= 1;
}
left /= 2;
right *= 2;
}
sum = right + remainder;
remainder = 0;
}
return sum;
}

String input:
ruM("18 x 23 x 23 x 23");
```
• douglas 2009-07-22 09:40
Bob:
Someone straighten me out here but I think the peasant don't know math for crap.

May be I'm doing it wrong but when I Multiply 45 x 76, I get 3420

Peasants get:
```45   x  76
22	152	0
11	304	304
5	608	608
2	1216	0
1	2432	2432
======================
3344
```

You're doing it wrong. The correct peasant algorithm here is:
```45   x  76	76
22	152	0
11	304	304
5	608	608
2	1216	0
1	2432	2432
======================
3420
```

Note the first line in particular.
• Steven de B 2009-07-22 09:40
Perl, with some nice recursion...
Code:

sub mul(\$\$)
{
my(\$a,\$b)=@_;
return \$a?((\$a&1?\$b:0)+mul(int(\$a/2),\$b*2)):0;
}

Probably already mentioned before in some variations, but I just want to have such a cool WTF-sticker :-)
• Romeo 2009-07-22 09:41
You've just forget to sum the first line...

Bob:
Someone straighten me out here but I think the peasant don't know math for crap.

May be I'm doing it wrong but when I Multiply 45 x 76, I get 3420

Peasants get:
```45   x  76
22	152	0
11	304	304
5	608	608
2	1216	0
1	2432	2432
======================
3344

Flip the numbers and you get the right answer
76	45
38	90	0
19	180	180
9	360	360
4	720	0
2	1440	0
1	2880	2880
=====================
3420
```

Peasant math apparently only works if one of the number is even and in the first column.

This must be why they remain peasants.
• Bob 2009-07-22 09:41
Jeff Kemp:
Bob:

Peasants get:[code]
45 x 76
22 152 0
11 304 304
5 608 608
2 1216 0
1 2432 2432
======================
3344

You forgot to add the initial 76: 45 is odd.

I will blame this on poor specifications.
• djjeavons 2009-07-22 09:42
```    Private Function Multiply(ByVal number As Integer, ByVal multiplyBy As Integer)

Dim lastNumber As Integer = number
Dim remainder As Integer = 0
Dim additionNumbers As Integer = 0
Dim lastMultiplyByValue As Integer = multiplyBy

System.Math.DivRem(System.Math.DivRem(lastNumber, 2, remainder), 2, remainder)
If remainder = 0 Then additionNumbers += lastMultiplyByValue

Do Until lastNumber = 1

lastMultiplyByValue *= 2
System.Math.DivRem(System.Math.DivRem(lastNumber, 2, remainder), 2, remainder)
lastNumber = System.Math.Floor(lastNumber / 2)

If Not remainder = 0 Then
End If

Loop

End Function
```
• csulli13 2009-07-22 09:43
SQL function using columns

CREATE FUNCTION RussianMultiply
(@Num1 int, @Num2 int)
RETURNS int
AS
BEGIN

CREATE TABLE #Columns(C1 int, C2 int)

WHILE @Num1 >= 1
BEGIN

INSERT INTO #Columns VALUES(@Num1, @Num2)

SET @Num1 = @Num1/2
SET @Num2 = @Num2 * 2

END

DELETE FROM #Columns WHERE C1 % 2 = 0

RETURN SUM(C2) FROM #Columns

END
• Maxim 2009-07-22 09:43

russian = curry \$ sum . map snd . filter (odd.fst) . takeWhile ((>0).fst) . iterate ((`div`2) *** (*2))
• darklajid 2009-07-22 09:43
Nice idea. F# solution, without much thoughts put into it (in other words: Nicer solutions probably exist) and assuming #light:

```let russianMultiplication (x:int) (y:int) =
let rec russianMultiplicationRec x y l =
match x with
| 0 -> [(1, 0)]
| 1 -> ((1, y) :: l)
| _ -> russianMultiplicationRec (x/2) (y*2) ((x, y) :: l)

russianMultiplicationRec x y []
|> List.fold (fun acc (x, y) ->
if x % 2 = 1 then acc + y
else acc
) 0
```
• ruckc 2009-07-22 09:44
I think we did one worse.

Database error
A database query syntax error has occurred. This may indicate a bug in the software. The last attempted database query was:

(SQL query hidden)

from within function "MediaWikiBagOStuff::_doquery". MySQL returned error "1194: Table 'mw_objectcache' is marked as crashed and should be repaired (localhost)".
• Osno 2009-07-22 09:44
All the people looping on 1 instead of 0 fail.
All the people using multiplication and division instead of shifting (except in languages where there is no shifting) also fail.
• SR 2009-07-22 09:45
ColdFusion:

&lt;cffunction name="multiply" returntype="numeric"&gt;
&lt;cfargument name="x" required="Yes" type="numeric"&gt;
&lt;cfargument name="y" required="Yes" type="numeric"&gt;
&lt;cfargument name="total" required="no" type="numeric"&gt;

&lt;cfif NOT IsDefined("arguments.total")&gt;
&lt;cfif arguments.x MOD 2 NEQ 0&gt;
&lt;cfset arguments.total = arguments.y&gt;
&lt;cfelse&gt;
&lt;cfset arguments.total = 0&gt;
&lt;/cfif&gt;
&lt;/cfif&gt;

&lt;cfset newX = Int(arguments.x / 2)&gt;
&lt;cfset newY = arguments.y * 2&gt;

&lt;cfif newX MOD 2 NEQ 0&gt;
&lt;cfset arguments.total = arguments.total + newY&gt;
&lt;/cfif&gt;
&lt;cfif arguments.x GT 1&gt;
&lt;cfset arguments.total = multiply(newX, newY, arguments.total)&gt;
&lt;/cfif&gt;
&lt;cfreturn arguments.total&gt;
&lt;/cffunction&gt;

Glad I use Java these days.
• GM 2009-07-22 09:45
Another C# one:
private int Multiply(int a, int b)
{
int result = 0, aBy2, bBy2;

if (a == 1) return b;

aBy2 = a ;
bBy2 = b ;
do
{
aBy2 = aBy2 / 2;
bBy2 = bBy2 * 2;
if (aBy2 % 2 == 1)
{
result += bBy2;
}
} while (aBy2 != 1);

return result;
}
• Damien 2009-07-22 09:45
For those "handling negatives and zero" - the correct behaviour for these, given the literal description of the algorithm, is to loop forever, because the left hand column will never equal 1. (Not that my previous solution gets this right either)
• SR 2009-07-22 09:45
2nd attempt:

<cffunction name="multiply" returntype="numeric">
<cfargument name="x" required="Yes" type="numeric">
<cfargument name="y" required="Yes" type="numeric">
<cfargument name="total" required="no" type="numeric">

<cfif NOT IsDefined("arguments.total")>
<cfif arguments.x MOD 2 NEQ 0>
<cfset arguments.total = arguments.y>
<cfelse>
<cfset arguments.total = 0>
</cfif>
</cfif>

<cfset newX = Int(arguments.x / 2)>
<cfset newY = arguments.y * 2>

<cfif newX MOD 2 NEQ 0>
<cfset arguments.total = arguments.total + newY>
</cfif>
<cfif arguments.x GT 1>
<cfset arguments.total = multiply(newX, newY, arguments.total)>
</cfif>
<cfreturn arguments.total>
</cffunction>
• Soops 2009-07-22 09:46
Clue:

3420 - 3344 = 76

• Jason Knight 2009-07-22 09:47
Javascript version:

function calculate() {
var num1 = 28;
var num2 = 13;
var tot = 0;
if ((num1 % 2) != 0) { tot = num2 }
while (num1 > 1) {
num1 = Math.floor(num1 / 2);
num2 *= 2;
if ((num1 % 2) != 0) { tot += num2 }
}
}
• cwink 2009-07-22 09:48
public static int Multiply( int op1, int op2 )
{
return Mult( Math.Abs(op1), op2*op1/Math.Abs(op1) );
}

private static int Mult( int op1, int op2 )
{
if( op1 == 1 )
return op2;
else
return (op1 & 1)*op2 + Mult( op1 >> 1, op2 << 1 );
}
• dee 2009-07-22 09:50
Iterative Scheme:

```(define (peasant left right)
(define (peasant-i left right sum)
(if (= left 0)
(apply + sum)
(peasant-i (floor (/ left 2))
(+ right right)
(if (= (modulo left 2) 1)
(append sum (list right))
sum))))
(if (< left 0)
(peasant-i (- left) (- right) '())
(peasant-i left right '())))
```

Works with negative numbers and zeroes. I tried to follow the manual process as closely as possible :)
• Jim 2009-07-22 09:51
phihag:
code golf: Python 3, 1 statement, 1 line, 70 characters:

`m=lambda a,b:sum(b<<i if a&1<<i else 0 for i in range(a.bit_length()))`

Python 3, 64 characters
`m=lambda a,b:sum(b<<i for i in range(a.bit_length()) if a&1<<i)`
• Bob 2009-07-22 09:51
Bob:
Jeff Kemp:
Bob:

Peasants get:[code]
45 x 76
22 152 0
11 304 304
5 608 608
2 1216 0
1 2432 2432
======================
3344

You forgot to add the initial 76: 45 is odd.

I will blame this on poor specifications.

I will add that many solutions here are making the same error.
• Philipp 2009-07-22 09:52
public class SmallTest {
public static void main(String [] args) {
try {
int m1 = Math.abs(Integer.parseInt(args[0]));
int m2 = Math.abs(Integer.parseInt(args[1]));
if (m1 > m2) {int temp = m1; m1 = m2; m2 = temp;}
int result = 0;
while (m1 >= 1) {
if ((m1 & 1) > 0) result += m2;
m1 >>= 1; m2 <<= 1;
}
System.err.println(args[0] + " * " + args[1] + " == " + result);
} catch (Exception e) {
System.err.println("Whoops: " + e.getMessage());
}
}
}

There you go. Even works for negative numbers ;) -- and it heavily optimizes... :)
• Daniel 2009-07-22 09:52
Recursion is always the right answer!!

function peasantMath(\$a,\$b) {
return ((\$a>>1)%2 == 0 ? 0 : \$b<<1) + (\$a>>1 == 1 ? 0 : peasantMath(\$a>>1, \$b<<1));
}

Also, TRWTF is that the link to esoteric languages is throwing database errors.

• cwink 2009-07-22 09:54
public static int Multiply( int op1, int op2 )
{
if( op1 == 0 || op2 == 0 )
return 0;
else
return Mult( Math.Abs(op1), op2*op1/Math.Abs(op1) );
}

private static int Mult( int op1, int op2 )
{
if( op1 == 1 )
return op2;
else
return (op1 & 1)*op2 + Mult( op1 >> 1, op2 << 1 );
}
• Anonymous 2009-07-22 09:56
Oh wow, this is unbelievable. No trolls, no grammar nazis, no flame-bait, no spammers - just everyone chipping in on an interesting coding challenge. I think this is probably the most civilised comments page I've ever seen on TDWTF. Well done everyone, you've all earnt a cookie.
• Bob 2009-07-22 09:56
```(define (halve x) (quotient x 2))
(define (double x) (+ x x))
(define (mul x y)
(let iter ((x (abs x))
(y (if (negative? x)
(- y)
y))
(acc 0))
(cond
((zero? x) acc)
((even? x) (iter (halve x) (double y) acc))
(else (iter (- x 1) y (+ acc y))))))
```

• Jeff Kemp 2009-07-22 09:57
Bob:
Bob:
Jeff Kemp:
...

You forgot to add the initial 76: 45 is odd.

I will blame this on poor specifications.

I will add that many solutions here are making the same error.

and only those who said their solution is "untested" have half an excuse... :)
• Daniel 2009-07-22 09:58
Adjusted to handle negatives, and to handle an initial odd left operand, as pointed out above. This is PHP by the way, though it's not doing anything special.

```function peasantMath(\$a,\$b) {
if ( \$a < 0 ) {
\$a *= -1;
\$b *= -1;
}
return ((\$a)%2 == 0 ? 0 : \$b) + (\$a == 1 ? 0 : peasantMath(\$a>>1, \$b<<1));
}```

• Éibhear 2009-07-22 09:59
Using emacs lisp (and the dreaded recursion):

(defun russian-peasant-multiply (factor1 factor2)
(cond ((eq factor1 1)
factor2
)
((eq (mod factor1 2) 0)
(russian-peasant-multiply (/ factor1 2) (* factor2 2))
)
(t
(+ factor2 (russian-peasant-multiply (/ factor1 2) (* factor2 2))))
)
)
• Stalker 2009-07-22 09:59
Another assembly version, this time x64 using nasm

```SECTION	.text
GLOBAL	RussianMul
RussianMul:

[BITS 64]
xor	rax, rax
.start:
bt	rcx, 0
jnc	.even
.even:
shr	rcx, 1
shl	rdx, 1
test	rcx, rcx
jnz	.start

ret
```
• YES WE CAN! 2009-07-22 10:00
doesn't use any * or /, supports negative numbers:

#define NEGATE(x) (~(x) + 1)

int russian_multiplication(int a, int b) {
short think_positive = 1;
int result=0;

if (a < 0) {
a=NEGATE(a);
think_positive=NEGATE(think_positive);
}

if (b < 0) {
b=NEGATE(b);
think_positive=NEGATE(think_positive);
}

// do it the russian way:
while (a > 0) {
if (a & 1) {
result+=b;
}
a >>= 1;
b <<= 1;
}

// think positive!
if (think_positive == -1)
result = NEGATE(result);
return result;
}
• Stefan 2009-07-22 10:00
Osno:
All the people looping on 1 instead of 0 fail.
All the people using multiplication and division instead of shifting (except in languages where there is no shifting) also fail.

java.math.abs(int x)

public static int abs(int a)

Returns the absolute value of an int value. If the argument is not negative, the argument is returned. If the argument is negative, the negation of the argument is returned.

Note that if the argument is equal to the value of Integer.MIN_VALUE, the most negative representable int value, the result is that same value, which is negative.

Parameters:
a - the argument whose absolute value is to be determined
Returns:
the absolute value of the argument.
Integer.MIN_VALUE

if you use shifting operators, russion(Integer.MIN_VALUE, ...) will always end in an infinity loop if your loop condition depends on a value != 0
• little3lue 2009-07-22 10:01
Damn: someone beat me to a C++ metaprogramming solution. This is easier to read:

template <long a, long b>
struct RusMult
{
enum { value = ((a&1) ? b : 0 ) + RusMult<(a>>1),(b<<1)>::value };
};

template <long b>
struct RusMult<0,b>
{
enum { value = 0 };
};

// Usage: result = RusMult< a, b >::value;

• Eutactic 2009-07-22 10:02
Python 3.x
Why else would they support unicode?
Translation is probably hilariously wrong.

#Русский крестьянин умножения модуль

def Умножение(X,Y):
пар = []

def Населять(X,Y):
пар = []
while X > 0:
пар.append([X,Y])
X = X//2
Y = Y*2
return Суммавсех(Ликвидировать(пар))

def Ликвидировать(пар):
пар = [Элемент for Элемент in пар if Элемент[0] %2 != 0]
return пар

def Суммавсех(пар):
Сумма = 0
for Элемент in пар:
Сумма += Элемент[1]
return Сумма

пар = Населять(X, Y)
return пар

print(Умножение(18, 23))

>>> 414
• RECURSIVEMAN 2009-07-22 10:02
RECURSIVE MAN SAYS:

def _mult(a,b):
if a == 1: return [(a,b)]
return [(a,b)]+_mult(a/2,b*2)
def mult(a,b):
return sum(b for (a,b) in _mult(a,b) if a%2==1)

I was trying to stick exactly to the algorithm. The intermediate list of numbers that you'd write down on paper is first produced by _mult. The list comprehension then crosses out which ones are unnecessary, and adds the rest.
• rob tracey 2009-07-22 10:02
python:

def rus(a,b):
c = 0
while a > 0:
a = a/2
b = b*2
if a % 2 != 0:
c += b
print 'total = ',c
• krat 2009-07-22 10:03
```def russian_peasant(n1, n2):
remainder = 0
if n1 > n2: n1, n2 = n2, n1
while n1 != 1:
if n1 % 2:
remainder += n2
n1 >>= 1
n2 <<= 1

return n2 + remainder
```
• Philipp 2009-07-22 10:03
Small improvement; now it _really_ works with negative numbers...

public class SmallTest {
public static void main(String [] args) {
try {
boolean n = args[0].trim().startsWith("-") ^ args[1].trim().startsWith("-");
int m1 = Math.abs(Integer.parseInt(args[0]));
int m2 = Math.abs(Integer.parseInt(args[1]));
if (m1 > m2) {int temp = m1; m1 = m2; m2 = temp;}
int result = 0;
while (m1 >= 1) {
if ((m1 & 1) > 0) result += m2;
m1 >>= 1; m2 <<= 1;
}
System.out.println(args[0] + " * " + args[1] + " == " + ((n && result != 0) ? "-" : "") + result);
} catch (Exception e) {
System.err.println("Whoops: " + e.getMessage());
}
}
}
• JaguarOne 2009-07-22 10:04
Not very esoteric.... LOLCODE

HAI
CAN HAS STDIO?

HOW DUZ I MULTIPLY_STALIN YR SOVIETA AN YR SOVIETB
I HAS A PROFIT
PROFIT R TROOF
I HAS A THROWFUD
THROWFUD R 0

IM IN YR USSR_LOOP WILE PROFIT AN SOVIETA BIGGR 0
IZ MOD OF SOVIETA AN 2 NOT 0?
YARLY
THROWFUD R SUM THROWFUD N SOVIETB

KTHX

SOVIETA R QUOSHUNT SOVIETA AN 2
SOVIETB R PRODUKT SOCIETB AN 2
IM OUTTA YR USSR_LOOP
IF U SAY SO
KTHXBYE

• Andrew Brehm 2009-07-22 10:04
"It is said that Russian peasants multiply using a most curious method"

Is that why there are so many of them?

• Fabio Lima 2009-07-22 10:05
Minimalist C#

static int RussianMultiply(int a, int b) {
int r=0;
for (int i=a/2;i!=1;i--,a=a/2,b=b*2,r=r+(a%2)*b){}
return r;
}
• povman 2009-07-22 10:06
Here's my very realistic solution, in C:

```/* Oh god, who wrote this? - geoff */
int RussianMultiply(int a, int b)
{
return a * b; /* TODO: Implement russian peasant multiplication */
}
```
• GWO 2009-07-22 10:07
unsigned long long mult(unsigned long a, unsigned b)
{
unsigned long long acc = 0;
while(a != 0) acc += (a%2)*b,a/=2,b*=2;
return acc;
}
• drBeat 2009-07-22 10:08
This never terminates if x == 0.

My try:

```def russian_multiply(a, b):
product = 0
while a:
if a & 1:
product += b
a >>= 1
b <<= 1
return product
```
• exo 2009-07-22 10:10
a very horribly ruby one-liner:

def mul(a, b)
(t=[[a, b]]).inject(0){|acc,(a, b)|a<=0?acc:acc+(t<<[a>>1,b<<1])[-2][1]*(a%2==1?1:0)}
end
• method1 2009-07-22 10:13
Paula:
public class Paula extends WTF {
public static string Paulabean = "brillant!";
}

Best solution by far
• Benjamin Bridges 2009-07-22 10:13
Don't see anyone doing this for the adding portion:
sum += b * (a & 1);

Save an if statement.
• avl 2009-07-22 10:19
uint32 rpMultiply(uint32 a, uint32 b)
{
uint32 res = 0;

if (b < a)
{
// change for shorten time
a = a ^ b;
b = a ^ b;
a = a ^ b;
}

do
{
if (a & 1)
{
res += b;
a >>= 1;
b <<= 1;
} while (a);
}
return res;
}
• kastein 2009-07-22 10:20
Dascandy:
X86:
```; assumption: eax contains arg1, ebx contains arg2
mov edx, eax
next:
shr ebx, 1
cmovc ecx, edx
cmovnc ecx, 0
jz end
lea eax, [eax*2 + ecx]
jmp next

end:
ret
```

ARM:
```	mov r2, r0
next    test r1, 1
mov r1, #0, r1 shr 1
movz pc, lr
b next
```

awesome! more assembly required...

In IA64 assembly:

```.text
.align 32
.global russian_multiply
.proc russian_multiply
russian_multiply::
alloc	r14=ar.pfs,2,0,0,0
mov	r2=pr
movl	r8=0;;
startloop:
tbit.nz	p6=r32,1
cmp.e	p7=1,r32;;
(p7)	br.cond	endloop;;
shr	r32=r32, 1
shl	r33=r33, 1;;
br.cond	startloop;;
endloop:
mov	pr=r2
mov	ar.pfs=r14;;
br.ret.sptk	b0;;
.endp russian_multiply
```

Usable in C as:
int russian_multiply(int num1, int num2);

cmp.eq not cmp.e. brainfart...
• ross 2009-07-22 10:20
Python. Recursive, works with positive integers.

def mul(a,b):
if a != 1:
if a % 2 == 1:
return b + mul(a >> 1, b << 1)
else:
return mul(a >> 1, b << 1)
else:
return b
• FatherStorm 2009-07-22 10:21
```<?php
\$x=rand(1,65535);
\$y=rand(1,65535);
\$ans=\$x*\$y;
while(\$x>=1){
if(\$x % 2==1 ){
\$z+=\$y;
}
\$x=intval(\$x/2);
\$y=\$y*2;
}
echo"\$ans == \$z";;
?>
```
• Phil 2009-07-22 10:21
Bob:
Someone straighten me out here but I think the peasant don't know math for crap.

May be I'm doing it wrong but when I Multiply 45 x 76, I get 3420

Peasants get:
```45   x  76
22	152	0
11	304	304
5	608	608
2	1216	0
1	2432	2432
======================
3344

Flip the numbers and you get the right answer
76	45
38	90	0
19	180	180
9	360	360
4	720	0
2	1440	0
1	2880	2880
=====================
3420
```

Peasant math apparently only works if one of the number is even and in the first column.

This must be why they remain peasants.

You're doing it wrong. In the first example you forgot to add the 76 on the first row.
• threecheese 2009-07-22 10:22
Me:
I was concerned my entry was too long and too legible. So I've shaved 11 bytes off it :)

sub m(){my(\$a,\$b)=@_;my\$t;while(\$a){\$t+=\$b if\$a&1;\$a>>=1;\$b<<=1;}\$t;}

if you wanted illegible, you should assume no strict (drop the 'my \$t') and use indexes of @_ instead of assigning \$a and \$b to it...
• halber_mensch 2009-07-22 10:23
A recursive python solution
```def умножить(a,b):
if (a==1): return b
_b = b
while(1):
a=a>>1
b=b<<1
if(a%2): break
return _b+умножить(a,b)
```
• Alex Ciarlillo 2009-07-22 10:24
recursive scala soln.

```  def do_mult(left : Int, right : Int) : Int = {
if (left == 1) right
else if (left%2 == 0) do_mult(left/2, right*2)
else do_mult(left/2, right*2) + right
}
```
• Anonymous Coward 2009-07-22 10:25
Prolog:

rusmul(0,_,0).
rusmul(A,B,X) :- C is A//2, D is B*2, rusmul(C,D,E), X is E+(A mod 2)*B.
• SR 2009-07-22 10:25
Anonymous:
Oh wow, this is unbelievable. No trolls, no grammar nazis, no flame-bait, no spammers - just everyone chipping in on an interesting coding challenge. I think this is probably the most civilised comments page I've ever seen on TDWTF. Well done everyone, you've all earnt a cookie.

• Jeff Kemp 2009-07-22 10:26
IMHO any multiplication and division operators (and related ones like the "-" unary operator) should be disallowed. Only bitwise ops!

New & improved Python implementation, borrowed "YES WE CAN!"'s trick for negating using ~; handles all combinations of positive/negative/zero integers, and only uses the ~, >> and << operators (apart from comparison ops):

```def rusky_mult(l,r):
if l<0 and r<0:
l,r=~l+1, ~r+1
elif l<0:
l,r=r,l
p=0
while l>=1:
if l&1: p+=r
l>>=1
r<<=1
return p```
• darklajid 2009-07-22 10:26
Another F# take. This time without recursion. I love "infinite" sequences..

```let russianMultiplication x y =
Seq.initInfinite (fun i -> (x >>> i, y <<< i))
|> Seq.takeWhile (fun t -> fst t > 0)
|> Seq.filter (fun f -> fst f % 2 = 1)
|> Seq.sumBy (fun z -> snd z)
```
• Will 2009-07-22 10:27
Not tested and not guaranteed correct (It's been years since I've used this stuff), but here's my attempt at a MUSH code solution.

@create peasant
&cmd_russianMult peasant = \$russianMult *: @emit v(russianMult, %0, %1)
&russianMult peasant = add(mult(mod(%0,2),%1), switch(%0,1,0,v(russianMult, div(%0,2), mult(%1,2))))
• halber_mensch 2009-07-22 10:27
No, this fails if a is even. damn
Perl >> 1 line >> 55 chars ... beat that python :)
sub r{(\$_[0]?r(\$_[0]>>1,\$_[1]<<1):0)+(\$_[0]&1)*\$_[1];}
• SR 2009-07-22 10:28
function russianMultiplication(a, b) {
if (frist) {
} else {
// do nothing
}
}
love that russian translation function name!
• Romeo 2009-07-22 10:30
This way, you won't make much money on those "pay-per-line" jobs...

Jim:
phihag:
code golf: Python 3, 1 statement, 1 line, 70 characters:

`m=lambda a,b:sum(b<<i if a&1<<i else 0 for i in range(a.bit_length()))`

Python 3, 64 characters
`m=lambda a,b:sum(b<<i for i in range(a.bit_length()) if a&1<<i)`
• Matt 2009-07-22 10:32
Didn't see Groovy listed, so:

import static Math.floor

def multiply(ln, rn){
def results = [[left: ln, right: rn]]
def product = 0
while ( results[-1]["left"] > 1){
results << [left: floor(results[-1]["left"]/2) as int, right: results[-1]["right"]*2]
}
results.findAll{it["left"] % 2 != 0}.each{product += it["right"]}
product
}
• Archimidas 2009-07-22 10:33
Where's the Shakespeare version?
• Nick Pope 2009-07-22 10:34
Perl >> 1 line >> 55 chars ... beat that python :)
sub r{(\$_[0]?r(\$_[0]>>1,\$_[1]<<1):0)+(\$_[0]&1)*\$_[1];}

Easy... I beat that with bc :) New target is sub 50 characters!

Code:
`a=read();b=read();while(a){c+=b*(a%2);a/=2;b*=2};c`
• ponky 2009-07-22 10:34
```#define HALF(X,Y) y*(1&Y)+a

int multiply(int x, int y)
{
int a = 0;
while (a=HALF(x,x),y<<=1,x>>=1);
return HALF(a,x);
}
```

maybe trying too hard :/
Romeo:
This way, you won't make much money on those "pay-per-line" jobs...

Jim:
phihag:
code golf: Python 3, 1 statement, 1 line, 70 characters:

`m=lambda a,b:sum(b<<i if a&1<<i else 0 for i in range(a.bit_length()))`

Python 3, 64 characters
`m=lambda a,b:sum(b<<i for i in range(a.bit_length()) if a&1<<i)`

And they still have 9 characters to go to catch up with perl.
• halber_mensch 2009-07-22 10:35
Better recursive python solution:
```def умножить(a,b):
if (a==1): return b
return b*(a%2)+умножить(a>>1,b<<1)
```
• kastein 2009-07-22 10:36
Also, I'm disappointed... no MUMPS? no MS-DOS batch?
• Fabio Lima 2009-07-22 10:36
I stand corrected. Was missing the case where the first parameter was odd.

static int RussianMultiply(int a, int b) {
int rest=0;
for (int i=a/2,r=(a%2)*b;i!=0;i--,a=a/2,b=b*2,r=r+(a%2)*b)
{if (a == 1) { return r ; }}
return 0;
}
• Nicholas Laux 2009-07-22 10:36
Ruby non-recursive:

print "First number: "
q = gets.chomp.to_i
print "Second number: "
t = gets.chomp.to_i

def ahh_motherland!(a, z)
p = (a > 0) == (z > 0)
a, z = (a > 0 ? a : -a), (z > 0 ? z : -z)
s = 0
while a > 0 do
s += a % 2 == 0 ? z : 0
a /= 2
z *= 2
end
return p ? s : -s
end

puts "#{q} * #{t} = #{ahh_motherland!(q, t)}"
• MeesterTurner 2009-07-22 10:36
Some lunchtime T-SQL:
DECLARE @N1 int
DECLARE @N2 int
DECLARE @tblMult TABLE(N1 int, N2 int)

SELECT @N1 = 18, @N2 = 23 -- The two numbers to multiply peasantly

WHILE @N1 >= 1
BEGIN
INSERT INTO @tblMult VALUES (@N1, @N2)
SELECT @N1 = @N1 * 0.5, @N2 = @N2 * 2

END

DELETE FROM @tblMult WHERE (N1 * 0.5) - (CAST((N1 / 2) AS INT)) = 0

SELECT SUM(N2) FROM @tblMult -- The Answer!
Nick Pope:
Perl >> 1 line >> 55 chars ... beat that python :)
sub r{(\$_[0]?r(\$_[0]>>1,\$_[1]<<1):0)+(\$_[0]&1)*\$_[1];}

Easy... I beat that with bc :) New target is sub 50 characters!

Code:
`a=read();b=read();while(a){c+=b*(a%2);a/=2;b*=2};c`

Did you check the output? ;)
• Osno 2009-07-22 10:36
@Stefan Agreed, but I don't think a russian counting peasants is counting negative peasants.
• GWO 2009-07-22 10:36
K&R C:
int m(a,b){c=0;while(a!=0)c+=a%2*b,a/=2,b*=2;return c}

54 characters - 59 if you include "K&R C"
• Kook 2009-07-22 10:37
Takes care of zeroes and negatives --
```	public static int compute(int left, int right) {
int result = 0;
int multiplier = 1;

if (left < 0) {
multiplier = -1;
left *= -1;
}

if (right < 0) {
multiplier *= -1;
right *= -1;
}

while (left > 0) {
if (left % 2 == 1) {
result += right;
}

left /= 2;
right *= 2;
}

return result * multiplier;
}
```
• GWO 2009-07-22 10:38
GWO:
K&R C:
int m(a,b){c=0;while(a!=0)c+=a%2*b,a/=2,b*=2;return c}

54 characters - 59 if you include "K&R C"

Oops : I meant

m(a,b){int c=0;while(a!=0)c+=a%2,a/=2,b*=2;return c;}

• GWO 2009-07-22 10:39
GWO:
GWO:
K&R C:
int m(a,b){c=0;while(a!=0)c+=a%2*b,a/=2,b*=2;return c}

54 characters - 59 if you include "K&R C"

Oops : I meant

m(a,b){int c=0;while(a!=0)c+=a%2,a/=2,b*=2;return c;}

m(a,b){int c=0;while(a)c+=a%2*b,a/=2,b*=2;return c;}

Stupid stale clipboard
• Matt 2009-07-22 10:40
int russianPeasantMultiplication(double a, double b) {
cout << "You";
return 0;
}

// In Soviet Russia, functions write You
• Jonathan 2009-07-22 10:41
Recursive version that handles negatives:

public int PeasantMultiply(int n1, int n2)
{
bool negate = false;
if (n1 < 0){
negate = true;
n1 = -n1;
}
int tot = n1 > 1 ? tot += PeasantMultiply(n1 / 2, n2 * 2) : 0;

if (n1 % 2 == 1) tot += n2;
if (negate) tot = -tot;

}
• Jeff Kemp 2009-07-22 10:43
Kook:
...
if (right < 0) {
multiplier *= -1;
right *= -1;
}
...
[/code]

You can remove this bit and it'll still work.
• hh10k 2009-07-22 10:43
Here's my specially optimised version, for all you C++ lovers:

```unsigned do_it_like_a_russian(unsigned a, unsigned b)
{
// Make rows
std::stringstream rows;
rows << a << " x " << b << "\n";
while (a > 0)
{
rows << (a>>=1) << " " << (b<<=1) << "\n";
}

// Cross out even rows
std::string line;
std::stringstream crossed;
crossed.fill('-');
while (std::getline(rows, line))
{
std::stringstream(line) >> a;
crossed.width(line.size());
crossed << ((a & 1) ? line : "") << "\n";
}

// Total remaining rows
unsigned total = 0;
while (std::getline(crossed, line))
{
std::string::size_type p = line.find_last_of(' ');
if (p != std::string::npos)
{
std::stringstream(line.substr(p)) >> b;
total += b;
}
}
}
```
• Frits 2009-07-22 10:43
Bob:
Someone straighten me out here but I think the peasant don't know math for crap.

May be I'm doing it wrong but when I Multiply 45 x 76, I get 3420

Peasants get:
```45   x  76
22	152	0
11	304	304
5	608	608
2	1216	0
1	2432	2432
======================
3344

Flip the numbers and you get the right answer
76	45
38	90	0
19	180	180
9	360	360
4	720	0
2	1440	0
1	2880	2880
=====================
3420
```

Peasant math apparently only works if one of the number is even and in the first column.

This must be why they remain peasants.

you forgot the first line contains an odd number, wich adds up to the total, there's your missing 76
• Nicholas Laux 2009-07-22 10:44
Ruby: 49 characters, counting spaces.

def a(b,c) return b==1?c:c*(b%2)+a(b>>1,c<<1) end

• Osno 2009-07-22 10:44
Btw, it's not in the spirit of the thread to criticize without chipping in. C#. Doesn't handle negative numbers, as per my previous logic:

private static long Multiply(long firstNum, long secondNum)
{
long acum = 0;
while (firstNum > 0)
{
if ((firstNum & 1) == 1)
acum += secondNum;
firstNum = firstNum >> 1;
secondNum = secondNum << 1;
}
return acum;
}

captcha: ludus (programming is always a game)
• Nick Pope 2009-07-22 10:45
Did you check the output? ;)

Aye, I did. And still seems to work fine... Are you having a problem with it?
• Real russian peasant :) 2009-07-22 10:46

>Python 3.x
>Why else would they support unicode?
>Translation is probably hilariously wrong.

I corrected yor translation a bit :)

# Модуль умножения, используемый русскими крестьянами

def Перемножить(X,Y):
пары = []

def СоздатьПары(X,Y):
пары = []
while X > 0:
пары.append([X,Y])
X = X//2
Y = Y*2
return СуммаВсех(Ликвидировать(пары))

def Ликвидировать(пары):
пары = [Элемент for Элемент in пары if Элемент[0] %2 != 0]
return пары

def СуммаВсех(пары):
Сумма = 0
for Элемент in пары:
Сумма += Элемент[1]
return Сумма

пары = СоздатьПары(X, Y)
return пары

print(Перемножить(18, 23))

>>> 414
• jcs 2009-07-22 10:47
• Samuel A. Falvo II 2009-07-22 10:47
I didn't see a Forth version yet. Maybe I scanned too quickly.

: russian* ( n1 n2 -- n3 )
0 -rot begin dup while
dup 1 and if -rot over + swap rot then 2/ swap 2* swap
repeat drop nip ;
• Anonymous 2009-07-22 10:48
Me:
Bah to all your bloaty solutions. Perlmongers do it in one line :P

sub m(){my(\$a,\$b)=@_;my \$t;while(\$a){\$t+=\$b if (\$a&1);\$a>>=1;\$b<<=1;}return \$t;}

But surely that's just..
```sub m()
{
my(\$a,\$b)=@_;
my \$t;
while(\$a)
{
\$t+=\$b if (\$a&1);
\$a>>=1;
\$b<<=1;
}
return \$t;
}
```

..with the returns stripped out..
• rst 2009-07-22 10:48
4 pages and no FORTRAN?
```      integer function mult (a, b)
integer a, b
logical neg
mult = 0
neg = (a .lt. 0)
if (neg) a = (-1) * a
do while (a .gt. 0)
if (mod(a, 2) .eq. 1) then
mult = mult + b
endif
a = a / 2
b = b * 2
enddo
if (neg) mult = (-1) * mult
return
end
```
• halber_mensch 2009-07-22 10:49
halber_mensch:
Better recursive python solution:
```def умножить(a,b):
if (a==1): return b
return b*(a%2)+умножить(a>>1,b<<1)
```

And one that handles all integers, not just natural numbers:
```def умножить(a,b):
if (-1<=a<=1): return a*b
return b*(a%2)+умножить(a>>1,b<<1)
```
• groknroll 2009-07-22 10:49
Recursive C# solution.

private int PeasantMultiply( int n1, int n2) {
if ( n1 == 1 )
return n2;

return ( n1 % 2 == 0 ? 0 : n2 ) + (n1 == 0 ? 0 : PeasantMultiply( n1 >> 1, n2 << 1 ));
}
• Samuel A. Falvo II 2009-07-22 10:51
Bugger! There's a bug in the code I posted, and I don't have time to fix it right now. :( At any rate, the Russian algorithm is what Chuck Moore used to implement his "*+" operator in his MISC processors.
• Xthlc 2009-07-22 10:52
Here's a slightly shorter and bitshiftier recursive ruby version, although I like that you modified the integer class. How very Ruby. :D

def russian(a, b)
return 0 if a == 0
(a & 0x1) * b + russian(a>>1, b*2)
end
• buzkie 2009-07-22 10:53
static int russianmult(int a,int b){
int total = 0;
while (a >= 1){
if (a% 2 != 0){total += b;}
a = a /2; b = b *2;
}
}

Any suggestions welcomed
• shub 2009-07-22 10:54
```#include <stdio.h>

int peasant_multiply(int x, int y)
{
int result;
for(result = 0; x != 0 && y != 0; x /= 2, y *= 2)
{
result += (x % 2) * y;
}
return result;
}
```

Depending on compiler behavior you could move
`result += (x % 2) * y`
into the update step and save a few lines, but that would be evil and wrong. :)
• Stephen 2009-07-22 10:58
This is similar to how I multiply numbers in my head, except that I will divide by any factor, and when I run into too large of a prime, I either change to estimating or play the "multiply by 7 means multiply by 8 and subtract by one" game. I don't recall where I learned to do that...
• Xthlc 2009-07-22 11:00
Curses! More-or-less beaten by this solution. For some reason I didn't think to shift b.
• Rootbeer 2009-07-22 11:00
Herman:
this is the exact implementation of the multiply function on binary computing hardware

Is this so? I had assumed that most CPUs with MULtiply opcodes used hardware lookup tables, in order to achieve a fast and constant O(1) execution time, but perhaps I am mistaken. It's certainly a less sensible approach with 32- or 64-bit operands than it would have been with 8- or 16-bit operands.

• campkev 2009-07-22 11:01
in C#
public int RussianMultiply(int operand1, int operand2)
{
int res = 0;
while (operand1 > 0)
{
if (operand1 % 2 == 1) res += operand2;
operand1 /= 2;
operand2 *= 2;
}
return res;
}
• Dmitri Savichev 2009-07-22 11:01
Yet another Scheme solution

;;proper R5RS
(define (rusmult a b)
(cond ;;special cases
((= a 0) 0);; okay, it's dirty, but i'm way to lasy
((= b 0) 0);; to try to come up with something better
((negative? a) (* -1 (rusmult (* -1 a) b)))
(else (if (= a 1) ;; real computation
(+ (if (odd? a) b 0))
(+ (if (odd? a) b 0)
(rusmult (if (even? a) (/ a 2) (/ (- a 1) 2)) (* b 2)))))))
• campkev 2009-07-22 11:02
Recursive in C#
public int RecursiveRussianMultiply(int operand1, int operand2)
{
return operand1 == 0 ? 0 : RecursiveRussianMultiply(operand1 / 2, operand2 * 2) + (operand1 % 2 == 1 ? operand2 : 0);
}
• Sean Handley 2009-07-22 11:03
C# solution (boilerplate not included)

```private static List<Pair> _pairs = new List<Pair>();

private static void RussianPeasant(int a, int b)
{
if (a == 1)
{
int result = 0;
foreach (Pair pair in _pairs)
{
if (pair.FirstNum % 2 != 0)
result += pair.SecondNum; //accumulate all second nums, if first num in pair is an odd number
}
DisplayMessage("Result: " + result.ToString());
}
else
{
//tail recursive call
RussianPeasant(a / 2, b * 2); //half first number (ignoring remainder), double second number
}
}
```
• lyml 2009-07-22 11:03
Scheme

(define (mult a b)
(cond ((= b 1) a)
((= (remainder b 2) 1) (+ b (mult (* 2 a) (quotient b 2))))
(else (mult (* 2 a) (/ b 2)))))

not tested
CAPTHA: vereor
• Osno 2009-07-22 11:03
Recursive C# in one line :)

private static long m(long f, long s) { return ((f&1)==1?s:0)+(f>0?m(f>>1,s<<1):0); }

Ok, it's just like the perl sample. Here, how it should be read:

private static long m(long f, long s)
{
return ((f&1)==1?s:0)+(f>0?m(f>>1,s<<1):0);
}

And for the whole "I can do it in a few chars" thing, from the return to the colon it's only 43 characters.
• Someone 2009-07-22 11:04
An ABAP solution that compiles:
```REPORT MULTIP.

DATA: product TYPE i,
left_num TYPE f VALUE 18,
right_num TYPE f VALUE 23,
half_left TYPE f,
half_left_floor TYPE f.

WHILE left_num > 0.
"check for even number and add to product (there must be a better way...)
half_left = left_num / 2.
half_left_floor = FLOOR( left_num / 2 ).
IF half_left <> half_left_floor.
product = product + right_num.
ENDIF.

"move to next set
left_num = FLOOR( left_num / 2 ).
right_num = right_num * 2.
ENDWHILE.

WRITE product.
```
• Dmitri Savichev 2009-07-22 11:04
ugh, i meant it that way
```;;proper R5RS
(define (rusmult a b)
(cond ;;special cases
((= a 0) 0);; okay, it's dirty, but i'm way to lasy
((= b 0) 0);; to try to come up with something better
((negative? a) (* -1 (rusmult (* -1 a) b)))
(else (if (= a 1) ;; real computation
(+ (if (odd? a) b 0))
(+ (if (odd? a) b 0)
(rusmult (if (even? a) (/ a 2) (/ (- a 1) 2)) (* b 2)))))))
```
• Oliver Klozoff 2009-07-22 11:04
This is going to get lost in the mix, but here's my take.

Note: I'm betting that most of the naive implementations people have done don't function correctly when multiplying negative numbers. This one does.

```using System;
using System.Data;
using System.Diagnostics;

using o = System.Console;

// to compile on any modern Windows machine:
//
// PATH=%PATH%;C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727
// csc rusmult.cs

class X {

public static void Main(string[] args) {
try {
if (args.Length != 2) {
o.WriteLine("Usage: {0} n1 n2", Environment.GetCommandLineArgs()[0]);
return;
}

// doing this makes negative numbers work
uint n1 = (uint)Convert.ToInt32(args[0]);
uint n2 = (uint)Convert.ToInt32(args[1]);

// ensure n1 < n2 to minimize steps
if (n1 > n2) { n1 ^= n2; n2 ^= n1; n1 ^= n2; }

int dig1 = (n1==0) ? 1 : (int) Math.Ceiling(Math.Log10(n1));
int dig2 = (n2==0) ? 1 : (int) Math.Ceiling(Math.Log10(n2));
int dig3 = dig1 + dig2;

string fmt1 = string.Format("{{0,{0}}} x {{1,{1}}} ", dig1, dig3);
string fmt2 = string.Format(" | + {{0,{0}}}", dig3);
string fmt3 = string.Format("{{0,{0}}} x {{1,{1}}}  =    {{2}}", dig1, dig3);

uint accum = 0;
while (n1 > 0) {
o.Write(fmt1, n1, n2);
if ( (n1 & 1) != 0) {
o.Write(fmt2, n2);
accum += n2;
}  else {
o.Write(" | strike");
}
o.WriteLine();
n1 >>= 1;
n2 <<= 1;
}
o.WriteLine(new string('-', dig1 + 3 + dig3 + 5 + dig3));
o.WriteLine(fmt3, args[0], args[1], (int)accum);

} catch (Exception ex) {
o.WriteLine("Error: {0}", ex);
}
}
}
```

```Function PeasantMultiply(x As Integer, y As Integer) As Integer
Dim product As Integer = 0

While x >= 1
If x Mod 2 == 1 Then
product += y;
End If

x /= 2
y *= 2
End If

Return product
End Function```
• _flt 2009-07-22 11:07
Some considerations for speed optimisation:
- Division, multiplication and modulo are quite complex and will take longer than standard bit operations on most CPUs.
- Have the smaller value be decremented will save cycles
```unsigned int rmul( unsigned int a, unsigned int b )
{
if ( a > b ) rmul( b, a );

unsigned int acc = (a & 1) ? b : 0;

for ( ; a >>= 1 ; b <<= 1 ) {
if ( a & 1 ) acc += b;
}
return acc;
}
```
• Remy 2009-07-22 11:07
Here's mine, in Python. It works for all integers.

```def russian(a, b):
if a < 0:
a, b = -a, -b
c = 0
while 1:
if a & 1:
c += b
a >>= 1
b <<= 1
if a <= 0:
break
return c```
• Mestafais 2009-07-22 11:08
Mine on javascript
function peasentDevide(a, b){r=0;while(a!=0){if (a%2==1)r+=b;a=Math.floor(a/2);b=b*2;}return r;}
• Rief 2009-07-22 11:08
Wrote in D language :P but the mult function should work also in C++, I think...well, with unsigned int instead of uint :P:

import std.stdio;
import std.string;

int mult(uint fst, uint snd)
{
uint result;

for(uint i=0; fst >= 1; fst/=2, snd*=2, i+=1)
if(fst % 2)
{
result += snd;
fst -= 1;
}

return result;
}

void main(string[] args)
{
if(args.length != 3)
{
writefln("Usage: %s <num> <num>", args[0]);
return 0;
}
if(!args[1].isNumeric())
{
writefln("First argument isn't a number");
return 0;
}
if(!args[2].isNumeric())
{
writefln("Second argument isn't a number");
return 0;
}

writefln(mult(atoi(args[1]),atoi(args[2])));

return 0;
}

To run put it in a file and use the gdc compiler....
• Billy 2009-07-22 11:09
In Python (Works with 0 and negative numbers!)

def p_mult(num1, num2) :
if num1 == 0 or num2 == 0 : return 0
sign = bool(num1 < 0) ^ bool(num2 < 0)
num1 = abs(num1)
num2 = abs(num2)
dat = [[num1, num2]]
while num1 != 1 :
num1 /= 2
num2 *= 2
dat.append([num1, num2])
total = 0
for n in dat :
if n[0] % 2 == 1 : total += n[1]

http://www.codeskilled.com
• Harleqin 2009-07-22 11:09
Common Lisp:
```(defun russkiply (a b &optional (sum 0))
"returns the product of a and b,
achieved by peasant multiplication."
(cond ((or (zerop a) (zerop b)) 0)
((minusp a) (- (russkiply (- a) b)))
((minusp b) (- (russkiply a (- b))))
((= a 1) (+ b sum))
(t (russkiply (floor (/ a 2))
(* b 2)
(+ sum (* b (logand a 1)))))))
```

C:
```int russkiply (int a, int b)
{ if (a == 0 || b == 0) { return 0; };
if (a < 0) { return - russkiply (- a, b); };
if (b < 0) { return - russkiply (a, - b); };
int p = 0;
for (;
p += (a & 1) * b, a != 1;
a /= 2, b *= 2) {};
return p; };
```

• Will 2009-07-22 11:09
My solution in LUA:
```function f(x, y)
return (x % 2 == 1 and y or 0) + (x > 0 and f(math.floor(x / 2), y * 2) or 0)
end```
• Anonymous 2009-07-22 11:10
SR:
Anonymous:
Oh wow, this is unbelievable. No trolls, no grammar nazis, no flame-bait, no spammers - just everyone chipping in on an interesting coding challenge. I think this is probably the most civilised comments page I've ever seen on TDWTF. Well done everyone, you've all earnt a cookie.

I dropped that in there to test the waters (FYI it is proper English) but amazingly enough, nobody took the bait. Everyone's just happy to work on the coding problem. I'm aghast at just how civil developers can be when they've got something to develop!
• bluebearr 2009-07-22 11:10
Windows XP batch file:
```@echo off
set _a=18
set _b=23
call :mult %_a% %_b% _result
echo %_a% x %_b% = %_result%
goto :EOF

:mult
::   Multiply two numbers
::   Parameters:
::    %1 - first number
::    %2 - second number
::    %3 - variable to return result in
setlocal
set _a=%1
set _b=%2
set _res=0
:calc
set _eventest=0
for /L %%i in (0,2,8) do if %_a:~-1%==%%i set _eventest=1
if %_eventest%==0 set /a _res+=_b
if %_a% LEQ 1 goto endcalc
set /a _a/=2
set /a _b*=2
goto calc
:endcalc
endlocal & set %3=%_res%
goto :EOF
```
Nick Pope:
Did you check the output? ;)

Aye, I did. And still seems to work fine... Are you having a problem with it?

Forgive, i missed the automagic vivification of c to existance and 0
• Josh Bohde 2009-07-22 11:11
Python 2.6

`m=lambda a,b:sum(a<<n for n in range(b) if b>>n&1)`

51 characters
• baka0815 2009-07-22 11:12
Since everyone is bragging about shifting instead of multiply/divide, here is a Pascal version with shifting:

```function RussianMultiply(Left, Right: Integer): Integer;
begin
if (Left = 1) then
begin
Result := Right;
Exit;
end;

Result := 0;

if ((Left mod 2) <> 0) then Inc(Result, Right);
while Left <> 1 do
begin

Left := Left shr 1;
Right := Right shl 1;
if ((Left mod 2) <> 0) then Inc(Result, Right);
end;
end;```

You could strip the
```  if (Left = 1) then
begin
Result := Right;
Exit;
end;```

part, but it would be slower I guess.
• Osno 2009-07-22 11:12
Shorter:
return f>0?m(f>>1,s<<1)+(f&1)*s:0;

Just realized that ( (a&1) == 1? s : 0 ) === ( (a&1)*s )

34 chars without the function header.
• Ian McLaird 2009-07-22 11:13
Alex Ciarlillo:
recursive scala soln.

```  def do_mult(left : Int, right : Int) : Int = {
if (left == 1) right
else if (left%2 == 0) do_mult(left/2, right*2)
else do_mult(left/2, right*2) + right
}
```

And, for even more fun, with a custom operator

```object praxis2 {
implicit def RussianIntInt(i: Int):RussianInt = new RussianInt(i)
implicit def IntRussianInt(i: RussianInt):Int = i.a

class RussianInt(val a: Int) {
def ***(b: RussianInt): RussianInt = {
if (a < 2) if (a == 1) b else 0
else if (a % 2 == 1) b + ((a / 2) *** (b * 2))
else ((a / 2) *** (b * 2))
}
}

def main(args: Array[String]) {
val a = args(0).toInt
val b = args(1).toInt
val res: Int = a *** b
println(res)
}
}
```
• Wulf0r 2009-07-22 11:14
Python:
```def russianMultiply(lst):
""" param is a list with one entry of tupel containing the ints to multiply """
arg = lst[-1]
# check if recursion is complete
if arg[0] == 1:
# pythons X-trem X-pressivnes -> filter all unevens and add them
return reduce( lambda x,y: x+y, [x[1] for x in lst if x[0] % 2 != 0])

lst.append( (arg[0] / 2, arg[1] * 2) )
return russianMultiply( lst)

print russianMultiply( list([(18,23)]))
```
• Xthlc 2009-07-22 11:15
Final version of my ruby function, slightly altered with some cribbage from halber_mensch to handle all integers.

```def russian(a, b)
return a*b if (-1..1).include? a
(a & 0x1) * b + russian(a>>1, b<<1)
end```
• baka0815 2009-07-22 11:16
Last one I submit, I promise! :)

```function RussianMultiply(Left, Right: Integer): Integer;
begin
Result := 0;

if ((Left and 1) = 1) then Inc(Result, Right);
while Left <> 1 do
begin
Left  := Left shr 1;
Right := Right shl 1;
if ((Left and 1) = 1) then Inc(Result, Right);
end;
end;```
• Steve the Cynic 2009-07-22 11:17
Captain Obvious:
I haven't done APL in a LONG time...

```     Z <- A RUSSIAN B
[1]  Z <- 0
[2] TOP:
[3]  Z <- Z + A * 0 = 2 | B
[4]  A <- |_ A (divide) 2
[5]  B <- B x 2
[6]  -> (A>0) / TOP
```

Or

```     RET <- A RUSSIAN B
[1] X <- 2 * (highminus)1 + (iota) (upside down L) 2 (star-in-circle) A + 1
[2] Y <- X x B
[3] Z <- 2 | |_ A / X
[4] RET <- +/ Y x Z
```

X gets a list of powers of two starting with 1

Y gets a list of B times powers of two

Z gets a list of (A/power of two) mod 2 (0 or 1)

RET gets the sum of the list of Y and Z elements multiplied together.

4 lines, no loops, no recursion, and only one Greek letter!

NOT TESTED. Written using a memory of APL not exercised in 25 years.
• - 2009-07-22 11:18
Herman:
As this is the exact implementation of the multiply function on binary computing hardware, a simple

```int Mult(int a, int b)
{
return a * b;
}```

should do for most platforms :)

Well that one wins Best Abuse Of The Rules.:) I've only seen one C preprocessor nasty so far.... any more takers?
• Ken B 2009-07-22 11:19
kastein:
Also, I'm disappointed... no MUMPS? no MS-DOS batch?
You just didn't wait long enough. :-)

Here is my MS-Windows Batch file:

```@echo off
rem Multiply.bat
rem Multiplication the "Russian Peasant" way.
rem To be called with two parameters -- the numbers to multiply.
rem For example:  multiply 18 23
rem
rem Note:  No sanity check is provided to verify two numbers are passed.

set /a Multiplier=%1
set /a Multiplicand=%2
set /a Product=0

:loop

set /a OddOrEven=%Multiplicand% / 2
set /a OddOrEven=%OddOrEven% * 2
if not %OddOrEven%==%Multiplicand% set /a Product=%Product% + %Multiplier%

set /a Multiplicand=%Multiplicand% / 2
set /a Multiplier=%Multiplier% * 2

if not %Multiplicand%==0 goto loop

echo %1 times %2 equals %Product%```
Now, how does one get code to single-space?
• Lupe 2009-07-22 11:20
A database query syntax error has occurred. This may indicate a bug in the software. The last attempted database query was:

(SQL query hidden)

from within function "MediaWikiBagOStuff::_doquery". MySQL returned error "1194: Table 'mw_objectcache' is marked as crashed and should be repaired (localhost)".
• aBase 2009-07-22 11:20
The problem says two numbers, not two integers, so here's the first draft of a PHP solution that will handle decimal fractions (and also negative numbers):
```function potemkin_multiply(\$two_numbers)
{
\$frac_len = array(0, 0);
foreach (\$two_numbers as \$num) {
if (\$num == 0) {
return 0;
}
\$num = rtrim(\$num, '.');
if (\$len = strrchr(\$num, '.')) {
\$frac_len[] = strlen(strrchr(\$num, '.')) - 1;
}
}
\$power = max(\$frac_len);
\$neg = false;
foreach (\$two_numbers as & \$num) {
if (\$num < 0) {
\$neg = !\$neg;
}
\$num = abs(\$num * pow(10, \$power));
}
\$total = 0;
while (\$two_numbers[0] > 1) {
if (\$two_numbers[0] % 2) {
\$total += \$two_numbers[1];
}
\$two_numbers[0] = floor(\$two_numbers[0] / 2);
\$two_numbers[1] *= 2;
}
\$total = (\$total + \$two_numbers[1]) / pow(10, \$power * 2);
if (\$neg) {
\$total *= -1;
}
return \$total;
}```
Test code:
```\$nums = array(0, -1, 1, 18, -23, 154., -229.5, 49.0, 389.99,
67.99999, -592.8729, .678, 0.00678);
for (\$i = 0; \$i < 50; \$i++) {
\$pair = array(\$nums[array_rand(\$nums)], \$nums[array_rand(\$nums)]);
\$russian = potemkin_multiply(\$pair);
\$orthodox = \$pair[0] * \$pair[1];
echo \$pair[0] . ' * ' . \$pair[1] . ' = <b>' . \$russian . '</b>';
if ((string) \$russian != (string) \$orthodox) {
echo ' <span style="color:red">(' . \$orthodox . ')</span>';
}
echo '<br />';
}```
• Qwertyuiopas 2009-07-22 11:21
I know everybody wants it :)

Hopefully none of it was removed.

Also, everything after the first . is disabled debugging code. Remove the [-] to see what is left of the memory.

>>>>>,>>,[->+>+<<]<<[[-[>+<-]>[>+>>>+<<<<-[[<+>-]>[-]<]]<]>>[>>[-]<<[-]]+>[->>>>>++>++<<<<<<]>>]>>>>[-]<<<<<<<[<<<<<]>>>>>[>>[->>>>>+<<<<<]>>>]>>.[-][<<<<<<<[<<<<<]>>>.>.>[.>.>.>.>.>].>.>.]
48 characters in javascript:

function m(a,b){return a>1?a%2*b+m(a>>1,b*2):b;}
• campkev 2009-07-22 11:23
Jay:

public static int multiply(int first, int second){
if(first == 1){
return second;
}

int result = 0;

if(first%2 != 0){
result += second;
}
result += multiply(first/2, second * 2);
return result;
}

Didn't test it, but I think this will infinite loop if the first number is 0;
• Ken B 2009-07-22 11:23
Steve the Cynic:
Captain Obvious:
I haven't done APL in a LONG time...

```...snip...
```

Or

```...snip...
```

...snip...

NOT TESTED. Written using a memory of APL not exercised in 25 years.
Noted. (Also, I am not familiar with using standard ASCII characters for APL, as I had a "real" APL character set to work with.) However, where's your single-line solution, as any "good" APL programmer knows is the target.
• christopher.n 2009-07-22 11:23
Efficient C solution:

int russianMult( int a, int b ){

return a*b;
}
• Zor 2009-07-22 11:24
All of these solutions are soooooo slooooooooow. Try this one out. Just call the function you need! Ex: for 5 x 18, call "F5x18();". Note: Doesn't yet work for all values, but I'm working on it.

static int F10x1() { return F5x2(); }
static int F10x10() { return F5x20(); }
static int F10x2() { return F5x4(); }
static int F10x3() { return F5x6(); }
static int F10x4() { return F5x8(); }
static int F10x5() { return F5x10(); }
static int F10x6() { return F5x12(); }
static int F10x7() { return F5x14(); }
static int F10x8() { return F5x16(); }
static int F10x9() { return F5x18(); }
static int F11x150() { return F5x300() + 150; }
static int F1x1() { return 1; }
static int F1x10() { return 10; }
static int F1x12() { return 12; }
static int F1x1200() { return 1200; }
static int F1x14() { return 14; }
static int F1x16() { return 16; }
static int F1x18() { return 18; }
static int F1x2() { return 2; }
static int F1x20() { return 20; }
static int F1x24() { return 24; }
static int F1x28() { return 28; }
static int F1x3() { return 3; }
static int F1x32() { return 32; }
static int F1x36() { return 36; }
static int F1x4() { return 4; }
static int F1x40() { return 40; }
static int F1x48() { return 48; }
static int F1x5() { return 5; }
static int F1x56() { return 56; }
static int F1x6() { return 6; }
static int F1x64() { return 64; }
static int F1x7() { return 7; }
static int F1x72() { return 72; }
static int F1x8() { return 8; }
static int F1x80() { return 80; }
static int F1x9() { return 9; }
static int F23x75() { return F11x150() + 75; }
static int F2x1() { return F1x2(); }
static int F2x10() { return F1x20(); }
static int F2x12() { return F1x24(); }
static int F2x14() { return F1x28(); }
static int F2x16() { return F1x32(); }
static int F2x18() { return F1x36(); }
static int F2x2() { return F1x4(); }
static int F2x20() { return F1x40(); }
static int F2x24() { return F1x48(); }
static int F2x28() { return F1x56(); }
static int F2x3() { return F1x6(); }
static int F2x32() { return F1x64(); }
static int F2x36() { return F1x72(); }
static int F2x4() { return F1x8(); }
static int F2x40() { return F1x80(); }
static int F2x5() { return F1x10(); }
static int F2x6() { return F1x12(); }
static int F2x600() { return F1x1200(); }
static int F2x7() { return F1x14(); }
static int F2x8() { return F1x16(); }
static int F2x9() { return F1x18(); }
static int F3x1() { return F1x2() + 1; }
static int F3x10() { return F1x20() + 10; }
static int F3x12() { return F1x24() + 12; }
static int F3x14() { return F1x28() + 14; }
static int F3x16() { return F1x32() + 16; }
static int F3x18() { return F1x36() + 18; }
static int F3x2() { return F1x4() + 2; }
static int F3x20() { return F1x40() + 20; }
static int F3x3() { return F1x6() + 3; }
static int F3x4() { return F1x8() + 4; }
static int F3x5() { return F1x10() + 5; }
static int F3x6() { return F1x12() + 6; }
static int F3x7() { return F1x14() + 7; }
static int F3x8() { return F1x16() + 8; }
static int F3x9() { return F1x18() + 9; }
static int F4x1() { return F2x2(); }
static int F4x10() { return F2x20(); }
static int F4x12() { return F2x24(); }
static int F4x14() { return F2x28(); }
static int F4x16() { return F2x32(); }
static int F4x18() { return F2x36(); }
static int F4x2() { return F2x4(); }
static int F4x20() { return F2x40(); }
static int F4x3() { return F2x6(); }
static int F4x4() { return F2x8(); }
static int F4x5() { return F2x10(); }
static int F4x6() { return F2x12(); }
static int F4x7() { return F2x14(); }
static int F4x8() { return F2x16(); }
static int F4x9() { return F2x18(); }
static int F5x1() { return F2x2() + 1; }
static int F5x10() { return F2x20() + 10; }
static int F5x12() { return F2x24() + 12; }
static int F5x14() { return F2x28() + 14; }
static int F5x16() { return F2x32() + 16; }
static int F5x18() { return F2x36() + 18; }
static int F5x2() { return F2x4() + 2; }
static int F5x20() { return F2x40() + 20; }
static int F5x3() { return F2x6() + 3; }
static int F5x300() { return F2x600() + 300; }
static int F5x4() { return F2x8() + 4; }
static int F5x5() { return F2x10() + 5; }
static int F5x6() { return F2x12() + 6; }
static int F5x7() { return F2x14() + 7; }
static int F5x8() { return F2x16() + 8; }
static int F5x9() { return F2x18() + 9; }
static int F6x1() { return F3x2(); }
static int F6x10() { return F3x20(); }
static int F6x2() { return F3x4(); }
static int F6x3() { return F3x6(); }
static int F6x4() { return F3x8(); }
static int F6x5() { return F3x10(); }
static int F6x6() { return F3x12(); }
static int F6x7() { return F3x14(); }
static int F6x8() { return F3x16(); }
static int F6x9() { return F3x18(); }
static int F7x1() { return F3x2() + 1; }
static int F7x10() { return F3x20() + 10; }
static int F7x2() { return F3x4() + 2; }
static int F7x3() { return F3x6() + 3; }
static int F7x4() { return F3x8() + 4; }
static int F7x5() { return F3x10() + 5; }
static int F7x6() { return F3x12() + 6; }
static int F7x7() { return F3x14() + 7; }
static int F7x8() { return F3x16() + 8; }
static int F7x9() { return F3x18() + 9; }
static int F8x1() { return F4x2(); }
static int F8x10() { return F4x20(); }
static int F8x2() { return F4x4(); }
static int F8x3() { return F4x6(); }
static int F8x4() { return F4x8(); }
static int F8x5() { return F4x10(); }
static int F8x6() { return F4x12(); }
static int F8x7() { return F4x14(); }
static int F8x8() { return F4x16(); }
static int F8x9() { return F4x18(); }
static int F9x1() { return F4x2() + 1; }
static int F9x10() { return F4x20() + 10; }
static int F9x2() { return F4x4() + 2; }
static int F9x3() { return F4x6() + 3; }
static int F9x4() { return F4x8() + 4; }
static int F9x5() { return F4x10() + 5; }
static int F9x6() { return F4x12() + 6; }
static int F9x7() { return F4x14() + 7; }
static int F9x8() { return F4x16() + 8; }
static int F9x9() { return F4x18() + 9; }
• derula 2009-07-22 11:26
While I haven't checked if it already exists, here a non-recursive Ruby solution overwriting the default operator.

I couldn't test it, so it'll probably not work.

But it has comments, works with negative numbers, and doesn't interfere with non-integral multiplication.

```class Bignum
# Save the old multiplication
alias old_mult *
end

class Fixnum
# Save the old multiplication
alias old_mult *
end

class Integer
def *(b)
# Only perform RPM on two integers
if b.is_a? Integer
# Copy first operand so that it can be modified in place *
a = self
# If any of the two is 0, result is 0
return 0 if a == 0 or b == 0
# Get the sign of the result **
sgn = ((a <=> 0) + (b <=> 0)).abs - 1
# Get the absolute values
a, b = a.abs, b.abs
# Initialize the result
result = 0
# > 0 because we want to do a last addition when a is 1
while a > 0
# Add b to result if a is odd
result += b if a % 2 == 1
a << -1 # Right shift a by one
b << 1  # Left shift b by one
end
# Return the result (also: get the sign right)
sgn * result
else
# Use old multiplication if no Integer supplied
old_mult(b)
end
end
end

=begin
* Not sure if this is neccessary, but as I said, I wasn't able to test it.
** You got it? No? Okay, explanation:
a<0^b>0 => (a<=>0)=-1^(b<=>0)=1 => sgn=(-1+1).abs-1=-1
a<0^b<0 => (a<=>0)=-1^(b<=>0)=-1 => sgn(-1-1).abs-1=1
a>0^b>0 => (a<=>0)=1^(b<=>0)=1 => sgn=(1+1).abs-1=1
a>0^b<0 => (a<=>0)=1^(b<=>0)=-1 => sgn(1-1).abs-1=-1
(a<=>0)=0 or (b<=>0)=0 cannot occur, because of the line above that.
=end```

Okay, so this is one of the least clever solutions... but it is commented like no other. Does this get me a sticker?

Damn! I'm stupid. Of course, sgn*result is incorrect. Take this instead:
`      (sgn == -1) ? 0 - result : resultAddendum (2009-07-22 13:34):`
(gotta close those tags.)
• Ken B 2009-07-22 11:28
Zor:
All of these solutions are soooooo slooooooooow. Try this one out. Just call the function you need! Ex: for 5 x 18, call "F5x18();". Note: Doesn't yet work for all values, but I'm working on it.

static int F10x1() { return F5x2(); }
static int F10x10() { return F5x20(); }
...snip...
static int F9x8() { return F4x16() + 8; }
static int F9x9() { return F4x18() + 9; }
The problem is when you don't know the two parameters until runtime. In that case, you'll need something like this:
```switch( x*y )
{
case 1: return F1x1();
case 2: return F1x2();
case 3: return F1x3();
case 4: return F2x2();
}
```
As in your code, it won't handle all cases, but you can finish this "enhancement" as you finish your original code.
• Steve the Cynic 2009-07-22 11:28
Ken B:
Noted. (Also, I am not familiar with using standard ASCII characters for APL, as I had a "real" APL character set to work with.) However, where's your single-line solution, as any "good" APL programmer knows is the target.

Exercise for the reader, as always.

Or if you insist:

```     RET <- A RUSSIAN B
[1] RET <- +/ X x B x 2 | |_ X <- 2 * (highminus)1 + (iota) (upside down L) 2 (star-in-circle) A + 1
```
• shub 2009-07-22 11:29
Osno:
All the people looping on 1 instead of 0 fail.
All the people using multiplication and division instead of shifting (except in languages where there is no shifting) also fail.
Except that C doesn't define bit shift on negative integers. How do you like this signature:
`int peasant_multiply(int x, int y, int *result);`
Maybe we could set errno, in the grand tradition of sqrt().

`unsigned int peasant_multiply(unsigned int x, unsigned int y);`
Using multiply and divide expands our domain from N × N to Z × Z. If that's not worth the minor performance penalty, you're doing much more interesting work than I am.
Since I read this as "Multiply exactly like russian peasants would" then I did it the old-fashioned C# way.

```public static int RussianPeasantMultiplication(int CurrentLeftValue, int CurrentRightValue)
{
List<int> LeftColumn = new List<int>();
List<int> RightColumn = new List<int>();
int FinalValue = 0;

while (true)
{
CurrentLeftValue = LeftColumn[LeftColumn.Count - 1];
CurrentRightValue = RightColumn[RightColumn.Count - 1];

CurrentLeftValue /= 2;
CurrentRightValue *= 2;

if (CurrentLeftValue <= 1) break;
}

for (int i = 0; i < LeftColumn.Count; i++)
{
if (LeftColumn[i] % 2 != 0)
FinalValue += RightColumn[i];
}

return FinalValue;
}```
• CF Guru 2009-07-22 11:30
Dammit...Someone beat me the the CF solution...

Where are the COBOL developers? Don't make me bust out my college COBOL!!!
• porty 2009-07-22 11:30
Zor, this is very useful.
Perhaps something like this would make it easier for the user?

#define multiply(X, Y) F##X##x##Y ()

But...

sub t{\$_[0]?t(\$_[0]>>1,\$_[1]<<1)+(\$_[0]&1)*\$_[1]:0}

52 char is about as far down as I can get it, and does not handle (-) due to Perl using C shifts, which dont operate properly on (-)..
• Kman 2009-07-22 11:31
inline bool shift(unsigned int& result, unsigned int a, unsigned int b)
{
return result += a & 1 ? b : 0;
}

unsigned int RM(unsigned int a, unsigned int b)
{
unsigned int result = 0;
while (a != 1 && shift(result, a>>=1, b<<=1)) {
}
return result;
}
• HonestJoe 2009-07-22 11:32
public class NotCheating {

public static int multiply(int i, int j) {
// using russian multiplication
return multiplyRussian(i, j);
}

private static int multiplyRussian(int i, int j) {

/*
* This method is so secret, you should not even know
* it is here!
* No kidding!
* Stop now, before it is to late!
* Trust me, this is a really neat implementation of the
* russian peasants algorithm, but for your own sake,
* STOP NOW!
*/

return i*j;

}

}
• baka0815 2009-07-22 11:32
Well, what's a promis if you don't break it? :)

- using bit shifting
- using and instead of mod
- working with zeros
- not working with negatives - but why should a peasant multiply negative values?

```function RussianMultiply(Left, Right: Integer): Integer;
begin
Result := 0;

Inc(Result, Right * (Left and 1));
while Left > 1 do
begin
Left  := Left shr 1;
Right := Right shl 1;
Inc(Result, Right * (Left and 1));
end;
end;```
• ponky 2009-07-22 11:32
C++ version
```
void russian(int x, int y)
{
if (x == 0) throw 0;
try { russian(x>>1, y<<1); }
catch (int a) { throw a + y * (x & 1); }
}

int multiply(int x, int y)
{
try { russian(x, y); }
catch (int a) { return a; }
}
```
• antelopelovefan 2009-07-22 11:34
Here's another VBScript version meant to run as an Excel macro.

It assumes the values to be multipled are in cells A2 and B2 of the first Worksheet and it stores all of the intermediate numbers in the cells below as it calculates.

The final output is put in cell C2

```Public Sub CalculateRussianPeasant()
Dim curSheet As Worksheet
Dim curRow: curRow = 2
Dim bDone
Dim i As Integer
Dim total

Set curSheet = Worksheets(1)

Rows("3:65536").Select
Selection.Delete Shift:=xlUp

While Not bDone
curSheet.Cells((curRow + 1), 1).Value = CInt(curSheet.Cells(curRow, 1).Value / 2)
curSheet.Cells((curRow + 1), 2).Value = CInt(curSheet.Cells(curRow, 2).Value * 2)

curRow = curRow + 1

If curSheet.Cells(curRow, 1).Value = 1 Then
bDone = True
End If
Wend

curSheet.Cells(2, 3).Value = 0
For i = 2 To curRow
If curSheet.Cells(i, 1).Value Mod 2 <> 0 Then
curSheet.Cells(2, 3).Value = curSheet.Cells(2, 3).Value + curSheet.Cells(i, 2).Value
ElseIf i > 2 Then
Range("A" & i & ":B" & i).Select
With Selection.Font
.Strikethrough = True
.ColorIndex = 3
End With
End If
Next

Range("C2").Select
End Sub
```
• Quxxy 2009-07-22 11:35
A version for the D programming language; both as an interative function and a template:

```// Regular version.  Can also be used in compile-time code.
long multiply(long a, long b)
{
if( a == 0 || b == 0 ) return 0;
if( a < 0 ) return -multiply(-a, b);
if( b < 0 ) return -multiply(a, -b);

long acc = 0;
do
{
if( a % 2 == 1 )
acc += b;
a /= 2;
b *= 2;
}
while( a >= 1 );
return acc;
}

// Template version
template Multiply(long a, long b)
{
static if( a == 0 || b == 0 )
const Multiply = 0L;

else static if( a < 0 )
const Multiply = Multiply!(-a, b);

else static if( b < 0 )
const Multiply = Multiply!(a, -b);

else static if( a == 1 )
const Multiply = b;

else static if( a % 2 == 1 )
const Multiply = b + Multiply!(a/2, b*2);

else
const Multiply = Multiply!(a/2, b*2);
}```
• f3nd3r 2009-07-22 11:35
Wow, you make PHP look good, that is pretty impressive.
In Ruby,
```class Fixnum
def *(b)
a, k = self, 0
a, b = -a, -b if a < 0
while a != 0
k += b if a & 1 == 1
a >>= 1
b <<= 1
end
k
end
end
```
• Northpole 2009-07-22 11:37
Ruby, one line, non-recursive:
`a,b,res=a/2,b*2,(res||0)+(a&1)*b while a>0`
• campkev 2009-07-22 11:42
Second attempt at C#, this works with negative numbers:
public int RussianMultiply(int operand1, int operand2)
{
int res = 0;
while (operand1 != 0)
{
if (operand1 % 2 == 1) res += operand2;
else if (operand1 % 2 == -1) res -= operand2;
operand1 /= 2;
operand2 *= 2;
}
return res;
}
• jweir77 2009-07-22 11:42
Different twist on a Ruby solution:

```class Fixnum
def rum n
product = 0
self.to_s(2).reverse.split(//).each_with_index do |bit, pos|
product += ( n << pos ) if bit.to_i == 1
end
product
end
end

p 3.rum(2)
p 2.rum(3)
p 18.rum(23)
p 23.rum(18)
p 76.rum(45)
p 45.rum(76)
```

• halber_mensch 2009-07-22 11:43
Josh Bohde:
Python 2.6

`m=lambda a,b:sum(a<<n for n in range(b) if b>>n&1)`

51 characters

I'd argue it's not quite the russian algorithm though, since you've both reversed the operands and you are evaluating a-log2(a) more iterations than would be done in the real algorithm. For example, if I were to feed 5,4 into the russian algorithm, it would make 3 iterations (the left column being 5,2,1). Taking into account that you've swapped the parameters, your algorithm would evaluate 5 iterations (the left column being 5,2,1,0,0), or two more (5 - log2(5)) iterations than you should if you were adhering to the real algorithm, which stops evaluating when reaching 1 in the left column. Your solution also fails for negative values of a.
• campkev 2009-07-22 11:43
second attempt at C# recurisive, this works with negative numbers:
public int RecursiveRussianMultiply(int operand1, int operand2)
{
return operand1 == 0 ? 0 : RecursiveRussianMultiply(operand1 / 2, operand2 * 2) + (operand1 % 2 == 1 ? operand2 : 0) + (operand1 % 2 == -1 ? -operand2 : 0);
}
• Floyd 2009-07-22 11:45
```using System;
using System.Collections.Generic;
using System.Text;
using System.Linq;

namespace RussianPeasant
{
class RussianPeasant
{
static void Main(string[] args)
{
if (args.Length != 2)
{
Console.Error.WriteLine("Peasants can't multiply " + args.Length + " operands!");
return;
}

int left = 0;
int right = 0;

if ((!int.TryParse(args[0], out left)) || (!int.TryParse(args[1], out right)))
{
Console.Error.WriteLine("Peasants can't multiply non-numeric operands!");
}

int solution = (from pair in GetColumns(left, right)
where pair.First() % 2 != 0
select pair).Sum(p => p.ElementAt(1));

Console.WriteLine(solution);
}

public static IEnumerable<IEnumerable<int>> GetColumns(int left, int right)
{
yield return new int[] { left, right };

while (left > 0)
{
left = left >> 1;
right = right * 2;

yield return new int[] { left, right };
}
}
}
}
```
• Alex Guzman 2009-07-22 11:46
int first = 18;
int second = 23;

int result = 0;

while ((first = first / 2) >= 1)
{
second = second * 2;

if (first % 2 != 0)
result += second;
}

• kastein 2009-07-22 11:47
Rootbeer:
Herman:
this is the exact implementation of the multiply function on binary computing hardware

Is this so? I had assumed that most CPUs with MULtiply opcodes used hardware lookup tables, in order to achieve a fast and constant O(1) execution time, but perhaps I am mistaken. It's certainly a less sensible approach with 32- or 64-bit operands than it would have been with 8- or 16-bit operands.

Yeah... it isn't really a good idea. I thought it was more sane until I considered the results...
for 8 bit multiplication we have two 8 bit inputs and a 16 bit output, so the table is 2^16 bits long with 16 bit entries... that's 1M transistors without the decoders/addressing logic. The average 8 bit CPU has a few thousand to a few tens of thousands of transistors. It just gets worse from there - multiplying two 16 bit numbers requires 4G 32-bit entries (128G transistors!) and multiplying two 32 bit numbers requires 1024E transistors... multiplying 64 bit numbers using a lookup table would require more transistors than there are on the planet (by at least a factor of 1 pentillion based on my napkin calculations...)

If you want to know how processors multiply, several methods are listed here: wikibooks: multiply
Booth's Algorithm
some more are listed here, not all easily applicable to microprocessor design: multiplication algorithms

More (basically the peasant's method in hardware!) binary multiplier
• Jürgen 2009-07-22 11:48
Python:

```def rpmul(a, b):
return ((a == 1) and b or (a % 2) * b + rpmul(a/2, 2*b))
```

Ruby:

```def rpmul a, b
(a == 1) ?  b : (a % 2) * b + rpmul(a/2, 2*b)
end
```

• Bryan 2009-07-22 11:53
All we need is a SAS submission and this thread will be complete.
• Alex Muscar 2009-07-22 11:53
Common Lisp

Imperative/iterative and functional solutions. Ain't it nice that Lisp's so versatile? :P
```(defun rpm (m n)
(do ((t1 m (ash t1 -1))
(t2 n (ash t2 1))
(r 0 (+ r (* (mod t1 2) t2))))
((= t1 0) r)))
```

```(defun rpm-r (m n)
(labels ((rec (acc m n)
(if (= m 0)
acc
(rec (+ acc (* (mod m 2) n)) (ash m -1) (ash n 1)))))
(rec 0 m n)))
```
• Josh Bohde 2009-07-22 11:55
halber_mensch:
Josh Bohde:
Python 2.6

`m=lambda a,b:sum(a<<n for n in range(b) if b>>n&1)`

51 characters

I'd argue it's not quite the russian algorithm though, since you've both reversed the operands and you are evaluating a-log2(a) more iterations than would be done in the real algorithm. For example, if I were to feed 5,4 into the russian algorithm, it would make 3 iterations (the left column being 5,2,1). Taking into account that you've swapped the parameters, your algorithm would evaluate 5 iterations (the left column being 5,2,1,0,0), or two more (5 - log2(5)) iterations than you should if you were adhering to the real algorithm, which stops evaluating when reaching 1 in the left column. Your solution also fails for negative values of a.

Yeah, I was saving some characters (at the cost of a lot of memory).

Here's a recursive version that is 48 characters

`m=lambda a,b:[0,b][a&1]+m(a>>1,b<<1)if a else 0`
• Sal 2009-07-22 11:56
Postscript:
/rmul{0{2 index 0 eq{exit}if exch dup 1 bitshift 4 1 roll 3 -1 roll dup -1 bitshift 5 1 roll 1 and 1 eq {add}{pop}ifelse}loop exch pop exch pop}def
Osno:
All the people using multiplication and division instead of shifting (except in languages where there is no shifting) also fail.

All the people who don't know what an optimizing compiler is also fail.
• Alex Muscar 2009-07-22 11:59
Common Lisp:

Shorter version of the recursive implementation:

```(defun rpm-r1 (m n &optional (acc 0))
(if (= m 0)
acc
(rpm-r1 (ash m -1) (ash n 1) (+ acc (* (mod m 2) n)))))
```
• Murray 2009-07-22 11:59
public String multiply(int a, int b){
return "Murray is awesome";
}
• PopeHappyCat 2009-07-22 12:03
Damn, you beat me too it. But here you can has lolcode spec 1.2

(Untested)

HAI 1.2
CAN HAS STDIO?

I HAS A X
I HAS A Y
I HAS A MULTIPL
X R NUMBR
Y R NUMBR

VISIBLE "CAN HAS X?:)"
GIMMEH X
VISIBLE "CAN HAS Y?:)"
GIMMEH Y

HOW DUZ I RPM YR X AN YR Y
I HAS A MUTLIPL ITZ 0
I HAS A MODD
I HAS A LOLCAT ITZ MAEK WIN A NUMBR BTW IS DUMMY VARIABLE FOR L00P
IM IN YR RPMLOOP UPPIN YR LOLCAT WILE DIFFRINT X AN 1
X R MAEK QUOSHUNT OF X AN 2 A NUMBR
Y R PRODUKT OF Y AN 2
MODD R MOD X AN 2
BOTH SAEM MODD AN 1, O RLY?
YA RLY, MULTIPL R SUM OF MULTIPL AN Y
NO WAI, BTW NOTHING HAPPENS
OIC
IM OUTTA YR RPMLOOP
FOUND YR MULTIPL
IF U SAY SO

MULTIPL R RPM X Y

VISIBLE "PRODUKT OF " N X N " N " N Y N " IZ " N MULTIPL N ":)"

KTHXBYE
• Fooba 2009-07-22 12:03
C implementation:

int russian(int a, int b) {int c=0,d=a^b;a*=(a<0)?-1:1;for(a<<=1;(a>>=1)!=0;b<<=1)c+=a&0x1?b:0;return((c^d)<0?-c:c);}

• koblas 2009-07-22 12:03
Another python version

```def mult(a, b) :
v = []
while a != 0 :
v.append((a % 2 != 0, b))
print a%2, a, b
a >>= 1
b <<= 1
print reduce(lambda x, y: x+y, [p[1] for p in v if p[0]])

```
• Bosshog 2009-07-22 12:06
```
;  6502 Assembler
;  Runs on NES, BBC, C64, Atari 2600 and Apple II :)
;  This is the 16-bit version to handle the example 18x23!

;  \$0002 contains unsigned 8-bit operand 1 (not preserved)
;  \$0004 contains unsigned 8-bit operand 2 (not preserved)
;  \$0001:0000 will contain HI:LO bytes of 16-bit answer

LDA #0
STA \$00
STA \$01
STA \$03
LDX #0
loop:
CPX \$04
BEQ done
CLC
LSR \$04
BCC skip

CLC
LDA \$00
STA \$00
LDA \$01
STA \$01
skip:
CLC
ASL \$02
ROL \$03
JMP loop
done:
```
• halber_mensch 2009-07-22 12:07
Josh Bohde:
halber_mensch:
Josh Bohde:
Python 2.6

`m=lambda a,b:sum(a<<n for n in range(b) if b>>n&1)`

51 characters

I'd argue it's not quite the russian algorithm though, since you've both reversed the operands and you are evaluating a-log2(a) more iterations than would be done in the real algorithm. For example, if I were to feed 5,4 into the russian algorithm, it would make 3 iterations (the left column being 5,2,1). Taking into account that you've swapped the parameters, your algorithm would evaluate 5 iterations (the left column being 5,2,1,0,0), or two more (5 - log2(5)) iterations than you should if you were adhering to the real algorithm, which stops evaluating when reaching 1 in the left column. Your solution also fails for negative values of a.

Yeah, I was saving some characters (at the cost of a lot of memory).

Here's a recursive version that is 48 characters

`m=lambda a,b:[0,b][a&1]+m(a>>1,b<<1)if a else 0`

m(-1,2)
....
File "<stdin>", line 1, in <lambda>
File "<stdin>", line 1, in <lambda>
RuntimeError: maximum recursion depth exceeded

=(

• Timepass 2009-07-22 12:08
```package com.timepass;

public class RussianMultiply {

private int mulTotal = 0;
RussianMultiply(){
super();
}
private void multiply(int first,int second, boolean isFirstTime){
if(first == 0 || second ==0){
return;
}
if(isFirstTime && first%2!=0){
mulTotal = mulTotal + second;
}
int tempFirst = first/2;
int tempSecond = second*2;
if(tempFirst%2!=0){
mulTotal = mulTotal + tempSecond;
}
if(tempFirst != 1){
multiply(tempFirst,tempSecond,false);
}
}
public void multiply(int first,int second){
multiply(first,second,true);
}

public void clearMulTotal(){
setMulTotal(0);
}

public int getMulTotal() {
return mulTotal;
}
public void setMulTotal(int mulTotal) {
this.mulTotal = mulTotal;
}

/**
* @param args
*/
public static void main(String[] args) {
RussianMultiply rm = new RussianMultiply();

rm.clearMulTotal();
rm.multiply(18, 23);
System.out.println("Multiplication of 18 and 23:" + rm.getMulTotal());

rm.clearMulTotal();
rm.multiply(13, 13);
System.out.println("Multiplication of 13 and 13:" + rm.getMulTotal());

}

}

```

result:
Multiplication of 18 and 23:414
Multiplication of 13 and 13:169
• chriswatson 2009-07-22 12:08
C# using the delightful LINQ to objects

```using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace RussianPeasantMultiplication
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine("Russian Peasant Multiplication");

Console.Write("Number 1: ");
Console.Write("Number 2: ");

List<Gimley> steps = new List<Gimley>();

Console.WriteLine("Mutiply {0} by {1}", number1, number2);

while (steps.Last().Left != 1)
{
Gimley lastStep = steps.Last();

int newLeft = lastStep.Left / 2;
int newRight = lastStep.Right * 2;

Console.WriteLine("Interim step: {0}, {1}", newLeft, newRight);
}

// discard even lefts and sum remaining rights
decimal answer = (from g in steps
where g.Left % 2 != 0
select g.Right).Sum();

}

class Gimley
{
public int Left { get; set; }
public int Right { get; set; }

public Gimley(int left, int right)
{
Left = left;
Right = right;
}
}
}
}
```
• Jürgen 2009-07-22 12:11
Alex thats nice, and very similiar to my ruby/python versions, except where summarization occurs.

I didn't bother with the 3rd acc parameter because
ruby/python don't do tail-end optimization on recursive calls any way.

That's probably why many diss recursive solutions,
but my profiler tells me theres little difference especially if you compare to solutions using python list comprehensions or ruby's .each iteration.

• Anonymous 2009-07-22 12:11
NO U!
• Rob W. 2009-07-22 12:12
#!/usr/bin/env python
import sys

try:
sys.argv[1]
sys.argv[2]
except IndexError:
numbers = raw_input("Please enter the two integers you wish to multiply separated by a space: ").split(' ')
else:
numbers = sys.argv[1:3]

left = int(numbers[0].strip())
right = int(numbers[1].strip())
product = 0

while left != 0:
if left % 2 != 0:
product += right
left /= 2
right*= 2

print "The product of " + numbers[0].strip() + " x " + numbers[1].strip() + " is " + str(product)
• serg 2009-07-22 12:13
Some thoughts...

------------8<-------------------
int mult(int a, int b) {
int result = 0;

while(a) {
if(a & 0x01) {
result += b;
}

a >>= 1;
b <<= 1;
}

return result;
}
------------8<-------------------
int mult2(int a, int b) {
int result = 0;

if(a != 0) {
result = mult2(a >> 1, b << 1);

if(a & 0x01) {
result += b;
}
}

return result;
}

• Jannik Jochem 2009-07-22 12:13
My functional-style java version...

```public static int multiply(int a, int b) {
if (a == 0 || b == 0)
return 0;
else if (a == 1)
return b;
else
return multiply(a/2, b*2) + ((a % 2 == 1) ? b : 0);
}
```
• Osno 2009-07-22 12:14
All the people who don't know what an optimizing compiler is also fail.

So you're basically agreeing with the " a * b " solution? Because defining multiplication by using multiplication is kind of weird (ok, I agree is in the spec, but anyway).

And no, when you're using rounding in vb.net (or the "\" operator) I can assure you that doesn't get optimized. And C# doesn't get optimized, at least not in IL (but maybe at the JIT level).
• wolf550e 2009-07-22 12:14
http://www.phy6.org/outreach/edu/roman.htm

This is not a Russian method but an ancient Roman one.
• tirerim 2009-07-22 12:17
```#!/usr/bin/perl
use integer;(\$a,\$b)=@ARGV;while(\$a){\$a%2and\$r+=\$b;\$a/=2;\$b*=2;}print \$r;```

I admit that this takes a bit of a shortcut: it checks each pair of numbers as it comes up, and adds the second to the result if necessary at that time, rather than saving them all and waiting for the end.

For anyone who really likes whitespace:
```#!/usr/bin/perl
use integer;
(\$a, \$b) = @ARGV;
while (\$a) {
\$a % 2 and \$r += \$b;
\$a /= 2;
\$b *= 2;
}
print \$r;
```

• SimonY 2009-07-22 12:17
let peasant a b =
let rec peasant a b acc =
if a = 1 then b + acc else
match a%2 with
| 0 -> peasant a/2 b*2 acc
| 1 -> peasant a/2 b*2 acc+b
in peasant a b 0
• Dave Havlicek 2009-07-22 12:18
ruby:

```class Fixnum

def *(num)
cols = Array.new
cols.push([self, num])
while cols.last[0] != 1 do
cols.push([cols.last[0] / 2, cols.last[1] + cols.last[1]])
end
cols.inject(0) { |sum, n| (n[0] % 2 == 1) ? sum + n[1] : sum }
end
end```
• Thuktun 2009-07-22 12:19
Well, that's freakishly easy.

```public class RussianPeasantMultiplication {
public static int multiply(int left, int right) {
int sum = 0;
while (left > 0) {
System.out.println("left=" + left + " right=" + right);
if ((left & 1) == 1) { // if odd
sum += right; // collect this row
}
left >>= 1; // divide by two
right <<= 1; // multiply by two
}
return sum;
}

public static void main(String[] args) {
int left = Integer.parseInt(args[0]);
int right = Integer.parseInt(args[1]);
int result = multiply(left, right);
System.out.println("result=" + result);
}
}

left=18 right=23
left=9 right=46
left=4 right=92
left=2 right=184
left=1 right=368
result=414```
• JoLoCo 2009-07-22 12:23
Here, for the sake of it, is a Sinclair BASIC version.

```10 LET a=18: LET b=23
20 LET tot=0
30 IF a<0 THEN LET a=0-a: LET b=0-b
40 IF (a/2) <> INT (a/2) AND a>0 THEN LET tot=tot+b
50 LET a= INT (a/2)
60 LET b=b*2
70 IF a>0 THEN GO TO 40
80 PRINT tot
```

Is this the first entry to feature line numbers?
• Patrick Simpson 2009-07-22 12:23
An F# quicky:

```let rec RussianPeasantMultiplication a b =
if a < 0 then -(RussianPeasantMultiplication (-a) b)
else (if a % 2 = 1 then b else 0) + (if a > 1 then RussianPeasantMultiplication (a / 2) (b * 2) else 0)```
• idle 2009-07-22 12:24
untested Java, quick and dirty...

public static int mult(int x, int y){

Integer x1 = new Integer(x);
int result = 0;

for(int i = 0; i < Integer.toBinaryString(x1).length(); i++){
if(Integer.toBinaryString(x1).endsWith("1"))
result += y * (int)Math.pow(2, i);
x1 = Integer.rotateRight(x1, 1);
}
return result;
}
• halber_mensch 2009-07-22 12:25
Extrapolated from discussion with Josh Bohde:

m=lambda a,b:b*(a&1)+m(a>>1,b<<1) if abs(a)>1 else a*b

55 chars... not as short but handles all integers.
• Noah Easterly 2009-07-22 12:25

```let peasantMultiply a b = f a b 0
where f a b s | a < 0 = f (negate a) (negate b) s
| a == 0 = s
| otherwise =
let (a',r) = a `divMod` 2 in
f a' (2*b) (if r == 1 then s + b else s)
```
• klagdon 2009-07-22 12:26
Accounts for either argument being zero, also throws an exception if trying to multiply a negative number. Tested with given main() method
```    public static long multiply(long first, long second) {
if(first < 0 || second < 0) {
throw new IllegalArgumentException("May only multiply positive numbers");
} else if(first == 0 || second == 0) {
return 0;
} else if(first == 1) {
return second;
} else if(first % 2 == 1) {
return second + multiply(first / 2, second * 2);
} else {
return multiply(first / 2, second * 2);
}
}

public static void main(String[] args) {
Random r = new Random();
for(int i = 0 ; i < 1000000 ; i++) {
long first = (long)Math.abs(r.nextInt());
long second = (long)Math.abs(r.nextInt());
if((first * second) != multiply(first,second)) {
System.out.println("Failed for " + first + " * " + second + "\t" + (first * second) + "\t" + multiply(first,second));
}
}
}
```
```def russian_mult(l, r):
"""Use Russian-peasant multiplication method.  They don't understand zero
or negative numbers very well, according to the description.  We fix that
with simple rules.  If left side has negative sign, change sign of result.   tdwtf at chad org
"""

rows = list()
rows.append((l, r))
while abs(l) > 1:
l = l // 2
r = r * 2
rows.append((l, r))

if l < 0:
return 0 - sum(r for l, r in rows if l%2==1)
else:
return sum(r for l, r in rows if l%2==1)
```

• Dave van der Brugge 2009-07-22 12:26
So many nice solutions, yet nobody has offered a solution using XSLT yet.

So here is mine. The xsl and xml code can be seen here:
http://damastabrain.mine.nu/RPA/highlight.php
For a better highlight function (at least Firefox), view the xsl itself:
http://damastabrain.mine.nu/RPA/russianPeasantAlgorithm.xsl
And ofcourse to show the outcome:
http://damastabrain.mine.nu/RPA/russianPeasantAlgorithm.xml

Note: it Does work with negative numbers, on either one of the two or both sides. (Integer only)
• jjs105 2009-07-22 12:28
```function russian_multiply_true_lookup (left, right) {

if (left == 0) return 0;
if (left == 1) return right;

var lookup = [{left: left, right: right}];

while (left > 1) {
left = Math.floor(left / 2);
right = right * 2;
lookup.push({left: left, right: right});
}

var result = 0;

for (var index = 0; index < lookup.length; index++)
if (lookup[index].left % 2 == 1)
result += lookup[index].right;

return result;
}

```
• darklajid 2009-07-22 12:29
Forget about the sticker, I played a lot with F# today. Thanks for the motivation.

```let russianMultiplication x y =
let rec l a b = seq { yield (a, b); yield! l (a>>>1) (b<<<1) }
l x y |> Seq.takeWhile (fun c -> fst c > 0) |> Seq.fold (fun acc (x,y) ->
if x % 2 = 1 then acc + y else acc
) 0
```
• imhe 2009-07-22 12:31
Accounts for 0 and negative numbers, tested with main
//Earlier posted as guest, now posting as member}
```package com.timepass;

public class RussianMultiply {

private int mulTotal = 0;
private boolean isMulTotalNegative = false;
RussianMultiply(){
super();
}
private void multiply(int first,int second, boolean isFirstTime){
// if any number 0 return
if(first == 0 || second ==0){
return;
}
//check for negative numbers
if(isFirstTime){

if(first < 0 && second < 0) {
isMulTotalNegative = false;
first = first*-1;
second = second * -1;
}
if(first < 0){
isMulTotalNegative = true; first = first*-1;
}
if(second < 0){
isMulTotalNegative = true;second = second * -1;
}
}
// first time and odd number add to total
if(isFirstTime && first%2!=0){
mulTotal = mulTotal + second;
}

// 1st column not even , add to total
int tempFirst = first/2;
int tempSecond = second*2;
if(tempFirst%2!=0){
mulTotal = mulTotal + tempSecond;
}
// first colum not 1, do it again
if(tempFirst != 1){
multiply(tempFirst,tempSecond,false);
}
}
public void multiply(int first,int second){
multiply(first,second,true);
}

public void clearMulTotal(){
setMulTotal(0);
}

public int getMulTotal() {
if(isMulTotalNegative()){
return -1*this.mulTotal;
}
return this.mulTotal;
}
public void setMulTotal(int mulTotal) {
this.mulTotal = mulTotal;
}

/**
* @param args
*/
public static void main(String[] args) {
RussianMultiply rm = new RussianMultiply();

rm.clearMulTotal();
rm.multiply(18, 23);
System.out.println("Multiplication of 18 and 23:" + rm.getMulTotal());

rm.clearMulTotal();
rm.multiply(13, 12);
System.out.println("Multiplication of 13 and 12:" + rm.getMulTotal());

rm.clearMulTotal();
rm.multiply(12, 12);
System.out.println("Multiplication of 12 and 12:" + rm.getMulTotal());

rm.clearMulTotal();
rm.multiply(-12, -12);
System.out.println("Multiplication of -12 and -12:" + rm.getMulTotal());

rm.clearMulTotal();
rm.multiply(-12, 12);
System.out.println("Multiplication of -12 and 12:" + rm.getMulTotal());

}
public boolean isMulTotalNegative() {
return isMulTotalNegative;
}
//	public void setMulTotalNegative(boolean isMulTotalNegative) {
//		this.isMulTotalNegative = isMulTotalNegative;
//	}

}

```

Multiplication of 18 and 23:414
Multiplication of 13 and 12:156
Multiplication of 12 and 12:144
Multiplication of -12 and -12:144
Multiplication of -12 and 12:-144
• Codism 2009-07-22 12:32
Yet another Linq solution:
public static int rpm(int a, int b)
{
return Enumerable.
Range(0, a < 2 ? 1 : (int)Math.Ceiling(Math.Log(a % 2 == 0 ? a + 1 : a, 2)))
.Select(i => new { L = a / (1 << i), R = b * (1 << i) })
.Where(x => x.L % 2 != 0).Sum(x => x.R);
}
• Anonymous 2009-07-22 12:32
I've never seen a comments page fill up so quickly (at least, not with legitimate and well thought out comments). This has been a rousing success!
This is PHP, although it probably works as Perl too.

```	\$a = 18;
\$b = 23;

for (\$t = 0; \$a > 0; \$a >>= 1, \$b <<= 1)
\$t += ((\$a % 2) * \$b);

echo "total: \$t\n";
```
• Albrecht from Germany 2009-07-22 12:36
# This one ist Tcl/Tk http://www.tcl.tk
proc russ {a b} {
set erg 0
if {\$a < 0} {
set a [expr {-1 * \$a}]
set b [expr {-1 * \$b}]
}
for {} {\$a} {} {
if {\$a&1} {
incr erg \$b
puts [format %5d%5d%5d \$a \$b \$erg]
} else {
puts [format %5d%5d \$a \$b ]
}
set a [expr {\$a >> 1}]
set b [expr {\$b << 1}]
}
puts "==========[format %5d \$erg] ======="
return \$erg
}
russ 18 23
• Jim Halfpenny 2009-07-22 12:37
Here's the 'schoolbook' perl version to demonstrate recusive fuctions. No fancy operators, indentation where appropriate and variable names which provide no description of that they do. And of course no comments.

It's kind of beautiful.

print axb(\$ARGV[0],\$ARGV[1]) . "\n";
sub axb {
my \$a = shift;
my \$b = shift;
my \$total = 0;
if (\$a == 1) {
return \$b;
} else {
if (\$a % 2) {
\$total += \$b;
}
\$ah = int(\$a / 2);
\$bh = \$b * 2;
return \$total + axb(\$ah,\$bh);
}
}
• leppie 2009-07-22 12:38
People still using * directly.

That's cheating yourself!

Try harder!
• Albrecht from Germany 2009-07-22 12:40
```# This one ist Tcl/Tk http://www.tcl.tk
# now with indentation
proc russ {a b} {
set erg 0
if {\$a < 0} {
set a [expr {-1 * \$a}]
set b [expr {-1 * \$b}]
}
for {} {\$a} {} {
if {\$a&1} {
incr erg \$b
puts [format %5d%5d%5d \$a \$b \$erg]
} else {
puts [format %5d%5d \$a \$b ]
}
set a [expr {\$a >> 1}]
set b [expr {\$b << 1}]
}
puts "==========[format %5d \$erg] ======="
return \$erg
}
russ 18 23
```
• Bob Montgomery 2009-07-22 12:40
Bosshog:
```	;  6502 Assembler (4-bit operands only)
;  \$0001 should contain operand 1 (not preserved)
;  \$0002 should contain operand 2 (not preserved)

LDA #0
LDX #0
loop:
CPX \$02
BEQ done
CLC
LSR \$02
BCC skip
CLC
skip:
ASL \$01
JMP loop

done:
STA \$00
```

You beat me to the punch, but there is some unnecessary code in there (you don't need to clear the carry before a LSR). And trashing X is unnecessary since you can test for zero just as fast with LDA \$02. Or with some crazy jujitsu to save a byte...
Here's my version, handles 8-bit operands:
```;--\$00 holds operand 1
;--\$01 (low byte) and \$02 (high byte) hold operand 2
;--\$03 (low byte) and \$04 (high byte) hold product
cld
Loop
lsr \$00
clc
lda \$03
sta \$03
lda \$04
sta \$04
.byte \$2C
beq Done
asl \$01
rol \$02
bcc Loop	;this assumes that operand 2 is 8-bit
Done```
• Jared Youtsey 2009-07-22 12:41
public static double Multiply(long left, long right)
{
Recurse(left, right);
var result = 0D;
foreach (var row in table)
{
result += row.Value;
}

return result;
}

public static void Recurse(long left, long right)
{
var newLeft = (long)(left / 2);
var newRight = right * 2;
if (newLeft != 1)
{
Recurse(newLeft, newRight);
}
}

private static void AddRecord(long newLeft, long newRight)
{
long remainder;
var ignored = Math.DivRem(newLeft, 2L, out remainder);
if (remainder != 0)
{
Console.WriteLine("left = " + newLeft + "\tright = " + newRight);
}
}
• acsi 2009-07-22 12:42

First number goes in A2
A3 through A41 have "=TRUNC(A2/2)", "=TRUNC(A3/2)", etc (enter in A3, drag lower-right corner to expand to full range, in Excel at least the formulas in the additional cells will be adjusted to keep the relative positions of the referenced cells the same).

Second number goes in B2
B3 through B41 have "B2*2", "B3*2", etc.

C2 through C41 have "=IF(MOD(A2, 2) = 1, B2, 0)", "=IF(MOD(A3, 2) = 1, B3, 0)", etc.

D2 has "=SUM(C2:C41)", and is the result.

A1 through D1 have headers "First Number", "Second Number", "Cross out where A is even", and "Result".

This function can be called by using the MSOffice interop libraries to open the spreadsheet, populate A2 and B2, and read D2 (there might be another step in between to tell it to run the actual calculation, I forget).
• amischiefr 2009-07-22 12:43
Just my own little recursive Java solution:
```	private int multiply(int n, int m, int val) {
if(n <= 1)
return val;
return multiply(n/2,m*2,((n/2)%2!=0 ? val+=m*2 : val) );
}

And of course, the ternary one liner:

private int multiplyOneLiner(int n, int m, int val) {
return (n <= 1 ? val : multiply(n/2,m*2,((n/2)%2!=0 ? val+=m*2 : val) ));
}
```
• Osno 2009-07-22 12:43
MSIL:

.method private hidebysig static int64 Multiply(int64 f, int64 s) cil managed
{
.maxstack 3
start:
ldarg.0
dup
ldc.i4.0
beq.s done
ldc.i4.1
and
ldarg.1
mul
next:
ldarg.0
ldc.i4.1
shr
ldarg.1
ldc.i4.1
shl
call int64 RussianMult.Program::Multiply(int64, int64)
done:
ret
}
• Lunkwill 2009-07-22 12:44
As we haven't had any m68k yet:

```; op1: d0
; op2: d1
; out: d0
; scratch: d2
peasantmult:
clr.l	d2
.loop:	tst.l	d0
beq.s	.exit
lsr.l	d0
bcc.s	l
asl.l	d1
bra.s	.loop
.exit:	move.l	d2,d0
rts```

20 bytes in binary :)
• Jared Youtsey 2009-07-22 12:45
After looking at some of the other solutions I realize that I don't do this kind of programming and why. This kind of boolific bitshifty goodness is brain melting. But it was fun. But boy am I shamed by the cleverness of many of the other solutions.
• HonoredMule 2009-07-22 12:46
This revision of The Wolf's PHP solution handles negative numbers and displays the columns in a table with unused rows crossed out.

```<?php

function visual_russian(\$x, \$y) {
\$left = array();
\$right = array();
\$str = "<table><th><tr><td><em>Operand:<br />\$x</em></td><td><em>Operator:<br />\$y</em></td></tr></th><tbody>";

\$sign = 1;
if(\$x < 0) {
\$sign *= -1;
\$x = abs(\$x);
}
if(\$y < 0) {
\$sign *= -1;
\$y = abs(\$y);
}

while (\$x >= 1) {
\$left[] = \$x;
\$right[] = \$y;
if(\$x % 2)
\$str .= "<tr><td><s>\$x</s></td><td><s>\$y</s></td></tr>";
else
\$str .= "<tr><td>\$x</td><td>\$y</td></tr>";
\$x = floor(\$x / 2);
\$y *= 2;
}

\$result = 0;
foreach (\$left as \$index => \$x) if (\$x % 2)
\$result += \$right[\$index];
\$result = \$sign * \$result;
return \$str;
}

echo visual_russian(156657, -159643248);

?>
```
• Alex Muscar 2009-07-22 12:47
Common Lisp:

No multiplication.
```(defun rpm (m n)
(do ((t1  m (ash t1 -1))
(t2  n (ash t2 1))
(r 0))
((= t1 0)  r)
(when (= (logand t1 1) 1)
(incf r t2))))
```

The parens might be unbalanced since I'm writing this from my phone.
• David C. 2009-07-22 12:47
33 characters in C#:

(a,b)=>a==1?b:m(a/2,b*2)+b*(a&1);

Implementing this lambda expression in code is left as an exercise for the reader (hint: assign it to a delegate named 'm')
• HonoredMule 2009-07-22 12:50
Reading many of these ingenious, esoteric, or even simple and straight-forward implementations in various languages makes me very happy that I don't often have to use languages other than PHP.
• Jörg 2009-07-22 12:50
A slightly more sophisticated python version:
```def peasant_mul(a,b):
def numbers(a=a, b=b):
if a < 0:
a, b =  -a, -b
while a:
if a & 1:
yield b
a >>= 1
b <<= 1
return sum(numbers())
```

why is code double-spaced or is that my firefox?
• Josh Bohde 2009-07-22 12:51
halber_mensch:
Extrapolated from discussion with Josh Bohde:

m=lambda a,b:b*(a&1)+m(a>>1,b<<1) if abs(a)>1 else a*b

55 chars... not as short but handles all integers.

Just because I think using * isn't in the spirit of this.

```m=lambda a,b:[0,b][a&1]+m(a>>1,b<<1)if a else 0
n=lambda a,b:(lambda n,t:[n,~n+1][t])((m(abs(a),abs(b))),(a<0)^(b<0))```

n will handle negatives.
118 characters, including newline.
• HonoredMule 2009-07-22 12:52
One last tweak: forgot to switch the floor(\$x / 2) for a bit shift.

```<?php

function visual_russian(\$x, \$y) {
\$left = array();
\$right = array();
\$str = "<table><th><tr><td><em>Operand:<br />\$x</em></td><td><em>Operator:<br />\$y</em></td></tr></th><tbody>";

\$sign = 1;
if(\$x < 0) {
\$sign *= -1;
\$x = abs(\$x);
}
if(\$y < 0) {
\$sign *= -1;
\$y = abs(\$y);
}

while (\$x >= 1) {
\$left[] = \$x;
\$right[] = \$y;
if(\$x % 2)
\$str .= "<tr><td><s>\$x</s></td><td><s>\$y</s></td></tr>";
else
\$str .= "<tr><td>\$x</td><td>\$y</td></tr>";
\$x = \$x >> 1; //floor(\$x / 2);
\$y *= 2;
}

\$result = 0;
foreach (\$left as \$index => \$x) if (\$x % 2)
\$result += \$right[\$index];
\$result = \$sign * \$result;
return \$str;
}

echo visual_russian(156657, -159643248);

?>
```
• DaMastaBrain 2009-07-22 12:53
Dave van der Brugge:
So many nice solutions, yet nobody has offered a solution using XSLT yet.

So here is mine. The xsl and xml code can be seen here:
http://damastabrain.mine.nu/RPA/highlight.php
For a better highlight function (at least Firefox), view the xsl itself:
http://damastabrain.mine.nu/RPA/russianPeasantAlgorithm.xsl
And ofcourse to show the outcome:
http://damastabrain.mine.nu/RPA/russianPeasantAlgorithm.xml

Note: it Does work with negative numbers, on either one of the two or both sides. (Integer only)

Also it now works with 0 on any side.
• semanticprecision 2009-07-22 12:54
Obligatory solution from a Haskell neophyte:

``` rpMultiply a b =
( sum . map snd . filter ( odd . fst ) ) ( zip ( takeWhile ( >= 1 ) a' ) b' )
where
a' = a : ( map ( `div` 2 ) a' )
b' = b : ( map ( (*)   2 ) b' )
```
• martinp 2009-07-22 12:55
Did this in Python, and it made me remember why I like it so much.

```def rp_multiply(m, n):
sum = 0
while m >= 1:
if m % 2 != 0:
sum += n
n *= 2
m /= 2;
return sum```

• hornet 2009-07-22 12:59
long rmultiply(long a, long b)
{
return (a==1)?b:((a&1)?b:0)+rmultiply(a>>1,b<<1);
}
• Cindi Knox 2009-07-22 12:59
mIRC
```alias productRussianPeasant {
;multiplies two integers using Russian Peasant method
;parms: multiplier, multiplicand
;returns: product
var %lMultiplier
var %lMultiplicand
var %lProduct

;use minimum iterations - smaller parm goes in multiplier:
if (\$1 < \$2) {
%lMultiplier = \$1
%lMultiplicand = \$2
}

else {
%lMultiplier = \$2
%lMultiplicand = \$1
}

;clear product accumulator:
%lProduct = 0

while (%lMultiplier > 0) {
if (\$calc(%lMultiplier % 2) > 0) {
;multiplicans counts toward product if multiplier is odd:
%lProduct = \$calc(%lProduct + %lMultiplicand)
}
%lMultiplier = \$int(\$calc(%lMultiplier / 2))
%lMultiplicand = %lMultiplicand * 2
}

return %lProduct
}

```
• Bored 2009-07-22 12:59
```int rmul(auto a, auto b) {
auto sum=0,target=a*b;
while(sum!=target) {
sum += a&1?b:0, a>>=1, b<<=1;
}
return sum;
}
```

I like it since it does the builtin multiply anyway, and then the calculation. NB: infinite loops may happen with -ve numbers.
• xtremezone 2009-07-22 13:00
My implementation is in C (or C++).
```typedef unsigned long ulong;
ulong russian_peasant_mult(ulong x, ulong y)
{
ulong result = 0;
if(x == 0 || y == 0)
return 0;
if(x % 2 != 0)
result += y;
while(x != 1)
{
y *= 2;
if((x /= 2) % 2 != 0)
result += y;
}
return result;
}```

If you accuse me of initially using std::list and std::pair I'll deny it! Deny!
• Tim Pierce 2009-07-22 13:01
There is no language restriction, though anything on the esoteric language list will probably be ignored.

Including Perl? :-)
• DougB 2009-07-22 13:02
Quick Solution in Delphi. Accompanying form has a StdCtrls Memo to display columns named Memo1. Two edit boxes allow input of multiplicands (edit1 := Leftside, edit2 := Rightside). ClearValues simply clears the edit boxes and resets all totals. lblResult is a label displaying the result. This routine will not handle negative numbers.

procedure TForm1.ComputeRpProduct;
var
vTotal : Integer;

{SUB}
begin
if (Leftside mod 2) <> 0 then
begin
Memo1.Lines.Add(inttostr(Leftside) + ' ' + inttostr(RightSide));
vTotal := vTotal + Rightside;
end
else
begin
Memo1.Lines.Add(inttostr(Leftside) + ' ' + inttostr(RightSide) + ' ---');
end;
end;
{/SUB}

begin
if (Leftside <> 0) and (Rightside <> 0) then
begin

vTotal := 0;

while Leftside <> 1 do
begin

Leftside := Leftside div 2;
Rightside := Rightside * 2;

end;

lblResult.Caption := IntToStr(vTotal);

end
else
begin
ShowMessage('Please enter numeric nonzero values to compute.');
ClearValues;
Edit1.setfocus;
end;

end;
• mucki.at 2009-07-22 13:06
I didn't read all the comments but this is also called "Shift and Add" in information processing, and this is typically how computers actually implement multiply. Thus, I propose this "hardware accelerated" version of the algorithm:

return a*b;

• HonoredMule 2009-07-22 13:07
I missed a lot previously...enough to make me register so I can erase evidence of future blunders. This PHP handles negative numbers, outputs an HTML table with the unused rows crossed out, and is derived from the code posted by The Wolf on page one of the comments:

```<?php

function visual_russian(\$x, \$y) {
\$str = "<table><th><tr><td><em>Operand:<br />\$x</em></td><td><em>Operator:<br />\$y</em></td></tr></th><tbody>";
\$result = 0;

\$sign = 1;
if(\$x < 0) {
\$sign *= -1;
\$x = abs(\$x);
}
if(\$y < 0) {
\$sign *= -1;
\$y = abs(\$y);
}

while (\$x > 1) {
\$x = \$x >> 1;
\$y *= 2; // Bit-shifting \$y causes overflow, but multiplication does not.
if(\$x % 2) {
\$str .= "<tr><td><s>\$x</s></td><td><s>\$y</s></td></tr>";
} else {
\$str .= "<tr><td>\$x</td><td>\$y</td></tr>";
\$result += \$y;
}
}
return \$str;
}

echo visual_russian(156657, -159643248);

?>
```
• David Young 2009-07-22 13:07
int russian_peasant(int n1, int n2) {
int product = 0, sign = 1;

if(n1 < 0) {
sign = -1;
}

for(; n1 != 0; n1 /= 2, n2 *= 2) {
if(n1 & 1) {
product += n2;
}
}

return product * sign;
}
• wombat 2009-07-22 13:08
Recursive Common Table Expression in MS SQL Server:

WITH russian
AS (
SELECT 45 a, 76 b
UNION ALL
SELECT a / 2, b + b
FROM russian
WHERE a > 1)
SELECT ISNULL(SUM(b), 0) AS product
FROM russian
WHERE a & 1 = 1
• Haggis 2009-07-22 13:10
C++ using for loop

for(int a=3,b=5,c=0;a>0;c+=(a&1?b:0),a>>=1,b<<=1,std::cout<<c<<std::endl);
• xtremezone 2009-07-22 13:10
xtremezone:
My implementation is in C (or C++).
```typedef unsigned long ulong;
ulong russian_peasant_mult(ulong x, ulong y)
{
ulong result = 0;
if(x == 0 || y == 0)
return 0;
if(x % 2 != 0)
result += y;
while(x != 1)
{
y *= 2;
if((x /= 2) % 2 != 0)
result += y;
}
return result;
}```

If you accuse me of initially using std::list and std::pair I'll deny it! Deny!
I wrongly assumed it only worked for positive integers so I used unsigned types. :-[ Here's a quick fix.
```long russian_peasant_mult(long x, long y)
{
int negative = 0;
long result = 0;
if(x == 0 || y == 0)
return 0;
if(x < 0 && y > 0)
{
x *= -1;
negative = 1;
}
else if(x > 0 && y < 0)
{
y *= -1;
negative = 1;
}
if(x % 2 != 0)
result += y;
while(x != 1)
{
y *= 2;
if((x /= 2) % 2 != 0)
result += y;
}
if(negative)
result *= -1;
return result;
}
```
• hornet 2009-07-22 13:12
Supporting negative numbers:
long multiply(long a, long b)
{
return (a<0)?-multiply(-a,b):(a==1)?b:((a&1)?b:0)+multiply(a>>1,b<<1);
}
• anonymous 2009-07-22 13:12
In JavaScript
var s = 7 * 38;

The binary approach is taken behind the scenes.
• JJM 2009-07-22 13:13
```def multiply(a,b):
c=0
while a>1:
a >>= 1
b <<= 1
c += b*(a&1)
return c
```
• Trey Jackson 2009-07-22 13:14
common lisp from Emacs:

(defun mymult (nn mm)
(loop for n = nn then (/ n 2)
for m = mm then (* m 2)
until (< n 1)
sum (if (oddp n) m 0)))
• IcePanther 2009-07-22 13:14
Solution in PHP :

function peasant(\$a,\$b)
{
\$s = 0;
while(\$a > 1)
{
\$b *= 2;
\$a = floor(\$a/2);
if((\$a % 2) != 0) { \$s += \$b; }
}

return \$s;
}

Could probably be made more efficient by using bitwise operations instead of base mathematical operators. Well, would obviously be more efficient NOT being written in PHP, too.
• Tim 2009-07-22 13:15
My recursive PHP CLI version. (Inputs must be >0)
The output will create the table as shown in the instructions and even cross out the even rows.

```<?php

{
\$even = (\$x % 2 == 0);

if (\$even) {
} else {
}

if (abs(\$x) == 1) {
return \$y;
}

if (!\$even) {
} else {
}

}

\$x = \$argv[1];
\$y = \$argv[2];

if (\$x <= 0 || \$y <= 0) {
echo 'Usage: ' . \$argv[0] . ' x y' . "\n"
. 'Both x and y must be greater than 0' . "\n";
exit;
}

```
• Osno 2009-07-22 13:16
Non-recursive MSIL, more stack-based:

.method private hidebysig static int64 m(int64 f, int64 s) cil managed
{
.maxstack 4
ldc.i4.0
conv.i8
start:
ldarg.0
ldc.i4.0
beq.s done
ldarg.0
ldc.i4.1
and
ldarg.1
mul
ldarg.0
ldc.i4.1
shr
starg.s 0
ldarg.1
ldc.i4.1
shl
starg.s 1
br.s start
done:
ret
}
• Andrew Nurse 2009-07-22 13:16
This was perfectly timed, since I'm learning Haskell. It gave me the perfect opportunity to try out what I've learned so far :). So to add to the already numerous Haskell solutions, here's mine (I noticed it looked similar to others, so I guess I'm getting the hang of this functional programming thing :D):

```russianMult :: (Integral a) => a -> a -> a
russianMult 1 y = y
russianMult x y = if x `mod` 2 == 0 then
multStep
else
multStep + y
where multStep = russianMult (x `div` 2) (y * 2)
```

I'm sure there's more concise ways to do this, but this works :).
• Igor V. 2009-07-22 13:17
Unobfuscated Perl:
```sub russian_peasant_multiply {
my (\$one, \$two) = @_;
my \$rus = 0;
do {
\$rus += \$two if (\$one & 1);
} while (\$one >>= 1 and \$two <<= 1);
return \$rus;
}```
• jeff.woodhull 2009-07-22 13:22
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
var leftNum = 0;
var rightNum = 0;

if (args.Length != 2 || (!Int32.TryParse(args[0], out leftNum) || ! Int32.TryParse(args[1], out rightNum)))
{
Console.WriteLine("Please enter numbers like ConsoleApplication1.exe 5 10");
return;
}

var answer = (from p in RussianPairs(leftNum, rightNum)
where p.Left % 2 != 0
select p.Right).Sum();

Console.WriteLine("Press <enter> to exit");
}

static IEnumerable<Pair> RussianPairs(int leftNumber, int rightNumber)
{
while (leftNumber >= 1)
{
yield return new Pair(leftNumber, rightNumber);
leftNumber /= 2;
rightNumber *= 2;
}
}

internal class Pair
{
internal Pair(int left, int right)
{
Left = left;
Right = right;
}

internal int Left { get; private set; }
internal int Right { get; private set; }
}
}
}
• Tyler 2009-07-22 13:23
• It'sMe (It_sMe@jabber.org) 2009-07-22 13:24
non recusive version in c# with 64bit in because russians love big numbers right?

```private static Int64 RussianPeasantMultiplication(Int64 first, Int64 second)
{
Int64 rvalue = 0;

while(first > 0)
{
if(first % 2 != 0)
{
rvalue += second;
}
first /= 2;
second *= 2;
}

return rvalue;
}
```
• Mike5 2009-07-22 13:27
Anonymous Coward:
Prolog:

rusmul(0,_,0).
rusmul(A,B,X) :- C is A//2, D is B*2, rusmul(C,D,E), X is E+(A mod 2)*B.

"optimized" with bit-shifting

```russian( 0, _, 0 ).

russian( A, B, C ) :-
A /\ 1 =:= 1,
B1 is B << 1,
A1 is A >> 1,
russian( A1, B1, C1 ),
C is C1 + B.

russian( A, B, C ) :-
B1 is B << 1,
A1 is A >> 1,
russian( A1, B1, C ).
```
• xtremezone 2009-07-22 13:28
xtremezone:
I wrongly assumed it only worked for positive integers so I used unsigned types. :-[ Here's a quick fix.
```long russian_peasant_mult(long x, long y)
{
int negative = 0;
long result = 0;
if(x == 0 || y == 0)
return 0;
if(x < 0 && y > 0)
{
x *= -1;
negative = 1;
}
else if(x > 0 && y < 0)
{
y *= -1;
negative = 1;
}
if(x % 2 != 0)
result += y;
while(x != 1)
{
y *= 2;
if((x /= 2) % 2 != 0)
result += y;
}
if(negative)
result *= -1;
return result;
}
```
<sigh/> Accounted for one negative number, but not two... Fixed. :P Maybe.
```long russian_peasant_mult(long x, long y)
{
int negative = x < 0 && y > 0 || x > 0 && y < 0;
long result = 0;
if(x == 0 || y == 0)
return 0;
if(x < 0)
x *= -1;
if(y < 0)
y *= -1;
if(x % 2 != 0)
result += y;
while(x != 1)
{
y *= 2;
if((x /= 2) % 2 != 0)
result += y;
}
if(negative)
result *= -1;
return result;
}
```

Though the negative workarounds do use multiplication which may be a paradox of sorts... >_<

I suppose you could replace...
`x *= -1;`

...with...
`x -= russian_peasant_mult(x, 2);`

:P

No, no, wait, no you couldn't... Infinite recursion...
• Bob 2009-07-22 13:28
Scheme:

```(define (peasant* a b)
(do ([acc '() (if (odd? a)
(cons b acc)
acc)]
[a a (quotient a 2)]
[b b (+ b b)])
[(= a 1)
(fold + b acc)]))```

Assumes fold:

```(define (fold p x l)
(if (null? l)
x
(fold p
(p (car l) x)
(cdr l))))```

Easily done without the list, I thought it was more in keeping, though.
• Nick Pope 2009-07-22 13:29
After my earlier attempt with bc, I decided to try something more difficult: dc. Seems to work with negative numbers nicely too.

Using dc (GNU bc 1.06.95) 1.3.95:

Code (peasant.dc):

`sbsa0[la2~rsalbd2*sb*+0la!=r]dsrxp`

Examples:
```\$ dc -e  39 -e 83 peasant.dc
3237
\$ dc -e _45 -e 76 peasant.dc
-3420
```
• jonnyq 2009-07-22 13:32
Ok here's mine... in javascript, which has its limits
```function multiply(x,y) {
var z = 0;
if(x < 0) y = 0-y;
do {
if(x&1 != 0) z += y; // add to z if x is odd
x = (x>0?Math.floor:Math.ceil)(x/2); // halve x, drop remainder
y += y; // double y
} while(x != 0);
return z;
}```

Works for signed integers.

• Ronuk Raval 2009-07-22 13:32
Don't know if this has been done yet (probably has).

Naive recursive Python implementation:
```def mult(n1, n2):
if n1 == 1:
return n2
if n1 % 2 == 1:
return n2 + mult(n1 // 2, 2 * n2)
else:
return mult(n1 // 2, 2 * n2)
```

Faster, bit-oriented C89 version (handles negatives):
```long mult(int n1, int n2)
{
int sign = 1, place = 1;
long result = 0;

if(n1 < 0) {
sign *= -1;
n1 = -n1;
}
if(n2 < 0) {
sign *= -1;
n2 = -n2;
}

while(n1 > 0) {
if(n1 & 1) {
result += place * n2;
}
n1 >>= 1;
place <<= 1;
}

return sign * result;
}
```
• shane blake 2009-07-22 13:32
wombat:
Recursive Common Table Expression in MS SQL Server:

ya beat me to it, but here's my similar effort anyway :

;with russia(x, y) as
(
select 18, 23
union all
select x / 2, y * 2 from russia where x > 1
)
select sum(y)
from russia
where x % 2 <> 0
• MUMPS 2009-07-22 13:33
MUMPS:
```P(I,S)
S Q=I I I I S#2 S Q=0
Q Q+P(I\2,S*2)```

Features:
Shortened keywords!
Keywords reused for variable names!
Recursion!
Untested!
• Greg R 2009-07-22 13:35
Recursive Java, taking advantage of its Unicode support.

```public static int умножить(int Значение1, int Значение2) {
if(Значение1 == 1)
return Значение2;

int крестьянин  = умножить(Значение1 / 2, Значение2 * 2);
if(Значение1 % 2 == 1)
крестьянин += Значение2;

return крестьянин;
}
```
• aBase 2009-07-22 13:36
I cleaned-up the PHP function I posted earler. As before, it
- handles non-integers,
- handles negative numbers,
- doesn't choke on zero.
```function potemkin_multiply(\$two_numbers)
{
\$power = 0;
\$sign  = 1;
foreach (\$two_numbers as \$num) {
if (\$num == 0) {
return 0;
} elseif (\$num < 0) {
\$sign *= -1;
}
if ((\$len = strlen(strrchr(\$num, '.'))) > \$power) {
\$power = \$len - 1;
}
}
foreach (\$two_numbers as & \$num) {
\$num = abs(\$num * pow(10, \$power));
}
\$total = 0;
while (\$two_numbers[0] > 1) {
if (\$two_numbers[0] % 2) {
\$total += \$two_numbers[1];
}
\$two_numbers[0] = floor(\$two_numbers[0] / 2);
\$two_numbers[1] *= 2;
}
return ((\$total + \$two_numbers[1]) / pow(10, \$power * 2)) * \$sign;
}```
Test code:
```\$nums = array(0, -1, 1, 18, -23, 154., -229.5, 49.0, 389.99,
67.99999, -592.8729, .678, 0.00678);
for (\$i = 0; \$i < 50; \$i++) {
\$pair = array(\$nums[array_rand(\$nums)], \$nums[array_rand(\$nums)]);
\$russian = potemkin_multiply(\$pair);
\$orthodox = \$pair[0] * \$pair[1];
echo \$pair[0] . ' * ' . \$pair[1] . ' = <b>' . \$russian . '</b>';
if ((string) \$russian != (string) \$orthodox) {
echo ' <span style="color:red">(' . \$orthodox . ')</span>';
}
echo '<br />';
}```
• Jeremy Weathers 2009-07-22 13:37
Ruby solution:

```def rpm (first, second) # russian peasant multiplication
total = 0
while first > 0
total += second if 0 != first % 2
first = first / 2
second = second * 2
end
total
end```
• xtremezone 2009-07-22 13:39
jonnyq:
`y = 0-y;`
There's the solution I was looking for. :P
• Jonas Kramer 2009-07-22 13:46

```multiply = ((sum . map snd . filter (odd . fst)) .) . tuples
where
tuples 1 y = [(1, y)]
tuples x y = (x, y) : tuples (x `div` 2) (y * 2)
```
• Phroggy 2009-07-22 13:46
Here's mine, in HTML5, JavaScript and CSS!
• lostlogic 2009-07-22 13:49
Pythonic solution:
```def mult(a,b):
def g(a,b):
while a > 0:
yield a,b
a /= 2
b *= 2
return reduce(lambda x,y: x+y, [b for a,b in g(a,b) if a % 2 == 1])
```

Fixed for negatives and zeros.
```def mult(a,b):
a,b = (-a,-b) if a < 0 else (a,b)
def g(a,b):
while a > 0:
yield a,b
a /= 2
b *= 2
return sum([b for a,b in g(a,b) if a % 2 == 1])
```

Reduce memory usage at the cost of one line:
```def mult(a,b):
a,b = (-a,-b) if a < 0 else (a,b)
def g(a,b):
while a > 0:
if a % 2 == 1:
yield b
a /= 2
b *= 2
return sum(g(a,b))
```
• Darren 2009-07-22 13:51
```#!/usr/bin/perl
package russianPeasantMultiplier;
use strict; use warnings;

if (@ARGV < 2) { die "I take a list of numbers to multiply together - I need at least 2" }

my \$register = shift @ARGV;
while (@ARGV) {
\$register = multiply( \$register, shift @ARGV );
printf "Result: %6d\n", \$register;
}

sub multiply {
die "multiply() takes two integers" unless (
@_ == 2
&& \$_[0] == int(\$_[0])
&& \$_[1] == int(\$_[1])
);

my (\$left, \$right) = @_;
my %set;

my \$expected_result = \$left * \$right;

do {
\$set{\$left} = \$right;
\$left = int( \$left / 2 ); #deliberately throw away remainder
\$right = \$right * 2;
} until \$left == 1;
\$set{\$left} = \$right; # make sure the 1=>x pair is recorded

my \$result = 0;
foreach (keys %set) {
next if \$_ % 2 == 0;  # skip any set with an even number on the "left"
\$result += \$set{\$_};
}

warn "Result mismatch: expected \$expected_result, got \$result.\n" unless \$result == \$expected_result;
return \$result;
}
```
• Chewbie 2009-07-22 13:51
In ruby :

def russian_peasant(x, y)
return y if x/2 == 0
(x % 2 == 0) ? russian_peasant(x/2, y*2) : y + russian_peasant(x/2, y*2)
end

Not properly tested, but I think it should work.
• Qwertyuiopas 2009-07-22 13:53
Any time you use n = n * 2 or n *=2, n += n would work.
Any time you use n = n * -1 or n *= -1, n = -n would work.

Anyone using * for 2 or -1 has NO EXCUSE.
• David C. 2009-07-22 13:57
Rather than settle with one 33-character entry, I decided to add a more robust solution. This does 2 things my previous solution doesn't: it handles negatives. And it doesn't use b*2 for doubling. Or a/2 for halving. I figured, since I'm writing a multiplication function anyway, why not use that instead?

static int RecursiveMultiply(int a, int b)
{
if (a == 0 || b == 0)
return 0;

if (a == 1)
return b;

if (b == 1)
return a;

if (a == -1)
return -b;

if (b == -1)
return -a;

if (a == 2)
return b + b;

if (b == 2)
return a + a;

bool negA = a < 0;
bool negB = b < 0;

a = Math.Abs(a);
b = Math.Abs(b);

int halfA = 0;

for (int x = 0; x < a; x++)
if (RecursiveMultiply(x, 2) == a || RecursiveMultiply(x, 2) + 1 == a)
{
halfA = x;
break;
}

int retVal = RecursiveMultiply(halfA, RecursiveMultiply(b, 2)) + RecursiveMultiply(a & 1, b);

if (negA ^ negB)
return RecursiveMultiply(retVal, -1);

return retVal;
}
• Davi Cavalcanti 2009-07-22 13:57
public static int multiplicate(int num1, int num2) {
System.out.print("call: " + num1 + " * " + num2);
int result = num2;
int oddLineValuesSum = 0;
while (num1 > 1) {
if (num1%2 == 1) {
oddLineValuesSum += result;
}
num1 /= 2;
result *= 2;
}
result += oddLineValuesSum;

// In case the left number was negative
if (num1 == -1) {
result = -result;
}

System.out.println(" = " + result);
return result;
}
• Trevor Dubinsky 2009-07-22 13:59
Pascal, though specifically written in Delphi 7

Function rpm (num1, num2 : integer; var accumulator : integer) :integer;
{ Russion Peasant Multiplication implementation}
begin
// If the first number is not even add the second number
// to the total
if (num1 mod 2 <> 0) then
accumulator := accumulator + num2;

// If the first number is not 1 recursively call self
if num1 > 1 then
rpm (num1 div 2, num2 * 2, accumulator);

//return result
result := accumulator;
end;
• DeepThought 2009-07-22 14:01
Here is my submission. I've not looked at any of the other comments yet, so I apologize if this is similar to any earlier posts.

The realize that submitting an entire class is probably overkill, but I thought it would be helpful to see the recursive method (_multiply(int,int,int)) in context.

```/**
* Simple utility class containing the static
* {@link #multiply(int,int) multiply} method used to determine the product
* of the two integer operands, but it does this by using the
* <a href="http://thedailywtf.com/Articles/Programming-Praxis-Russian-Peasant-Multiplication.aspx">
* Russian Peasant algorithm</a>. <br/>
* This code is a response to a &quot;Programming Praxis&quot; challenge put
* forth by the <a href="http://thedailywtf.com">thedailywtf.com</a> website.
* <br/>While not a specific requirement of the challenge, this class was
* specifically coded to avoid directly making use of the language's
* multiplication (*) or division (/) operators.
* @author DeepThought (2009-07-22)
*/
public class RussianPeasantMultiply2
{
/**
* Recursive method used to determine which of the second operands is to
* be summed into the final result. It returns the results of that
* summation when the first operand has been reduced to 1. <br/>
* Each successive call to this method will result in the first operator
* being reduced by half while the second operator is doubled.
* The value of second operator will be added to the final results
* whenever the first operator is found to be an odd number.
* @param operand1 int - first operand
* @param operand2 int - second operand
* @param intermediateSum int - current result of summing up the second
* operators when the first operator is odd
*/
protected static int _multiply(int operand1, int operand2, int intermediateSum)
{
int results = 0;
if ((operand1 & 1) == 1)
{
intermediateSum += operand2;
}
results = (operand1 == 1) ?
intermediateSum :
_multiply(operand1 >> 1, operand2 + operand2, intermediateSum);
return(results);
}
/**
* This method is what is to be called to evaluate the product of the two operands.
* It will short-circuit the logic when either operand is 0 or 1 and will also negate
* the results of the recursive
* {@link #_multiply(int,int,int) _multiply(int,int,int)} method when the first
* operator is a negative number.
*/
public static int multiply(int operand1, int operand2)
{
int results;
int absOp1 = Math.abs(operand1);
int absOp2 = Math.abs(operand2);
if (absOp1 == 0 || absOp2 == 0)
{
results = 0;
}
else if (absOp1 == 1)
{
results = absOp2;
}
else if (absOp2 == 1)
{
results = absOp1;
}
else
{
results = _multiply(absOp1, operand2, 0);
if (operand1 < 0) results = (results ^ -1) + 1;
}
return(results);
}
/**
* Parsed a string argument supplied by the command-line and returns
* the integer equivalent.<br/>It will display an error message and
* exit processing if a <code>java.lang.NumberFormatException</code>
* is thrown.
*/
public static int parseIntArguement(String strValue)
{
int intValue = 0;
try
{
intValue = Integer.parseInt(strValue);
}
catch (NumberFormatException nfe)
{
System.err.println("Invalid number for operand \"" + strValue + "\"!");
System.exit(1);
}
return(intValue);
}
/**
* Main application entry point
*/
public static void main(String args[])
{
try
{
if (args.length < 2)
{
System.exit(1);
}
int operand1 = parseIntArguement(args[0]);
int operand2 = parseIntArguement(args[1]);
System.out.println("results = " + multiply(operand1,operand2));
}
catch (Exception e)
{
e.printStackTrace();
}
}
}
```

P.S. While previewing the comment I can see that the site appears to be inserting <br/> tags and the beginning of each line of my code block even though it is embedding the code within a <pre> tag. If that is also the case for the final post then not a result of me intentionally adding extra carriage returns or line-feeds in the original source. Sorry, but there doesn't appear to be anything I can do about it.
• Greg R 2009-07-22 14:02
Fine, I've rewritten mine to handle negative numbers (even if they are restricted to the party elite who will simply subtract the peasants from the population until they have the proper answer) and to avoid explicitly using multiplication anywhere.

```public static int умножить(int Значение1, int Значение2) {
if(Значение1 == 1)
return Значение2;

if (Значение1 < 0) {
Значение2 = 0 - Значение2;
Значение1 = 0 - Значение1;
}

int крестьянин  = умножить(Значение1 / 2, Значение2 + Значение2);
if(Значение1 % 2 == 1)
крестьянин += Значение2;

return крестьянин;
}
```
• Tyches 2009-07-22 14:04
I think I've implemented a quantum physics one, but can't tell unless I open the box, and then it might kill the cat. Damn Schrödinger.
• bb 2009-07-22 14:05
Here is the wtf of java program you would likely find when looking at others code :

int multiply(int a, int b){
int stuff = 0, z = -1;
while ( a >> ++z > 0)
stuff += (((a >> z) & 0x1) == 1 ? b * Math.pow(2, z) : 0 );

return stuff;
}
• Shiftyness 2009-07-22 14:08
C#
int RussianMult(int a, int b)
{
int c = 0;
if (a == 0 || b == 0) return c;
else
{
int d = 0;
while (a != 0)
{
if ((a % 2) != 0) d += (b * 2);
a = a / 2;
b = b * 2;
}
c = d/2;
return c;
}

}
• cincinnatvs 2009-07-22 14:08
public int multiply (int operand1, int operand2) throws Exception {
int product = 0;

// While the first operand is still at least one, continue to execute the loop...
while (operand1 >= 1) {
// Show the current values...
System.out.println ("" + operand1 + "\t" + operand2);

// If the first operand is odd, add the value of the second operand to the total (our product).
if (operand1 % 2 > 0) product += operand2;

// In accordance with the "Russian Peasant Multiplication" method, divide the first operand by 2
// and multiply the second operand by two.
operand1 /= 2;
operand2 *= 2;
}

// Return the product of this process.
return product;
}
• Humanoid Life-form 2009-07-22 14:08
```int russianMultiply(int a, int b) {
// Create vars
int left=a;
int right=b;
int rightSum=0;
int errorOffset=0;

if(left % 2 != 0 && right % 2 == 0) { // Prevent incorrect results
int t = left;
left = right;
right = t;
} else if(left % 2 != 0 && right % 2 != 0) {
errorOffset = right;
left++;
}

// Multiply
for(;left > 1;) {
left /= 2;
right *= 2;
if((left % 2) != 0) rightSum += right;
}

return rightSum - errorOffset;
}```

I had to compensate for the algorithm's failure when a is odd.
• Alan Woodland 2009-07-22 14:09
My attempt at a compile time C++ version - outputs the answer in the form of an error message. Actually builds the whole table like the pen and paper working in the example animation too.

```template <int N, int M, typename NEXT=void>
struct mult_list {
enum {n=N};
enum {m=M};
typedef NEXT tail;
};

template <int N, int M>
struct mult_list<N,M,void> {
enum {n=N};
enum {m=M};
typedef void tail;
};

template <int N, int M>
struct russian {
typedef mult_list<N,M, typename russian<N/2,M*2>::result> result;
};

template <int M>
struct russian<1,M> {
typedef mult_list<1,M> result;
};

template <typename LIST>
enum {total=add_odd<typename LIST::tail>::total + (LIST::n % 2 ? LIST::m : 0) };
};

template <>
enum {total=0};
};

template <int N>
struct output;

namespace {
}
```
• Eyrieowl 2009-07-22 14:09
brainfuck...not sure if this is going to show up properly with all the angle braces, but let's give it a try....

```>+<+[>[>[-]+<-]>[<+>>>>>>>>>>>>>>[-]<<<<<<<<<<<<+[->,.----------[<+>>++++++[<------>-]>>>>>>>>>>[<<<<<<<<<<+>>>>>>>>>>-]<<<<<<<<<<[>>>>
>>>>>>++++++++++<<<<<<<<<<-]<[>>>>>>>>>>>+<<<<<<<<<<<-]]<]>>>>>>>>>>>>>[-]<<<<<<<<<<<<<+[->,.----------[<+>>++++++[<------>-]>>>>>>>>>>
>[<<<<<<<<<<<+>>>>>>>>>>>-]<<<<<<<<<<<[>>>>>>>>>>>++++++++++<<<<<<<<<<<-]<[>>>>>>>>>>>>+<<<<<<<<<<<<-]]<]>>>>>>>>[-]>>[-]<<[>>+<<-][-]>
>>>>[<<<<<+<<<<<<<<+>>>>>>>>>>>>>-]<<<<<<<<<<<<<[>>>>>>>>>>>>>+<<<<<<<<<<<<<-]>>>>>>>>>>>[-]<<<[>>>+<<<-][-]>>>>[<<<<+<<<<<<<<+>>>>>>>>
>>>>-]<<<<<<<<<<<<[>>>>>>>>>>>>+<<<<<<<<<<<<-]>>>>>>>>>[-]<[>+<-]<<<<<<<<<-]>>>>>>>>>>>>>>>>>[<<<<<<<<<<<<<<<<<<+>>>>>>>>>>>>>>>>>>-]<<
<<<<<<<<<<<<<<<<[>[-]+<-]>[<+>>>>>>>>>>[-]>[<+<<<<<<<<+>>>>>>>>>-]<<<<<<<<<[>>>>>>>>>+<<<<<<<<<-]>>>>>>>[-]>>>>>>>>>>[<<<<<<<<<<+<<<<<<
<+>>>>>>>>>>>>>>>>>-]<<<<<<<<<<<<<<<<<[>>>>>>>>>>>>>>>>>+<<<<<<<<<<<<<<<<<-]>>>>>>>>>>>>>>[-]++>[-]+<[<<<<<<<<<<<<<+>>>>>>>>>>>>>-]->[<
<<<<<<<<<<<<<-<+>>>>>>>>>>>>>>>-]<<<<<<<<<<<<<<<[>>>>>>>>>>>>>>>+<<<<<<<<<<<<<<<-]>[>>>>>>>>>>>>>+<<<<<<<<<<<<<[-]]<->>>>>>>>>>>>>>[<<<
<<<<<<<<<<<->>>>>>>>>>>>>>-]<<<<<<<<<<<<<<[>>>>>>>>>>>>>>+<<<<<<<<<<<<<<-]>>>>>>>>[>>>>>>>>>>+<<<<<<<<<<<<<<<<<<<<->>>>>>>>>>[-]]<<<<<<
<<<-]<[>[-]+<-]>[<+>>>>>>>>>>[-]>>[<<+<<<<<<<<+>>>>>>>>>>-]<<<<<<<<<<[>>>>>>>>>>+<<<<<<<<<<-]>>>>>>>[-]>>>>[<<<<+<<<<<<<+>>>>>>>>>>>-]<
<<<<<<<<<<[>>>>>>>>>>>+<<<<<<<<<<<-]>>>>>>>[>+<<<<<<<<+>>>>>>>-]<<<<<<<[>>>>>>>+<<<<<<<-]>>>>>>>>>>[-]<<[>>+<<-][-]>[<+<<<<<<<<+>>>>>>>
>>-]<<<<<<<<<[>>>>>>>>>+<<<<<<<<<-]>>>>>>>[-]+>[<<<<<<<+>>>>>>>-]-<[<<<<<<-<+>>>>>>>-]<<<<<<<[>>>>>>>+<<<<<<<-]>[>>>>>>>+<<<<<<<[-]]>>>
>>>>[>>>>>>>>>>>+<<<<<<<<<<<<<<<<<<<<<->>>>>>>>>>[-]]<<<<<<<<<-]<[>[-]+<-]>[<+>>>>>>>>>>[-]>[<+<<<<<<<<+>>>>>>>>>-]<<<<<<<<<[>>>>>>>>>+
<<<<<<<<<-]>>>>>>>[-]++>[<<<<<+>>>>>-]<<<<<[>>>>[<<<<<+<<+>>>>>>>-]<<<<<<<[>>>>>>>+<<<<<<<-]>>[>-[<<+<+>>>-]<<<[>>>+<<<-]+>[<->[-]]<[>>
-[>>>>>>-<<<<<<[-]]+<<[-]]>>-]>>>>>>+<<<<<]>>>>>>[-]<[>+<-][-]>>>[<<<+<<<<<<<<+>>>>>>>>>>>-]<<<<<<<<<<<[>>>>>>>>>>>+<<<<<<<<<<<-]>>>>>>
>[-]++>[<<<<<<<+>>>>>>>-]<<<<<<<[>>>>>>[>+<<<<<<<<+>>>>>>>-]<<<<<<<[>>>>>>>+<<<<<<<-]>-]>>>>>>>>>>[-]<<<[>>>+<<<-]>>>>>>>>+<<<<<<<<<<<<
<<<<<<->-]>>>>>>>>>>>>>>>>>>>>[<<<<<<<<<<<<<<<<<<<<<+>>>>>>>>>>>>>>>>>>>>>-]<<<<<<<<<<<<<<<<<<<<<[>[-]+<-]>[<+>>++++++++++++++[>++++++>
+++++++>++++++++>++++>++<<<<<-]>--.>+++.>+++.++.<+++++++.>-.>++.>++++.[-]<[-]<[-]<[-]<[-]<>>>>>>>>[-]>>[<<+<<<<<<<<+>>>>>>>>>>-]<<<<<<<
<<<[>>>>>>>>>>+<<<<<<<<<<-]>[-]>[-]>[-]>[-]>>>>[<<<<<+[>+<<<<+>>>-]<<<[>>>+<<<-]+>>>>----------[<<<<->>>>[-]]<<<<[>>+>[-]<<<-]>>[>>+<<<
<+>>-]<<[>>+<<-]+>>>>----------[<<<<->>>>[-]]<<<<[>+>[-]<<-]>>>>>>>>-]<<<<<<<[<++++++++[>++++++>++++++<<-]>.>.[-]<[-]]>[<<++++++++[>>++
++++<<-]>>.[-]]<<++++++++[>>>++++++<<<-]>>>.[-]<<<++++++++++.[-]<<<->>-]<<]@
```
• klagdon 2009-07-22 14:11
Ok, once more with bit shifting and accounting for negative numbers.
```    public static long multiply(long first, long second) {
if(first < 0 && second < 0) {
return multiply(Math.abs(first), Math.abs(second));
} else if(first < 0 || second < 0) {
return -multiply(Math.abs(first), Math.abs(second));
} else if(first == 0 || second == 0) {
return 0;
} else if(first == 1) {
return second;
} else if(first % 2 == 1) {
return second + multiply(first >> 1, second << 1);
} else {
return multiply(first >> 1, second << 1);
}
}

public static void main(String[] args) {
Random r = new Random();
for(int i = 0 ; i < 1000000 ; i++) {
long first = (long)r.nextInt();
long second = (long)r.nextInt();
long result = multiply(first,second);
if((first * second) != result) {
System.out.println("Failed for " + first + " * " + second + " = " + (first * second) + "\t" + result);
}
}
}
```
• bluebearr 2009-07-22 14:11
Fine, since everyone seems soooo concerned that peasants be able to properly multiply negative numbers, I revised my Windows XP batch file answer. I also removed the multiplication assignment step, since I guess it is cheating.

Check out the _sign variable! Don't you wish your language could do that sort of nonsense?
```@echo off
set _a=18
set _b=23
call :mult %_a% %_b% _result
echo %_a% x %_b% = %_result%
goto :EOF

:mult
::   Multiply two numbers
::   Parameters:
::    %1 - first number
::    %2 - second number
::    %3 - variable to return result in
setlocal
set _a=%1
set _b=%2
set _res=0
set _sign=LEQ 1
if "%_a:~0,1%"=="-" set _sign=GEQ -1
:calc
set _eventest=0
for /L %%i in (0,2,8) do if %_a:~-1%==%%i set _eventest=1
if %_eventest%==0 set /a _res+=_b
if %_a% %_sign% goto endcalc
set /a _a/=2
set /a _b=_b+_b
goto calc
:endcalc
if "%_a:~0,1%"=="-" (
if "%_res:~0,1%"=="-" set _res=%_res:~1%
if Not "%_res:~0,1%"=="-" set _res=-%_res%
)
endlocal & set %3=%_res%
goto :EOF```
• EngleBart 2009-07-22 14:12
ath:
Same thing in python:
```def is_odd(n):
return (n % 2) != 0

def rmul(x, y):
s = 0
while(x != 1):
if is_odd(x):
s += y
x /= 2
y *= 2
return y + s
```

Any of these solutions checking for != 1 need to double check when the argument is 0.

This (and floating point numbers) are why it is always safer to use > or >= versus trying to "hit" an exact match.

As far as I can tell rmul(0,y) == infinite loop.
• aef123 2009-07-22 14:14
public static long PeasantMult(long operand1, long operand2)
{
long product = 0;
while (operand1 != 1)
{
if (operand1 % 2 != 0) { product += operand2; }
operand1 /= 2;
operand2 *= 2;
}
return (product + operand2);
}
• Trurl 2009-07-22 14:17

MUMPS:

P(I,S)

S Q=I I I I S#2 S Q=0

Q Q+P(I\2,S*2)

Features:
Shortened keywords!
Keywords reused for variable names!
Recursion!
Untested!

That doesn't work:

`\$ZE:<UNDEFINED>P+2^cTRAL1`

This is tested and i added some extra MUMPS-flavour:

```M(S,Q) N N,FN,F Q:\$G(S)=""!(\$G(Q)="") "0" ; wtf?!
S N=\$S('(+S<0=(+Q<0)):"-",1:""),S=\$FN(+S,"-",0),Q=\$FN(+Q,"-",0)
S F=\$S(S#2:Q,1:"") Q:S=0!(Q=0) "0"
S FN="" F  S S=S\2,Q=Q*2 S:S#2 FN=FN+Q Q:S=1
Q N_(FN+F)
```

->

```:W \$\$M^cTRAL1(18,23)
414
:W \$\$M^cTRAL1(19,23)
437
:W \$\$M^cTRAL1(-23,42)
-966
:W \$\$M^cTRAL1(-23,-12.5)
299
```

:
• aef123 2009-07-22 14:18
public static long PeasantMult(long operand1, long operand2)
{
long product = 0;
while (operand1 > 1)
{
if (operand1 % 2 != 0) { product += operand2; }
operand1 /= 2;
operand2 *= 2;
}
return operand1 * (product + operand2);
}
• astonerbum 2009-07-22 14:18
JavaScript. No Bitwise operations, but no use of multiplication either... Thats v2 :) Though still uses division so its still a problem, bitwise operations eliminate the need.

Handles positive and negative numbers.

```function rpmult(x, y){
var flip = false;
if ( x === 0 || y === 0 ) {
return 0;
}
if ( x === 1 ) {
return y;
}
if ( x < 0 ) {
x = -x;
flip = true;
}
if ( x % 2 === 0) {
}
var added = ( x % 2 === 0 ? 0 : y );
var recurse = rpmult(Math.floor(x / 2), y + y);
}
```
• Matt 2009-07-22 14:20
Here's another scala solution. It's not as neat as the recursive solution but it's based on lists, so more like the pen-and-paper version.

def mult(a: Int, b: Int) = {
def m(a: Int, b: Int): List[(Int,Int)] =
if (a==1) List((a,b)) else (a,b) :: m(a/2,b*2)
m(a,b).filter(_._1%2 == 1).foldLeft(0)(_ + _._2)
}
• blueberry 2009-07-22 14:23
Osno:
All the people using multiplication and division instead of shifting (except in languages where there is no shifting) also fail.

Granted, the goal was to define the multiply operator so it shouldn't be in the code.

HOWEVER, it is almost always a really bad idea to bitshift instead of using multiply/divide:

- << may lead to silent overflows instead of throwing an exception.
```  int z1 = int.MaxValue * 2;   // Compile-time exception
int z2 = int.MaxValue << 1;  // Silent overflow, return -2
```

- For negative values, >> and / are NOT equivalent ((-1 >> 1) != (-1 / 2)).
```  int y1 = -1 >> 1;   // -1
int y2 = -1 / 2;    // 0
```

Numerical multiply/divide are hardly the bottleneck of any modern application. Let's keep the bitshift operators for what it was intended: shift bits. It was probably a smart optimization 30 years ago, but in 2009 it is a bad and pointless practice.

• Maks Verver 2009-07-22 14:27
Eyrieowl:
brainfuck...

Nice, but two questions:
- How am I supposed to format the input? I wasn't able to get anything sensible out of it.
- Was this hand-written? (I always think generated Brainfuck code is lame.)
• Trurl 2009-07-22 14:29
Granted, the goal was to define the multiply operator so it shouldn't be in the code.

I see...

Here's my altered submission:

MUMPS:
``` ;-
M(S,Q) N N,FN,F Q:\$G(S)=""!(\$G(Q)="") "0" ; wtf?!
S N=\$S('(+S<0=(+Q<0)):"-",1:""),S=\$FN(+S,"-",0),Q=\$FN(+Q,"-",0)
S F=\$S(S#2:Q,1:"") Q:S=0!(Q=0) "0"
S FN="" F  S S=S\2,Q=Q+Q S:S#2 FN=FN+Q Q:S=1
Q N_(FN+F)
;-
```

Trurl
• CMIT 2009-07-22 14:30
method1:
Paula:
public class Paula extends WTF {
public static string Paulabean = "brillant!";
}

Best solution by far

especially since she misspelled 'brilliant' ;)
• tirerim 2009-07-22 14:31
Qwertyuiopas:
Any time you use n = n * 2 or n *=2, n += n would work.
Any time you use n = n * -1 or n *= -1, n = -n would work.

Anyone using * for 2 or -1 has NO EXCUSE.

Nonsense. In Perl, \$n*=2 has fewer characters than \$n+=\$n. :-P
• Warr 2009-07-22 14:32
I figured that, to keep things interesting, I'd try to implement this using only regular expressions, instead of any real "math." I didn't quite accomplish it, since writing regular expressions to perform addition seemed too tedious, so I threw in a lookup table to assist with the additon step (only accounting for 2 addition operators in code, and a fixed 200 of them at run-time).

Interestingly enough, the thing actually works pretty well, has no theoretical limits on integer size, and never has to do decimal/binary translation at any point (though, technically, operations are carried out internally in a sort of base-30 system). Works with positive and negative integers of arbitrary size. Faster run-time if the smaller operand is on the left. :-)

#!/usr/bin/perl -w
\$_ = join(' ', @ARGV);
m#^\s*-?\d+\s*x\s*-?\d+\s*# or die('Input should be in "#### x ####" format.');
\$sign = '+'; while(s#-##) { \$sign =~ tr#+-#-+#; }
s#\s##g;
s#\$#=0\n#;
%sums = ();
%out = ();
%carry = ();
for(\$a = 0; \$a < 10; \$a++)
{
\$i = \$a; \$i =~ tr#0-9#a-j#;
\$k = \$a; \$k =~ tr#0-9#A-J#;
for(\$b = 0; \$b < 10; \$b++)
{
\$c = \$a + \$b; # FIXME: Math on processor!
\$d = \$c + 1; # FIXME: Math on processor!
\$j = \$b; \$j =~ tr#0-9#a-j#;
length(\$c) > 1 and
\$c =~ tr#0-9#A-J# or
\$c =~ tr#0-9#a-j#;
\$c =~ s#.*(?=.)##;
length(\$d) > 1 and
\$d =~ tr#0-9#A-J# or
\$d =~ tr#0-9#a-j#;
\$d =~ s#.*(?=.)##;
for(\$e = 0; \$e < 10; \$e++)
{
\$f = \$e; \$f =~ tr#0-9#a-j#;
\$g = \$e; \$g =~ tr#0-9#A-J#;
\$sums{\$a . \$b . \$e} = \$c;
\$sums{\$i . \$b . \$e} = \$c;
\$sums{\$a . \$j . \$e} = \$c;
\$sums{\$i . \$j . \$e} = \$c;
\$sums{\$a . \$b . \$f} = \$c;
\$sums{\$i . \$b . \$f} = \$c;
\$sums{\$a . \$j . \$f} = \$c;
\$sums{\$i . \$j . \$f} = \$c;
\$sums{\$a . \$b . \$g} = \$d;
\$sums{\$i . \$b . \$g} = \$d;
\$sums{\$a . \$j . \$g} = \$d;
\$sums{\$i . \$j . \$g} = \$d;
}
}
\$out{\$a} = \$i;
\$carry{\$a} = \$k;
}
while(!m#^0+x#)
{
s#(?<!\d)(\d)#0\$1#g;
if(m#\d+[13579]x#)
{
s#(\d)(=\d*)(\d)#\$out{\$1}\$2\$sums{\$1.\$3.0}#;
while(m#\d[a-j]*=#)
{
s#=([^0])#=0\$1#;
s#(\d)([a-j]*=\d*)(\d)(.)#\$out{\$1}\$2\$sums{\$1.\$3.\$4}\$4#;
}
while(m#=0*[0-9A-J]#)
{
s#=([A-J])#=0\$1#;
s#0(?=[a-j]*\$)#a#;
s#1(?=[a-j]*\$)#b#;
s#2(?=[a-j]*\$)#c#;
s#3(?=[a-j]*\$)#d#;
s#4(?=[a-j]*\$)#e#;
s#5(?=[a-j]*\$)#f#;
s#6(?=[a-j]*\$)#g#;
s#7(?=[a-j]*\$)#h#;
s#8(?=[a-j]*\$)#i#;
s#9(?=[a-j]*\$)#j#;
s#0(?=[A-J]*\$)#b#;
s#1(?=[A-J]*\$)#c#;
s#2(?=[A-J]*\$)#d#;
s#3(?=[A-J]*\$)#e#;
s#4(?=[A-J]*\$)#f#;
s#5(?=[A-J]*\$)#g#;
s#6(?=[A-J]*\$)#h#;
s#7(?=[A-J]*\$)#i#;
s#8(?=[A-J]*\$)#j#;
s#9(?=[A-J]*\$)#A#;
}
tr#A-Ja-j#0-90-9#;
}
s#^0#a#;
s#^1#A#;
s#^2#b#;
s#^3#B#;
s#^4#c#;
s#^5#C#;
s#^6#d#;
s#^7#h#;
s#^8#i#;
s#^9#j#;
while(m#^[A-Ja-j]*\d#)
{
s#(?<=[a-j])0#a#;
s#(?<=[a-j])1#A#;
s#(?<=[a-j])2#b#;
s#(?<=[a-j])3#B#;
s#(?<=[a-j])4#c#;
s#(?<=[a-j])5#C#;
s#(?<=[a-j])6#d#;
s#(?<=[a-j])7#D#;
s#(?<=[a-j])8#e#;
s#(?<=[a-j])9#E#;
s#(?<=[A-J])0#f#;
s#(?<=[A-J])1#F#;
s#(?<=[A-J])2#g#;
s#(?<=[A-J])3#G#;
s#(?<=[A-J])4#h#;
s#(?<=[A-J])5#H#;
s#(?<=[A-J])6#i#;
s#(?<=[A-J])7#I#;
s#(?<=[A-J])8#j#;
s#(?<=[A-J])9#J#;
}
tr#A-Ja-j#0-90-9#;
s#0=#a=#;
s#1=#c=#;
s#2=#e=#;
s#3=#g=#;
s#4=#i=#;
s#5=#A=#;
s#6=#C=#;
s#7=#E=#;
s#8=#G=#;
s#9=#I=#;
while(m#\d[A-Ja-j]*=#)
{
s#0(?=[a-j])#a#;
s#1(?=[a-j])#c#;
s#2(?=[a-j])#e#;
s#3(?=[a-j])#g#;
s#4(?=[a-j])#i#;
s#5(?=[a-j])#A#;
s#6(?=[a-j])#C#;
s#7(?=[a-j])#E#;
s#8(?=[a-j])#G#;
s#9(?=[a-j])#I#;
s#0(?=[A-J])#b#;
s#1(?=[A-J])#d#;
s#2(?=[A-J])#f#;
s#3(?=[A-J])#h#;
s#4(?=[A-J])#j#;
s#5(?=[A-J])#B#;
s#6(?=[A-J])#D#;
s#7(?=[A-J])#F#;
s#8(?=[A-J])#H#;
s#9(?=[A-J])#J#;
}
tr#A-Ja-j#0-90-9#;
s#(?<!\d)0+(?=\d|0(?!\d))##g;
}
s#.*=##;
s#^#\$sign#;
s#^\+##;
print;
• stannius 2009-07-22 14:32
Mine is similar. Too bad we were prevented from making one-liners by "The yield statement cannot be used inside an anonymous method or lambda expression!"

```private int PeasantMultiply(int first, int second)
{
return GetColumns(first, second).Where(foo => foo.First % 2 == 1).Sum(bar => bar.Second);
}

private IEnumerable<Pair<int>> GetColumns(int a, int b)
{
while (a >= 1)
{
yield return new Pair<int>(a, b);
a = a / 2;
b = b * 2;
}
}
```
• moltonel 2009-07-22 14:35
#!/bin/sh

grep -q '^1\*' <<< \$1 && echo \$(( \$1 )) || \$0 "\$(( \$(sed 's/\*.*//' <<< \$1)/2 ))*\$(( \$(sed 's/.*\*//;s/+.*//' <<< \$1)*2 ))\$(grep -oE '[13579]\*[0-9]+' <<< \$1| sed 's/.*\*/+/')\$(grep -o '\+.*' <<< \$1)"

# only one line and no modification of a variable :p

That's bash of course, not sh.
• flax 2009-07-22 14:35
Nobody has submitted ARM code yet that I have seen. Does this win for smallest number of instructions?
``` ; multiplicands in r0 and r1

mov r2,#0
loop
movs r0,r0,lsr #1
mov r1,r1,asl #1
bne loop```
• astonerbum 2009-07-22 14:37
finally its time i learned how to do bitwise operations in javascript :P

This time there is absolutely no division or multiplication used in the algorithm, or Math.floor :P

```function rpmult(x, y){
var flip = false;
if (x === 0 || y === 0) {
return 0;
}
if (x === 1) {
return y;
}
if (x < 0) {
x = -x;
flip = true;
}
var added = (((x & 0x1) === 0x1) ? 0 : y);
var recurse = rpmult(x >>> 1, y + y);
}
```
• Paul 2009-07-22 14:37
```interface IMultiplierStrategy {
public function mul( \$a, \$b );
}
abstract class Arithmetic  {
protected
\$a, \$b;
public function __construct( \$a, \$b ) 	{
\$this->a = \$a;
\$this->b = \$b;
}
}
class Multiply extends Arithmetic {
public function mul( IMultiplierStrategy \$strategy ) 	{
return \$strategy->mul( \$this->a, \$this->b );
}
}
class RussianMultiplierStrategy implements IMultiplierStrategy {
protected
\$tally = 0;
public function mul( \$a, \$b ) {
if( \$a > 1 && \$a %2 != 0 ) {
\$this->tally += \$b;
}
if( \$a == 1 ) {
return \$this->tally + \$b;
}
return \$this->mul( intval( \$a /2 ), \$b *2 );
}
}
\$mul = new Multiply( 18, 23 );
echo \$mul->mul( new RussianMultiplierStrategy );
```

To the PHB: it's extensible multiplication architecture.
• java.lang.Chris; 2009-07-22 14:38
FORTRAN 77

```       PROGRAM RUSSIAN_MULTIPLY
IMPLICIT NONE

INTEGER RM
INTEGER N

N = RM(34, 4)

PRINT *, '34 * 4 = ', N

STOP
END

INTEGER FUNCTION RM(X, Y)
INTEGER X
INTEGER Y

INTEGER Z

Z = 0

DO WHILE (X .GT. 0)
Z = Z + MOD(X, 2) * Y
X = X / 2
Y = Y * 2
ENDDO

RM = Z

RETURN
END
```
• Михаил 2009-07-22 14:38
#define int инт
#define return разврат
#define if еслибы
#define while покашто
#define else иначе
#define printf напечатать
//к черту всех floats
инт множение(инт пиво,инт квас)
{
инт чердылка=0;
еслибы(пиво > квас ) //чтобы быстрее работала, пацаны
{чердылка=квас;квас=пиво;пиво=чердылка;чердылка=0;}

покашто(пиво!=1)
{
еслибы((пиво & 0x1)==1) //ne делитса на два
чердылка+= квас;
пиво>>=1;
еслибы(квас < 0)
напечатать("Ну твою мать!");
}

разврат чердылка;
}

инт негативноеMноение(инт пиво,инт квас)
{разврат -1*множение(инт пиво,инт квас);}
• Qwertyuiopas 2009-07-22 14:41
• OmnipotentEntity 2009-07-22 14:43
My solution.

```#include <stdio.h>

int main (int argc, char* argv[]) {
if (argc == 3) {
long a = atoi(argv[1]);
long b = atoi(argv[2]);
long sum = 0;
if (b&1) {
sum += a;
}
while (b > 1) {
b = b >> 1;
a = a << 1;
if (b&1) {
sum += a;
}
}
printf("%ld\n", sum);
return 0;
} else {
return 1;
}
}```

• samanddeanus 2009-07-22 14:43
Scheme with fold and unfold:
```(define (mul a b)
(fold +
0
(unfold (lambda (x)
(zero? (car x)))
(lambda (x)
(if (odd? (car x))
(cdr x)
0))
(lambda (x)
(cons (quotient (car x) 2)
(+ (cdr x) (cdr x))))
(cons (abs a)
(if (negative? a)
(- b)
b)))))
```
• Maks Verver 2009-07-22 14:43
moltonel:
#!/bin/sh
grep -q '^1\*' <<< \$1 && echo \$(( \$1 )) || \$0 "\$(( \$(sed 's/\*.*//' <<< \$1)/2 ))*\$(( \$(sed 's/.*\*//;s/+.*//' <<< \$1)*2 ))\$(grep -oE '[13579]\*[0-9]+' <<< \$1| sed 's/.*\*/+/')\$(grep -o '\+.*' <<< \$1)"

I can't get this to work properly. With BSD sh it doesn't parse, with Bash it runs, but produces incorrect answers for the simplest arguments (and when the first argument is 1, it doesn't produce a result at all).

Any explanation? Maybe some of the code got mangled while posting, or you're using yet a different shell?
• Ingo 2009-07-22 14:45
I can beat that...

int RussianPeasantMultiplyFor18And23( )
{
return 414;
}

OMG.. my code is fastest?
• moltonel 2009-07-22 14:51
Maks Verver:
moltonel:
#!/bin/sh
grep -q '^1\*' <<< \$1 && echo \$(( \$1 )) || \$0 "\$(( \$(sed 's/\*.*//' <<< \$1)/2 ))*\$(( \$(sed 's/.*\*//;s/+.*//' <<< \$1)*2 ))\$(grep -oE '[13579]\*[0-9]+' <<< \$1| sed 's/.*\*/+/')\$(grep -o '\+.*' <<< \$1)"

I can't get this to work properly. With BSD sh it doesn't parse, with Bash it runs, but produces incorrect answers for the simplest arguments (and when the first argument is 1, it doesn't produce a result at all).

Any explanation? Maybe some of the code got mangled while posting, or you're using yet a different shell?

Yes, bash, sorry.
You'll have to give it two numbers, without space, and the multiplication sign must be an actual '*'.

eg:
\$ ./russian.sh 19*29
551
\$ ./russian.sh 18*23
414
• newlisp.org 2009-07-22 14:51
improvement for some problems starting with even number:

```(define (rmul x y , (s 0))
(until (= x 1)
(unless (zero? (% x 2))
(inc s y))
(setq x (>> x) y (<< y)))
(+ y s)
)
```
• MG 2009-07-22 14:52
Why recurse when you can use a linked list?

```#include <stdio.h>
#include <stdlib.h>

struct rus_row {
long left;
long right;
struct rus_row *next;
};
int main(int, char **);
long rus_multiply(long, long, int);
struct rus_row *make_row(long, long, struct rus_row *);
void rus_freemem(struct rus_row *);

int main(int argc, char *argv[]) {
if (argc != 3) {
printf("Usage: %s <num> <num>\n", argv[0]);
exit(1);
}
long a = atol(argv[1]);
long b = atol(argv[2]);
long result = rus_multiply(a, b, 1);
return 0;
}

long rus_multiply(long a, long b, int print) {
long total = 0;

struct rus_row *head = make_row(a, b, NULL);
while(tail->left > 1) {
struct rus_row *new_row = make_row(tail->left / 2, tail->right * 2, NULL);
tail->next = new_row;
tail = tail->next;
}
while (curr) {
if (curr->left & 1) {
// odd
if (print) {
printf ("%ld\t%ld\t+ %ld\n", curr->left, curr->right, curr->right);
}
total = total + curr->right;

} else {
// even
if (print) {
printf ("%ld\t%ld\n", curr->left, curr->right);
}
}
curr = curr->next;
}
if (print) {
printf ("\t\t-----\n\t\t= %ld\n", total);
}
}

struct rus_row *make_row(long left, long right, struct rus_row *next) {
struct rus_row *row = (struct rus_row *) malloc(sizeof(struct rus_row));  //todo:  check for malloc failure
row->left = left;
row->right = right;
row->next = next;
return row;
}

while (next) {
struct rus_row *curr = next;
next = curr->next;
free(curr);
}
}
```
• Will 2009-07-22 14:56
Nice callback to the futility closet article from last week. It is interesting to see how many different languages / methods people found for executing this procedure.
• blueberry 2009-07-22 14:59
Here is my solution in C#:

```        static int PeasantMult(int x, int y)
{
switch (x)
{
case -1: return -y;
case 0: return 0;
case 1: return y;
default: return PeasantMult(x % 2, y) + PeasantMult(x / 2, y + y);
}
}
```

-Works with negative values on any or both operands
-No multiplication
• Alan Woodland 2009-07-22 15:00
MG:
Why recurse when you can use a linked list?

• Osno 2009-07-22 15:03
I think everybody misrepresented my comment on using multiplication/division instead of bitshifting being fail as a performance comment. What I was aiming at is that if you're defining multiplication, multiplying is kind of lame. Then, I changed my mind and started using ( left & 1 ) * right, but that was just a shortcut :). Also, bitshifting was closer to the original demonstration in the "spec".

I agree with all that multiplying here is safer and probably close in performance. I doubt most of the compilers present (python, java, c#, vb.net, javascript, etc) will optimize it to the same thing, but who cares? (btw, I do think C, C++, Delphi, Scheme, Haskell and a few others may optimize).
• Osno 2009-07-22 15:05
Google Search (by far the most commonly used programming language):

http://lmgtfy.com/?q=russian+peasant+multiplication
• VirtualBlackFox 2009-07-22 15:07
C#, just for fun :

```namespace Test
{
using System;
using System.Collections.Generic;
using System.Linq;

class Program
{
class Elem
{
public int Left { get; set; }
public int Right { get; set; }
}

static IEnumerable<Elem> DivideUntilOneOnLeft(Elem e)
{
while (e.Left != 1)
{
e = new Elem() { Left = e.Left / 2, Right = e.Right * 2 };
yield return e;
}
}

static int Mutiply(int left, int right)
{
return DivideUntilOneOnLeft(new Elem() { Left = left, Right = right })
.Where(e => e.Left % 2 != 0)
.Aggregate(0, (accum, e) => accum + e.Right);
}

static void Main(string[] args)
{
Console.WriteLine(Mutiply(18, 23));
}
}
}```
• nine 2009-07-22 15:08
C# Recursive solution. Handles edge cases (negative integers, 0). Focus is on readability/clarity and not performance:

public static int RussianMultiply(int x, int y)
{
if (x < 0) return RussianMultiply(-x, -y);
else if (x == 0) return 0;
else if (x == 1) return y;
else if (x % 2 == 1) return y + RussianMultiply(x/2, y*2);
else return RussianMultiply(x/2, y*2);
}
• Scott 2009-07-22 15:09
Here is an interesting javascript version
```function russia(a,b){ return new (function(){
while(a&1?((this.c?this.c+=b:this.c=b),a=a>>1,b=b<<1,(a==0?false:true)):(a=a>>1,b=b<<1,true)){};
})().c;}
```

The reason for the anonymous function is because of a variable scope issue that occurs when the function is called multiple times.
• darkscout 2009-07-22 15:18
```function [c] = rpm(a,b)
while (a(end)~=1)
a(end+1)=floor(a(end)/2);
b(end+1)=b(end)*2;
end
c=sum(b(logical(mod(a,2))));
```
• ikorb 2009-07-22 15:19
Yet another Haskell version. Distinguishing features: No indented lines, overly verbose

peasant_step :: (Int, Int) -> (Int, Int)
peasant_step (x,y) = (div x 2, y + y)

first_is_positive :: (Int, Int) -> Bool
first_is_positive (x,y) = x > 0

peasant_list :: (Int, Int) -> [(Int, Int)]
peasant_list args = takeWhile first_is_positive \$ iterate peasant_step args

first_is_odd :: (Int, Int) -> Bool
first_is_odd (x,y) = (mod x 2) == 1

peasant_filter :: [(Int, Int)] -> [(Int, Int)]
peasant_filter = filter first_is_odd

accumulate_second :: (Int, Int) -> Int -> Int
accumulate_second (x,y) a = y + a

peasant_sum :: [(Int, Int)] -> Int
peasant_sum = foldr accumulate_second 0

peasant_multiply :: Int -> Int -> Int
peasant_multiply x y = peasant_sum \$ peasant_filter \$ peasant_list (x,y)
• treyb 2009-07-22 15:23
In excel:

Column A:
A1: number_1
A2: =rounddown(A1/2,0)
A3: =rounddown(A2/2,0)
A4: and so on

Column B:
B1: number_2
B2: =if(A2,B1*2,0)
B3: =if(A3,B2*2,0)
B4: and so on

Column C:
C1: =if(mod(A1,2)=0,0,1)
C2: =if(mod(A2,2)=0,0,1)
C3: and so on

Column D:
D1: =sumproduct(B:B,C:C)
• iMalc 2009-07-22 15:26
Anyone done is using a .BAT script yet?
• TNProgrammer 2009-07-22 15:27
//C#
public static void Go()
{
Console.WriteLine(PraxisMultiply(18, 23).ToString());
}

public static int PraxisMultiply(int number1, int number2)
{
List<PraxisPair> pairs = new List<PraxisPair>();
while(number1 > 1)
{
number1 = number1 / 2;
number2 = number2 * 2;
}
int result = 0;
foreach(PraxisPair p in pairs)
{
if(p.Left % 2 == 0)
{
p.Right = 0;
}
result += p.Right;
}
return result;
}

public class PraxisPair
{

public PraxisPair(int left, int right)
{
Left = left;
Right = right;
}

public int Left{ get; set; }
public int Right{ get; set; }
}
• Josue Chi 2009-07-22 15:28
Short as can be

public static int russian(int multiplier1, int multiplier2) {
int result = 0;
while (multiplier1 >= 1) {
result += (multiplier1 % 2 == 1)? multiplier2: 0;
multiplier2 *= 2;
multiplier1 /= 2;
}
return result;
}
• SoaperGEM 2009-07-22 15:32
I'm not going to read through all the 400+ comments to see if this exact version's been done yet, but here's an implementation in Python:

```def multtwo(one, two):
result = 0
while (one >= 1):
if (one & 1):
result += two
one >>= 1
two <<= 1
return result```

I did scan through the code a little bit though, and seeing so many people using division and modulo operators made me sad. Don't they teach kids anything about bitwise operators anymore?
• blueberry 2009-07-22 15:35
SoaperGEM:

I did scan through the code a little bit though, and seeing so many people using division and modulo operators made me sad. Don't they teach kids anything about bitwise operators anymore?

See post #278250
Maybe it's time to go back to school :P
• asdfghj 2009-07-22 15:51
recursive scheme solution:

(define (russian_m a b) (if (= b 1)
a
(russian a b)
)
)

(define (russian a b)
(if (= a 1)
b
(+
(if (= (remainder a 2) 0) 0 b)
(russian (/ a 2) (* b 2))
)
)
)

not tested
• Josue Chi 2009-07-22 15:52
blueberry:
SoaperGEM:

I did scan through the code a little bit though, and seeing so many people using division and modulo operators made me sad. Don't they teach kids anything about bitwise operators anymore?

See post #278250
Maybe it's time to go back to school :P

As long as we don't multiply directly A * B, we are not violating any of the "original requirements". Of course using bit shifting can give you points, if we were at school (and may give you points here too :), but if it is not part of the requirements, I don't think we should feel forced to use it.

Cheers and good luck (I want my Sticker!)
• Alvie 2009-07-22 15:54
You win so far :) As long as that works, obviously.
• guille_ 2009-07-22 15:57
```(defun rmul (x y)
(let ((l (truncate x 2))
(r (* y 2)))
(reduce '+ (do ((sums '())
(l l (truncate l 2))
(r r (* r 2)))
((< l 1) sums)
(when (oddp l)
(push r sums))))))
```
• ZzzZZZz 2009-07-22 15:57
Recursive Python. Pretty disappointed with my work after seeing some of the others!

```def peasant(x, y):
n = 1
m = n
while (n < y):
m = n
n = n * 2
out = m * x
d = y - m
if (d == 0):
return out
else:
return peasant(x, d) + out```
• Beat by the system 2009-07-22 15:58
anyone done this in javascript?
function multiply (x, y, total)
{
(x == 0) ? alert(total) : multiply (Math.floor(x/2),Math.floor(y*2),(x % 2 == 0) ? total : total+y);
}
• Resistance 2009-07-22 16:00
In spite of being epic late, here's mine:
```#include <stdio.h>

int main() {
int a;
int b;
int c;

printf("A = ");
scanf("%d", &a);
printf("B = ");
scanf("%d", &b);

asm(
"movl \$0, %%ecx\n\t"
"loop:\n\t"
"shrl \$1, %%eax\n\t"    // divide left side by 2
"jnc skip_add\n\t"      // carry is set if eax was odd
"addl %%ebx, %%ecx\n\t" // accumulate right side
"shll \$1, %%ebx\n\t"    // multiply right side by 2
"cmpl \$0, %%eax\n\t"
"jne loop"              // equal if left side was 1
: "=c" (c)              // out: ecx - result
: "a" (a), "b" (b)      // in: eax - left side, ebx - right side
);

printf("A * B = %d\n", c);

return 0;
}
```
• Dave Havlicek 2009-07-22 16:01

```DECLARE
tmp1 INTEGER;
tmp2 INTEGER;
BEGIN
CREATE TEMPORARY TABLE tmp_columns ( "left_col" INTEGER NOT NULL, "right_col" INTEGER NOT NULL );
tmp1 := \$1;
tmp2 := \$2;
INSERT INTO tmp_columns (left_col, right_col) VALUES (tmp1, tmp2);
WHILE tmp1 != 1 LOOP
tmp1 := tmp1 / 2;
tmp2 := tmp2 + tmp2;
INSERT INTO tmp_columns (left_col, right_col) VALUES (tmp1, tmp2);
END LOOP;
return ( SELECT SUM(right_col) FROM tmp_columns WHERE (left_col % 2) = 1 );
END
```
• dontera 2009-07-22 16:02
```        private static int CalculateLikeRussianPeasant(int a, int b, List<int[]> lines)
{
if (lines == null)
{
lines = new List<int[]>();
int[] lr = new int[2];
lr[0] = a;
lr[1] = b;
CalculateLikeRussianPeasant(-1, -1, lines);
}

int[] lastLr = lines[lines.Count - 1];
if (lastLr[0] != 1)
{
int[] lr = new int[2];
lr[0] = lastLr[0] / 2;
lr[1] = lastLr[1] * 2;
if (lr[0] != 1)
CalculateLikeRussianPeasant(-1, -1, lines);
}

int result = 0;
lines.ForEach(delegate(int[] lr)
{
if (lr[0] % 2 != 0)
result += lr[1];
});

return result;
}
```

call into it with CalculateLikeRussianPeasant(101, 202, null);
• AshG 2009-07-22 16:05
I'm at the end of the third page of comments and have yet to see an Objective C solution.

What, no Apple/iPhone developers here? WTF?
• The Answer + 2 2009-07-22 16:11
C# (assumes a,b,c are defined and assigned elsewhere)

for(c=(a&1)*b;(a>1);c+=((a>>=1)&1)*(b<<=1));

44 characters
• Rob Hulswit 2009-07-22 16:15
Arrgh, some challenges are just too challenging...
35 characters, freestanding, no need to declare and assign delegates ;-)

C++, supports negative (at least the C++ dialect of Borland C++ Builder 5, the sign of (negative number % another number) is implementation defined in C++... sigh).
int r=0;for(;b;r+=b%2*c;b/=2;c*=2;}

Or a recursive version in 42 characters:
int a(b,c){return b?a(b/2,c*2)+(b%2)*c:0;}

C++ template meta programming:
template <int b, int c>
struct r
{
static const int s = b?r<b/2,c*2>::s+b%2*c:0;
};

Javascript 35 characters (works in firefox 3.0.11 and IE6). Damn, difficult to do integer division by 2 that also works good for negative numbers.
for(r=0;b/=2;b-=d=b%1,r+=d*(c*=2));
• Rob Hulswit 2009-07-22 16:21
Oops, copy-paste for the fail.

Real C++ version:
int r=0;for(;b;r+=b%2*c,b/=2,c*=2);
• Unlabeled Meat 2009-07-22 16:25
Shifty recursive Scala

```def rusMult(x: Int, y: Int): Int =
rusMult(x, y, 0)

def rusMult(x: Int, y: Int, sum: Int): Int =
if ((x == 0) || (y == 0)) 0
else
x match {
case 1 =>
sum + y
case _ =>
rusMult(x >> 1, y << 1, (if (x % 2 == 0) sum else sum + y))
}

```
• Talks Funny 2009-07-22 16:28
newlisp.org:
improvement for some problems starting with even number:

```(define (rmul x y , (s 0))
(until (= x 1)
(unless (zero? (% x 2))
(inc s y))
(setq x (>> x) y (<< y)))
(+ y s)
)
```

If you're gonna do it in good LISP, don't use setq so much.
• Anti-Ruski 2009-07-22 16:30
Hell with them, just do:

Function mult (a,b)
mult = a*b
end

Screw the Russians
• Roger 2009-07-22 16:38
Free format RPGLE
```  SOURCE FILE . . . . . . .  QRPGLESRC
MEMBER  . . . . . . . . .  RUSPEASANT
SEQNBR*...+... 1 ...+... 2 ...+... 3 ...+... 4 ...+... 5 ...+... 6 ...+... 7 ...+... 8
100       * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
200      H DEBUG OPTION(*SRCSTMT:*NODEBUGIO) DFTACTGRP(*NO)
300       * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
400      Fqsysprt   O    F   85        printer OFLIND(*INOF)
500       * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
600      D A               S             10I 0
700      D B               S             10I 0
800      D DIV             S             10I 0
900      D REM             S             10I 0
1000      D RESULT          S             10I 0
1100       * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1200      D  RUSPEASANT     PR
1300      D    IN_A                       15P 5
1400      D    IN_B                       15P 5
1500      D  RUSPEASANT     PI
1600      D    IN_A                       15P 5
1700      D    IN_B                       15P 5
1800       * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1900       /FREE
2000          A = IN_A                                                              ;
2100          B = IN_B                                                              ;
2200          RESULT = A * B                                                        ;
2400          except detail1                                                        ;
2500          dow A > 1                                                             ;
2600              A = %div(A:2)                                                     ;
2700              REM = %REM(A:2)                                                   ;
2800              B = B * 2                                                         ;
2900              if rem > 0                                                        ;
3000                    RESULT += B                                                 ;
3100              endif                                                             ;
3200              except detail2                                                    ;
3300              if *INOF                                                          ;
3500              endif                                                             ;
3600          enddo                                                                 ;
3700          except total                                                          ;
3800          *INLR = *on                                                           ;
3900          return                                                                ;
4000       /END-FREE
4100      Oqsysprt   E            head           1  1
4200      O                                           20 'Russian Peasant '
4300      O                                           34 'Multiplication'
4400      O          E            detail1        1
4500      O                       A             Z     15
4600      O                                           20 '*'
4700      O                       B             Z     35
4800      O                                           40 '='
4900      O                       RESULT        ZB    55
5000      O          E            detail2        1
5100      O                       A             Z     15
5200      O                       B             Z     35
5300      O          E            total          1
5400      O                       RESULT        Z     55
* * * *  E N D  O F  S O U R C E  * * * *```
• bluebearr 2009-07-22 16:41
SoaperGEM:
I did scan through the code a little bit though, and seeing so many people using division and modulo operators made me sad.

Your challenge: write a function that multiplies two numbers using the Russian peasant algorithm.

I didn't see anything in the original article about the peasants using bit shifting. I did see information about the peasants multiplying by two, and dividing by two and dropping the remainder.

But hey, maybe I missed something.
• hornet 2009-07-22 16:44
Threaded solution for maximum performance on a multicore system - not yet capable of negative or zero first multiplicand:

```using System;
using System.Collections.Generic;
using System.Text;
using System.ComponentModel;

namespace RussianMultiply
{
struct Multiplicands
{
public ManualResetEvent waitHandle;
public int a;
public int b;
}

class RussianMultiplyData
{
public volatile int result;
public RussianMultiplyData()
{
result = 0;
}
public void PartialCalculateMultiplication(object o, DoWorkEventArgs dwea)
{
Multiplicands mp = (Multiplicands)dwea.Argument;
if ((mp.a % 2) == 1) result += mp.b;
mp.waitHandle.Set();
}
};

class Program
{
static int MultiplyMultiCore(int a, int b)
{
List<BackgroundWorker> multiplicationWorkers = new List<BackgroundWorker>();
RussianMultiplyData rmd = new RussianMultiplyData();
while (a > 0)
{
BackgroundWorker bw = new BackgroundWorker();
Multiplicands mps;
mps.waitHandle = new ManualResetEvent(false);
mps.a = a;
mps.b = b;
bw.DoWork += rmd.PartialCalculateMultiplication;
bw.RunWorkerAsync(mps);

a >>= 1;
b <<= 1;
}

return rmd.result;
}

static void Main(string[] args)
{
Console.WriteLine(MultiplyMultiCore(18, 23));
}
}
}
```
• Bodestone 2009-07-22 16:44
I happened to be in SQL server at the the time so...

```DECLARE @factor1 INT, @factor2 INT SET @factor1 =18 SET @factor2 = 23

SELECT	SUM(rightCol)
FROM	(SELECT	@factor1/POWER(2,N) AS leftCol, @factor2*POWER(2,N) AS rightCol
FROM	Tally
WHERE	N < cast(log10(@factor1)/log10(2) as int) +1) таблица
WHERE leftCol%2=1
```

This does require that you have a Tally table with the integers 0 to x where x is big enough to do any calculation that won't overflow.
• mxsscott 2009-07-22 16:45
A solution in C that must be given the input as English transliterations of Russian numbers, in case voice input is used [a must for all future programs]. e.g. 18x23 is
`./russianmultiply AdeenDva TriVosyem`

It outputs in a similar form, as well as digits.

```#include <stdio.h>
#include <string.h>
#include <stdlib.h>

/* Must be 1+7 (not 8 or 7+1) */
#define MAGIC_LEN 1+7
const char* numerals[] =
{
};

char* intToRussian(unsigned int num)
{
char b[11];
sprintf(b,"%lu",num);
/* Allocate enough for longest string int and one terminating character */
char* russian = calloc(MAGIC_LEN * 10, sizeof(char));
for (int i = 0; i < 10 && b[i]; ++i)
{
strcat(russian, numerals[b[i] - '0']);
}
return russian;
}

unsigned int russianToInt(const char *russian)
{
int i,j,num;
num = j - j;
for (i = num ; i < strlen(russian); ++i)
{
for (j = i - i; j < 0x0A; ++j)
{
if ((j - j) == strncmp(russian + i, numerals[j], strlen(numerals[j])))
{
num *= 10;
num += j;
}
}
}
return num;
}

char *multiply(const char* a, const char* b)
{
unsigned int a1 = russianToInt(a);
unsigned int b1 = russianToInt(b);

while (a1 > 0)
{
a1 = a1 >> 1;
b1 = b1 << 1;
if (a1 & 0x01)
}
}

int main (int argc, const char * argv[]) {
return 0;
}
```
• astonerbum 2009-07-22 16:45
Beat by the system:
anyone done this in javascript?
function multiply (x, y, total)
{
(x == 0) ? alert(total) : multiply (Math.floor(x/2),Math.floor(y*2),(x % 2 == 0) ? total : total+y);
}

Also an inefficiency I had was not using shift for multiply by two. I added the y to itself. Also I coulda removed one comparison. Hey we want ultimate efficiency.

I still wonder if this algorithm is what is used for doing multiplication internally in the processor. Seems a WHOLE lot more efficient than doing addition a whole lota times, or even doing times tables or whatever... Those brilliant russian peasents :)

```function rpmult(x, y){
if (x === 0) {
return 0;
}
if (x === 1) {
return y;
}

var flip = false;
if (x < 0) {
x = -x;
flip = true;
}
var added = (((0x1 & num) === 0x1) ? 0 : y);
var recurse = rpmult(x >> 1, y << 1);
}
```
• Ted Walther, newLISP fan 2009-07-22 16:46
Unlike the perl one-liner, this newlisp one-liner is actually readable!

(define (rmul x y) (if (= x 1) y (+ (if (zero? (% x 2)) 0 y) (rmul (>> x) (<< y)))))
• Jeb Walter Strate 2009-07-22 16:46
My javascript version uses no multiplication, division, nor bit-shifting. Handles decimals, but negatives are left as an exercise for the reader.
```<html><head><title>Multiply WFT</title><script>
double={0:0,1:2,2:4,3:6,4:8,'.':'.'};
doubleNeedsCarry={5:0,6:2,7:4,8:6,9:8};
carriedDouble={0:1,1:3,2:5,3:7,4:9};
carriedDoubleNeedsCarry={5:1,6:3,7:5,8:7,9:9,'.':'.'};
halve={0:0,2:1,4:2,6:3,8:4,'.':'.'}
halveHasRemainder={1:0,3:1,5:2,7:3,9:4};
RemainderedHalve={0:5,2:6,4:7,6:8,8:9};
RemainderedHalveHasRemainder={1:5,3:6,5:7,7:8,9:9,'.':'.'};
function halveRow(row){
var cells=row.cells;
var out=document.createElement('tr');
var remaindered=false;
var visible='hidden';
for(var cellIndex=0;cellIndex<cells.length;cellIndex++){
var cell=cells[cellIndex];
var cellValue=cell.innerHTML;
var newCell=document.createElement('td');
if(remaindered==false){
if(cellValue in halve){
newCell.innerHTML=halve[cellValue];}
if(cellValue in halveHasRemainder){
newCell.innerHTML=halveHasRemainder[cellValue];}}
else if(remaindered=true){
if(cellValue in RemainderedHalve){
newCell.innerHTML=RemainderedHalve[cellValue];}
if(cellValue in RemainderedHalveHasRemainder){
newCell.innerHTML=RemainderedHalveHasRemainder[cellValue];}}
if(!remaindered && cellValue in halve || remaindered && !(cellValue in RemainderedHalveHasRemainder)){
remaindered=false;}
else{
remaindered=true;}
if(newCell.innerHTML=='0'){
newCell.style.visibility=visible;}
else if(newCell.innerHTML=='.'){
visible='';}
else
out.appendChild(newCell);}
if(newCell.innerHTML in halve){
out.style.textDecoration='line-through';}
row.parentNode.appendChild(out);
out.style.visibility='hidden';
return false;}
else{
function doubleRow(row){
var cells=row.cells;
var cellIndex=cells.length;
var out=document.createElement('tr');
var carried=false;
while(cellIndex--){
var cell=cells[cellIndex];
var cellValue=cell.innerHTML;
var newCell=document.createElement('td');
if(carried==false){
if(cellValue in double){
newCell.innerHTML=double[cellValue];}
if(cellValue in doubleNeedsCarry){
newCell.innerHTML=doubleNeedsCarry[cellValue];}}
else if(carried=true){
if(cellValue in carriedDouble){
newCell.innerHTML=carriedDouble[cellValue];}
if(cellValue in carriedDoubleNeedsCarry){
newCell.innerHTML=carriedDoubleNeedsCarry[cellValue];}}
if(!carried && cellValue in double || carried && !(cellValue in carriedDoubleNeedsCarry)){
carried=false;}
else{
carried=true;}
out.insertBefore(newCell,out.firstChild);}
if(carried!=false){
var newCell=document.createElement('td');
newCell.innerHTML=carriedDouble['0'];
out.insertBefore(newCell,out.firstChild);}
var tb=row.parentNode;
tb.appendChild(out);
if(row.cells.length==out.cells.length){}
else{
for(var i=0;i<tb.rows.length;i++){
while(tb.rows[i].cells.length<out.cells.length){
var blank=document.createElement('td');
blank.innerHTML='0';
blank.style.visibility='hidden';
tb.rows[i].insertBefore(blank,tb.rows[i].firstChild);}}}}
function multiply(form){
var a=form.inta.value;
var b=form.intb.value;
if(a.charAt(a.length-1)=='.'){a+='0'}
if(b.charAt(b.length-1)=='.'){b+='0'}
var row=document.getElementsByTagName('tr')[0];
var t=document.createElement('table');
t.cellSpacing=0;
var tb=document.createElement('tbody');
var tr=document.createElement('tr');
t.appendChild(tb).appendChild(tr);
var digits=a.split('');
for(var i=0;i<digits.length;i++){
var td=document.createElement('td');
td.innerHTML=digits[i];
tr.appendChild(td);}
if(digits[digits.length-1] in halve){
tr.style.textDecoration='line-through';}
row.cells[0].innerHTML='';
row.cells[0].appendChild(t);
row.cells[1].innerHTML='<table cellSpacing=0><tbody><tr><td>&nbsp;X</td></tr></tbody></table>';
t=document.createElement('table');
t.cellSpacing=0;
tb=document.createElement('tbody');
tr=document.createElement('tr');
t.appendChild(tb).appendChild(tr);
if(digits.pop() in halve){
tr.style.textDecoration='line-through';}
digits=b.split('');
for(var i=0;i<digits.length;i++){
var td=document.createElement('td');
td.innerHTML=digits[i];
tr.appendChild(td);}
row.cells[2].innerHTML='';
row.cells[2].appendChild(t);
while(halveRow(row.cells[0].firstChild.firstChild.lastChild) ){
doubleRow(row.cells[2].firstChild.firstChild.lastChild);
row.cells[2].firstChild.firstChild.lastChild.style.textDecoration=row.cells[0].firstChild.firstChild.lastChild.style.textDecoration
row.cells[1].firstChild.firstChild.insertRow(-1).insertCell(0).innerHTML='&nbsp;';}
row.cells[1].firstChild.firstChild.insertRow(-1).insertCell(0).innerHTML='&nbsp;';
row.cells[2].firstChild.firstChild.insertRow(-1).insertCell(0).innerHTML='&nbsp;';
row.cells[1].firstChild.cellSpacing=0;
t=document.createElement('table');
t.cellSpacing=0;
tb=document.createElement('tbody');
tr=document.createElement('tr');
t.appendChild(tb).appendChild(tr);
row.cells[3].innerHTML='';
row.cells[3].appendChild(t);
var decimala=0;
for(var i=0;i<row.cells[0].firstChild.firstChild.firstChild.cells.length;i++){
if(row.cells[0].firstChild.firstChild.firstChild.cells[i].innerHTML=='.'){
decimala=row.cells[0].firstChild.firstChild.firstChild.cells.length-i;
break}}
var decimalb=0;
for(var i=0;i<row.cells[2].firstChild.firstChild.firstChild.cells.length;i++){
if(row.cells[2].firstChild.firstChild.firstChild.cells[i].innerHTML=='.'){
decimalb=row.cells[2].firstChild.firstChild.firstChild.cells.length-i;
break}}
var r=row.cells[2].firstChild.firstChild.lastChild;
while(r=r.previousSibling){
var newRow=tb.insertBefore(r.cloneNode(true),tb.firstChild);
if(tb.firstChild.style.textDecoration){
tb.firstChild.style.visibility='hidden';}
if(decimala && decimalb){
var dec=newRow.removeChild(newRow.cells[newRow.cells.length-decimalb]);
newRow.insertBefore(dec, newRow.cells[newRow.cells.length-decimalb-decimala+2]);}
if(decimala && !decimalb){
var dec=document.createElement('td');
dec.innerHTML='.';
newRow.insertBefore(dec, newRow.cells[newRow.cells.length-decimala+1]);}}
var carry=0;
for(var i=tb.rows[0].cells.length;i;){
--i;
var t=carry*1;
carry=0;
for(var j=0;j<tb.rows.length-1;j++){
if(tb.rows[j].style.visibility=='hidden') continue;
if(tb.rows[j].cells[i].innerHTML=='.'){
carry=t;
t='.';
break;}
t+=parseInt(tb.rows[j].cells[i].innerHTML);}
if(t>9){
var s=t.toString().split('');
t=s.pop();
carry=s.join('');}
tb.lastChild.insertCell(0).innerHTML=t;}
if(carry!='0'){
for(j=0;j<tb.rows.length;j++){
var blank=document.createElement('td');
blank.innerHTML='0';
blank.style.visibility='hidden';
tb.rows[j].insertBefore(blank,tb.rows[j].firstChild);}
blank.innerHTML=carry;
blank.style.visibility='visible';}
row.cells[3].getElementsByTagName('tr')[row.cells[3].getElementsByTagName('tr').length-1].style.textDecoration='overline';}
</script>
<input name=inta><br>
<input name=intb><br>
<input type=submit value=multiply><br>
<table cellspacing=5><tbody><tr><td></td><td></td><td></td><td></td></tr></tbody></table>
</body></html>```
• Roger 2009-07-22 16:46
The program listed above produces this output
```Russian Peasant Multiplication
18    *             23    =            414
9                  46
4                  92
2                 184
1                 368
414
```
• WTF! 2009-07-22 16:51
My WTF is that I'd just create a huge times-table in MS Access and use DAO calls to read it back.
• Tom Medley - www.tommedley.com 2009-07-22 16:54
This problem is trivial in ML (4 lines):

fun peasant (1,r,q) = sum(r::q)
| peasant (l,r,q) = if(l mod 2 = 1)
then peasant((l div 2),(r*2),(r::q))
else peasant((l div 2),(r*2),q);

...a wrapper function to make it nice:

fun russian(x,y) = peasant(x,y,[]);

...and in case you need a sum function (most ml versions come with standard functions such as sum):

fun sum [] = 0
| sum (x::xs) = x + sum(xs);
• Rob H 2009-07-22 16:55
In C, C++, C#, taking zeros and negative numbers into account:

Recursive (not tested):
```INT Multiply(INT a, INT B)
{
INT c, PosNeg = 1;

// first, deal with zeros
if ((a == 0) || (b == 0))
return 0;

// now, deal with negative numbers
if (a < 0)
{
a = -a;
PosNeg = -PosNeg;
}
if (b < 0)
{
b = -b;
PosNeg = -PosNeg;
}

// now, the meat of the problem
if (a == 1)
return b;
else
return (b * (a & 1) + Multiply(a / 2, b * 2)) * PosNeg;
}```
Alternatively, if you use the following as the last line, you accomplish this using only one multiplication (the one dealing with +/-) and one division per step:
```    return ((a & 1) ? b : 0) + Multiply(a / 2, b + b)) *
PosNeg;```

Non-recursive (also not tested):
```INT Multiply(INT a, INT B)
{
INT c = 0, PosNeg = 1;

// first, deal with zeros
if ((a == 0) || (b == 0))
return 0;

// now, deal with negative numbers
if (a < 0)
{
a = -a;
PosNeg = -PosNeg;
}
if (b < 0)
{
b = -b;
PosNeg = -PosNeg;
}

// now, the meat of the problem
while (a > 0)
{
if (a & 1)
c += b;
a /= 2;
b *= 2; // or b += b; if you want to get rid of a multiplication
}
return c * PosNeg;
}```

(Of course, in C++ and C#, you would probably move the declarations for c and PosNeg down closer to where they're actually used.)
• qoo3h 2009-07-22 16:59

In Perl, implementing the algorithm as described, showing working:

#!/usr/bin/perl -w

use strict;

my \$a = shift or die( "need arg 1" );
my \$b = shift or die( "need arg 2" );
my \$neg = (\$a < 0 xor \$b < 0) ? -1 : 1;
my @nums;
for (\$a = abs \$a, \$b = abs \$b; \$a > 0; push(@nums,{'a'=>\$a, 'b'=>\$b}), \$a >>= 1, \$b <<= 1) {}
map {print "\$_->{'a'} + \$_->{'b'}\n" } @nums;
print( "###\n" );
@nums = grep {\$_->{'a'} % 2} @nums;
map {print "\$_->{'a'} + \$_->{'b'}\n" ;\$a += \$_->{'b'} } @nums;
print( 'sum: ', \$a * \$neg, "\n" );
• Lee Crabtree 2009-07-22 17:03
A Python solution. It could definitely be done in less code, but I'd rather be able to understand it.
```import math

def russian_multiply(x, y):
cols = [(x, y)]

while True:
x = int(math.floor(x / 2))
y = int(math.floor(y * 2))

cols.append((x, y))

if x <= 1:
break

col_sum = sum([c[1] for c in cols if c[0] % 2 != 0])

return col_sum

print russian_multiply(18, 23)
```
• J.I. 2009-07-22 17:04
Pretty similar in C;

int l(int l1, int ll) { return l1&-2?l1%2*ll+l(l1/2,ll*2):ll; }

Looks kind of like a traffic accident, doesn't it?
• ajp 2009-07-22 17:09
I didn't check to see if there was an F# one done yet or not. But here is my attempt.

```F# Version 1.9.6.16, compiling for .NET Framework Version v4.0.20506
#light
let isOdd x =
(x%2) = 1

let rec mult x y =
match x with
| 1 -> y
| _ when isOdd x -> y + mult (x/2) (y*2)
| _ -> mult (x/2) (y*2)```

• Andrew Rodland 2009-07-22 17:10
I was disturbed by the fact that the Perl uses the multiplication operator when it doesn't need to, so I offer:
```sub rp_mult {
my (\$i, \$j) = @_;
my \$r = 0;
do {
\$r += (\$j & 1) && \$i;
\$i <<= 1;
\$j >>= 1;
} while (\$i);
\$r;
}
```

Or, moderately golfed:
`sub rpmul{(\$r,\$i,\$j)=(0,@_);\$r+=\$j&1&&\$i,\$i<<=1,\$j>>=1while\$i;\$r;}`

Or, from a slightly different angle:
```use List::Util 'sum';
sub rp_mult {
my (\$i, \$j) = @_;
sum map \$j >> \$_ & 1 && \$i << \$_,
0 .. log \$j / log 2;
}
```
• sdeek 2009-07-22 17:11
python. Gratuitous use of list comprehensions and generators.
Doesn't work for negative numbers. Patches welcome ;-)

```a=22
b=66
import math
def half():
aa=a
while aa >=1:
yield aa
aa= aa/2
print sum([y for (x,y) in zip([x for x in half()],[b*(2**(x)) for x in range(0,len([x for x in half()])+1)]) if x%2==1])
```
• Michael Clark (mjac.co.uk) 2009-07-22 17:13
fun pmulti 1 r t = t + r
| pmulti l r t = pmulti (l div 2) (r * 2) (t + r * (l mod 2))

pmulti 3 4 0 will give you 3 * 4, t is just an accumulator
• opussf 2009-07-22 17:15
In Python:

a,b = 190, 232
if a<0: a=-a; b=-b
print sum([b<<s for s in xrange(0,int(math.log(a,2)+1)) if ((a>>s>0) and ((a>>s)%2)) ])

• KukkerMan 2009-07-22 17:25
```def rpmult(a, b):
rows = []
while a > 1:
rows.append( (a, b) )
a, b = a >> 1, b << 1
rows.append( (a, b) )
return reduce(lambda (_, b1), (__, b2): b1 + b2, filter(lambda (a, _): a & 1, rows))
```

• Jimmy Selgen 2009-07-22 17:26
Handles negative numbers (and unlike some of the examples i read, returns correct signs)

```class Rpm
def self.multiply(x1,x2)
ret = 0
is_neg = false

if x1 < 0
is_neg = true
x1 = -x1
end

if x2 < 0
is_neg = !is_neg
x2 = -x2
end

return 0 if x1 == 0

begin
ret += x2 if x1 % 2 != 0
x1 = (x1 / 2).floor
x2 = x2 * 2
end while( x1 >= 1)

ret = -ret if is_neg
return(ret)
end
end```
• Tiogshi 2009-07-22 17:29
For maximum speed, I pre-allocate the tables I use for storage, and avoid all floating-point multiplies and divides. A complete executable program in Lua; run with an argument (any argument) for the peasant-product, without to use the baseline-for-testing "Gold" function.

```function Gold(a, b)
return a * b
end

function DivideByTwo(n)
local m = n
while m + m > n do
m = m - 1
end
return m
end

function AllocateTable(a)
local t = {}
while a >= 1 do
a = DivideByTwo(a)
t[#t + 1] = {}
end
return t
end

function AllocateColumnTable(t)
for i = 1, #t do
t[i].aColumn = 0
t[i].bColumn = 0
end
end

function AllocateValidTable(t)
for i = 1, #t do
t[i].truth = false
end
end

function TestIsOdd(n)
n = math.abs(n)

while n > 1 do
n = n - 2
end

if n == 0 then
return false
elseif n == 1 then
return true
else
print("unknown failure")
os.exit(-1)
end
end

function PopulateTable(t, a, b)
for i = 1, #t do
local j = i - 1
local aC, bC = a, b
while j > 0 do
if TestIsOdd(aC) then
aC = DivideByTwo(aC - 1)
else
aC = DivideByTwo(aC)
end

bC = bC + bC

j = math.floor(j - 1)
end

t[i].aColumn = aC
t[i].bColumn = bC
end
end

function CollectValidRows(t, v)
local n = math.min(#t, #v)
for i = 1, n do
if TestIsOdd(t[i].aColumn) then
v[i].truth = true
end
end
end

function SumValidRows(t, v)
local n = math.min(#t, #v)
local sum = 0
for i = 1, n do
if v[i].truth == true then
sum = sum + t[i].bColumn
end
end
return sum
end

function PeasantProduct(a, b)
local columTable = AllocateTable(a)
local validTable = AllocateTable(a)

AllocateColumnTable(columTable)
AllocateValidTable(validTable)

PopulateTable(columTable, a, b)
CollectValidRows(columTable, validTable)

return SumValidRows(columTable, validTable)
end

function DoTest(f)
-- Generated by fair dice roll. Guaranteed to be random.
math.randomseed(4)

for n = 1, 1000 do
local a = math.random(1, 200)
local b = math.random(1, 200)
print( string.format("%d * %d = %d", a, b, f(a,b)))
end
end

local args = {...}

if args[1] then
print("Peasant")
DoTest(PeasantProduct)
else
print("Baseline")
DoTest(Gold)
end```
• ikegami 2009-07-22 17:31
As a circuit diagram

(Handles 4-bit unsigned integers)

The selection of input wires for AND gates perform the right shifts.
The AND gates perform the oddness test.
The selection of input wires for the adders perform the left shifts.

I forgot to mention this was done in MS Paint
• Eric 2009-07-22 17:31

```(defun multiply (x y)
(loop
with result = 0
for first = x then (floor first 2)
for second = y then (* second 2)
if (oddp first)
do (incf result second)
if (= first 1)
do (return result)))

(defun trmultiply (x y)
(labels
((inner
(x y acc)
(if (> x 0)
(inner (floor x 2)
(* y 2)
(if (oddp x) (+ y acc) acc))
acc)))
(inner x y 0)))```
• Yorick 2009-07-22 17:31
Speccy basic, recursive:
```  10 DEF FN m(a,b)=VAL ((("FN m(
"+STR\$ a+"*2,INT ("+STR\$ b+"/2))
+("+STR\$ b+"-2*INT ("+STR\$ b+"/2
))*"+STR\$ a) AND b<>1)+(STR\$ a A
ND b=1))
```

• mol1111 2009-07-22 17:35
Originally I thought about sending 1235th boring C# version or 436th Python version but then I realized that there is no GUI version (except for few PHP or JS versions with HTML WUI [Web User Interface :-) ]). So I created one using my all-time favourite library: Turbo Vision (so it's really TUI and not GUI). Tested with BP7 and recent FreePascal.
```program RussianMultiplicationTV;

uses App, Dialogs, Drivers, Menus, MsgBox, Objects, Validate, Views;

const
cmCalculate = 1001;

type
TRussMultApp = object(TApplication)
procedure HandleEvent(var Event: TEvent); virtual;
procedure ExecuteMainDlg;
end;

PMainDlg = ^TMainDlg;
TMainDlg = object(TDialog)
ResultListBox: PListBox;
FirstInputLine: PInputLine;
SecondInputLine: PInputLine;
constructor Init;
procedure HandleEvent(var Event: TEvent); virtual;
end;

function Calculate(x, y: longint): PCollection;
type
TFormatRec = record
Line, X, Y, Extra: longint;
end;
var
List: PStringCollection;
TempStr: String;
FormatRec: TFormatRec;
begin
New(List, Init(10, 10));
List^.Insert(NewStr(#0 + 'Step    First   Second    Extra'));
FormatRec.Line := 1;
FormatRec.Extra := 0;
while (x > 0) do begin
FormatRec.X := x;
FormatRec.Y := y;
Inc(FormatRec.Extra, (x mod 2) * y);
FormatStr(TempStr, '%5d %8d %8d %8d', FormatRec);
List^.Insert(NewStr(TempStr));
x := x shr 1;
y := y shl 1;
Inc(FormatRec.Line);
end;
List^.Insert(NewStr(' ------'));
Str(FormatRec.Extra, TempStr);
List^.Insert(NewStr(' Result = ' +  TempStr));
Calculate := List;
end;

procedure TRussMultApp.ExecuteMainDlg;
var
Dlg: PMainDlg;
begin
New(Dlg, Init);
ExecuteDialog(Dlg, nil);
end;

procedure TMainDlg.HandleEvent(var Event: TEvent);
var
x, y: longint;
code: integer;
begin
inherited HandleEvent(Event);
if (Event.What = evCommand) and (Event.Command = cmCalculate) then begin
Val(FirstInputLine^.Data^, x, code);
if code <> 0 then begin
MessageBox('Please put valid number into the first input field.', nil,
mfError or mfOKButton);
exit;
end;
Val(SecondInputLine^.Data^, y, code);
if code <> 0 then begin
MessageBox('Please put valid number into the second input field.', nil,
mfError or mfOKButton);
exit;
end;
ResultListBox^.NewList(Calculate(x, y));
ClearEvent(Event);
end;
end;

procedure TRussMultApp.HandleEvent(var Event: TEvent);
begin
inherited HandleEvent(Event);
if ((Event.What = evCommand) and (Event.Command = cmNew)) then begin
ExecuteMainDlg;
ClearEvent(Event);
end;
end;

var
R: TRect;
begin
GetExtent(R);
R.B.Y := R.A.Y + 1;
NewItem('~C~alculator', '', kbNoKey, cmNew, 0,
NewItem('E~x~it', 'Alt+X', kbAltX, cmQuit, hcExit,
nil)))));
end;

constructor TMainDlg.Init;
var
R: TRect;
ScrollBar: PScrollBar;
S: String[8];
begin
R.Assign(0, 0, 60, 20);
inherited Init(R, 'Russian Multiplication');
Options := Options or ofCentered;

R.Assign(2, 2, 12, 3);
New(FirstInputLine, Init(R, 8));
FirstInputLine^.SetValidator(New(PRangeValidator, Init(1, 1000)));
Str(Random(9999) + 1, S);
FirstInputLine^.SetData(S);
Insert(FirstInputLine);
R.Assign(14, 2, 26, 3);
New(SecondInputLine, Init(R, 8));
SecondInputLine^.SetValidator(New(PRangeValidator, Init(1, 1000)));
Str(Random(999) + 1, S);
SecondInputLine^.SetData(S);
Insert(SecondInputLine);
R.Assign(27, 2, 45, 4);
Insert(New(PButton, Init(R, 'Calculate!', cmCalculate, bfDefault)));
R.Assign(57, 4, 58, 19);
New(ScrollBar, Init(R));
Insert(ScrollBar);
R.Assign(2, 4, 57, 19);
New(ResultListBox, Init(R, 1, ScrollBar));
Insert(ResultListBox);

{ Selects first input box }
SelectNext(False);
end;

var
RussMultApp: TRussMultApp;

begin
Randomize;
RussMultApp.Init;
RussMultApp.Run;
RussMultApp.Done;
end.```

• Edinburgh Mike 2009-07-22 17:36
#!/usr/bin/env python

def rus_mult(A, B):
if A == 1:
return B
else:
return rus_mult(A / 2, B * 2) + (A % 2) * B

def run_tests():
tests = [(18, 23), (12, 3), (1, 1), (15, 2), (8, 22), (7, 13), (9, 20)]

for (A, B) in tests:
print "Test", A, "*", B, "Result:", rus_mult(A, B) == A * B

if __name__ == "__main__":
run_tests()
• Lernin ur codez 2009-07-22 17:42
C#, handles negative numbers 0, 1.

And, as usual, the most elegant solution is the recursive one.

```private int RussianPeasant(int a, int b)
{
int c;
if (a < 0)
{
a = -a;
b = -b;
}
for (c = (a & 1) * b; (a > 1); c += ((a >>= 1) & 1) * (b <<= 1)) ;
return c;
}

private int RecursiveRussianPeasant(int a, int b)
{
if (a < 0)
return RecursiveRussianPeasant(-a, -b);
return (a == 0) ? 0 : ((a & 1) * b) + RecursiveRussianPeasant(a >> 1, b << 1);
}

```
• Redredredredredred 2009-07-22 17:47
theres some ruby code for you

```def rmul(a,b)
ret = 0
begin
ret = (a<0) ? ret-b : ret+b if a%2==1 or a%2==-1
a = (a<0) ? a/2 + a%2 : a/2
b = b*2
end while a != 1 and a != -1 and a != 0
ret = (a<0) ? ret-b : ret+b if a%2==1 or a%2==-1
ret
end

puts rmul(-10,20)
puts rmul(10,20)
puts rmul(-3,500)
puts rmul(1002,343)```
• Kevin Kofler 2009-07-22 17:48
Here's one in Motorola 68000 assembly:
```.xdef __mulsi3
__mulsi3:
move.l 4(%a7),%d1
move.l 8(%a7),%d2
moveq.l #0,%d0
0:
lsr.l #1,%d1
bcc.s 1f
1:
tst.l %d1
bne.s 0b
rts```

Note that this one is actually useful, it can be used if you don't have a working libgcc for your target. :-) Though that one is faster. ;-)

That said, on CPUs like the Z80 which don't have a native multiplication instruction, Russian Peasant is actually extremely useful.
• Rasmus 2009-07-22 17:52
def Mul(a,b):
return DirectionsFromLeaders( "mul", a, b )

example:

> Mul(3,56)
: Illegal Question, Caller terminated
• H2 2009-07-22 17:58
My Perl-solution with optimization, a bit of math and several tests. It also handles negative numbers.

```#/usr/bin/perl
use strict;
use warnings;

if ((@ARGV != 2) || (\$ARGV[0]!~m/\d/) || (\$ARGV[1]!~m/\d/)) {
print "Missing or wrong arguments! Need two integers\n";
exit(0);
}

my (\$left,\$right)=@ARGV;

if (\$right lt \$left) {
my \$temp=\$right;
\$right=\$left;
\$left=\$temp;
}

my \$negative=1;

if (\$left==1) {
print \$right."\n";
exit(0);
}
elsif (\$left==0) {
print "0\n";
exit(0);
}
elsif ((\$left lt 0) && (\$right lt 0)) {
\$left*=-1;
\$right*=-1;
}
elsif ((\$left lt 0) || (\$right lt 0)) {
\$left=abs(\$left);
\$right=abs(\$right);
\$negative=-1;
}

my \$result=0;
for (my \$iteration=int(log(\$left)/log(2));\$iteration>=0;\$iteration--) {
if (\$left%2!=0) {
\$result+=\$right;
}
\$left=int(\$left/2);
\$right*=2;
}
print \$negative*\$result."\n";```
• Ben 2009-07-22 17:59
ath:
Same thing in python:
```def is_odd(n):
return (n % 2) != 0

def rmul(x, y):
s = 0
while(x != 1):
if is_odd(x):
s += y
x /= 2
y *= 2
return y + s
```

Funnily enough, I did the same thing... then realized that is_odd() can be superseded by the simple statement "if (num%2)".
Mine prints output, but it's basically the same. I wasn't aware that Python supported +=, though.
• Sam 2009-07-22 18:07
```#include <libgen.h>
#include <stdio.h>
#include <stdlib.h>

int main(int argc, char **argv)
{
int lhs, rhs;
int res;

if (argc != 3) {
printf("usage: %s <lhs> <rhs>\n", basename(argv[0]));
return (1);
}

lhs = atoi(argv[1]);
rhs = atoi(argv[2]);

res = 0;
while (lhs > 1) {
if (lhs % 2 == 1) {
res += rhs;
}
lhs /= 2;
rhs *= 2;
}

res += rhs;

printf("result: %d\n", res);

return (0);
}
```
• PatrickBeebe 2009-07-22 18:08
In c#

public static int RussianMultiplication(int x, int y)
{
if ((y >> 31 | 1) * y < (x >> 31 | 1) * x)
y = (x + y) - (x = y);

int result = 0;
for (result = 0; x != 0; x /= 2, y >>= 1)
result += ((x >> 31) | 1) * ((0 - (x & 1)) & y);

return result;
}

Handles 0, negatives, and optimizes which digits to place in which column.

And. Fast.

Whoops, that should have been:

public static int RussianMultiplication(int x, int y)
{
if ((y >> 31 | 1) * y < (x >> 31 | 1) * x)
y = (x + y) - (x = y);

int result = 0;
for (result = 0; x != 0; x /= 2, y += y)
result += ((x >> 31) | 1) * ((0 - (x & 1)) & y);

return result;
}
• mwchase 2009-07-22 18:11
Bah, one-liners. I figured I'd write my code in true WTF style.

```#!/usr/bin/env python

def mult(a, b):
d = {a: b}
if d.keys() == [0] or d.values() == [0]:
return 0
if d.keys() < [0]:
return mult(*(increment(~d.keys()[0]), increment(~d.values()[0])))
extend(d)
[d.__delitem__(k) for k in d.keys() if not k&1]
return sum(d.values())

def extend(d):
d[min(d.keys())>>1] = (d[min(d.keys())])<<1
if min(d.keys()) != 1 and min(d.keys()) != 0:
extend(d)
return

def increment(x, p=0):
if x & (1<<p):
return increment(x^(1<<p), increment(p))
return x | (1<<p)```

Note that I only used arithmetic-related stuff on the lists. Everything else is done bit-wise. See if you can spot the weird abuses and seemingly-random edge cases! (Hint: if there's code that doesn't seem to serve much of a purpose, especially in an if-statement, it's probably deflecting execution around an infinite loop. Either that or I thought it would be funny.)

Looking back on this, it turns out I could have made parts of it even worse. The if-statement in extend, for example, could use instead "min(d.keys())&-2" (or ~1, if you like. The values are equivalent)

I think the lesson to take away from this is, if any potential employers decided to see if Google knew about my python experience, this is all a joke.
• LeCoyote 2009-07-22 18:11
Two PHP functions in there: the first one does the maths, the second one displays a (very) barren page detailing the steps.
```<?php
function motherland(\$a,\$b)
{
\$r=0 ;
while(\$a)
{
(\$a%2) && \$r+=\$b ;
\$a>>=1 ;
\$b<<=1 ;
}
return \$r ;
}

function motherland2(\$a,\$b)
{
\$r = 0 ;
\$o = "<table>";
while(\$a)
{
\$t = " text-decoration: line-through" ;
\$o .= "<tr style='text-align: right;";
(\$a % 2) && list(\$r,\$t) = array(\$r+\$b,"") ;
\$o .= "\$t'><td>\$a</td><td>x</td><td>\$b</td></tr>";
\$a >>= 1 ;
\$b <<= 1 ;
}
\$o .= "<tr><td></td><td></td><td>\$r</td></table>";
return \$o ;
}
echo motherland2(167, 24);
echo motherland(167, 24);
?>
```

Fun :-)
Syntax highlighting was just ... too much free time ;)
• AshG 2009-07-22 18:17
ikegami:
As a circuit diagram

(Handles 4-bit unsigned integers)

The selection of input wires for AND gates perform the right shifts.
The AND gates perform the oddness test.
The selection of input wires for the adders perform the left shifts.
This one rocks! But you need to expand adders as well, either on a separate sheet or the same one. Also show the transistor logic for each AND gate and adders.
• Florent 2009-07-22 18:24
\$ perl -E'(\$i,\$j)=@ARGV;while(\$i){(\$i!=int(\$i/2)*2||!int(\$i/2))&&(\$k+=\$j);\$j*=2;\$i=int(\$i/2)}say\$k' 18 23
414
\$
Here's my code in python:
```def mul(a,b):
m=[(a,b)]
while(m[-1][0]<>1):
m.append((m[-1][0]/2, m[-1][1]*2))
return sum([x[1] for x in m if x[0]%2==1])
```
• dee 2009-07-22 18:34
I'm a little disappointed that I haven't seen any submissions in the language actually used to perform Important tasks involving numbers: COBOL.

```       IDENTIFICATION DIVISION.
PROGRAM-ID.  RussianPeasantMultiplication.

DATA DIVISION.
WORKING-STORAGE SECTION.
01 FirstNumber    PIC S9(18).
01 SecondNumber   PIC S9(18).
01 Result         PIC S9(18) VALUE 0.
01 ResultFormat   PIC ------------------9.

PROCEDURE DIVISION.
MAIN.
PERFORM DATA-ACQUISITION.
PERFORM PEASANT-MULTIPLICATION-PROCEDURE.
STOP RUN.

DATA-ACQUISITION.
DISPLAY "First number: " WITH NO ADVANCING.
ACCEPT FirstNumber.
DISPLAY "Second number: " WITH NO ADVANCING.
ACCEPT SecondNumber.

PEASANT-MULTIPLICATION-PROCEDURE.
IF FirstNumber IS NEGATIVE THEN
COMPUTE FirstNumber = - FirstNumber
COMPUTE SecondNumber = - SecondNumber
END-IF.

PERFORM UNTIL FirstNumber IS ZERO
IF FUNCTION MOD(FirstNumber 2) = 1 THEN
END-IF
DIVIDE FirstNumber BY 2 GIVING FirstNumber
ADD SecondNumber TO SecondNumber GIVING SecondNumber
END-PERFORM.

MOVE Result TO ResultFormat.
DISPLAY 'Result: ' ResultFormat.
```

Tested with OpenCobol 1.0.
• Florent 2009-07-22 18:35
Or shorter :
\$ perl -E'(\$i,\$j)=@ARGV;while(\$i){(\$i%2||!\$i/2)&&(\$k+=\$j);\$j*=2;\$i=int(\$i/2)}say\$k' 18 23
414
\$
• valderman 2009-07-22 18:37
IMO, the peasants aren't actually multiplying and dividing by two, rather, they're doubling and halving numbers, a less generic but far simpler operation, that's why using * and / is cheating.

Anyway, some more Haskell. This one handles negative numbers (don't think any Haskell entry so far does that,) is tail recursive AND uses type classes!

```import Data.Bits (shiftL, shiftR, Bits)

rmult :: (Integral a, Bits a) => a -> a -> a
rmult a b | a < 0     = - (rmult (-a) b)
| a < 0     = - (rmult a (-b))
| otherwise = go 0 a b where
go acc 0 b = acc
go acc a b = go (acc + if odd a then b else 0)
(a `shiftR` 1)
(b `shiftL` 1)```
• valderman 2009-07-22 18:38
Oops, that second | a < 0 ... should be | b < 0 ...!
• RayS 2009-07-22 18:47
Updated from earlier post that I never bothered to updeate correctly.

done in wonderful VBA, and just like in the article, shows full manual working out table in the debug window. Works with negatives, zeros, hopefully everything really. I stuck to the principle and process of the manual process instead of taking shortcuts.

```Public Function RussianMultiply(x As Long, y As Long) As Long
Dim vals() As Long
ReDim vals(1 To Round(Sqr(Abs(x)), 0) + 1, 1 To 2) As Long
Dim i As Long, j As Long, c As Long, Msg As String, s As Long
s = Sgn(x) * Sgn(y)
i = 1
Do Until x = 0
vals(i, 1) = x
vals(i, 2) = y
i = i + 1
x = x \ 2
y = y * 2
Loop
For j = 1 To i - 1
If vals(j, 1) / 2 = vals(j, 1) \ 2 Then
Msg = " X"
Else
c = c + (s * Abs(vals(j, 2)))
Msg = s * Abs(vals(j, 2))
End If
Debug.Print vals(j, 1) & vbTab & vals(j, 2) & vbTab & Msg
Next
Debug.Print vbCrLf & "=" & vbTab & c
RussianMultiply = c
End Function
```

Sample output
```>RussianMultiply 18,23

18  23   X
9   46  46
4   92   X
2   184  X
1   368 368

=   414```
• Fred Dagg 2009-07-22 18:55
package test;

import java.util.ArrayList;
import java.util.List;

public class RussianMultiplication {

public RussianMultiplication() {}

public long multiply(long parameter1, long parameter2) {
if (parameter2 < parameter1) {
return handleMultiplication(parameter2, parameter1);
} else {
return handleMultiplication(parameter1, parameter2);
}
}

private long handleMultiplication(long lhs, long rhs) {
List<RussianNumber> numberList = new ArrayList<RussianNumber>();
while (lhs > 1) {
lhs = lhs / 2;
rhs = rhs * 2;
}
long result = 0;
for (RussianNumber number : numberList) {
if (number.getLhs() % 2 != 0) {
result = result + number.getRhs();
}
}
return result;
}

public static void main(String[] args) {
RussianMultiplication rm = new RussianMultiplication();
long result = rm.multiply(23, 18);
System.out.println("Result: " + result);
}

private class RussianNumber {
private long lhs;
private long rhs;

public RussianNumber(long lhs, long rhs) {
this.lhs = lhs;
this.rhs = rhs;
}

public long getLhs() {
return lhs;
}

public void setLhs(long lhs) {
this.lhs = lhs;
}

public long getRhs() {
return rhs;
}

public void setRhs(long rhs) {
this.rhs = rhs;
}

public String toString() {
return lhs + "::" + rhs;
}
}

}
• DFHawthorne 2009-07-22 18:55
Another Oracle SQL Example:

```SQL> VARIABLE left_num NUMBER
SQL> VARIABLE right_num NUMBER
SQL> BEGIN
:left_num := 18;
:right_num := 23;
END;
PL/SQL procedure successfully completed.
Elapsed: 00:00:00.06
SQL> SELECT     SUM (DECODE (MOD (TRUNC (:left_num / POWER (2, ROWNUM - 1), 0), 2),
1, :right_num * POWER (2, ROWNUM - 1)
)
) AS RESULT
FROM DUAL
CONNECT BY TRUNC (:left_num / POWER (2, ROWNUM - 1), 0) > 0

RESULT
----------
414

1 row selected.
Elapsed: 00:00:00.06
```
• Jukka 2009-07-22 19:00
```def russian_peasant(x,y):
steps=[(x,y)]
while x>1 or x<-1:
x/=2
y*=2
steps.append((x,y))
return sum([y for x,y in steps if x % 2 == 1]) * x # * x is there to give the correct sign for the result

# Test it
print russian_peasant(18,23), 18*23
print russian_peasant(18,0), 18*0
print russian_peasant(-2,400), -2*400
print russian_peasant(40,-30), 40*-30
print russian_peasant(40,30), 40*30
```
• mjomble 2009-07-22 19:04
How about a good dose of OOM?

The code's too long to post here, but beyond this link you can enjoy it in fully highlighted PHP syntax: http://justas.ggcmedia.com/MultiplicationFramework.html (usage example at the end of the file)

Sample output:
```Multiplying 18 by 23 Russian peasant style:

Numeric result: 414

Full result:
18 x  23 |   0 +
9 x  46 |  46 +
4 x  92 |   0 +
2 x 184 |   0 +
1 x 368 | 368 =
----------------
Total: 414```

...hmm, I need to go clean my hands now.
• spiderlama 2009-07-22 19:14
int mul_rus(int a, int b)
{
int c = 0;

while (a != 1)
{
if (a & 1)
c += b;

a >>= 1;
b <<= 1;
}

return b + c;
}
• unit3 2009-07-22 19:23
Here's a fairly straightforward implementation in common lisp:
```(defun mult (x y)
(if (= x 1)
y
(+ (if (= (rem x 2) 0) 0 y) (mult (floor (/ x 2)) (* y 2)) )
)
)
```

It could be all on one line, but that'd be harder to read. If someone has suggestions on how to simplify it, that'd be great. :)
• Gumpy Guss 2009-07-22 19:24
In PDP-8 assembly language. Untested

X, 0
Y, 0
Z, 0

RUSMUL, 0 // entry point
CLA
DCA Z / clear total

SNA
JMP DONE

ROR
DCA X
SZL CLA
DCA Z
ROL
DCA Y
JMP LP

JMP I RUSMUL

• Crindigo 2009-07-22 19:29
Sloppy JS version with animated step-by-step output: http://crindigo.com/stuff/praxis.html
• Warr 2009-07-22 19:30
Uses NO math operations, only regex and string operations. Almost all major work is kept in the global \$_ variable. Numbers are represented internally using a base-30-like system, then converted directly back to decimal at the end of each operation. Some assumptions about collating sequence were made (e.g. \d == [0-9]).

```#!/usr/bin/perl
\$_ = join(' ', @ARGV);
m#^\s*-?\d+\s*x\s*-?\d+\s*# or die('Input should be in "#### x ####" format.');
\$sign = '+'; while(s#-##) { \$sign =~ tr#+-#-+#; }
s#\s##g;
s#\$#=0#;
while(!m#^0*x#)
{
s#(?<!\d)(\d)#0\$1#g;
if(m#\d+[13579]x#)
{
s#(.*x)(.*)(=.*)#\$1\$2\$3+\$2#;
while(m#(.*)(\d)([a-jA-J]?)([a-jA-J]*\+\d*)(\d)(.*)#)
{
my(\$a, \$b, \$c, \$d, \$e, \$f);
\$a = \$1; \$b = \$2; \$c = \$3; \$d = \$4; \$e = \$5; \$f = \$6;
while(\$e =~ m#[^a0]#)
{
\$e =~ tr#1-9#a1-8#;
\$b =~ tr#0-9a-jA-I#b-jAb-jA-J#;
}
\$e =~ tr#0#a#; \$b =~ tr#0-9#a-j#;
\$c =~ m#[A-J]# and \$b =~ tr#0-9a-jA-J#b-jAb-jA-J#;
\$_ = \$a . \$b . \$c . \$d . \$e . \$f;
s#=(?!0)#=0#;
}
while(m#(.*)(\d)([A-J].*\+)#)
{
\$x = \$2;
\$x =~ tr#0-9#b-jA#;
\$_ = \$1 . 0 . \$x . \$3;
}
tr#a-jA-J#0-90-9#;
s#\+.*##;
}
if(m#^(\d)(.*)#)
{
\$x = \$1;
\$x =~ tr#0-9#aAbBcCdDeE#;
\$_ = \$x . \$2;
}
while(m#^([A-Ja-j]*?)([A-Ja-j]?)(\d)(.*)#)
{
my(\$a, \$b, \$c, \$d);
\$a = \$1; \$b = \$2; \$c = \$3; \$d = \$4;
\$b =~ m#[a-j]# and \$c =~ tr#0-9#aAbBcCdDeE#
or \$c =~ tr#0-9#fFgGhHiIjJ#;
\$_ = \$a . \$b . \$c . \$d;
}
tr#A-Ja-j#0-90-9#;
if(m#^(.*)(\d)(=.*)#)
{
\$x = \$2;
\$x =~ tr#0-9#acegiACEGI#;
\$_ = \$1 . \$x . \$3;
}
while(m#(.*?)(\d)([A-Ja-j]?)([A-Ja-j]*=.*)#)
{
my(\$a, \$b, \$c, \$d);
\$a = \$1; \$b = \$2; \$c = \$3; \$d = \$4;
\$c =~ m#[a-j]# and \$b =~ tr#0-9#acegiACEGI#
or \$b =~ tr#0-9#bdfhjBDFHJ#;
\$_ = \$a . \$b . \$c . \$d;
}
tr#A-Ja-j#0-90-9#;
s#(?<!\d)0+(?=\d|0(?!\d))##g;
}
s#.*=##;
s#^#\$sign#;
s#^\+##;
s#\$#\n#;
print;```
• Paul N 2009-07-22 19:48
--SQL Server using Common Table Expression

DECLARE @number1 int;
DECLARE @number2 int;

SET @number1 = 18;
SET @number2 = 23;

WITH Multiplication (Row, Factor1, Factor2) AS
(
SELECT 1, @number1, @number2
UNION ALL
SELECT Row + 1, Factor1 / 2, Factor2 * 2
FROM Multiplication
WHERE Factor1 > 1
)
SELECT SUM(Factor2) FROM Multiplication
WHERE Factor1 % 2 = 1;
• Wheaties 2009-07-22 19:53
func(a, b):
if(a == 1)
return b
if(a%2 == 1)
return b*2 + func(a/2, b*2)
else
return func(a/2, b*2)

Had to do it with recursion. I can't think of a reason why not to do it that way. I also haven't looked at the comments. Someone probably came up with this solution or it has already been shown to be wrong. I could also shrink it to be a single line but then it wouldn't be nearly as readable.
• Paul N 2009-07-22 19:56
--It works better as a stored procedure

SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
-- =============================================
-- Author: Paul N
-- Create date: 7/22/2009
-- Description: multiplies two numbers using
-- Russian Peasant Multiplication
-- =============================================
CREATE PROCEDURE dbo.[Russian Peasant Multiplication]
-- Add the parameters for the stored procedure here
@number1 int,
@number2 int
AS
BEGIN
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON;

-- Insert statements for procedure here
WITH Multiplication (Row, Factor1, Factor2) AS
(
SELECT 1, @number1, @number2
UNION ALL
SELECT Row + 1, Factor1 / 2, Factor2 * 2
FROM Multiplication
WHERE Factor1 > 1
)
SELECT SUM(Factor2) FROM Multiplication
WHERE Factor1 % 2 = 1;
END
GO
• yowzer 2009-07-22 19:59
open List

let oddcar (n, _) = (n land 1) = 1
let sum = fold_left (+) 0

let rec do_mul = function
| (x,_) :: _ as lst when x == 1 ->
sum (map snd (filter oddcar lst))
| (x,y) :: _ as lst ->
do_mul ((x / 2, y * 2) :: lst)

let mul x y =
do_mul [x,y]

• Veryth 2009-07-22 20:12
C# + LINQ
```int Multiply(int x, int y)
{
return Enumerable.Range(0, (int)(1.0 + Math.Log(x)/Math.Log(2)))
.Select(i => new {x = x >> i, y = y << i})
.Where(p => p.x > 0 && p.x % 2 == 1)
.Sum(p => p.y);
}
```

More LINQ-ish:
```int Multiply(int x, int y)
{
return (
from i in Enumerable.Range(0, (int)(1.0 + Math.Log(x)/Math.Log(2)))
where (x >> i) % 2 == 1
select y << i
).Sum();
}
```
• Mike McNally 2009-07-22 20:12
simple erlang:
```-module(rmult).
-export([rmult/2]).

rmult(M1, M2) -> rmult(M1, M2, [{M1, M2}]).

rmult(1, _, P) -> rsum(P, 0);
rmult(M1, M2, P) ->
M1n = M1 div 2, M2n = M2 * 2,
rmult(M1n, M2n, [{M1n, M2n} | P]).

rsum([], S) -> S;
rsum([{M, _} | P], S) ->
rsum(P, S + case M rem 2 of 0 -> 0; 1 -> M end).
```
• bd_ 2009-07-22 20:19
```; Rabbit 2000 assembler
; Inputs in A, B
; Result in HL

ld d, 0
ld e, b 		;; DE = second operand
ld hl, 0		;; accum = 0
or a
;; For the first iteration, we need to just test whether the second
;; operand is even, rather than using a side effect of the rotate
bit 0, a
..mul_loop:
jr nc, ..odd
..odd:
or a			;; CF = 0
jr z, ..done	;; A = 0?
rl de			;; DE *= 2
rr a			;; A /= 2. CF can't be nonzero as that would imply overflow
jr ..mul_loop	;; CF from A is used on next iteration
..done:
;; result in HL```
• Twey 2009-07-22 20:19
This is, of course, a one- or two-liner (depending how long you like your lines) in Haskell and probably most other functional languages:

```-- Just for neatness; without this, ((`div` 2) *** (* 2)) can be
--  written (\(a, b) -> (a `div` 2, b * 2))
import Control.Arrow ((***))

rus n m = sum . map snd . filter ((/= 0) . (`mod` 2) . fst)
. takeWhile ((> 0) . fst) \$ iterate ((`div` 2) *** (* 2)) (n, m)
```

Or adding some labels for clarity:

```rus n m = sum . rightColumn . filter hasOddRight
. takeWhile nonZeroLeft \$ makeColumns (n, m)
where rightColumn       = map snd
hasOddRight       = (/= 0) . (`mod` 2) . fst
makeColumns       = iterate multiplyAndDivide
multiplyAndDivide = ((`div` 2) *** (* 2))
nonZeroLeft       = ((> 0) . fst)
```
• Mike McNally 2009-07-22 20:22
oops the last 2 lines are busted (great idea to refactor just before posting :-)

```  rsum([M, N} | P], S) ->
rsum(P, S + case M rem 2 of 0 -> 0; 1 -> N end).
```
• tdh 2009-07-22 20:34
Not the shortest or simplest bit of code, but a pretty elegant way of mirroring the Russian Peasant method, as opposed to looking more like binary multiplication.

Python:
```def multiply(a, b):
def pairs():
nonlocal a, b
while a:
yield a, b
a //= 2
b *= 2
return sum(j for (i, j) in pairs() if i % 2)
```
• brian 2009-07-22 21:19
I'm sure this is lost in the haze:
```int peasant(int x, int y)
{
int result = 0;

do
{
result += (x % 2) * y;
x /= 2;
y *= 2;
}
while(x > 0);

return result;
}
```

Didn't bother with bitshifting. Looking at the generated assembly is an interesting excersize.
• 0ffh 2009-07-22 21:25
I feel daring today and throw this in untested.
thx for spoiler alert i did it in a text editor
before scrolling down to comment. =)

// russian multiply
// the usual limitations on result size apply
int ru_mul(int fac0,int fac1) {
int prod=0;
do {
prod+=(fac0&1)*fac1;
fac1<<=1;
} while (fac0>>=1);
return prod;
}
• 0ffh 2009-07-22 21:27
the wtf is of course that my spaces got eaten... =)
• Bob 2009-07-22 21:35
echo "In soviet russia, multiplication does YOU!"
• 0ffh 2009-07-22 21:48
nah, the real wtf is:
ye shouldnae do sucha thing that i did there:
late night surfing on coding sites while not sober.
speaking of test-driven development, hihi!
take brians solution!
• Thomas Eyde 2009-07-22 21:50
```using Microsoft.VisualStudio.TestTools.UnitTesting;

namespace RussianPeasantMultiplication
{
/// <summary>
/// The biggest WTF, of course, is there are tests!
/// </summary>
[TestClass]
public class Multiply_numbers
{
[TestMethod]
public void Multiply_some_numbers()
{
Assert.AreEqual(18*23, WtfPeasantCalculator.Multiply(18, 23));
Assert.AreEqual(0*1, WtfPeasantCalculator.Multiply(0, 1));
Assert.AreEqual(1*0, WtfPeasantCalculator.Multiply(1, 0));
Assert.AreEqual(11*13, WtfPeasantCalculator.Multiply(11, 13));
}

[TestMethod]
public void Multiply_with_cryptic_version()
{
Assert.AreEqual(18*23, CrypticPeasantCalculator.Multiply(18, 23));
}
}

/// <summary>
/// What kind of entry would it be, if the expected code quality wasn't posted?
/// </summary>
internal static class CrypticPeasantCalculator
{
public static long Multiply(int a, int b)
{
return a < 1 ? 0 : (a%2 != 0 ? b : 0) + Multiply(a/2, b*2);
}
}

/// <summary>
/// Another WTF is to actually try to write readable, understandable code.
/// </summary>
internal static class WtfPeasantCalculator
{
public static long Multiply(int a, int b)
{
if (ThereIsNothingLeftToAccumulate(a)) return 0;
return ValueToAccumulate(a, b) + FollowingAccumulatedValues(a, b);
}

private static bool ThereIsNothingLeftToAccumulate(int a)
{
return a < 1;
}

private static int ValueToAccumulate(int a, int b)
{
return IsOddNumber(a) ? b : 0;
}

private static bool IsOddNumber(int number)
{
return number%2 != 0;
}

private static long FollowingAccumulatedValues(int a, int b)
{
return Multiply(a/2, b*2);
}
}
}
```
• Mr.'; Drop Database -- 2009-07-22 22:00
```def russianpeasants(x, y):
print 'Useless waste of time. Any idiot could write this.'

def multiply(x, y):
if x < 0 and y < 0: x = -x; y = -y
elif x < 0 or y < 0: return -multiply(abs(x), abs(y))
if x == 0 or y == 0: return 0
if x == 1 or y == 1: return x+y-1
bits = 0; tempx = x; tempy = y
while tempx: tempx >>= 1; bits += 1
while tempy: tempy >>= 1; bits += 1
bits >>= 2
a = x >> bits; b = x & ((1 << bits) - 1)
c = y >> bits; d = y & ((1 << bits) - 1)
ac = multiply(a, c); bd = multiply(b, d)
abcd = multiply(a+b, c+d)
return (bd
+ ((abcd - bd - ac) << bits)
+ (ac << (bits + bits)))```
• bluebearr 2009-07-22 22:18

```Func _RussianMultiplication( \$var1, \$var2)
Dim \$iResult=0, \$iLeft = \$var1, \$iRight = \$var2
While Abs(\$iLeft) >= 1
If StringInStr("13579", StringRight(\$iLeft, 1)) > 0 Then \$iResult+=\$iRight
\$iLeft = Int(\$iLeft/2)
\$iRight *= 2
WEnd
If \$var1 < 0 Then \$iResult *= -1
Return \$iResult
EndFunc```
• Joel 2009-07-22 22:22
Short recursive C# technique:

```int Russian(int left, int right, int progress){
if(x==0) return progress;
return Russian(left/2, right*2, progress+((left%2==1)?right:0));
}```
• Bruce 2009-07-22 22:44
This actually misses adding the first row if the initial lval is odd.
• Bruce 2009-07-22 22:46
(sorry, I meant the first sample given)
• J 2009-07-22 22:51
Tail-recursive Mathematica implementation:

RussianPeasantTimes[x_Integer, y_Integer] :=
Sign[x] RussianPeasantTimesImpl[Abs[x], y, 0];

RussianPeasantTimesImpl[x_, y_, res_] :=
RussianPeasantTimesImpl[Quotient[x, 2], 2 y, res + Mod[x, 2] y];
RussianPeasantTimesImpl[1, y_, res_] := res + y;
RussianPeasantTimesImpl[0, _, res_] := res;
• noSignal 2009-07-22 23:14
Scheme:

(define peasant
(lambda (x y)
(letrec
((loop
(lambda (ls1 ls2)
(if (eq? (car ls1) 1)
(apply + (select odd? ls1 ls2))
(loop (cons (quotient (car ls1) 2) ls1) (cons (* 2 (car ls2)) ls2))))))
(loop (list x) (list y)))))
• noSignal 2009-07-22 23:17
I salute you sir!
I found a neat little trick to it. See if you can figure out what I did ;-) :

```uint32_t multiply(uint32_t a, uint32_t b) {
uint64_t ab = 0;
uint32_t r = 9;
while (--r) {
ab <<= 4;
ab |= ((0xf7b3d591e6a2c480ULL>>((a&0xF)<<2)) & 0xF);
a >>= 4;
}
ab <<= 32;
ab |= b;
while (ab >> 32) {
if (ab >> 63)
r += ab;
ab <<= 1;
ab &= 0xFFFFFFFEFFFFFFFFULL;
}
return r;
}
```

I stress tested this (with 100 million random trials against the * operator) on an x86 and a PPC machine, so it works, trust me.
• noSignal 2009-07-22 23:20
You spent more than 5 minutes on a 3 minute problem. Congratulations.
• jnz 2009-07-22 23:25
Here's a version in C that multiplies two 8-bit numbers and produces a 16-bit result. It requires a 64-bit unsigned type. I know it doesn't look much like the original algorithm but that's because it treats the 64-bit variables as an array of 8-bit values that can be operated on in parallel.

```unsigned int mult(unsigned char a, unsigned char b)
{
uint64_t x, y;

x = a;          y = b;
x |= x << 7;    y |= y << 8;
x |= x << 14;   y |= y << 16;
x |= x << 28;   y |= y << 32;

x &= 0x0101010101010101ULL;
x = (0x8080808080808080ULL - x) ^ 0x8080808080808080ULL;
x &= y;

x = (x & 0x00FF00FF00FF00FFULL) + ((x & 0xFF00FF00FF00FF00ULL) >> 7);
x = (x & 0x0000FFFF0000FFFFULL) + ((x & 0xFFFF0000FFFF0000ULL) >> 14);
x = (x & 0x00000000FFFFFFFFULL) + ((x & 0xFFFFFFFF00000000ULL) >> 28);

return (unsigned int)x;
}```

• JXO 2009-07-22 23:28
C code. FACTOR can be changed to another integer > 1 without breaking the code.
```#define FACTOR 2
unsigned int ruski_mul(unsigned int a, unsigned int b)
{
unsigned int result = 0;
while (a >= 1)
{
result += (a % FACTOR) * b;
a /= FACTOR;
b *= FACTOR;
}
return result;
}
```
• zcl 2009-07-22 23:45

Yes ,your article is very good, we have the same belief with you,so let me introduce the area to you.Now Juicy Jewelry become more adn more popular within all kind of people. Juicy couture is a kind of juicy series . It won a good reputation. Juicy sale often held its regular discount juicy activities,such as juicy charms,cheap juicy and so on.In these activities juicy couture sale got great success. juicy couture consists of two main aspects, juicy couture jewelry and juicy couture accessories
Juicy couture series are worthwhile than other juicy on sales. They have a lot of discounted jewelry,for example discount Juicy Couture necklaces, juicy earrings , juicy bracelets and rings on sale. Benefit from the discount,you can get juicy jewelry save up to 30%, We assure you of our best services at all times.
• Chris 2009-07-23 00:14
Here my implementation i JavaScript (yeah, I know, not a programming language :D )

Ok, the WTF is also that it doesn't work in IE, and looks funny in Opera. And that it's a bit long, not because of the calculation, but because of the whizbang :)

```<script language="JavaScript">
function PeasantMultiply()
{
var one = Math.round(document.getElementById("first_value").value * 1);
var two = Math.round(document.getElementById("second_value").value * 1);
var mytable = document.getElementById("my_table");
var columns = 1;
var rows = 1;
var newRow = null;
var newCell = null;
var rowIndices = new Array();
if (one < 1 || two < 1)
{
alert ("Russian Peasants only knew how to multiply positive integer numbers!");
return false;
}
mytable.innerHTML = "";
newRow = document.createElement("tr");
newCell = document.createElement("td");
newCell.innerHTML = one + "&nbsp;*&nbsp;" + two;
newRow.appendChild(newCell);
mytable.appendChild(newRow);
if (one % 2)
{
rowIndices.push(true);
}
else
{
rowIndices.push(false);
}
while (true)
{
one >>= 1;
if (one <= 0) break;
two *= 2;
if (one % 2)
{
rowIndices.push(true);
}
else
{
rowIndices.push(false);
}
newCell = document.createElement("td");
newCell.innerHTML = one + "<span style='float:right'>" + two + "</span>";
newRow = document.createElement("tr");
for (r=null, i=0; i < mytable.getElementsByTagName("tr").length; i++)
{
r = mytable.getElementsByTagName("tr")[i];
r.appendChild(r.lastChild.cloneNode(true));
}
for (var i=0; i < columns; i++)
{
newRow.appendChild(document.createElement("td"));
}
newRow.appendChild(newCell);
mytable.appendChild(newRow);
columns++; rows++;
}
var first = true;
for (r=null, i=0; i < mytable.getElementsByTagName("tr").length; i++)
{
r = mytable.getElementsByTagName("tr")[i];
newCell = r.lastChild.cloneNode(true);
if (!(rowIndices[i]))
newCell.innerHTML = "<strike>" + newCell.innerHTML + "</strike>";
r.appendChild(newCell);
newCell = document.createElement("td");
if (rowIndices[i])
{
if (!first) newCell.innerHTML = "+ " + newCell.innerHTML;
newCell.innerHTML = "<span style='float:right'>" + newCell.innerHTML + "</span>";
first = false;
}
else
newCell.innerHTML = "&nbsp;";
r.appendChild(newCell);
}
newCell = document.createElement("td");
newCell.setAttribute( "rowspan", rows);
newCell.innerHTML = "=";
mytable.firstChild.appendChild(newCell);

newCell = document.createElement("td");
newCell.setAttribute( "rowspan", rows);
mytable.firstChild.appendChild(newCell);

return false;
}
</script>

<style type="text/css">
td {
border: 1px solid black;
}
</style>

<form>
Multiply: <input type="text" id="first_value" />
By: <input type="text" id="second_value" />
<input type="button" value="using russian peasant multiplication" onClick="javascript:PeasantMultiply(); return false;" />
</form>

<table id="my_table" style="border: 1px solid black; border-collapse: collapse; font-family: Arial,Helvetica;">
<tr id="row_0">
<td id="cell_0_0">
Russian Peasant Multiplication
</td>
</tr>
</table>
```
• Julian Calaby 2009-07-23 00:33
Bash: abusing the arithmetic evaluation to fit the bulk of the algorithm on one line. (Everything except the line starting with echo is to handle the first argument being negative.)

```#! /bin/bash

if [ \$1 -lt 0 ]; then
\$0 \$(( \$1 * -1 )) \$(( \$2 * -1 ))
else
echo \$(( \$([ \$((\$1 & 1)) -eq 1 ] && echo \$2 +) \$(if [ \$1 -gt 1 ]; then \$0 \$((\$1 >> 1)) \$((\$2 << 1)); else echo 0; fi) ))
fi```

Remove the outermost arithmetic brackets on the second last line to see the working.

(Note that this doesn't work unless it's in an actual script file and called as such)
• cmugford 2009-07-23 00:37
Couldn't see if this had been done - but anyway how about some F#.
```let rec multiply x y = match x with
| 0 -> 0
| 1 -> y
| -1 -> -y
| x when x % 2 = 0 -> multiply (x / 2) (y * 2)
| x when x > 0 ->  y + multiply (x / 2) (y * 2)
| x when x < 0 ->  -y + multiply (x / 2) (y * 2);
```
• James 2009-07-23 00:50

If you've got a copy of Excel you can always do it this way, and lets face if, if you've got Excel why wouldn't you?

-----
Sub WhyOhWhy()
Dim iRowNo As Integer
Dim sValue As String

iRowNo = 2

sValue = InputBox("Enter first value to mulitply", "Peasant Multiply")
If sValue = "" Then
MsgBox "You're not playing the game..."
Do Until sValue <> ""
sValue = InputBox("Enter first value to mulitply", "Peasant Multiply")
If Not IsNumeric(sValue) Then
MsgBox "You're not playing the game..."
sValue = ""
Else
If CLng(sValue) > 33554431 Then
MsgBox "Upper limit on first number is 33,554,431"
sValue = ""
End If
End If

Loop
End If
Cells(iRowNo, 3).Value = CLng(sValue)

sValue = InputBox("Enter second value to mulitply", "Peasant Multiply")
If sValue = "" Then
MsgBox "You're not playing the game..."
Do Until sValue <> ""
sValue = InputBox("Enter second value to mulitply", "Peasant Multiply")
If Not IsNumeric(sValue) Then
MsgBox "You're not playing the game..."
sValue = ""
End If
Loop
End If
Cells(iRowNo, 4).Value = CLng(sValue)

Cells(iRowNo, 3).Interior.ColorIndex = 36
Cells(iRowNo, 4).Interior.ColorIndex = 36
Cells(iRowNo, 5).Interior.ColorIndex = 45
Cells(iRowNo, 5).FormulaR1C1 = "=SUM(R[1]C:R[24]C)"

iRowNo = iRowNo + 1
Cells(iRowNo, 3).Value = Cells(iRowNo, 3).Value
Cells(iRowNo, 4).Value = Cells(iRowNo, 4).Value
Cells(iRowNo, 5).FormulaR1C1 = "=IF(RC[-2]<>"""",IF(MOD(RC[-2],2)<>0,RC[-1],0),"""")"

For iRowNo = 3 To 26
Cells(iRowNo, 3).FormulaR1C1 = "=IF(OR(R[-1]C=1,R[-1]C=""""),"""",INT(R[-1]C/2))"
Cells(iRowNo, 4).FormulaR1C1 = "=IF(RC[-1]<>"""",R[-1]C*2,"""")"
Cells(iRowNo, 5).FormulaR1C1 = "=IF(RC[-2]<>"""",IF(MOD(RC[-2],2)<>0,RC[-1],0),"""")"
Next iRowNo
MsgBox "There you go, the answer is " & Format(Cells(2, 5).Value, "#,##0")
End Sub

• iamtim2 2009-07-23 00:56
In Newlisp. I came up with & on my own but after reading Tim's version, I used >> and <<. Mine's tested.

; odd? (= (& col1 1) 1) instead of (= (% col1 2) 0)
; half! (>> col1 1) instead of (/ col1 2)
; double! (<< col2 1) instead of (* col2 2)
; because %, / and * are expensive

(define (rus col1 col2)
(let ((t 0))
(do-until (< col1 1)
(if (= (& col1 1) 1)
(setq t (+ col2 t)))
(println col1 " x " col2)
(set 'col1 (>> col1 1) 'col2 (<< col2 1)))
(println t)))
• jvmbsd7 2009-07-23 00:59
;; Scheme using the design recipe and optimized for lowest number of iterations

(define (russian-multiply m n)
(define (russian-multiply* x y p)
(if (zero? x)
p
(russian-multiply* (quotient x 2) (+ y y) (if (odd? x) (+ p y) p))))
(if (< m n)
(russian-multiply* m n 0)
(russian-multiply* n m 0)))
• agrif 2009-07-23 01:29
these are all in python

the first is the most verbose:
```def russian(x, y):
def generate_list(x, y):
while x != 0:
yield x, y
x /= 2
y *= 2

def filter_even(i):
if i[0] % 2 == 0:
return False
return True

def drop_first_column(i):
return i[1]

l = generate_list(x, y)
l = filter(filter_even, l)
l = map(drop_first_column, l)
return sum(l)
```

The next one is less verbose, but still easy to follow:
```def russian(x, y):
l = []
while x != 0:
if x % 2:
l.append(y)
x /= 2
y *= 2
return sum(l)
```

Personally, I like this one for it's complete incomprehensibility (and that it says "lambda f,a,b:a", which makes me laugh):
```russian = lambda x,y:(lambda f:f(f,x,y))(lambda f,a,b:a and f(f,a/2,b*2)+a%2*b)
```

agrif - 71aaeb8b415a620bf185b6093ebaf5c5
• Chris Walton 2009-07-23 01:35
No branches in the innerloop. Should run pretty fast.

C-version:
```int russianMul(int a, int b)
{
int s = 0;
while(a > 1)
{
b <<= 1;
a >>= 1;
s += b & -(a & 1);
}
return s;
}
```

x86 Assembly version, as compiled by MSVC
```00401000  xor         eax,eax
00401002  cmp         ecx,1
00401005  jle         russianMul+1Dh (40101Dh)
00401007  push        esi
00401008  sar         ecx,1
0040100A  mov         esi,ecx
0040100C  and         esi,1
00401011  neg         esi
00401013  and         esi,edx
00401017  cmp         ecx,1
0040101A  jg          russianMul+8 (401008h)
0040101C  pop         esi
```
• arke 2009-07-23 01:38
Chris Walton:
...

Oops, I probably should have logged in. :)

Something to add - my version doesn't need the actual CPU's multiply or divide instructions, making it feasible to implement on some processor that doesn't have that. Also, in its current incarnation, it depends on 2's Complement numbers being used.
• sxeraverx 2009-07-23 02:11
int mult(int a, int b) { return a*b; }
/*because that's how computers do it in hardware, anyway.*/
• Mr M 2009-07-23 02:14
The question is, why would I want to?
• Philipp 2009-07-23 02:23
Qwertyuiopas:
I know everybody wants it :)

Hopefully none of it was removed.

Also, everything after the first . is disabled debugging code. Remove the [-] to see what is left of the memory.

>>>>>,>>,[->+>+<<]<<[[-[>+<-]>[>+>>>+<<<<-[[<+>-]>[-]<]]<]>>[>>[-]<<[-]]+>[->>>>>++>++<<<<<<]>>]>>>>[-]<<<<<<<[<<<<<]>>>>>[>>[->>>>>+<<<<<]>>>]>>.[-][<<<<<<<[<<<<<]>>>.>.>[.>.>.>.>.>].>.>.]

Ok, so how do I run that? I tried the "Brainfuck Interpreter" (http://koti.mbnet.fi/villes/php/bf.php), but I couldn't get any meaningful result. How do I set the input?

Otherwise: Coolest solution so far -- imho.
zcl:

Yes ,your article is very good, we have the same belief with you,so let me introduce the area to you.Now Juicy Jewelry become more adn more popular within all kind of people. Juicy couture is a kind of juicy series . It won a good reputation. Juicy sale often held its regular discount juicy activities,such as juicy charms,cheap juicy and so on.In these activities juicy couture sale got great success. juicy couture consists of two main aspects, juicy couture jewelry and juicy couture accessories
Juicy couture series are worthwhile than other juicy on sales. They have a lot of discounted jewelry,for example discount Juicy Couture necklaces, juicy earrings , juicy bracelets and rings on sale. Benefit from the discount,you can get juicy jewelry save up to 30%, We assure you of our best services at all times.

Can we please end the off-topic rants about Russian peasant multiplication and get back to our juicy jewelry discussion?
• Alex Muscar 2009-07-23 02:32
Common Lisp:

This time it does the expected thing when the first number is negative instead of looping forever :)

```(defun rpm4 (m n &optional (acc 0))
(do ((aux (abs m) (ash aux -1)))
((= aux 0) (if (< m 0) (- 0 acc) acc))
(incf acc (if (oddp aux) n 0))
(incf n n)))
```
• Alex Muscar 2009-07-23 02:45
Common Lisp:

```(defun rpm4 (m n)
(do ((t1 (abs m) (ash t1 -1))
(t2 n (ash t2 1))
(acc 0 (+ acc (if (oddp t1) t2 0))))
((= t1 0) (if (< m 0) (- 0 acc) acc))))
```
• mneimeyer 2009-07-23 03:08
This feels a little "me too" at this point but I've tried to follow all the "rules".

Here's PHP that accounts for negative numbers, doesn't use * or /, accounts for 0 in either position and generates nifty colored output.

<?php

function Russian(\$a,\$b)
{
echo "\n<tr bgcolor='".(\$a&1?"green":"red")."'><td>".\$a."</td><td>".\$b."</td></tr>";
if(!\$a || !\$b) { return 0; }
if(\$a < 0) { \$a = (\$a^-1)+1; \$b = (\$b^-1)+1; }
return ((\$a <= 1)?(\$a?\$b:0):((intval(\$a&1)?\$b:0)+Russian(intval(\$a>>1),\$b<<1)));
}

?><html>
<body>

<form method="get">
<tr>
<td><input type="text" size="4" name="a" value="<?= \$_GET['a'] ?>"></td>
<td>&nbsp;x&nbsp;</td>
<td><input type="text" size="4" name="b" value="<?= \$_GET['b'] ?>"></td>
<td><input type="submit" value="Multiply"></td>
</tr>
</table>
</form>

<?php

if(isset(\$_GET['a']) && isset(\$_GET['b']))
{
echo "\n<p align='center'>Quick: ".(\$_GET['a']*\$_GET['b'])."</p>\n";

echo "<table border='0' align='center'>\n";
\$c = Russian(\$_GET['a'],\$_GET['b']);
echo "\n<tr><td>Sum:</td><td>".\$c."</td></tr>";
echo "</table>\n";
}

?>

</body>
</html>
• Hidayat 2009-07-23 03:14
Another using Oracle PL/SQL

```create or replace
function russian(p in number, q in number) return number is
res number;
begin
select sum( decode(mod(floor(p/power(2,level-1)),2),0,0,1) * q * power(2,level-1) ) into res
from dual where floor(p/power(2,level-1))>0 connect by level<q;
return res;
end;

select russian(18,23) from dual
```
• demo 2009-07-23 03:15
#include <iostream>

template<int I>
struct is_odd
{
enum { value = I % 2 };
};

template<int A, int B, int Odd>
struct russian_impl;

template<int A, int B>
struct russian_impl<A, B, 1>
{
enum { value = B + russian_impl<A/2, B*2, is_odd<A/2>::value>::value };
};

template<int A, int B>
struct russian_impl<A, B, 0>
{
enum { value = russian_impl<A/2, B*2, is_odd<A/2>::value>::value };
};

template<int B>
struct russian_impl<1, B, 1>
{
enum { value = B };
};

template<int A, int B>
struct russian
{
enum { value = russian_impl<A, B, is_odd<A>::value>::value };
};

int main(int argc, char* argv[])
{
std::cout << russian<18, 23>::value << std::endl;
return EXIT_SUCCESS;
}

• Don Knisley 2009-07-23 03:56
In VBA

Function RussianPeasantMultiplication()
Dim a As Integer, b As Integer, c As Integer
a = 18
b = 23
Debug.Print a & " x " & b
Do Until a = 1
a = Int(a / 2)
b = b * 2
If a / 2 <> Int(a / 2) Then
c = c + b
Debug.Print a & vbTab & b & vbTab & b
Else
Debug.Print a & vbTab & b
End If
Loop
Debug.Print vbTab & vbTab & c
End Function
• SlyEcho 2009-07-23 03:59
CREATE FUNCTION Peasant_Mul (@A INT, @B INT)
RETURNS INT
AS
BEGIN
DECLARE @Result INT;
WITH f AS (
SELECT @A A, @B B
UNION ALL
SELECT A / 2, B * 2 FROM f WHERE A > 1
)
SELECT @Result = SUM(B) FROM f
WHERE A % 2 = 1;

RETURN @Result;
END
GO
• subanark 2009-07-23 04:04
Here is my solution in Java. It supports really big numbers and does pretty much what you do in Russian peasant multiplication.

public static BigInteger multiply(BigInteger a, BigInteger b)
{
BigInteger two = BigInteger.valueOf(2);
while(!a.equals(BigInteger.ONE))
{
if(a.mod(two).equals(BigInteger.ONE))
a = a.divide(two);
b = b.multiply(two);
}
//trick: b already holds the last line
return b;
}
• Toby Gray 2009-07-23 04:07
In Perl:

print "Enter sum in form \"a x b\":\n";\$_=<>;
s!(\n|^)(\d+) x (\d+)\n\$!"\$1\$2 x \$3\n".int((\$2)/2)." x ".(\$3 * 2)."\n"!e while!/^1 x \d+\$/m;
s!(\n|^)(\d*[24680]) x (\d+)!\$1-(\$2 x \$3)-!g;
\$v+=\$2 while/(\n|^)\d+ x (\d+)/g;\$_.="\nTotal: \$v\n";
print "Paper working is:\n\$_";
• freewildebeest 2009-07-23 04:10
Repost now I've worked out how to create an account...

In Perl:

print "Enter sum in form \"a x b\":\n";\$_=<>;
s!(\n|^)(\d+) x (\d+)\n\$!"\$1\$2 x \$3\n".int((\$2)/2)." x ".(\$3 * 2)."\n"!e while!/^1 x \d+\$/m;
s!(\n|^)(\d*[24680]) x (\d+)!\$1-(\$2 x \$3)-!g;
\$v+=\$2 while/(\n|^)\d+ x (\d+)/g;\$_.="\nTotal: \$v\n";
print "Paper working is:\n\$_";
• astander 2009-07-23 04:15
private int RussianMultiply(int input1, int input2)
{
int retVal = 0;
do
{
retVal += (input1 & 1) * input2;

input1 = input1 >> 1;
input2 = input2 << 1;

} while (input1 > 0);
return retVal;
}
• k1 2009-07-23 04:45
10 PRINT "HELLO, WELCOME TO THE RUSSIAN (FORMERLY ROMAN) PEASANT MULTIPLICATION"
20 INPUT "PLEASE, ENTER THE TWO OPERANDS: "; A, B
30 SIGN = 1
40 PRINT "IS "; A; " NEGATIVE? (Y/N)"
60 IF ANSWER = "Y" THEN SIGN = -1
70 PRINT "IS "; B; " NEGATIVE? (Y/N)"
90 IF ANSWER = "Y" THEN SIGN = SIGN * -1
100 PRINT A; " EQUALS 0? (Y/N)"
120 IF ANSWER = "Y" THEN PRINT "THE PRODUCT IS 0": END
130 PRINT B; " EQUALS 0? (Y/N)"
150 IF ANSWER = "Y" THEN PRINT "THE PRODUCT IS 0": END
160 PRINT A; " EQUALS 1? (Y/N)"
180 IF ANSWER = "Y" THEN PRINT "THE PRODUCT IS "; B: END
190 PRINT B; " EQUALS 1? (Y/N)"
210 IF ANSWER = "Y" THEN PRINT "THE PRODUCT IS "; A: END
220 INDEX = 1
230 PRINT "IS "; A; " EVEN? (Y/N)"
240 IF ANSWER = "Y" THEN PRINT "USEFUL VALUE "; INDEX; " -> "; B: INDEX = INDEX+1
250 PRINT "PLEASE, DIVIDE "; A; " BY 2 (GIVE ME THE SMALLEST PART):"
260 INPUT A
270 PRINT "PLEASE, DOUBLE "; B
280 INPUT B
290 PRINT A; " EQUALS 1? (Y/N)"
310 IF ANSWER = "Y" THEN PRINT "USEFUL VALUE "; INDEX; " -> "; B: GOTO 330
320 GOTO 250
330 PRINT "PLEASE, GIVE ME THE USEFUL VALUE 1, FROM ABOVE:"
340 INPUT A
350 AINDEX = 1
360 FOR I=2 TO INDEX
370 PRINT "PARTIAL RESULT "; AINDEX; " -> "; A
380 PRINT "PLEASE, SUM USEFUL ANSWER "; I; " WITH PARTIAL RESULT ": AINDEX
390 INPUT A
400 AINDEX = AINDEX + 1
410 NEXT
420 PRINT "THE PRODUCT IS "; A
430 END
• k1 2009-07-23 04:58
whoops...
k1:

<snip>
420 PRINT "THE PRODUCT IS "; A
430 END

420 PRINT "THE PRODUCT IS "; A * SIGN

There, fixed.

CYA
• Boneist 2009-07-23 05:29
Oracle SQL version, showing the working out:

```with  my_data as (select :p1 col1, :p2 col2 from dual),
list_gen as (select level -1 lvl
from   my_data
connect by power(2,level-1) <= col1),
results as (select lvl,
floor(col1/power(2,lvl)) col3,
col2*power(2, lvl) col4
from   my_data,
list_gen)
select col3,
col4,
decode(floor(col3/2)*2,
col3, null,
sum(case when floor(col3/2)*2 != col3 then col4 end) over (order by lvl)) sum_col
from   results
order by lvl
```
• C 2009-07-23 05:49
; EDX:EAX <- ECX * EBX (untested)
; (all other gp registers trashed)
MOV ECX, multiplicand
MOV EBX, multiplier
multiply:
XOR EAX, EAX
XOR EDX, EDX
CMP ECX, EAX
JNL .ps
NEG ECX
NEG EBX
.ps: XOR EDI, EDI
CMP EBX, EAX
SBB EBP, EBP
SHR ECX, 1
JZ .nd
.lp: SBB ESI, ESI
MOV EDI, ESI
AND ESI, EBX
AND EDI, EBP
SHR ECX, 1
JNZ .lp
.nd: SBB ESI, ESI
MOV EDI, ESI
AND ESI, EBX
AND EDI, EBP
; done
; ... or just use IMUL
• Joost 2009-07-23 05:54

multiply n m = sum \$ map snd \$ filter (odd . fst) \$ russian n m
where russian 1 m = [(1,m)]
russian n m = (n,m) : russian (n `div` 2) (m * 2)
• StarLite 2009-07-23 06:10
My take using Progress V9 (will probably work in most older versions as well)
Code:
```function multiply returns integer (input ip_int1 as integer, input ip_int2 as integer):
define variable v_result as integer no-undo.

if ip_int1 = 1 then
return ip_int2.

if ip_int1 mod 2 <> 0 then
v_result = v_result + ip_int2.

v_result = v_result + multiply(integer(truncate(ip_int1 / 2, 0)), (ip_int2 * 2)).
return v_result.
end.

message "Russian Peasant Notation: " multiply(18, 23) view-as alert-box info buttons ok.
```
• col obvious 2009-07-23 06:15
static int m(int x,int y){return x==1?y:x%2==0?m(x/=2,y*=2):y+m(x/=2,y*=2);}
• LatecomerX 2009-07-23 06:28
I've been a TDWTF reader for the past few months, and I'm dedicating my first comment to this interesting question here:

In PHP:

<?

function multiply(\$x, \$y, \$o = 0) {
return \$x > 1 ?
multiply(floor(\$x / 2), \$y * 2, \$o + \$x % 2 * \$y) :
\$o + \$y;
}

echo multiply(18, 23);

?>

Also available at:
http://phpieceofcake.com/?83344437
• Alex 2009-07-23 06:40
Not sure if anyone posted this solution yet. Here's mine:

private int Multiply(int x, int y)
{
return x == 1 ? y : Multiply(x / 2, y * 2) + x % 2 * y;
}
• A.T. 2009-07-23 06:45
Mike5:

Anonymous Coward:
Prolog...

"optimized" with bit-shifting ...

To get the real prolog feeling:

```%% russian(?A,?B,?P).
%% multiplies A and B the russian way,
%% all parameters are optional
russian(A,B,P) :- nonvar(A), var(B), !, russian(B,A,P).
russian(A,B,P) :- var(A), (nonvar(B),!;length(_,P),between(0,P,B)),
row(A,B,P,0,P).
russian(A,B,P) :- nonvar(A), row(A,B,P,0,P), !.

row(_,_,P,F,_) :- nonvar(P), P < 1<<(F-1), !, fail.
row(0,_,_,_,0).
row(A,B,P,F,R) :-
row(Ax,B<<1,P,F+1,Rx),
double(Ax,A,Odd),
R is Rx+B*Odd.

double(0,1,1) :- !.
double(X,X2,Odd) :- (Odd=0;Odd=1), X2 is X*2+Odd.
```

may need some optimization though...
• A.T. 2009-07-23 06:51
Mike5:

Anonymous Coward:
Prolog...

"optimized" with bit-shifting ...

To get the real prolog feeling:

```%% russian(?A,?B,?P).
%% multiplies A and B the russian way,
%% all parameters are optional
russian(A,B,P) :- nonvar(A), var(B), !, russian(B,A,P).
russian(A,B,P) :- var(A), (nonvar(B),!;length(_,P),between(0,P,B)),
row(A,B,P,0,P).
russian(A,B,P) :- nonvar(A), row(A,B,P,0,P), !.

row(_,_,P,F,_) :- nonvar(P), P < 1<<(F-1), !, fail.
row(0,_,_,_,0).
row(A,B,P,F,R) :-
row(Ax,B<<1,P,F+1,Rx),
double(Ax,A,Odd),
R is Rx+B*Odd.

double(0,1,1) :- !.
double(X,X2,Odd) :- (Odd=0;Odd=1), X2 is X*2+Odd.
```

may need some optimization though...
• bugmonkey 2009-07-23 06:54
PHP and Perl, and gives the same output for both:
```#
#<?php echo "\x8";ob_start();
\$rm='return int(\$a/2)==1?\$b*2:(int(\$a/2)%2==1?\$b*2+rm(int(\$a/2),\$b*2):rm(int(\$a/2),\$b*2));';
#?><?php function int(\$a){return floor(\$a);}\$a=\$argv[1];\$b=\$argv[2];eval('function rm(\$a, \$b){'.\$rm.'}');?>
\$a=\$ARGV[0];\$b=\$ARGV[1];eval("sub rm{\\$a=shift;\\$b=shift;\$rm}");#<?php ob_end_clean();
print rm(\$a,\$b);```
• LatecomerX 2009-07-23 07:08
Came up with a more condensed PHP function after another 45 minutes or so:

function multiply(\$x, \$y) {
return \$x % 2 * \$y + (\$x > 1 ? multiply(floor(\$x / 2), \$y * 2) : 0);
}

LatecomerX:
I've been a TDWTF reader for the past few months, and I'm dedicating my first comment to this interesting question here:

In PHP:

<?

function multiply(\$x, \$y, \$o = 0) {
return \$x > 1 ?
multiply(floor(\$x / 2), \$y * 2, \$o + \$x % 2 * \$y) :
\$o + \$y;
}

echo multiply(18, 23);

?>

Also available at:
http://phpieceofcake.com/?83344437
• Methuselah 2009-07-23 07:14
Here's some Lua code:
```function russian(a, b)
if a==1 then
return b
else
if a%2==1 then
return b+russian(math.floor(a/2), b*2)
else
return russian(math.floor(a/2), b*2)
end
end
end```

Code only: 189 bytes
Code with BBCode coloring: 1190 bytes
• dv 2009-07-23 07:23
Someone:
An ABAP solution that compiles:
```REPORT MULTIP.

DATA: product TYPE i,
left_num TYPE f VALUE 18,
right_num TYPE f VALUE 23,
half_left TYPE f,
half_left_floor TYPE f.

WHILE left_num > 0.
"check for even number and add to product (there must be a better way...)
half_left = left_num / 2.
half_left_floor = FLOOR( left_num / 2 ).
IF half_left <> half_left_floor.
product = product + right_num.
ENDIF.

"move to next set
left_num = FLOOR( left_num / 2 ).
right_num = right_num * 2.
ENDWHILE.

WRITE product.
```

Yes there is a better way, the MOD operator. Also, when creating a whole report for it, why not include a nice, verbose, selection screen?

```SELECTION-SCREEN BEGIN OF BLOCK 1 WITH FRAME TITLE 'Input'.
PARAMETER p_num1 TYPE I DEFAULT 18 OBLIGATORY.
PARAMETER p_num2 TYPE I DEFAULT 23 OBLIGATORY.
SELECTION-SCREEN END OF BLOCK 1.
```

• Python 2009-07-23 07:26
#! -*- Encoding: Latin-1 -*-

import Queue

# classic spaghetti code
def rupmul1(a,aa):
aaa = lambda:(a % 2) and aa
aaaa = aaa()
while a > 1:
a, aa = a/2, aa*2
aaaa += aaa()
return aaaa

# functional programming
rupmul2 = lambda a,b: sum(map(
lambda b:a&b[0] and b[1],zip(map(
lambda a:pow(2,a),range(31)),map(
lambda a:b*pow(2,a),range(31)))))

# multicore power using threads + functional programming = TOTAL WIN!
def rupmul3(a,b,__=Queue.Queue()):
__.put((a&1<<_) and b<<_),args=(_,)).start(),_][-1],range(32))))

def selftest():
import random

for k in range(60):
a = random.randrange(1,10000)
b = random.randrange(1,10000)

n = a*b
assert rupmul1(a,b) == rupmul2(a,b) == rupmul3(a,b) == a*b

if __name__ == "__main__":
selftest()
• London Developer 2009-07-23 07:32
ParkinT:
Wow!
I had not time to submit a solution.
Everyone was too busy Russian to provide an answer!

OH DEAR!!! LOL!
• Anonymous 2009-07-23 07:40
That ARM code is both wrong and far too long. This is perhaps slightly less wrong:

```    mov    r2,#0
loop:
movs   r1,r1,lsr #1
mov    r0,r0,lsl #1
bne    loop```

• rjp 2009-07-23 07:41
Me:
Bah to all your bloaty solutions. Perlmongers do it in one line :P

sub m(){my(\$a,\$b)=@_;my \$t;while(\$a){\$t+=\$b if (\$a&1);\$a>>=1;\$b<<=1;}return \$t;}

Apologies if this has been pointed out already but you can shorten that slightly.

sub m{my(\$a,\$b)=@_;my \$t;while(\$a){\$t+=\$b*(\$a&1);\$a>>=1;\$b*=2}\$t}
• Osno 2009-07-23 08:00
Tail recursive in IL (based on 278641, not sure if C# can compile a tail recursivity, I'll have to check later). The first param is the acumulator and should be initialized to 0 (or wrapped in another method):

.method private hidebysig static int64 Russian(int64 a, int64 f, int64 s) cil managed
{
.maxstack 4
ldarg.0
dup
ldarg.1
brfalse.s done
ldarg.1
ldc.i4.1
and
ldarg.2
mul
ldarg.1
ldc.i4.1
shr
ldarg.2
ldc.i4.1
shl
tail.
call int64 RussianMult.Program::Russian(int64, int64, int64)
done:
ret
}
• Osno 2009-07-23 08:01
BTW, I think I've never seen a post in this site with 12 pages of comments.
• khahem 2009-07-23 08:01
C++ with a 'simple' iterator.
```#include <numeric>
struct gen {
int a, b;
gen(int a=0, int b=0) : a(a), b(b) { }
gen operator*() { return *this; }
void operator++() { a /= 2; b *= 2; }
bool operator!=(gen b) { return a != b.a; }
gen operator+(gen r) {
if (r.a % 2)
return gen(0, b + r.b);
return gen(0, b);
}
};

int mul(int a, int b) {
return std::accumulate(gen(a, b), gen(), gen()).b;
}
```
• Lom 2009-07-23 08:02
Python, nominate for shortest one :)
49 characters.
And, with python, numbers multiply peasants.

m=lambda a,b:sum(b<<i for i in range(a)if a&1<<i)
• Rorick 2009-07-23 08:13
Java:
```public static long multiply(int a, int b) {
if (a < 0) {
a = -a;
b = -b;
}
int result = 0;
while (a > 0) {
int tz = Integer.numberOfTrailingZeros(a);
result += b << tz;
a = a >> ++tz << tz;
}
return result;
}
```
• Queex 2009-07-23 08:16
This nearly works; I'll leave the rest to the in-house coders.

```    public static int multiply(int x, int y) {
StringBuffer sb = new StringBuffer();
sb.append("" + x);
sb.append(" x "); // prettify output
sb.append(y + "");

while (doIt(sb));

System.err.println(sb.toString());

String str = sb.toString();
StringTokenizer st = new StringTokenizer(sb.toString(), "\n ");
int o = 0;
while (st.hasMoreTokens()) {
if (Integer.parseInt(st.nextToken()) % 2 == 0) {
//do nothing
} else {
o += Integer.parseInt(st.nextToken());
}
}

return o;
}

public static boolean doIt(StringBuffer sb) {
int line = sb.lastIndexOf("\n");
line++; //need this for some reason!!!!!1!

//if(line<0){
//      line++;
//}

int split = sb.indexOf(" ", line);
String x = sb.substring(line, split);
String y = sb.substring(split);

sb.append("\n");
sb.append(Integer.parseInt(x) / 2);
sb.append(" ");
sb.append(Integer.parseInt(y.trim()) * 2);

if (x.equalsIgnoreCase("1")) {
return false;
}

return true;
}

//    public static int multiply(int x, int y) {
//        int out = 0;
//        while (x != 1) {
//            if (x % 2 != 0) {
//                out += y;
//            }
//            x = x >> 1;
//            y = y << 1;
//        }
//        return out + y;
//    }```
• ath 2009-07-23 08:17
Wow, the number of unreadable and unmaintainable examples outweight the readable and maintainable ones by about 50:1!
That's the real WTF...
• Mr. Black 2009-07-23 08:18
my crappy C version that doesn't work for negative numbers ;)
----------------------- <snip> --------------------------
```#include <stdio.h>

main( argc, argv)
int argc;
char *argv[3];
{
int n1 = 0;
int n2 = 0;
int n3 = 0;

n1 = atoi(argv[1]);
n2 = atoi(argv[2]);
/* Implement Russian Peasant Multiplication algorithm */
if ( argc != 3 )
{
printf("USAGE: rpm n n\nrpm multiplies two numbers via the Russian peasant method\n");
return(1);
}

/* if either parameter is zero, the answer is zero */
if ( n1 == 0 || n2 == 0 )
{
printf("Result of %d * %d via Russian peasant method is: 0.\n", n1, n2);
return(0);
}

if ( n1 == 1 || n2 == 1 )
{
printf("Result of %d * %d via Russian peasant method is: %d.\n", n1, n2, n1*n2);
return(0);
}

if ( (n1 % 2) != 0 )
{
n3 = n2;
}

while ( n1 >= 1 )
{
n1 = n1 / 2;
n2 = n2 * 2;
if ( (n1 % 2) != 0 )
{
n3 = n3 + n2;
}
}

printf("Result of %d * %d via Russian peasant method is: %d.\n", atoi(argv[1]), atoi(argv[2]), n3);

return(0);
}
```

----------------------- <snip> ---------------------
• Alex Muscar 2009-07-23 08:29
The C# compiler does tail call optimisation only on x64 afaik.
• Ralf 2009-07-23 09:08
Smalltalk

Note that this overwrites the System's definition of *
and everything still works.
```* aNumber

self isZero ifTrue: [^0].
self < 0
ifTrue: [^(self negated * aNumber) negated]
ifFalse:  [^ ((self bitShift: -1) * (aNumber + aNumber)) + ((self bitAnd: 1) = 1 ifTrue: [aNumber] ifFalse: [0])]
```

• EJCorcoran 2009-07-23 09:13
DECLARE @X INT, @Y INT, @Z INT
SELECT @X=18,@Y=23,@Z=0
WHILE @X!=1
BEGIN
IF (@X%2)!=0
SET @Z=@Z+@Y
SET @X=@X/2
SET @Y=@Y*2
END
SET @Z=@Z+@Y
SELECT @Z

• Takis 2009-07-23 09:17
577 comments later and still no recursive VB.Net solution, so here's my second try; it handles negatives as well and doesn't use multiplication:

```Function Russiply2(ByVal a As Long, ByVal b As Long) As Long

Return If(a < 0, Russiply2(-a, -b), If(a > 1, If((a And 1) = 1, b, 0) + Russiply2(a >> 1, b << 1), If(a = 1, b, 0)))

End Function
```

• Osno 2009-07-23 09:18
Just checked on an x64. At least by default, it doesn't do tail recursion. Also, when compiled in Release the output is really really close to my solution. The only real difference is that it branches on non-equal instead of false.
zcl:

Yes ,your article is very good, we have the same belief with you,so let me introduce the area to you.Now Juicy Jewelry become more adn more popular within all kind of people. Juicy couture is a kind of juicy series . It won a good reputation. Juicy sale often held its regular discount juicy activities,such as juicy charms,cheap juicy and so on.In these activities juicy couture sale got great success. juicy couture consists of two main aspects, juicy couture jewelry and juicy couture accessories
Juicy couture series are worthwhile than other juicy on sales. They have a lot of discounted jewelry,for example discount Juicy Couture necklaces, juicy earrings , juicy bracelets and rings on sale. Benefit from the discount,you can get juicy jewelry save up to 30%, We assure you of our best services at all times.

Can we please end the off-topic rants about Russian peasant multiplication and get back to our juicy jewelry discussion?

I believe the problem is that we've made this poor russian peasant thirsty, after warping his brain with such compressed algorithms in as many languages we could come up with. PDP-8, nice touch, but its still ASM! CP/M shell anyone???
Lom:
Python, nominate for shortest one :)
49 characters.
And, with python, numbers multiply peasants.

m=lambda a,b:sum(b<<i for i in range(a)if a&1<<i)

There is a 44 character python, and a 40 characther bc, although you still have several characters to go to catch perl :)
rjp:
Me:
Bah to all your bloaty solutions. Perlmongers do it in one line :P

sub m(){my(\$a,\$b)=@_;my \$t;while(\$a){\$t+=\$b if (\$a&1);\$a>>=1;\$b<<=1;}return \$t;}

Apologies if this has been pointed out already but you can shorten that slightly.

sub m{my(\$a,\$b)=@_;my \$t;while(\$a){\$t+=\$b*(\$a&1);\$a>>=1;\$b*=2}\$t}

It has, but then its perl.. TIMTOW! stub..! oww.
• wombat 2009-07-23 09:25
Only works with positive integers.

```<?xml version="1.0"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

<!-- get initial values out of xml -->
<xsl:template match="/">
<xsl:variable name="number1">
<xsl:value-of select="*/number[1]"/>
</xsl:variable>

<xsl:variable name="number2">
<xsl:value-of select="*/number[2]"/>
</xsl:variable>

<!--call the loop for the first time-->
<xsl:call-template name="loop">
<xsl:with-param name="a" select="\$number1"/>
<xsl:with-param name="b" select="\$number2"/>
<xsl:with-param name="r" select="0"/>
</xsl:call-template>
</xsl:template>

<!-- the loop to recurse over-->
<xsl:template name="loop">
<xsl:param name="a"/>
<xsl:param name="b"/>
<xsl:param name="r"/>
<xsl:choose>
<xsl:when test="\$a = 1">
<!-- we have finished print the result -->
<xsl:value-of select="\$b + \$r"/>
</xsl:when>
<xsl:otherwise>
<!--call the template again. each time divide "a" by 2 multiple "b" by 2, and sum "b" to the remainder if "a" is odd -->
<xsl:call-template name="loop">
<xsl:with-param name="a" select="round((\$a div 2) - 0.5)"/>
<xsl:with-param name="b" select="\$b * 2"/>
<xsl:with-param name="r" select="(\$a mod 2) * \$b + \$r"/>
</xsl:call-template>
</xsl:otherwise>
</xsl:choose>
</xsl:template>

</xsl:stylesheet>
```
• Rorick 2009-07-23 09:27
Another version, now in Rebol.
```multru: func [a b /local res] [
res: copy []
append res [res: 0]
append res compose [(either a < 0 [[-res]] [[res]])]
res: back tail res
until [
insert res compose/deep [either odd? (a) [add res (b)] [res]]
insert res to-set-word 'res
set [a b] compose [(round/down divide a 2) (multiply b 2)]
zero? a
]
]
```

It generates rebol code composed from additions and checks for oddity and then executes it. For 23 and 18 generated code looks like:
```[res: 0 res: either odd? 1 [add res 288] [res] res: either odd? 2 [add res 144] [res] res: either odd? 5 [add res 72] [
res] res: either odd? 11 [add res 36] [res] res: either odd? 23 [add res 18] [res] res]
```
• Philipp 2009-07-23 10:12
Ok, I couldn't resist. Here's an (amended!) brainfuck interpreter in Java, running the brainfuck code from Qwertyuiopas:

```public class BrainfuckJavaRussianMultiplication {
private static final String input =
">>>>>,>>,[->+>+<<]<<[[-[>+<-]>[>+>>>+<<<<-[[<+>-]>[-]<]]<]>>[>>[-]" +
"<<[-]]+>[->>>>>++>++<<<<<<]>>]>>>>[-]<<<<<<<[<<<<<]>>>>>[>>[->>>>>" +
"+<<<<<]>>>]>>%";

BrainfuckJavaRussionMultiplication(String code) {
int ptr = 0;
int [] cell = new int[10000];

for (int i = 0; i < 10000; i++) {
cell[i] = 0;
}

char [] chars = code.toCharArray();
for (int i = 0, n = chars.length; i < n; i++) {
char c = chars[i];
if (c == '>') {
ptr++;
} else if (c == '<') {
ptr--;
} else if (c == '+') {
cell[ptr]++;
} else if (c == '-') {
cell[ptr]--;
} else if (c == '.') {
System.out.print((char) cell[ptr]);
} else if (c == '%') {
System.out.print((int) cell[ptr]);
} else if (c == ',') {
Scanner in = new Scanner(System.in);
try {
cell[ptr] = Integer.parseInt(in.nextLine());
} catch (Exception e) {
cell[ptr] = 0;
}
} else if (c == '[') {
if (cell[ptr] == 0) {
int counter = 0;
int position = i + 1;
while (chars[position] != ']' || counter != 0) {
if (chars[position] == '[') {
counter++;
}
if (chars[position] == ']') {
counter--;
}
position++;
}
i = position;
}
} else if (c == ']') {
int counter = 0;
int position = i - 1;
while (chars[position] != '[' || counter != 0) {
if (chars[position] == ']') {
counter++;
}
if (chars[position] == '[') {
counter--;
}
position--;
}
i = position - 1;
}
}
}

public static void main(String [] args) {
new BrainfuckJavaRussianMultiplication(input);
}
}
```

As you can see, you may enter integers (instead of characters whose ASCII code is interpreted), also we are dealing with Brainfuck++ here, since it has the % command ;)
• jefu 2009-07-23 10:15
Haskell (with quickCheck to test it) :
```import Test.QuickCheck

pm 0 y = 0
pm 1 y = y
pm x y
| x < 0     = - pm (-x) y
| even x    = next
| otherwise = y + next
where next = pm (x `div` 2) (y*2)

prop_PMOK x y = pm x y == x*y
where types = (x::Int,y::Int)

quickCheck prop_PMOK
```
• the real wtf fool 2009-07-23 10:20
```#!/usr/bin/python

from sys import argv

if len(argv) < 3:
print "input values missing"
print "usage: "
print argv[0] + " value1 value2"
exit()

a = int(argv[1])
b = int(argv[2])
acc = 0
sep = " x "

justWidth = 5

while (a > 0):
if a & 0x1:
acc = acc + b
print "  ",
else:
print "--",

print str(a).rjust(justWidth) + sep + str(b).rjust(justWidth)
sep = "   "

a = a >> 1
b = b << 1

print "   " + "-" * ((justWidth*2)+len(sep))
print "  =" + str(acc).rjust((justWidth*2)+len(sep))
```

The output:
```>pmath.py 18 23
--    18 x    23
9      46
--     4      92
--     2     184
1     368
-------------
=          414
```

The lines starting with -- should be considered crossed out
• n1L 2009-07-23 10:24
soulution as c++ template:
```//////////////////////////////
template <int I, int J>
struct Pmul
{
operator int()
{
return (I%2)?J+Pmul<I/2,J*2>():Pmul<I/2,J*2>();
}
};
//////////////////////////////
template <int J>
struct Pmul<1, J>
{
operator int()
{
return J;
}
};
//////////////////////////////
```
i.e.:
`int res = Pmul<2311, 1234>();`
• czetts 2009-07-23 10:27
Well, I wanted to go back and make this more "clever", but this works just fine (C#):

```public static int MultiplyLikeARussianPeasant(int x, int y)
{
int sum = 0;
do
{
sum += (x%2 == 1) ? y : 0;
x /= 2;
y *= 2;
} while (x >= 1);
return sum;
}```

(I haven't checked the comments for this solution, that would have been cheating!)
• Josh Bohde 2009-07-23 10:43
Lom:
Python, nominate for shortest one :)
49 characters.
And, with python, numbers multiply peasants.

m=lambda a,b:sum(b<<i for i in range(a)if a&1<<i)

There is a 44 character python, and a 40 characther bc, although you still have several characters to go to catch perl :)

37 using * and /
```m=lambda a,b:a and(a&1)*b+m(a/2,b+b)
```

41 without
```m=lambda a,b:a and[0,b][a&1]+m(a>>1,b+b)
```

• some VBA coder 2009-07-23 10:50
Function peasant(factor1, factor2)
peasant = 0
If factor1 < 0 Then factor2 = -factor2
While factor1 <> 0
If (factor1 / 2) <> Round(factor1 / 2, 0) Then peasant = peasant + factor2
factor1 = factor1 / 2 - (factor1 Mod 2) / 2
factor2 = 2 * factor2
Wend
End Function
• Chris Judge 2009-07-23 10:55
Bob:
Someone straighten me out here but I think the peasant don't know math for crap.

May be I'm doing it wrong but when I Multiply 45 x 76, I get 3420

Peasants get:
```45   x  76
22	152	0
11	304	304
5	608	608
2	1216	0
1	2432	2432
======================
3344

Flip the numbers and you get the right answer
76	45
38	90	0
19	180	180
9	360	360
4	720	0
2	1440	0
1	2880	2880
=====================
3420
```

Peasant math apparently only works if one of the number is even and in the first column.

This must be why they remain peasants.

When you start with the 45 in the left column, you forgot to include the 76 in your sum.

Oh, and by the way:

```(define (pm x y)
(define (pm2 acc x y)
(cond
[(= x 0) acc]
[(= (remainder x 2) 0) (pm2 acc (floor (/ x 2)) (+ y y))]
[else (pm2 (+ acc y) (floor (/ x 2)) (+ y y))]
)
)

(pm2 0 x y)
)
```
• Rorick 2009-07-23 11:01
In rebol with caching of generated code stuff.
```multru: func [a b /local res cached] [
if not value? 'cache [
set/any in system/words 'cache []
]
select-cache: func [a b /local cached] [select/only cache compose [(a) (b)]]
case [
found? cached: any [select-cache a b select-cache b a] [return do cached]
true [
append/only cache compose [(a) (b)]
res: copy []
append res [res: 0]
append res compose [(either a < 0 [[-res]] [[res]])]
res: back tail res
until [
insert res compose/deep [either odd? (a) [add res (b)] [res]]
insert res to-set-word 'res
set [a b] compose [(round/down divide a 2) (multiply b 2)]
zero? a
]
]
]
do last cache
]
```
• dub 2009-07-23 11:01
I'm in the process of learning Haskell so here's my haskell solution. Feel free to give feedback so I can improve.

rus 0 _ = 0
rus a b
| a < 0 = (-1) * (rus (abs a) b)
| b < 0 = (-1) * (rus a (abs b))
| odd a = b + (rus (div a 2) (b*2) )
| otherwise = (rus (div a 2) (b*2) )
• MichaelWH 2009-07-23 11:06
Erlang, as a module.
```-module(peasant).
-export([peasant/2]).

peasant (1,Y) -> Y;
peasant (X,Y) when (X rem 2 == 1) ->
Y + peasant ((X bsr 1),(Y bsl 1));
peasant (X,Y) ->
peasant ((X bsr 1),(Y bsl 1)).```
• Kman 2009-07-23 11:09
c++ templates

template <unsigned int a, unsigned int b> struct RM_ {
static const unsigned int result = a & 0x1 ? b + RM_<a / 2, b * 2>::result : RM_<a / 2, b * 2>::result;
};
template <unsigned int b> struct RM_<1, b> {
static const unsigned int result = b;
};

unsigned int c = RM_<18, 23>::result;
• Evo 2009-07-23 11:21
The only real solution:

```<?php
function ymhoxntb(\$n1, \$n2)
{
\$written = "\$n1 x \$n2";

// Create the next line, dividing the left number by two and
// doubling the right.
do {
// Get the last line
\$lines = split("\n", \$written);
\$line = \$lines[count(\$lines)-1];
preg_match("/([0-9]*)\s+[x]?\s*([0-9]*)/", \$line, \$matches);
\$a1 = intval(\$matches[1]);
\$a2 = intval(\$matches[2]);

// Make the next line
\$a1 = floor(\$a1/2);
\$a2 *= 2;
\$written .= "\n\$a1 \$a2";
}
while(\$a1 > 1);
echo \$written."\n\n";

// Cross out the even numbers on the left side
\$docrossout = TRUE;
for(\$i = 0; \$i < strlen(\$written); \$i++) {
if(\$written[\$i] == "\n") {
\$docrossout = FALSE;
if(intval(substr(\$written, \$i)) % 2 == 0)
\$docrossout = TRUE;
continue;
}

if(\$docrossout)
\$written[\$i] = "-";
}
echo \$written."\n\n";

// Add the remaining right columns
\$lines = split("\n", \$written);
\$result = "";
foreach(\$lines AS \$line) {
if(!preg_match("/([0-9]*)\s+[x]?\s*([0-9]*)/", \$line, \$matches))
continue;

if(\$result == "")
\$result .= \$matches[2];
else
\$result .= " + ".\$matches[2];
}
echo \$result." = ";
eval("echo ".\$result.";");
echo "\n";
}
ymhoxntb(18, 23);
```
• Coyne 2009-07-23 11:25
This is in Java. It was tested and works for negatives.
```public static int doRussianMultiply(int a, int b)
{
if (a < 0) return -doRussianMultiply(-a,b);

int sum = 0;
while (a > 1) {
if ((a & 1) == 1) sum += b;
a >>= 1;
b += b;
}
if (a == 1) sum += b;

return sum;
}
```
• markwhi 2009-07-23 11:48
Late to the game, I guess. Replying without viewing comments, wonder if mine is original :)

http://pastebin.com/f50d7e6d5
• markwhi 2009-07-23 11:51
I guess I should post the code, not just a link to it:

/**
* Submission for TDWTF Programming Praxis 1: Russian Peasant Multiplication
* July 23, 2009
*/
#include <stdio.h>
#include <stdlib.h>

void
usage (void)
{
printf ("usage: rmult <int> <int>\n") ;
exit (-1) ;
}

int
main (int argc, char **argv)
{
int a, b, total = 0 ;

if (argc != 3)
usage () ;

a = atoi (argv[1]) ;
b = atoi (argv[2]) ;
if (a <= 0 || b <= 0)
usage () ;

printf ("%i * %i = ", a, b) ;

while (1) {
if (a % 2)
total += b ;

if (a == 1)
break ;

a /= 2 ;
b *= 2 ;
}

printf ("%i\n", total) ;

return 0 ;
}
• HCGL 2009-07-23 11:54
public static double RussianMultiply(int left, int right)
{
var columns = new Dictionary<int, int> {{left, right}};
var product=0;
while (left > 1)
columns.Add(left /= 2, right *= 2);

foreach (var row in columns)
product += row.Value * (row.Key % 2);

return product;
}
• Jeremy Burns 2009-07-23 12:01
```uint multiplyIntegers( uint a, uint b ) // C#
{
uint up, down, res = 0;

if( a > b ) { up = a; down = b; }
else { up = b; down = a; }

do
{
if( (down & 1) != 0 ) res += up;
up <<= 1;
down >>= 1;
}
while( down > 0 );

return res;
}
```
• Evo 2009-07-23 12:16
Oops... bugfix:

```function ymhoxntb(\$n1, \$n2)
{
\$written = "\$n1 x \$n2";

// Create the next line, dividing the left number by two and
// doubling the right.
do {
// Get the last line
\$lines = split("\n", \$written);
\$line = \$lines[count(\$lines)-1];
preg_match("/([0-9]*)\s+[x]?\s*([0-9]*)/", \$line, \$matches);
\$a1 = intval(\$matches[1]);
\$a2 = intval(\$matches[2]);

// Make the next line
\$a1 = floor(\$a1/2);
\$a2 *= 2;
\$written .= "\n\$a1 \$a2";
}
while(\$a1 > 1);
echo \$written."\n\n";

// Cross out the even numbers on the left side
\$docrossout = FALSE;
for(\$i = -1; \$i < strlen(\$written); \$i++) {
if(\$i == -1 || \$written[\$i] == "\n") {
\$docrossout = FALSE;
if(intval(substr(\$written, \$i + 1)) % 2 == 0)
\$docrossout = TRUE;
continue;
}

if(\$docrossout)
\$written[\$i] = "-";
}
echo \$written."\n\n";

// Add the remaining right columns
\$lines = split("\n", \$written);
\$result = "";
foreach(\$lines AS \$line) {
if(!preg_match("/([0-9]*)\s+[x]?\s*([0-9]*)/", \$line, \$matches))
continue;

if(\$result == "")
\$result .= \$matches[2];
else
\$result .= " + ".\$matches[2];
}
echo \$result." = ";
eval("echo ".\$result.";");
echo "\n";
}
ymhoxntb(18, 23);
```
• iggy 2009-07-23 12:19

```rpm :: Int -> Int -> Int
rpm a b = sum \$ aux a b [] where
aux 1 b xs = b:xs
aux a b xs | odd a     = aux (a`div`2) (b*2) (b:xs)
| otherwise = aux (a`div`2) (b*2) xs
```

P.S. Does not terminate for a<=0
• AngeloR. 2009-07-23 13:12
Simple PHP version. No array lists.

function rpm(\$val1,\$val2){
echo \$val1.' x '.\$val2.' = ';

while(\$val1 >= 1){
if(\$val1%2 != 0)
\$done += \$val2;
\$val1 = floor(\$val1/2);
\$val2 *= 2;
}
echo \$done;
}
• juancn 2009-07-23 13:20
Simple recursive implementation in scala (first version):
```def peasant(a : Int, b : Int) : Int =
if (a < 0 && b > 0) -peasant(-a, b)
else if (a < 0 && b < 0) peasant(-a, -b)
else if (a > 0 && b < 0) -peasant(a, -b)
else if (a > b) peasant(b, a)
else if (a == 0) 0
else if (a == 1) b
else if (a % 2 != 0) a+b+peasant(a/2, b*2)
else peasant(a/2, b*2)
```

It's not too pretty, but supports all edge cases (since the naive algorithm only works for positive integers).

This one, is a bit denser (but more obscure):
```def peasant(a : Int, b : Int) : Int =
if (a.abs > b.abs) peasant(b, a)
else if (a.abs < 2) a*b
else if (a % 2 != 0) a+b+peasant(a/2, b*2)
else peasant(a/2, b*2)
```

Also note that the multiplications can be removed (either changed by shifts or by an additional if clause).

It can probably be simplified. I don't like the first if very much, and my gut tells me that it's probably a more elegant way to solve this.

I haven't read other solutions yet and I'm eagerly waiting for the winning entries :D

OoopS! That's what happens when you post without properly testing:
```def peasant1(a : Int, b : Int) : Int =
if (a < 0 && b > 0) -peasant1(-a, b)
else if (a < 0 && b < 0) peasant1(-a, -b)
else if (a > 0 && b < 0) -peasant1(a, -b)
else if (a > b) peasant1(b, a)
else if (a == 0) 0
else if (a == 1) b
else if (a % 2 != 0) b+peasant1(a/2, b*2)
else peasant1(a/2, b*2)

for{ a <- -100 to 100
b <- -100 to 100 }
assert (a*b == peasant1(a,b), "peasant1 a: " + a + ", b: " + b + " => " + peasant1(a,b) )
```

And the (not much) denser version:
```def peasant(a : Int, b : Int) : Int =
if (a < 0) -peasant(-a,b)
else if(b < 0) -peasant(a,-b)
else if(a < 2) a*b
else if (a % 2 != 0) b+peasant(a/2, b*2)
else peasant(a/2, b*2)

for{ a <- -100 to 100
b <- -100 to 100 }
assert (a*b == peasant(a,b), "peasant a: " + a + ", b: " + b + " => " + peasant(a,b) )
```

(I might still have one or two WTFs in this code, but that's life ;) )
• Pony Princess 2009-07-23 13:35
In Ruby:

def mul(a,b)
(1..a).to_a.reverse.inject(0){|res,i| (i == a) ? ( [res + ((a % 2 == 1) ? b : 0) , ( a >>= 1; b <<= 1 )][0]) : res }
end
• PatrickBeebe 2009-07-23 13:59
C# Recursion:

public static int RussianMultiplication(int x, int y)
{
if (x == 0 || y == 0) return 0;
int sign = (x >> 31 | 1) * (y >> 31 | 1);
x *= (x >> 31 | 1);
y *= (y >> 31 | 1);
if (y < x)
return sign*RecursiveRussianMultiplication(y, x);
else
return sign*RecursiveRussianMultiplication(x, y);
}

public static int RecursiveRussianMultiplication(int x, int y)
{
if (x ==-1 || x == 1) return y;
return (x % 2 == 0 ? 0 : y) + RecursiveRussianMultiplication(x /= 2, y += y);
}
Here's mine, in python, with doctests, in 4 variations... it was a slow day at work :P
```"""
Russian peasant multiplication functions.

>>> russian_mult(18, 23)
414
>>> russian_mult(2, 4)
8
>>> russian_mult(-2, 4)
-8
>>> russian_mult(-2, -4)
8
>>> russian_mult_gen(18, 23)
414
>>> russian_mult_gen(2, 4)
8
>>> russian_mult_gen(-2, 4)
-8
>>> russian_mult_gen(-2, -4)
8
>>> russian_mult_opt(18, 23)
414
>>> russian_mult_opt(2, 4)
8
>>> russian_mult_opt(-2, 4)
-8
>>> russian_mult_opt(-2, -4)
8
>>> russian_mult_rec(18, 23)
414
>>> russian_mult_rec(2, 4)
8
>>> russian_mult_rec(-2, 4)
-8
>>> russian_mult_rec(-2, -4)
8
"""

def correct_values(func):
"""
This decorator function 'corrects' the inputs of the
other functions. It does this in two ways:
1) It ensures that the numerically lowest absolute value is the lhs. This is to minimise the looping as this is the loop control
2) It ensures negative multiplication can take place. It does this by multiplying both sides by -1 if the lhs is less than -1.
This can be removed by taking away the '@correct_values' line before a function to return to a 'pure' russian peasant multiplication algorithm
>>> def echo(lhs, rhs):
...     print lhs, rhs
>>> correct_values(echo)(-23, -18)
18 23
>>> correct_values(echo)(-43245, 2)
2 -43245
"""
def corrector(lhs, rhs):
lhs, rhs = (rhs, lhs) if abs(rhs) < abs(lhs) else (lhs, rhs)
lhs, rhs = (lhs * -1, rhs * -1) if lhs < 0 else (lhs, rhs)
return func(lhs, rhs)
corrector.__doc__ = func.__doc__
return corrector

@correct_values
def russian_mult(lhs, rhs):
"""
Simplest, most exact conversion of 'russian peasant multiplication'.
Builds a list of pairs and then iterates over them to find the result

>>> russian_mult(18, 23)
414
"""
mult_list = [(lhs, rhs)]
while mult_list[-1][0]:
mult_list.append( (mult_list[-1][0] / 2,
mult_list[-1][1] * 2) )
result = 0
for line in mult_list:
result += line[1] if line[0] % 2 else 0
return result

@correct_values
def russian_mult_opt(lhs, rhs):
"""
'Optimised' version of the first algorithm. It removes the
need to store the results by calculating the result in a
single pass.

>>> russian_mult_opt(18, 23)
414
"""
result = 0
while lhs:
result += rhs if lhs % 2 else 0
lhs /= 2
rhs *= 2
return result

@correct_values
def russian_mult_gen(lhs, rhs):
"""
Generator version of the russian_mult_opt function.
Uses a python generator to get values. This is then
given to a reduce which iterates over the generator
and produces the result.

>>> russian_mult_gen(18, 23)
414
"""
def build_list(lhs, rhs):
while lhs:
yield rhs if lhs % 2 else 0
lhs /= 2
rhs *= 2
return reduce(lambda x, y: x + y, build_list(lhs, rhs))
@correct_values
def russian_mult_rec(lhs, rhs):
"""
'Russian peasant multiplication' reduced to a recursive one-liner.
Returns 0 when lhs is 0, otherwise recursion, adding the rhs to the resu
lt
when called with an odd lhs value.
The recursion is done within the inline _russian_mult_rec function so as
to
avoid issues with the @correct_values decorator. If this isn't done then
infinite
recursion can occur and correct values aren't obtained.

>>> russian_mult_rec(18, 23)
414
"""
def _russian_mult_rec(lhs, rhs):
return 0 if not lhs else (rhs if lhs % 2 else 0) + _russian_mult
_rec(lhs / 2, rhs * 2)
return _russian_mult_rec(lhs, rhs)

if __name__ == '__main__':
import doctest
doctest.testmod()
```

I also added a 'correction' decorator to allow multiplication with negatives and to switch the inputs if the larger one is first (minor optimisation)
• Paul N 2009-07-23 14:19
Here is a C# version that multiplies two text numbers
```private static string Multiply(string number1, string number2)
{
string[,] multiplicationSteps = {{ number1, number2 }};
{
}
multiplicationSteps = RemoveEvenFactor1Steps(multiplicationSteps);
return result;
}

{
string lastStep = string.Empty;
string result = string.Empty;
for (int index = 0; index < multiplicationSteps.GetLength(0); index++)
{
lastStep = result;
}
return result;
}

private static string AddNumbers(string number1, string number2)
{
StringBuilder result = new StringBuilder();
string lastStep = string.Empty;
string currentStep = string.Empty;
for (int index = addendum1.Length - 1; index >= 0; index--)
{
lastStep = currentStep;
if (string.IsNullOrEmpty(currentStep))
{
currentStep = "0";
}
if (lastStep.Length > 1)
{
}
int lastDigitOfCurrentStep = currentStep.Length - 1;
result.Insert(0, currentStep[lastDigitOfCurrentStep]);
}
if (currentStep.Length > 1)
{
result.Insert(0, currentStep[0]);
}
return result.ToString();
}

private static string[,] RemoveEvenFactor1Steps(string[,] multiplicationSteps)
{
int newArraySize = multiplicationSteps.GetLength(0);
string[,] result = new string[newArraySize, 2];
Array.Copy(multiplicationSteps, result, multiplicationSteps.Length);
int indexStop = result.GetLength(0) - 1;
for (int index = 0; index < indexStop; index++)
{
string lastValue = result.GetValue(index, 0).ToString();
int lastDigitOfLastValue = lastValue.Length - 1;
string halfLastDigit = GetHalfOfDigit(lastValue[lastDigitOfLastValue]);
if (halfLastDigit.Length == 1)
{
result.SetValue(string.Empty, index, 0);
result.SetValue(string.Empty, index, 1);
}
}
return result;
}

{
int newArraySize = multiplicationSteps.GetLength(0) + 1;
string[,] result = new string[newArraySize, 2];
Array.Copy(multiplicationSteps, result, multiplicationSteps.Length);
int index = multiplicationSteps.GetLength(0) - 1;
string nextNumber1 = GetHalfOfNumber(multiplicationSteps.GetValue(index, 0).ToString());
string nextNumber2 = DoubleNumber(multiplicationSteps.GetValue(index, 1).ToString());
int nextArrayLocation = multiplicationSteps.GetLength(0);
result.SetValue(nextNumber1, nextArrayLocation, 0);
result.SetValue(nextNumber2, nextArrayLocation, 1);
return result;
}

private static string DoubleNumber(string number)
{
StringBuilder result = new StringBuilder();
string lastStep = string.Empty;
string currentStep = string.Empty;
for (int index = number.Length - 1; index >= 0 ; index--)
{
lastStep = currentStep;
currentStep = DoubleDigit(number[index]);
if (string.IsNullOrEmpty(currentStep))
{
currentStep = "0";
}
if (lastStep.Length > 1)
{
}
int lastDigitOfCurrentStep = currentStep.Length - 1;
result.Insert(0, currentStep[lastDigitOfCurrentStep]);
}
if (currentStep.Length > 1)
{
result.Insert(0, currentStep[0]);
}
return result.ToString();
}

private static string DoubleDigit(char digit)
{
switch (digit)
{
case '0':
return "0";
case '1':
return "2";
case '2':
return "4";
case '3':
return "6";
case '4':
return "8";
case '5':
return "10";
case '6':
return "12";
case '7':
return "14";
case '8':
return "16";
case '9':
return "18";
}
return string.Empty;
}

{
int index = multiplicationSteps.GetLength(0) - 1;
string halfValue = GetHalfOfNumber(multiplicationSteps.GetValue(index, 0).ToString());
if (string.IsNullOrEmpty(halfValue))
{ return false; }
else
{ return true; }
}

private static string GetHalfOfNumber(string number)
{
StringBuilder result = new StringBuilder();
string lastStep = string.Empty;
string currentStep = string.Empty;
for (int index = 0; index < number.Length; index++)
{
lastStep = currentStep;
currentStep = GetHalfOfDigit(number[index]);
if (string.IsNullOrEmpty(currentStep))
{
currentStep = "0";
}
if (lastStep.Length > 1)
{
int lastDigitOfLastStep = lastStep.Length - 1;
}
if (currentStep[0] != '0')
{
result.Insert(0, currentStep[0]);
}
}
return result.ToString();
}

private static string GetHalfOfDigit(char digit)
{
switch (digit)
{
case '0':
return "0";
case '1':
return "05";
case '2':
return "1";
case '3':
return "15";
case '4':
return "2";
case '5':
return "25";
case '6':
return "3";
case '7':
return "35";
case '8':
return "4";
case '9':
return "45";
}
return string.Empty;
}

private static string AddDigits(char digit1, char digit2)
{
switch (digit1)
{
case '0':
switch (digit2)
{
case '0':
return "0";
case '1':
return "1";
case '2':
return "2";
case '3':
return "3";
case '4':
return "4";
case '5':
return "5";
case '6':
return "6";
case '7':
return "7";
case '8':
return "8";
case '9':
return "9";
}
break;
case '1':
switch (digit2)
{
case '0':
return "1";
case '1':
return "2";
case '2':
return "3";
case '3':
return "4";
case '4':
return "5";
case '5':
return "6";
case '6':
return "7";
case '7':
return "8";
case '8':
return "9";
case '9':
return "10";
}
break;
case '2':
switch (digit2)
{
case '0':
return "2";
case '1':
return "3";
case '2':
return "4";
case '3':
return "5";
case '4':
return "6";
case '5':
return "7";
case '6':
return "8";
case '7':
return "9";
case '8':
return "10";
case '9':
return "11";
}
break;
case '3':
switch (digit2)
{
case '0':
return "3";
case '1':
return "4";
case '2':
return "5";
case '3':
return "6";
case '4':
return "7";
case '5':
return "8";
case '6':
return "9";
case '7':
return "10";
case '8':
return "11";
case '9':
return "12";
}
break;
case '4':
switch (digit2)
{
case '0':
return "4";
case '1':
return "5";
case '2':
return "6";
case '3':
return "7";
case '4':
return "8";
case '5':
return "9";
case '6':
return "10";
case '7':
return "11";
case '8':
return "12";
case '9':
return "13";
}
break;
case '5':
switch (digit2)
{
case '0':
return "5";
case '1':
return "6";
case '2':
return "7";
case '3':
return "8";
case '4':
return "9";
case '5':
return "10";
case '6':
return "11";
case '7':
return "12";
case '8':
return "13";
case '9':
return "14";
}
break;
case '6':
switch (digit2)
{
case '0':
return "6";
case '1':
return "7";
case '2':
return "8";
case '3':
return "9";
case '4':
return "10";
case '5':
return "11";
case '6':
return "12";
case '7':
return "13";
case '8':
return "14";
case '9':
return "15";
}
break;
case '7':
switch (digit2)
{
case '0':
return "7";
case '1':
return "8";
case '2':
return "9";
case '3':
return "10";
case '4':
return "11";
case '5':
return "12";
case '6':
return "13";
case '7':
return "14";
case '8':
return "15";
case '9':
return "16";
}
break;
case '8':
switch (digit2)
{
case '0':
return "8";
case '1':
return "9";
case '2':
return "10";
case '3':
return "11";
case '4':
return "12";
case '5':
return "13";
case '6':
return "14";
case '7':
return "15";
case '8':
return "16";
case '9':
return "17";
}
break;
case '9':
switch (digit2)
{
case '0':
return "9";
case '1':
return "10";
case '2':
return "11";
case '3':
return "12";
case '4':
return "13";
case '5':
return "14";
case '6':
return "15";
case '7':
return "16";
case '8':
return "17";
case '9':
return "18";
}
break;
}
return string.Empty;
}
```
• Ted Walther, newLISP fan 2009-07-23 14:30
An even better newlisp oneliner:

(define (rmul x y) (if (= x 1) y (+ (* (& x 1) y) (rmul (>> x) (<< y)))))

Thanks to the poster who noticed that the and operator is of use here, it saved a comparison operation.
• Whatever 2009-07-23 14:40
```0&&>::+13p\:2/23p:v
^g31g32    +*%2_\$\$.@```

Befunge-93. Shortest so far excluding whitespace?
• Lightnix 2009-07-23 14:53
C++ :)
```#include <iostream>

template <typename T>
class RussianNumerable
{
protected:
T value;
public:
bool printoutput;

RussianNumerable(T val)
{
value = (T)val;
printoutput = false;
}

//must maintain compatibility with regular numbers!
RussianNumerable & operator = (const T &in)
{
value = in;
return *this;
}

operator T()
{
return value;
}

//correct way of multiplying!!!
T & operator * (const T &in)
{
T n1 = value;
T n2 = in;
T first = 0;
T second = 0;
if(printoutput)
{
std::cout<<n1<<" x "<<n2<<"\n";
}
for(int i = n2; i != 1;)
{
if(i == n2)
{
first = n2*2;
}
n1/=2;
n2*=2;
if(printoutput)
{
std::cout<<n1<<"    "<<n2<<"\n";
}
for(int a=0;a<2000000;a+=3){a-=2;} //executes too fast?
if((int)n1 == 1 || (int)n1 == -1)
{
second = n2;
break;
}
}
if(printoutput)
{
std::cout<<"========\n";
}

}
};

int main()
{
RussianNumerable<float> a = 18;
RussianNumerable<float> b = 23;
a.printoutput = true;
std::cout<<a*b<<"\n";
std::cin.get();

return 0;
}
```
• inky 2009-07-23 15:08
First attempt, in Python.

```def multiply(x, y):
while x:
x, odd = divmod(x, 2)
if odd:
y += y
• samanddeanus 2009-07-23 15:14
Scheme with objects represented as higher order functions using message passing and GOTO done with call-with-current-continuation:
```(define (adder x)
(let ((total x))
(lambda (op)
(cond ((eq? op 'total) total)
((eq? op 'add) (lambda (x) (set! total (+ total x)) total))
(else (error "Invalid operation -- ADDER" op))))))

(define (halver x)
(let ((value x))
(lambda (op)
(cond ((eq? op 'value) value)
((eq? op 'halve) (set! value (quotient value 2)) value)
(else (error "Invalid operation -- HALVER" op))))))

(define (doubler x)
(let ((value x))
(lambda (op)
(cond ((eq? op 'value) value)
((eq? op 'double) (set! value (+ value value)))
(else (error "Invalid operation -- DOUBLER" op))))))

(define (mul x y)
(let ((left (halver (abs x)))
(right (doubler (if (negative? x)
(- y)
y)))
((call-with-current-continuation
(lambda (goto)
(letrec ((ten (lambda ()
(if (zero? (left 'value))
(result 'total)
(goto twenty))))
(twenty (lambda ()
(if (odd? (left 'value))
(left 'halve)
(right 'double)
(goto ten))))
ten))))))

```

• dee 2009-07-23 15:58
One more; MySQL stored function:

```DELIMITER WTF

CREATE FUNCTION peasant (argLeft BIGINT, argRight BIGINT)
RETURNS BIGINT
DETERMINISTIC
BEGIN
DECLARE result BIGINT DEFAULT 0;
IF argLeft = 0 THEN
RETURN 0;
END IF;

-- negative numbers
IF argLeft < 0 THEN
SET argLeft = -argLeft;
SET argRight = -argRight;
END IF;

-- helper table for multiplication rows
CREATE TEMPORARY TABLE peasant_helper (
itemLeft BIGINT NOT NULL,
itemRight BIGINT NOT NULL
);

-- insert the multiplication rows
WHILE argLeft > 0 DO
INSERT INTO peasant_helper VALUES (argLeft, argRight);
SET argLeft = argLeft >> 1;
SET argRight = argRight + argRight;
END WHILE;

-- calculate the sum of the right side
-- of the rows with an odd left side
SET result = (
SELECT
SUM(itemRight)
FROM
peasant_helper
WHERE
itemLeft & 1
);

DROP TEMPORARY TABLE peasant_helper;
RETURN result;
END
WTF

DELIMITER ;
```

------------------------

```mysql> SELECT peasant(18,23);
+----------------+
| peasant(18,23) |
+----------------+
|            414 |
+----------------+
1 row in set (0.00 sec)
```

Accumulators are so non-inventive. Try harder, people!
• John Stracke 2009-07-23 15:59
I've seen a couple of Erlang solutions, but neither of them did concurrency, so here:

```-module(peasant).

pairs(0,_,FilterPid) ->
FilterPid ! over;
pairs(X,Y,FilterPid) ->
FilterPid ! [X,Y],
pairs(X div 2, Y*2, FilterPid).

filter(FlattenPid) ->
over ->
FlattenPid ! over;
[X,Y] ->
if
(X rem 2)==1 ->
FlattenPid ! [X,Y]
end,
filter(FlattenPid)
end.

over ->
[_,Y] ->
end.

over ->
MulPid ! Total;
X ->
end.

mul(X, Y) ->
spawn(peasant,pairs,
[X,Y,
spawn(peasant,filter,
[spawn(peasant,flatten,
Res ->
Res
end.
```
• Scott 2009-07-23 16:11
Here's a simple recursive algorithm, written in python (I'm a Plone/Zope developer, so it's what I use regularly... plus, it's awesomest). A little colour for that cozy vi feeling ;)

I thought about handling the negative numbers in the recursive part, which is much more satisfying, algorithmically, but that would mean calculating the sign of left for every recursion, rather than just once. In my solution, calculating the sign takes work on the order of O(1); the alternate would be on the order of O(log(left)). It makes more sense to just pass the magnitudes in for recursion, and slap the sign back on afterwards. I'm sure that's how the Russians are tought to do it, anyway.

```def _russian (left, right):
result = {}
if left:
result[left] = right
result.update(_russian(left // 2, right * 2))
return result

def russian (left, right):
sign = left * right / abs(left * right)
return sign * sum([
r for l, r in _russian(abs(left), abs(right)).items()
if l % 2
])

```
• Paul N 2009-07-23 16:22
I think I am ahead on longest version. ;)

In the interest of being true to the problem, I used no built in math functions on the numbers passed in (which is why it is all string manipulation). I did use built in math functions with the integers used for indexing, but only addition and subtraction.

The Multiplication function works just fine with non-negative integers passed in as strings, but will give unpredictable results if anything else is passed in, which is a big WTF.

I tried to use as many WTFs in the function as possible, but don't know how to count them.

It is very easy to read, so maybe I should have obfuscated it to make it unmainable.

I think I have come up with the most WTF version so far (in a commonly used language), and would really like that sticker. ;)

The real WTF is the amount of time taken to write a simple multiplication function.
• Queex 2009-07-23 16:35
I, too, tried to pack mine with any many WTFs as possible, but no-one even seems to have noticed. Hell, mine crashes and burns as written.

Way to code review, everyone...
• epv 2009-07-23 16:37
Qwertyuiopas:
Any time you use n = n * 2 or n *=2, n += n would work.
Any time you use n = n * -1 or n *= -1, n = -n would work.

Anyone using * for 2 or -1 has NO EXCUSE.

The excuse is called compilers. Code what you mean and not what you want the compiler to do. The compiler knows what is fast better then you do more often then not. If you want a double, double it. 'n*=2' will take an identical number of cycles as 'n+=n' on modern CPUs. All you've done is obfuscate that you wanted to double something to increment something by something else, that happens to be itself, so that it is double what you wanted it to be.

Same with the left shift and right shift by 1. Do you mean multiply by two or do you actually want to use it as a bit mask? The compiler will probably change it to a bit-wise operator if it is faster anyways. Or as it more likely the case, the arithmetic operator is just as fast as the bit-wise operator. All you've accomplished is made it harder on humans and taken options away from the compiler.
• TP 2009-07-23 17:20
My C++ version is here:

int multiply(int a, int b)
{
int aa[32];
int bb[32];
int i = 0;
aa[i] = a;
bb[i] = b;
while(a!=1)
{
a/=2;
b*=2;
i++;
aa[i]=a;
bb[i]=b;
}
int result = 0;
for(int ii=0;ii<=i;ii++)
{
if ((aa[ii]&1) == 1)
{
result += bb[ii];
}
}
return result;
}
• The_Assimilator 2009-07-23 17:26
WTF, no PowerShell yet?

# begin script
clear-host

\$left = 18
\$right = 23
\$sum = 0

if (\$left -lt 0)
{
\$left *= -1
\$right *= -1
}

while (\$left -gt 0)
{
if ((\$left % 2) -eq 1)
{
\$sum += \$right
}

\$left = [Math]::Floor(\$left / 2)
\$right = \$right * 2
}

write-host \$sum
# end script

Should handle negative numbers and 0 but haven't tested it too much because I couldn't be arsed. For the same reason, no bitwise operators or recursion.
• ajp 2009-07-23 17:36
did this one that handles 0 and negative numbers.
```//F# Version 1.9.6.16
#light
let isOdd x =
(x%2) = 1

let abs x =
if x < 0 then -x else x

let rec mult x y =
match x with
| 0 -> 0
| 1 -> y
| _ when isOdd x -> y + mult (x/2) (y*2)
| _ -> mult (x/2) (y*2)

let Multiply a b =
match a with
| _ when ((a < 0) && (b > 0)) or ((a>0) && (b<0)) -> -mult (abs a) (abs b)
| _ -> mult (abs a) (abs b)
```
• DGM 2009-07-23 17:39
Larry H.:
```unsigned russian(unsigned a, unsigned b)
{
return ((a & 1) ? b : 0) + ((a & ~1) ? russian(a>>1, b<<1) : 0);
}```

Not tested.

Now that's what I was looking for. No fair using standard multiplication, division or mod operators. This code gets the job done using only shifts. Bravo!
• TP 2009-07-23 17:53
1) operations are done in wrong order
2) not doing correct operations (a & 1 is and-operation, not testing whether it's odd or even -- proper solution tests for decimal number last digit equals 1,3,5,7 or 9 to test if it's odd - otherwise it's different from how you do it by hand)
3) not following the rules (it said just ONE FUNCTION is allowed)
• Rusty Nail 2009-07-23 18:27
The assembly language submissions seemed a little too high level, so I went for Verilog. It compiles, probably synthesizes, but I didn't simulate it...

Implement it in a CPLD, no processor required :)

Just saw Ikegami's discrete logic solution for 4-bit numbers. Cool! Mine does 32-bit numbers though :P

```module multiply (
input               clock,
input               reset,

input               start,
input       [31:0]  a,
input       [31:0]  b,

output reg          finished,
output reg  [63:0]  c
);

reg     [4:0]   count;

reg     [31:0]  a_latched;
reg     [63:0]  b_latched;

always @(posedge clock or posedge reset)
begin
if (reset == 1'b1) begin
finished    <= 1'b0;
a_latched   <= 32'b0;
b_latched   <= 64'b0;
c           <= 64'b0;
count       <= 5'd0;
end else begin

finished    <= 1'b0;

if (start == 1'b1) begin
count[4:0] <= 5'd31;

a_latched[31:0] <= a[31:0];
b_latched[63:0] <= { 32'b0, b[31:0] };
c               <= 64'b0;

end else if (|count) begin
if ( a_latched[0] == 1'b1 ) begin
c[63:0] <= c[63:0] + b_latched[63:0];
end

a_latched[31:0] <= { 1'b0, a_latched[31:1] };
b_latched[63:0] <= { b_latched[62:0], 1'b0 };

count[4:0] <= count[4:0] - 5'd1;

if (count[4:0] == 5'd1) begin
finished    <= 1'b1;
end
end
end
end

endmodule
```
• Landei 2009-07-23 18:28
Scala:
```def russianMultiply(a:Int, b:Int) = {
def loop(x:Int, y:Int, list:List[(Int,Int)]):List[(Int,Int)] =
if(x == 0) list else loop(x >> 1, y << 1, (x, y) :: list)
loop(a, b, Nil).filter(_._1 % 2 == 1).foldLeft(0)(_+_._2)
}
```
• vog 2009-07-23 18:55
In addition to Python3, there is also a non-recursive, one-line, one-statement solution in Haskell:
```mul a b =
let (_,_,p) = foldl (\(a,b,p) _ -> (div a 2,b*2,p+b*mod a 2)) (a,b,0) [1..a] in p
```

Or, more efficiently:
```mul a b =
let (_,_,p) = foldl (\(a,b,p) _ -> (div a 2,b*2,p+b*mod a 2)) (a,b,0) [1..ceiling\$logBase 2\$fromIntegral a+1] in p
```

However, recursion (over "interm") makes it more clear:
```mul a b =
let interm = (a,b) : [ (div a 2,b*2) | (a,b) <- interm ]
cut_interm = takeWhile ((0<).fst) interm
in
sum [ b | (a,b) <- cut_interm, odd a ]
```
• Maurits 2009-07-23 18:59
80 characters, Perl, requires positive whole multiplicands:

perl -e "(\$a,\$b)=@ARGV;map{\$c+=\$b<<\$_ if\$a>>\$_&1}(0..log(\$a)/log 2);print\$c" 8 7

• MichaelWH 2009-07-23 19:02

```peasant :: Int -> Int -> Int
peasant 1 y = y
peasant x y
| x < 0     = -(peasant (-x) y)
| odd x     = y + p
| otherwise = p
where
p = peasant (x `div` 2) (y * 2)
```
• andyesslinger 2009-07-23 19:07
Hopefully this is original enough... Batch file...

@echo ON
REM Russian Peasant Multiplication via Batch file

@echo OFF
set /A m1 = %1
set /A m2 = %2
set /A EvenOdd=0
set /A EvenOddRet=0
set /A Calc=0

REM Cheat so we know if the output is correct.
set /A mval = %1 * %2

REM Decide if we're going to use the given numbers...
Set /A EvenOdd = %m1%
goto FindEvenOdd

REM Begin the loop
:Start

REM Odd Numbers are added to the accumulator
REM Even numbers are displayed but not used
if %EvenOddRet% equ 0 echo '--- %m1% x %m2%'
if %EvenOddRet% equ 1 echo ' %m1% x %m2%'
if %EvenOddRet% equ 1 set /A Calc = calc + %m2%

REM Divide m1; multiply m2
set /A m1 = (%m1% / 2)
set /A m2 = %m2% * 2

REM Reset the storage to the current number
Set /A EvenOdd = %m1%

goto FindEvenOdd

REM Jump back after determining Even/Odd
:Back

REM if m1 is zero or less we're done; print the totals...
if %m1% GTR 0 goto Start

echo 'Calc : %Calc%'
pause

REM Subtract 10 from the current number until we have a single digit
REM then hit the brute force code to see if it's even/odd
:FindEvenOdd
if %EvenOdd% GTR 9 set /A EvenOdd = %EvenOdd% - 10

if %EvenOdd% GTR 9 goto FindEvenOdd

if %EvenOdd% EQU 0 Set /A EvenOddRet = 0
if %EvenOdd% EQU 1 Set /A EvenOddRet = 1
if %EvenOdd% EQU 2 Set /A EvenOddRet = 0
if %EvenOdd% EQU 3 Set /A EvenOddRet = 1
if %EvenOdd% EQU 4 Set /A EvenOddRet = 0
if %EvenOdd% EQU 5 Set /A EvenOddRet = 1
if %EvenOdd% EQU 6 Set /A EvenOddRet = 0
if %EvenOdd% EQU 7 Set /A EvenOddRet = 1
if %EvenOdd% EQU 8 Set /A EvenOddRet = 0
if %EvenOdd% EQU 9 Set /A EvenOddRet = 1

GOTO Back
• Corpsegrinder 2009-07-23 19:20
Here´s my solution in PROLOG:
```russian_mul(X,1,Erg):-
!, Erg = X.

russian_mul(X,Y,Erg):-
1 is Y mod 2,
YHalf is Y // 2,
XDouble is X * 2,
russian_mul(XDouble, YHalf, RekErg),
Erg is X + RekErg.

russian_mul(X,Y,Erg):-
0 is Y mod 2,
YHalf is Y // 2,
XDouble is X * 2,
russian_mul(XDouble, YHalf, RekErg),
Erg = RekErg.
```
• Moe 2009-07-23 19:25
A proper 6502 assembler solution.

Features:
- multiplies two 8-bit numbers with 16 bit result
- inner loop of only 17 clock cycles per iteration
- worst case behaviour of 40 clock cycles per iteration
- minimizes number of iterations
- total execution time: 25 - 320 cycles
(i.e. only 3x slower (worst case) than MUL on Intel 8088)
- 43 bytes size
- uses C64-friendly memory locations

```; INPUT  = op1 in A, op2 in X
; OUTPUT = low byte in X, high byte in Y
; memory locations used as temp space = \$fb, \$fc, \$fd
stx \$fc    ; save op2
cmp \$fc    ; compare both operands
bcc noswap ; swap them unless op1 < op2
sta \$fc    ; save op1 instead of op2
txa        ; swap op2 for op1
noswap:
ldx #\$00   ; prepare result low byte
stx \$fd    ; clear high byte of op2
ldy #\$00   ; prepare result high byte
beq begin  ; skip shift of op2 for first iteration

loop:
asl \$fc    ; multiply op2 by 2, low byte
rol \$fd    ; multiply op2 by 2, high byte
begin:
lsr        ; divide op1 by 2
bne loop   ; if op1 is not zero repeat loop
rts        ; otherwise return result

sta \$fb    ; save current value of op1
txa        ; fetch low byte
tax        ; store low byte
tya        ; fetch high byte
tay        ; store high byte
lda \$fb    ; restore op1
bne loop   ; if op1 is not zero repeat loop
rts        ; otherwise return result
```
• mol1111 2009-07-23 20:56
I created index of all entries. Languages sorted by their name, entries sorted by order in which they appear. If you cannot find your entry, look in the "Other" (for languages with only one entry) or "Unspecified" (if you have not specified language and it was not easily deductable).

ABAP
dv 277800
Someone 277998 278677

APL
Captain Obvious 277817
Steve the Cynic 278029 278054

Assembler
Dascandy x86, ARM 277793
Bosshog 6502 277804 278103
Stalker x64 277911
kastein IA64 277930
Bob Montgomery 6502 278147
Lunkwill m68k 278154
flax ARM 278263
Kevin Kofler m68k 278381
Gumpy Guss PDP-8 278418
bd_ Rabbit 2000 278438
Chris Walton x86 278499
C x86 278562
Anonymous ARM 278710
Moe 6502 279053

BASIC
Kees QB/VB ? 277803
Takis VB.Net 277814
RayS VBA 277842 278407
djjeavons VB.Net 277887
antelopelovefan VBA 278068
JoLoCo Sinclair 278126
Yorick Sinclair 278372
bluebearr AutoIt 278460
James VBA 278489
Don Knisley VBA 278534
k1 278548 278550
Takis VB.Net 278799
some VBA coder VBA 278862

bc/dc
Nick Pope 277951 278207

brainfuck
Qwertyuiopas 278037
Eyrieowl 278241
Philipp 278837

Brilliant
Paula 277801

C/C++
Tim 277783 277784
Larry H. 277798
Stefan 277813
Zombywuf templates 277815
darkwraith 277832
KimmoS 277850
KnoNoth 277851
whileloopsareugly 277873
TerraNova 277876
YES WE CAN! 277912
little3lue templates 277914
GWO 277924 277962 277964 277965
ponky 277952 278066
hh10k 277969
shub 277985 278055
_flt 278003
Harleqin 278009
Zor 278046 278053 278059
Kman templates 278062 278880
Fooba 278100
serg 278113
hornet 278173 278191
Bored 278175
xtremezone 278176 278190 278205
Haggis 278189
Ronuk Raval 278209
Alan Woodland templates 278240
Михаил 278267
OmnipotentEntity 278270
MG 278284
Resistance Assembler 278321
Rob Hulswit templates 278329 278331
mxsscott 278342
Rob H 278352
J.I. 278356
Sam 278391
spiderlama 278416
0ffh 278451
Chris Walton 278499
demo templates 278528
khahem 278731
Mr. Black 278769
n1L templates 278844
markwhi 278906 278908
Lightnix 278994
TP 279023

C#
Jay 277786
Dopefish 277788
Brettm 277812
Dan 277834 277856
Damien 277843
Felix Ungman 277867
GM 277894
Fabio Lima 277922 277957
Osno 277972 277997 278021
groknroll 277980
campkev 277991 277994 278078 278081
Sean Handley 277995
Oliver Klozoff 278000
Floyd LINQ 278082
chriswatson LINQ 278106
Codism LINQ 278139
Jared Youtsey 278149
David C. 278161 278226
jeff.woodhull LINQ 278201
It'sMe 278203
Shiftyness 278236
stannius LINQ 278261
blueberry 278286
VirtualBlackFox LINQ 278292
nine 278293
TNProgrammer 278302
dontera 278324
Rob H 278352
Lernin ur codez 278376
PatrickBeebe 278393
Veryth LINQ 278433
brian 278450
Thomas Eyde 278456
Joel 278461
jnz 278473
JXO 278474
czetts 278846
HCGL 278911
Jeremy Burns 278922
PatrickBeebe 278974
Paul N 278983

D
Rief 278006
Quxxy 278069

Erlang
Mike McNally 278434 278440
MichaelWH 278877
John Stracke 279008

F#
darklajid 277890 277941 278137
Patrick Simpson 278127
ajp 278357 279029
cmugford 278486

FORTRAN
rst 277978
java.lang.Chris; 278266

Groovy
Matt 277949

freako 277838
Dave Ingram 277839
HypocriteWorld 277878
Maxim 277889
Noah Easterly 278130
semanticprecision 278170
Andrew Nurse 278198
Jonas Kramer 278220
ikorb 278299
valderman 278405 278406
Twey 278439
Joost 278567
jefu 278838
dub 278874
iggy 278935
vog 279045
MichaelWH 279047

Java
Jay 277786
Mat Rantell 277802
Will 277831
Drew 277844
Arjan 277879
Philipp 277903 277919
Kook 277963 277968
imhe 278105 278138
Jannik Jochem 278115
Thuktun 278124
idle 278128
klagdon 278131 278242
amischiefr 278152
Greg R 278212 278231
Davi Cavalcanti 278228
DeepThought 278230
bb 278235
cincinnatvs 278237
Fred Dagg 278408
subanark 278537
Rorick 278749
Queex 278761
Coyne 278892

Javascript
Zishan 277882
Jason Knight 277898
Mestafais 278005
jjs105 278136
jonnyq 278208
Phroggy 278221
astonerbum 278248 278264 278343
Scott 278294
Beat by the system 278319
Rob Hulswit 278329
Jeb Walter Strate 278345
Crindigo 278419
Chris 278484

LISP
newlisp.org newLISP 277861 278283
MP 2778711
leppie Scheme 277881
dee Scheme 277900
Éibhear Emacs 277910
Dmitri Savichev Scheme 277992 277999
lyml Scheme 277996
Harleqin Common Lisp 278009
Alex Muscar Common Lisp 278090 278096 278160 278514 278516
Trey Jackson Emacs 278194
Bob Scheme 278206
samanddeanus Scheme 278271
asdfghj Scheme 278311
guille_ 278317
Ted Walther, newLISP fan newLISP 278344 278986
unit3 Common Lisp 278417
noSignal Scheme 278469
iamtim2 newLISP 278491
jvmbsd7 Scheme 278493
Chris Judge 278868
samanddeanus Scheme 278998

LOLCODE
JaguarOne 277920
PopeHappyCat 278099

Lua
Stefan 277854
Will 278010
Tiogshi 278368
Methuselah 278675

MSIL
Osno 278153 278197 278729 278786 278801

Other
hydrus Clojure 277792
db2 HP 48 277857
Dave Ingram vimscript 277862
pjt33 SML 277864
SR ColdFusion 277896
Will MUSH 277942
Samuel A. Falvo II Forth 277976
Sal Postscript 278093
Cindi Knox mIRC 278174
MUMPS MUMPS 278211
Trurl MUMPS 278246 278255
darkscout Matlab 278298
treyb Excel 278300
Roger RPGLE 278337
Tom Medley - www.tommedley.com ML 278350
ikegami circuit diagram 278370
dee COBOL 278403
yowzer ocaml 278428
J Mathematica 278467
StarLite Progress V9 278583
Ralf Smalltalk 278794
Rorick Rebol 278810 278873
Whatever Befunge-93 278988
Rusty Nail Verilog 279040

Pascal
Azeroth 277837
malach Delphi 277860
baka0815 277868 277877 278020 278028 278065
DougB Delphi 278179
Trevor Dubinsky Delphi 278229
mol1111 Turbo Vision 278374

Perl
Me 277807 277845
epv 277849
Steven de B 277884
Anonymous 277977
tirerim 278119
John Evans 278141
Jim Halfpenny 278143
Igor V. 278199
Darren 278223
Warr regex 278260 278420
qoo3h 278353
Andrew Rodland 278358
H2 278388
Florent 278401 278404
Toby Gray 278538 278540
bugmonkey 278658
rjp 278714
Maurits 279046

PHP
The Wolf 277787 277799
Erin 277797
Clark S 277858 277872
Ryan 277863
Daniel 277904 277909
FatherStorm 277932
aBase 278036 278214
John Evans 278141
HonoredMule 278158 278168 278184
IcePanther 278195
Tim 278196
Paul 278265
LeCoyote 278396
mjomble 278413
mneimeyer 278524
LatecomerX 278617 278673
bugmonkey 278658
Evo 278886 278934
AngeloR. 278960

Prolog
Anonymous Coward 277938
Mike5 278204
A.T. 278641 278646
Corpsegrinder 279051

Python
ath 277789 277806 278244
phihag 277811 277818 277869
Fenris 277823
Jeff Kemp 277852 277940
Tempura 277875
Stalin 277880
Jim 277901
Eutactic 277915
RECURSIVEMAN 277916
rob tracey 277917
krat 277918
drBeat 277925
ross 277931
halber_mensch 277936 277943 277955 277979 278129
Real russian peasant :) 277974
Remy 278004
Billy 278007
Josh Bohde 278017 278080 278092 278104 278166 278854
Wulf0r 278024
Jürgen 278086
koblas 278101
Rob W. 278111
Jörg 278163
martinp 278172
JJM 278193
Ronuk Raval 278209
lostlogic 278222
SoaperGEM 278305
ZzzZZZz 278318
Lee Crabtree 278355
sdeek 278359
opussf 278364
KukkerMan 278366
Edinburgh Mike 278375
mwchase 278395
Jukka 278412
tdh 278444
Mr.'; Drop Database -- 278459
agrif 278497
Python 278688
Lom 278732
the real wtf fool 278842
inky 278996
Scott 279009

Ruby
arnemart 277825 277855
Mike Dotterer 277829
exo 277926
Nicholas Laux 277958 277971
Xthlc 277983 278026
derula 278050
Northpole 278072
jweir77 278079
Jürgen 278086
Dave Havlicek 278122
Jeremy Weathers 278216
Chewbie 278224
Jimmy Selgen 278367
Redredredredredred 278380
Pony Princess 278967

Scala
Alex Ciarlillo 277937
Ian McLaird 278023
Matt 278249
Unlabeled Meat 278332
juancn 278962
Landei 279042

Shell
mat BASH 277791
bluebearr Batch 278012 278243
Ken B Batch 278032
moltonel BASH 278262 278272 278282
Julian Calaby BASH 278485
The_Assimilator PowerShell 279028
andyesslinger Batch 279049

SQL
SQLDork 277795
KnowOracle Oracle 277816 277822 277824
Chris Hunt Oracle 277836
csulli13 277888
MeesterTurner T-SQL 277959
wombat T-SQL 278186
shane blake T-SQL 278210
Dave Havlicek PL/pgSQL 278322
Bodestone 278341
DFHawthorne Oracle 278409
Paul N T-SQL 278425 278427
Hidayat Oracle 278526
SlyEcho 278535
Boneist Oracle 278555
EJCorcoran T-SQL 278795
dee MySQL 279007

Tcl/Tk
Albrecht from Germany 278142 278145

Unspecified
Z 277796
Matthew Verleger 277827
ruckc 277828
cwink 277899 277905
Bob 277907
avl 277929
Jonathan 277967
buzkie 277984
Alex Guzman 278084
SimonY 278120
David Young 278185
Humanoid Life-form 278238
aef123 278245 278247
Josue Chi 278303
Michael Clark (mjac.co.uk) 278360
Eric 278371
Wheaties 278426
astander 278544
col obvious 278598
Alex 278628

XSLT
Dave van der Brugge 278133
wombat 278808

jnz 278473 should be in C/C++ category.
• mol1111 2009-07-23 21:25
Yorick:
Speccy basic, recursive:
```  10 DEF FN m(a,b)=VAL ((("FN m(
"+STR\$ a+"*2,INT ("+STR\$ b+"/2))
+("+STR\$ b+"-2*INT ("+STR\$ b+"/2
))*"+STR\$ a) AND b<>1)+(STR\$ a A
ND b=1))
```

C Nonsense in BASIC, 20:1
• jnz 2009-07-23 22:20
mol1111:
I created index of all entries.

Wow, that must have taken a lot of work.

mol1111:
C#
...
jnz 278473

My entry should be in the C/C++ section.
• dysfunctor 2009-07-23 22:44
This seems like a good opportunity to show the world why Haskell is interesting. I'll write several implementations.

We'll need some import statements:
```import Control.Monad.State
import Test.QuickCheck```

Unit tests

Where would we be without unit tests, eh? QuickCheck is a really cool library that automagically generates lots of test-cases for you.

Here's our generic test case. We write it as a function called prop_russian_multiplication with arguments mul, n1 and n2. mul is the multiply function we want to test. We leave it as a parameter because we will want to test several different implementations. When we run QuickCheck it evaluates prop_russian_multiplication with lots of random numbers for n1 and n2, checking that it is always True:
```prop_russian_multiplication mul n1 n2 =
n1 >= 0 ==> -- Only generate test cases with n1 >= 0
n1 `mul` n2 == n1 * n2 -- The property to test
-- This line doesn't do anything, but it gives QuickCheck
-- some hints.
where types = (n1 :: Integer, n2 :: Integer)```

Syntax notes: Whitespace (indents and newlines) is significant. "--" marks comments. Backticks (`) are syntactic sugar that let us write a prefix function (mul n1 n2) as an infix (n1 `mul` n2).

Iterative style

Haskell is a pure functional language, so it doesn't let you modify variables. If it did, we could write code like:
```russian_multiply n1 n2 =
total := 0
while (n1 > 0)
if (odd n1) total += n2
n1 := n1 `div` 2
n2 := n2 * 2

We can't do that, but we can cheat! We can write an auxiliary function called loop with arguments total, n1 and n2. loop can modify n1, n2 and total by calling itself with modified values, like this:
```russian_multiply_iterative n1 n2 = loop n1 n2 0
where
-- First the special case where n1 == 0.
loop 0  n2 total = total -- We're done here.  total is the answer
-- Now the general case.
loop n1 n2 total = loop (n1 `div` 2) -- new value for n1
(n2 * 2)     -- new value for n2
(if (odd n1) then total + n2 else total)
-- new value for total```

Then (here's the cool part) the compiler will notice that this is equivalent to a loop that modifies local variables. After the compiler has worked its magic, we have code exactly the same as the pseudo-code I wrote earlier. loop really is a loop! (This is known as tail-call optimisation, and is a requirement in the Haskell 98 standard.)

List style

This most closely matches the way the Russian peasant would really do it. It is also, perhaps, the most Haskell-ish way.

To solve 18 x 23, we first generate the list [18, 9, 4, 2, 1] (called halves) and the infinite list [23, 46, 92, ...] (called doubles). (Haskell is lazy, so infinite lists are fine. Haskell constructs only as much of the list as is needed.) Haskell's powerful list-processing syntax and libraries can do the rest in a single line:
```russian_multiply_lists n1 n2 =
sum [d | (h, d) <- zip halves doubles, odd h]
where
halves = f n1
where
f 0 = []
f n = n : f (n `div` 2)
doubles = iterate (* 2) n2```

Here's another cool thing. As I said earlier, Haskell constructs the lists on demand, but the elements of the list are consumed as soon as they are produced. A smart compiler will notice that the lists are just intermediaries between a producer and consumer, and cut out the middle man. Ultimately, we end up with object code that is exactly the same as for the iterative version!

Why does this matter? Well, the "natural" way to do it is the list way. That's how the Russian peasant does it. But the most efficient way to do it is the iterative way. Of course, any half-decent programmer knows this already, and writes his code the efficient way, but if he is a Haskell programmer, he doesn't need to. The compiler is smart enough to figure it out for him.

This technique for eliminating intermediate data structures is, known as deforestation. It is based on a deep, mathematical relationship between Data Structures (lists, in this case) and Algorithms (iteration) known as a hylomorphism.

I told a small lie earlier. Haskell does let you modify variables, but only in carefully controlled circumstances. You have to wrap it all in a thing called a Monad. There's more deep maths involved, and it's hard to get your head round, but here's a simple example using the State Monad.

This code is similar to the iterative code, except that instead of total we have state. The state only exists within stateful_loop. execState initialises the state of (stateful_loop n1 n2) to 0, runs it, and then returns the final state.
```russian_multiply_monadic n1 n2 =
execState (stateful_loop n1 n2) 0
where
stateful_loop n1 n2 =
-- We're done here.
--  () is a dummy value; it's the state we want
if n1 == 0 then return ()
else do
-- if n1 is odd modify the state
when (odd n1) \$ modify (n2 +)
-- repeat the loop with new n1 and n2
-- but keeping the same state
stateful_loop (n1 `div` 2)
(n2 * 2)```

This code might be equivalent to the iterative code ... but I'm not sure. Monads can be tricky. But very powerful. Monads are a principled way to implement things like: non-determinism, really smart parsing libraries, I/O, and much more besides.

Running it
```main = do
quickCheck \$ prop_russian_multiplication russian_multiply_iterative
quickCheck \$ prop_russian_multiplication russian_multiply_lists
putStrLn \$ "18 x 23 = " ++ show (18 `russian_multiply_lists` 23)```

Which should give the output:
```OK, passed 100 tests.
OK, passed 100 tests.
OK, passed 100 tests.
18 x 23 = 414```
• Moritz 2009-07-23 22:51
```import scala.annotation.tailrec
def rpmul(a : Int, b : Int) : Int = {
if (a < 0) {
if (b < 0) rpmul(-a,-b) else -rpmul(-a,b)
}
else if (b < 0) -rpmul(a,-b)
else {
val (x,y) = if (a > b) (b,a) else (a,b)
@tailrec def f(a : Int, b : Int, result : Int) : Int =
if (a == 0) result
else f(a>>1, b<<1, result + (a & 1) * b)
f(x, y, 0)
}
}```

Scala 2.8 trunk - remove @tailrec and import for 2.7.
• Greg 2009-07-23 23:14
didn't look too hard, but didn't see any awk solutions. how about:

awk 'NF==2{t=0;x=\$1;y=\$2;while(x>=1){if(x%2==1){t+=y}x=int(x/2);y=y*2}print t}'

just feed in 2 numbers per input line
• zcl 2009-07-23 23:22

Yes ,your article is very good, we have the same belief with you,so let me introduce the area to you.Now Juicy Jewelry become more adn more popular within all kind of people. Juicy couture is a kind of juicy series . It won a good reputation. Juicy sale often held its regular discount juicy activities,such as juicy charms,juicy couture charms and so on.In these activities juicy couture sale got great success. juicy couture consists of two main aspects, juicy couture jewelry and juicy couture accessories
Juicy couture series are worthwhile than other juicy on sales. They have a lot of discounted jewelry,for example discount Juicy Couture necklaces, juicy earrings , juicy bracelets and rings on sale. Benefit from the discount,you can get juicy jewelry save up to 30%, We assure you of our best services at all times.
• Kenneth Pullen 2009-07-24 00:01
It's not much, but here was my solution. Copy this into a .lua and watch the magic!
```-- rpc.lua
-- the russian peasant calculator
-- http://thedailywtf.com/Articles/Programming-Praxis-Russian-Peasant-Multiplication.aspx

function iterate_calculation(num1, num2, racetrack)
accumulator = 0
racetrack = racetrack or {}
table.insert(racetrack, {num1 = num1, num2 = num2})

num1 = math.floor(num1 / 2)
num2 = math.floor(num2 * 2)

if num1 >= 1 then
iterate_calculation(num1, num2, racetrack)
else
for key, value in ipairs(racetrack) do
if (value.num1 % 2) == 0 then
value.num2 = 0
end
end
for key, value in ipairs(racetrack) do
accumulator = accumulator + value.num2
end
end
return accumulator
end

if not arg[1] then
print("Usage: " .. arg[-1] .. " " .. arg[0] .. " num1 num2")
os.exit()
end

print(arg[1] .. " x " .. arg[2] .. " = " .. iterate_calculation(arg[1], arg[2]))
```
• DBA_In_OKC 2009-07-24 00:50
MSSQL 2005/2008. No loops, only CTE recursion.

CREATE TABLE #operands (leftval int, rightval int);
INSERT #operands SELECT 18, 23;

WITH russians (leftval, rightval) AS (
SELECT leftval / 2, rightval * 2
FROM #operands
UNION ALL
SELECT leftval / 2, rightval * 2
FROM russians
WHERE leftval > 0
)

SELECT SUM(rightval)
FROM russians
WHERE leftval % 2 = 1;

DROP TABLE #operands;

Sorry, should be
...
WITH russians (leftval, rightval) AS (
SELECT leftval, rightval
FROM #operands
...

in case the first value is odd...
• derari (was A.T.) 2009-07-24 02:08
```%% russian(?A,?B,?P)
%% Multiplies A and B the russian style and unifies the result with P.
%% All parameters may be variables.
russian(A,B,P) :-
% validate that all args are variables or positive integers
(var(A);integer(A),A>=0),
(var(B);integer(B),B>=0),
(var(P);integer(P),P>=0), !,
do_crazy_table_stuff(A,B,P).

%% do_crazy_table_stuff(?A,?B,?P)
%% does the crazy table stuff
do_crazy_table_stuff(A,B,P) :-
% If one of the factors is a variable, I prefer if it's the first one.
nonvar(A), var(B), !, do_crazy_table_stuff(B,A,P).
do_crazy_table_stuff(A,B,P) :-
% A is a value, B as well. Thus, there is exactly one result P.
nonvar(A), !, row(A,B,P,0,P), !. % <-- Therefore, here is a cut.
do_crazy_table_stuff(A,B,P) :-
% A is a variable, B is not -> many results
nonvar(B), !, row(A,B,P,0,P).
do_crazy_table_stuff(A,B,P) :-
% A is a variable, B as well -> even more results
% make sure P is initialized somehow
length(_,P), between(0,P,B), row(A,B,P,0,P).

%% row(?A,+B,?P,+N,?R).
%% A single row of the multiplication table
%% A: factor 1 in this row; B: factor 2 in this row
%% P: Result of the multiplication (only set if provided externally)
%% N: Number of current row, starting at 0
%% R: Result so far (sum of rows >= N where A is odd)
row(_,_,P,N,_) :-
% if P is provided, end recursion if N is just too big
nonvar(P), P < 1<<(N-1), !, fail.
row(0,_,_,_,0). % if A is 0, the result should be 0 as well
row(A,B,P,N,R) :-
row(Ax,B<<1,P,N+1,Rx),
% of course, this A should be twice as big
halve(A,Ax,Rem),
% add B to result if A is odd
R is Rx+B*Rem.

%% halve(-X2,+X,-Rem)
%% Ensures that X is halve the size of X2,
%% the remainder is stored in Rem (1 if X2 is odd, 0 else)
halve(1,0,1) :- !. % X and X2 being zero is not allowed
halve(X2,X,Rem) :- (Rem=0;Rem=1), X2 is X*2+Rem.
```
Examples:
```?- russian(18,23,Z).  % Z = 414;
?- russian(18,Y,414). % Y = 23;
?- russian(X,23,Z).   % X = 1, Z = 23; X = 2, Z = 46; ...
?- russian(X,Y,414).  % X = 1, Y = 414; X = 2, Y = 207; ...
?- russian(X,Y,Z).    % X = 0, Y = 0, Z = 0; X = 1, Y = 1, ...
```
• mol1111 2009-07-24 02:26
jnz:

mol1111:
C#
...
jnz 278473

My entry should be in the C/C++ section.

Sorry for the mistake. I guess it isn't the last one but I had no energy to check the results :-)
• astander 2009-07-24 02:38
• Boombuler 2009-07-24 03:23
Ok here is one more Brainfuck version. This one has comments ;)
```++++++>	                                            # A=6 (Input 1)
++++++++++++<                                       # B=12 (Input 2)
[                                                   # While (A <> 0) {
>>>[-]>[-]>[-]>[-]<<<<<<                          #   D = 0; E = 0; F = 0; G = 0;| P = A
[>>>+>+>+<<<<<-]                                  #   D = A; E = A; F = A; A = 0;
>>>>>[-<<<<<+>>>>>]<                              #   A = F; F = 0;
[-[->+<[>>+<<-]]>>[<<+>>-]<<]                     #   F = E / 2; E = 0; G = 0;
>[-<+>]<                                          #   E = F; F = 0;
[>++<-]>[<+>-]<                                   #   E = E * 2; F = 0;
>>[-]<<<                                          #   G = 0;
>[-<->]<                                          #   if (D != E)
[                                                 #   {
[-]<<                                           #     D = 0
[>+>+<<-]                                       #     C = C (plus) B; D = B; B = 0;
>>[-<<+>>]                                      #     B = D; D = 0;
]                                                 #   }
<<[>>++<<-]>>[-<<+>>]>[-]                         #   B = B * 2; D = 0;
<<<<[-[->>>+<<<[->>>>+<<<<]]>>>>[-<<<<+>>>>]<<<<] #   D = A / 2; A = 0; E = 0;
>>>[-<<<+>>>]<<<                                  #   A = D; D = 0;
]                                                   # }
>>.                                                 # Output as Ascii (H = 66)```
• symcbean 2009-07-24 03:57
A major shortcoming of all the examples I've looked as the insistence on using base 10 operations - this smacks of a distinct lack of under-engineering and foresight on the part of the developers. My code can use any radix which can be represented by a single character per digit:

<?php

// \$digits=array('0','1','2','3','4','5','6','7','8','9'); // decimal
\$digits=array('0','1'); // binary
// \$digits=array('.','!','\$','%','^','*','{','>'); // wtfimal

\$a=\$argv[1];
\$b=\$argv[2];

\$reverse_digits=array_flip(\$digits);
\$base=count(\$digits);
\$pairs=array();
\$even=array();

for (\$offset=0; \$offset<count(\$digits); \$offset++) {
\$even[]=\$digits[\$offset++];
}

praxis_gen_pairs(\$a, \$b);
\$out=praxis_reduce_pairs();

print "\$a x \$b = \$out\n";
exit;

function praxis_gen_pairs(\$a, \$b)
{
global \$pairs, \$digits;
\$pairs[]=array(\$a, \$b);
\$a=praxis_half(\$a);
\$b=praxis_double(\$b);
if (\$a!=\$digits[0]) {
praxis_gen_pairs(\$a, \$b);
}
}

function praxis_double(\$x)
{
global \$digits, \$reverse_digits, \$base;
\$out='';
\$carry=0;
for (\$i=strlen(\$x)-1; \$i>=0; \$i--) {
\$new_offset=\$reverse_digits[\$x[\$i]]+\$reverse_digits[\$x[\$i]]+\$carry;
\$carry=0;
if (\$new_offset>=\$base) {
\$carry=1;
\$new_offset=\$new_offset % \$base;
}
\$out=\$digits[\$new_offset] . \$out;
}
if (\$carry) \$out=\$digits[\$carry] . \$out;
return praxis_tidy(\$out);
}

function praxis_half(\$x)
{
global \$digits, \$reverse_digits, \$base, \$even;
\$out='';
\$carry=0;
for (\$i=0; \$i<strlen(\$x); \$i++) {
\$offset=(integer)((\$reverse_digits[\$x[\$i]] + \$carry)/2);
\$carry=0;
if (!in_array(\$reverse_digits[\$x[\$i]], \$even)) {
\$carry=\$base;
}
\$out.=\$digits[\$offset];
}
return praxis_tidy(\$out);
}

function praxis_reduce_pairs()
{
global \$pairs, \$even, \$digits;
\$out=\$digits[0];
foreach(\$pairs as \$offset=>\$val) {
// is it even?
\$digit=substr(\$val[0],-1);
if (in_array(\$digit, \$even)) {
unset(\$pairs[\$offset]);
} else {
}
}
return \$out;
}

{
global \$digits, \$reverse_digits, \$base;
if (strlen(\$a)<strlen(\$b)) {
\$x=\$a;
\$a=\$b;
\$b=\$x;
}
while (strlen(\$b)<strlen(\$a)) {
\$b=\$digits[0] . \$b;
}
\$carry=0;
\$out='';
for (\$x=strlen(\$a); \$x>0; \$x--) {
\$offset=\$reverse_digits[\$a[\$x-1]] + \$reverse_digits[\$b[\$x-1]] + \$carry;
if (\$offset>=\$base) {
\$carry=1;
\$offset-=\$base;
} else {
\$carry=0;
}
\$out=\$digits[\$offset] . \$out;
}
if (\$carry) \$out=\$digits[\$carry].\$out;
return praxis_tidy(\$out);
}

function praxis_tidy(\$a)
{
global \$digits;
while ((substr(\$a,0,1)==\$digits[0]) && (strlen(\$a)>1)) {
\$a=substr(\$a,1);
}
return(\$a);
}
?>
• Yorick 2009-07-24 05:42
mol1111:
C Nonsense in BASIC, 20:1

Do you mean it didn't work when you tried it? I may have made a mistake when transcribing it from the emulator window, but I think I checked it thoroughly. If you type it in, please take care to use tokens for DEF FN, VAL, FN, STR\$, INT, AND and <> instead of spelling them out.
• Marlon 2009-07-24 05:48
A False implementation!

`0 23 18 [\$0>][\$[\$1>][2-]#1=[@@\$@+@@\]?2/\2*\]#%%.`
• Marlon 2009-07-24 06:17
And the ugly simple False implementation...

`18a:23b:0[a;\$2/2*=~[b;+]?a;1>][a;2/a:b;2*b:]#.`
• Yorick 2009-07-24 06:25
Perl, entirely without arithmetic.
```(\$_,\$b)=map{'.'x\$_}@ARGV;
/^(.+)\1(.?)\$/,(\$_,\$b,\$c)=(\$1,\$b.\$b,\$c.(\$2&&\$b))while/../;
print length\$b.\$c;
```

• ClaudeSuck.de 2009-07-24 06:36
Matthew Verleger:
int RussianSum( int A, int B ){
return A ? RussianSum(A>>2,B<<2) + (!!(A&1))*(B): 0;
}

"RussianSum(A>>2,B<<2) + (!!(A&1))*(B): 0;" looks more like a swearing Russian @!#&^\$
• Marlon 2009-07-24 06:40
Finally the most aesthetic esoteric False version:

`0 23 18 [\$\$2/2*\-[@@\$@+\@]?\$1>][2/\2*\]#%%.`
• mol1111 2009-07-24 07:02
Yorick:
mol1111:
C Nonsense in BASIC, 20:1

Do you mean it didn't work when you tried it? I may have made a mistake when transcribing it from the emulator window, but I think I checked it thoroughly. If you type it in, please take care to use tokens for DEF FN, VAL, FN, STR\$, INT, AND and <> instead of spelling them out.

Sorry, it was my mistake, I had not used tokens for keywords inside strings. Now it works perfectly! Great job! And I thought that deffn is useless...
• cofiem 2009-07-24 08:31
Javascript version:

<!DOCTYPE html>
<html>
<title> Russian Peasant Multiplication</title>
<script>
function RussianMultiply(num1, num2){

var total = 0;
var easymultiply = num1*num2;

while(num1 > 0){
var newNum1 = Math.floor(num1/2);
var newNum2 = num2*2;
if(Math.floor(newNum1/2) != newNum1/2){
total += newNum2;
}
num1 = newNum1;
num2 = newNum2;
}
document.getElementById('results').innerHTML += "Russian result: "+total+" ("+easymultiply+")<br>";
}

</script>
<body>
<div id="results"></div>
<script>
RussianMultiply(18, 23);
RussianMultiply(0, 1);
RussianMultiply(4, 100);
RussianMultiply(8, 56);
RussianMultiply(100, 0);
</script>

</body>
</html>
• Corpsegrinder 2009-07-24 08:44
And a solution in AppleScript

```set res to 0
display dialog "First value:" default answer "" buttons {"OK"} default button 1
set firstVal to text returned of the result
display dialog "Second value:" default answer "" buttons {"OK"} default button 1
set secondVal to text returned of the result

repeat while secondVal is greater than or equal to 1
if secondVal mod 2 is 1 then
set res to res + firstVal
end if
set firstVal to firstVal * 2
set secondVal to round secondVal / 2 rounding down
end repeat

display dialog res buttons {"OK"} default button 1

```
• Corpsegrinder 2009-07-24 08:49
and to provide negative multipliers add

```if secondVal is less than 0 then
set firstVal to firstVal * -1
set secondVal to secondVal * -1
end if
```

after the first two dialogs
• PopeHappyCat 2009-07-24 09:13
Another lolcode, this time following the letter of the challenge more than the spirit.

LOLCODE 1.2X. Extends LOLCODE 1.2, by having a BUKKIT (array) and shift operators:
SHIFTROFL <x> <y> BTW shift x right y bits
SHIFTLOL <x> <y> BTW shift x left y bits

```HAI 1.2X
OBTW THIS IS EXTENSHUN OF 1.2 IT HAS BUKKIT N SHIFT
TLDR

CAN HAS STDIO?

I HAS A X
I HAS A Y
I HAS A MULTIPL

VISIBLE "CAN HAS X?:)"
GIMMEH X
VISIBLE "CAN HAS Y?:)"
GIMMEH Y

X R MAEK X A NUMBR
Y R MAEK Y A NUMBR

HOW DUZ I RPM YR X AN YR Y
I HAS A THING
THING IS NOW A BUKKIT
I HAS A MUTLIPL ITZ 0
I HAS A DUMMY
I HAS A COUNTR ITZ 0
IM IN YR RPMLOOP UPPIN YR COUNTR WILE DIFFRINT X AN 1
DUMMY R PRODUKT OF COUNTR AN 2
THING[DUMMY] R X
THING[SUM OF DUMMY AN 1] R y
X R SHIFTROFL X AN 1
Y R SHIFTLOL Y AN 1
IM OUTTA YR RPMLOOP
IM IN YR RPMLOOPAGAIN NERFIN YR COUNTR WILE BOTH SAEM COUNTR AN BIGGR OF COUNTR AN 0
DUMMY R PRODUKT OF COUNTR AN 2
X R THING[DUMMY]
Y R THING[SUM OF DUMMY AN 1]
MOD X AN 2
BOTH SAEM IT AN 1, O RLY?
YA RLY, MULTIPL R SUM OF MULTIPL AN Y
NO WAI, BTW NOTHING HAPPENS
OIC
IM OUTTA YR RPMLOOPAGAIN
FOUND YR MULTIPL
IF U SAY SO

MULTIPL R RPM X Y

VISIBLE "PRODUKT OF " N X N " N " N Y N " IZ " N MULTIPL N ":)"

KTHXBYE
```
• asd 2009-07-24 09:14
> perl wtf.pl 101 6
606

```eval eval '"'.

('`'|                       '-').  ('['^'"').('{'^'[').'(' .'\\'.'\$'.('`'|'!').','
.'\\'                     .'\$'.   ('`'|'"').')'.('{'^'[') .'='.('{'^'[').'\\'.'@'
.('`'       ^'!')       .('{'             ^')')          .('`'
^"'")     .("\{"^     '-').              ';'.(          "\`"|
'-').   ('['^'"')   .('{'               ^'[')          .'\\'.'\$'.('['
^'/') .';'. ('['^ ',').                ('`'|          '(').('`'|')')
.('`'|','   ).(('`')|                 '%').          "\(".
('\\').     ('\$').(                  "\`"|          '!').
"\)".       '\\'.                   "\{".          '\\'.
'\$'.(                       "\["^  '/').'+'.'='.'\\'.'\$'.( '`'|'"').'*'."\(".'\\'.
'\$'.(                     "\`"|   '!').'&'.('^'^('`'|'/') ).')'.';'.'\\'.'\$'.('`'
|'!')       .'>'.       "\>".             '='.(          '^'^(
"\`"|     "\/")).     "\;".              '\\'.          '\$'.(
"\`"|   '"').'*'.   '='.(               '^'^(          '`'|',')).'\\'
.'}'. ('['^ '+'). ('['^                ')').          ('`'|')').('`'
|('.')).(   '['^'/').                 ('{'^          '[').
('\\').     ('\$').(                  "\["^          '/').
';'.(       "\!"^                   '+').          ('!'^
'+').                       "\"";  \$:='.'^'~';\$~='@'|"\("; \$^=')'^'[';\$/='`'|"\.";
(\$,)=                     "\("^   '}';\$\='`'|'!';\$:="\)"^ '}';\$~='*'|'`';\$^="\+"^
"\_";       (\$/)=       "\&"|             "\@";          (\$,)=
"\["&     '~';\$\=     "\,"^              "\|";          (\$:)=
"\."^   ('~');\$~=   "\@"|               "\(";          \$^=')'^'[';\$/=
"\`"| "\."; (\$,)= "\("^                "\}";          \$\='`'|'!';\$:=
')'^"\}";   \$~=('*')|                 "\`";          (\$^)=
'+'^'_'     ;\$/='&'                  |'@';          (\$,)=
"\["&       "\~";                   (\$\)=          "\,";
```
• Dascandy 2009-07-24 09:22
flax:
Nobody has submitted ARM code yet that I have seen. Does this win for smallest number of instructions?
``` ; multiplicands in r0 and r1

mov r2,#0
loop
movs r0,r0,lsr #1
mov r1,r1,asl #1
bne loop```

Yours is second (I posted mine way too soon) but it is shorter and probably better tested. You don't have a return though, which I do have. IIRC I only have one opcode more though, so that would be the return.
• Tachyon 2009-07-24 09:29
Slightly evil asp.net dynamicly created controls version. Why hasn't anyone done an asp.net version (yet)?

using System;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Data;

public partial class Default : Page
{
protected void Page_Load(object sender, EventArgs e)
{
if (IsPostBack)
{
TextBox t1 = form1.FindControl("m1") as TextBox;
TextBox t2 = form1.FindControl("m2") as TextBox;
if ((t1.Text.Length > 0) && (t2.Text.Length > 0))
{
int mu1 = int.Parse(t1.Text);
int mu2 = int.Parse(t2.Text);
DataRow dr = d.Tables[0].NewRow();
dr[0] = mu1;
dr[1] = mu2;
d.Tables[0].AcceptChanges();
DoRussian();
l1.Text = "Result is : ";
int ret = 0;
foreach (DataRow dre in d.Tables[0].Rows)
{
int fi1 = (int)dre[0];
double fi = (double)fi1;
double f = fi / 2;
if (f != (fi1 / 2))
{
ret += (int)dre[1];
}
}
l1.Text += ret.ToString();
}
}
g.DataSource = d;
g.DataBind();
}

protected override void OnInit(EventArgs e)
{
base.OnInit(e);
Panel p2 = new Panel();
Label m = new Label();
m.Text = "Enter two numbers: ";
TextBox m1 = new TextBox();
m1.ID = "m1";
m1.MaxLength = 3;
TextBox m2 = new TextBox();
m2.ID = "m2";
m2.MaxLength = 3;
m1.Text = "4";
m2.Text = "6";
Label s = new Label();
s.Text = " &nbsp; &nbsp; ";
Label s1 = new Label();
s1.Text = " &nbsp; &nbsp; ";
Button b = new Button();
b.Text = "Do it!";
g.CellSpacing = 2;
g.BorderWidth = 1;
Panel p1 = new Panel();
}

private GridView g = new GridView();
private DataSet d = new DataSet();
private Label l1 = new Label();

private void DoRussian()
{
DataRow dr = d.Tables[0].Rows[d.Tables[0].Rows.Count - 1];
int d1 = (int)dr[0];
int d2 = (int)dr[1];
if (d1 > 1)
{
int d3 = d1 / 2;
int d4 = d2 * 2;
DataRow dn = d.Tables[0].NewRow();
dn[0] = d3;
dn[1] = d4;
d.Tables[0].AcceptChanges();
DoRussian();
}
}
}
• Jason 2009-07-24 11:19
one line recursive c# version:

static int OneLineRussian(int a, int b)
{
return (a==0)?0:(a%2==0)?OneLineRussian(a/2,b* 2):b+OneLineRussian(a/2,b*2);
}
• Ed 2009-07-24 11:25
Fairly elegant functional JavaScript 1.8 one-liner:
```function russian(a, b) [d for ([c, d] in function(c, d) {
do { yield [c, d]; } while (d <<= 1, c >>= 1)
}(a, b)) if (c & 1)].reduce(function(p, c) p + c, 0);
```

Might work in Firefox 3; I just used the JavaScript shell.
• kramthegram 2009-07-24 11:33
Here is my pretty schweet python version with a test script!(sorry for any the tabs, I prefer them)

def peasant(a,b):
oddnums=[]
while(a>1):
if((a%2)!=0):
oddnums.append(b)
a=a/2
b=b*2
for num in oddnums:
b=b+num
return b

for a in range(1,100):
for b in range(a,100):
if(peasant(a,b)!=(a*b)):
print "fail!", a, b
else:
print "schweet!"
• kramthegram 2009-07-24 11:35
Drat! Two spaces it is then!
def peasant(a,b):
oddnums=[]
while(a>1):
if((a%2)!=0):
oddnums.append(b)
a=a/2
b=b*2
for num in oddnums:
b=b+num
return b

for a in range(1,100):
for b in range(a,100):
if(peasant(a,b)!=(a*b)):
print "fail!", a, b
else:
print "schweet!"
• kramthegram 2009-07-24 11:44
Double Drat! bbcode, I hates you
```def peasant(a,b):
oddnums=[]
while(a>1):
if((a%2)!=0):
oddnums.append(b)
a=a/2
b=b*2
for num in oddnums:
b=b+num
return b

for a in range(1,100):
for b in range(a,100):
if(peasant(a,b)!=(a*b)):
print "fail!", a, b
else:
print "schweet!"
```
Got it to one line in a function on VBA. My proudest moment.

Function RussedRightUp(nr1 As Long, nr2 As Long) As Long

If nr1 > 0 Then RussedRightUp = RussedRightUp(nr1 \ 2, nr2 * 2) + nr2 * (nr1 Mod 2)

End Function
• curtmack 2009-07-24 13:49
Well, here's mine in Perl. The order of statements in the iterate function is a bit confusing, but it's all to ensure that it works in all of the unusual cases (namely, when 1 or 0 is given as the left operand).

Also, it doesn't work at all when given negative numbers... but that's a flaw inherent in the method itself, not necessarily in my implementation.

```#!/usr/bin/perl

use POSIX qw/ceil floor/;
my (\$op1, \$op2) = @ARGV;

sub iterate {

my (\$left, \$right, \$sum) = @_;
\$sum += \$right if \$left % 2;

return \$sum if \$left <= 1;

\$left = floor(\$left / 2);
\$right *= 2;

&iterate (\$left, \$right, \$sum);
}

my \$product = &iterate (\$op1, \$op2, 0);
print "\$product\n";

```
• Joe 2009-07-24 13:58
Excel Array Formula:

=SUM(MOD(INT(A\$1/POWER(2,ROW(A1:OFFSET(A1,INT(LN(A1)/LN(2)),0))-1)),2)*POWER(2,ROW(A1:OFFSET(A1,INT(LN(A1)/LN(2)),0))-1)*\$B\$1)

When pasting in the formula, instead of hitting enter, you need to press CTRL-SHIFT-ENTER to tell excel it's an array formula.

First number goes in A1
Second number goes in B1

• Cale Gibbard 2009-07-24 14:01
Here's a Haskell implementation using a list comprehension:

`multiply x y = sum [v | (u,v) <- zip (takeWhile (> 0) \$ iterate (`div` 2) x) (iterate (*2) y), odd u]`

• JS ROX! 2009-07-24 14:26
I LOVE me some js.

Wait, is this thing on? Is there anybody still here??

Well, here are my two favorites, in js one-liners :
```function grif(x,y){
return x>1?(x&1?y:0)+grif(x>>1,y<<1):y;
}

function firg(x,y){
for(var r=0;x&1?r+=y:1;x>>=1,y<<=1)if(!x)return r;
}
```
firg is almost twice as fast as grif. and only half to a third as fast as straight multiplication, depending on the script engine. here's the instrumentation (works in WSH, or browser):]
```//instrumentation

function straight(x,y){
return x*y;
}

function timeMethod(method,args,loop){
var start=new Date();
for(var i=0;i<loop;i++)method.apply(this,args);
var end=new Date();
return end-start;
}

new function main(){
var params=[990,990];
var loopCount=20000;
var methods=[
straight,
grif,
firg
]
var results=[];
for(var i=0;i<methods.length;i++){
var time=timeMethod(methods[i],params,loopCount);
var result=methods[i].apply(this,params);
results.push(methods[i].toString().match(/function ([^(]*)/)[1]+" took: "+time+"ms to get "+result);
}
}
```

for extra credit, here's the link to run the above in your browser:

Test Grif and Firg

Cheers, and thanks for the game!
• curtmack 2009-07-24 14:37
For an encore, I did 6502 assembly as well.

It should work, but I can't test it, because I don't know enough 6502 assembly to make a program that actually does something.

There's also the issue of whether or not BIT can actually be used the way I use it. The reference I used wasn't clear on the subject. Frankly, if BIT can't use constants as operands, I am going to invent a time machine, go back to 1975, and storm into MOS Technology with a pitchfork demanding to know why the hell it can't.

```PHA
LDA #00
STA \$03
LDA \$00

_ITER BIT #01
BNE _ROLL

CLC

STA \$00
LDA \$03

STA \$03
LDA \$00

_ROLL ASL \$02
LSR A
BNE _ITER

PLA
RTS```
• raony 2009-07-24 15:26
python:

f = lambda x,y, h = lambda x,y: x%2 != 0 and y or 0, g = lambda x,y: x > 1 and f(x/2, y*2) or 0: h(x,y) + g(x,y)
• Joel Klein 2009-07-24 16:04
Mathematica version that tries to match the algorithm as described:

RussianPeasantMultiply[i_, j_] :=
Total@Map[#[[2]]&,
DeleteCases[
NestWhileList[
Function[args, {Floor[args[[1]]/2.], args[[2]]*2}],
{i, j},
First[#] =!= 1 &],
{_?EvenQ, _}]]

The innermost call is NestWhileList, having the form NestWhileList[f, {i,j}, test].

If you use the NestWhileList expression with {12,23} as in the example you get a matrix representing the rows and columns:
{{12, 23}, {6, 46}, {3, 92}, {1, 184}}

Next is the DeleteCases expression, which uses a pattern {_?EvenQ, _} to delete rows where the first element is even.

Next out from that is Map[#[[2]]&, rows], which gives us just the 2nd column.

Finally, the numbers from the 2nd column are passed to Total.
• Just another Russian peasant 2009-07-24 17:07
Just a bit on the "curious" nature of the algorithm: doubling or halving a number using abacus is fast, even faster than adding or subtracting two numbers.

For example, here is the doubling algorithm:
```for every digit from the least significant to the most do:
if digit >=5 do
subtract 5 from this digit
carry 1 to next digit (propagate if needed)
end if
double this digit
continue to next digit
```

It may look complex, but actually doesn't involve counting beads (due to the most types of abaci being bi-quinary, including the Russian one), and therefore as fast as one could move his hand.

Addition or subtraction requires either counting beads, or messing with decimal half-carry (that is 4-bead wire on Russian abacus is really for; counting quarter-copecs is a marginal use).
• Bob 2009-07-24 18:16
This is exercise 1.18 in Structure and Interpretation of Computer Programs
• ikegami 2009-07-24 20:31
curtmack:
For an encore, I did 6502 assembly as well.

Wow, that's very similar to Varian72 (as in 1972). I helped write a number of control programs in Varian72 assembler. They're used to control CANDU nuclear power reactors and the 100s of valves of the attached boiler system. This is what's being used today!

Varian72 has a richer instruction set, and supports constants (bit 15 of the address field = 1: constant; bit 15 of the address field = 0: address)

For common constants, we used low memory which could be addressed using a single-word instructions.

```* RMUL - Russion Multiply
*
* Inputs:
* A-REG: Multiplier
* B-REG: Multiplicand
* X-REG: Anything
*
* Outputs:
* A-REG: Product
* B-REG: Destroyed
* X-REG: Unchanged

RMUL   ENTR
STA     MULTER        Save the multiplier

TZA                   A-REG = 0
STA     PROD          Init the product to zero.

LDA     MULTER        A-REG = Multiplier
RMUL01 BTA0    BT0,RMUL02    Jump over add if multiplier is even or zero

TBA                   A-REG = Multiplicand
STA     PROD          Save product.

LDA     MULTER        A-REG = Multiplier
RMUL02 LSLB    1             Double the multiplicand
LSRA    1             Half the multiplier
STA     MULTER        Save the multiplier
JANZ    RMUL01        Loop if multiplier is non-zero

RMULEX LDA     PROD          A-REG = Product
RETU*   RMUL

PROD   BSS     1
```

• Dale King 2009-07-24 20:31
Features:
- excessive use of goto
- no bitwise operations
- no mul/div/mod operations

```#include <stdio.h>

int peasantiply(int a, int b) {

int r = 0;
int h, d;

firstodd:
h = a;
while (h > 1) {
h -= 2;
}
d = b;
if (h == 1)

start:
if (a == 0)
goto done;

halve:
h = 0;
while (a > 1) {
h++;
a -= 2;
}
a = h;

doubleup:
d = b;
while (d > 0) {
d--;
b++;
}
d = b;

h = a;
while (h > 1) {
h -= 2;
}
if (h == 1) {
while (d >0) {
d--;
r++;
}
}

goto start;

done:
return r;
}

int main() {
printf("%d\n", peasantiply(18, 23));
}
```
• mol1111 2009-07-24 20:34
Updated version of index. Added entries from yesterday, fixed jnz's entry, resolved most entries without specified language, removed duplicates.

ABAP
dv 277800
Someone 277998 278677

APL
Captain Obvious 277817
Steve the Cynic 278029 278054

Assembler
Dascandy x86, ARM 277793
Bosshog 6502 277804 278103
Stalker x64 277911
kastein IA64 277930
Bob Montgomery 6502 278147
Lunkwill m68k 278154
flax ARM 278263
Kevin Kofler m68k 278381
Gumpy Guss PDP-8 278418
bd_ Rabbit 2000 278438
Chris Walton x86 278499
C x86 278562
Anonymous ARM 278710
Moe 6502 279053
curtmack 6502 279343

BASIC
Kees QB/VB ? 277803
Takis VB.Net 277814 278799
RayS VBA 277842 278407
djjeavons VB.Net 277887
antelopelovefan VBA 278068
JoLoCo Sinclair 278126
Yorick Sinclair 278372
bluebearr AutoIt 278460
James VBA 278489
Don Knisley VBA 278534
k1 278548 278550
some VBA coder VBA 278862

bc/dc
Nick Pope 277951 278207

brainfuck
Qwertyuiopas 278037
Eyrieowl 278241
Philipp 278837
Boombuler 279204

Brilliant
Paula 277801

C/C++
Tim 277783 277784
Larry H. 277798
Stefan 277813
Zombywuf templates 277815
Matthew Verleger 277827
darkwraith 277832
KimmoS 277850
KnoNoth 277851
whileloopsareugly 277873
TerraNova 277876
YES WE CAN! 277912
little3lue templates 277914
GWO 277924 277962 277964 277965
avl 277929
ponky 277952 278066
hh10k 277969
buzkie 277984
shub 277985 278055
_flt 278003
Harleqin 278009
Zor 278046 278053 278059
Kman templates 278062 278880
Alex Guzman 278084
Fooba 278100
serg 278113
hornet 278173 278191
Bored 278175
xtremezone 278176 278190 278205
David Young 278185
Haggis 278189
Ronuk Raval 278209
Humanoid Life-form 278238
Alan Woodland templates 278240
Михаил 278267
OmnipotentEntity 278270
MG 278284
Resistance Assembler 278321
Rob Hulswit templates 278329 278331
mxsscott 278342
Rob H 278352
J.I. 278356
Sam 278391
spiderlama 278416
0ffh 278451
jnz 278473
Chris Walton 278499
demo templates 278528
khahem 278731
Mr. Black 278769
n1L templates 278844
markwhi 278906 278908
Lightnix 278994
TP 279023

C#
Jay 277786
Dopefish 277788
Brettm 277812
ruckc 277828
Dan 277834 277856
Damien 277843
Felix Ungman 277867
GM 277894
cwink 277899 277905
Fabio Lima 277922 277957
Jonathan 277967
Osno 277972 277997 278021
groknroll 277980
buzkie 277984
campkev 277991 277994 278078 278081
Sean Handley 277995
Oliver Klozoff 278000
Floyd LINQ 278082
Alex Guzman 278084
chriswatson LINQ 278106
Codism LINQ 278139
Jared Youtsey 278149
David C. 278161 278226
jeff.woodhull LINQ 278201
It'sMe 278203
Shiftyness 278236
Humanoid Life-form 278238
aef123 278245 278247
stannius LINQ 278261
blueberry 278286
VirtualBlackFox LINQ 278292
nine 278293
TNProgrammer 278302
Josue Chi 278303
dontera 278324
Rob H 278352
Lernin ur codez 278376
PatrickBeebe 278393 278974
Veryth LINQ 278433
brian 278450
Thomas Eyde 278456
Joel 278461
JXO 278474
astander 278544
col obvious 278598
Alex 278628
czetts 278846
HCGL 278911
Jeremy Burns 278922
Paul N 278983
Tachyon ASP.Net 279255
Jason 279280

D
Rief 278006
Quxxy 278069

Erlang
Mike McNally 278434 278440
MichaelWH 278877
John Stracke 279008

F#
darklajid 277890 277941 278137
Patrick Simpson 278127
ajp 278357 279029
cmugford 278486

FORTRAN
rst 277978
java.lang.Chris; 278266

Groovy
Matt 277949

freako 277838
Dave Ingram 277839
HypocriteWorld 277878
Maxim 277889
Noah Easterly 278130
semanticprecision 278170
Andrew Nurse 278198
Jonas Kramer 278220
ikorb 278299
valderman 278405 278406
Twey 278439
Joost 278567
jefu 278838
dub 278874
iggy 278935
vog 279045
MichaelWH 279047
dysfunctor 279081
Cale Gibbard 279334

Java
Jay 277786
Mat Rantell 277802
ruckc 277828
Will 277831
Drew 277844
Arjan 277879
Philipp 277903 277919
Kook 277963 277968
buzkie 277984
Alex Guzman 278084
imhe 278105 278138
Jannik Jochem 278115
Thuktun 278124
idle 278128
klagdon 278131 278242
amischiefr 278152
Greg R 278212 278231
Davi Cavalcanti 278228
DeepThought 278230
bb 278235
cincinnatvs 278237
Humanoid Life-form 278238
aef123 278245 278247
Josue Chi 278303
Fred Dagg 278408
subanark 278537
astander 278544
col obvious 278598
Alex 278628
Rorick 278749
Queex 278761
Coyne 278892

Javascript
Z 277796
Zishan 277882
Jason Knight 277898
Mestafais 278005
jjs105 278136
jonnyq 278208
Phroggy 278221
astonerbum 278248 278264 278343
Scott 278294
Beat by the system 278319
Rob Hulswit 278329
Jeb Walter Strate 278345
Crindigo 278419
Chris 278484
cofiem 279233
Ed 279287
JS ROX! 279340

LISP
newlisp.org newLISP 277861 278283
MP 2778711
leppie Scheme 277881
dee Scheme 277900
Bob Scheme 277907 278206
Éibhear Emacs 277910
Dmitri Savichev Scheme 277992 277999
lyml Scheme 277996
Harleqin Common Lisp 278009
Alex Muscar Common Lisp 278090 278096 278160 278514 278516
Trey Jackson Emacs 278194
samanddeanus Scheme 278271 278998
asdfghj Scheme 278311
guille_ 278317
Ted Walther, newLISP fan newLISP 278344 278986
unit3 Common Lisp 278417
noSignal Scheme 278469
iamtim2 newLISP 278491
jvmbsd7 Scheme 278493
Chris Judge 278868

LOLCODE
JaguarOne 277920
PopeHappyCat 278099 279245

Lua
Stefan 277854
Will 278010
Tiogshi 278368
Methuselah 278675
Kenneth Pullen 279099

Mathematica
J 278467
Joel Klein 279356

MSIL
Osno 278153 278197 278729 278786 278801

MUMPS
MUMPS 278211
Trurl 278246 278255

Other
hydrus Clojure 277792
db2 HP 48 277857
Dave Ingram vimscript 277862
pjt33 SML 277864
SR ColdFusion 277896
Will MUSH 277942
Samuel A. Falvo II Forth 277976
Sal Postscript 278093
Cindi Knox mIRC 278174
darkscout Matlab 278298
Roger RPGLE 278337
Tom Medley - www.tommedley.com ML 278350
ikegami circuit diagram 278370
dee COBOL 278403
yowzer ocaml 278428
StarLite Progress V9 278583
Ralf Smalltalk 278794
Rorick Rebol 278810 278873
Whatever Befunge-93 278988
Rusty Nail Verilog 279040
Greg awk 279087
Marlon False 279219 279220 279225
Corpsegrinder AppleScript 279236 279237

Pascal
Azeroth 277837
malach Delphi 277860
baka0815 277868 277877 278020 278028 278065
DougB Delphi 278179
Trevor Dubinsky Delphi 278229
mol1111 Turbo Vision 278374

Perl
Me 277807 277845
epv 277849
Steven de B 277884
Anonymous 277977
tirerim 278119
John Evans 278141
Jim Halfpenny 278143
Igor V. 278199
Darren 278223
Warr regex 278260 278420
qoo3h 278353
Andrew Rodland 278358
H2 278388
Florent 278401 278404
Toby Gray 278538 278540
bugmonkey 278658
rjp 278714
Maurits 279046
Yorick 279222
asd 279246
curtmack 279331

PHP
The Wolf 277787 277799
Erin 277797
Clark S 277858 277872
Ryan 277863
Daniel 277904 277909
FatherStorm 277932
aBase 278036 278214
John Evans 278141
HonoredMule 278158 278168 278184
IcePanther 278195
Tim 278196
Paul 278265
LeCoyote 278396
mjomble 278413
mneimeyer 278524
LatecomerX 278617 278673
bugmonkey 278658
Evo 278886 278934
AngeloR. 278960
symcbean 279208

Prolog
Anonymous Coward 277938
Mike5 278204
A.T. 278641 278646 279196
Corpsegrinder 279051

Python
ath 277789 277806 278244
phihag 277811 277818 277869
Fenris 277823
Jeff Kemp 277852 277940
Tempura 277875
Stalin 277880
Jim 277901
Eutactic 277915
RECURSIVEMAN 277916
rob tracey 277917
krat 277918
drBeat 277925
ross 277931
halber_mensch 277936 277943 277955 277979 278129
Real russian peasant :) 277974
Remy 278004
Billy 278007
Josh Bohde 278017 278080 278092 278104 278166 278854
Wulf0r 278024
Jürgen 278086
koblas 278101
Rob W. 278111
Jörg 278163
martinp 278172
JJM 278193
Ronuk Raval 278209
lostlogic 278222
SoaperGEM 278305
ZzzZZZz 278318
Lee Crabtree 278355
sdeek 278359
opussf 278364
KukkerMan 278366
Edinburgh Mike 278375
mwchase 278395
Jukka 278412
tdh 278444
Mr.'; Drop Database -- 278459
agrif 278497
Python 278688
Lom 278732
the real wtf fool 278842
inky 278996
Scott 279009
kramthegram 279290 279292 279297
raony 279352

Ruby
arnemart 277825 277855
Mike Dotterer 277829
exo 277926
Nicholas Laux 277958 277971
Xthlc 277983 278026
derula 278050
Northpole 278072
jweir77 278079
Jürgen 278086
Dave Havlicek 278122
Jeremy Weathers 278216
Chewbie 278224
Jimmy Selgen 278367
Redredredredredred 278380
Pony Princess 278967

Scala
Alex Ciarlillo 277937
Ian McLaird 278023
Matt 278249
Unlabeled Meat 278332
juancn 278962
Landei 279042
Moritz 279082

Shell
mat BASH 277791
bluebearr Batch 278012 278243
Ken B Batch 278032
moltonel BASH 278262 278272 278282
Julian Calaby BASH 278485
The_Assimilator PowerShell 279028
andyesslinger Batch 279049

acsi 278150
treyb Excel 278300
Joe Excel 279333

SQL
SQLDork 277795
KnowOracle Oracle 277816 277822 277824
Chris Hunt Oracle 277836
csulli13 277888
MeesterTurner T-SQL 277959
wombat T-SQL 278186
shane blake T-SQL 278210
Dave Havlicek PL/pgSQL 278322
Bodestone 278341
DFHawthorne Oracle 278409
Paul N T-SQL 278425 278427
Hidayat Oracle 278526
SlyEcho 278535
Boneist Oracle 278555
EJCorcoran T-SQL 278795
dee MySQL 279007
DBA_In_OKC T-SQL 279145

Tcl/Tk
Albrecht from Germany 278142 278145

Unspecified
SimonY 278120
Michael Clark (mjac.co.uk) 278360
Eric 278371
Wheaties 278426

XSLT
Dave van der Brugge 278133
wombat 278808

BTW If anybody (Alex?) interested, here are sources for the index generator (datafile + python script).
• iamtim2 2009-07-25 01:33
;Done in Newlisp without using variables to store calculations. Making it purely functional, I believe.

(define (odd? x)
(= (& x 1) 1))

(define (half! x)
(>> x 1))

(define (double! x)
(<< x 1))

(define (b x y)
(cond
((= 1 x) y)
((and (< 1 x) (odd? x)) (+ y (b (half! x) (double! y))))
((< 1 x) (b (half! x) (double! y)))))
• Serpardum 2009-07-25 06:00
This is what I slapped together. It's fairly simply actually. This is C++ code but the only thing I notice right away keeping it from becoming C code is the use of bool.

A friend are I were discussing the fact he would use a & 1 to check for odd/even where I would use a % 2 == 1. just because I think it's more self explanitory.

```#include <iostream>

int russianMultiply( int a, int b ) {
// Multiplication on the chip may be innaccurate.
// Lets use the manual way to multiply to ensure we
bool aneg = a < 0;
if ( aneg )
a = -a;

int result = 0;
if ( a % 2 == 1 ) {
result += b;
}
while ( a > 1 ) {
a /= 2;
b <<= 1; // I don't even trust *2 to be accurate
if ( a % 2 == 1 ) { // is a odd?
result += b; // It is so add our current multicant
}
}

if ( aneg )
result = -result;
return result;
}

int main() {

std::cout << russianMultiply( 18, 23 ) << "\n";
std::cout << russianMultiply( -18, 23 ) << "\n";
std::cout << russianMultiply( 18, -23 ) << "\n";
std::cout << russianMultiply( -18, -23 ) << "\n";
}```
• mr.DUDA 2009-07-25 06:00
Did anyone try High-Level Shader Language? With modern video cards the program can run entirely on GPU and take no CPU time at all.

Here it goes (uncomment mul operation to apply results to any 3D model; leave it commented out for screen-aligned quad):

```uniform float A = 37;
uniform float B = 258;

uniform float4x4 worldViewProj;

float3 numbers[] =
{
{ 0, 1, 0 }, { 1, 0, 1 }, { 1, 0, 1 }, { 1, 0, 1 }, { 0, 1, 0 },
{ 0, 1, 0 }, { 1, 1, 0 }, { 0, 1, 0 }, { 0, 1, 0 }, { 1, 1, 1 },
{ 0, 1, 0 }, { 1, 0, 1 }, { 0, 0, 1 }, { 0, 1, 0 }, { 1, 1, 1 },
{ 1, 1, 1 }, { 0, 0, 1 }, { 0, 1, 0 }, { 0, 0, 1 }, { 1, 1, 1 },
{ 1, 0, 1 }, { 1, 0, 1 }, { 1, 1, 1 }, { 0, 0, 1 }, { 0, 0, 1 },
{ 1, 1, 1 }, { 1, 0, 0 }, { 1, 1, 0 }, { 0, 0, 1 }, { 1, 1, 0 },
{ 0, 1, 1 }, { 1, 0, 0 }, { 1, 1, 0 }, { 1, 0, 1 }, { 1, 1, 0 },
{ 1, 1, 1 }, { 0, 0, 1 }, { 0, 1, 0 }, { 0, 1, 0 }, { 0, 1, 0 },
{ 0, 1, 0 }, { 1, 0, 1 }, { 0, 1, 0 }, { 1, 0, 1 }, { 0, 1, 0 },
{ 0, 1, 0 }, { 1, 0, 1 }, { 0, 1, 1 }, { 0, 0, 1 }, { 1, 1, 0 }
};

void vs_main(float4 pos : POSITION, float2 t : TEXCOORD0, out float4 oPos : POSITION, out float3 oT : TEXCOORD0)
{
// russian multiplication goes here
float a = A, b = B, c = 0;
do
{
float a2 = a / 2;
float a2f = floor(a2);
c += b * (1 - step(a2, a2f));
a = a2f;
b *= 2;
} while (a > 0);

// pass outputs to pixel shader, convert pos to 0..1 up-down left-right
oPos = pos;// mul(pos, worldViewProj); --- TODO: leave commented out for screen-space quad
oT = float3(t, c);
}

float4 ps_main (float3 t : TEXCOORD0) : COLOR
{
// # of digits in result
float x = t.x, y = t.y, result = t.z;
float maxDigits = 1 + floor(log10(result));

// determine value and index of digit in result
float idigit = (maxDigits - 1) - floor(x * maxDigits);
float digit = floor(result * pow(10, -idigit));
float nonempty = digit > 0;
digit -= 10 * floor(digit * 0.1);

// get row and column of output number
float3 row = numbers[floor((y + digit) * 5)];
float col = row[4 * fmod(x * maxDigits, 1)] * nonempty;

return float4(col.xx, 1, 1);
}

technique
{
pass
{
ZEnable = false;
ZWriteEnable = false;
CullMode = NONE;
AlphaBlendEnable = false;
}
}```

P.S. the graphic is ASCII-style but is capable to display numbers of any width
• Stalker 2009-07-25 07:01
No hardware implementations yet? Oh well, VHDL isn't really my field (haven't done anything real in it ever) but this actually seem to work.

Put factors on input and then pulse start, the result can then be read from prod on rising edge of done.

```library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
use ieee.numeric_std.all;

entity RusMulUnit is
port
(
clk	: in std_logic;
fac0 	: in std_logic_vector( 19 downto 0 );
fac1	: in std_logic_vector( 19 downto 0 );
start 	: in std_logic;

prod 	: out std_logic_vector( 39 downto 0 ) := (others => '0');
done 	: out std_logic := '0'
);
end RusMulUnit;

architecture bdf_type of RusMulUnit is
signal fac0i 	: std_logic_vector( 19 downto 0 ) := (others => '0');
signal fac1i 	: std_logic_vector( 19 downto 0 ) := (others => '0');
signal sumi	: std_logic_vector( 39 downto 0 ) := (others => '0');
begin
process( clk )
begin
if rising_edge( clk ) then
if start = '1' then
fac0i <= fac0;
fac1i <= fac1;
sumi <= (others => '0');
done <= '0';
else
fac0i <= '0' & fac0i(19 downto 1);	-- shift right
fac1i <= fac1i(18 downto 0) & '0';	-- shift left
if fac0i(0) = '1' then
sumi <= sumi + fac1i;
end if;
if fac0i = 0 then
done <= '1';
end if;
end if;
end if;

if falling_edge( clk ) then
if start = '1' then
prod <= (others => '0');
else
if fac0i = 0 then
prod <= sumi;
end if;
end if;
end if;
end process;
end bdf_type;
```
• The_Assimilator 2009-07-25 07:41
Was going to submit a HLSL version as well but I thought I'd leave it up to someone more competent in HLSL than myself. :)
• mr.DUDA 2009-07-25 10:51
Hey, feel free to submit your version as well!

My code isn't well optimized, e.g. some calculations can be moved into vertex pipeline rather than perform per-pixel; also, if еру screen quad geometry is highly tesselated, everything can perform at per-vertex basis; also, by using a texture with baked numbers we can just tex2D instead of messing with ASCII-like-grid-symbols etc.

:)
• Kennie Nybo Pontoppidan 2009-07-25 13:18
let
in
end
• Rusty Nail 2009-07-25 15:11
No hardware implementations yet?

There's a schematic version and a verilog version way back in the flood of posts :)
• mol1111 2009-07-25 15:25
Rusty Nail:
No hardware implementations yet?

There's a schematic version and a verilog version way back in the flood of posts :)

ikegami circuit diagram 278370
Rusty Nail Verilog 279040
• Ben 2009-07-25 16:49
A bit late to this party, but here's my take:
```#include <assert.h>

#define is_odd(num) (num % 2 != 0)

/* Multiply two numbers together, in the manner of Russian peasants. */
/* This method expects and accepts only non-negative integers. */
int multiply(int lh, int rh)
{
assert(lh >= 0 && rh >= 0);

int total = 0;

while (lh > 0)
{
if (is_odd(lh))
total += rh;

lh /= 2;
rh *= 2;
}

}
```
• mol1111 2009-07-25 19:20
Does anybody has some idea in what language is this entry:
Wheaties 278426
written?

I was able to indentify all others, but this one remains mystery.
• Stalker 2009-07-25 20:05
Oops. Guess I fell asleep after a few hundred posts. Anyway, here's an implementation in a language having some neat functions but otherwise severely lacking (no bitwise and, no shift etc).

```function integer mul: integer f0, integer f1
begin
mul = 0;
while f0 > 0 do

// Just because we can
function boolean isEven: integer n
begin
isEven = n == (n / 2) + (n / 2);
end;

if !isEven( f0 ) then
mul = mul + f1;
end;

f0 = f0 / 2;
f1 = f1 + f1;
end;
end;

procedure main:
begin
// Test it
for x = 0 to 100 do
for y = 100 to 0 step -1 do
output x * y;
output mul( x, y );
end;
end;
end;
```
• Paul Marfleet 2009-07-25 20:34
Solution in F#:

let multiply a b =
let rec getWorkings a b lst =
match a with
| 1 -> lst
| _ ->
let c, d = a / 2, b * 2
getWorkings c d (lst @ [(c, d)])

let result =
getWorkings a b []
|> Seq.filter (fun (a, b) -> a % 2 = 1)
|> Seq.map (fun (a, b) -> b)
|> Seq.fold (fun acc b -> acc + b) 0
result

printf "%d" (multiply 18 23)
• fuggit 2009-07-26 00:40

mul 0 y = 0
mul x y | x < 0 = -(mul (- x) y)
mul x y = mul (x `div` 2) (y * 2) + if (even x) then 0 else y
• Paul Marfleet 2009-07-26 05:43
Refined F# solution:

let multiply a b =
let rec getResult a b sum =
match a with
| 1 -> sum
| _ ->
let c, d = (a / 2), (b * 2)
match c with
| x when c % 2 = 1 -> getResult c d (sum + d)
| _ -> getResult c d sum

match a with
| 0 -> 0
| 1 -> b
| _ -> getResult a b 0
• f_ranek 2009-07-26 06:25
Writen in Java, works for both nonnegative and negative numbers. Int type can be used as well as long.

long multiply(long a1, long a2)
{
long res = 0;
for (; a1 != 0; a1 >>>= 1, a2 <<= 1)
if ((a1&1) != 0)
res += a2;
return res;
}
• f_ranek 2009-07-26 09:28
@echo off

:: WindowsXP CMD script
:: Usage: save to file multiply.cmd, call multiply.cmd -13 56
:: Correct negative numbers handling

set result=0
set a=%1
set b=%2

if %a% lss 0 (
set /a a = -a
set /a b = -b
)

:loop
if %a% equ 0 goto :endx
set /a tmp = "a & 1"
if not %tmp% equ 0 set /a result += b
set /a "a >>= 1"
set /a "b <<= 1"
goto loop
:endx

echo %result%
• Alex Muscar 2009-07-26 10:28
Common Lisp:

This is a long one :). Assuming that function composition and unfold are provided by a library (eventually sigfun too, but it's not such a useful function after all) the implementation would be made out of rpm5-aux and rpm5. This is just because i wanted the implementation to be functional (sorta').

```(declaim (inline comp))
(defun comp (f g)
(lambda (&rest args)
(funcall f (apply g args))))

(defun unfold* (f &rest s)
(multiple-value-bind (c s) (apply f s)
(when c
(cons c (apply #'unfold* f s)))))

(declaim (inline sigfun))
(defun sigfun (n)
(if (minusp n)
#'-
#'+))

(defun rpm5-aux (m n)
(when (> m 0)
(values (list m n)
(list (ash m -1) (ash n 1)))))

(defun rpm5 (m n)
(let* ((ns (unfold* #'rpm5-aux (abs m) n)))
(reduce (sigfun m) (delete-if (comp #'evenp #'car) ns)
```
• Alex Muscar 2009-07-26 10:46
This is so nice :).
• Alex Muscar 2009-07-26 11:55
Common Lisp:

Corrected version of the tail recursive variant:
```(defun rpm7 (m n)
(labels ((rec (m n acc)
(if (= m 0)
acc
(rec (ash m -1) (ash n 1) (if (oddp m) (+ acc n) acc)))))
(funcall (sigfun m) (rec (abs m) n 0))))
```
• Михаил 2009-07-26 13:25
ehrm, forgot.

квас<<=1;

after the пиво>>=1;.
• curtmack 2009-07-26 13:33
I had to cheat a little bit here. I don't know of any way to make this algorithm work in Befunge without very advanced trickery. So, it doesn't actually print the result of the multiplication - it just prints out the values that would be added together if Befunge could actually handle such a thing.

```&&v
v <   \.:\<
>2/\2*\:2%|
^        <:
@        ^_```
• Karol Urbanski 2009-07-26 14:02
Here's mine in perl:
`sub k{(\$a,\$b)=@_,\$a%2&&(\$_+=\$b),\$a&&k(\$a>>1,\$b*2)}`

(50 chars)

And the one liner to use that:
```\$ perl -E'sub k{(\$a,\$b)=@_,\$a%2&&(\$_+=\$b),\$a&&k(\$a>>1,\$b*2)}k(@ARGV),say' 18 23
414
\$ perl -E'sub k{(\$a,\$b)=@_,\$a%2&&(\$_+=\$b),\$a&&k(\$a>>1,\$b*2)}k(@ARGV),say' 7 7
49```

(71 chars + args; also a true one-liner - no semicolons :))
That's making a function, as said in the article. Without using a subroutine, the algorithm by itself:
`\$a%2&&(\$_+=\$b),\$b*=2,\$a>>=1while \$a`

(35 chars! though \$a and \$b have to be initialised, if
`(\$a,\$b)=@ARGV;`
is used it becomes 49 chars)
And the one liners for that (slightly cheaty because semicolons):
```\$ perl -E'(\$a,\$b)=@ARGV;\$a%2&&(\$_+=\$b),\$b*=2,\$a>>=1while \$a;say' 7 3
21
\$ perl -E'(\$a,\$b)=@ARGV;\$a%2&&(\$_+=\$b),\$b*=2,\$a>>=1while \$a;say' 135 975
131625```

This is 62 chars + args.

Also, the above Befunge program is awesome and I fully endorse it, even if it doesn't fully work ;).
• djhworld 2009-07-26 14:10
I enjoy these tasks, they give me something to do whilst I'm feeling a bit of a blackout on the "programming ideas" but still want to write some code.

My solution isn't as elegant or "efficient" as everyone elses seems to be but it was fun none the less.

```public static int doPeasantMaths(int left, int right)
{
int leftColumn[] = new int[20];
int rightColumn[] = new int[20];

int product = 0;
int i = 0;

leftColumn[i] = left;
rightColumn[i] = right;

if( (leftColumn[i] % 2) != 0 )
{
product = product + rightColumn[i];
}

while(leftColumn[i] != 1)
{
if(leftColumn[i] != 1)
{
i++;
}

leftColumn[i] = leftColumn[i-1] / 2;
rightColumn[i] = rightColumn[i-1] * 2;

if( (leftColumn[i] % 2) != 0 )
{
product = product + rightColumn[i];
}

}

return product;
}
```

Obviously this code would fail if

a) The number of iterations exceeds 20 steps (as defined by the column sizes)
b) The number in the left column is entered as 0

but it works otherwise : '}
• djhworld 2009-07-26 14:17
Just refined my previous code, it was terrible in retrospect, this is a cleaner method!

```public static int doPeasantMaths(int left, int right)
{
int product = 0;

if( (left % 2) != 0 )
{
product = product + right;
}

while(left != 1)
{
left = left / 2;
right = right * 2;

if( (left % 2) != 0 )
{
product = product + right;
}
}

return product;
}
```
• Matti Helin 2009-07-26 17:04
A couple of more solutions with Matlab.
A solution, which follows the specifications pretty much to the letter:
```function z = russianmultiply(x, y)
A = [x, y];
while A(end,1) ~= 1
A(end+1,:) = [floor(A(end,1)/2), A(end,2)*2];
end
A(~mod(A(:,1), 2),:) = [];
z = sum(A(:, 2));```

And another solution for matrix input (works as Matlab function times would with positive integers):
```function Z = russianpeasantmultiply(X, Y)
if any(size(X) ~= size(Y))
error('Matrix dimensions must agree');
end
dim = size(X);
X = reshape(X, 1, prod(size(X)));
Y = reshape(Y, 1, prod(size(Y)));
while any(X(end, :) > 1)
X(end+1, :) = floor(X(end, :)/2);
Y(end+1, :) = Y(end, :)*2;
end
Z = sum(Y.*mod(X,2));
Z = reshape(Z, dim);```
• Karol Urbanski 2009-07-26 18:57
Ok, I found a very small improvement to my earlier progs.
Function:
```sub k{(\$a,\$b)=@_,\$a%2&&(\$_+=\$b),\$a&&k(\$a/2,\$b*2)}

\$ perl -E'sub k{(\$a,\$b)=@_,\$a%2&&(\$_+=\$b),\$a&&k(\$a/2,\$b*2)}k(@ARGV),say' 18 23
414```

1 char less, for 49 and 70 respectively...

Not a function:
```\$a%2&&(\$_+=\$b),\$b*=2,\$a/=2while \$a

\$ perl -E'(\$a,\$b)=@ARGV;\$a%2&&(\$_+=\$b),\$b*=2,\$a/=2while \$a;say' 135 975
131625```

One char less, 34 chars for the algorithm, 61 for the one-liner.

I actually thought / wouldn't return