# Print X without X (robber's thread)

This is the robber's thread of a challenge. You can view the cop's thread here

A pretty common beginner style question is to print some string, but, there's a catch!, you need to do it without using any of the characters in the string itself!

For this challenge we will find out who is the best at printing X without X. There are two threads to this, a cop's thread and a robber's thread.

In the cop's thread users will choose a language (which we will call Y) and a string (which we will call X) and write a program in language Y which takes no input and outputs X without using any of the characters in X. The cop will then post both X and Y without revealing the program they have written.

Robbers will be select cop answers and write programs in language Y which take no input and output X. They will post these "cracks" as answers in this thread. A crack need only work not be the intended solution.

Once a cop's answer is one week old, so long as it has not been cracked, the cop may reveal their program and mark it as "safe". Safe answers can no longer be cracked

Robbers will be scored by the total number of successful cracks with more cracks being better.

• Congrats on an excellent challenge with high 'replay value'. I've had a lot of fun participating on both sides, digging into a couple of languages for the first time along the way. Aug 20, 2020 at 3:22

# Python 3, cracks @nthistle's answer

𝓹𝓻𝓲𝓷𝓽(𝓬𝓱𝓻(97)+𝓬𝓱𝓻(98)+𝓬𝓱𝓻(99)+𝓬𝓱𝓻(100)+𝓬𝓱𝓻(101)+𝓬𝓱𝓻(102)+𝓬𝓱𝓻(103)+𝓬𝓱𝓻(104)+𝓬𝓱𝓻(105)+𝓬𝓱𝓻(106)+𝓬𝓱𝓻(107)+𝓬𝓱𝓻(108)+𝓬𝓱𝓻(109)+𝓬𝓱𝓻(110)+𝓬𝓱𝓻(111)+𝓬𝓱𝓻(112)+𝓬𝓱𝓻(113)+𝓬𝓱𝓻(114)+𝓬𝓱𝓻(115)+𝓬𝓱𝓻(116)+𝓬𝓱𝓻(117)+𝓬𝓱𝓻(118)+𝓬𝓱𝓻(119)+𝓬𝓱𝓻(120)+𝓬𝓱𝓻(121)+𝓬𝓱𝓻(122)+𝓬𝓱𝓻(65)+𝓬𝓱𝓻(66)+𝓬𝓱𝓻(67)+𝓬𝓱𝓻(68)+𝓬𝓱𝓻(69)+𝓬𝓱𝓻(70)+𝓬𝓱𝓻(71)+𝓬𝓱𝓻(72)+𝓬𝓱𝓻(73)+𝓬𝓱𝓻(74)+𝓬𝓱𝓻(75)+𝓬𝓱𝓻(76)+𝓬𝓱𝓻(77)+𝓬𝓱𝓻(78)+𝓬𝓱𝓻(79)+𝓬𝓱𝓻(80)+𝓬𝓱𝓻(81)+𝓬𝓱𝓻(82)+𝓬𝓱𝓻(83)+𝓬𝓱𝓻(84)+𝓬𝓱𝓻(85)+𝓬𝓱𝓻(86)+𝓬𝓱𝓻(87)+𝓬𝓱𝓻(88)+𝓬𝓱𝓻(89)+𝓬𝓱𝓻(90)+𝓬𝓱𝓻(33)+𝓬𝓱𝓻(34)+𝓬𝓱𝓻(35)+𝓬𝓱𝓻(36)+𝓬𝓱𝓻(37)+𝓬𝓱𝓻(38)+𝓬𝓱𝓻(39)+𝓬𝓱𝓻(42)+𝓬𝓱𝓻(44)+𝓬𝓱𝓻(46)+𝓬𝓱𝓻(47)+𝓬𝓱𝓻(58)+𝓬𝓱𝓻(59)+𝓬𝓱𝓻(60)+𝓬𝓱𝓻(61)+𝓬𝓱𝓻(62)+𝓬𝓱𝓻(63)+𝓬𝓱𝓻(64)+𝓬𝓱𝓻(91)+𝓬𝓱𝓻(93)+𝓬𝓱𝓻(94)+𝓬𝓱𝓻(95)+𝓬𝓱𝓻(96)+𝓬𝓱𝓻(123)+𝓬𝓱𝓻(124)+𝓬𝓱𝓻(125)+𝓬𝓱𝓻(126))

Try it online!

• Almost exactly the same as mine, nice job! Jul 25, 2020 at 16:12
• @nthistle Thanks! This was fun Jul 25, 2020 at 16:13
• Can someone explain why this works? Jul 25, 2020 at 16:20
• @SurculoseSputum I took inspiration from this Q&A, which I recently read by chance. I wasn't sure it would work for builtin methods Jul 25, 2020 at 16:28
• Why this answer got more upvotes than the cops answer is the mystery of Stack Exchange. Jul 28, 2020 at 16:16

# Python 3.7, 128 bytes, cracks jez's answer

import sys
class A:__class_getitem__=chr
class B:__class_getitem__=ord
class C:__class_getitem__=sys.stdout.write
C[A[B["'"]+1]]

Try it online!

• You beat me to it! I had just realized I could use __class_getitem__ to call functions when I saw the notification. Good job! Not sure why you need three classes though. chr is totally unnecessary. Jul 27, 2020 at 2:49
• Love it. (and @Sisyphus's solution too). And it has introduced me to __class_getitem__ for the first time. There's no need to golf, true, but wouldn't it be fun? Try to beat my 97 bytes.
– jez
Jul 27, 2020 at 2:53
• @jez 29 bytes - Try it online! Jul 27, 2020 at 3:02
• @Sisyphus You should have posted that as a cop answer rather than wasting it here. Jul 27, 2020 at 3:03

send("ev"+("%x"%(5+5))+"l",send("ev"+("%x"%(5+5))+"l",("%d"%(4-3))+("%d"%(4-3))+"2"+("%f"%2)[4-3]+"chr")+"uts \""+send("ev"+("%x"%(5+5))+"l",("%d"%(4-3))+("%d"%(4-3))+"2"+("%f"%2)[4-3]+"chr")+send("ev"+("%x"%(5+5))+"l","60"+("%f"%2)[4-3]+"chr")+("%f"%2)[4-3]+send("ev"+("%x"%(5+5))+"l","36"+("%f"%2)[4-3]+"chr")+("%x"%(5+5))+("%d"%(4-3))+"\"")

Try it online!

I'm gonna be honest – about an hour ago, I didn't know Ruby. But I didn't let that stop me!

Explanation: In general, my approach to these is to get some kind of eval construct, and then convert numbers to characters and combine to get any payload (as long as numbers and + allowed, and you can do the former with the language, this works).

The immediate problems with this one are that we don't have access to p, which is necessary for any(?) kind of printing in ruby (p, puts, pp, ...), we can't use a, so eval is out, and we can't use ., so it's difficult to call any methods or get attributes. For that matter, we're going to have difficulty converting numbers => characters without Integer.chr (I found some hacky ways to get it to call without using ., including overriding * for Integers, but not without using a in class).

In my quest to find reflection tricks that would be useful, I stumbled across the send method, although it took a while before I realized you didn't have to invoke it on an object. Now we're at send("eval","[payload]"), but still need a way to construct strings. I banged my head on this for a while before I realized that for the a restriction at least, I could simply use a format string with hex. ("%x" % 10) gets us a, although we need to change 10 to 5+5 in order to bypass the 1 restriction.

Great, now we have eval. Unfortunately, p is not a hex character. Not a problem, though, since we have eval! We can recover "." from ("%f"%1)[1] (changing to ("%f"%2)[4-3] to bypass 1), so now we can just send "112.chr" to eval, and we're golden.

From here it's just combining these primitives to get a payload that translates to the string puts "p<.$a1", and we're done! Edit: I just realized that I could've also just used "%c" % ... to get characters instead of the clunky trick I have for invoking .chr. For completeness, here's a much shorter version that uses this: send("ev"+("%c"%97)+"l",("%c"%(56+56))+"uts \""+("%c"%(56+56))+("%c"%60)+("%f"%2)[4-3]+("%c"%36)+("%c"%97)+("%d"%(4-3))+"\"") • This is awesome. Jul 25, 2020 at 20:56 • Out of curiosity, what did your original program look like? Jul 25, 2020 at 20:59 • Very different, but I think I'll iterate on it and post another cop before surrendering :) Jul 26, 2020 at 0:08 # Befunge-93 (FBBI), cracks @Ethan Chapman's (new) answer >g::g- :::+:+:+:+:++\::+:+:+:+:+:+\::+::+::+::+::+::++++++\::+::+:+:+:++\: v v +::+:+::+::+::\+++++::+:+::+::+:::\+++::+::+:+:+::\++++::+::+:+:+:: < > +++\:::+:+::+:+::++++\::+:+::+:+::+++\:::+::+:+:+::++++\::+::+:+:+: v v \+++:+::+::+:+::\+++:+::+::+:+::\++::+:+:+:+::\+++::+:+:+:+:::\+++: < > ::+\::+::+:++\::+:+:+:+:+:+\::+\::+:+::++\$pp                       v
v                                                                          <
>                                                                          v
v                                                                          <

v <
X
>:|
Y

=

Try it online!

A Brief History/Explanation: I originally started writing this answer when I saw Ethan Chapman's first Befunge-93 answer, but progress was hampered by the fact that I didn't know Befunge. I took a lunch break and by the time I came back, it had already been cracked (in a different way)! My original approach was simply to use ! to get 1 on the stack (it implicitly reads a 0 off the stack), and then just duplicate (:) and add (+) that to itself to create whatever numbers I needed.

Then, you can take advantage of Befunge's ability to modify the source code to write a , into some specific location and then print off the stack as ASCII characters. It was easy enough to write the following snippet that prints off the entire stack, which also only has a single , (which means it only requires one self-write).

v <   (Whee!)
,  Prints top of stack as ASCII character
>:|  Duplicates top of stack, then pops, going down if zero, up otherwise
@  Terminates

Fortunately, this general approach didn't change too much between the two answers. The main difference is that I can no longer use ! to get a 1 on top of the stack from the empty stack (I also can't use @ to terminate, but that's not an issue, since we can just use another self-write for that).

Some simple process of elimination reveals that g (pop y, x, then push value of ASCII character at location (x,y)) is just about the only way to get non-zero values onto the stack now. Since the stack is implicitly zero, the first g we hit with an empty stack will simply push the value of character at (0,0). However, unlike some more convenient languages (cough, cough, 05AB1E), we don't have builtin operators to divide by 2 that we might use to reduce this value down to 1.

Thus, we need to use our ability to read again. The simplest way to do this is have the value at (0,0) be ASCII value v, and then put v-1 at (v,v). At this point, I ran into some problems with a lot of the Befunge-93 interpreters on TIO, since by default they only support a 25x80 program, and will complain about reads outside of this range. I can start with a space, which has ASCII value 32, but that's still out of bounds. Fortunately, the FBBI version works just fine, although I can't start with a space because for some reason it doesn't terminate unless you begin with a direction(?).

In any case, I can recover the magic 1 by starting with > (value 62) at (0,0), then using g:: to push 62 onto the stack and duplicate it twice, then using g to read (62,62), where I have = (value 61), and then finally subtract the top two elements of the stack, 62 and 61, in order to get 1.

From here, it's straightforward, if slightly painful. We just need to produce a stack that looks like our target string (in reverse order), followed by our two writes of , and @ (denoted by X and Y in the original source). While I could just duplicate the 1 several hundreds of times, I decided it was worth the effort to write a more efficient method, which encodes the target value in binary, then produces the binary decomposition on the stack, before summing (it's easy to get 1,4,16,32, for instance, because I can double with :+).

