esmpmpmeimtmemqmememqicelic
esmpmpmeimememqmlmtmemoc
esmpmpmeimememqmtmtmtmtmeic
esmpmpmeimememqmtmtmtmtmeic
esmpmpmeimeiscic
esmpmpmeimemeimfsic
esmpmpmeisciscimqmtmemeic
esmpmpmeiscimlmqmqmemeic
esmpmpmeimemomqmqmemeic
esmpmpmeisciscimfsimqic
esmpmpmeimeiscic
esmpmpmeisciscimfsimqic
esmpmpmeimemomqmemqmemtmemoc
esmpmpmeiscic
esmpmpmeimemomeimqmeic
esmpmpmeimemeimqmlmtmeic
esmpmpmeimtmtmqmemtmtmeic
esmpmpmeimemomqmqmtmeic
esmpmpmeimemqmqmemeic
esmpmpmeiscimlmqmqmemeic
esmpmpmeiscimqmtmtmtmqmemeic
esmpmpmeimeimemtmqmemeic
esmpmpmeimeiscimlmlmtmlmtic
esmpmpmeimemeimqmlmtmeic
~~
All linefeeds are for cosmetic purposes and can be removed without affecting the program.
Try it online!
Explanation
After Lynn removed {|}
from the list of allowed characters, I had to try something new. It turns out we can still construct arbitrary strings and evaluate them as code.
First, we need to get some value onto the stack. The only available built-ins that push something without popping something else first (and without reading the input) are es
, ea
and et
. I'm sure you could start from all of these one way or another, but I went with es
which pushes the current timestamp. Since I didn't want to make any assumptions about its actual value, I test its primality with mp
(which gives 0
and 1
) and test that value's primality again to ensure I've got a 0
on the stack. A 1
will be more useful, so we compute exp(0)
with me
and turn it into an integer with i
. So all the numbers start with:
esmpmpmei
Now we've got a whole bunch of unary maths operators to work with:
i int(x) (floor for positive numbers, ceiling for negative)
me exp(x)
ml ln(x)
mq sqrt(x)
mo round(x)
mt tan(x)
We can also combine a few built-ins for more elaborate functions of x
:
sci Extract first digit of x and add 48 (convert to string, convert
to character, convert to integer).
ceui Convert to character, convert to upper case, convert to integer.
celi Convert to character, convert to lower case, convert to integer.
mfsi Get a sorted list of prime factors of x and concatenate them into
a new number.
mfseei Get a sorted list of prime factors, interleave it with 1,2,3,..., and
concatenate the result into a new number.
Using these, we can obtain any number in 0 <= x < 128
(and many others) in less than 10 steps from 1
. I'm sure a much smaller subset of these commands would also suffice. I've written a small Mathematica program, to determine all of these snippets (it's not very readable, sorry):
codes = SortBy[
Select[Nest[Select[DeleteDuplicatesBy[SortBy[Join @@ (Through[{
List,
If[1 <= # < 50, {Exp@#, #2 <> "me"}, Nothing] &,
If[# >= 1, {Log@#, #2 <> "ml"}, Nothing] &,
If[# > 1, {Sqrt@#, #2 <> "mq"}, Nothing] &,
{If[# > 0, Floor@#, Ceiling@#], #2 <> "i"} &,
{Floor[# + 1/2], #2 <> "mo"} &,
{Tan@#, #2 <> "mt"} &,
If[NumberQ@# && # >= 0, {First@
ToCharacterCode@ToString@#, #2 <> "sci"},
Nothing] &,
If[IntegerQ@# &&
32 < # < 65536, {First@
ToCharacterCode@
ToUpperCase@FromCharacterCode@#, #2 <> "ceui"},
Nothing] &,
If[IntegerQ@# &&
32 < # < 65536, {First@
ToCharacterCode@
ToLowerCase@FromCharacterCode@#, #2 <> "celi"},
Nothing] &,
If[IntegerQ@# && # > 0, ## & @@ {
{FromDigits[
"" <> (ToString /@ (f =
Join @@ Table @@@ FactorInteger@#))], #2 <>
"mfsi"},
{FromDigits[
"" <> (ToString /@
MapIndexed[## & @@ {#2[[1]] - 1, #} &, f])], #2 <>
"mfeesi"}
}, Nothing] &
}@##] &) @@@ #, StringLength@*Last],
First], #[[1]] < 1000000 &] &, {{1, "esmpmpmei"}}, 9],
IntegerQ@# && 0 <= # < 128 &@*First], First]
With that, we can simply push an arbitrary list of character codes, converting each of them to a character with c
afterwards. Once we've pushed the entire code we want to execute, we push 95
(]
). We eval that one with ~
to wrap all the others in a string, and then we eval that string with ~
.
The actual code run at the end of the program is again:
ri__2#,:)/2/[1W]f.%:~<p
See my previous solution for an explanation.
Uh, the way
¦
works kills me every time, I tried this yesterday but withṚ
rather thanU
and decided theḤ
was not working out. – Jonathan Allan – 2017-03-09T12:25:42.720Nice, I nearly had it but got stuck at selecting every other element as well.
F
was a great idea, – ETHproductions – 2017-03-09T12:38:12.100My original code is pretty much identical to this. I just used
J
instead ofF
. – Dennis – 2017-03-09T12:39:18.503@Dennis Oh,
J
... I had tried withLR
but couldn't get it under 11 bytes – ETHproductions – 2017-03-09T12:41:06.273