60
11
The robbers thread can be found here: The Mystery String Printer (Robbers)
Your challenge
- Write a program, function, or REPL script that prints a string to STDOUT.
- The robbers will try to create a program that prints the same string.
- If they successfully can create the program within 7 days, your submission is cracked.
- If nobody can create a program that prints the same string within 7 days, your submission is safe. You may choose to reveal your program, or leave it to challenge future robbers. However, if you don't reveal it, you can't get any points from your submission (don't put "safe" in your answer header if you choose to do this).
Restrictions
- The program must be less than or equal to 128 bytes total (more on this later).
- If the program depends on the program name, or the name/contents of an external file, you must say that it does so, and include this in your total byte count.
- The printed string must be less than or equal to 2048 bytes.
- The printed string must consist of only printable ASCII characters (new lines can be included).
- The program must produce the same output every time that it is run.
- Built-in cryptographic primitives (includes any rng, encryption, decryption, and hash) aren't allowed.
- The program must not take input.
- No standard loopholes.
Scoring
- If a submission is cracked before seven days, the submission earns 0 points.
- A safe submission of ≤128 characters earns 1 point.
- A safe submission of ≤64 characters earns 2 points. If it's less than or equal to 32 bytes, it earns 4 points, and so on.
- Each safe submission also earns an additional 3 point bonus (independent of the length).
- There is a tiny (1/2 point) penalty for every cracked after your first one.
- Note that the robber's solution has to be in the same range of program lengths.
- Each person may submit a maximum of 1 program per byte range per language (different versions and arbitrary substitutions of the same language don't count as separate languages). Example: you can post a 32 byte and a 64 byte pyth program, but you can't post a 128 byte program in both Java 7 and Java 8.
- The person with the highest point total wins.
Submissions
Each submission must have the following pieces of information:
- The name of the language. All new robbers' solutions must be the same language.
- The range of the program size (this is the nearest power of two higher than the size of the program; for example, if your program is 25 bytes, this would be "≤32").
- The actual string to be printed out.
- If a submission is safe, put "safe" and the program length (to the nearest power of 2) in your header. If there are multiple numbers in your header, put the power of 2 last.
This stack snippet generates leaderboards and lists all of the open submissions. If there are any problems with the snippet, please leave a comment.
/* Configuration */
var QUESTION_ID = 60328; // Obtain this from the url
// It will be like http://XYZ.stackexchange.com/questions/QUESTION_ID/... on any question page
var ANSWER_FILTER = "!t)IWYnsLAZle2tQ3KqrVveCRJfxcRLe";
var COMMENT_FILTER = "!)Q2B_A2kjfAiU78X(md6BoYk";
var OVERRIDE_USER = 167084; // This should be the user ID of the challenge author.
var SECONDSINDAY = 86400;
var SAFECUTOFFDAYS = 7;
var SORTBYTIME = true;
var SUBTRACTCRACKEDPOINTS = true;
var EXPIREDTIME = 1446336000;
/* App */
var answers = [],
answers_hash, answer_ids, answer_page = 1,
more_answers = true,
comment_page;
function answersUrl(index) {
return "//api.stackexchange.com/2.2/questions/" + QUESTION_ID + "/answers?page=" + index + "&pagesize=100&order=desc&sort=creation&site=codegolf&filter=" + ANSWER_FILTER;
}
function commentUrl(index, answers) {
return "//api.stackexchange.com/2.2/answers/" + answers.join(';') + "/comments?page=" + index + "&pagesize=100&order=desc&sort=creation&site=codegolf&filter=" + COMMENT_FILTER;
}
function getAnswers() {
jQuery.ajax({
url: answersUrl(answer_page++),
method: "get",
dataType: "jsonp",
crossDomain: true,
success: function(data) {
answers.push.apply(answers, data.items);
answers_hash = [];
answer_ids = [];
data.items.forEach(function(a) {
a.comments = [];
var id = +a.share_link.match(/\d+/);
answer_ids.push(id);
answers_hash[id] = a;
});
if (!data.has_more) more_answers = false;
comment_page = 1;
getComments();
}
});
}
function getComments() {
jQuery.ajax({
url: commentUrl(comment_page++, answer_ids),
method: "get",
dataType: "jsonp",
crossDomain: true,
success: function(data) {
data.items.forEach(function(c) {
answers_hash[c.post_id].comments.push(c);
});
if (data.has_more) getComments();
else if (more_answers) getAnswers();
else process();
}
});
}
getAnswers();
var SAFE_REG = /<h\d>.*?[sS][aA][fF][eE].*<\/\h\d>/;
var POINTS_REG = /(?:<=|≤|<=)\s?(?:<\/?strong>)?\s?(\d+)/
var POINTS_REG_ALT = /<h\d>.*?(\d+)(?=[^\n\d<>]*(?:<(?:s>[^\n<>]*<\/s>|[^\n<>]+>)[^\n\d<>]*)*<\/h\d>)/;
var CRACKED_HEADER_REG = /<h\d>.*[Cc][Rr][Aa][Cc][Kk][Ee][Dd].*<\/h\d>/;
var CRACKED_COMMENT_REG = /(.*[Cc][Rr][Aa][Cc][Kk][Ee][Dd].*<a href=.*)|(.*<a href=.*[Cc][Rr][Aa][Cc][Kk][Ee][Dd].*)/
var OVERRIDE_REG = /^Override\s*header:\s*/i;
var LANGUAGE_REG = /<h\d>\s*(.+?),.*<\/h\d>/;
var LANGUAGE_REG_ALT = /<h\d>\s*(<a href=.+<\/a>).*<\/h\d>/
var LANGUAGE_REG_ALT_2 = /<h\d>\s*(.+?)\s.*<\/h\d>/;
var LANGUAGE_REG_ALT_3 = /<h\d>(.+?)<\/h\d>/;
function getAuthorName(a) {
return a.owner.display_name;
}
function process() {
var valid = [];
var open = [];
answers.forEach(function(a) {
var body = a.body;
var cracked = false;
a.comments.forEach(function(c) {
var was_safe = (c.creation_date + (SECONDSINDAY * SAFECUTOFFDAYS) > a.creation_date);
if (CRACKED_COMMENT_REG.test(c.body) && !was_safe)
cracked = true;
});
if (CRACKED_HEADER_REG.test(body)) cracked = true;
// if (SUBTRACTCRACKEDPOINTS||!cracked) {
var createDate = a.creation_date;
var currentDate = Date.now() / 1000;
var timeToSafe = (createDate + (SECONDSINDAY * SAFECUTOFFDAYS) - currentDate) / SECONDSINDAY;
var SafeTimeStr = (timeToSafe > 2) ? (Math.floor(timeToSafe) + " Days") :
(timeToSafe > 1) ? ("1 Day") :
(timeToSafe > (2 / 24)) ? (Math.floor(timeToSafe * 24) + " Hours") :
(timeToSafe > (1 / 24)) ? ("1 Hour") :
"<1 Hour";
var expired = createDate > (EXPIREDTIME);
var safe = timeToSafe < 0;
var points = body.match(POINTS_REG);
if (!points) points = body.match(POINTS_REG_ALT);
safe = safe && !cracked
isOpen = !(cracked || safe);
if (points) {
var length = parseInt(points[1]);
var safepoints = 0;
if (length <= 4) safepoints = 32;
else if (length <= 8) safepoints = 16;
else if (length <= 16) safepoints = 8;
else if (length <= 32) safepoints = 4;
else if (length <= 64) safepoints = 2;
else if (length <= 128) safepoints = 1;
valid.push({
user: getAuthorName(a),
numberOfSubmissions: (safe && !expired) ? 1 : 0,
points: (safe && !expired) ? safepoints : 0,
open: (isOpen && !expired) ? 1 : 0,
cracked: (cracked && !expired) ? 1 : 0,
expired: (expired) ? 1 : 0
});
}
if ((isOpen || expired) && points) {
var language = body.match(LANGUAGE_REG);
if (!language) language = body.match(LANGUAGE_REG_ALT);
if (!language) language = body.match(LANGUAGE_REG_ALT_2);
if (!language) language = body.match(LANGUAGE_REG_ALT_3);
open.push({
user: getAuthorName(a),
length: points ? points[1] : "???",
language: language ? language[1] : "???",
link: a.share_link,
timeToSafe: timeToSafe,
timeStr: (expired) ? "Challenge closed" : SafeTimeStr
});
}
// }
});
if (SORTBYTIME) {
open.sort(function(a, b) {
return a.timeToSafe - b.timeToSafe;
});
} else {
open.sort(function(a, b) {
var r1 = parseInt(a.length);
var r2 = parseInt(b.length);
if (r1 && r2) return r1 - r2;
else if (r1) return r2;
else if (r2) return r1;
else return 0;
});
}
var pointTotals = [];
valid.forEach(function(a) {
var index = -1;
var author = a.user;
pointTotals.forEach(function(p) {
if (p.user == author) index = pointTotals.indexOf(p);
});
if (index == -1) pointTotals.push(a);
else {
pointTotals[index].points += a.points;
pointTotals[index].numberOfSubmissions += a.numberOfSubmissions;
pointTotals[index].cracked += a.cracked;
pointTotals[index].expired += a.expired;
pointTotals[index].open += a.open;
if (SUBTRACTCRACKEDPOINTS && a.cracked && pointTotals[index].cracked > 1) pointTotals[index].points -= .5;
}
});
pointTotals.forEach(function(a) {
a.points += (a.numberOfSubmissions) ? ((a.numberOfSubmissions) * 3) : 0;
});
pointTotals.sort(function(a, b) {
if (a.points != b.points)
return b.points - a.points;
else if (a.numberOfSubmissions != b.numberOfSubmissions)
return b.numberOfSubmissions - a.numberOfSubmissions;
else if (a.open != b.open)
return b.open - a.open;
else if (a.cracked != b.cracked)
return a.cracked - b.cracked;
else return 0;
});
pointTotals.forEach(function(a) {
var answer = jQuery("#answer-template").html();
answer = answer
.replace("{{NAME}}", a.user)
.replace("{{SAFE}}", a.numberOfSubmissions)
.replace("{{OPEN}}", a.open)
.replace("{{CLOSED}}", a.expired)
.replace("{{CRACKED}}", a.cracked)
.replace("{{POINTS}}", a.points);
answer = jQuery(answer);
jQuery("#answers").append(answer);
});
open.forEach(function(a) {
var answer = jQuery("#open-template").html();
answer = answer
.replace("{{NAME}}", a.user)
.replace("{{LENGTH}}", a.length)
.replace("{{LANGUAGE}}", a.language)
.replace("{{TIME}}", a.timeStr)
.replace("{{LINK}}", a.link);
answer = jQuery(answer);
jQuery("#opensubs").append(answer);
});
}
body {
text-align: left !important
}
#answer-list {
padding: 10px;
width: 350px;
float: left;
}
#open-list {
padding: 10px;
width: 470px;
float: left;
}
table thead {
font-weight: bold;
vertical-align: top;
}
table td {
padding: 5px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<link rel="stylesheet" type="text/css" href="//cdn.sstatic.net/codegolf/all.css?v=83c949450c8b">
<div id="answer-list">
<h2>Leaderboard</h2>
<table class="answer-list">
<thead>
<tr>
<td>Author</td>
<td>Safe</td>
<td>Open</td>
<td>Cracked</td>
<td>Late Entry</td>
<td>Score</td>
</tr>
</thead>
<tbody id="answers">
</tbody>
</table>
</div>
<div id="open-list">
<h2>Open submissions</h2>
<table class="open-list">
<thead>
<tr>
<td>Author</td>
<td>Length</td>
<td>Language</td>
<td>Time Remaining</td>
<td>Link (open in new tab)</td>
</tr>
</thead>
<tbody id="opensubs">
</tbody>
</table>
</div>
<table style="display: none">
<tbody id="answer-template">
<tr>
<td>{{NAME}}</td>
<td>{{SAFE}}</td>
<td>{{OPEN}}</td>
<td>{{CRACKED}}</td>
<td>{{CLOSED}}</td>
<td>{{POINTS}}</td>
</tr>
</tbody>
</table>
<table style="display: none">
<tbody id="open-template">
<tr>
<td>{{NAME}}</td>
<td>{{LENGTH}}</td>
<td>{{LANGUAGE}}</td>
<td>{{TIME}}</td>
<td><a target="_parent" href="{{LINK}}">Link</a>
</td>
</tr>
</tbody>
</table>
Use the following formats for entries:
Language, (any text with the program size as the last number)
=
or
Language
=
Length <= 16
Note that the snippet will only put the first word in the header as the language if it doesn't detect a comma.
For safe submissions, put safe in your header. The snippet will automatically put your program in the "safe" column if the time is expired, so this is more to tell any robbers that your program is safe.
For cracked submissions, put cracked in your header.
The program should also be able to recognize if a comment says "cracked" and has a link; however, this is not guaranteed.
Tiebreaking order: Points -> # of Safe submissions -> Least amount of cracked submissions.
Note that the snippet sorts by open submissions before least cracked, but open submissions will not be counted at the end of the contest.
This challenge is now closed.
Most points overall winner: Dennis
Most safe submissions: DLosc
(Note that the number of safe submissions doesn't translate to a point amount, as the size of the programs are considered in calculating the score).
5
We should remind the cops that the output should better be longer than the program size, to reduce trivial solutions like http://codegolf.stackexchange.com/a/60395/ and http://codegolf.stackexchange.com/a/60359
– kennytm – 2015-10-11T16:56:35.213I changed the scoring a bit so that an 8 byte submission isn't worth 81 times as much as a 128 byte, but is still considerably more. – Daniel M. – 2015-10-12T20:24:24.287
Are you using this definition of programming languages? For example, is it required that there is a free interpreter/compiler available?
– bmarks – 2015-10-12T20:31:26.2972@bmarks There has to exist a way to execute the language, and the language must be able to display a string of ASCII characters. If you want to use HQ9+, congratulations, you have just gotten yourself a cracked submission. – Daniel M. – 2015-10-12T20:35:28.603
1
For example, if I want to use features from STATA that are only supported in the paid version and not the free version, is that allowed?
– bmarks – 2015-10-12T20:39:34.2133@bmarks I'd prefer not, but I'm not going to stop you. – Daniel M. – 2015-10-12T21:30:55.953
Do we have a limit on how many times we can post? – J Atkin – 2015-10-13T02:02:12.207
@JAtkin Once per program length per language (effectively 5-6 times/language). Keep in mind that having too many cracked submissions can start to bring the score down a tad (see main post). – Daniel M. – 2015-10-13T02:08:36.100
@DanielM. I see, I saw that in the post but was wondering if maybe 6 was too much ;) – J Atkin – 2015-10-13T02:10:43.833
@JAtkin 1 is too small, and most other limits feel very arbitrary. Besides, changing it now would invalidate a bunch of posts. – Daniel M. – 2015-10-13T02:15:42.283
@JAtkin Besides, there are so many esolangs out there that if someone wanted to, they could have thousands of submissions with only one per language. If it gets out of hand, people can be restricted to a few dozen total submissions, or maybe just not count points (possibly a -0.5 score penalty) for submissions with downvotes. – Daniel M. – 2015-10-13T03:24:11.750
15All the number-only outputs are super boring. – mbomb007 – 2015-10-13T20:06:28.823
"different versions and arbitrary substitutions of the same language don't count as separate languages" - what qualifies as an arbitrary substitution? Would, for example, having both a JavaScript and a CoffeeScript answer of the same length be allowed? (I guess it would because there is quite a bit of logic in the conversion, but it ultimately compiles down to JavaScript.) – user2428118 – 2015-10-14T12:53:11.660
1This is going to get rather interesting in 8 hours when submissions start becoming "safe." – Arcturus – 2015-10-17T19:50:37.100
4
Please consider using the Sandbox the next time. Preferably, the rules of a challenge shouldn't change at all after it has been posted. I've lost track of how many times the rules have changed here...
– Dennis – 2015-10-17T20:01:21.573This challenge should probably be closed to further submissions. I haven't been trying to crack any for a while, and I doubt other people are either. – mbomb007 – 2015-10-27T03:52:52.037
@mbomb007 I'll give people a little time in advance- no new entries will be counted on or after November 1st. Any further entries will not become safe. This will be scored after November 7th. – Daniel M. – 2015-10-27T09:50:31.163