Report abuse


			
#!/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