-----Original Message-----
From: Matthew Moss [mailto:matt / moss.name] 

## Long Division (#180)

Your task this week is to perform and display long division.
Here's a solution. I checked it with quite a few combinations, seems
like its robust.
A define and use an object called "Slot" which takes a number and puts
each digit
in a "slot".

Comments welcome.


Run this like

$ ruby longdiv.rb 5002101 201

      24886  R 15
   +-------
201|5002101
    402
    ---
     982
     804
     ---
     1781
     1608
     ----
      1730
      1608
      ----
       1221
       1206
       ----
         15

Checked answer ! Correct



=== CODE follows ===
# An abstraction where a number is modeled
# such that each digit sits in a "slot"
# Eg : 345 ==> |3|4|5| (internally stored in an array)
# Makes it easy to left shift
class Slot
	def initialize(num)
		@x = []
		if (num == 0) then
			@x << 0
		else
			while (num > 0)
				@x <<  num % 10
				num = num / 10
			end
			@x.reverse!
		end
	end

	def zero?
		(@x == "0" * @x.length) 
	end

	def show
		@x.each {|f| print f}
		puts
	end

	def length
		return @x.length
	end

	def int
		return 0 if self.zero?
		y = @x.reverse
		val = 0
		(0 .. (y.length - 1)).each {|i| val += y[i]*(10 ** i)}
		return val
	end

	# left shift
	def lshift(p=1)
		return if @x.empty?
		val = 0
		(p-1).downto(0) do |i|
			val += @x.shift * (10 ** (i))
		end
		return Slot.new(val)
	end

	def div(a)
		return Slot.new(0) if self.zero?
		x = self.int
		y = a.int
		return Slot.new(x/y)
	end

	def mod(a)
		return Slot.new(0) if self.zero?
		x = self.int
		y = a.int
		return Slot.new(x % y)
	end

	def concat(p)
		return self if p == nil
		s = p.clone
		s.length.times do |i|
			@x << s.lshift.int
		end
		return self
	end

	def clone
		return Slot.new(self.int)
	end

	def to_s
		@x.to_s
	end
end

def spc(x)
	" " * x.to_i
end

#
# MAIN
# Programmer: Shourya Sarcar
# ruby log_div.rb <dividend> <divisor>
#

# Get the dividend followed by the divisor
b = Slot.new(ARGV.shift.to_i)
a = Slot.new(ARGV.shift.to_i)

# Some initialisation
al = a.length
q = b.clone
steps, anss, rems, ds = [], [], [], [] # Arrays to store numbers at
various stages
init_gaps = 0
first_line = true
rem = q.lshift

# That magic loop of long division
# This is where the calculation is performed
while (q.length > 0) do
	d = rem
	while (d.int < a.int && (q.length > 0)) do 
		d.concat(q.lshift)
		anss << d.div(a).int if (d.int < a.int)
		init_gaps += 1 if (first_line)
	end
	first_line = false
	ans = d.div(a)
	step = Slot.new(a.int * ans.int)
	rem = d.mod(a)
	#puts "Divide " + d.to_s + " by " + a.to_s +  " ==> " + ans.to_s
+ " Step " + step.to_s + " , R " + rem.to_s
	ds << d
	steps << step
	anss << ans.int if (ans.int > 0)
end

# Print the hard-earned results
lm = spc(al + 1) # left margin
while (anss[0] == 0) do anss.shift end # spit leading zeroes if any
ansline = lm + spc(init_gaps) + anss.to_s 
ansline += "  R " + rem.to_s if (rem.int != 0)
puts ansline
puts spc(al) +  "+" + "-" * b.length
mainline = a.to_s + "|" + b.to_s
puts mainline
pre_line = lm
d = ds.shift
steps.each do |s|
	puts pre_line + spc(d.length - s.length)+ s.to_s
	puts pre_line + "-" * d.length
	pre_line += spc(d.length - Slot.new(d.int - s.int).length)
	d = ds.shift
	if (d!=nil) then
		puts pre_line + d.to_s
	else
		puts pre_line + rem.to_s
	end
end


# Check results
puts
if (a.int * anss.to_s.to_i + rem.int == b.int) then
	puts "Checked answer ! Correct"
else
	puts "Problem in calculation :-(. Answer is not correct"
end



=========================hourya Sarcar
http://blog.shouryalive.com