Slightly over-engineered solution in Scala.
object Hamelin { trait Character case object Piper extends Character case object Left extends Character case object Right extends Character type Town = Seq[Character] def of (raw: String): Town = { @tailrec def iter (chars: Seq[Char], result: Town = List()): Town = chars match { case Nil => result case 'P' :: xs => iter(xs, result :+ Piper) case 'O' :: '~' :: xs => iter(xs, result :+ Left) case '~' :: 'O' :: xs => iter(xs, result :+ Right) case _ :: xs => iter(xs, result) } iter(raw.toList) } def countDeafRats (town: Town): Int = { val (result, _) = town.foldLeft((0, false)) { case ((x, _), Piper) => (x, true) case ((x, false), Left) => (x + 1, false) case ((x, true), Right) => (x + 1, true) case (x, _) => x } result } val solve = countDeafRats _ compose of _ }
And the tests:
class HamelinTest extends FunSuite { trait Input { val raw1 = "~O~O~O~O P" val raw2 = "P O~ O~ ~O O~" val raw3 = "~O~O~O~OP~O~OO~" } trait Parsed { val parsed1 = List(Right, Right, Right, Right, Piper) val parsed2 = List(Piper, Left, Left, Right, Left) val parsed3 = List(Right, Right, Right, Right, Piper, Right, Right, Left) } test("of") { new Input with Parsed { assert(of(raw1) == parsed1) assert(of(raw2) == parsed2) assert(of(raw3) == parsed3) } } test("countDeafRats") { new Parsed { assert(countDeafRats(parsed1) == 0) assert(countDeafRats(parsed2) == 1) assert(countDeafRats(parsed3) == 2) } } test("solve") { new Input { assert(solve(raw1) == 0) assert(solve(raw2) == 1) assert(solve(raw3) == 2) } } }
Are you sure you want to hide this comment? It will become hidden in your post, but will still be visible via the comment's permalink.
Hide child comments as well
Confirm
For further actions, you may consider blocking this person and/or reporting abuse
We're a place where coders share, stay up-to-date and grow their careers.
Slightly over-engineered solution in Scala.
And the tests: