- 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
My solution in haskell:
P.S. Does not terminate for a<=0
Admin
Simple PHP version. No array lists.
function rpm($val1,$val2){ echo $val1.' x '.$val2.' = ';
}
Admin
Simple recursive implementation in scala (first version):
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):
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
Addendum (2009-07-23 14:51): OoopS! That's what happens when you post without properly testing:
And the (not much) denser version:
(I might still have one or two WTFs in this code, but that's life ;) )
Admin
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
Admin
C# Recursion:
Admin
Here's mine, in python, with doctests, in 4 variations... it was a slow day at work :P
I also added a 'correction' decorator to allow multiplication with negatives and to switch the inputs if the larger one is first (minor optimisation)
Admin
Here is a C# version that multiplies two text numbers
Admin
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.
Admin
C++ :)
Admin
First attempt, in Python.
Admin
Scheme with objects represented as higher order functions using message passing and GOTO done with call-with-current-continuation:
Admin
One more; MySQL stored function:
Addendum (2009-07-23 16:04): Accumulators are so non-inventive. Try harder, people!
Admin
I've seen a couple of Erlang solutions, but neither of them did concurrency, so here:
Admin
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.
Admin
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.
Admin
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...
Admin
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.
Admin
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; }
Admin
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.
Admin
did this one that handles 0 and negative numbers.
Admin
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!
Admin
Admin
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
Admin
Scala:
Admin
In addition to Python3, there is also a non-recursive, one-line, one-statement solution in Haskell:
Or, more efficiently:
However, recursion (over "interm") makes it more clear:
Admin
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
http://blogs.msdn.com/matthew_van_eerde/archive/2009/07/23/bad-perl-russian-peasant-multiplication-algorithm.aspx
Admin
In Haskell, dealing with negatives.
Admin
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 'Answer: %mval%' 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
Admin
Here´s my solution in PROLOG:
Admin
A proper 6502 assembler solution.
Features:
Admin
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 Alex Papadimoulis VBScript 277748 Kees QB/VB ? 277803 Takis VB.Net 277814 RayS VBA 277842 278407 djjeavons VB.Net 277887 Slinky VB? 278001 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 WraithShade 278057 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 The Answer + 2 278328 hornet threads 278340 Rob H 278352 Lernin ur codez 278376 PatrickBeebe 278393 Veryth LINQ 278433 brian 278450 Thomas Eyde 278456 Joel 278461 joeyadams 278471 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
Haskell freako 277838 Dave Ingram 277839 Sebastian Paaske Tørholm 277870 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 Cookie 277785 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 Markus Persson 278039 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 acsi Spreadsheet 278150 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 WarheadsSE 277944 278061 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 Chad M 278132 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 Adrian 278402 Jukka 278412 tdh 278444 Mr.'; Drop Database -- 278459 agrif 278497 Python 278688 Lom 278732 the real wtf fool 278842 workmad3 278975 inky 278996 Scott 279009
Ruby arnemart 277825 277855 Mike Dotterer 277829 exo 277926 Nicholas Laux 277958 277971 Xthlc 277983 278026 derula 278050 Amadan 278071 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
Addendum (2009-07-24 02:26): jnz 278473 should be in C/C++ category.
Admin
C Nonsense in BASIC, 20:1
Admin
Admin
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:
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:
Syntax notes: Whitespace (indents and newlines) is significant. "--" marks comments. Backticks (
) are syntactic sugar that let us write a prefix function (<i>mul n1 n2</i>) as an infix (<i>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:
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:
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:
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.
Monadic style
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.
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
Which should give the output:
Admin
Scala 2.8 trunk - remove @tailrec and import for 2.7.
Admin
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
Admin
It's not much, but here was my solution. Copy this into a .lua and watch the magic!
Admin
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;
Addendum (2009-07-24 00:59): Sorry, should be ... WITH russians (leftval, rightval) AS ( SELECT leftval, rightval FROM #operands ...
in case the first value is odd...
Admin
As there were complaints about the maintainability of the solutions, I added some comments.
Examples:Admin
Admin
45 X 76 is uneven, so you add 76 to start with
Admin
Ok here is one more Brainfuck version. This one has comments ;)
Admin
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('0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f'); // hexadecimal // $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 { $out=praxis_add($pairs[$offset][1], $out); } } return $out; } function praxis_add($a, $b) { 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); } ?>Admin
Admin
A False implementation!
Admin
And the ugly simple False implementation...
Admin
Perl, entirely without arithmetic.
Admin
"RussianSum(A>>2,B<<2) + (!!(A&1))*(B): 0;" looks more like a swearing Russian @!#&^$
Admin
Finally the most aesthetic esoteric False version:
Admin
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...