```On Sun, 19 Oct 2008 10:07:34 -0500, Sebastian Hungerecker wrote:

> Matthew Moss wrote:
>> ## Long Division (#180)
>>
>> Your task this week is to perform and display long division.
>
> This isn't thoroughly tested but it seems to work. It supports
> specifying a base and it can display the result either as
> integer+remainder or as a decimal. There's no option to limit the digits
> as I didn't see the point. If the number is periodic, it draws a
> vinculum above the apropriate digits. Usage: long_divide dividend
> divisor [--base=BASE] [--remainder] BASE is the base as a decimal number
> (both dividend and divisor are specified as BASE)
> If --remainder is specified, it will print the integer part of the
> division and the remainder, instead of printing the result as a decimal.
> If the division has no remainder, there is no difference.
>
> The code can be used from irb (or another script, if you should want to
> do that for some reason), by requireing it and then using the divide
> method. Here's the code:
> http://pastie.org/295741
>
> Some sample output from irb:
>>> divide(1,3)
>     _
>   0.3
>  +-
> 3|1
>   0
>   -
>   10
>    9
>   --
>    1
> => nil
>>> divide(1,3,2)
>      __
>    0.01
>   +-
> 11|1
>    0
>    -
>    10
>     0
>    --
>    100
>     11
>    ---
>      1
> => nil
>>> divide(10,7)
>      ______
>    1.428571
>  +--
> 7|10
>    7
>   --
>    30
>    28
>    --
>     20
>     14
>     --
>      60
>      56
>      --
>       40
>       35
>       --
>        50
>        49
>        --
>         10
>          7
>         --
>          3
> => nil
>>> divide(1,6)
>      _
>   0.16
>  +-
> 6|1
>   0
>   -
>   10
>    6
>   --
>    40
>    36
>    --
>     4
>>> divide(1,6,10,false)
>   0 R1
>  +-
> 6|1
>   0
>   -
>   1
> => nil

I'm posting Sebastian's solution to the newsgroup, because I don't know
long pastie will keep the code around. Please don't use pastebins with
ruby-talk -- the code may disappear while the message sticks around, then
we can't see your ingenious solutions or your questions.

#!/usr/bin/ruby

module LongDivision
module_function
def divide(dividend, divisor, base=10, decimal=true)
result = ""
division = " "*divisor.to_s(base).length
division << "+".ljust(dividend.to_s(base).length + 1,"-") << "\n"
division << "#{divisor.to_s(base)}|#{dividend.to_s(base)}"
indent = divisor.to_s(base).length + 1
digits = dividend.to_s(base).chars.map {|d| d.to_i(base) }
quotient = 0
remainder = 0
while remainder < divisor && digits.size > 0
remainder = remainder * base + digits.shift
indent += 1
end

digits << nil
digits.each do |digit|
quotient = remainder / divisor
result << quotient.to_s(base)
prod = (quotient * divisor).to_s(base)
division << "\n" << prod.rjust(indent) << "\n"
division << ("-" * remainder.to_s(base).length).rjust(indent) << "\n"
remainder %= divisor
remstring = ""
if digit
remstring = "0" if remainder == 0
remainder = remainder * base + digit
indent += 1
end
remstring << remainder.to_s(base)
division << remstring.rjust(indent)
end

if remainder == 0
puts result.rjust(division.lines.first.length-1), division
elsif decimal
rem_positions = {}
dec_result = ""
periodicity = 0
while remainder > 0
if rem_positions[remainder]
periodicity = rem_positions.size - rem_positions[remainder]
break
end
rem_positions[remainder] = rem_positions.size
division << "0\n"
indent += 1
remainder *= base
quotient = remainder / divisor
dec_result << quotient.to_s(base)
prod = (quotient * divisor).to_s(base)
division <<  prod.rjust(indent) << "\n"
division << ("-" * remainder.to_s(base).length).rjust(indent) << "\n"
remainder %= divisor
division << remainder.to_s(base).rjust(indent)
end
result = "#{result.rjust(division.lines.first.length-1)}.#{dec_result}"
if periodicity > 0
puts ("_"*periodicity).rjust(result.size)
end
puts result, division
else
puts "#{result.rjust(division.lines.first.length-1)} R#{remainder.to_s(base)}", division
end
end
end

if \$0 == __FILE__
base = ARGV.find {|arg| arg =~ /^--base/}
if base
base = base.split("=",2).last.to_i(10)
else
base = 10
end

dividend = ARGV.shift.to_i(base)
divisor = ARGV.shift.to_i(base)
decimal = !ARGV.include?("--remainder")
LongDivision.divide(dividend, divisor, base, decimal)
end

--
Chanoch (Ken) Bloom. PhD candidate. Linguistic Cognition Laboratory.
Department of Computer Science. Illinois Institute of Technology.
http://www.iit.edu/~kbloom1/

```