OSDN Git Service

fix generation documentation
[mint/mint-lib.git] / lib / mint / generator / fractional_expression_arithmetic.rb
index 39c57f3..eb0a7e4 100644 (file)
@@ -5,17 +5,29 @@ module Mint::Generator
   #
   # 分数式の問題を生成するジェネレータ
   #
-  # オプション ::
-  #               以下のオプションが使用出来る
-  #               [_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
 
@@ -25,63 +37,53 @@ module Mint::Generator
 
     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