要零还是无限?科特林
在Codewars,这是惊人的Kata。 我是从双人开始的,但是在阶乘30之后!应该使用bigdecimal。在200!我改进了代码,并在时间
执行时遇到问题(16000 ms)
请帮助我改善代码以计算超过200个!快速。
我的代码(用于200个!)SIPL测试可以通过,但是在随机测试中有200多个测试!我有时间有问题。在我的想法IDE中可以计算没有问题,但是服务器代码战争无法计算。
fun going(n: Int): Double {
val factorial = factorial(n)
val zeroField = zero(factorial)
val infiniteField = infinite(n)
val beforeRound = zeroField.multiply(infiniteField)
return beforeRound.setScale(6, RoundingMode.DOWN).toDouble()
}
fun factorial(n: Int): BigDecimal{
if (n<=1) return BigDecimal.ONE
return BigDecimal(n).multiply(factorial(n-1))
}
fun infinite(n: Int): BigDecimal {
var sumFact = BigDecimal(0)
var factCounter = 1
repeat(n){
sumFact += factorial(factCounter)
factCounter++
}
return sumFact
}
fun zero(factorial: BigDecimal): BigDecimal{
return BigDecimal.ONE.divide(factorial, MathContext.DECIMAL128)
}
在提示K314159提示之后,我尝试使用hashmap兑现我的阶乘结果。它一直在工作直到N&lt; 1000。N&GT; 〜5800 - &gt;线程“ main” java.lang.stackoverflowerror中的例外,
我需要计算出非常大的数字,例如fortorial 10_000!
我的hashmap的代码
val myFactorialHash = mutableMapOf<Int, BigDecimal>(1 to BigDecimal.ONE)
fun going(n: Int): Double {
println(n)
val factorial = factorial(n)
val zeroField = zero(factorial)
val infiniteField = infinite(n)
val beforeRound = zeroField.multiply(infiniteField)
return beforeRound.setScale(6, RoundingMode.DOWN).toDouble()
}
fun factorial(n: Int): BigDecimal{
if (n<=1){
return myFactorialHash[1]!!
}
if (myFactorialHash.containsKey(n)){
return myFactorialHash[n]!!
} else {
myFactorialHash[n] = BigDecimal(n).multiply(factorial(n-1))
}
return myFactorialHash[n]!!
}
fun infinite(n: Int): BigDecimal {
var sumFact = BigDecimal(0)
var factCounter = 1
repeat(n){
sumFact += factorial(factCounter)
factCounter++
}
return sumFact
}
fun zero(factorial: BigDecimal): BigDecimal{
return BigDecimal.ONE.divide(factorial, MathContext.DECIMAL128)
}
在实验中有点涉及递归的tailRec,
之间没有区别
tailRec或没有tailrec n == 7027 - &gt 。一切都很好 n == 7028-&gt; stackoverflow异常
我的实验代码在下面
fun main(){
println(factorial(7027))
}
tailrec fun factorial(n: Int): BigDecimal{
if (n<1) return BigDecimal.ONE
return BigDecimal(n).multiply(factorial(n-1))
}
,5小时后... 在最大堆栈容量上初始化我的哈希,
val myFactorialHash = mutableMapOf<Int, BigDecimal>(1 to BigDecimal.ONE)
fun going(n: Int): Double {
initHash()
val factorial = factorial(n)
val zeroField = zero(factorial)
val infiniteField = infinite(n)
val beforeRound = zeroField.multiply(infiniteField)
return beforeRound.setScale(6, RoundingMode.DOWN).toDouble()
}
fun factorial(n: Int): BigDecimal{
if (n<=1){
return myFactorialHash[1]!!
}
var counter = n
if (myFactorialHash.containsKey(n)){
return myFactorialHash[n]!!
} else {
myFactorialHash[n] = BigDecimal(n).multiply(factorial(n-1))
}
return myFactorialHash[n]!!
}
fun infinite(n: Int): BigDecimal {
var sumFact = BigDecimal(0)
var factCounter = 1
repeat(n){
sumFact += factorial(factCounter)
factCounter++
}
return sumFact
}
fun zero(factorial: BigDecimal): BigDecimal{
return BigDecimal.ONE.divide(factorial, MathContext.DECIMAL128)
}
fun initHash(){
repeat(7000){
myFactorialHash[it] = factorial(it)
}
}
谢谢K314159。我使用BigDecimal的哈希通过了这一点。 当我找到在解决方案中解决此KATA的简便方法时,我的头会利用)))))))
我不明白它是如何工作的,但它是1行代码
fun going(n: Int): Double = if (n == 0) 0.0 else 1 + going(n - 1) / n
It is amazing kata at CodeWars.
I started from Double, but after factorial 30! should use BigDecimal. On 200! I improved my code and had a problem with time
Execution Timed Out (16000 ms)
Zero or Infinity description Image
Please help me to improve my code to calculate more than 200! in quick time.
My code (working to 200! ) Siple tests passed ok, but in random tests with more than 200! I have problem with time. No problem to calculate in my Idea IDE, but server Code Wars can't calculate.
fun going(n: Int): Double {
val factorial = factorial(n)
val zeroField = zero(factorial)
val infiniteField = infinite(n)
val beforeRound = zeroField.multiply(infiniteField)
return beforeRound.setScale(6, RoundingMode.DOWN).toDouble()
}
fun factorial(n: Int): BigDecimal{
if (n<=1) return BigDecimal.ONE
return BigDecimal(n).multiply(factorial(n-1))
}
fun infinite(n: Int): BigDecimal {
var sumFact = BigDecimal(0)
var factCounter = 1
repeat(n){
sumFact += factorial(factCounter)
factCounter++
}
return sumFact
}
fun zero(factorial: BigDecimal): BigDecimal{
return BigDecimal.ONE.divide(factorial, MathContext.DECIMAL128)
}
After hint k314159 i try to use hashMap to cash my factorial results. It is working till n< 1000. When n> ~5800 -> Exception in thread "main" java.lang.StackOverflowError
I need to calculate really big numbers, like factorial 10_000 !
My code with hashMap
val myFactorialHash = mutableMapOf<Int, BigDecimal>(1 to BigDecimal.ONE)
fun going(n: Int): Double {
println(n)
val factorial = factorial(n)
val zeroField = zero(factorial)
val infiniteField = infinite(n)
val beforeRound = zeroField.multiply(infiniteField)
return beforeRound.setScale(6, RoundingMode.DOWN).toDouble()
}
fun factorial(n: Int): BigDecimal{
if (n<=1){
return myFactorialHash[1]!!
}
if (myFactorialHash.containsKey(n)){
return myFactorialHash[n]!!
} else {
myFactorialHash[n] = BigDecimal(n).multiply(factorial(n-1))
}
return myFactorialHash[n]!!
}
fun infinite(n: Int): BigDecimal {
var sumFact = BigDecimal(0)
var factCounter = 1
repeat(n){
sumFact += factorial(factCounter)
factCounter++
}
return sumFact
}
fun zero(factorial: BigDecimal): BigDecimal{
return BigDecimal.ONE.divide(factorial, MathContext.DECIMAL128)
}
a little bit about tailrec for recursion
In practical experiment there is no difference between tailrec or without tailrec
n == 7027 -> everything ok
n == 7028 -> StackOverFlow exception
my experimental code below
fun main(){
println(factorial(7027))
}
tailrec fun factorial(n: Int): BigDecimal{
if (n<1) return BigDecimal.ONE
return BigDecimal(n).multiply(factorial(n-1))
}
Ok, 5 hours later ...
Initialize my hash on max stack capacity
val myFactorialHash = mutableMapOf<Int, BigDecimal>(1 to BigDecimal.ONE)
fun going(n: Int): Double {
initHash()
val factorial = factorial(n)
val zeroField = zero(factorial)
val infiniteField = infinite(n)
val beforeRound = zeroField.multiply(infiniteField)
return beforeRound.setScale(6, RoundingMode.DOWN).toDouble()
}
fun factorial(n: Int): BigDecimal{
if (n<=1){
return myFactorialHash[1]!!
}
var counter = n
if (myFactorialHash.containsKey(n)){
return myFactorialHash[n]!!
} else {
myFactorialHash[n] = BigDecimal(n).multiply(factorial(n-1))
}
return myFactorialHash[n]!!
}
fun infinite(n: Int): BigDecimal {
var sumFact = BigDecimal(0)
var factCounter = 1
repeat(n){
sumFact += factorial(factCounter)
factCounter++
}
return sumFact
}
fun zero(factorial: BigDecimal): BigDecimal{
return BigDecimal.ONE.divide(factorial, MathContext.DECIMAL128)
}
fun initHash(){
repeat(7000){
myFactorialHash[it] = factorial(it)
}
}
Thank you k314159. I passed this using hash of BigDecimal.
When I found easy way to solve this kata in solutions, my head exploit ))))
I don't understand how it's work, but it is 1 line of code
fun going(n: Int): Double = if (n == 0) 0.0 else 1 + going(n - 1) / n
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
让我们简化表达式
(1/n!) *(1! + 2! + 3! + ... + N!)= 1!/n! + 2!/n! + ... + n!/n!
现在让我们为
n = k-1
和n = k
:1!/(K-1)! + 2!/(K-1)! + ... +(k-1)!/(k-1)!
1!/k! + 2!/k! + ... +(k-1)!/k! + k!/k!
您可以注意到第二个表达式是更长的一个总结,并且此汇总等于
1
。由于k!! =(k-1)! * k
。因此,如果我们现在的答案n = k-1
我们需要做的一切来计算n = k
的答案,就是通过k 并添加
1
。我们可以简单地循环做到这一点:Let's simplify the expression
(1/n!) * (1! + 2! + 3! + ... + n!) = 1!/n! + 2!/n! + ... + n!/n!
Now let's write this expression for
n = k-1
and forn = k
:1!/(k-1)! + 2!/(k-1)! + ... + (k-1)!/(k-1)!
1!/k! + 2!/k! + ... + (k-1)!/k! + k!/k!
You can notice that second expression is one summand longer, and this summand is equal to
1
. All other summands becomek
times smaller becausek! = (k-1)! * k
. Thus, if we now the answer forn = k-1
all we need to do to calculate the answer forn = k
is to divide byk
and add1
. And we can simply do it in a loop: