Sha256: 9f234b3cf4f6dcd712b0dbc03f8e60fd5a2f99d6793d104f85acb96d2e5f2710

Contents?: true

Size: 1.95 KB

Versions: 1

Compression:

Stored size: 1.95 KB

Contents

# frozen_string_literal: true

module GermanNumbers
  class Stringifier
    SMALL_KEYWORDS = %w(hundert tausend).freeze
    BIG_KEYWORDS = %w(Million Milliarde).freeze

    def words(number)
      raise ArgumentError if number > 999_999_999_999 || number.negative?
      return postprocess(DIGITS[number]) unless DIGITS[number].nil?

      number = number.to_s.rjust(12, '0')

      billions, millions, thousands, number = number.to_s.reverse.scan(/.{1,3}/).map do |part|
        part.reverse.to_i
      end.reverse

      postprocess(process(billions, millions, thousands, number))
    end

    private

    def process(billions, millions, thousands, number)
      result = under_thousand(number)
      result = "#{under_thousand(thousands)}#{DIGITS[1000]}#{result}" unless thousands.zero?
      unless millions.zero?
        n = under_thousand(millions)
        result = "#{n == 'ein' ? 'eine' : n} #{decline(millions, DIGITS[1_000_000])} #{result}"
      end
      unless billions.zero?
        n = under_thousand(billions)
        result = "#{n == 'ein' ? 'eine' : n} #{decline(billions, DIGITS[1_000_000_000])} #{result}"
      end
      result
    end

    def postprocess(result)
      result += 's' if result.end_with?('ein')
      result = 'ein' + result if SMALL_KEYWORDS.include?(result)
      result = 'eine ' + result if BIG_KEYWORDS.include?(result)
      result.strip
    end

    def under_thousand(number)
      digits = number.to_s.split('').reverse.map(&:to_i)
      result = under_hundred(digits.first(2))
      result = DIGITS[digits.last] + DIGITS[100] + result if digits.count > 2
      result
    end

    def under_hundred(digits)
      return '' if digits.all?(&:zero?)
      n = DIGITS["#{digits[1]}#{digits[0]}".to_i]
      return n unless n.nil?
      DIGITS[digits[0]] + 'und' + DIGITS[(digits[1] * 10)]
    end

    def decline(count, number)
      return number if count == 1
      return number + 'n' if number.end_with?('e')
      number + 'en'
    end
  end
end

Version data entries

1 entries across 1 versions & 1 rubygems

Version Path
german_numbers-0.5 lib/german_numbers/stringifier.rb