Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Come risolvere un puzzle crypto-aritmetico in Scala

Come risolvere un puzzle crypto-aritmetico in Scala

Bartosz Milewski ha scritto 4 blog post su come risolvere una semplice puzzle matematico come un vero Programmatore Funzionale.

Modelleremo il problema come un problema di soddisfacimento di vincoli per poi risolverlo in Scala combinando 2 diversi monad. L'implementazione Scala in stile FP sara' estremamente simile a quella in Haskell presentata da Bartosz.

Per quanto elegante, tuttavia questo non sara' l'unico approccio interessante che verra' presentato.

Filippo Vitale

December 20, 2016
Tweet

More Decks by Filippo Vitale

Other Decks in Programming

Transcript

  1. 20 Dicembre 2016 @filippovitale Come risolvere un puzzle crypto-aritmetico in

    Scala
  2. None
  3. ~ scala Welcome to Scala version 2.11.7 (Java HotSpot(TM) 64-Bit

    Server VM, Java 1.8.0_91). Type in expressions to have them evaluated. Type :help for more information. scala>
  4. ~ scala Welcome to Scala version 2.11.7 (Java HotSpot(TM) 64-Bit

    Server VM, Java 1.8.0_91). Type in expressions to have them evaluated. Type :help for more information. scala> import scalaz._, Scalaz._ // o cats._
  5. @alexeyraga

  6. SEND + MORE ------- MONEY @alexeyraga https://en.wikipedia.org/wiki/Verbal_arithmetic

  7. SEND + MORE ------- MONEY @alexeyraga E == E ==

    E
  8. SEND + MORE ------- MONEY @alexeyraga S,M ≠ 0

  9. None
  10. SEND + MORE ------- MONEY

  11. SEND + MORE ------- MONEY

  12. SEND + MORE ------- MONEY

  13. SEND + MORE ------- MONEY M←1

  14. SEND + MORE ------- MONEY M←1

  15. SEND + 1ORE ------- 1ONEY M←1

  16. SEND + 1ORE ------- 1ONEY M←1 O←0 S←8,9

  17. M←1 Aspetta un attimo... @alexeyraga

  18. None
  19. Immutability Higher-order function Monad Referential transparency http://bartoszmilewski.com/2015/05/11/using-monads-in-c-to-solve-constraints-1-the-list-monad/

  20. Brute force 10! / (10 – 8)! ≈ 2 Milioni

    Ricerca esaustiva e spazio di ricerca
  21. Ricerca Esaustiva Implementazione naïve

  22. for (int s = 0; s < 10; ++s) for

    (int e = 0; e < 10; ++e) for (int n = 0; n < 10; ++n) for (int d = 0; d < 10; ++d) ... s != 0 e != s n != s && n != e d != s && d != e && d != n Approccio Imperativo: 8 loop annidiati
  23. for (int s = 0; s < 10; ++s) for

    (int e = 0; e < 10; ++e) for (int n = 0; n < 10; ++n) for (int d = 0; d < 10; ++d) ... s != 0 e != s n != s && n != e d != s && d != e && d != n Ricerca soluzioni teoricamente possibili: ➔ Generazione delle assegnazioni ➔ Verifica dei vincoli
  24. for { s <- 0 to 9 if s !=

    0 e <- 0 to 9 if e != s n <- 0 to 9 if n != s && n != e d <- 0 to 9 if d != s && d != e && d!=n ... for (int s = 0; s < 10; ++s) for (int e = 0; e < 10; ++e) for (int n = 0; n < 10; ++n) for (int d = 0; d < 10; ++d) ... s != 0 e != s n != s && n != e d != s && d != e && d != n Ricerca soluzioni teoricamente possibili: ➔ Generazione delle assegnazioni ➔ Verifica dei vincoli
  25. Ricerca soluzioni teoricamente possibili Verifica vincoli

  26. val listOfDigits = (0 to 9).toList val solutions = for

    { s <- listOfDigits if s != 0 e <- listOfDigits if s != e n <- listOfDigits if s != n && e != n d <- listOfDigits if s != d && e != d && n != d m <- listOfDigits if m != 0 if s != m && e != m && n != m && d != m o <- listOfDigits if s != o && e != o && n != o && d != o && m != o r <- listOfDigits if s != r && e != r && n != r && d != r && m != r && o != r y <- listOfDigits if s != y && e != y && n != y && d != y && m != y && o != y && r != y } yield ??? Ricerca soluzioni teoricamente possibili Verifica vincoli
  27. val listOfDigits = (0 to 9).toList val solutions = for

    { s <- listOfDigits if s != 0 e <- listOfDigits if s != e n <- listOfDigits if s != n && e != n d <- listOfDigits if s != d && e != d && n != d m <- listOfDigits if m != 0 if s != m && e != m && n != m && d != m o <- listOfDigits if s != o && e != o && n != o && d != o && m != o r <- listOfDigits if s != r && e != r && n != r && d != r && m != r && o != r y <- listOfDigits if s != y && e != y && n != y && d != y && m != y && o != y && r != y send = List(s, e, n, d).reduce(_ * 10 + _) more = List(m, o, r, e).reduce(_ * 10 + _) money = List(m, o, n, e, y).reduce(_ * 10 + _) if send + more == money } yield (send, more, money) Ricerca soluzioni teoricamente possibili Verifica vincoli
  28. val listOfDigits = (0 to 9).toList val solutions = for

    { s <- listOfDigits if s != 0 e <- listOfDigits if s != e n <- listOfDigits if s != n && e != n d <- listOfDigits if s != d && e != d && n != d m <- listOfDigits if m != 0 if s != m && e != m && n != m && d != m o <- listOfDigits if s != o && e != o && n != o && d != o && m != o r <- listOfDigits if s != r && e != r && n != r && d != r && m != r && o != r y <- listOfDigits if s != y && e != y && n != y && d != y && m != y && o != y && r != y send = List(s, e, n, d).reduce(_ * 10 + _) more = List(m, o, r, e).reduce(_ * 10 + _) money = List(m, o, n, e, y).reduce(_ * 10 + _) if send + more == money } yield (send, more, money)
  29. “Jimmy” e il Multiverso

  30. None
  31. 0 1 2 3 4 5 6 7 8 9

  32. 1 2 3 4 5 6 7 8 9 0

  33. ? ? ? ? ? ? ? ? ? ?

    S = …
  34. 1 2 3 4 5 6 7 8 9 0

    0 S = 0!
  35. None
  36. ? ? ? ? ? ? ? ? ? ?

    S = …
  37. 0 1 2 3 4 5 6 7 8 9

    0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 5 1 2 3 4 0 6 7 8 9 0 6 2 3 4 5 1 7 8 9 0 1 7 3 4 5 6 2 8 9 0 1 3 2 4 5 6 7 8 9 0 1 8 3 4 5 6 7 8 9 0 1 4 3 2 5 6 7 8 9 0 1 9 3 4 5 6 7 8 2
  38. 0 1 2 3 4 5 6 7 8 9

    0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 5 1 2 3 4 0 6 7 8 9 0 6 2 3 4 5 1 7 8 9 0 1 7 3 4 5 6 2 8 9 0 1 3 2 4 5 6 7 8 9 0 1 8 3 4 5 6 7 8 9 0 1 4 3 2 5 6 7 8 9 0 1 9 3 4 5 6 7 8 2 S = 1
  39. 0 1 2 3 4 5 6 7 8 9

    S = 1
  40. 0 1 2 3 4 5 6 7 8 9

    S = 1 E = …
  41. 0 1 2 3 4 5 6 7 8 9

    S = 1 E = … 0 2 3 4 5 6 7 8 9
  42. None
  43. Implementazione delle Dimensioni Parallele utilizzando il List Monad

  44. Implementazione delle Dimensioni Parallele utilizzando il List Monad imperative code

    ⇒ declarative code
  45. val l = for { a <- List(1, 2) b

    <- List(1, 2) } yield Map('a' -> a, 'b' -> b) val l = ???
  46. val l = for { a <- List(1, 2) b

    <- List(1, 2) } yield Map('a' -> a, 'b' -> b) val l: List[A] = ???
  47. val l = for { a <- List(1, 2) b

    <- List(1, 2) } yield Map('a' -> a, 'b' -> b) val l: List[Map[Char, Int]] = ???
  48. val l = for { a <- List(1, 2) b

    <- List(1, 2) } yield Map('a' -> a, 'b' -> b) List(Map('a' -> 1, 'b' -> 1), Map('a' -> 1, 'b' -> 2), Map('a' -> 2, 'b' -> 1), Map('a' -> 2, 'b' -> 2))
  49. val l = for { a <- List(1, 2) b

    <- List(1, 2) if a != b } yield Map('a' -> a, 'b' -> b) List(Map('a' -> 1, 'b' -> 2), Map('a' -> 2, 'b' -> 1))
  50. Implementazione delle Dimensioni Parallele utilizzando lo State Monad https://www.manning.com/books/functional-programming-in-scala#chapter-6

  51. Implementazione delle Dimensioni Parallele utilizzando lo State Monad https://www.manning.com/books/functional-programming-in-scala#chapter-6 La

    analogia del burrito comincia a scricchiolare
  52. “The future is a function of the past.” – A.

    P. Robertson https://goo.gl/jt6bvz
  53. // stateful computation type State[S, +A] = S => (S,

    A) https://bartoszmilewski.com/2016/11/30/monads-and-effects/#State
  54. trait State[S, +A] { def eval(initial: S): A def map[B](f:

    A => B): State[S, B] def flatMap[B](f: A => State[S, B]): State[S, B] } object State { def apply[S, A](f: S => (S, A)): State[S, A] }
  55. // stateful computation f: S => (S, A) def select(xs:

    List[Int]): (List[Int], Int) = (xs.tail, xs.head)
  56. // stateful computation f: S => (S, A) def select(xs:

    List[Int]): (List[Int], Int) = (xs.tail, xs.head)
  57. // stateful computation f: S => (S, A) def select(xs:

    List[Int]): (List[Int], Int) = (xs.tail, xs.head)
  58. import scalaz.State val s = for { a <- State(select)

    b <- State(select) } yield Map('a' -> a, 'b' -> b) val s = ???
  59. import scalaz.State val s = for { a <- State(select)

    b <- State(select) } yield Map('a' -> a, 'b' -> b) val s: State[ S, A ] = ???
  60. import scalaz.State val s = for { a <- State(select)

    b <- State(select) } yield Map('a' -> a, 'b' -> b) val s: State[ List[Int], Map[Char, Int] ] = ???
  61. import scalaz.State val s = for { a <- State(select)

    b <- State(select) } yield Map('a' -> a, 'b' -> b) val s: State[ List[Int], Map[Char, Int] ] = ??? s.eval(List(1, 2)) ==== Map('a' -> 1, 'b' -> 2)
  62. import scalaz.State val s = for { a <- State(select)

    b <- State(select) } yield Map('a' -> a, 'b' -> b) val s: State[ List[Int], Map[Char, Int] ] = ??? s.eval(List(8, 3)) ==== Map('a' -> 8, 'b' -> 3)
  63. val s = for { a <- State(select) b <-

    State(select) c <- State(select) } yield Map('a' -> a, 'b' -> b, 'c' -> c) s.eval(1 |-> 3) ==== Map('a' -> 1, 'b' -> 2, 'c' -> 3)
  64. val s = for { a <- State(select) b <-

    State(select) c <- State(select) d <- State(select) } yield Map('a' -> a, 'b' -> b, 'c' -> c, 'd' -> d) s.eval(1 |-> 4) ==== Map('a' -> 1, 'b' -> 2, 'c' -> 3, 'd' -> 4)
  65. None
  66. Implementazione delle Dimensioni Parallele utilizzando StateT[List, S, A]

  67. Implementazione delle Dimensioni Parallele utilizzando StateT[List, S, A] https://speakerdeck.com/gabro/monad-transformers-what-and-why

  68. None
  69. http://book.realworldhaskell.org/read/monad-transformers.html

  70. def select[A](xs: List[A]): (List[A], A) State S => ( S

    , A)
  71. State S => ( S , A) StateT[F, S, A]

    S => F[( S , A)]
  72. State S => ( S , A) List[( S ,

    A)] StateT[F, S, A] S => F[( S , A)]
  73. State S => ( S , A) List[(List[A], A)] StateT[F,

    S, A] S => F[( S , A)]
  74. def select[A](xs: List[A]): (List[A], A) State S => ( S

    , A) def select[A](xs: List[A]): List[(List[A], A)] StateT[F, S, A] S => F[( S , A)]
  75. def select[A](xs: List[A]): List[(List[A], A)] = xs map { x

    => ( ??? ) }
  76. def select[A](xs: List[A]): List[(List[A], A)] = xs map { x

    => ( , x) }
  77. def select[A](xs: List[A]): List[(List[A], A)] = xs map { x

    => (xs.filterNot(_ == x), x) }
  78. 0 1 2 3 4 5 6 7 8 9

    0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 5 1 2 3 4 0 6 7 8 9 0 6 2 3 4 5 1 7 8 9 0 1 7 3 4 5 6 2 8 9 0 1 3 2 4 5 6 7 8 9 0 1 8 3 4 5 6 7 8 9 0 1 4 3 2 5 6 7 8 9 0 1 9 3 4 5 6 7 8 2
  79. sl.eval(1 |-> 2) == ??? import scalaz.StateT import scalaz.std.list._ val

    sl = for { a <- StateT(select) b <- StateT(select) } yield Map('a' -> a, 'b' -> b)
  80. import scalaz.StateT import scalaz.std.list._ val sl = for { a

    <- StateT(select) b <- StateT(select) } yield Map('a' -> a, 'b' -> b) sl.eval(1 |-> 2) == List(Map('a' -> 1, 'b' -> 2), Map('a' -> 2, 'b' -> 1)) https://gist.github.com/filippovitale/6cc45396ed917a2a8411
  81. val sel = StateT(select[Int]) for { s <- sel e

    <- sel n <- sel d <- sel m <- sel o <- sel r <- sel y <- sel … }
  82. val sel = StateT(select[Int]) for { s <- sel e

    <- sel n <- sel d <- sel m <- sel o <- sel r <- sel y <- sel … } Lo stesso `sel` restituisce ad ogni `.flatMap` un numero diverso
  83. val sel = StateT(select[Int]) for { s <- sel e

    <- sel n <- sel d <- sel m <- sel o <- sel r <- sel y <- sel … } Lo stesso `sel` restituisce ad ogni `.flatMap` un numero diverso 0 1 2 3 4 5 6 7 8 9
  84. Risolvere il puzzle con StateT[List, S, A]

  85. val sel = StateT(select[Int]) for { s <- sel if

    s != 0 e <- sel n <- sel d <- sel m <- sel if m != 0 o <- sel r <- sel y <- sel send = List(s, e, n, d).reduce(_ * 10 + _) more = List(m, o, r, e).reduce(_ * 10 + _) money = List(m, o, n, e, y).reduce(_ * 10 + _) if send + more == money } yield (s, e, n, d, m, o, r, y)
  86. val sel = StateT(select[Int]) for { s <- sel if

    s != 0 e <- sel n <- sel d <- sel m <- sel if m != 0 o <- sel r <- sel y <- sel send = List(s, e, n, d).reduce(_ * 10 + _) more = List(m, o, r, e).reduce(_ * 10 + _) money = List(m, o, n, e, y).reduce(_ * 10 + _) if send + more == money } yield (s, e, n, d, m, o, r, y) MonadPlus MonadPlus https://speakerdeck.com/filippovitale/send-plus-more-equals-money-scalasyd-july-2015
  87. Risolvere il puzzle sfruttando le API di Scala

  88. val listOfDigits = (0 to 9).toList val solutions = for

    { s <- listOfDigits if s != 0 e <- listOfDigits if s != e n <- listOfDigits if s != n && e != n d <- listOfDigits if s != d && e != d && n != d m <- listOfDigits if m != 0 if s != m && e != m && n != m && d != m o <- listOfDigits if s != o && e != o && n != o && d != o && m != o r <- listOfDigits if s != r && e != r && n != r && d != r && m != r && o != r y <- listOfDigits if s != y && e != y && n != y && d != y && m != y && o != y && r != y send = List(s, e, n, d).reduce(_ * 10 + _) more = List(m, o, r, e).reduce(_ * 10 + _) money = List(m, o, n, e, y).reduce(_ * 10 + _) if send + more == money } yield (send, more, money) Ricerca soluzioni teoricamente possibili Verifica vincoli
  89. val maps = for { ??? } yield ??? Ricerca

    soluzioni teoricamente possibili Verifica vincoli
  90. "sendmoremoney".distinct.size // 8 distinct `char` val maps = for {

    ??? } yield ??? Ricerca soluzioni teoricamente possibili Verifica vincoli
  91. "sendmoremoney".distinct.size // 8 distinct `char` val maps = for {

    ??? } yield ("sendmoremoney".distinct zip ???).toMap Ricerca soluzioni teoricamente possibili Verifica vincoli
  92. val maps = for { ??? } yield ("sendmoremoney".distinct zip

    ???).toMap Ricerca soluzioni teoricamente possibili Verifica vincoli
  93. val maps = for { combination <- (0 to 9).combinations(8)

    // 45 combinazioni // Vector(0, 1, 2, 3, 4, 5, 6, 7) // Vector(0, 1, 2, 3, 4, 5, 6, 8) // Vector(0, 1, 2, 3, 4, 5, 6, 9) // Vector(0, 1, 2, 3, 4, 5, 7, 8) // Vector(0, 1, 2, 3, 4, 5, 7, 9) // Vector(0, 1, 2, 3, 4, 5, 8, 9) // Vector(0, 1, 2, 3, 4, 6, 7, 8) // Vector(0, 1, 2, 3, 4, 6, 7, 9) // Vector(0, 1, 2, 3, 4, 6, 8, 9) // ... } yield ("sendmoremoney".distinct zip ???).toMap Ricerca soluzioni teoricamente possibili Verifica vincoli
  94. val maps = for { combination <- (0 to 9).combinations(8)

    // 45 combinazioni // Vector(0, 1, 2, 3, 4, 5, 6, 7) // (8, 9) // Vector(0, 1, 2, 3, 4, 5, 6, 8) // (7, 9) // Vector(0, 1, 2, 3, 4, 5, 6, 9) // (7, 8) // Vector(0, 1, 2, 3, 4, 5, 7, 8) // (6, 9) // Vector(0, 1, 2, 3, 4, 5, 7, 9) // (6, 8) // Vector(0, 1, 2, 3, 4, 5, 8, 9) // (6, 7) // Vector(0, 1, 2, 3, 4, 6, 7, 8) // (5, 9) // Vector(0, 1, 2, 3, 4, 6, 7, 9) // (5, 8) // Vector(0, 1, 2, 3, 4, 6, 8, 9) // (5, 7) // ... } yield ("sendmoremoney".distinct zip ???).toMap Ricerca soluzioni teoricamente possibili Verifica vincoli
  95. val maps = for { combination <- (0 to 9).combinations(8)

    // 45 combinazioni permutation <- combination.permutations // 40K permutazioni } yield ("sendmoremoney".distinct zip permutation).toMap Ricerca soluzioni teoricamente possibili Verifica vincoli
  96. val maps = for { combination <- (0 to 9).combinations(8)

    // 45 combinazioni permutation <- combination.permutations // 40K permutazioni } yield ("sendmoremoney".distinct zip permutation).toMap // ~2M Ricerca soluzioni teoricamente possibili Verifica vincoli
  97. val maps = for { combination <- (0 to 9).combinations(8)

    // 45 combinazioni permutation <- combination.permutations // 40K permutazioni } yield ("sendmoremoney".distinct zip permutation).toMap // ~2M val solutions = for { m <- maps if m('s') != 0 && m('m') != 0 send = "send" map m reduce (_ * 10 + _) more = "more" map m reduce (_ * 10 + _) money = "money" map m reduce (_ * 10 + _) if send + more == money } yield (send, more, money) Ricerca soluzioni teoricamente possibili Verifica vincoli
  98. val maps = for { combination <- (0 to 9).combinations(8)

    // 45 combinazioni permutation <- combination.permutations // 40K permutazioni } yield ("sendmoremoney".distinct zip permutation).toMap // ~2M val solutions = for { m <- maps if m('s') != 0 && m('m') != 0 send = "send" map m reduce (_ * 10 + _) more = "more" map m reduce (_ * 10 + _) money = "money" map m reduce (_ * 10 + _) if send + more == money } yield (send, more, money) solutions.next() // (9567,1085,10652) Ricerca soluzioni teoricamente possibili Verifica vincoli
  99. Risolvere il puzzle a compile-time

  100. Risolvere il puzzle a compile-time Peano's arithmetic Shapeless: HList, Sum,

    … http://jto.github.io/articles/typelevel_quicksort/
  101. None
  102. Queste sono tutte implementazioni di ricerche depth-first

  103. None
  104. Risolvere il puzzle con un algoritmo genetico http://dl.acm.org/citation.cfm?id=1725467

  105. - Individuo - Popolazione - Generazione Algoritmo genetico

  106. Algoritmo genetico - Individuo - Popolazione - Generazione - Funz.

    di Fitness - Mutazione
  107. Algoritmo genetico - Individuo - Popolazione - Generazione - Funz.

    di Fitness - Mutazione type Digit = Int type Individual = Vector[Digit]
  108. Algoritmo genetico - Individuo - Popolazione - Generazione - Funz.

    di Fitness - Mutazione type Digit = Int type Individual = Vector[Digit] // “sendmory”
  109. Algoritmo genetico - Individuo - Popolazione - Generazione - Funz.

    di Fitness - Mutazione type Digit = Int type Individual = Vector[Digit] // “sendmory” Vector di lunghezza 8 2 Digit non utilizzate
  110. Algoritmo genetico - Individuo - Popolazione - Generazione - Funz.

    di Fitness - Mutazione type Digit = Int type Individual = Vector[Digit] // “sendmory” List(0 |-> 9) .combinations(2) .toSet .size // 45 Vector di lunghezza 8 2 Digit non utilizzate ⇒ 45 Specie diverse
  111. Algoritmo genetico - Individuo - Popolazione - Generazione - Funz.

    di Fitness - Mutazione type Digit = Int type Individual = Vector[Digit] type Population = List[Individual] def fitness(individual: Individual): Int
  112. Algoritmo genetico - Individuo - Popolazione - Generazione - Funz.

    di Fitness - Mutazione type Digit = Int type Individual = Vector[Digit] type Population = List[Individual] def fitness(individual: Individual): Int // 0
  113. Algoritmo genetico - Individuo - Popolazione - Generazione - Funz.

    di Fitness - Mutazione type Digit = Int type Individual = Vector[Digit] type Population = List[Individual] def fitness(individual: Individual): Int def mutation(individual: Individual): Individual
  114. Algoritmo genetico - Individuo - Popolazione - Generazione - Funz.

    di Fitness - Mutazione type Digit = Int type Individual = Vector[Digit] type Population = List[Individual] def fitness(individual: Individual): Int def mutation(individual: Individual): Individual // “asexual genetic algorithm in this paper”
  115. Semplice implementazione di un Algoritmo Genetico per risolvere il puzzle

  116. /** side-effect */ val r = util.Random val generationSize =

    512 val generationRetainment = 32 // top 6% // 16 of the 28 possible mutations val individualProlificness: Int = generationSize / generationRetainment
  117. def fitness(individual: Individual): Int = { math.abs(send + more -

    money) }
  118. def fitness(individual: Individual): Int = { val cs = "sendmoremoney".distinct

    val m = cs.zip(individual).toMap math.abs(send + more - money) }
  119. def fitness(individual: Individual): Int = { val cs = "sendmoremoney".distinct

    val m = cs.zip(individual).toMap val send = "send" map m reduce (_ * 10 + _) val more = "more" map m reduce (_ * 10 + _) val money = "money" map m reduce (_ * 10 + _) math.abs(send + more - money) }
  120. val mutationIndices = List(0 |-> 7).combinations(2) def everyMutation(individual: Individual): Iterator[Individual]

    = r.shuffle(mutationIndices) .map { case Seq(i, j) => individual .updated(i, individual(j)) .updated(j, individual(i)) } // +-+-+-+-+-+-+-+-+ // |S|E|N|D|M|O|R|Y| // +-+-+-+-+-+-+-+-+ // |0|1|2|3|4|5|6|7| // +-+-+-+-+-+-+-+-+ // ^ ^ // | | // +-----+ // [i] [j]
  121. val solution = ???

  122. val solution = Iterator .iterate(generatePopulation(generationSize)) (createNextGeneration)

  123. val solution = Iterator .iterate(generatePopulation(generationSize)) (createNextGeneration)

  124. def createNextGeneration(currentGeneration: Population) : Population = ???

  125. def createNextGeneration(currentGeneration: Population) : Population = currentGeneration .take(generationRetainment)

  126. def createNextGeneration(currentGeneration: Population) : Population = currentGeneration .take(generationRetainment) .flatMap(everyMutation(_).take(individualProlificness))

  127. def createNextGeneration(currentGeneration: Population) : Population = currentGeneration .take(generationRetainment) .flatMap(everyMutation(_).take(individualProlificness)) .sortBy(fitness)

  128. def createNextGeneration(currentGeneration: Population) : Population = if (fitness(currentGeneration.head) == 0)

    { ??? } else { ??? }
  129. def createNextGeneration(currentGeneration: Population) : Population = if (fitness(currentGeneration.head) == 0)

    { ??? } else { currentGeneration.take(generationRetainment) .flatMap(everyMutation(_).take(individualProlificness)) .sortBy(fitness) }
  130. def createNextGeneration(currentGeneration: Population) : Population = if (fitness(currentGeneration.head) == 0)

    { currentGeneration.take(1) } else { currentGeneration.take(generationRetainment) .flatMap(everyMutation(_).take(individualProlificness)) .sortBy(fitness) }
  131. val solution = Iterator .iterate(generatePopulation(generationSize)) (createNextGeneration) .dropWhile(_.size > 1)

  132. val solution = Iterator .iterate(generatePopulation(generationSize)) (createNextGeneration) .dropWhile(_.size > 1) .map(_.head).next()

  133. None
  134. None
  135. None
  136. 20 Dicembre 2016 @filippovitale Grazie

  137. 20 Dicembre 2016 @filippovitale $ tail -f questions