fork download
import scala.collection._

class Bag[E] private (val items: Map[E, Int]) {
  def isEmpty = items.isEmpty
  def view = items.keys
  def -(item: E) = new Bag[E](items(item) match {
    case 1 => items - item
    case n => items.updated(item, n - 1)
  })
}

object Bag {
  def apply[E](items: Traversable[E]): Bag[E] = {
    val itemCounts = mutable.HashMap.empty[E, Int].withDefaultValue(0)
    items.foreach(itemCounts(_) += 1)
    new Bag[E](itemCounts)
  }
}

object Main extends App {
  type Solution = Option[Seq[(String, String)]]

  def solve(items: Bag[String], anagrams: String, matches: Solution = None): Solution =
    if (items.isEmpty) matches
    else (for {
      item <- items.view
      (label, rest) = anagrams.splitAt(item.length)
      if item == label.sorted
      newMatches = Option(matches.getOrElse(immutable.Queue.empty) :+ (item, label))
      solution <- solve(items - item, rest, newMatches)
    } yield solution).headOption

  val items = readLine().split(" ")
  val anagrams = readLine()

  val sortedItems = mutable.Buffer.empty[String]
  val itemOrderRestorator = mutable.Map.empty[String, mutable.Queue[String]]

  for (item <- items) {
    val sorted = item.sorted
    sortedItems += sorted
    itemOrderRestorator.getOrElseUpdate(sorted, new mutable.Queue).enqueue(item)
  }

  solve(Bag(sortedItems), anagrams).map(_.unzip) match {
    case None => println("Ne fart")
    case Some((items, labels)) =>
      println(labels.mkString(" "))
      items.foreach(s => print(itemOrderRestorator(s).dequeue() + " "))
  }
}
Success #stdin #stdout 0.44s 382080KB
stdin
odin dva odindva
odindvadvaodin
stdout
odindva dva odin
odindva dva odin