Knight (with ASCII
), score 55 4
AE(any whitespace)+1AE+1
Using the proposed ASCII
function, we can now assemble arbitrary strings using +A(whitespace)1
. However, since we know that all Knight programs will always be printable ASCII, tab, CR, or LF, we can always assume codepoints will be >= 9.
Therefore, to avoid whitespace, we can use EVAL.
+
can be used to both concatenate strings and do addition, A
converts an integer to a string with its ASCII value, and 1
is used to add a bunch of 1's together to get any non-zero integer (strings with null bytes are illegal in Knight).
For example, if we wanted a string with a tab (ASCII 9) followed by a newline (ASCII 10) we would do this:
+ A ++++++++ 1 1 1 1 1 1 1 1 1
A +++++++++ 1 1 1 1 1 1 1 1 1 1+A++++++++E1E1E1E1E1E1E1E1E1A+++++++++E1E1E1E1E1E1E1E1E1E1
Now, we can simply encode a Knight program using this method and evaluate it with E
.
Here is the conversion program in Knight. It adds a leading newline and leaves out the trailing newline, but otherwise encodes a functionally equivalent program.
It usesThis could be further optimized if we used \n111
for its whitespaceand 11
, but this isn't code-golf despite the question being tagged it...
# start with empty string
; = acc ""
# slurp the entirety of stdin and concatenate with newlines
; WHILE(= tmp PROMPT)
: = acc + + acc ASCII(10) tmp
# First output the E to evaluate the next expression
# note: #"# is just to fix syntax highlighting
; OUTPUT("E""E\") #"#
# Now output length - 1 `+`'s to build the string one ASCII at a time
; OUTPUT(+ * "+" (- LENGTH(acc) 1) "\") #"#
# Now loop through the string
: WHILE(acc)
# Grab the ASCII value of the first character in acc
; = char ASCII(acc)
# snip off the first character of acc
; = acc SUBSTITUTE(acc 0 1 "")
# output the ASCII keyword
; OUTPUT("A""A\") #"#
# output n - 1 pluses
; OUTPUT(*+* "+" (- char 1) "\") #"#
# output n ones
: OUTPUT(*(++*"E1" "1"char ASCII(10)"\") char)#"#