This, plus the careful positioning of everything so the writes end up in the correct place, is a lot of work, so I just wrote a Python script that does it for me.

from collections import defaultdict

# by convention, assume there is a 1 on top of the stack
def gen_stack(stack):
# goal is to produce stack:list[int]
def gen_single(ch):
if type(ch) is chr:
ch = ord(ch)
binary_decomp = []
cur = ch
while cur > 0: # I know this is inefficient
r = (1 << (cur.bit_length() - 1))
cur -= r
binary_decomp.append(r)
binary_decomp = binary_decomp[::-1]
total = ""
value = 1
for c in binary_decomp:
total += ":"
while value < c:
total += ":+"
value *= 2
return "".join(gen_single(c) for c in stack)

# places string segment starting at (i,j) in given direction
def place_segment(prog, i, j, segment, direction=(1,0)):
for k, c in enumerate(segment):
prog[i + k*direction[0], j + k*direction[1]] = c
return len(segment)

target_string = """,0123456789"~@!"""

# [x,y], use implicit grid
prog = defaultdict(lambda : ' ')

W = 75
offset = 0
offset += place_segment(prog, offset, 0, ">g::g-") # ends at 6,0 excl
# store this for 1-recovery
prog[62,62] = "="

# now have 1 on stack
target_stack = list(map(ord,target_string))[::-1]
target_stack.extend([ord(","),2,10]) # write , to 2,10
target_stack.extend([ord("@"),2,12]) # write @ to 2,12

stack_generation = gen_stack(target_stack)

stack_generation += "\$" # pop the 1
stack_generation += "p" # place the @
stack_generation += "p" # place the ,

# program flow routing
for i in range(8):
prog[W,i] = "<" if (i % 2 == 1) else "v"
prog[0,i] = "v" if (i % 2 == 1) else ">"

# makes it more aesthetically pleasing
offset += 1
row = 0
while len(stack_generation) > 0:
# zig-zag segment placement until we're out
if row % 2 == 0:
place_segment(prog, offset, row, stack_generation[:W-offset-1])
stack_generation = stack_generation[W-offset-1:]
else:
place_segment(prog, W - 2, row, stack_generation[:W-offset-1], (-1,0))
stack_generation = stack_generation[W-offset-1:]
row += 1

# first 8 rows were allocated for the stack generation
# place the print-stack block
place_segment(prog, 0,  9, "v <")
place_segment(prog, 0, 10, "  X")
place_segment(prog, 0, 11, ">:|")
place_segment(prog, 0, 12, "  Y")

# print prog
max_y = max(k[1] for k in prog.keys())
max_x = lambda y : max([0, *[k[0] for k in prog.keys() if k[1] == y]])
# just so we don't print tons of extra spaces

source = "\n".join("".join(prog[i,j] for i in range(max_x(j)+1)) for j in range(max_y+1))
print(source)

# verify
for c in target_string:
if c in source:
print("Failed check for",c)
• Very nice, similar to what I wrote but a little less verbose and a little more convoluted. I'll add my answer on the cops post. Jul 26, 2020 at 20:19
• I think your code is angry: >:| (line 3) Aug 18, 2020 at 14:15

Hard version:

main=print[p|r<-[[n..m]|m<-[a|a<-['n'..],init[a|a<-['n'..],'|'<a,[a,']','<']<[a,']'..]]<[a],[a,']','<']<[a,']'..]],n<-[a|a<-init=<<[init['n','a'..]],a<'-']],p<-r,p<','||','<p,p<'.'||'.'<p,p<'['||'['<p,p<'|'||'|'<p,p<'<'||'<'<p,p<'-'||'-'<p,p<']'||']'<p,p<'m'||'m'<p,p<'a'||'a'<p,p<'i'||'i'<p,p<'n'||'n'<p,p<'p'||'p'<p,p<'r'||'r'<p,p<'t'||'t'<p,p<'='||'='<p,t<-init=<<[init=<<[init=<<[init=<<[init[t|n<-[a|a<-init=<<[init['n','a'..]],a<'-'],t<-[n..','],[n,t,'.']<[n,t..]]]]]],p<t||t<p,i<-init[a|a<-['n','['..],a<'.'],i<p||p<i]

Easy version:

main=print[p|r<-[[n..m]|m<-[a|a<-['n'..],init[a|a<-['n'..],'|'<a,[a,']','<']<[a,']'..]]<[a],[a,']','<']<[a,']'..]],n<-[a|a<-init=<<[init['n','a'..]],a<'-']],p<-r,p<','||','<p,p<'.'||'.'<p,p<'['||'['<p,p<'|'||'|'<p,p<'<'||'<'<p,p<'-'||'-'<p,p<']'||']'<p,p<'m'||'m'<p,p<'a'||'a'<p,p<'i'||'i'<p,p<'n'||'n'<p,p<'p'||'p'<p,p<'r'||'r'<p,p<'t'||'t'<p,p<'='||'='<p,t<-init=<<[init=<<[init=<<[init=<<[init[t|n<-[a|a<-init=<<[init['n','a'..]],a<'-'],t<-[n..','],[n,t,'.']<[n,t..]]]]]],p<t||t<p,i<-init[a|a<-['n','['..],a<'.'],i<p||p<i,':'<p||p<':']

Found by lots of trial and error, mostly using ranges, list comprehensions and comparisons as filters. Some used tricks:

• We can only ever obtain strings, never single characters (except those that are allowed). List comprehensions work around this: If s=[c] and t=[d] are single-character strings, then [[c,d..]|c<-s,d<-t] is equivalent to [[c,d..]]
• init.init[1,2,3] doesn't work due to precedence. Use init=<<[init[1,2,3]] instead
• Lexicographic ordering is useful! Things like [a,'.'..]>[a,'.'] (check if further terms in arithmetic sequence exist) and [a,'m'..]>[a,'m',']'] (check if next term is greater than ']') are useful checks for narrowing down characters
• After we have ' ' and '~' we can construct [' '..'~'], and filter out the allowed chars using the construct p<'m'||'m'<p. However, we can't write ''', so ' has to again be generated using range tricks

