1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
|
import java.lang.Math.floor
import java.lang.Math.max
import javax.script.ScriptEngine
import javax.script.ScriptEngineManager
data class Expression(val expression: String)
fun main(args:Array<String>) {
while (true) {
println("---------------------------")
println("Separate numbers by comma.")
print("Enter numbers: ")
val inputNumbers = readLine()!!.split(",").map { it.trim().toDouble() }
val formula = findFormula(inputNumbers)
println("Formula: $formula")
println("Pattern: " + continuePattern(formula))
}
}
private fun findFormula(numbers: List<Double>): String {
// Find difference between numbers
val differences = listOf(
numbers[1] - numbers[0],
numbers[2] - numbers[1]
)
var incrementsByDifference = true
var increment = 0.0
if (differences[0] != differences[1]) // If the pattern doesn't increment by difference
incrementsByDifference = false
else
increment = differences[0]
// Start-value
val nAsExponent = nAsExponent(differences)
val startValueDifference = when {
incrementsByDifference -> differences[0] // xn
nAsExponent -> getBase(differences) // x^n
else -> 1.0 // n^x
}
val startValue = numbers[0] - startValueDifference
// Exponents
var base = "n"
var exponent = ""
if (nAsExponent(differences)) {
base = getBase(differences).cleanRedundancy() + "^"
exponent = "n"
} else if (!incrementsByDifference) {
base = "n^"
exponent = getExponent(numbers[1], startValue).cleanRedundancy()
}
// Add the pieces together
var formula = increment.cleanRedundancy()
formula += base + exponent + startValue.cleanRedundancy().addSign()
return formula
}
private fun continuePattern(formula: String): String {
var output = ""
for (i in 1..20) {
val expression = Expression(formula.replace("n", i.toString()))
output += expression.calculate().cleanRedundancy() + ", "
}
return output.cleanRedundancy()
}
fun Double.cleanRedundancy(): String {
return when {
this == 0.0 -> return ""
floor(this) == this -> this.toInt().toString()
else -> return this.toString()
}
}
fun String.cleanRedundancy(): String {
return if (this.endsWith(", "))
this.substring(0, this.length - 3)
else
this
}
fun String.addSign(): String {
return if (!this.startsWith("-"))
"+" + this
else
this
}
fun Expression.calculate(): Double {
val addSubSign = max(expression.indexOf("+"), expression.indexOf("-"))
val addSub = expression.substring(addSubSign + 1, expression.length).toDouble()
val numbers = expression.substring(0, addSubSign)
.split(Regex("[*^]")).map { it.toDouble() }
if (expression.contains("*"))
return numbers[0] * numbers[1] + addSub
else if (expression.contains("^"))
return Math.pow(numbers[0], numbers[1]) + addSub
return 0.0
}
private fun getBase(differences: List<Double>): Double {
return differences[1] / differences[0]
}
private fun getExponent(secondNumber: Double, startValue: Double): Double {
return Math.log(secondNumber - startValue) / Math.log(2.0)
}
private fun nAsExponent(differences: List<Double>): Boolean {
val base = getBase(differences)
return base == differences[0] / (differences[0] / base)
}
|