#
# 分数式の問題を生成するジェネレータ
#
- # オプション ::
- # 以下のオプションが使用出来る
- # [_term_number_] 生成する項の数 (ex. 2)
- # [_operators_] 使用する演算子 (ex. %w[ + - * div ]
- # [numerator_term_number_min] 分子の項数の最小値 (ex. 1)
- # [numerator_term_number_max] 分子の項数の最大値 (ex. 1)
- # [denominator_term_number_min] 分母の項数の最大値 (ex. 1)
- # [denominator_term_number_max] 分母の項数の最大値 (ex. 1)
- # [factor_minus] 整数部にマイナスを使うか (ex. false)
- # [factor_min] 整数部の最小値 (ex. 1)
- # [factor_max] 整数部の最大値 (ex. 9)
+ # == オプション
+ # [_term_number_]
+ # 生成する式の項数を1以上の整数で指定します。
+ # [_operators_]
+ # 使用可能な演算子を指定します。
+ # +, -, *, div の4種類から使用したいものを配列で指定します。
+ # [__numerator_term_min_]
+ # 生成する分子の項数の最小値を1以上の整数で指定します。
+ # [_numerator_term_max_]
+ # 生成する分子の項数の最大値を1以上の整数で指定します。
+ # _numerator_term_min_ より小さい値を指定することは出来ません。
+ # [_denominator_term_min_]
+ # 生成する分母の項数の最小値を1以上の整数で指定します。
+ # [_denominator_term_max_]
+ # 生成する分母の項数の最大値を1以上の整数で指定します。
+ # _denominator_term_min_ より小さい値を指定することは出来ません。
+ # [_factor_min_]
+ # 生成する式の各項の最小値を0以上の整数で指定します。
+ # [_factor_max_]
+ # 生成する式の各項の最大値を0以上の整数で指定します。
+ # _factor_min_ よりも小さい値を指定することは出来ません。
+ # [_factor_minus_]
+ # 真を指定すると、負の値も生成します。
#
class FractionalExpressionArithmetic < Arithmetic
include Utilities
- def generate_problem
- # TODO: I wanna set option for expression order
- defaults = {
- :x => ['x'],
- :numerator_term_number_min => 1, :numerator_term_number_max => 1,
- :denominator_term_number_min => 1, :denominator_term_number_max => 1,
- :factor_minus => false, :factor_min => 1, :factor_max => 9,
- }
- do_generate(defaults)
+ # TODO: I wanna set option for expression order
+ option :x, ['x']
+ option :numerator_term_min, 1
+ option :numerator_term_max, 1
+ option :denominator_term_min, 1
+ option :denominator_term_max, 1
+ option :factor_min, 1
+ option :factor_max, 9
+ option :factor_minus, false
+
+ def setup
+ @x = options[:x].sample
end
def operand
- @x ||= options[:x].sample
- fraction(@x)
+ fraction
end
- def fraction(x)
- result = ''
- result << '(' if options[:denominator_term_number_max] > 1
- result << denominator_part(x)
- result << ')' if options[:denominator_term_number_max] > 1
- result << '/'
- result << '(' if options[:numerator_term_number_max] > 1
- result << "#{numerator_part(x)}"
- result << ')' if options[:numerator_term_number_max] > 1
- result
- end
+ def fraction
+ parenthesis = lambda do |value, flag|
+ result = ''
+ result << '(' if flag
+ result << value
+ result << ')' if flag
+ result
+ end
+ np_flag = options[:numerator_term_max] > 1
+ dp_flag = options[:denominator_term_max] > 1
- def numerator_part(x)
- term(:numerator, x)
+ result = []
+ result << parenthesis[numerator_part, np_flag]
+ result << parenthesis[denominator_part, dp_flag]
+ result.join('/')
end
- def denominator_part(x)
- term(:denominator, x)
+ def numerator_part
+ term(:numerator)
end
- def term(position, x)
- result = []
- term_number = term_number(position)
- if term_number == 0
- return create_integer(
- options[:factor_min],
- options[:factor_max],
- options[:factor_minus]).to_s
- end
- term_number.times {
- factor = factor(options, 'factor')
- result << single(1, factor, x)
- }
- result.join
+ def denominator_part
+ term(:denominator)
end
- def term_number(position)
- create_integer(
- options[:"#{position}_term_number_min"],
- options[:"#{position}_term_number_max"],
- false)
+ def term(position)
+ term_number = term_number(position)
+ return factor(options).to_s if term_number == 0
+ term_number.times.map { single(1, factor(options), @x) }.join
end
end
end