|
|
|
textb="What hath the Flying Spaghetti Monster wrought?" |
|
|
|
# Firstly, I finally realised after a bunch of testing that 1) "(8#2)" does something like this. |
|
# That is, the result of 8#2 is (2 2 2 2 2 2 2 2), which was totally not what I expected. |
|
def reshape(len,items) = [].fill(0...x) |
|
|
|
class Integer |
|
# For the special case of (x#y) where x is a positive integer, which is frankly the only one |
|
# I've looked at, we can do: |
|
# So now 4.reshape(2) returns [2 2 2 2] just like (4#2) in ngn/k |
|
def reshape(items) = Array(items)*self |
|
|
|
# Now we can do something somewhat like what I think "encode" is |
|
# actually doing - this can be golfed down, but anyway: |
|
# With this, "a".ord.encode(8.reshape(2)) returns [0,1,1,0,0,0,0,1], |
|
# equivalent to (8#2)\ "a" in ngn\k |
|
def encode(shape) |
|
q = self |
|
Array(shape).reverse.map do |m| |
|
val = q % m |
|
q = q / m |
|
val |
|
end.reverse |
|
end |
|
end |
|
|
|
# Now we can break Array too. |
|
class Array |
|
# First a minor concession to how Ruby methods even on the Array |
|
# class sees the focal point as the Array rather than the elements. |
|
# E.g. `self` in #map is the Array. If the focus is to be on applying the |
|
# same operation to each element, then it might be more convenient |
|
# if `self` was the element. With this, we can do ary.amap{reverse} |
|
# instead of ary.map{|e| e.reverse} or ary.map{ _1.reverse}. |
|
# To get closer to k, we'd have needed a postfix operator that we could |
|
# override to take a block, but unfortunately there are no overridable |
|
# postfix operators in Ruby. E.g. we can hackily make |
|
# ary.>>(some_dummy_value) {a block} work, but not even |
|
# ary >> (some_dummy_value) { a block} and certainly not |
|
# ary >> { a block } |
|
# |
|
def amap(&block) = map { _1.instance_eval(&block) } |
|
|
|
# If we could do a "nice" operator based map, we'd just have left it |
|
# at that. But to smooth over the lack of one, we can forward some |
|
# methods to amap: |
|
def encode(...) = amap{encode(...)} |
|
# ... with the caveat that I realised afterwards that this is almost certainly |
|
# horribly wrong, in that I think the k "encode" applies each step of the |
|
# above to each element of the array and returns a list of *columns* of modulos. |
|
# I haven't tried to replicate that, as it breaks my mind to think about |
|
# operating on it that way. That is, [65,70].encode(2.reshape(10)) |
|
# really ought to return [[6,7],[5,0]] to match the k, but it returns |
|
# [[6,5],[7,0]]. Maybe the k result will make more sense to me if I |
|
# take a look at how encode is implemented... |
|
|
|
def mreverse = amap{reverse} |
|
end |
|
|
|
# Now we can finally get back to the original, with the caveat that due to |
|
# the encode() difference, the "mreverse.flatten(1)" step is in actuality |
|
# working quite differently, in that for starters it's not transposing the arrays. |
|
# |
|
p textb.bytes.encode(8.reshape(2)).mreverse.flatten(1) |
|
|
|
# So to sum up: |
|
# |
|
# textb -> textb.bytes since strings and byte arrays are distinct in Ruby |
|
# (8#2) -> 8.reshape(2) |
|
# x\y -> y.encode(x) ... but transposed. |
|
# |x -> x.mreverse |
|
# ,/+x -> x.flatten(1) .. but really should be x.transpose.flatten(1) |
|
# |
|
# Of course with a hell of a lot of type combinations and other cases the k |
|
# verbs supports that I haven't tried to copy. |
(P.S: Don't actually go doing any of the horrible deeds I've done above in "real" Ruby code, or Matz and the developers who come after you will haunt you forever)