OSDN Git Service

move generate_problem into base class
[mint/mint-lib.git] / lib / mint / generator / square_root_arithmetic.rb
1 # -*- coding: nil -*-
2
3 module Mint::Generator
4
5   #
6   # 無理数の四則演算を生成するジェネレータ
7   #
8   # オプション ::
9   #               以下のオプションが使用出来る
10   #               [_term_number_] 生成する項の数 (ex. 2)
11   #               [_operators_] 使用する演算子 (ex. %w[ + - ])
12   #               [_min_] 各項の最小値 (ex. 0)
13   #               [_max_] 各項の最大値 (ex. 30)
14   #               [_single_term_min_] 各項の最小項数 (ex. 1)
15   #               [_single_term_max_] 各項の最大項数 (ex. 1)
16   #               [_use_coefficient_] 真なら係数をつける (ex. true)
17   #               [_use_power_] 真なら2乗した項を作る (ex. false)
18   #
19   class SquareRootArithmetic < Arithmetic
20
21     root_pattern = /[2-9]?sqrt\((?:[2-9]|\d\d)\)/
22     term_pattern = /#{root_pattern} [+\-] #{root_pattern}/
23     validation /\A\(#{root_pattern}\)\^2\z/
24     validation /\A#{term_pattern}\z/
25     validation /\A\(#{term_pattern}\)(?:\^2)? [+\-] \(#{term_pattern}(?:\^2)?\)\z/
26     validation /\A\(#{term_pattern}\) [\*\/] \(#{term_pattern}\)\z/
27
28     private
29
30     option :min,             0
31     option :max,             30
32     option :operators,       %w[ + - ]
33     option :use_power,       false
34     option :single_term_min, 1
35     option :single_term_max, 2
36
37     def term_number
38       max = options.values_at(:single_term_min, :single_term_max).max
39       amount_seed = (options[:single_term_min]..max).to_a
40       amount = amount_seed.sample
41       amount = 1 if amount <= 0
42       amount
43     end
44
45     def operand
46       results = []
47       term_number.times do
48         results << create_square_root_number
49         results << %w[ + - ].sample
50       end
51       result = results[0..-2].join(' ')
52       result = "(#{result})" if results.size > 2
53       if options[:use_power]
54         power = rand(2)
55         if power == 1
56           result = "#{result}^2"
57         end
58       end
59       result
60     end
61
62     def create_square_root_number
63       number = create_integer(options[:min], options[:max], false)
64       coefficient = ''
65       need_coefficient = options[:use_coefficient] ? rand(2) == 0 : false
66         if need_coefficient || [0, 1].include?(number)
67         min = 2 # MEMO: 2 - 9
68         coefficient = (min + rand(10 - min)).to_s
69       end
70       root = [0, 1].include?(number) ? '' : "sqrt(#{number})"
71       "#{coefficient}#{root}"
72     end
73   end
74 end
75