--- a/progs/lecture3.scala Fri Nov 22 17:01:55 2019 +0000
+++ b/progs/lecture3.scala Tue Nov 26 01:22:36 2019 +0000
@@ -300,215 +300,6 @@
// User-defined Datatypes and Pattern Matching
//=============================================
-// trees
-
-
-
-// expressions
-
-sealed abstract class Exp
-case class N(n: Int) extends Exp // for numbers
-case class Plus(e1: Exp, e2: Exp) extends Exp
-case class Times(e1: Exp, e2: Exp) extends Exp
-
-def string(e: Exp) : String = e match {
- case N(n) => s"$n"
- case Plus(e1, e2) => s"(${string(e1)} + ${string(e2)})"
- case Times(e1, e2) => s"(${string(e1)} * ${string(e2)})"
-}
-
-val e = Plus(N(9), Times(N(3), N(4)))
-println(string(e))
-
-def eval(e: Exp) : Int = e match {
- case N(n) => n
- case Plus(e1, e2) => eval(e1) + eval(e2)
- case Times(e1, e2) => eval(e1) * eval(e2)
-}
-
-println(eval(e))
-
-def simp(e: Exp) : Exp = e match {
- case N(n) => N(n)
- case Plus(e1, e2) => (simp(e1), simp(e2)) match {
- case (N(0), e2s) => e2s
- case (e1s, N(0)) => e1s
- case (e1s, e2s) => Plus(e1s, e2s)
- }
- case Times(e1, e2) => (simp(e1), simp(e2)) match {
- case (N(0), _) => N(0)
- case (_, N(0)) => N(0)
- case (N(1), e2s) => e2s
- case (e1s, N(1)) => e1s
- case (e1s, e2s) => Times(e1s, e2s)
- }
-}
-
-
-val e2 = Times(Plus(N(0), N(1)), Plus(N(0), N(9)))
-println(string(e2))
-println(string(simp(e2)))
-
-
-// Tokens and Reverse Polish Notation
-sealed abstract class Token
-case class T(n: Int) extends Token
-case object PL extends Token
-case object TI extends Token
-
-def rp(e: Exp) : List[Token] = e match {
- case N(n) => List(T(n))
- case Plus(e1, e2) => rp(e1) ::: rp(e2) ::: List(PL)
- case Times(e1, e2) => rp(e1) ::: rp(e2) ::: List(TI)
-}
-println(string(e2))
-println(rp(e2))
-
-def comp(ls: List[Token], st: List[Int]) : Int = (ls, st) match {
- case (Nil, st) => st.head
- case (T(n)::rest, st) => comp(rest, n::st)
- case (PL::rest, n1::n2::st) => comp(rest, n1 + n2::st)
- case (TI::rest, n1::n2::st) => comp(rest, n1 * n2::st)
-}
-
-comp(rp(e), Nil)
-
-def proc(s: String) : Token = s match {
- case "+" => PL
- case "*" => TI
- case _ => T(s.toInt)
-}
-
-comp("1 2 + 4 * 5 + 3 +".split(" ").toList.map(proc), Nil)
-
-
-
-
-// Sudoku
-//========
-
-// THE POINT OF THIS CODE IS NOT TO BE SUPER
-// EFFICIENT AND FAST, just explaining exhaustive
-// depth-first search
-
-
-val game0 = """.14.6.3..
- |62...4..9
- |.8..5.6..
- |.6.2....3
- |.7..1..5.
- |5....9.6.
- |..6.2..3.
- |1..5...92
- |..7.9.41.""".stripMargin.replaceAll("\\n", "")
-
-type Pos = (Int, Int)
-val EmptyValue = '.'
-val MaxValue = 9
-
-val allValues = "123456789".toList
-val indexes = (0 to 8).toList
-
-
-def empty(game: String) = game.indexOf(EmptyValue)
-def isDone(game: String) = empty(game) == -1
-def emptyPosition(game: String) =
- (empty(game) % MaxValue, empty(game) / MaxValue)
-
-
-def get_row(game: String, y: Int) =
- indexes.map(col => game(y * MaxValue + col))
-def get_col(game: String, x: Int) =
- indexes.map(row => game(x + row * MaxValue))
-
-def get_box(game: String, pos: Pos): List[Char] = {
- def base(p: Int): Int = (p / 3) * 3
- val x0 = base(pos._1)
- val y0 = base(pos._2)
- val ys = (y0 until y0 + 3).toList
- (x0 until x0 + 3).toList.flatMap(x => ys.map(y => game(x + y * MaxValue)))
-}
-
-//get_row(game0, 0)
-//get_row(game0, 1)
-//get_col(game0, 0)
-//get_box(game0, (3, 1))
-
-
-// this is not mutable!!
-def update(game: String, pos: Int, value: Char): String =
- game.updated(pos, value)
-
-def toAvoid(game: String, pos: Pos): List[Char] =
- (get_col(game, pos._1) ++ get_row(game, pos._2) ++ get_box(game, pos))
-
-def candidates(game: String, pos: Pos): List[Char] =
- allValues.diff(toAvoid(game, pos))
-
-//candidates(game0, (0,0))
-
-def pretty(game: String): String =
- "\n" + (game.sliding(MaxValue, MaxValue).mkString("\n"))
-
-
-def search(game: String): List[String] = {
- if (isDone(game)) List(game)
- else {
- val cs = candidates(game, emptyPosition(game))
- cs.map(c => search(update(game, empty(game), c))).toList.flatten
- }
-}
-
-search(game0).map(pretty)
-
-val game1 = """23.915...
- |...2..54.
- |6.7......
- |..1.....9
- |89.5.3.17
- |5.....6..
- |......9.5
- |.16..7...
- |...329..1""".stripMargin.replaceAll("\\n", "")
-
-
-// game that is in the hard category
-val game2 = """8........
- |..36.....
- |.7..9.2..
- |.5...7...
- |....457..
- |...1...3.
- |..1....68
- |..85...1.
- |.9....4..""".stripMargin.replaceAll("\\n", "")
-
-// game with multiple solutions
-val game3 = """.8...9743
- |.5...8.1.
- |.1.......
- |8....5...
- |...8.4...
- |...3....6
- |.......7.
- |.3.5...8.
- |9724...5.""".stripMargin.replaceAll("\\n", "")
-
-
-search(game1).map(pretty)
-search(game3).map(pretty)
-search(game2).map(pretty)
-
-// for measuring time
-def time_needed[T](i: Int, code: => T) = {
- val start = System.nanoTime()
- for (j <- 1 to i) code
- val end = System.nanoTime()
- ((end - start) / 1.0e9) + " secs"
-}
-
-time_needed(1, search(game2))
-