There are probably some shortcuts using some kind of pattern matching inside the assignment (for example, the inits could be elimited by something like [a,_,_]<-[[...]] instead of a<-init=<<[init[...]].

• I see you got some use out of the library functions other than print! Interesting approach. I'm going to have to see if I can rework this to curb this approach. Jul 26, 2020 at 1:44

# Java (JDK), cracks user's answer

class T{public static void main(String... args){if(System.out.printf(""+(char)92+(char)91+(char)59)==null){}}}

Try it online!

This was pretty fun. First, we need a main method without the square brackets, which can be done with the standard main method definition replacing the square brackets with ellipsis, and then to avoid the semicolon we can wrap the print statement into an if conditional so that it executes when the condition is being checked, printing the characters according to their ascii values.

• This is almost exactly what I had. Well done!
– user
Jul 26, 2020 at 19:24

# Shakespeare Programming Language, 1034 bytes, cracks @RobinRyder's answer

Restricted sauce, or, A shortage of ketchup.

Othello, also known as Reversi.
Ophelia, a satellite of Uranus.

Act I: Love's letters lost.

Scene I: Cracked pepper.

[Enter Othello and Ophelia]

Othello:
Thou art as sweet as the square root of a cute peaceful fair fine gentle angel!

Ophelia:
Thou art as cunning as the square root of the product of the factorial of I and the product of a trustworthy rich pony and the square of I!
Speak thy deceitful treachery!

Othello:
Thou art as golden as the square root of twice the square of thou!

Ophelia:
Thou art as healthy as the product of the square root of a cunning pretty trustworthy good peaceful gentle fine squirrel and I!
Speak thy awful truth!
Thou art as loving as twice the square of I!
Speak thy flirtatious trifles!

Othello:
Thou art as happy as the square root of a gentle delicious cunning golden honest trustworthy sweet Lord!

Ophelia:
Thou art as peaceful as the product of twice the square root of I and I!

[Exeunt]

Try it online!

Constructing integers was tricky. As Robin noted, addition and subtraction are out. So too are cubing (the cube of), division (the quotient between), and modulo (the remainder of the quotient between). We will have to make do with multiplication, squares, square roots, and factorials. These operations are incompletely documented in the official docs; I actually found the interpreter source code to be a more useful reference in this regard.

We also need a way to output characters given that the usual Speak thy mind! is banned as well. Digging into the interpreter source code, I found that mind may be replaced with arbitrary text (a warning is printed to STDERR). There's that problem solved. Now, on to generating the required characters.

The required ASCII codes are 109, 77, 98, and 66. The basic idea is to set Othello to each of these values in succession, then print the character via Speak thy ... (I took some poetic licence with the ...s). Ophelia stores some intermediate values for convenience.

# International Phonetic Esoteric Language, cracks @bigyihsuan's answer

{32}χu{33}χu{34}χu{35}χu{36}χu{37}χu{38}χu{39}χu{40}χu{41}χu{42}χu{43}χu{44}χu{45}χu{46}χu{65}χu{66}χu{67}χu{68}χu{69}χu{70}χu{71}χu{72}χu{73}χu{74}χu{75}χu{76}χu{77}χu{78}χu{79}χu{80}χu{81}χu{82}χu{83}χu{84}χu{85}χu{86}χu{87}χu{88}χu{89}χu{90}χu{91}χu{92}χu{93}χu{94}χu{95}χu{96}χu

To my knowledge, the only way to test this is with the interpreter here.

# R, 209 bytes, cracks Robin Ryder's answer

dput(intToUtf8(c(59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,86,87,88,89,90,91,92,93,94,95,96,97,98,101,103,104,106,107,108,109,113,114,115,118,119,120,121,122,123,124,125,126)))

Try it online!

Found the right output function dput by using apropos on the remaining alphabet characters. dput also happens to be a key element of an R quine.

• Well done! Would it have been more difficult if I had included fewer characters, to make apropos less useful? Jul 26, 2020 at 6:26
• @RobinRyder probably! It certainly would have taken me a lot longer to golf on my phone, since it'd be harder to try the larger range of functions, but I guess then the only barrier still would have been time. Jul 26, 2020 at 13:51

#include <stdio.h>

int main(void) <%
if (printf("%c%c", 123, 59)) <% %>
%>

For some reason, you can use <% instead of { in C. You can also use printf inside an if block to avoid having a single statement with a semicolon.

Try it online!

• The <% is a legacy feature since not all machines had {} iirc. However today it seems a bit absurd. Jul 26, 2020 at 19:37
• Yes, that was my solution as well. Older Keyboard didn't have some special characters like { an so digraphs were introduced as alternatives for them.
– xibu
Jul 26, 2020 at 19:43
• @user Here's the relevant page on cppreference: en.cppreference.com/w/c/language/operator_alternative Jul 28, 2020 at 15:35