### November 18, 2011

We begin with the function that displays a single multiplication. We find it easiest to plan everything first, calculating the width of the output display in the variable `len` and the number of lines in the body of the multiplication in the variable `lines`:

```(define (mult x y)   (let* ((ys (digits y))          (len (length (digits (* x y))))          (lines (length (filter positive? ys))))     (display-right x len)     (display-right y len)     (display (repeat len #\-)) (newline)     (when (< 1 lines)       (let loop ((ys (reverse ys)) (i 0) (z 1))         (when (pair? ys)           (if (zero? (car ys))               (loop (cdr ys) i (* z 10))               (begin (display-right (* x (car ys) z) (- len i))                      (loop (cdr ys) (+ i (ilog10 z) 1) 1)))))       (display (repeat len #\-)) (newline))     (display-right (* x y) len)))```

We used several utility functions that aren’t shown here, though all are at http://programmingpraxis.codepad.org/AMItBoYw: `digits`, which returns a list of the digits in a number, is from the Standard Prelude; `repeat` returns a string consisting of n repetitions of the character c; `display-right` displays a number n right-justified in a string of width len, and appends a newline; and `ilog10` returns the number of digits in the input number n, minus one.

Function `problem-a` takes a filename and outputs the requested multiplications:

```(define (problem-a filename)   (with-input-from-file filename     (lambda ()       (let loop ((x (read)) (y (read)) (i 1))         (when (and (positive? x) (positive? y))           (display "Problem ") (display i) (newline)           (mult x y)           (loop (read) (read) (+ i 1)))))))```

To solve the problem, say `problem-a multiply.in`.

Pages: 1 2

### 6 Responses to “Grade School Multiplication”

1. DGel said

My quickly hacked together version in Python. Would love to see more elegant versions, but right now can’t think of one.

```#!/usr/bin/python

import sys

def expand_string(a, n):
diff = n - len(a)
if diff > 0:
a = ' ' * diff + a
return a

def pprint_mult(i, j, counter):
print "Problem", counter
res = int(i) * int(j)
length = len(str(res))
separator = '-' * length
print expand_string(i, length)
i = int(i)
print expand_string(j, length)
print separator

n_printed = 0
printstring = ''
printlen = length
for pos in range(len(j)):
if j[len(j) - 1 - pos] == '0':
printstring += '0'
else:
print expand_string(str(int(j[len(j) - 1 - pos]) * i) + printstring, printlen)
n_printed += 1
printlen = length - pos - 1
printstring = ''
if n_printed > 1:
print separator
print res

with open(sys.argv, 'r') as dfile:
counter = 1
for line in dfile:
a, b = line.split()
if a == '0' and b == '0':
break
pprint_mult(a, b, counter)
counter += 1
```
2. DGel said

minor correction: instead of writing my expand_string() function, I could have used something like:

```('{0: >' + str(printlen) + '}').format(int(j[len(j) - 1 - pos]) * i) + printstring)
```
3. DGel said

sigh… correction on my correction: I should leave the string conversion in :)

4. ”’
My python solution
”’
i1=int(raw_input(‘enter first no’))
i2=int(raw_input(‘enter second no’))
print i1,’\n’,i2
print ‘————‘
t=i2
cnt=0
x=0
while t!=0:
x=(t%10)*i1
if cnt==0 and x!=0:
print x
elif x!=0:
print x*(cnt*10)
t=t/10
cnt+=1
print ‘————‘
print i1*i2

5. ```
i1=int(raw_input('enter first no'))
i2=int(raw_input('enter second no'))
print i1,'\n',i2
print '------------'
t=i2
cnt=0
x=0
while t!=0:
x=(t%10)*i1
if cnt==0 and x!=0:
print x
elif x!=0:
print x*(cnt*10)
t=t/10
cnt+=1
print '------------'
print i1*i2
```
6. A Clojure solution:

```(defn digits [n]
(loop [k n acc ()]
(if (zero? k)
acc
(recur (quot k 10) (conj acc (rem k 10))))))

(defn partials [a b]
(map #(* % a) (digits b)))

(defn repeated [n x]
(apply str (repeat n x)))

(str (repeated (- len (count (digits n))) pad) n))

(defn print-multiplication [a b]
(let [r (* a b) rlen (count (digits r)) ps (reverse (partials a b))]
(println  (rpad rlen " " a) "x")
(println  (rpad rlen " " b))
(when (not (= 1 (count (filter #(not (zero? %)) ps))))
(println  (repeated rlen "-"))
(loop [p ps i 0 suffix ""]
(when (seq p)
(when (not (zero? (first p)))
(println (str (rpad (- rlen i) " " (first p)) suffix)))
(recur
(rest p)
(inc i)
(if (zero? (first p)) (str suffix "0") "")))))
(println (repeated rlen "-"))
(println r)))

(defn problem-a [filename]
(let [stream (java.util.Scanner. (java.io.File. filename))]
(while (.hasNextInt stream)
(let [a (.nextInt stream) b (.nextInt stream)]
(when (and (> a 0) (> b 0))
(print-multiplication a b))))))
```