18
This is the cops' thread. For the robbers' thread, go here.
Introduction
For this Cops/Robbers challenge, the cops will write output-producing programs and interweave them together. It is the robber's job to pick apart the cops' programs to produce the desired outputs.
Cop rules
The cops may use up to 256 bytes total to write between 2 and 8 (inclusive) programs, all of which must produce some output. All programs written must be in the same language. The cops will "interweave" their programs together to make it harder for the robbers to figure out what the programs are.
Now for a description of interweaving. Consider the strings representing the different programs. The process of interweaving is the repeated pulling off of the first character of any of the programs and concatenating it to the end of a new string until no characters in any of the programs are left. For example, if two programs are lion
and TIGER
, a possible interweaving is TIliGoEnR
. However, the programs cannot be scrambled in any way, so RoITEnlGi
is not acceptable.
It should be noted that when the characters of all but one program are removed from the results of an interweaving, the remaining program would be shown intact. Removing the letters TIGER
from TIliGoEnR
results in lion
.
All of the cops' programs and outputs must contain only printable ASCII characters (20-7E) and newlines. Programs must not contain errors and must run in 10 seconds on a reasonable machine. For any submission, there must be a free interpreter of the language somewhere. Adding comments to the submissions is not allowed, as are hashing and other forms of cryptography. Blank programs are not allowed (Sorry Stuck).
The cop will post the interweaved code, the language, the number of different programs used, and the output for each program. A big thanks to Martin for writing this CJam script to automatically interweave your programs.
Programs are deemed safe after one week has elapsed from the time of posting. At that point, the cops must post the individual programs in order to receive points.
Scoring
There are two components that are added together when scoring a safe submission.
- 256 divided by the quantity 2 raised to the power of the number of programs used.
- Round the number of bytes in the interweaving up to the nearest power of 2 and divide it into 256.
For example, if the entry TIliGoEnR
(9 bytes) were safe, it would receive 256/2^2+256/16=80 points.
When a cop's submission is cracked, the cop loses 16 points. The cop must indicate that their submission has been cracked.
The winner of the cops' challenge will be the person with the most points after a sufficient period of time for people to participate.
Leaderboard
This is a work in progress that was adapted by intrepidcoder from this question.
To make sure that your answer shows up, please start your answer with a headline, using the exact Markdown template:
# Language Name, N programs, M bytes; Score ###/### (if safe/cracked)
Anything after a semicolon will be ignored, so you can put your score there.
If your submission is safe put a header like this:
# Language Name, safe, N programs, M bytes; Score ###
If it is cracked, put a header like this:
# Language Name, [cracked](link-to-crack), N programs, M bytes; Score -16
/* Configuration */
var QUESTION_ID = 64520; // 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 = 43444; // This should be the user ID of the challenge author.
var SECONDSINDAY = 86400;
var SAFECUTOFFDAYS = 7;
var SORTBYTIME = true;
var SUBTRACTCRACKEDPOINTS = true;
var EXPIREDTIME = 1448232502000;
/* App */
var SAFE_REG = /<h\d>.*?[sS][aA][fF][eE].*<\/\h\d>/;
var POINTS_REG = /<h\d>.*(\d+)\s*program.*<\/h\d>/i; // /(?:<=|≤|<=)\s?(?:<\/?strong>)?\s?(\d+)/
// var POINTS_REG_ALT = /<h\d>.*?(\d+)(?=[^\n\d<>]*(?:<(?:s>[^\n<>]*<\/s>|[^\n<>]+>)[^\n\d<>]*)*<\/h\d>)/;
var LENGTH_REG = /<h\d>.*?((\d+)\s*byte).*<\/h\d>/i;
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>/;
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();
function getAuthorName(a) {
return a.owner.display_name;
}
function process() {
var valid = [];
var open = [];
answers.forEach(function(a) {
var body = a.body.replace(/(<h\d>.*);.*(<\/h\d>)/,"$1$2"); // Ignore all text after a semicolon.
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 programs = body.match(POINTS_REG);
var length = body.match(LENGTH_REG);
safe = safe && !cracked
isOpen = !(cracked || safe);
if (programs && length) {
var safepoints = (256/Math.pow(2,parseInt(programs[1],10)) +
256/Math.pow(2,Math.ceil(Math.log2(parseInt(length[1],10)))));
var crackedpoints = Math.pow(2, parseInt(programs[1],10),2) +
Math.pow(2,Math.floor(Math.log2(parseInt(length[1],10))));
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) && programs) {
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),
safePts: programs ? safepoints : "???",
crackedPts: programs ? crackedpoints : "???",
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) {
if (SUBTRACTCRACKEDPOINTS && a.cracked) a.points -= 16;
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].points -= 16;
}
});
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("{{SAFE}}", a.safePts)
.replace("{{CRACKED}}", a.crackedPts)
.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>Points if Safe</td>
<td>Points if Cracked</td>
<td>Language</td>
<td>Time Remaining</td>
<td>Link</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>{{SAFE}}</td>
<td>{{CRACKED}}</td>
<td>{{LANGUAGE}}</td>
<td>{{TIME}}</td>
<td><a target="_parent" href="{{LINK}}">Link</a>
</td>
</tr>
</tbody>
</table>
8I'd be extremely impressed if someone manages to crack one of the 8-programs. – ETHproductions – 2015-11-22T22:53:25.187
I added a leaderboard, Feel free to edit it if anything isn't right. – intrepidcoder – 2015-11-23T01:22:29.833
@intrepidcoder Nice work! Thanks (If you enter, I'll give you a 50-rep thank you). Maybe you could implement the second half of ETH's suggestion too? Also, I'm not sure why, but it says that Dennis's score for his submission if cracked is 68 instead of 65. – Arcturus – 2015-11-23T02:42:08.330
1"only printable ASCII characters" ... there goes my plan to use left to right overrides to confuse everyone. – TheNumberOne – 2015-11-23T16:24:17.453
How do you determine the score? I have to post with the following format
Score ###/###
, but what does the second###
mean? – Adnan – 2015-11-23T16:37:12.723@Adriandmen The first score is the number of points you get if you are safe. The second score is the number of points the robber would get if you are cracked. – Arcturus – 2015-11-23T17:04:20.203
7I understand what you're trying to do with the opposing scoring systems for cops and robbers, but it creates weird incentives. It means that robbers will predominantly try to crack those answers for which the cops wouldn't receive many points anyway, whereas they have much less motivation to tackle those which would give the cop a decent amount of points. – Martin Ender – 2015-11-23T20:46:51.717
May programs terminate with an error? – mbomb007 – 2015-11-23T22:33:22.380
@mbomb007 No, as errors go to STDERR instead of STDOUT. – Arcturus – 2015-11-23T22:55:34.243
4
If it's useful for anyone here is a CJam script which randomly interleaves any number of programs. Just provide the programs on STDIN, one on each line. If that's not practical (because your programs themselves contain linefeeds), you can choose any other delimiter (
– Martin Ender – 2015-11-24T09:18:23.183|||
say) and then replace theN
in the code with a string containing your delimiter, e.g."|||"
. (@Eridan feel free to include this in the challenge.)can we output to the console? e.g. javascript console? – Seadrus – 2015-11-26T00:13:19.980
@ETHproductions I cracked an (albeit easy) 8-program. – Arcturus – 2015-11-29T17:49:10.120
4Honestly, if that one made it I would have laughed so much. – Generic User – 2015-11-29T18:24:35.310
Someone pls write a cop so I can try to crack – ev3commander – 2015-12-08T20:32:49.200
@ev3commander Okay ^_^ – Conor O'Brien – 2015-12-09T13:06:20.047