OSDN Git Service

use expression instead of do_generae in generator
[mint/mint-lib.git] / lib / mint / generator / fractional_expression_arithmetic.rb
1 # -*- coding: utf-8 -*-
2
3 module Mint::Generator
4
5   #
6   # 分数式の問題を生成するジェネレータ
7   #
8   # オプション ::
9   #               以下のオプションが使用出来る
10   #               [_term_number_] 生成する項の数 (ex. 2)
11   #               [_operators_] 使用する演算子 (ex. %w[ + - * div ]
12   #               [numerator_term_min] 分子の項数の最小値 (ex. 1)
13   #               [numerator_term_max] 分子の項数の最大値 (ex. 1)
14   #               [denominator_term_min] 分母の項数の最大値 (ex. 1)
15   #               [denominator_term_max] 分母の項数の最大値 (ex. 1)
16   #               [factor_minus] 真なら整数部に負の数を使う (ex. false)
17   #               [factor_min] 整数部の最小値 (ex. 1)
18   #               [factor_max] 整数部の最大値 (ex. 9)
19   #
20   class FractionalExpressionArithmetic < Arithmetic
21
22     DEFAULT_OPERATORS = %w[+ - * div]
23
24     private
25
26     include Utilities
27
28     # TODO: I wanna set option for expression order
29     option :x,                    ['x']
30     option :numerator_term_min,   1
31     option :numerator_term_max,   1
32     option :denominator_term_min, 1
33     option :denominator_term_max, 1
34     option :factor_minus,         false
35     option :factor_min,           1
36     option :factor_max,           9
37
38     def generate_problem
39       expression
40     end
41
42     def operand
43       @x ||= options[:x].sample
44       fraction(@x)
45     end
46
47     def fraction(x)
48       result = ''
49       result << '(' if options[:denominator_term_max] > 1
50       result << denominator_part(x)
51       result << ')' if options[:denominator_term_max] > 1
52       result << '/'
53       result << '(' if options[:numerator_term_max] > 1
54       result << "#{numerator_part(x)}"
55       result << ')' if options[:numerator_term_max] > 1
56       result
57     end
58
59     def numerator_part(x)
60       term(:numerator, x)
61     end
62
63     def denominator_part(x)
64       term(:denominator, x)
65     end
66
67     def term(position, x)
68       result = []
69       term_number = term_number(position)
70       if term_number == 0
71         return create_integer(
72           options[:factor_min],
73           options[:factor_max],
74           options[:factor_minus]).to_s
75       end
76       term_number.times {
77         factor = factor(options, 'factor')
78         result << single(1, factor, x)
79       }
80       result.join
81     end
82
83     def term_number(position)
84       create_integer(
85         options[:"#{position}_term_min"],
86         options[:"#{position}_term_max"],
87         false)
88     end
89   end
90 end
91