type Matrix
= IndexedSeq
[IndexedSeq
[IndexedSeq
[Int
]]]
def initial
(folds
: Int
): Matrix
= { val sideLen
= math.
pow(2, folds /
2).
toInt (1 to sideLen * sideLen) map (Vector(_)) grouped sideLen toIndexedSeq
}
def leftFold
(m
: Matrix
): Matrix
= m map
{ r
=> val (a, b
) = r splitAt
(r.
size /
2) (a.reverse, b).zipped map (_.reverse ++ _)
}
def rightFold
(m
: Matrix
): Matrix
= m map
{ r
=> val (a, b
) = r splitAt
(r.
size /
2) (b.reverse, a).zipped map (_.reverse ++ _)
}
def topFold
(m
: Matrix
): Matrix
= leftFold
(m.
transpose).
transpose def bottomFold
(m
: Matrix
): Matrix
= rightFold
(m.
transpose).
transpose
def fold
(input
: String
): Seq
[Int
] = { def go
(in
: String, m
: Matrix
): Seq
[Int
] = in
match { case 'B' => bottomFold
(m
) })
}
go(input, initial(input.length))
}
def unfold
(input
: Seq
[Int
]): String
= { val m0
: Matrix
= Vector
(Vector
(Vector
(input
: _*))) val sideLen
= math.
sqrt(input.
length).
toInt
def go
(m
: Matrix, out
: String
): String
= { if (m.
length == sideLen
&& m.
head.
length == sideLen
) out.
reverse else if (tl.
head == tl.
last -
1) go
(leftUnfold
(m
), out +
'L') else if (tl.
head == tl.
last +
1) go
(rightUnfold
(m
), out +
'R') else if (tl.
head == tl.
last - sideLen
) go
(topUnfold
(m
), out +
'T') else if (tl.
head == tl.
last + sideLen
) go
(bottomUnfold
(m
), out +
'B') else sys.
error("no fold found " + m
) }
go(m0, "")
}
def leftUnfold
(m
: Matrix
): Matrix
= m map
{ r
=> val (a, b
) = r.
map(e
=> e.
splitAt(e.
size /
2)).
unzip a.map(_.reverse).reverse ++ b
}
def rightUnfold
(m
: Matrix
): Matrix
= m map
{ r
=> val (a, b
) = r.
map(e
=> e.
splitAt(e.
size /
2)).
unzip b ++ a.map(_.reverse).reverse
}
def topUnfold
(m
: Matrix
): Matrix
= leftUnfold
(m.
transpose).
transpose def bottomUnfold
(m
: Matrix
): Matrix
= rightUnfold
(m.
transpose).
transpose
def main
(args
: Array
[String
]) { println(fold("RBLT"))
println(unfold(fold("RBLT")))
}
}
b2JqZWN0IE1haW4gewoKdHlwZSBNYXRyaXggPSBJbmRleGVkU2VxW0luZGV4ZWRTZXFbSW5kZXhlZFNlcVtJbnRdXV0KCiAgZGVmIGluaXRpYWwoZm9sZHM6IEludCk6IE1hdHJpeCA9IHsKICAgIHZhbCBzaWRlTGVuID0gbWF0aC5wb3coMiwgZm9sZHMgLyAyKS50b0ludAogICAgKDEgdG8gc2lkZUxlbiAqIHNpZGVMZW4pIG1hcCAoVmVjdG9yKF8pKSBncm91cGVkIHNpZGVMZW4gdG9JbmRleGVkU2VxCiAgfQoKICBkZWYgbGVmdEZvbGQgKG06IE1hdHJpeCk6IE1hdHJpeCA9IG0gbWFwIHsgciA9PiAKICAgIHZhbCAoYSwgYikgPSByIHNwbGl0QXQgKHIuc2l6ZSAvIDIpIAogICAgKGEucmV2ZXJzZSwgYikuemlwcGVkIG1hcCAoXy5yZXZlcnNlICsrIF8pCiAgfQoKICBkZWYgcmlnaHRGb2xkKG06IE1hdHJpeCk6IE1hdHJpeCA9IG0gbWFwIHsgciA9PiAKICAgIHZhbCAoYSwgYikgPSByIHNwbGl0QXQgKHIuc2l6ZSAvIDIpIAogICAgKGIucmV2ZXJzZSwgYSkuemlwcGVkIG1hcCAoXy5yZXZlcnNlICsrIF8pCiAgfQoKICBkZWYgdG9wRm9sZCAgIChtOiBNYXRyaXgpOiBNYXRyaXggPSBsZWZ0Rm9sZChtLnRyYW5zcG9zZSkudHJhbnNwb3NlCiAgZGVmIGJvdHRvbUZvbGQobTogTWF0cml4KTogTWF0cml4ID0gcmlnaHRGb2xkKG0udHJhbnNwb3NlKS50cmFuc3Bvc2UKCiAgZGVmIGZvbGQoaW5wdXQ6IFN0cmluZyk6IFNlcVtJbnRdID0gewogICAgZGVmIGdvKGluOiBTdHJpbmcsIG06IE1hdHJpeCk6IFNlcVtJbnRdID0gaW4gbWF0Y2ggewogICAgICBjYXNlICIiID0+IG0oMCkoMCkKICAgICAgY2FzZSBzICA9PiBnbyhzLnRhaWwsIHMuaGVhZCBtYXRjaCB7CiAgICAgICAgY2FzZSAnTCcgPT4gbGVmdEZvbGQobSkKICAgICAgICBjYXNlICdSJyA9PiByaWdodEZvbGQobSkKICAgICAgICBjYXNlICdUJyA9PiB0b3BGb2xkKG0pCiAgICAgICAgY2FzZSAnQicgPT4gYm90dG9tRm9sZChtKQogICAgICB9KQogICAgfQogICAgZ28oaW5wdXQsIGluaXRpYWwoaW5wdXQubGVuZ3RoKSkKICB9CgpkZWYgdW5mb2xkKGlucHV0OiBTZXFbSW50XSk6IFN0cmluZyA9IHsgCiAgICB2YWwgbTA6IE1hdHJpeCA9IFZlY3RvcihWZWN0b3IoVmVjdG9yKGlucHV0OiBfKikpKQogICAgdmFsIHNpZGVMZW4gPSBtYXRoLnNxcnQoaW5wdXQubGVuZ3RoKS50b0ludCAKCiAgICBkZWYgZ28obTogTWF0cml4LCBvdXQ6IFN0cmluZyk6IFN0cmluZyA9IHsKICAgICAgdmFsIHRsID0gbS5oZWFkLmhlYWQKICAgICAgaWYgKG0ubGVuZ3RoID09IHNpZGVMZW4gJiYgbS5oZWFkLmxlbmd0aCA9PSBzaWRlTGVuKSBvdXQucmV2ZXJzZQogICAgICBlbHNlIGlmICh0bC5oZWFkID09IHRsLmxhc3QgLSAxKSAgICAgICBnbyhsZWZ0VW5mb2xkKG0pLCAgIG91dCArICdMJykKICAgICAgZWxzZSBpZiAodGwuaGVhZCA9PSB0bC5sYXN0ICsgMSkgICAgICAgZ28ocmlnaHRVbmZvbGQobSksICBvdXQgKyAnUicpCiAgICAgIGVsc2UgaWYgKHRsLmhlYWQgPT0gdGwubGFzdCAtIHNpZGVMZW4pIGdvKHRvcFVuZm9sZChtKSwgICAgb3V0ICsgJ1QnKQogICAgICBlbHNlIGlmICh0bC5oZWFkID09IHRsLmxhc3QgKyBzaWRlTGVuKSBnbyhib3R0b21VbmZvbGQobSksIG91dCArICdCJykKICAgICAgZWxzZSBzeXMuZXJyb3IoIm5vIGZvbGQgZm91bmQgIiArIG0pIAogICAgfQogICAgZ28obTAsICIiKQogIH0gICAgCgogIGRlZiBsZWZ0VW5mb2xkIChtOiBNYXRyaXgpOiBNYXRyaXggPSBtIG1hcCB7IHIgPT4KICAgIHZhbCAoYSwgYikgPSByLm1hcChlID0+IGUuc3BsaXRBdChlLnNpemUgLyAyKSkudW56aXAKICAgIGEubWFwKF8ucmV2ZXJzZSkucmV2ZXJzZSArKyBiCiAgfQoKICBkZWYgcmlnaHRVbmZvbGQobTogTWF0cml4KTogTWF0cml4ID0gbSBtYXAgeyByID0+CiAgICB2YWwgKGEsIGIpID0gci5tYXAoZSA9PiBlLnNwbGl0QXQoZS5zaXplIC8gMikpLnVuemlwCiAgICBiICsrIGEubWFwKF8ucmV2ZXJzZSkucmV2ZXJzZQogIH0KCiAgZGVmIHRvcFVuZm9sZCAgIChtOiBNYXRyaXgpOiBNYXRyaXggPSBsZWZ0VW5mb2xkIChtLnRyYW5zcG9zZSkudHJhbnNwb3NlCiAgZGVmIGJvdHRvbVVuZm9sZChtOiBNYXRyaXgpOiBNYXRyaXggPSByaWdodFVuZm9sZChtLnRyYW5zcG9zZSkudHJhbnNwb3NlCgogIGRlZiBtYWluKGFyZ3M6IEFycmF5W1N0cmluZ10pIHsKICAgIHByaW50bG4oZm9sZCgiUkJMVCIpKQogICAgcHJpbnRsbih1bmZvbGQoZm9sZCgiUkJMVCIpKSkKICB9Cn0=
Vector(2, 3, 15, 14, 13, 16, 4, 1, 5, 8, 12, 9, 10, 11, 7, 6)