Skip to content

Instantly share code, notes, and snippets.

@pathikrit
pathikrit / TypedRest.scala
Last active February 2, 2016 21:26
Well typed REST skeleton
object TypedRest {
type Id[A] = Long
object Request {
private[this] trait HasId[A] {
val id: Id[A]
}
trait Get[A] extends HasId[A]
trait Put[A] extends HasId[A]
trait Post[A]
@pathikrit
pathikrit / DataTable.scala
Last active September 7, 2016 19:30
DataTables in Scala
trait DataTable[PK, C, V] {
type Row = C => V
type Filter = Row => Boolean
val table: PK => Row
def apply(id: PK): Row = table(id)
def keys: Iterable[PK]
def rows: Iterable[Row] = keys.map(apply)
@pathikrit
pathikrit / BiMap.scala
Last active March 8, 2016 19:58
Bi-directional map in Scala
class BiMap[A, B] private(var a2b: Map[A, B], var b2a: Map[B, A]) extends Tuple2(a2b, b2a) with collection.mutable.MapLike[A, B, BiMap[A, B]] {
override def +=(kv: (A, B)) = {
a2b = a2b + kv
b2a = b2a + kv.swap
this
}
override def -=(a: A) = {
get(a).foreach {b => b2a = b2a - b}
a2b = a2b - a
@pathikrit
pathikrit / EquivalenceLock.scala
Last active February 7, 2017 21:14
Locking based on object equality rather than referential equality in Scala
/**
* An util that provides synchronization using value equality rather than referential equality
* It is guaranteed that if two objects are value-equal, their corresponding blocks are invoked mutually exclusively.
* But the converse may not be true i.e. if two objects are not value-equal, they may be invoked exclusively too
* Note: Typically, no need to create instances of this class. The default instance in the companion object can be safely reused
*
* @param size There is a 1/size probability that two invocations that could be invoked concurrently is invoked sequentially
*
* Example usage:
* import EquivalenceLock.{defaultInstance => lock}
@pathikrit
pathikrit / debounce.scala
Last active August 29, 2015 14:26
Debounce in Scala
import scala.compat.Platform.{currentTime => now}
import scala.concurrent.duration.FiniteDuration
import java.util.concurrent.atomic.AtomicBoolean
/**
* Debounce a function i.e. it can only be invoked iff it is not already running
* and atleast wait duration has passed since it last stopped running
* Usage:
* def test(i: Int) = println(i)
@pathikrit
pathikrit / IsPalindrome.scala
Last active April 15, 2018 11:19
Scala isPalindrome
def isPalindrome[A](x: Vector[A]): Boolean = x match {
case start +: middle :+ end => start == end && isPalindrome(middle)
case _ => true
}
@pathikrit
pathikrit / git-standup
Created June 22, 2015 22:32
git daily standup
log --all --no-merges --graph --date=relative --committer=$(git config --get user.email) --pretty=format:'%C(cyan) %ad %C(yellow)%h %Creset %s %Cgreen%d' --since="$(if [[ "Mon" == "$(date +%a)" ]]; then echo "last friday"; else echo "yesterday"; fi)"
@pathikrit
pathikrit / Node.scala
Last active September 17, 2021 02:02
Reverse a LinkedList in Scala
case class Node(value: Int, next: Option[Node])
def reverse(node: Node, prev: Option[Node] = None): Node = {
val reversed = node.copy(next = prev)
node.next map {reverse(_, Some(reversed))} getOrElse reversed
}
/****************************************************************/
val one = Node(1,Some(Node(2,Some(Node(3,None)))))
println(s"$one\n${reverse(one)}")
@pathikrit
pathikrit / SudokuSolver.scala
Last active April 12, 2024 15:00
Sudoku Solver in Scala
val n = 9
val s = Math.sqrt(n).toInt
type Board = IndexedSeq[IndexedSeq[Int]]
def solve(board: Board, cell: Int = 0): Option[Board] = (cell%n, cell/n) match {
case (r, `n`) => Some(board)
case (r, c) if board(r)(c) > 0 => solve(board, cell + 1)
case (r, c) =>
def guess(x: Int) = solve(board.updated(r, board(r).updated(c, x)), cell + 1)
val used = board.indices.flatMap(i => Seq(board(r)(i), board(i)(c), board(s*(r/s) + i/s)(s*(c/s) + i%s)))
@pathikrit
pathikrit / weeker.scala
Last active August 29, 2015 14:17
Natural weekday chooser
val weekdays = IndexedSeq("Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat")
def solve(idx: Int*) = (idx foldLeft Seq.empty[(Int, Int)]) {
case (ts :+ ((start, end)), x) if x == end + 1 => ts :+ (start, x)
case (t, x) => t :+ (x, x)
} map {
case (start, end) if start == end => weekdays(start)
case (start, end) => s"${weekdays(start)}-${weekdays(end)}"
}