diff --git a/src/main/scala/DynamicProgramming/Fibonacci.scala b/src/main/scala/DynamicProgramming/Fibonacci.scala new file mode 100644 index 0000000..26d92b3 --- /dev/null +++ b/src/main/scala/DynamicProgramming/Fibonacci.scala @@ -0,0 +1,18 @@ +package DynamicProgramming + +object Fibonacci extends ProblemDP[Int]{ + type S = Int + type F[x] = (x, x) + + def decompose(problem: Int): Either[Int, (Int, Int)] = + problem match { + case x if x<=1 => Left(1) + case x => Right((x-1, x-2)) + } + + def compose(solution: (Int, Int)): Int = { + val (x1, x2) = solution + x1+x2 + } +} + diff --git a/src/main/scala/DynamicProgramming/ProblemDP.scala b/src/main/scala/DynamicProgramming/ProblemDP.scala new file mode 100644 index 0000000..023a29f --- /dev/null +++ b/src/main/scala/DynamicProgramming/ProblemDP.scala @@ -0,0 +1,31 @@ +package DynamicProgramming + +import cats.Functor +import cats.implicits.toFunctorOps + +import scala.collection.immutable.HashMap + +trait ProblemDP[T] { + type S + type F[_] + var map= HashMap[T, S]() + + def decompose(problem: T): Either[S, F[T]] + def compose(solution: F[S]): S + + def apply(problem: T)(implicit F: Functor[F]): S = + map.get(problem) match { + case None => + decompose(problem) match { + case Left(s) => + map+= (problem -> s) + case Right(p)=> + map+= (problem -> compose(p.map(apply))) + } + apply(problem) + case Some(s) => s + } + + + +} diff --git a/src/test/scala/DynamicProgramming/FibonacciTest.scala b/src/test/scala/DynamicProgramming/FibonacciTest.scala new file mode 100644 index 0000000..33a0ecd --- /dev/null +++ b/src/test/scala/DynamicProgramming/FibonacciTest.scala @@ -0,0 +1,16 @@ +package DynamicProgramming + +import org.scalatest.FunSuite +import DynamicProgramming.Fibonacci._ + +class FibonacciTest extends FunSuite { + + test("Fibonacci"){ + assert(apply(0)===1) + assert(apply(1)===1) + assert(apply(3)===3) + assert(apply(4)===5) + assert(apply(10)===89) + } + +}