- 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
Scheme with fold and unfold:
Admin
Any explanation? Maybe some of the code got mangled while posting, or you're using yet a different shell?
Admin
I can beat that...
int RussianPeasantMultiplyFor18And23( ) { return 414; }
OMG.. my code is fastest?
Admin
Yes, bash, sorry. You'll have to give it two numbers, without space, and the multiplication sign must be an actual '*'.
eg: $ ./russian.sh 1929 551 $ ./russian.sh 1823 414
Admin
improvement for some problems starting with even number:
Admin
Why recurse when you can use a linked list?
Admin
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.
Admin
Here is my solution in C#:
-Works with negative values on any or both operands -No multiplication
Admin
You could always recurse over linked lists and get the best of both worlds :P
Admin
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).
Admin
Google Search (by far the most commonly used programming language):
http://lmgtfy.com/?q=russian+peasant+multiplication
Admin
C#, just for fun :
Admin
C# Recursive solution. Handles edge cases (negative integers, 0). Focus is on readability/clarity and not performance:
Admin
Here is an interesting javascript version
The reason for the anonymous function is because of a variable scope issue that occurs when the function is called multiple times.
Admin
Admin
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)
Admin
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,B12,0) B3: =if(A3,B22,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)
Admin
Anyone done is using a .BAT script yet?
Admin
//C# public static void Go() { Console.WriteLine(PraxisMultiply(18, 23).ToString()); }
Admin
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; }
Admin
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:
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?
Admin
See post #278250 Maybe it's time to go back to school :P
Admin
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
Admin
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!)
Admin
You win so far :) As long as that works, obviously.
Admin
Admin
Recursive Python. Pretty disappointed with my work after seeing some of the others!
Admin
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); }
Admin
In spite of being epic late, here's mine:
Admin
how about PL/pgSQL?
Admin
call into it with CalculateLikeRussianPeasant(101, 202, null);
Admin
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?
Admin
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
Admin
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%2c;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,c2>::s+b%2c: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));
Admin
Oops, copy-paste for the fail.
Real C++ version: int r=0;for(;b;r+=b%2c,b/=2,c=2);
Admin
Shifty recursive Scala
Admin
If you're gonna do it in good LISP, don't use setq so much.
Admin
Hell with them, just do:
Function mult (a,b) mult = a*b end
Screw the Russians
Admin
Free format RPGLE
Admin
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.
Admin
Threaded solution for maximum performance on a multicore system - not yet capable of negative or zero first multiplicand:
Admin
I happened to be in SQL server at the the time so...
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.
Admin
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
It outputs in a similar form, as well as digits.Admin
http://thedailywtf.com/Comments/Programming-Praxis-Russian-Peasant-Multiplication.aspx?pg=8#278264
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 :)
Admin
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)))))
Admin
My javascript version uses no multiplication, division, nor bit-shifting. Handles decimals, but negatives are left as an exercise for the reader.
Admin
The program listed above produces this output
Admin
My WTF is that I'd just create a huge times-table in MS Access and use DAO calls to read it back.
Admin
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),(r2),(r::q)) else peasant((l div 2),(r2),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);
Admin
In C, C++, C#, taking zeros and negative numbers into account:
Recursive (not tested):
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:Non-recursive (also not tested):
(Of course, in C++ and C#, you would probably move the declarations for c and PosNeg down closer to where they're actually used.)