Skip to content

Instantly share code, notes, and snippets.

@sumew
sumew / slidingwindow.scala
Last active November 26, 2020 07:15
A generic representation of a sliding window problem
def lengthOfLongestSubstring(in: String): Int = {
//A type alias to simplify the syntax
type CounterContainer[T] = Map[T, Int]
//The elements are Chars and our container, a map with the Char as key and the frequence as value holds the elements within the current window
val longest = new SlidingWindow[Char, CounterContainer[Char]] {
override val input: Seq[Char] = in
trait Container[T, F[_]]
@sumew
sumew / state.scala
Created November 26, 2020 05:57
The state, holds the current window and the optimum (so far) window
case class State[Container](current: Window, best: Window, contained: Container) {
def lastIndex(): Int = current.r
def firstIndex(): Int = current.l
override def toString =
s"current: [${current.l}, ${current.r}], best: [${best.l}, ${best.r}], excess: ${contained}"
}
@sumew
sumew / window.scala
Last active November 26, 2020 06:33
A window that can expand to the right and contract from the left
case class Window(l: Int, r: Int) {
def size = r - l
def ||->(i: Int): Window = this.copy(r = r + i) //widen by moving right edge right
def |->|(i: Int): Window = this.copy(l = l + i) //shrink by moving left edge right
}
/**
* At each step, enqueue the value at the current node and add
* the left & right children to the stack. Option's toList
* helps convert empty children (None values) to an empty list
*/
def preOrderC[T, S](root: Option[BTree[T]], f: T => S): Queue[S] = {
def loop(stack: List[BTree[T]], acc: Queue[S]): Queue[S] = stack match {
case Nil => acc
case BTree(v, l, r) :: ts => loop(l.toList ::: r.toList ::: ts, acc.enqueue(f(v)))
}
case class BTree[T](value: T, left: Option[BTree[T]], right: Option[BTree[T]])
def preOrderR[T,S](tree: Tree[T], f: T => S): Queue[S] = {
def loop(stack: List[Tree[T]], output: Queue[S]): Queue[S] = stack match {
case Nil => output
case Tree(v,c)::ts => loop(c:::ts,output.enqueue(f(v)))
}
loop(tree::Nil, Queue.empty)
}
def postOrderR[T,S](tree: Tree[T], f: T => S): Queue[S] = {
def loop(stack: List[Tree[T]], output: Queue[S]): Queue[S] = stack match {
def inOrder[T,S](tree: Tree[T], f: T => S): Queue[S] = {
def loop(g: Tree[T], output: Queue[S]): Queue[S] = g match {
case Tree(v,l::ls) => ls.foldLeft(loop(l,output).enqueue(f(v))){case (acc,n) => loop(n,acc)}
case Tree(v,Nil) => output.enqueue(f(v))
}
loop(tree, Queue.empty)
}
def postOrder[T,S](tree: Tree[T], f: T => S): Queue[S] = {
def loop(g: Tree[T], output: Queue[S]): Queue[S] = g match {
case Tree(v,rest) => rest.foldLeft(output){case (agg,node) => loop(node,agg)}.enqueue(f(v))
}
loop(tree,Queue.empty)
}
def foldLeft[B](z: B)(op: (B, A) => B): B