a moderately cursed dollcode implementation
recently, dollcode has become a thing frquently utilized by both this one's friends and other beings it observes. this is inconvenient, because many of them have written their own transcoders for the format, which can handle arbitrarily large numbers. at time of writing, the only two translators it has found (https://noe.sh/dollcode, https://999eagle.moe/dollcode) do not support nubbers larger than 64 bit integers. thusly, it can read few of its friends encoded strings.
the optimal solution to such a problem is probably either asking the sender of a given message what said message says, or asking them for their transcoder. this one being this one, it did neither: below, one may find a very good and very reasonable dollcode transcoder. one can tell it is good and reasonable because it contains the y combinator written in python lambda statements.
#!/usr/bin/env -S bash -c 'python3 -c "__import__(\"sys\").setrecursionlimit(2**31-1); exec(open(\"$(which dollcode)\").read())" "$@"' _
print((lambda d,ud,args:d(int(args[-1]))if'-n'in args else d(int(''.join(map(lambda x:str(hex(ord(x))[2::]),args[-1])),16))if'-a'in args else ud(args[-1])if'-dn'in args else(lambda h:''.join(map(lambda i:chr(int(h[i:i+2],16)),range(0,len(h),2))))(hex(ud(args[-1]))[2::])if'-da'in args else"0x6e6174\'s dollcode conversion tool\n\t-n: encode decimal number as dollcode\n\t-a: encode ascii string as dollcode\n\t-dn: decode dollcode as decimal\n\t-da:decode dollcode as ascii string")(lambda n:''.join(map(lambda n:''.join(['▖','▘','▌'][int(n)]),(lambda f:(lambda x:f(lambda y:x(x)(y)))(lambda x:f(lambda y:x(x)(y))))(lambda f:lambda n:(lambda x,y:str(f(x))+str(y))(*divmod(n-1,3))if n else'')(n))),lambda d:__import__('functools').reduce(lambda a,d:a*3+d,map(lambda x:{'▖':1,'▘':2,'▌':3}[x],d),0),__import__('sys').argv))
python is a very good programming language. this is observable in that it allows integers to have up to 4300 digits[1]
one may wonder: "why is the shebang like that?" the answer to such a question is that it did not want to set the recursion limit inside the actual program (it did not realize it would hit recursion limit issues until after it was done writing the program), and it decided it would be amusing to have a really weird shebang line.
bafflingly, this program works:
~ λ dollcode -a nat
▖▖▖▖▘▖▖▖▖▘▌▖▖▖▘it is very efficient:
~ λ dollcode -a "$(for i in {0..65536}; do echo -ne a; done)" >/dev/null & pid=$!; while kill -0 $pid 2>/dev/null; do pmap -x $pid | tail -n 1 | awk '{print ""$3/1024/1024 " GB"}'; sleep .5; done; wait $pid
[1] 11113
0.0247803 GB
0.261642 GB
0.625462 GB
0.982468 GB
1.34475 GB
1.69653 GB
2.07035 GB
2.43603 GB
2.80609 GB
3.16292 GB
3.53598 GB
3.90202 GB
4.27491 GB
4.63856 GB
5.02195 GB
5.37629 GB
5.75089 GB
6.13502 GB
6.48058 GB
6.85527 GB
7.24199 GB
7.6222 GB
7.96089 GB
8.33753 GB
8.719 GB
9.0616 GB
9.44017 GB
9.82001 GB
10.1397 GB
10.526 GB
10.9109 GB
11.0703 GB
10.956 GB
10.8826 GB
10.8184 GB
0 GB
[1] + done dollcode -a "$(for i in {0..65536}; do echo -ne a; done)" > /dev/null
the reason for this is interesting: looking at the the argument passed to the encode function, d, we can see it is an integer such that if the integer were to be represented in base 16 and split in to groups of two characters, each set of two characters would represent the byte that a character to be encoded is (ex: "nat" -> 0x6e6174 -> 6e, 61, 74 -> n, a, t).
after this process of encoding the string to be encoded as a potentially very very big integer, d defines two important internal functions: we will call them a and b. a takes an argument n, and returns the result of b called on both return values of divmod(n-1, 3) (those being the quotient and modulus of n by 3). the second function, b, takes two arguments: x, and y. it then returns str(f(x)) + str(y), where f is defined by the y combinator to be the first function, a.
since, before b can return, a((n-1)//3) must first return, which in turn calls b with different arguments, we fill the stack with approximately log3(n) frames containing numbers smaller than the initial (arbitrarily large) number. not accounting for the overhead of the memory taken by each function, the number of bytes it takes to store an array of [n, n//3, n//9... 1] is approximately 2.7*n^2. if we plug 65536 in to our equation, we get 2.7*65536^2 = 11596411699.2. dividing this by 1024^3, we get 10.8, which is very nearly the amount of memory, in gigabytes, this program uses to encode 65536 chars
it is also very fast:[2]
~ λ time dollcode -a "$(for i in {0..65536}; do echo -ne a; done)" >/dev/null
dollcode -a "$(for i in {0..65536}; do echo -ne a; done)" > /dev/null 14.31s user 7.79s system 99% cpu 22.202 total
comments
as an anti-bot measure, in order for $VIEWER's comment to be stored on the server, $VIEWER MUST enter the commit hash of the current deployment found in the bottom right of the page footer. failure to do so will result in the comment being disregarded.