Sto cercando di imparare il funzionale Swift e ho iniziato a fare alcuni esercizi da Project Euler.Somma del termine Fibonacci usando Functional Swift
numeri Anche Fibonacci Problema 2 Ogni nuovo termine della sequenza di Fibonacci è generato sommando i precedenti due termini. Partendo da 1 e 2, i primi 10 termini saranno:
1, 2, 3, 5, 8, 13, 21, 34, 55, 89, ...
Considerando i termini la sequenza di Fibonacci i cui valori non superano i quattro milioni, trova la somma dei termini con valore pari.
implementato una funzione di Fibonacci memoized, come da WWDC avanzata video Swift:
func memoize<T:Hashable, U>(body: ((T)->U,T) -> U) -> (T)->U {
var memo = [T:U]()
var result: ((T)->U)!
result = { x in
if let q = memo[x] { return q }
let r = body(result,x)
memo[x] = r
return r
}
return result
}
let fibonacci = memoize { (fibonacci:Int->Double,n:Int) in n < 2 ? Double(n) : fibonacci(n-1) + fibonacci(n-2) }
e implementato una classe che è conforme alla Sequence
protocollo
class FibonacciSequence: SequenceType {
func generate() -> GeneratorOf<Double> {
var n = 0
return GeneratorOf<Double> { fibonacci(n++) }
}
subscript(n: Int) -> Double {
return fibonacci(n)
}
}
La prima (non funzionale) soluzione del problema:
var fib = FibonacciSequence().generate()
var n:Double = 0
var sum:Double = 0
while n < Double(4_000_000) {
if n % 2 == 0 {
sum += n
}
n = fib.next()!
}
println(sum)
La seconda soluzione, più funzionale, utilizzando ExSwift per la sua takeWhile
funzione
let f = FibonacciSequence()
println((1...40).map { f[$0] }
.filter { $0 % 2 == 0 }
.takeWhile { $0 < 4_000_000 }
.reduce(0, combine: +))
Mi piacerebbe migliorare su questa soluzione, a causa della gamma 1...40
ai accattonaggio che è calcolo troppi termini per nessun motivo. Idealmente mi piacerebbe poter avere una sorta di raggio infinito, ma allo stesso tempo calcolare solo i termini richiesti che soddisfano la condizione nello takeWhile
Qualche suggerimento?
A proposito, si noti che il tipo 'Double' non è necessario. Potresti preferire l'uso di 'UInt' –
Vero, è un residuo di quando ho provato a calcolare phi –
Ok, modificato ... potrebbe sembrare più _functional_ ora ;-) –