Vyxal, 732 bytes, score 0
uTuJuJnJnJnJnJuTuJuJnJuJuTuJnJuJnJnJuTuJnJnJuJuJuJuTuJnJuJnJuJuTuJnJuJuJuJuJuTuJnJuJuJnJuTuJuJuJnJuJuTuJuJuJuTuJnJuJnJnJuTuJnJuJnJuJuTuJnJuJnJuJuTuJnJuTuJnJuJnJuJuTuJuJnJuJuJuTuJnJuJnJuTuJuJnJuJuJuTuJnJnJnJuTuJuJuJuJuTuJuJnJnJnJuTuJnJuJuTuJnJuJnJuTuJuJnJuJnJuTuJnJuJuTuJnJnJnJuJnJuTuJnJnJuJuJuTuJnJnJnJuJnJuTuJnJuJnJuJuTuJuJuJuTuJuJnJuJuTuJnJuJuTuJnJnJnJuJnJuTuJuJuJuTuJnJnJnJuJnJuTuJnJnJuJuJuTuJnJnJnJuJnJuTuJuJuJuTuJnJnJuJuJuTuJnJuJnJuJuTuJnJnJnJuJuJuTuJuJuJnJuJuTuJuJuJuJuTuJnJnJuJuJuTuJuJuJuTuJuJnJuJuTuJnJuJuTuJnJnJnJuJnJuTuJnJnJuJuJuTuJnJnJnJuJnJuTuJuJuJuTuJnJnJuJuJuTuJnJnJnJuJuJuTuJuJuJuJuTuJnJuJnJuJuTuJnJnJnJuTuJuJuJuJuTuJnJuJuTuJnJuJnJnJuTuJnJnJnJuJnJuTuJnJnJuJWnuNvVwDhuvvcvBkBipyfkAfItIvhnfIhItIhtvJDpthnfItIhtJpvipfuIj
Try it Online!
This hurt my brain.
The standard way to do this sort of restricted quine, using only the ASCII letters, is to:
- Push a list of numbers to the stack, encoding the rest of the code
- Have the rest of the code reconstruct the code pushing those numbers, and itself
However, it's a bit more complicated than that. Vyxal's set of built-in constants includes kL
, the concatenation of the lowercase and uppercase alphabets, so we can just index each number into that to recover the rest of the source code, but actually generating those numbers with this builtin set is the problem. The numbers need to be encoded in a way that:
- Ideally, is as compact as possible
- Can be easily decoded using the limited set of builtins available, which is not particularly powerful.
We have no access to string, number or list literals, or pretty much any form of arithmetic, but we can still construct lists with the J
and p
builtins, which respectively append/prepend two values. We also have the single-char constants u
and n
, which push -1
and the lowercase alphabet respectively (don't ask).
One way to encode numbers would be to map each number to that many copies of -1
- e.g. 5
-> [-1, -1, -1, -1, -1]
, which can be generated with u uJ uJ uJ uJ
- push -1
, and append another four -1
s. However, part of the program needs to be able to take this array and reconstruct the code that generated it, and this is somewhat annoying to do with this method as the first u
is different: we'd need to to remove the first -1
, replace all the rest with uJ
, then prepend a u
. A smarter way to do this would be to use e.g. [0, -1, -1, -1, -1]
, and map 0
to [some code generating a 0] and -1
to uJ
(append -1).
However, that approach still requires amounts of code proportional to each number included. Instead, we can encode each number in binary, and decode it with the B
builtin. The approach I ended up going with was mapping 0
to the lowercase alphabet and 1
to -1
, then prepending -3
, which can be created with uT
(T is triple). This results in a list like [-3, -1, alphabet, alphabet, -1]
encoding 0b1001
== 9
, and to reconstruct it we map -3
to uT
, -1
to uJ
and alphabet
to nJ
. This can be accomplished by replacing (V
) alphabet
with 1
and indexing into the list ["uT", "nJ", "uJ"]
.
Constructing this list is somewhat annoying. We have access to the builtins kA
(uppercase alphabet) and n
(lowercase alphabet); I
, which cuts a list of characters into two pieces, and h
and t
which get the first and last items of a list respectively (along with J
and p
from before to concatenate). With this, it's not too hard to construct
kAfI # Split uppercase alphabet in half - ["ABCDEFGHIJKLM", "NOPQRSTUVWXYZ"]
tI # Get the second half and halve it - ["NOPQRST","UVWXYZ"]
vh # Get the first item of each - ["N","U"]
nfIhI # first half of lowercase alphabet in half - ["abcdefg","hijklm"]
tIht # last of first half of second item - "j"
vJ # append to each - ["Nj","Uj"]
Dpth # Grab the "U" from the previous
nfItIht # Last char of first half of second half of lowercase alphabet - "t"
Jp # Append to the U and prepend - ["Ut","Nj","Uj"]
The final piece of the puzzle is the case swapping. While Vyxal's case swap builtin N
is available, it's shorter to just construct the data code flipped and also flip the decoding. Then, it's just a matter of decoding everything:
WnuNvVwDhuvvcvBkBipyfk...pvipfuIj
W # Wrap all pushed data into an array
vV # Over each, replace
nuN # alphabet with -1
uvvc # Check if each is -1 - -1 -> 1, alphabet/-3 -> 0
vB # Convert each from binary
kBi # Index each into uppercase+lowercase alphabet
wDh py # Swap to another copy of the data (no stack manip = pain)
k...p # Construct ["Ut","Nj","Uj"] (from befor)
f vi # and index each value into that
pf # Prepend to the original data and flatten
uIj # And concatenate
invert the case of as many ascii characters
Does that mean that if a unicode character has its case inverted complement, we aren't expected to count that unicode character if we invert it in our output? \$\endgroup\$Gol><>
wins over><>
). OP didn't have access to the sandbox when they wrote the challenge (see OP's first comment). \$\endgroup\$