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.

2fa9df92d8d7eba3e17207c86f953be3?s=128

Filippo Vitale

December 20, 2016
Tweet

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