fork download
  1. object Main {
  2.  
  3. type Matrix = IndexedSeq[IndexedSeq[IndexedSeq[Int]]]
  4.  
  5. def initial(folds: Int): Matrix = {
  6. val sideLen = math.pow(2, folds / 2).toInt
  7. (1 to sideLen * sideLen) map (Vector(_)) grouped sideLen toIndexedSeq
  8. }
  9.  
  10. def leftFold (m: Matrix): Matrix = m map { r =>
  11. val (a, b) = r splitAt (r.size / 2)
  12. (a.reverse, b).zipped map (_.reverse ++ _)
  13. }
  14.  
  15. def rightFold(m: Matrix): Matrix = m map { r =>
  16. val (a, b) = r splitAt (r.size / 2)
  17. (b.reverse, a).zipped map (_.reverse ++ _)
  18. }
  19.  
  20. def topFold (m: Matrix): Matrix = leftFold(m.transpose).transpose
  21. def bottomFold(m: Matrix): Matrix = rightFold(m.transpose).transpose
  22.  
  23. def fold(input: String): Seq[Int] = {
  24. def go(in: String, m: Matrix): Seq[Int] = in match {
  25. case "" => m(0)(0)
  26. case s => go(s.tail, s.head match {
  27. case 'L' => leftFold(m)
  28. case 'R' => rightFold(m)
  29. case 'T' => topFold(m)
  30. case 'B' => bottomFold(m)
  31. })
  32. }
  33. go(input, initial(input.length))
  34. }
  35.  
  36. def unfold(input: Seq[Int]): String = {
  37. val m0: Matrix = Vector(Vector(Vector(input: _*)))
  38. val sideLen = math.sqrt(input.length).toInt
  39.  
  40. def go(m: Matrix, out: String): String = {
  41. val tl = m.head.head
  42. if (m.length == sideLen && m.head.length == sideLen) out.reverse
  43. else if (tl.head == tl.last - 1) go(leftUnfold(m), out + 'L')
  44. else if (tl.head == tl.last + 1) go(rightUnfold(m), out + 'R')
  45. else if (tl.head == tl.last - sideLen) go(topUnfold(m), out + 'T')
  46. else if (tl.head == tl.last + sideLen) go(bottomUnfold(m), out + 'B')
  47. else sys.error("no fold found " + m)
  48. }
  49. go(m0, "")
  50. }
  51.  
  52. def leftUnfold (m: Matrix): Matrix = m map { r =>
  53. val (a, b) = r.map(e => e.splitAt(e.size / 2)).unzip
  54. a.map(_.reverse).reverse ++ b
  55. }
  56.  
  57. def rightUnfold(m: Matrix): Matrix = m map { r =>
  58. val (a, b) = r.map(e => e.splitAt(e.size / 2)).unzip
  59. b ++ a.map(_.reverse).reverse
  60. }
  61.  
  62. def topUnfold (m: Matrix): Matrix = leftUnfold (m.transpose).transpose
  63. def bottomUnfold(m: Matrix): Matrix = rightUnfold(m.transpose).transpose
  64.  
  65. def main(args: Array[String]) {
  66. println(fold("RBLT"))
  67. println(unfold(fold("RBLT")))
  68. }
  69. }
Runtime error #stdin #stdout 0.33s 247552KB
stdin
Standard input is empty
stdout
Vector(2, 3, 15, 14, 13, 16, 4, 1, 5, 8, 12, 9, 10, 11, 7, 6)