- Feature Articles
- CodeSOD
- Error'd
- Forums
-
Other Articles
- Random Article
- Other Series
- Alex's Soapbox
- Announcements
- Best of…
- Best of Email
- Best of the Sidebar
- Bring Your Own Code
- Coded Smorgasbord
- Mandatory Fun Day
- Off Topic
- Representative Line
- News Roundup
- Editor's Soapbox
- Software on the Rocks
- Souvenir Potpourri
- Sponsor Post
- Tales from the Interview
- The Daily WTF: Live
- Virtudyne
Admin
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:
Admin
Ok here's mine... in javascript, which has its limits
Works for signed integers.
Haven't read the comments, so someone may have already done the same thing.
Admin
Don't know if this has been done yet (probably has).
Naive recursive Python implementation:
Faster, bit-oriented C89 version (handles negatives):
Admin
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
Admin
MUMPS:
Features: Shortened keywords! Keywords reused for variable names! Recursion! Untested!
Admin
Recursive Java, taking advantage of its Unicode support.
Admin
I cleaned-up the PHP function I posted earler. As before, it
Admin
Ruby solution:
Admin
Admin
Haskell:
Admin
Here's mine, in HTML5, JavaScript and CSS!
Admin
Pythonic solution:
Addendum (2009-07-22 14:02): Fixed for negatives and zeros.
Addendum (2009-07-22 14:10): Reduce memory usage at the cost of one line:
Admin
Admin
In ruby :
def russian_peasant(x, y) return y if x/2 == 0 (x % 2 == 0) ? russian_peasant(x/2, y2) : y + russian_peasant(x/2, y2) end
Not properly tested, but I think it should work.
Admin
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.
Admin
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?
Admin
Admin
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;
Admin
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.
P.S. While previewing the comment I can see that the site appears to be inserting
tags and the beginning of each line of my code block even though it is embedding the code within a
Admin
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.
Admin
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.
Admin
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; }
Admin
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; }
}
Admin
Admin
I had to compensate for the algorithm's failure when a is odd.
Admin
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.
Admin
brainfuck...not sure if this is going to show up properly with all the angle braces, but let's give it a try....
Admin
Ok, once more with bit shifting and accounting for negative numbers.
Admin
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?
Admin
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.
Admin
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); }
Admin
That doesn't work:
This is tested and i added some extra MUMPS-flavour:
->
:
Admin
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); }
Admin
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.
Admin
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) }
Admin
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:
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.
Admin
Admin
Here's my altered submission:
MUMPS:
Trurl
Admin
especially since she misspelled 'brilliant' ;)
Admin
Nonsense. In Perl, $n*=2 has fewer characters than $n+=$n. :-P
Admin
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+\sx\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;
Admin
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!"
Admin
#!/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
Addendum (2009-07-22 14:42): That's bash of course, not sh.
Admin
Nobody has submitted ARM code yet that I have seen. Does this win for smallest number of instructions?
Admin
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
Admin
Sorry, in advance.
To the PHB: it's extensible multiplication architecture.
Admin
FORTRAN 77
Admin
#define int инт #define return разврат #define if еслибы #define while покашто #define else иначе #define printf напечатать //к черту всех floats инт множение(инт пиво,инт квас) { инт чердылка=0; еслибы(пиво > квас ) //чтобы быстрее работала, пацаны {чердылка=квас;квас=пиво;пиво=чердылка;чердылка=0;}
покашто(пиво!=1) { еслибы((пиво & 0x1)==1) //ne делитса на два чердылка+= квас; пиво>>=1; еслибы(квас < 0) напечатать("Ну твою мать!"); }
разврат чердылка; }
инт негативноеMноение(инт пиво,инт квас) {разврат -1*множение(инт пиво,инт квас);}
Admin
http://thedailywtf.com/Comments/Programming-Praxis-Russian-Peasant-Multiplication.aspx?pg=5#278037
Admin
My solution.