Skip to content

Instantly share code, notes, and snippets.

@gkm2164
Last active February 28, 2021 20:53
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save gkm2164/8e5ddf670cc43abb745863586c53bf74 to your computer and use it in GitHub Desktop.
Save gkm2164/8e5ddf670cc43abb745863586c53bf74 to your computer and use it in GitHub Desktop.
Scala 3 - Trie
import scala.io.{Source, StdIn}
object Main {
type Trie[A] = A match {
case Nothing => Map[A, Nothing]
case A => Map[A, Trie[A]]
}
def toTrie(names: List[String]): Trie[Char] =
names.filterNot(_.isEmpty)
.groupBy(_.head)
.view
.mapValues(x => toTrie(x.map(_.tail)))
.toMap
extension (self: Trie[Char]) {
def search(keyword: List[Char]): Boolean = keyword match {
case Nil => true
case h :: t => self match {
case map: Map[Char, Trie[Char]] if map.contains(h) => map(h).search(t)
case _ => false
}
}
def insert(keyword: List[Char]): Trie[Char] = keyword match {
case Nil => self
case h :: t => self match {
case map: Map[Char, Trie[Char]] if map.contains(h) =>
map.updated(h, map(h).insert(t))
case map: Map[Char, Trie[Char]] =>
map.updated(h, toTrie(List(t.mkString(""))))
}
}
def isEmpty: Boolean = self == Map()
def delete(keyword: List[Char]): Trie[Char] = keyword match {
case Nil => self
case h :: t => self match {
case map: Map[Char, Trie[Char]] if map.contains(h) && map(h).isEmpty => map.removed(h)
case map: Map[Char, Trie[Char]] if map.contains(h) =>
val deleted = map(h).delete(t)
if (deleted.isEmpty) {
map.removed(h)
} else {
map.updated(h, deleted)
}
case map: Map[Char, Trie[Char]] =>
println("doing nothing")
self
}
}
}
def main(args: Array[String]): Unit = {
val words = List()
val trie = toTrie(words)
println(trie)
var nextTrie = trie
val deleteCommand = "del (.+)".r
while (true) {
print("> ")
StdIn.readLine() match {
case "" =>
println("Can't be empty string")
case "quit" =>
println("Finish")
System.exit(1)
case "print" =>
println(nextTrie)
case deleteCommand(str) =>
nextTrie = nextTrie.delete(str.toList)
case str if nextTrie.search(str.toList) =>
println("Found words")
case str =>
println("No word found, try next time")
nextTrie = nextTrie.insert(str.toList)
}
System.out.flush()
}
}
def msg = "I was compiled by dotty :)"
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment