10 # 生成する式の項数を1以上の整数で指定します。
13 # +, - の2種類から使用したいものを配列で指定します。
15 # 生成する式の各項の最小値を0以上の整数で指定します。
17 # 生成する式の各項の最大値を0以上の整数で指定します。
18 # _min_ よりも小さい値を指定することは出来ません。
20 # すべてが数字だった場合は強制的に1つ根号を追加します。
21 # そのときの根号内の数字の最大値を2以上の整数で指定します。
22 # なお、最小値は自動的に2に設定されます。
24 # 生成する式の項数の最小値を1以上の整数で指定します。
26 # 生成する式の項数の最大値を1以上の整数で指定します。
27 # _single_term_min_ より小さい値は指定出来ません。
29 # 真を指定すると根号を含む項の係数を生成します。
33 class SquareRootArithmetic < Arithmetic
35 # root_pattern = /[2-9]?sqrt\((?:[2-9]|\d\d)\)/
36 # term_pattern = /#{root_pattern} [+\-] #{root_pattern}/
37 # validation /\A\(#{root_pattern}\)\^2\z/
38 # validation /\A#{term_pattern}\z/
39 # validation /\A\(#{term_pattern}\)(?:\^2)? [+\-] \(#{term_pattern}(?:\^2)?\)\z/
40 # validation /\A\(#{term_pattern}\) [\*\/] \(#{term_pattern}\)\z/
41 # validation /\A#{root_pattern} \* #{root_pattern}\z/
47 option :upper_limit, 20
48 option :operators, %w[ * ]
49 option :use_power, false
50 option :use_coefficient, false
51 option :single_term_min, 2
52 option :single_term_max, 2
55 results = square_root_expression_parts
56 result = results[0..-2].join(' ')
57 result = "(#{result})" if results.size > 2
58 result = "#{result}^2" if options[:use_power] && rand(2) == 0
62 def swap_options_with(temp)
63 temp_options = options.dup
64 self.options = temp_options.merge(temp)
66 self.options = temp_options
69 def have_common_prime_divisor?(numbers)
70 return true unless numbers.size == 2
71 return true if numbers.include?(0)
72 return true if numbers.any? {|n| n < 10 }
73 prime_divisors = numbers.map {|num| num.factorize }
74 prime_divisors[0].each do |hoge|
75 prime_divisors[1].each do |piyo|
77 return true unless commons.empty? || commons.first == 1
83 def square_root_expression_parts
84 term_number = term_number(:single)
86 if options[:use_power]
88 numbers = Array.new(term_number) { create_integer(options[:min], options[:max], false) }
89 end until numbers.size == 1 || have_common_prime_divisor?(numbers)
90 results = numbers.map {|number| create_square_root_number(number) }
92 results = Array.new(term_number) { create_square_root_number }
95 if results.all? {|r| /sqrt/ !~ r }
96 results.delete_at rand(results.length)
97 swap_options_with(:min => 2, :max => options[:upper_limit]) do
98 results << create_square_root_number
101 operators = term_number.times.map { %w[ + - ].sample }
102 results.zip(operators).flatten
105 def create_square_root_number(number = nil)
107 number = create_integer(options[:min], options[:max], false)
109 "#{coefficient(number)}#{root(number)}"
113 zero_or_one?(number) ? '' : "sqrt(#{number})"
116 def coefficient(number)
117 if options[:use_coefficient] || zero_or_one?(number)
118 return create_integer(2, 9, false)
123 def zero_or_one?(number)
124 number == 0 || number == 1