Last active
May 24, 2018 18:42
-
-
Save mmirolim/e5c188fac93078da4dced4bd0a5f941b to your computer and use it in GitHub Desktop.
FP ideas implementation
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package main | |
import scala.annotation.tailrec | |
object FP extends App { | |
println("test solution") | |
val nums = List(1, -1, 1, 2,-1) | |
def comp(in: List[Int]): Int = { | |
@tailrec | |
def helper(in: List[Int], prev: Int, agg: Int): Int = { | |
if (in.isEmpty) agg | |
else if ((in.head > 0 && prev < 0) || (in.head < 0 && prev > 0)) helper(in.tail, in.head, agg + 1) | |
else helper(in.tail, in.head, agg) | |
} | |
helper(in.tail, in.head, 0) | |
} | |
val res = comp(nums) | |
println(res) | |
def sum(l: List[Int]): Int = { | |
if (l.isEmpty) 0 | |
else l.head + sum(l.tail) | |
} | |
val l = List(1,2,5) | |
println(sum(l)) | |
def foldr[A,B](xs: List[A], e : B, f: (A,B) => B): B = { | |
xs match { | |
case Nil => e | |
case y::ys => f(y, foldr(ys, e, f)) | |
} | |
} | |
def sumF(l: List[Int]): Int = foldr(l, 0, (a: Int, b: Int) => a + b) | |
val res2 = sumF(l) | |
println("res2") | |
println(res2) | |
val lstr = List("a", "b", "x") | |
println(foldr(lstr, "", (a: String, b: String) => a + b)) | |
def product(l: List[Int]): Int = foldr(l, 1, (a: Int, b: Int) => a * b) | |
println("product") | |
println(l) | |
println(product(l)) | |
println("anytrue") | |
def anyTrue(l: List[Boolean]): Boolean = | |
foldr(l, false, (a: Boolean, b: Boolean) => a || b) | |
val bools = List(true, true, true) | |
println(anyTrue(bools)) | |
println("allTrue") | |
def allTrue(l: List[Boolean]): Boolean = | |
foldr(l, true, (a: Boolean, b: Boolean) => a && b) | |
println(allTrue(bools)) | |
println("append") | |
def copy(l: List[Int]): List[Int] = | |
foldr(l, Nil, (a: Int, b: List[Int]) => a :: b) | |
// def append(a: List[Int], b: List[Int]): List[Int] = | |
// foldr(Nil, b, Cons) | |
val cL = copy(nums) | |
println(cL) | |
def append(a: List[Int], b: List[Int]): List[Int] = | |
foldr(b, a, (a: Int, b: List[Int]) => a :: b) | |
val jCll = append(cL, l) | |
println(jCll) | |
def count(n: Int): Int = n + 1 | |
def len[T](l: List[T]): Int = | |
foldr(l, 0, (a: T, b: Int) => count(b)) | |
println((len(jCll), len(bools), len(lstr))) | |
def fcur(a: Int)(b: Int)(c: Int, d: Int): Int = | |
a + b + c + d | |
println(fcur(1)(2)(3,1)) | |
// curried with default init aggregator equal to 0 | |
def foldrC[A,B](l: List[A], e: B = 0)(f: (A, B) =>B):B = { | |
l match { | |
case Nil => e | |
case head::tail => f(head, foldrC(tail, e)(f)) | |
} | |
} | |
def sumCur(l: List[Int]): Int = | |
foldrC(l)(_+_) | |
println(sumCur(nums)) | |
// append with new foldr | |
def appendC[T](a: List[T], b: List[T]): List[T] = | |
foldrC(b, a)(_::_) | |
val lstr2 = List("a","b","c") | |
val lnum2 = List(1,2,3) | |
val lstr3 = List("d","e") | |
val resl = appendC(lstr2, lstr3) | |
println(resl) | |
def doubleAndCons(n: Int, l: List[Int]): List[Int] = | |
2 * n :: l | |
def double(n: Int): Int = 2 * n | |
def fAndCons(el: Int, l: List[Int])(f: (Int)=>Int): List[Int] = f(el)::l | |
def doubleall(l: List[Int]): List[Int] = | |
l match { | |
case Nil => Nil | |
case x::xs => fAndCons(x, xs)(double(_)) | |
} | |
val leven = List(2,3,4) | |
println(doubleall(leven)) | |
def map[T](l: List[T])(f: T => T): List[T] = | |
foldrC(l, List[T]())((a: T, b: List[T]) => f(a) :: b) | |
def doubleAllWithMap(l: List[Int]): List[Int] = map(l)(double) | |
val l10 = List.range(1,10) | |
println(doubleAllWithMap(l10)) | |
case class Node[T](v: T, chlds: List[Node[T]]) | |
val tree1 = Node( | |
1, | |
Node(2, Nil) :: | |
List(Node(3, | |
List(Node(4, | |
List(Node(2, Nil))))))) | |
def foldTree[A,B](nodes: List[Node[A]], e: B, g: Node[A] => A, f: (A,B) => B): B = { | |
nodes match { | |
case Nil => e | |
case x :: Nil => f(g(x), foldTree(x.chlds, e, g ,f)) | |
case x :: xs => f(g(x), foldTree(xs, e, g, f)) | |
} | |
} | |
println("foldTree tree1") | |
def plus(a: Int, b: Int): Int = a + b | |
println(foldTree(List(tree1), 0, (n: Node[Int]) => n.v, plus)) | |
def mul(a: Int, b: Int) = a * b | |
println(foldTree(List(tree1), 1, (n: Node[Int]) => n.v, mul)) | |
val labels = foldTree(List(tree1), Nil, (n: Node[Int]) => n.v, (a: Int, l: List[Int]) => a :: l) | |
println(labels) | |
// Newton-Raphson algorithm | |
def next(n: Int)(x: Float): Float = (x + n / x)/2 | |
def repeat[T](f: (T) => T, a0: T): Stream[T]= Stream.cons(a0,repeat(f, f(a0))) | |
def abs(x: Float) = if (x > 0) x else -x | |
def within(eps: Float, vals : Stream[Float]): Float = { | |
val a = vals.head | |
val b = vals.tail.head | |
if (abs(a - b) <= eps) b | |
else within(eps, vals.tail) | |
} | |
def sqrt(n: Int, guess: Float, eps: Float): Float = | |
within(eps, repeat(next(n), guess)) | |
// square root of 2 | |
println(sqrt(2, 1, 0.001f)) | |
// square root of 5 | |
println(sqrt(25, 4, 0.001f)) | |
// square root of 90 | |
println(sqrt(90, 8, 0.001f)) | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment