6 # 四則演算を行う式のジェネレータの基底クラス
8 class Arithmetic < Base
11 DEFAULT_OPERATORS = %w[+ - * div]
17 option :term_number, 2
18 option :operators, DEFAULT_OPERATORS
25 # 後処理 (継承した時は super を呼ぶこと)
28 String(problem).gsub(%r! (-[0-9./]+)!, ' (\\1)')
33 # 各ジェネレータでオーバライドする必要あり
36 raise 'need to overwrite'
42 def last_operand(operand = nil)
43 @last_operand = operand if operand
50 def last_operator(operator = nil)
51 @last_operator = operator if operator
60 options[:term_number].times do
61 result << last_operand(operand)
62 result << last_operator(options[:operators].sample)
64 # except last operator
65 result[0..-2].join(" ")
72 create_integer(options[:min], options[:max], options[:minus]).to_s
79 use_integer = rand(3) == 0
82 integer_part = create_integer(options[:min].to_i, options[:max].to_i, false)
84 decimal_part = rand(10**options[:digits])
85 ("#{integer_part}.#{decimal_part}".to_f * sign(options[:minus])).to_s
93 numerator = numerator_part
94 denominator = denominator_part
95 end while numerator == denominator
96 "#{numerator}/#{denominator}"
100 create_integer(options[:numerator_min], options[:numerator_max], options[:minus])
104 create_integer(options[:denominator_min], options[:denominator_max], false)
108 # 最大値、最小値から項数をランダムに生成するメソッド
110 def term_number(position)
111 min, max = options.values_at(:"#{position}_term_min", :"#{position}_term_max")
112 create_integer(min, max, false)