12
\$\begingroup\$

The challenge

Write a program that takes two integers from standard input, separated by a comma, and then prints a visualisation of long multiplication of those two integers to standard output.

Eg:

Input

14, 11

Program output

     14
    x11
   _____
     14
    14
  ______
    154

Input

-7, 20

Program output

     -7
    x20
   _____
     00
    14
   _____
   -140

Assume always correct inputs and numbers in the range [-999, 999]

Winning criteria

Shortest code wins!

\$\endgroup\$
1

5 Answers 5

5
\$\begingroup\$

Mathematica 213 217 197 193 186 184 193 184 177

Code

a_~g~b_ := 
With[{e = IntegerDigits@b}, Column[Flatten@{a, UnderBar["x " <> IntegerString[b]], 
Table[Row @@ {PadRight[{a Reverse[e][[i]]}, i, " "]}, {i, Length@e}], OverBar[a b]}, 
Alignment -> Right]]

Usage

g[845, 921]

multiply

\$\endgroup\$
4
  • \$\begingroup\$ Surely by IntegerString[921] you mean IntegerString[b]? \$\endgroup\$ Dec 21, 2014 at 4:51
  • \$\begingroup\$ Yes, good catch! \$\endgroup\$
    – DavidC
    Dec 21, 2014 at 6:09
  • \$\begingroup\$ I think the spec allows for the removal of the space in "x ". \$\endgroup\$ Dec 21, 2014 at 12:08
  • \$\begingroup\$ Your're correct. I decided to leave it in because it looked better (and I wasn't going to have the shortest code anyway). \$\endgroup\$
    – DavidC
    Dec 21, 2014 at 13:30
3
\$\begingroup\$

Perl, 108 chars

Best of breed 108 char solution, incorporating some ideas from Orabig.

($x,$y)=<>=~/[-\d]+/g;printf"%7s
",$_ for$x,x.$y,"-"x7,(map{abs($x*$_).$"x$i++}reverse$y=~/\d/g),"-"x7,$x*$y

Earlier 139 char solution

sub P{sprintf"%*d",@_}
($x,$y)=<>=~/[^,]+/g;$,=$/;
print P(7,$x),"  x".P(4,$y),"-"x7,(map{P 7-$i++,abs$_*$x}reverse$y=~/\d/g),
"-"x7,P 7,$x*$y
\$\endgroup\$
1
  • \$\begingroup\$ /me bow in respect... I didn't see the possibility to include the map in the printf part. And the $y=~/\d/g trick was clever \$\endgroup\$
    – Orabîg
    Sep 18, 2012 at 19:15
1
\$\begingroup\$

Python, 174 170:

a,b=input();r,s=str(a),str(b);h=len(r+s)*'-';print'\n'.join(["%9s\n%9s\n%9s"%(r,'x'+s,h)]+["%%%ii"%(9-i)%(int(d)%10*a)for i,d in enumerate(s[::-1])]+["%9s\n%9i"%(h,a*b)])

Usage: exactly as requested, run and input the values in standard input.

To see running: http://ideone.com/S8xNb

Output:

     1234
    x5678
 --------
     9872
    8638
   7404
  6170
 --------
  7006652

Thanks to fabiocerqueira and beary605 and David Carraher

\$\endgroup\$
1
  • \$\begingroup\$ You can remove 4 characters of whitespace: print '\n' -> print'\n', 10*a) for i,d in enumerate -> 10*a)for i,d in enumerate, "%9s\n%9i" % (h,a*b) -> "%9s\n%9i"%(h,a*b) \$\endgroup\$
    – beary605
    Sep 14, 2012 at 23:40
1
\$\begingroup\$

Python, 145, another answer with a little bit different output.

Code

a,b=input();h=6*'-';print'\n'.join(["%6i\nx%5i\n%s"%(a,b,h)]+["%%%ii"%(6-i)%(int(d)%10*a)for i,d in enumerate(str(b)[::-1])]+["%s\n%6i"%(h,a*b)])

Usage

just as requested

Output

   999
x  999
------
  8991
 8991
8991
------
998001

To see running: http://ideone.com/mdR18

\$\endgroup\$
1
\$\begingroup\$

Perl, 157 151 150 144 141 133 chars :

($x,$y)=<>=~/[-\d]+/g;map{$z=~s/z/ z/g;$z=(abs$x*$_)."z$z"}split//,abs$y;map{printf"%6s
",$_}$x,"x$y",$b="-"x6,(split/z/,$z),$b,$x*$y

Usage :

>echo "-123, 456" | perl mult.pl
   -123
   x456
-------
    738
   615
  492
-------
 -56088
\$\endgroup\$
1
  • \$\begingroup\$ Had an idea this morning : using printf make me improve my solution by 8 characters :) \$\endgroup\$
    – Orabîg
    Sep 18, 2012 at 8:05

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.