Sha256: 4b4b5685773e4da1d0051d73e6ae370950dcd469bfa47b3f1ba6a58b292d2334

Contents?: true

Size: 1.48 KB

Versions: 1

Compression:

Stored size: 1.48 KB

Contents

require "rypto"

module Rypto
  # Solution returned by {Rypto::Hand#solve}
  class Solution
    # @private
    def initialize(target)
      @target    = target
      @solutions = []
    end

    # Array of all solutions in postfix notation.
    # @return [Array<String>]
    def postfix
      @solutions.map do |solution|
        '%s = %d' % [solution.join(" "), @target]
      end
    end

    # Array of all solutions in infix notation.
    # @return [Array<String>]
    def infix
      @solutions.map do |solution|
        stack = []

        solution.each do |s|
          if s.is_a? Fixnum
            stack.push s
          else
            b = stack.pop
            a = stack.pop
            stack.push left: a, op: s, right: b
          end
        end

        '%s = %d' % [expr_tree_to_infix(stack.pop), @target]
      end
    end

    # Add solution to list of possible solutions
    # @private 
    def push(solution)
      @solutions << solution
    end

    private

    def expr_tree_to_infix(node, parent_node = nil)
      return node.to_s if node.is_a? Fixnum
      use_parens = parent_node && op_precedence(parent_node[:op]) > op_precedence(node[:op])
      '%s%s %s %s%s' % [
        use_parens ? '(' : nil,
        expr_tree_to_infix(node[:left], node),
        node[:op],
        expr_tree_to_infix(node[:right], node),
        use_parens ? ')' : nil
      ]
    end

    def op_precedence(op)
      case op
        when '/', '*' then 2
        else
          1
      end
    end
  end
end

Version data entries

1 entries across 1 versions & 1 rubygems

Version Path
rypto-0.1.0 lib/rypto/solution.rb