52
\$\begingroup\$

This is the cop's thread of a challenge. You can view the robber'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 (this 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 exactly X without using any of the characters in X. The cop will then post both X and Y without revealing the program the 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 their 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 and are eligible for scoring.

Cops will be scored by length of X in characters with smaller scores being better. Only safe answers are eligible for scoring.

Extra Rules

You may be as specific or precise in choosing your language as you wish. For example you may say your language is Python, or Python 3, or Python 3.9 (pre-release) or even point to a specific implementation. Robbers solutions need only work in one implementation of the given language. So for example if you say Python is your language a Robber's crack is not required to work in all versions of Python only one.

Since command line flags count as different languages you should indicate specific command line flags or the possibility of command line flag as part of your language. For ease of use I ask that you assume there are no command line flags in cases where command line flags are not mentioned.

You may choose to have your output as an error. If your intended solution does output as an error you must indicate this in your answer.

Find Uncracked Cops

<script>site = 'meta.codegolf'; postID = 5686; isAnswer = false; QUESTION_ID = 207558;</script><script src='https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js'></script><script>jQuery(function(){var u='https://api.stackexchange.com/2.2/';if(isAnswer)u+='answers/'+postID+'?order=asc&sort=creation&site='+site+'&filter=!GeEyUcJFJeRCD';else u+='questions/'+postID+'?order=asc&sort=creation&site='+site+'&filter=!GeEyUcJFJO6t)';jQuery.get(u,function(b){function d(s){return jQuery('<textarea>').html(s).text()};function r(l){return new RegExp('<pre class="snippet-code-'+l+'\\b[^>]*><code>([\\s\\S]*?)</code></pre>')};b=b.items[0].body;var j=r('js').exec(b),c=r('css').exec(b),h=r('html').exec(b);if(c!==null)jQuery('head').append(jQuery('<style>').text(d(c[1])));if (h!==null)jQuery('body').append(d(h[1]));if(j!==null)jQuery('body').append(jQuery('<script>').text(d(j[1])))})})</script>

\$\endgroup\$
  • 1
    \$\begingroup\$ @user I believe errors are considered output, by our standard rules. I defer to those, so I believe the answer is yes. \$\endgroup\$ – Wheat Wizard Jul 25 at 15:53
  • 1
    \$\begingroup\$ @SomoKRoceS You can use any characters. \$\endgroup\$ – Wheat Wizard Jul 25 at 21:03
  • 3
    \$\begingroup\$ @Discretelizard I am not AdHocGarfHunter, but if your program does anything with the input (other than completely ignoring it), it is almost certainly invalid. \$\endgroup\$ – the default. Jul 26 at 15:09
  • 3
    \$\begingroup\$ @Discretelizard they have the requirement by default at Loopholes that are forbidden by default \$\endgroup\$ – the default. Jul 26 at 15:43
  • 3
    \$\begingroup\$ Given the large number of answers to this challenge, I suggest adding the uncracked answers stack snippet to the question body, so it's easier to find uncracked cops. (I'm posting a comment rather than adding it myself due to the rule against adding leaderboards) \$\endgroup\$ – pppery Jul 27 at 23:14

91 Answers 91

28
\$\begingroup\$

Python 3, Score: 81, Cracked

X = abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ!"#$%&'*,./:;<=>?@[]^_`{|}~

Not terribly interesting since it has such a high score, but this should be somewhat difficult to crack...

Clarification: This is in fact a full Python 3 program, running it locally with python3 print_x_out.py produces the above output for me. Likewise, the below verifier script produces no output:

with open("print_x_out.py") as file:
    source = file.read()

output = """ abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ!"#$%&'*,./:;<=>?@[\]^_`{|}~"""

for c in output:
    if c in source:
        print(f"Failed verifier check for '{c}'")

Edit: Well, that was faster than expected...

| improve this answer | |
\$\endgroup\$
  • 3
    \$\begingroup\$ I hope this is a program (complete program or function) and not a snippet? \$\endgroup\$ – user202729 Jul 25 at 15:25
  • 2
    \$\begingroup\$ I don't think there's actually a way to output something without any letters. If the language is actually Python 3 REPL, can you label it as such? \$\endgroup\$ – Jo King Jul 25 at 15:29
  • 3
    \$\begingroup\$ No, this is a full program. python3 print_x_out.py produces this output for me. \$\endgroup\$ – nthistle Jul 25 at 15:49
  • \$\begingroup\$ I added this clarification to the answer -- I can assure you it is possible, but you might have to wait a week to find out how ;) \$\endgroup\$ – nthistle Jul 25 at 15:54
  • 7
    \$\begingroup\$ Cracked \$\endgroup\$ – Luis Mendo Jul 25 at 16:09
13
\$\begingroup\$

Javascript (Browser), score: 3, Cracked

(\)

Simple, but hard.

My solution:

Function`$${unescape`alert%28"%28%5C%5C%29"%29`}```

| improve this answer | |
\$\endgroup\$
  • \$\begingroup\$ Cracked \$\endgroup\$ – nthistle Jul 25 at 18:12
  • 22
    \$\begingroup\$ Every day I learn about more cursed JavaScript features... \$\endgroup\$ – nthistle Jul 25 at 18:12
  • \$\begingroup\$ @nthistle: Ah yes javascript is turing complete in so few characters. \$\endgroup\$ – Joshua Jul 28 at 15:54
12
\$\begingroup\$

Python 3.7, Score: 1 - Cracked

X = (

Same base rules as nthistle's challenge above: must be a full script, run with python3 print_x_out.py.

I believe it's not possible to use wacky non-ascii substitutes for ( in a Python 3 script, but I may be wrong (I haven't tried them all). My solution does not use that approach, anyway, and the intention is that yours should not either—now that we've seen it once, there's no fun in taking that as the easy way out for all Python 3 challenges.

