2017-08-17 27 views
4

機能的なスタイルにwhileループ変換:Kotlin - 私は、次のKotlin機能を持っている

fun func(n: Int): Int { 

    var count = 1 

    var m = n 
    while(m != 1) { 

     m = if(m.isOdd()) 3 * m + 1 else m/2 

     count++ 
    } 

    return count 
} 

私は(、)(マップのようKotlinの演算子を使用して、「機能的」なスタイルでその単純なアルゴリズムを書くのが好き数えるう

fun func(n: Int): Int { 

    return n.toList() 
      .map{ if(it.isOdd()) 3*it+1 else it/2 } 
      .takeWhile { it != 1 } 
      .count() 

} 

もちろん、マップは一度だけ実行されるため、上記のコードは動作しませんが、あなたは私が達成しようとしているもののアイデアを得る:)、私が思い付くことができ等の最も近いものは、このでした。

PS:ToListメソッド()がINTことを含むリストにint型に変換だけで拡張機能である:あなたはそこになりますどのように多くの項目がわからないので

fun Int.toList() = listOf(this) 
+0

おそらく@hotkeyは正しい答えを提供していましたが、元のコードは実際にはメモリ効率が高く、生成された要素数を調べるために数千の要素を含むシーケンスを作成しません。 – Strelok

+0

@Strelokそれは良い点です。私が探していたのは、すべての変数が不変で、ホットキーの答えがそれを提供するソリューションです。しかし、誰かが同じことをする方法を知っているが、「オンザフライで要素を破棄する」(メモリは問題ではない)場合は、私たちに知らせてください。 – Tiago

答えて

6

、あなたは(おそらく構築することができます各項目は、前の1に基づいて計算される無限)シーケンスは、その後、あなたの状態it != 1でそれを制限してありますどのように多くの項目数える:ここ

return generateSequence(n) { if (it.isOdd()) 3 * it + 1 else it/2 } 
     .takeWhile { it != 1 } 
     .count() 

generateSequence(n) { ... }、を持ってSequence<Int>構築最初の要素については、次の各要素はラムダとして渡されたコードによって計算されます(前の要素で呼び出され、別の項目が照会されたとき、すなわち遅れている場合のみ)。

関連する問題