All about flooble | fun stuff | Get a free chatterbox | Free JavaScript | Avatars    
perplexus dot info

Home > Algorithms
Ternary Multiplication Algorithm (Posted on 2023-03-24) Difficulty: 3 of 5
Provide an algorithm to multiply a series of Base 3 integers, represented as strings, without converting to any other base during any part of the algorithm. Each string (Base 3 integer) may have an arbitrary number of digits.

You may not use arithmetic operations on the digits in a way that is equivalent to changing the base, although you may use a dictionary or table lookup to recognize, for example, that in Base 3, 2*2 = 11.

You can use any programming language, or pseudo-code, or provide a verbal description.

See The Solution Submitted by Larry    
Rating: 5.0000 (1 votes)

Comments: ( Back to comment list | You must be logged in to post comments.)
Some Thoughts Possible solution | Comment 1 of 2
I'm on the fence over whether this approach truly doesn't perform any operation that could be construed as changing the base, but I'll share it anyway because I thought it was an interesting problem. I've used ruby here since that's what was handy, but I think the sense of it is clear enough if that's not one of your languages. 

usage: BaseMultiplier.multiply '102', '201', '11', '221'
example: BaseMultiplier.multiply '212', '1022', '10' = 10022110


Bonus -- see the same multiplication interpreted in another base by overriding the default of '3' [DOES NOT WORK WITH BASES > 10]
example: BaseMultiplier.multply '212', '1022', '10', base: 10 = 2166640

I've made no attempt to handle weirdness in the input like non-digit characters or digits inconsistent with the base like 'foo' or '13' but a robust implementation would certainly include that handling.

class BaseMultiplier
  def self.multiply(*items, base: 3)
    return items[0] if items.count == 1 # one item means nothing to multiple
    return multiply_pair(items[0], items[1], base:) if items.count == 2 # no need for recursion
    elem = items.shift
    multiply_pair(elem, multiply(*items, base:), base:) # multiply the first by the product of the rest
  end

  def self.multiply_pair(a, b, base: 3)
    adig = a.split('').map(&:to_i).reverse # digits, converted to numbers with least significant first
    bdig = b.split('').map(&:to_i).reverse
    buckets = Hash.new(0) # will store digit products grouped by place
    # multiply each pair of digits, and offset the result by the total number of "places"
    adig.each_with_index do |dig1, dig1_index|
      bdig.each_with_index do |dig2, dig2_index|
        bucket = dig1_index + dig2_index
        buckets[bucket] += dig1 * dig2
      end
    end
    # now handle carrying to ensure no digit exceeds the base
    buckets.keys.sort.each do |k| # sort ensures we work from least significant to most
      if (val = buckets[k]) >= base
        buckets[k] = val % base
        buckets[k+1] += (val - (val % base)) / base
      end
    end
    # collect the digits, and reverse since the first is the least significant
    buckets.keys.sort.reverse.map{|k| buckets[k]}.join('')
  end
end

  Posted by Paul on 2023-03-27 14:04:19
Please log in:
Login:
Password:
Remember me:
Sign up! | Forgot password


Search:
Search body:
Forums (0)
Newest Problems
Random Problem
FAQ | About This Site
Site Statistics
New Comments (3)
Unsolved Problems
Top Rated Problems
This month's top
Most Commented On

Chatterbox:
Copyright © 2002 - 2024 by Animus Pactum Consulting. All rights reserved. Privacy Information