I know code length is not in the rules, but as we're all golfers here I'd be curious to see how short the solution can get. FWIW mine is 104 characters (97 if we're allowing a trailing newline at the end of the output).

| improve this answer | |
\$\endgroup\$
10
\$\begingroup\$

Haskell, Score 81, Cracked

" !#$%&()*+/0123456789;>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ\\^_`bcdefghjkloqsuvwxyz{}~"

This one might be a little difficult.

Stuff you don't have

You don't have newlines or spaces (my intended answer doesn't use any whitespace at all, however I can't get it to print some of the funkier whitespace characters so you are free to use them for yourself). You also don't have any of the other ways to apply functions such as $ or parentheses. You don't have the other line delimiter ;, so everything has to be on one line (as far as I know).

Stuff you do have

I had to give you the bare minimum of main= for a complete program. I've also given you prt as extra letters, it shouldn't take much to see that this allows for print.

You also have an assortment of other symbols available to you, I'll let you figure out how to use them.

:,.[|<-]'

These are all the characters I've used, there are no unprintables present in my intended solution. However since I can't print the unprintables you are fine to use them.

For your reference here are all the functions available using only the permitted characters:

(||) (==) (<) (<=) min (-) pi tan atan (=<<) (.) map init (:) print

Even harder Haskell, Score 82, Cracked

" !#$%&()*+/0123456789:;>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ\\^_`bcdefghjkloqsuvwxyz{}~"

A little while after I posted this I realized I do not need :, so this version has a : in the output as well. I have posted in this answer to prevent clutter from two nearly identical answers, but both should be crack-able separately.

| improve this answer | |
\$\endgroup\$
  • \$\begingroup\$ Cracked (both versions) \$\endgroup\$ – ManfP Jul 26 at 1:34
10
\$\begingroup\$

Mornington Crescent, Score: 4, Cracked

X = myHp

You may have survived the 7UBES, but the real challenge begins now. Face me in battle! First, allow me to rid us of some distractions. Four lines are closed. Over half of the special stations are unavailable. In spite of this ruin, victory remains possible. Even for the likes of you, but it won't come easily... I'll be impressed if you can cut even the tiniest bit of my Hp.


Consider the language again to be defined by the linked interpreter, also available on TIO.


The main challenge here was the fact that your only arithmetic operation is division, so there is no way to get the character codes by only using arithmetic operations.

My solution is below is quite a bit shorter than the crack (7410 bytes after removing comments), but uses the same basic idea: first divide the character codes of some lowercase letters by 2 to get the character codes of the symbols '1' '2' '7' '9' '0'. Then, copy and concatenate these symbols to get strings '109' '121' '72' '112'. Parsing these strings to integers at Parsons green gives the character codes for m y H p, which can then be concatenated to get the result.

A simple trick, but quite a piece of work to implement. In hindsight, I was lucky that I only needed 5 different number symbols and all symbols could be found on position -7 in some available station name.

# "myHp" 7 and division is enough to create 2. 
#7 can also be used to get the lower case characters:
# 2 == ord('A')//ord(' ');  Goodge# Street, 7 [District]
#'1' == chr(ord('c')//2);       Be#contree, 7 [District]
#'2' == chr(ord('e')//2); Gloucest#er Road, 7 [District]
#'7' == chr(ord('o')//2);        B#ow Road, 7 [District]
#'9' == chr(ord('s')//2);    Baron#s Court, 7 [District]
#'0' == chr(ord('a')//2);        W#aterloo, 7 [Northern]


###print "myHP" without using those characters
##Plan: get 2
#get 65
Take Northern Line to Bank
Take District Line to Acton Town
Take District Line to Bank
Take District Line to Bank
Take Northern Line to Charing Cross
Take Northern Line to Charing Cross #ACC: 65
#put 65 at Cannon Street
Take Northern Line to Bank
Take Northern Line to Bank
Take District Line to Cannon Street
#get 32
Take District Line to Sloane Square
Take District Line to Mile End
Take District Line to Victoria
Take Victoria Line to Seven Sisters
Take Victoria Line to Victoria
Take Victoria Line to Victoria
Take District Line to Mile End #ACC: ' ...', End: 7
Take District Line to Bank
Take District Line to Bank
Take Northern Line to Charing Cross
Take Northern Line to Charing Cross #ACC: 32
# 65//32 == 2
Take Northern Line to Bank
Take Northern Line to Bank
Take District Line to Cannon Street #ACC: 2, CS: 32
Take District Line to Southfields #Sof: 2
Take District Line to Cannon Street #CS: str
##Plan: get '1'
#get 99
Take District Line to Becontree
Take District Line to Mile End #ACC: 'c...', End: str
Take District Line to Bank
Take District Line to Bank
Take Northern Line to Charing Cross
Take Northern Line to Charing Cross #ACC: 99
#put 99 at CS
Take Northern Line to Bank
Take Northern Line to Bank
Take District Line to Cannon Street
#99//2 == 49
Take District Line to Southfields
Take District Line to Cannon Street
Take District Line to Bank
Take District Line to Cannon Street #CS: str
Take District Line to Southfields #Sof: 2
Take District Line to Bank
Take Northern Line to Charing Cross
Take Northern Line to Charing Cross #ACC: '1'
Take Northern Line to Bank
Take Northern Line to Bank
Take District Line to Kew Gardens #Ke: '1'
##Plan: get '2'
#get 101
Take District Line to Gloucester Road
Take District Line to Mile End
Take District Line to Victoria
Take Victoria Line to Seven Sisters
Take Victoria Line to Victoria
Take Victoria Line to Victoria
Take District Line to Mile End #ACC: 'e...', End: 7
Take District Line to Bank
Take District Line to Bank
Take Northern Line to Charing Cross
Take Northern Line to Charing Cross #ACC: 101
#put 101 at CS
Take Northern Line to Bank
Take Northern Line to Bank
Take District Line to Cannon Street
# 101//2 == 50
Take District Line to Southfields
Take District Line to Cannon Street
Take District Line to Bank
Take District Line to Cannon Street #CS: str
Take District Line to Southfields #Sof: 2
Take District Line to Bank
Take Northern Line to Charing Cross
Take Northern Line to Charing Cross #ACC: '2'
Take Northern Line to Bank
Take Northern Line to Bank
Take District Line to Chiswick Park #Chi: '2'
##Plan: get '7'
#get 111
Take District Line to Bow Road
Take District Line to Mile End
Take District Line to Bank
Take District Line to Bank
Take Northern Line to Charing Cross
Take Northern Line to Charing Cross #ACC: 111
#Put 111 at CS
Take Northern Line to Bank
Take Northern Line to Bank
Take District Line to Cannon Street
# 111//2 == 55
Take District Line to Southfields
Take District Line to Cannon Street
Take District Line to Bank
Take District Line to Cannon Street #CS: str
Take District Line to Southfields #Sof: 2
Take District Line to Bank
Take Northern Line to Charing Cross
Take Northern Line to Charing Cross #ACC: '7'
Take Northern Line to Bank
Take Northern Line to Bank
Take District Line to Ravenscourt Park #Ra: '7'
##Plan: get '9'
#get 115
Take District Line to Barons Court
Take District Line to Mile End
Take District Line to Victoria
Take Victoria Line to Seven Sisters
Take Victoria Line to Victoria
Take Victoria Line to Victoria
Take District Line to Mile End #ACC: 's...', End: 7
Take District Line to Bank
Take District Line to Bank
Take Northern Line to Charing Cross
Take Northern Line to Charing Cross #ACC: 115
#Put 115 at CS
Take Northern Line to Bank
Take Northern Line to Bank
Take District Line to Cannon Street
# 115//2 == 57
Take District Line to Southfields
Take District Line to Cannon Street
Take District Line to Bank
Take District Line to Cannon Street #CS: str
Take District Line to Southfields #Sof: 2
Take District Line to Bank
Take Northern Line to Charing Cross
Take Northern Line to Charing Cross #ACC: '9'
Take Northern Line to Bank
Take Northern Line to Waterloo
Take Northern Line to Bank
Take District Line to Acton Town #Act: '9'
##Plan: get '0'
#get 97
Take District Line to Bank
Take District Line to Mile End
Take District Line to Bank
Take District Line to Bank
Take Northern Line to Charing Cross
Take Northern Line to Charing Cross #ACC: 97
#Put 97 at CS
Take Northern Line to Bank
Take Northern Line to Bank
Take District Line to Cannon Street
# 97//2 == 48
Take District Line to Southfields
Take District Line to Cannon Street
Take District Line to Bank
Take District Line to Cannon Street #CS: str
Take District Line to Southfields #Sof: 2
Take District Line to Bank
Take Northern Line to Charing Cross
Take Northern Line to Charing Cross #ACC: '0'
Take Northern Line to Bank
Take Northern Line to Bank
Take District Line to Earl's Court #Earl: '0'
##Plan: get 1 
# 7//2 == 3
Take District Line to Victoria
Take Victoria Line to Seven Sisters
Take Victoria Line to Victoria
Take Victoria Line to Victoria
Take District Line to Cannon Street 
Take District Line to Southfields 
Take District Line to Cannon Street #ACC: 3, CS: 2
# 3//2 == 1
Take District Line to Bank
Take District Line to Cannon Street
Take District Line to Bank
Take District Line to Cannon Street
Take District Line to Bank
Take District Line to Cannon Street #ACC: 1, CS: 2
Take District Line to Barking #Ba: 1
##Plan: make 109
#copy '1'
Take District Line to Kew Gardens
Take District Line to Paddington #ACC: 'Paddington1', Pad: '1'
Take District Line to Mile End
Take District Line to Barking
Take District Line to Mile End #ACC: '1', End: 1
Take District Line to Kew Gardens #Ke: '1'
#concat '109'
Take District Line to Earl's Court
Take District Line to Paddington #ACC: '10', Pad '0'
Take District Line to Paddington #ACC: '010', Pad '10'
Take District Line to Acton Town 
Take District Line to Paddington #ACC: '109', Pad '9'
Take District Line to Parsons Green
Take District Line to Acton Town #Act: 109
#make 72
Take District Line to Ravenscourt Park
Take District Line to Paddington #ACC: '97', Pad '7'
Take District Line to Chiswick Park
Take District Line to Paddington #ACC: '72', Pad '2'
Take District Line to Parsons Green
Take District Line to Ravenscourt Park #Ra: 72
##Plan: make 112
#Grab '2'
Take District Line to Parsons Green #ACC: 10
Take District Line to Paddington #ACC: '2' , Pad 10
Take District Line to Barons Court #Ba: '2'
#copy '1'
Take District Line to Paddington 
Take District Line to Kew Gardens #Ke: 10
Take District Line to Paddington #ACC: '...1', Pad '1'
Take District Line to Kew Gardens
Take District Line to Mile End #ACC: 1, End: 10
Take District Line to Bank
Take District Line to Mile End #End: str
Take District Line to Kew Gardens
Take District Line to Mile End #End: '...1'
Take District Line to Bank
Take District Line to Mile End #ACC: '1', End: 1
Take District Line to Paddington #ACC: '11', Pad '1'
Take District Line to Cannon Street
Take District Line to Paddington #ACC: '1', Pad int
Take District Line to Cannon Street #Can: '1'
Take District Line to Paddington #Pad: '11'
Take District Line to Barons Court
Take District Line to Paddington #ACC: '112', Pad '2'
Take District Line to Parsons Green
Take District Line to Bank #Ban: 112
#make 121
Take District Line to Cannon Street
Take District Line to Paddington
Take District Line to Paddington
Take District Line to Parsons Green
#int to char
Take District Line to Bank #Ban: 121
Take Northern Line to Charing Cross
Take Northern Line to Charing Cross
Take Northern Line to Bank #Ban: 'p'
Take Northern Line to Charing Cross
Take Northern Line to Charing Cross
Take Northern Line to Bank #Ban: 'y'
Take District Line to Barons Court #Bar: 'p'
Take District Line to Acton Town
Take District Line to Bank #Ban: 109
Take District Line to Kew Gardens #Ke: 'y'
Take District Line to Ravenscourt Park
Take District Line to Bank #Ban: 72
Take Northern Line to Charing Cross
Take Northern Line to Charing Cross
Take Northern Line to Bank #Ban: 'm'
Take Northern Line to Charing Cross
Take Northern Line to Charing Cross
Take Northern Line to Bank #Ban: 'H'
Take District Line to Acton Town #Act: 'm'
#Concat 'myHp'
Take District Line to Paddington
Take District Line to Acton Town
Take District Line to Paddington #Pad: 'm'
Take District Line to Kew Gardens
Take District Line to Paddington
Take District Line to Paddington #Pad: 'my'
Take District Line to Bank
Take District Line to Paddington
Take District Line to Paddington #Pad: 'myH'
Take District Line to Barons Court
Take District Line to Paddington #ACC: 'myHp'
Take District Line to Bank
Take District Line to Bank
Take Northern Line to Mornington Crescent

Version without comments on TIO

The cutting room floor

As much as I'd like to be able to give an encore, I'm afraid I've exhausted my material. The design-space is a bit limited both due to the fact that Mornington Crescent is a language with a simple description and few commands (unlike, say, Javascript or Perl), as well as the fact that Take Northern Line to Mornington Crescent must be present in every valid program.

I can't present any challenge that is solvable only by a method different from the solutions given so far. Best I can give you is some strings that I didn't use either because they were too easy (i.e. solvable with ideas already given) or too hard. (i.e. I couldn't think of a method to solve them. Feel free to post these as a challenge here if you do!)

I provide the following strings at your own risk, do with them as you please.

Easy

  1. Spy leaves open a bit too many arithmetical operators for my taste.
  2. l shuts down surprisingly many lines with only a single letter, but still leaves many options open.
  3. HypV is too similar to this challenge, with only a small difference in the startup due to the lack of Seven Sisters

Hard (likely impossible)

  1. SpyH closes down many pesky operators, but I don't see a way to get a 1 and am stuck without it.
  2. HypVm is similar to the this challenge, but I don't see how to get a 2 without Seven Sisters here.
| improve this answer | |
\$\endgroup\$
  • 1
    \$\begingroup\$ This is definitely much harder that the previous answer. \$\endgroup\$ – pppery Aug 1 at 3:25
  • \$\begingroup\$ FWIW, the four lines are Hammersmith & City, Piccadilly, Metropolitan and Waterloo & City. \$\endgroup\$ – Lyxal Aug 1 at 4:46
  • 1
    \$\begingroup\$ Cracked \$\endgroup\$ – pppery Aug 1 at 14:38
  • \$\begingroup\$ That was a great challenge, I didn't managed to solve it, but I had fun trying. So if there gonna be more, please notify me :) \$\endgroup\$ – SomoKRoceS Aug 1 at 16:09
  • 1
    \$\begingroup\$ @SomoKRoceS Unfortunately, this is the last one from me. I have added a few strings that I didn't end up using for various reasons. I think l is a reasonable one to try if you're new to the language. \$\endgroup\$ – Discrete lizard Aug 1 at 17:18
7
\$\begingroup\$

Rust, score 3 (safe)

pwx

No extern possible this time, so no calling C functions! (or other crates, but that wouldn't be allowed anyways)

Pretty challenging to output to stdout without being able to type print or write!

Rust version: rustc 1.45.1 (c367798cf 2020-07-26)


Solution

The main challenge is printing to stdout. I identified the following methods:

  • print!/println!
  • std::io::stdout() and then:
    • write!/writeln! (or std::fmt::Write)
    • using the std::io::Write trait and calling .write() or similar

All of these require calling a method or macro whose name is excluded by p or w.

Enter trait objects, Rust's method of having runtime polymorphism. Trait objects are pointers both to some data (like regular pointers) and to a vtable which is used to look up the implementation of the trait method when called. So a the code

let trait_obj : &mut dyn Write = ...;
trait_obj.write(&buf[..]);

is transformed to something like this

let trait_obj : (&WriteVtable, *mut ()) = ...;
(trait_obj.0[WriteVtable::write_index])(trait_obj.1, &buf[..])

Now we obviously still can't directly call .write on the &dyn Write trait object, but we can instead do the vtable lookup ourselves. This is extremely unsafe, but it works. Now Rust understandably doesn't provide a way to get the index of a trait method in the vtable (wich we probably couldn't do anyways without spelling write). This is implementation dependent code, which is why I specified the compiler version.

Looking at the compiler code that generates the vtable, we see that it first contains the Drop::drop implementation (needed for owned trait object such as Box<dyn Trait>) and then size and alignment. Then come the trait methods in the order specified by the function vtable_methods. We see it first collects methods from supertraits, and then methods from the trait in definition order. Looking at the trait definition for std::io::Write, we see that it has no supertraits, and write is the first method, so its vtable index is 3.

This is the final code:

use std::io::Write;
fn main() { unsafe {
    let y = std::io::stdout();
    let lock = y.lock();
    let x : &dyn Write = &lock;
    let (data,vtable) = std::mem::transmute::<&dyn Write, (*const (), *mut usize)>(x);
    let z : usize = vtable.offset(3).read();
    let fun = std::mem::transmute::<_, fn (*mut (), &[u8]) -> std::io::Result<usize>>(z);
    let array = [112,119,120];

    fun(std::mem::transmute(data), &array[..]);
}}

Try it online!

| improve this answer | |
\$\endgroup\$
6
\$\begingroup\$

Javascript, score: 83, cracked?

(the crack is not executable like /path/to/interpreter file.js, unlike my solution, but I don't think that matters a lot)
I only know one Javascript implementation where my intended solution works.

!"#$%&'()*,-./0123456789:;=ABCDEFGHIJKLMNOPQRSTUVWXYZ\^_`abcdefghijklmnopqrstuvwxyz

In this implementation, only five distinct characters are sufficient to represent any Javascript code. I removed some more characters to (try to) avoid giving away the answer.

The solution should be a full program, executable like this:

$ /path/to/interpreter file.js

I solved this by modifying aemkei/jsfuck on GitHub, until it was able to encode JSFuck code using the 5 characters []+|>. My solution was produced by encoding console.log("the string") in JSFuck (via jscrew.it so that I do not run out of both RAM and HDD space), and then encoding the JSFuck using the modified JSFuck generator. My solution is 46 megabytes of code, its sha256sum is d0c72f380b1623f9bff06fbed03b1ecd9c7fc012c9cc1ac9d758c9a317ad6855, and it is very slow; if anybody is interested I can try to upload it somewhere.

| improve this answer | |
\$\endgroup\$
  • 3
    \$\begingroup\$ Are these the five characters you're talking about? \$\endgroup\$ – PkmnQ Jul 26 at 8:36
  • 1
    \$\begingroup\$ I might be wrong, but I think, since you listed just Javascript as the lang name (without specifying an implementation) then a crack that works in another JavaScript interpreter is fine: "Robbers solutions need only work in one implementation of the given language"? \$\endgroup\$ – Dom Hastings Jul 26 at 10:31
  • 3
    \$\begingroup\$ @DomHastings It does not seem to work in Babel (it produces the scary syntax error mentioned above). \$\endgroup\$ – the default. Jul 26 at 10:48
  • 1
    \$\begingroup\$ I could make a solution withour using a generator, but then I would manually have to make every single character. Maybe a converter from JSFuck to pipeline five would be good. I think all you'd have to do is change (thing) into [thing][+[]] and change function(thing) to thing|>function. \$\endgroup\$ – PkmnQ Jul 26 at 12:13
  • 4
    \$\begingroup\$ For reference, the allowed characters from ASCII 33-126 are +<>?@[]{|}~. \$\endgroup\$ – Calculuswhiz Jul 26 at 14:14
6
\$\begingroup\$

Haskell, Score 74, Cracked

	
 !"#$%&()*+/0123456789:?;@BEDAFGHIJKLMNOPQRSTUVWXYZ\^_`bcdefgjkloqsvwxyz

I've changed this one up quite a bit from my last Haskell answer. The basics are somewhat similar:

  • Hard to apply functions due to missing whitespace, () and $.
  • No line delimiters so program must be on one line

This time I've given you some new characters to play with. Along most the characters from the last version you also get

uCh>{}~

The only character's I've taken away are :, which was already disallowed in the hard version, and tab, which neither me or the cracker used in the first place.

So how is this harder than those versions? Well this time the output is not possible in whole or in part with print, you will need to use putChar. Which you will find much less coöperative.

Intended solution, 829 bytes

main|[ih,a,i,n,p,u,t,h,r,mm,ma,mi,mn,mp,mu,mt,mC,mh,mr,am,aa,ai,an,ap,au,at,aC,ah,ar,im,ia,ii,ip,iu,it,iC,m,ir,nm,na,ni,nn,np,nu,nt,nC]<-['-',','..],[m,a,mat,i,n,p,u,t,h,r,mm,ma,mi,mn,mp,mu,mt,mC,mh,mr,am,aa,ai,an,ap,au,at,aC,ah,ar,im,ia,ii,ip,iu,it,iC,ih,ir,nm,na,ni,nn,np,nu,nt,nC,nh,nr,pm,pa,pi,pn,pp,pu,pt,pC,ph,pr,um,ua,ui,un,up,uu,ut,uC,uh,ur,tm,ta,ti,tn,tp,tu,tt,tC,th,tr,hm,ha,hi,hn,hp,hu,ht,hC,hh,hr,rm,ra,ri,rn,rp,ru,rt,rC,rh,rr,mmm,mma,mmi,mmn,mmp,mmu,mmt,mmC,mmh,mmr,mam,maa,mai,man,map,mau]<-map{--}putChar[m..'{']=m>>a>>an>>ap>>au>>at>>aC>>ah>>ar>>ia>>ii>>ip>>iu>>ir>>nm>>na>>ni>>nn>>np>>nu>>nt>>nC>>nh>>nr>>pm>>pu>>pa>>pt>>ph>>ua>>um>>pC>>ui>>un>>up>>uu>>ut>>uC>>uh>>ur>>tm>>ta>>ti>>tn>>tp>>tu>>tt>>tC>>th>>tr>>hm>>ha>>hi>>hp>>ht>>hC>>hh>>rm>>ra>>ri>>rn>>rp>>ru>>rh>>rr>>mmm>>mmn>>mmu>>mmC>>mam>>maa>>mai>>man>>map

Try it online!

My intended solution uses the fact that {--}, that is opening and closing a comment, separates tokens, so it can be used as a substitute for space.

Although it seems unlikely anyone might ever realize this fact, it seems near impossible to construct a cop that requires this fact, so after two failed cops I am giving up that attempt. Good job to both the robbers here.

| improve this answer | |
\$\endgroup\$
  • \$\begingroup\$ What is preventing the use of print? The characters are still available (set("print")<=set("main")|set("putChar")) \$\endgroup\$ – ManfP Jul 26 at 15:35
  • 1
    \$\begingroup\$ @ManfP The actual output can't be produced in whole or in part by print (without adding new Show instances). This is because print adds a trailing newline and the only newline in the output is the second character. No native haskell object has a show that produces a single tab or the empty string to my knowledge. \$\endgroup\$ – Wheat Wizard Jul 26 at 15:37
  • \$\begingroup\$ Oh right! Totally missed that, was just looking at the character diff, not the actual output \$\endgroup\$ – ManfP Jul 26 at 21:53
  • \$\begingroup\$ cracked \$\endgroup\$ – Potato44 Aug 1 at 13:05
5
\$\begingroup\$

International Phonetic Esoteric Language, Score: 47, Cracked

Let's throw my own language into the ring.

 !"#$%&'()*+,-.ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`

My solution:

{32}{15}0ɑbesχue1søɒ{65}{32}0ɑbesχue1søɒ

| improve this answer | |
\$\endgroup\$
  • 5
    \$\begingroup\$ Cracked, your well-documented esolangs page was your own downfall... \$\endgroup\$ – nthistle Jul 25 at 17:47
  • 11
    \$\begingroup\$ aaa well that goes to show that documentation is good \$\endgroup\$ – bigyihsuan Jul 25 at 17:54
5
\$\begingroup\$

R, Score 60, cracked

";<=>?@ABCDEFGHIJKLMNOPQRSVWXYZ[\\]^_`abeghjklmqrsvwxyz{|}~"

Note that your output cannot have an initial [1] (as would be given by default printing). You cannot use cat because of the a, and you cannot use write because of the w.

Cracked by Giuseppe.

My solution:

dput(intToUtf8(c(59:83,86:98,101,103:104,106:109,113:115,118:126)))

| improve this answer | |
\$\endgroup\$
  • 1
    \$\begingroup\$ Oh good, you left us with '() at least... \$\endgroup\$ – Giuseppe Jul 25 at 23:52
  • 1
    \$\begingroup\$ cracked! \$\endgroup\$ – Giuseppe Jul 26 at 0:23
5
\$\begingroup\$

Ruby, Score: 7, Cracked

p<.$a1s

Previous crack wasn't the intended one, so trying to head it off with another character.

| improve this answer | |
\$\endgroup\$
5
\$\begingroup\$

Befunge 93 (FBBI), score 15 (Cracked)

,0123456789"~@!

Take two. Thanks to Befunge's limited instruction set, I expect you'll find out what I think is the only remaining way to get a non-0 value on the stack, but I don't expect you to enjoy using it. That said, it wasn't as bad as I was hoping. It should be possible to remove : and maybe some others too, but I'm not going to code it to verify by hand.

Good crack, I'll post my solution here (as a TIO link, because the <pre> block didn't like it), which is along the same lines but more brute-forcey. It takes a + from the top left with g whenever it needs a new character, does some math to make that a ,, and does a little more math to place it. Then it takes a copy of that comma and turns it into whatever character it needs, then rinses and repeats.

Try it online

| improve this answer | |
\$\endgroup\$
  • \$\begingroup\$ Cracked \$\endgroup\$ – nthistle Jul 26 at 19:11
  • 4
    \$\begingroup\$ I very much did not enjoy using it :) \$\endgroup\$ – nthistle Jul 26 at 19:11
  • \$\begingroup\$ By the way, it looks like your solution uses an @, although it shouldn't be too hard to change to self-write that. Nice answer! \$\endgroup\$ – nthistle Jul 26 at 20:51
  • 1
    \$\begingroup\$ Oops, I meant to specify & in the challenge but accidentally put @ instead. It shouldn't be hard to self-write, though, no. Fortunately the & loophole didn't come up, so it's no big deal. If I post another one with even more characters removed, I'll make sure to fix that. \$\endgroup\$ – Ethan Chapman Jul 26 at 20:55
5
\$\begingroup\$

Wolfram Language (Mathematica), Score: 14, cracked

Echo@Dt[0 & ]

| improve this answer | |
\$\endgroup\$
  • 3
    \$\begingroup\$ Can we output via SendMail? (this is the only acceptable way to output I found so far) \$\endgroup\$ – the default. Jul 26 at 3:39
  • \$\begingroup\$ @mypronounismonicareinstate standard output \$\endgroup\$ – att Jul 26 at 4:19
  • 7
    \$\begingroup\$ It seems like that should maybe count as a file? I don't think output as email was explicitly brought up in there, but the idea of output as email is so hilarious to me that I really want it to be legal. \$\endgroup\$ – Ethan Chapman Jul 26 at 6:14
  • \$\begingroup\$ @att by standard output, do you mean the output which is shown with -print (which is also the output shown as Out[1] in documentation examples like these)? \$\endgroup\$ – Ethan Chapman Jul 26 at 22:56
  • \$\begingroup\$ @EthanChapman no additional flags needed \$\endgroup\$ – att Jul 27 at 2:09
5
\$\begingroup\$

Mornington Crescent, Score: 5, Cracked

X = 7UBES

London's burning! A large amount of the Underground has been closed off while the authorities try to avert disaster. Amid hellfire, dare you enter... the 7UBES?


As for the language definition, consider it defined by the linked interpreter (This interpreter is also used on TIO). Note that the interpreter may not fully conform to the language specification, in particular not to the forward compatibility clause, as the interpreter is not maintained in parallel with infrastructural projects taking place in the Underground.


While the lack of Upminster and Upney block the easiest ways, there are quite a few options left. My solution mostly depended on Manor House while ignoring Holland Park, in contrast to @pppery.

#First, place an int at Paddington, such that the string starts with our character instead of 'Paddington'
Take Northern Line to Charing Cross #ACC: 67
Take Northern Line to Moorgate
Take Circle Line to Moorgate
Take Circle Line to Paddington #PAD: 67
##Plan: get 120
#First, put 'Oxford Circus' on Gunnersbury
Take Circle Line to Victoria
Take Victoria Line to Oxford Circus
Take Victoria Line to Victoria
Take Victoria Line to Victoria
Take District Line to Gunnersbury
#Now, get 2
Take District Line to Acton Town
Take Piccadilly Line to Heathrow Terminals 1, 2, 3
Take Piccadilly Line to Acton Town
Take District Line to Acton Town
Take District Line to Parsons Green
Take District Line to Parsons Green
Take District Line to Parsons Green
#Get 'x...'
Take District Line to Gunnersbury #ACC: 'Ox'
Take District Line to Acton Town
Take District Line to Acton Town
Take Piccadilly Line to Turnpike Lane
Take Piccadilly Line to Turnpike Lane
#Get 120
Take Piccadilly Line to Holborn
Take Central Line to Holborn
Take Central Line to Tottenham Court Road
Take Central Line to Tottenham Court Road
Take Northern Line to Charing Cross
Take Northern Line to Charing Cross #ACC: 120
#Move to PR
Take Northern Line to Moorgate
Take Circle Line to Moorgate
Take Metropolitan Line to Preston Road #PR: 120
#get 65
Take Metropolitan Line to Amersham
Take Metropolitan Line to Moorgate
Take Circle Line to Moorgate
Take Northern Line to Charing Cross
Take Northern Line to Charing Cross
Take Northern Line to Moorgate
Take Circle Line to Moorgate
#get '7'
Take Metropolitan Line to Preston Road #ACC:55 PR:65
Take Metropolitan Line to Moorgate
Take Circle Line to Moorgate
Take Northern Line to Charing Cross
Take Northern Line to Charing Cross
Take Northern Line to Moorgate
Take Northern Line to Moorgate
Take Circle Line to Paddington #PAD: '7' 
##Plan: get 85
#get 4
Take District Line to Parsons Green #int from Pad triggers swap
Take District Line to Parsons Green #ACC: 3
Take District Line to Wimbledon #Wi: 3
Take District Line to Acton Town
Take Piccadilly Line to Heathrow Terminal 4
Take Piccadilly Line to Acton Town
Take District Line to Acton Town
Take District Line to Parsons Green #ACC: 4
#put 4 at MH
Take District Line to Acton Town
Take District Line to Acton Town
Take Piccadilly Line to Manor House
#get 81
Take Piccadilly Line to Holborn
Take Central Line to Queensway
Take Central Line to Tottenham Court Road
Take Central Line to Tottenham Court Road
Take Northern Line to Charing Cross
Take Northern Line to Charing Cross #ACC: 81
# ~~(81 | 4) == 85
Take Northern Line to Tottenham Court Road
Take Central Line to Tottenham Court Road
Take Central Line to Holborn
Take Central Line to Holborn
Take Piccadilly Line to Manor House #ACC: ~85, nor: 81
Take Piccadilly Line to Holborn
Take Central Line to Holborn
Take Central Line to Notting Hill Gate
Take Central Line to Notting Hill Gate #ACC: 85
#get 'U'
Take Circle Line to Moorgate
Take Circle Line to Moorgate
Take Northern Line to Charing Cross
Take Northern Line to Charing Cross #ACC: 'U'
#concat 'U'
Take Northern Line to Moorgate
Take Circle Line to Moorgate
Take Circle Line to Paddington
Take Circle Line to Paddington #PAD: '7U'
##Plan: Get 66
#get 32
Take District Line to Parsons Green #ACC: 7
Take District Line to Gunnersbury #Gu: 7
Take District Line to Richmond #Ri: 2
Take District Line to Acton Town
Take Piccadilly Line to Covent Garden
Take Piccadilly Line to Acton Town
Take District Line to Acton Town
Take District Line to Gunnersbury #ACC: 'Covent '
Take District Line to Acton Town
Take District Line to Acton Town
Take Piccadilly Line to Turnpike Lane
Take Piccadilly Line to Turnpike Lane
Take Piccadilly Line to Holborn
Take Central Line to Holborn
Take Central Line to Tottenham Court Road
Take Central Line to Tottenham Court Road
Take Northern Line to Charing Cross
Take Northern Line to Charing Cross #ACC: 32
#Get 64
Take Northern Line to Moorgate
Take Northern Line to Moorgate
Take Metropolitan Line to Chalfont & Latimer
Take Metropolitan Line to Moorgate
Take Circle Line to Temple
Take District Line to Richmond #ACC: 2
Take District Line to Temple
Take Circle Line to Moorgate
Take Circle Line to Moorgate
Take Metropolitan Line to Chalfont & Latimer #ACC: 64, tim: 2
# ~~(64 | 2) == 66
Take Metropolitan Line to Rayners Lane
Take Metropolitan Line to Chalfont & Latimer
Take Metropolitan Line to Rayners Lane
Take Metropolitan Line to Rayners Lane
Take Piccadilly Line to Oakwood
Take Piccadilly Line to Manor House
Take Piccadilly Line to Oakwood #Oak: 81
Take Piccadilly Line to Manor House
Take Piccadilly Line to Rayners Lane
Take Piccadilly Line to Manor House #ACC: ~66, nor: 64
Take Piccadilly Line to Holborn
Take Central Line to Holborn
Take Central Line to Notting Hill Gate
Take Central Line to Notting Hill Gate #ACC: 66
#get 'B'
Take Circle Line to Moorgate
Take Circle Line to Moorgate
Take Northern Line to Charing Cross
Take Northern Line to Charing Cross
#concat 'B'
Take Northern Line to Moorgate
Take Circle Line to Moorgate
Take Circle Line to Paddington
Take Circle Line to Paddington #PAD: '7UB'
##Plan: get 69
#Get 5
Take District Line to Acton Town
Take Piccadilly Line to Heathrow Terminal 5
Take Piccadilly Line to Acton Town
Take Piccadilly Line to Acton Town
Take District Line to Parsons Green #ACC: 5
# ~~(64 | 5) == 69
Take District Line to Acton Town
Take District Line to Acton Town
Take Piccadilly Line to Manor House #ACC: ~69, nor: 5
Take Piccadilly Line to Holborn
Take Central Line to Holborn
Take Central Line to Notting Hill Gate
Take Central Line to Notting Hill Gate #ACC: 69
#get 'E'
Take Circle Line to Moorgate
Take Circle Line to Moorgate
Take Northern Line to Charing Cross
Take Northern Line to Charing Cross
#concat 'E'
Take Northern Line to Moorgate
Take Circle Line to Moorgate
Take Circle Line to Paddington
Take Circle Line to Paddington #PAD: '7UBE'
##Plan: get 83
#Place 81 at nor
Take District Line to Acton Town
Take Piccadilly Line to Manor House #nor: 'B7UB'
Take Piccadilly Line to Oakwood #ACC: 81, Oak: 5
Take Piccadilly Line to Manor House #nor: 81
#get 2 == 65 % 3
Take Piccadilly Line to Acton Town
Take District Line to Wimbledon #ACC: 3
Take District Line to Temple
Take Circle Line to Moorgate
Take Circle Line to Moorgate
Take Metropolitan Line to Preston Road #ACC: 2
# ~~(81 | 2) == 83
Take Metropolitan Line to Rayners Lane
Take Metropolitan Line to Rayners Lane
Take Piccadilly Line to Manor House #ACC ~83
Take Piccadilly Line to Holborn
Take Central Line to Holborn
Take Central Line to Notting Hill Gate
Take Central Line to Notting Hill Gate #ACC: 83
#get 'S'
Take Circle Line to Moorgate
Take Circle Line to Moorgate
Take Northern Line to Charing Cross
Take Northern Line to Charing Cross
#concat 'S'
Take Northern Line to Moorgate
Take Circle Line to Moorgate
Take Circle Line to Paddington #PAD: '7UBES'
Take Circle Line to Moorgate
Take Circle Line to Moorgate
Take Northern Line to Mornington Crescent

Try it online! (without comments)

†: Pardon me for the 1337-speak, my options are limited: each valid program in this language ends with Take Northern Line to Mornington Crescent.

| improve this answer | |
\$\endgroup\$
  • \$\begingroup\$ Cracked \$\endgroup\$ – pppery Jul 28 at 17:08
4
\$\begingroup\$

Scala, score: 2 Cracked

(.

Shouldn't be too hard to crack.

Edit: Guess I was right :/

The code I used:

 object Main extends App {
   def f: String => Unit = println _
   this f "\u0028\u002e"
 }

| improve this answer | |
\$\endgroup\$
  • \$\begingroup\$ I'd crack it, but I don't know Scala. \$\endgroup\$ – PkmnQ Jul 25 at 16:32
  • 1
    \$\begingroup\$ Cracked, unless the main method declaration can't use ( either (it works fine in a repl). \$\endgroup\$ – nthistle Jul 25 at 17:28
4
\$\begingroup\$

Ruby, score 6, cracked by @nthistle

p<.$a1

Not intended to output via error, although I also don't think it's possible to do so without a lot of other characters.

| improve this answer | |
\$\endgroup\$
  • 1
    \$\begingroup\$ I'm not sure how you could get p<.$a1 as a ruby error, but you're fine to say so. \$\endgroup\$ – Wheat Wizard Jul 25 at 18:46
  • 1
    \$\begingroup\$ Cracked \$\endgroup\$ – nthistle Jul 25 at 20:20
4
\$\begingroup\$

CJam, score 6 (Cracked)

"aces'

This will more than likely get cracked, but I couldn't quite manage to make it harder. Hopefully this is difficult enough that it remains open for a little while.

Update: 5 hours, I'll take it. My solution:

1`{15-}%135`{48+}%1`{66+}%1`{10-}%

| improve this answer | |
\$\endgroup\$
  • \$\begingroup\$ I'd try, but I don't know CJam. It seems some things are missing from the PDF. Like the double quotes. Sure, that might be obvious, but I don't know what else is missing. \$\endgroup\$ – PkmnQ Jul 26 at 6:55
  • \$\begingroup\$ Cracked \$\endgroup\$ – user92069 Jul 26 at 8:05
  • \$\begingroup\$ @PkmnQ If you're referring to the PDF here, that's only meant as a cheatsheet. I use that PDF for the basics but defer to the wiki on the Sourceforge (which I thought I linked, sorry) for detailed documentation. \$\endgroup\$ – Ethan Chapman Jul 26 at 14:05
  • \$\begingroup\$ @Ethan Chapman Well, time for me to learn CJam and use it for a few weeks, then change to another golfing language. \$\endgroup\$ – PkmnQ Jul 26 at 14:55
4
\$\begingroup\$

C (gcc), score 4 (Cracked)

#_ep

My source code doesn't contain any of these characters and when complied and run, it outputs #_ep to stdout.

| improve this answer | |
\$\endgroup\$
  • \$\begingroup\$ Cracked. Interesting question, I have never had to use inline assembly before. \$\endgroup\$ – xibu Jul 26 at 18:19
  • \$\begingroup\$ @xibu You got it bang on! Well done! :-) \$\endgroup\$ – Noodle9 Jul 26 at 19:04
4
\$\begingroup\$

R, Score=23 cracked by Robin Ryder

0123456789+-*/^!&|%`()$

This has a worse score than Robin Ryder's currently-latest R challenge, but if you crack this you'll probably crack his one, too.

| improve this answer | |
\$\endgroup\$
  • 1
    \$\begingroup\$ Clearly, my challenge is easier, as I have a solution to mine but not yours. For yours, without `(), we can't even call functions!? \$\endgroup\$ – Robin Ryder Jul 26 at 13:31
  • \$\begingroup\$ @RobinRyder we have '=<>?~" so we can reassign some functions if we are clever... \$\endgroup\$ – Giuseppe Jul 26 at 15:16
  • \$\begingroup\$ @Giuseppe Indeed! I'm so used to using backticks when reassigning functions that I had forgotten quotes worked as well. We are also allowed [], which should be useful. \$\endgroup\$ – Robin Ryder Jul 26 at 19:35
  • 1
    \$\begingroup\$ Cracked! (with a lot of sweat!) \$\endgroup\$ – Robin Ryder Jul 26 at 22:11
4
\$\begingroup\$

BBC Basic II, Score: 2, Cracked

One more example in a "non-golfing" language:

VP

(I tested my program on an Acorn BBC model B emulator and on an Acorn Archimedes emulator. However, according to the BBC Basic manual I found in the internet, it should work on "modern" BBC Basic versions for the PC, too.)


My solution:

The solution in the crack directly writes to the display memory of the BBC model B. This means that the solution would not work on an Archimedes, an x86-based machine or on a second CPU (tube) of a BBC.

My solution uses a special feature of BBC Basic:

On 6502-based computers (like the BBC), the CALL command calls some assembly function located at a certain address. The value in the variable A% is written to the A register before calling the function.

On non-6502 systems (ARM or x86), the CALL command normally works in a similar way; however, if the parameter is the address of an operating system routine of the 6502 operating system, the BASIC does not interpret the argument as address of an ARM or x86 assembly language routine. Instead, the CALL command will more or less emulate a call to the OS of a 6502-based computer for such arguments.

For this reason CALL 65518 will always write the byte represented by the value in variable A% to the "standard output" - even on ARM-based computers where 65518 is not a valid code address!

Using this feature, the solution is quite simple:

10 A%=80
20 CALL 65518
30 A%=86
40 CALL 65518

| improve this answer | |
\$\endgroup\$
  • 1
    \$\begingroup\$ I've never touched any assembly in my life and I'm feeling like that's what I need to do here... Slowly making progress though! \$\endgroup\$ – Dom Hastings Jul 27 at 18:29
  • \$\begingroup\$ @DomHastings Maybe. You will see when the answer is cracked or one week is over. However, you should keep in mind that assembly language differs on different CPU types: I wrote in my comment that my program works on the BBC (6502 CPU), on the Archimedes (ARM CPU) and with a high probability on the PC (x86 CPU), too. \$\endgroup\$ – Martin Rosenau Jul 28 at 5:02
  • 3
    \$\begingroup\$ Cracked. \$\endgroup\$ – Dominic van Essen Jul 29 at 11:02
  • 1
    \$\begingroup\$ Thankyou very much for this challenge! I haven't written BBC BASIC for many years, and this was a lot of nostagic fun! \$\endgroup\$ – Dominic van Essen Jul 29 at 11:24
4
\$\begingroup\$

Perl 5, Score: 80, Cracked

!"'*+,-0123456789:;<?@ABCDEFGHIJKLMNOPQRSTUVWXYZ\^`abcdefghijklmnopqrstuvwxyz{|~

This means that the following printable ASCII characters are permitted:

 #$%&()./=>[]_}

Inspired by Dom Hastings's challenges (1, 2, 3) and my solutions (1, 2, 3).

| improve this answer | |
\$\endgroup\$
  • \$\begingroup\$ So, I have a solution, but it relies on an implementation detail and a low-byte char, so I imagine it's not quite right... I'm going to continue just in case I can figure out a more portable way... \$\endgroup\$ – Dom Hastings Jul 28 at 20:22
  • \$\begingroup\$ @DomHastings My solution only uses ASCII characters, but I'd be curious to see what you can gain with an unprintable character: I didn't find a way to make use of one until I no longer had any use for it. My solution technically uses an implementation detail, but one that works very broadly. \$\endgroup\$ – Gilles 'SO- stop being evil' Jul 28 at 21:51
  • \$\begingroup\$ Cracked, although if this isn't the intended solution, adding \x18 to the output would give me another chance to figure out how to generate a! \$\endgroup\$ – Dom Hastings Jul 29 at 16:56
  • \$\begingroup\$ @DomHastings Nice! Pretty different from my solution. I'm going to make another challenge that forbids $^X, but first I want to try and see if I can close another loophole. \$\endgroup\$ – Gilles 'SO- stop being evil' Jul 29 at 17:49
  • \$\begingroup\$ @DomHastings Here we go. In addition to forbidding some control variables with system-dependent content, I'm also trying to steer you away from constructing numbers as the length of a list. If you're stuck, start with / instead of ?, it lets you do pretty interesting things, but I eventually decided that it was an unnecessary indulgence. \$\endgroup\$ – Gilles 'SO- stop being evil' Jul 30 at 1:38
4
\$\begingroup\$

Rust, score 2 32, Cracked

pw

pw?@ABCDEFGHIJKLMNOPQSTUXYZ!"#$%

Pretty challenging to output to stdout without being able to type print or write!

Rust version: rustc 1.45.1 (c367798cf 2020-07-26)

| improve this answer | |
\$\endgroup\$
4
\$\begingroup\$

R, Score=30, safe

t <-
"$&0123456789=?[\\^`lv{|"

A trickier version of my previous challenge, which Dominic van Essen cracked in a few hours. Without t you cannot easily use get or cat, and without l you cannot use ls, eval, do.call or el.

Hopefully this time you will have to come closer to my intended solution!


Solution :

The key is to use the function dump to print. This function produces a text representation of objects, i.e. R code to recreate the objects. All we need to do is assign to t the character string "$&0123456789=?[\\^lv{|", and then use dump('t','').

This requires two tricks. First, to create strings, we shall use rawToChar(as.raw(NNN)) where NNN is the ASCII code of the characters. Such integers can be created with T+T+T+...+T. Second, since we cannot assign using =, <- or ->, we use the function assign. Conveniently, this requires the object name to be given as a string, so we can also define the object name with rawToChar(as.raw(NNN)).

In order to make the solution more readable, I have added spaces and newlines, and I have written the integers directly rather than as T+T+T+...+T. The TIO gives the complete solution.

assign(rawToChar(as.raw(116)), rawToChar(as.raw(c(36, 38, 48:57, 61, 63, 91, 92, 94, 96, 108, 118, 123, 124))))
dump(rawToChar(as.raw(116)), '')

Try it online!

| improve this answer | |
\$\endgroup\$
  • \$\begingroup\$ Hmm... I notice that you're suspiciously still allowing 'e' and 'a'... \$\endgroup\$ – Dominic van Essen Jul 28 at 9:28
  • \$\begingroup\$ @DominicvanEssen I'm trying not to give too much away, it was used against me in my first challenge! \$\endgroup\$ – Robin Ryder Jul 28 at 9:29
  • 2
    \$\begingroup\$ Congratulations Robin! I got as far asdump(), assign() and (of course) the integers, but rawToChar(as.raw()) eluded me! Good challenge! \$\endgroup\$ – Dominic van Essen Aug 4 at 15:12
  • 1
    \$\begingroup\$ Congrats! rawToChar threw me too! I did not know about dump, though, good one to file away for future reference. \$\endgroup\$ – Giuseppe Aug 4 at 15:13
  • \$\begingroup\$ @Giuseppe I've just used dump to create a new (shortest) R quine. I've been sitting on this function since I discovered it 10 days ago! \$\endgroup\$ – Robin Ryder Aug 4 at 15:30
4
\$\begingroup\$

Wolfram Language (Mathematica), score: 71 (safe)

AbCdEfGhIjKlMnOpQrStUvWxYz
⁢{@[0 & ], \" <-> (.|), +*/, 123456789[]}

There are 4 characters preceding the { on the second line: invisible times (U+2062) followed by 3 private use characters (U+F39E, U+F765, U+F76D), in ascending order.


My solution

The exclusions of [], @, /, and \[InvisibleApply] mean that, apart from special forms, only the infix ~ ~ can be used to apply functions.

In order to allow application of functions with a number of arguments other than 2, we need a way to generate Sequences. Defining one of Mathematica’s built-in undefined bracketing operators allows us to do this:

〈$___〉:=$

Now, 〈〉 is a Sequence[]. As commas (and \[InvisibleComma]) are not permitted, we also define

$_·$$___=〈〉~$~$$

which allows us to apply an arbitrary head to an arbitrarily long list of arguments, without commas.

Now, to generate heads to apply. Note that Names is permitted. Names·__ generates a list of names we can index into, and we can generate positive numbers with sufficient abuse of π/Pi, (Sqrt), ⌊ ⌋ (Floor), ⌈ ⌉ (Ceiling), ^ (Power), and juxtaposition, using 〈 〉 as parentheses, for multiplication.

There’s one last thing: values returned from Names are Strings, not Symbols. Applying Symbol to a string returns a symbol with that name, though, and every symbol has the head Symbol. We can extract it by taking its 0th part. While the operations we used earlier can’t generate 0, ' (Derivative) can (As an aside, my version of Mathematica evaluates N' to 1&, but TIO’s evaluates the same expression to 0&). For the sake of convenience, again:

±$_:=〈Names·__〉〚$〛;∓$_:=N〚N''·〈〉〛·±$

(We actually didn’t need ·: we can build arbitrarily long expressions with #1~〈〉〚N''〛~#2~〈〉〚N''〛~...~head~#k, but · is much nicer to look at)

and we can put the parts together to make:

〈$___〉:=$;$_·$$___=〈〉~$~$$;±$_:=〈Names·__〉〚$〛;∓$_:=N〚N''·〈〉〛·±$;$=〈∓〈⌊〈√〈⌊π⌋^π〉〉〈〈〈π〉π〉^⌊π⌋〉⌋〉·〈∓〈⌈〈√√⌊π⌋〉〈〈√π〉^⌈π⌈π⌉⌉〉⌉〉·〈⌈〈π〉〈π^〈π〉〉⌉〉〉·〈∓〈⌈〈√√⌊π⌋〉〈〈√π〉^⌈π⌈π⌉⌉〉⌉〉·〈⌊〈π〉⌈π^π⌉⌋〉〉·〈∓〈⌈〈√√⌊π⌋〉〈〈√π〉^⌈π⌈π⌉⌉〉⌉〉·〈⌈〈π〉〈⌊π⌋^π〉⌉〉〉·〈∓〈⌈〈√√⌊π⌋〉〈〈√π〉^⌈π⌈π⌉⌉〉⌉〉·〈⌊π⌋⌈π^π⌉〉〉·〈∓〈⌈〈√√⌊π⌋〉〈〈√π〉^⌈π⌈π⌉⌉〉⌉〉·〈⌈〈π〉⌈π^π⌉⌉〉〉·〈∓〈⌈〈√√⌊π⌋〉〈〈√π〉^⌈π⌈π⌉⌉〉⌉〉·〈⌊〈π〉⌈π^π⌉⌋〉〉〉;∓〈〈⌈⌈π⌉^π⌉〉〈⌈〈√π〉〈π^〈π〉〉⌉〉〉·$·〈∓〈⌊〈⌈π⌉^π〉〈⌊〈√π〉〈⌊π^〈π〉⌋〉⌋〉⌋〉·∓〈⌊〈⌈π^π⌉^〈√π〉〉〈⌈π⌉〈√⌊π⌋〉〉⌋〉·∓〈⌊〈⌊〈π〉〈⌊π⌋^π〉⌋〉^√⌊π⌋⌋〉〉;∓〈⌈〈π^⌊π⌋〉〈⌈〈π〉〈⌈π⌉^⌊π⌋〉⌉〉⌉〉·$·〈∓〈⌊〈√〈⌊π⌋^π〉〉〈〈〈π〉π〉^⌊π⌋〉⌋〉·〈∓〈⌈〈√〈〈π〉⌈π⌉〉〉^〈⌊π⌋^√⌊π⌋〉⌉〉·〈∓〈⌈〈⌈π⌉^〈√π〉〉〈〈⌊π^〈π〉⌋〉^√⌊π⌋〉⌉〉·〈〈∓〈⌈⌈π⌉〈〈〈π〉π〉^√⌊π⌋〉⌉〉·〈〉〉〚;;;;〈√⌈π⌉〉〛〉〉·〈∓〈⌈⌈π⌉〈〈〈π〉π〉^√⌊π⌋〉⌉〉·〈〉〉〚〈√⌈π⌉〉;;;;〈√⌈π⌉〉〛〉〉·〈∓〈⌈〈√√⌊π⌋〉〈〈√π〉^⌈π⌈π⌉⌉〉⌉〉·〈⌈〈π〉π⌉〉〉·〈∓〈⌈〈√√⌊π⌋〉〈〈√π〉^⌈π⌈π⌉⌉〉⌉〉·〈⌊〈〈π〉〈〈π〉⌊π⌋〉〉〈⌈〈π^⌊π⌋〉〈⌊〈π〉π⌋〉⌉〉⌋〉〉·〈∓〈⌈〈√√⌊π⌋〉〈〈√π〉^⌈π⌈π⌉⌉〉⌉〉·〈⌊〈π〉π〈⌈〈√⌈π⌉〉〈⌈π⌈π⌉⌉^π〉⌉〉⌋〉〉·〈∓〈⌈〈√√⌊π⌋〉〈〈√π〉^⌈π⌈π⌉⌉〉⌉〉·〈〈〈⌊〈π〉π⌋〉〈⌊π^⌊π⌋⌋〉〉〈⌈〈√⌊π⌋〉^〈〈π〉π〉⌉〉〉〉·〈∓〈⌈〈√√⌊π⌋〉〈〈√π〉^⌈π⌈π⌉⌉〉⌉〉·〈⌊π^⌈π⌉⌋⌊〈π^⌈π⌉〉〈⌊π⌋^√⌊π⌋〉⌋〉〉·〈∓〈⌊〈√〈⌈π^⌊π⌋⌉〉〉〈⌈〈π^〈π〉〉^〈√π〉⌉〉⌋〉·〈〈∓〈⌈〈√√⌊π⌋〉〈〈√π〉^⌈π⌈π⌉⌉〉⌉〉·〈⌈π⌉^⌊π⌋〉〉·〈N''〉〉·〈∓〈⌊〈⌊π⌋〈√π〉〉^〈⌊π⌋〈√⌊π⌋〉〉⌋〉·〈∓〈⌊〈√〈⌊π⌋^π〉〉〈〈〈π〉π〉^⌊π⌋〉⌋〉·〈∓〈⌈〈√√⌊π⌋〉〈〈√π〉^⌈π⌈π⌉⌉〉⌉〉·〈⌈〈π〉〈⌊〈π〉〈〈π〉⌊π⌋〉⌋〉⌉〉〉·〈∓〈⌈〈√√⌊π⌋〉〈〈√π〉^⌈π⌈π⌉⌉〉⌉〉·〈⌈√〈〈〈π〉⌊π⌋〉^π〉⌉〉〉〉·〈∓〈⌊〈√〈⌊π⌋^π〉〉〈〈〈π〉π〉^⌊π⌋〉⌋〉·〈∓〈⌈〈√√⌊π⌋〉〈〈√π〉^⌈π⌈π⌉⌉〉⌉〉·〈⌈π⌉〈⌈〈π〉π⌉〉〉〉·〈∓〈⌈〈√√⌊π⌋〉〈〈√π〉^⌈π⌈π⌉⌉〉⌉〉·〈⌊⌈π⌉〈⌈π⌉^〈√π〉〉⌋〉〉·〈∓〈⌈〈√√⌊π⌋〉〈〈√π〉^⌈π⌈π⌉⌉〉⌉〉·〈⌈π⌉〈⌊π^⌊π⌋⌋〉〉〉·〈∓〈⌈〈√√⌊π⌋〉〈〈√π〉^⌈π⌈π⌉⌉〉⌉〉·〈⌈〈π〉⌈π⌈π⌉⌉⌉〉〉〉〉·〈∓〈⌊〈√〈⌊π⌋^π〉〉〈〈〈π〉π〉^⌊π⌋〉⌋〉·〈∓〈⌈〈√√⌊π⌋〉〈〈√π〉^⌈π⌈π⌉⌉〉⌉〉·〈⌊〈√⌈π⌉〉^〈〈π〉〈√⌊π⌋〉〉⌋〉〉·〈∓〈⌈〈√√⌊π⌋〉〈〈√π〉^⌈π⌈π⌉⌉〉⌉〉·〈⌈〈π^⌊π⌋〉〈√〈√π〉〉⌉〉〉·〈∓〈⌈〈√√⌊π⌋〉〈〈√π〉^⌈π⌈π⌉⌉〉⌉〉·〈⌊〈√π〉〈⌊π⌋^⌊π⌋〉⌋〉〉〉·〈〈∓〈⌊〈√〈⌊π⌋^π〉〉〈〈〈π〉π〉^⌊π⌋〉⌋〉·〈〈∓〈⌊〈√〈⌈π⌉^π〉〉〈〈⌊π⌋^π〉^√⌊π⌋〉⌋〉·∓〈〈⌈π^⌈π⌉⌉〉〈⌊〈⌈〈π〉π⌉〉^〈√π〉⌋〉〉〉·〈∓〈⌈〈〈π〉〈√⌊π⌋〉〉〈〈⌊π⌋^π〉〈⌊π⌋^⌊π⌋〉〉⌉〉·〈⌊〈π〉π⌋〉〉〉〉·〈〉〉〉

Try it online!

On the current version of Mathematica on TIO, this is equivalent to

$= StringJoin[FromCharacterCode[115], FromCharacterCode[116], FromCharacterCode[100], FromCharacterCode[111], FromCharacterCode[117], FromCharacterCode[116]]; (* "stdout" *)
WriteString[$, StringJoin[Riffle[ToUpperCase[Alphabet[]〚;;;;2〛], Alphabet[]〚2;;;;2〛]], FromCharacterCode[10], FromCharacterCode[8290], FromCharacterCode[62366], FromCharacterCode[63333], FromCharacterCode[63341], List[FromCharacterCode[64][N''], TwoWayRule[StringJoin[FromCharacterCode[92], FromCharacterCode[34]], StringJoin[FromCharacterCode[40], FromCharacterCode[46], FromCharacterCode[124], FromCharacterCode[41]]], StringJoin[FromCharacterCode[43], FromCharacterCode[42], FromCharacterCode[47]], StringJoin[Map[ToString][Range[9]]][]]]

This could also just be put together with FromCharacterCode alone. WriteString is required here to suppress the trailing newline, and to get special characters to print verbatim instead of as \[name] (and yes, $Output would have been much shorter to generate than "stdout").

| improve this answer | |
\$\endgroup\$
  • \$\begingroup\$ Are Mathematica-specific fancy characters (that keep getting converted to \[Something]) allowed? \$\endgroup\$ – the default. Jul 29 at 9:27
  • \$\begingroup\$ @mypronounismonicareinstate yes. \$\endgroup\$ – att Jul 29 at 17:47
4
\$\begingroup\$

Stack Cats, Score: 3, Safe

)*(

All Stack Cats programs are symmetrical, and the reflection of a command undoes the original.

As a result, every program with an even length either runs forever or does some work, then immediately undoes that work, and devolves into a cat program. The only way to write something else is to use an odd number of characters and let the center give structure to the rest of the code.

If you want to run the code xyz, the easiest approach is to use a structure like <(zyx)*(xyz)>, which completely skips the first half. This is boring, so I’ve made that construction impossible.

Naturally, the output is also symmetrical :)

Solution:

_+!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_[!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_]_:_[_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!]_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!_!+_

Try it online!

Explanation:

For this explanation, s[0] is the top of a stack, s[1] is the element below s[0], and a stack is written [top, middle, bottom]

Here's what the stack looks like after each step. I’ll use a number to represent how many !_ / _! pairs are used:

_+       # [0, 0, 1]
62       # [62, 0, 1]
[152]    # [214, 0, 1]    
_:_      # [-214, -214, 1]
[152]    # [-366, -214, 1]
62       # [12840, -214, 1]
+_       # [-215, -214, 12840]

This approach is mostly built around !_ and its reflection _!. _ sets s[0] = s[1] - s[0], and ! sets s[0] to its bitwise negation. When s[1] is 0, !_ increments the top of the stack and _! decrements it.

In the first half of the program, [ moves the top element to a different stack and continues incrementing it there, then ] moves it back. By itself, this is pointless, but those characters are important in the second half. The code increments the top of the stack 214 times (62 + 152).

In the center, _:_ negates the top of the stack and sets s[1] = s[0]. [152] moves the top element to its own stack, decrements it 152 times, then puts it back on the primary stack. Now that the stack has a nonzero s[1], _! no longer decrements the top, but sets s[0] = !(-214 - s[0]) 62 times.

Once the program ends, the stack has the values [-215, -214, 12840]. These are output mod 256, giving [41, 42, 40], which in ASCII makes )*(

| improve this answer | |
\$\endgroup\$
4
\$\begingroup\$

Python 3.7, Score: 7, Cracked by Ethan White

(nuvwxy

Inspired by Tips for restricted source in Python.

This should block eval and exec, function calls that don't use the __class_getitem__ trick, and most forms of output (print, write, etc.)

My solution only uses ASCII characters.

My Solution

class C:__class_getitem__=chr
class D:__class_getitem__=dir
class M:__class_getitem__=__import__
    
code = M[C[99]+C[111]+C[100]+C[101]]  # Import code
i_spect = M[C[105]+C[110]+C[115]+C[112]+C[101]+C[99]+C[116]]  # Import inspect
    
I = code.__dict__[D[code][2]]  # I = code.InteractiveInterpreter
class A:__class_getitem__=I.__call__
e = A[{}]  # Instantiate InteractiveInterpreter({})
    
class S:__class_getitem__=i_spect.getmembers.__call__
class R:__class_getitem__=S[e][28][1]  # Get the runcode method

z=C[112]+C[114]+C[105]+C[110]+C[116]+C[40]+C[34]+C[92]+C[34]+C[39]+C[40]+C[110]+C[117]+C[118]+C[119]+C[120]+C[121]+C[34]+C[41]

R[z]  # Run the constructed print statement

My approach was to use code.InteractiveInterpreter().runcode() as an alternate version of exec. Since I blocked n, I couldn't type that class or method directly, so I imported InteractiveInterpreter and inspect by constructing strings and passing them to __import__, then used dir and inspect.getmembers to get the runcode method, then passed in a string to execute.

I had a lot of fun coming up with this convoluted approach, but I didn't realize timeit was a much simpler version of exec that avoided this complexity, and there's no way to block timeit without also blocking __class_getitem__.

| improve this answer | |
\$\endgroup\$
3
\$\begingroup\$

Befunge 98, Score: 4, cracked

=sp,

Trying to prove ovs' claim that "I don't think this can be made harder in Befunge" wrong. (This answer may still be too easy, but I can say for sure that it is harder than the other one, because I've blocked both self-modifying code operators)

Intended solution:

"PAMI"4('+1+'o1+'r1+'<1+'+1+'ZMZZZZ@

| improve this answer | |
\$\endgroup\$
  • 2
    \$\begingroup\$ Are fingerprints allowed? \$\endgroup\$ – ovs Jul 25 at 20:52
  • \$\begingroup\$ "You may be as specific or precise in choosing your language as you wish.". I was very un-specific about what language in the header I used, so any Befunge 98 interpreter can be used the crack this answer, regardless of what features it supports or doesn't support. \$\endgroup\$ – pppery Jul 25 at 20:56
  • \$\begingroup\$ Cracked (using a fingerprint): codegolf.stackexchange.com/a/207607 \$\endgroup\$ – the default. Jul 26 at 7:56
  • \$\begingroup\$ This can also be done with the ORTH and the IMAP fingerprint. \$\endgroup\$ – ovs Jul 26 at 8:45
  • \$\begingroup\$ The intended solution was using IMAP. (I was deliberately vague about whether fingerprints were allowed earlier in an attempt to avoid giving the fact that I used them away). Ah, well, this answer still served its purpose, because it lasted 13 hours, and the previous answer lasted less than an hour, so it was definitely harder) \$\endgroup\$ – pppery Jul 26 at 13:55
3
\$\begingroup\$

C, score 2 (cracked)

Output {; to stdout.

Probably not that difficult, but I was quite surprised when I first saw this C feature.

| improve this answer | |
\$\endgroup\$
3
\$\begingroup\$

Python 2, Score: 7 (Cracked)

cdnsvw,

Note: There is no newline at the end

| improve this answer | |
\$\endgroup\$
3
\$\begingroup\$

R, Score=14 cracked by Giuseppe

0123456789([aE

My previous challenge was cracked (embarassingly within less than a day) using indexed-retrieval of the searched-for characters from within larger expressions/strings.

This challenge is intended to make that approach more difficult.

Solution

Giuseppe's crack was different in several places, so here's the solution that I had in mind when I posed the challenge:

    # make some numbers:
    zero=T-T
    two=T+T
    three=T+T+T
    one=three-two
    four=T+T+T+T
    five=T+T+T+T+T
    six=T+T+T+T+T+T
    seven=T+T+T+T+T+T+T
    eight=T+T+T+T+T+T+T+T
    nine=T+T+T+T+T+T+T+T+T
    ten=nine+one

    # zero to nine is the first series of digits in the output string:
    zerotonine=zero:nine

    # 40, 69 and 91 are the ASCII values of ([ and E
    forty=ten+ten+ten+ten
    sixtynine=forty+ten+ten+ten-one
    ninetyone=forty+forty+ten+one

    # now we need to get some of the 'forbidden' functions
    # first we use 'tolower' to get the (lowercase) function names of 'apropos',
    # 'tail' and 'cat' (so we avoid the the lower-case letter 'a')
    ~=tolower
    b=~'APROPOS'
    A=~'A'
    t=~'TAIL'
    c=~'CAT'

    # Now we can use 'get()' to get the functions from the names
    ?=get
    ~=?b          # apropos()
    i=~'intToUtf'   # look-up the full-length 'intToUtf8' function name
    !=?i          # intToUtf8()

    # Now we've got 'intToUtf8()' we can create the forbidden characters
    p=!forty;b=!ninetyone;e=!sixtynine

    # We want to paste them all together with no separator.  Since we can't easily give
    # multiple arguments to a function (because we're always replacing binary operators),
    # we need to construct 'paste0'.  This is the second function looked-up using
    # 'PAST' (without the final E), so we use 'tail()' to get it.
    -=?t
    pp=~'PAST'
    ppp=pp-one
    +=?ppp

# Finally, we build our string using our new 'paste0' function, and use 'cat()' # to output it: string=zero+one+two+three+four+five+six+seven+eight+nine+p+b+A+e ~=?c ~string

Try it online!

| improve this answer | |
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.