二次式 αx^2+βx+γ を (ax+b)(cx+d) の形に因数分解せよと
func = function(a, b, c) {
##
factorize = function(n) {
div = function(n) {
if (n%%2 == 0) return(2)
else if (n%%3 == 0) return(3)
maxitr = floor(sqrt(n))
i = 1
repeat {
i = i + 4
if (i > maxitr) return(n)
else if (n%%i == 0) return(i)
i = i + 2
if (i > maxitr) return(n)
else if (n%%i == 0) return(i)
}
}
result = NULL
repeat {
d = div(n)
result = append(result, d)
n = n/d
if (n == 1) break
}
return(result)
}
##
is.int = function(x) {
result = all.equal(x, floor(x))
return(ifelse(class(result) == "character", FALSE, TRUE))
}
##
if (0 > a) {
a = -a; b = -b; c = -c
}
if (a == 0) return("Error")
d = b^2-4*a*c
if (0 > d) return("Error")
if (b >= 0) {
x1 = (-b - sqrt(d)) / 2 / a
} else {
x1 = (-b + sqrt(d)) / 2 / a
}
x2 = (c / a) / x1
##
result = factorize(a)
n = length(result)
ans = ""
for (i in 1:2^n) {
factor = prod(result[as.integer(intToBits(i-1))[1:n] == 1])
if (is.int(factor * x1) && is.int((a / factor) * x2)) {
ans = c(factor, -factor * x1, a / factor, -(a / factor) * x2)
break
}
}
return(ans)
}
> func(4, -23, 15) # 1, -5, 4, -3
[1] 1 -5 4 -3
> func(-4, 23, -15) # 1, -5, 4, -3
[1] 1 -5 4 -3
> func(3, 10, 3) # 1, 3, 3, 1
[1] 1 3 3 1
> func(6, -1, -15) # 3, -5, 2, 3
[1] 3 -5 2 3
> func(12, -1, -6) # 4, -3, 3, 2
[1] 4 -3 3 2
> func(3, -8, 4) # 1, -2, 3, -2
[1] 1 -2 3 -2
> func(3, 5, 7) # Error 実数解はない
[1] "Error"
> func(268231, -374150, 128851) # 347, -269, 773, 479
[1] 347 -269 773 -479
> func(1, 1.0000000000000001, 0.0000000000000001) # "" 適切な解はない
[1] ""