112
\$\begingroup\$

One of the most common standard tasks (especially when showcasing esoteric programming languages) is to implement a "cat program": read all of STDIN and print it to STDOUT. While this is named after the Unix shell utility cat it is of course much less powerful than the real thing, which is normally used to print (and concatenate) several files read from disc.

Task

You should write a full program which reads the contents of the standard input stream and writes them verbatim to the standard output stream. If and only if your language does not support standard input and/or output streams (as understood in most languages), you may instead take these terms to mean their closest equivalent in your language (e.g. JavaScript's prompt and alert). These are the only admissible forms of I/O, as any other interface would largely change the nature of the task and make answers much less comparable.

The output should contain exactly the input and nothing else. The only exception to this rule is constant output of your language's interpreter that cannot be suppressed, such as a greeting, ANSI color codes or indentation. This also applies to trailing newlines. If the input does not contain a trailing newline, the output shouldn't include one either! (The only exception being if your language absolutely always prints a trailing newline after execution.)

Output to the standard error stream is ignored, so long as the standard output stream contains the expected output. In particular, this means your program can terminate with an error upon hitting the end of the stream (EOF), provided that doesn't pollute the standard output stream. If you do this, I encourage you to add an error-free version to your answer as well (for reference).

As this is intended as a challenge within each language and not between languages, there are a few language specific rules:

  • If it is at all possible in your language to distinguish null bytes in the standard input stream from the EOF, your program must support null bytes like any other bytes (that is, they have to be written to the standard output stream as well).
  • If it is at all possible in your language to support an arbitrary infinite input stream (i.e. if you can start printing bytes to the output before you hit EOF in the input), your program has to work correctly in this case. As an example yes | tr -d \\n | ./my_cat should print an infinite stream of ys. It is up to you how often you print and flush the standard output stream, but it must be guaranteed to happen after a finite amount of time, regardless of the stream (this means, in particular, that you cannot wait for a specific character like a linefeed before printing).

Please add a note to your answer about the exact behaviour regarding null-bytes, infinite streams, and extraneous output.

Additional rules

  • This is not about finding the language with the shortest solution for this (there are some where the empty program does the trick) - this is about finding the shortest solution in every language. Therefore, no answer will be marked as accepted.

  • Submissions in most languages will be scored in bytes in an appropriate preexisting encoding, usually (but not necessarily) UTF-8.

    Some languages, like Folders, are a bit tricky to score. If in doubt, please ask on Meta.

  • Feel free to use a language (or language version) even if it's newer than this challenge. Languages specifically written to submit a 0-byte answer to this challenge are fair game but not particularly interesting.

    Note that there must be an interpreter so the submission can be tested. It is allowed (and even encouraged) to write this interpreter yourself for a previously unimplemented language.

    Also note that languages do have to fulfill our usual criteria for programming languages.

  • If your language of choice is a trivial variant of another (potentially more popular) language which already has an answer (think BASIC or SQL dialects, Unix shells or trivial Brainfuck derivatives like Headsecks or Unary), consider adding a note to the existing answer that the same or a very similar solution is also the shortest in the other language.

  • Unless they have been overruled earlier, all standard rules apply, including the [http://meta.codegolf.stackexchange.com/q/1061](loopholes that are forbidden by default).

As a side note, please don't downvote boring (but valid) answers in languages where there is not much to golf; these are still useful to this question as it tries to compile a catalogue as complete as possible. However, do primarily upvote answers in languages where the author actually had to put effort into golfing the code.

Catalogue

The Stack Snippet at the bottom of this post generates the catalogue from the answers a) as a list of shortest solution per language and b) as an overall leaderboard.

To make sure that your answer shows up, please start your answer with a headline, using the following Markdown template:

## Language Name, N bytes

where N is the size of your submission. If you improve your score, you can keep old scores in the headline, by striking them through. For instance:

## Ruby, <s>104</s> <s>101</s> 96 bytes

If there you want to include multiple numbers in your header (e.g. because your score is the sum of two files or you want to list interpreter flag penalties separately), make sure that the actual score is the last number in the header:

## Perl, 43 + 2 (-p flag) = 45 bytes

You can also make the language name a link which will then show up in the snippet:

## [><>](http://esolangs.org/wiki/Fish), 121 bytes

<style>body { text-align: left !important} #answer-list { padding: 10px; width: 290px; float: left; } #language-list { padding: 10px; width: 290px; float: left; } table thead { font-weight: bold; } table td { padding: 5px; }</style><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="language-list"> <h2>Shortest Solution by Language</h2> <table class="language-list"> <thead> <tr><td>Language</td><td>User</td><td>Score</td></tr> </thead> <tbody id="languages"> </tbody> </table> </div> <div id="answer-list"> <h2>Leaderboard</h2> <table class="answer-list"> <thead> <tr><td></td><td>Author</td><td>Language</td><td>Size</td></tr> </thead> <tbody id="answers"> </tbody> </table> </div> <table style="display: none"> <tbody id="answer-template"> <tr><td>{{PLACE}}</td><td>{{NAME}}</td><td>{{LANGUAGE}}</td><td>{{SIZE}}</td><td><a href="{{LINK}}">Link</a></td></tr> </tbody> </table> <table style="display: none"> <tbody id="language-template"> <tr><td>{{LANGUAGE}}</td><td>{{NAME}}</td><td>{{SIZE}}</td><td><a href="{{LINK}}">Link</a></td></tr> </tbody> </table><script>var QUESTION_ID = 62230; var ANSWER_FILTER = "!t)IWYnsLAZle2tQ3KqrVveCRJfxcRLe"; var COMMENT_FILTER = "!)Q2B_A2kjfAiU78X(md6BoYk"; var OVERRIDE_USER = 8478; 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) { if (c.owner.user_id === OVERRIDE_USER) answers_hash[c.post_id].comments.push(c); }); if (data.has_more) getComments(); else if (more_answers) getAnswers(); else process(); } }); } getAnswers(); var SCORE_REG = /<h\d>\s*([^\n,<]*(?:<(?:[^\n>]*>[^\n<]*<\/[^\n>]*>)[^\n,<]*)*),.*?(\d+)(?=[^\n\d<>]*(?:<(?:s>[^\n<>]*<\/s>|[^\n<>]+>)[^\n\d<>]*)*<\/h\d>)/; var OVERRIDE_REG = /^Override\s*header:\s*/i; function getAuthorName(a) { return a.owner.display_name; } function process() { var valid = []; answers.forEach(function(a) { var body = a.body; a.comments.forEach(function(c) { if(OVERRIDE_REG.test(c.body)) body = '<h1>' + c.body.replace(OVERRIDE_REG, '') + '</h1>'; }); var match = body.match(SCORE_REG); if (match) valid.push({ user: getAuthorName(a), size: +match[2], language: match[1], link: a.share_link, }); else console.log(body); }); valid.sort(function (a, b) { var aB = a.size, bB = b.size; return aB - bB }); var languages = {}; var place = 1; var lastSize = null; var lastPlace = 1; valid.forEach(function (a) { if (a.size != lastSize) lastPlace = place; lastSize = a.size; ++place; var answer = jQuery("#answer-template").html(); answer = answer.replace("{{PLACE}}", lastPlace + ".") .replace("{{NAME}}", a.user) .replace("{{LANGUAGE}}", a.language) .replace("{{SIZE}}", a.size) .replace("{{LINK}}", a.link); answer = jQuery(answer); jQuery("#answers").append(answer); var lang = a.language; lang = jQuery('<a>'+lang+'</a>').text(); languages[lang] = languages[lang] || {lang: a.language, lang_raw: lang.toLowerCase(42), user: a.user, size: a.size, link: a.link}; }); var langs = []; for (var lang in languages) if (languages.hasOwnProperty(lang)) langs.push(languages[lang]); langs.sort(function (a, b) { if (a.lang_raw > b.lang_raw) return 1; if (a.lang_raw < b.lang_raw) return -1; return 0; }); for (var i = 0; i < langs.length; ++i) { var language = jQuery("#language-template").html(); var lang = langs[i]; language = language.replace("{{LANGUAGE}}", lang.lang) .replace("{{NAME}}", lang.user) .replace("{{SIZE}}", lang.size) .replace("{{LINK}}", lang.link); language = jQuery(language); jQuery("#languages").append(language); } }</script>

\$\endgroup\$
14
  • 78
    \$\begingroup\$ Bash, 3 bytes: cat \$\endgroup\$
    – TheDoctor
    Commented Oct 31, 2015 at 19:02
  • 4
    \$\begingroup\$ @TheDoctor I guess this would fall into the "don't use a builtin which does exactly what is needed" rule. \$\endgroup\$ Commented Oct 31, 2015 at 19:46
  • 14
    \$\begingroup\$ @PaŭloEbermann There is no such rule, and the corresponding standard loophole is no longer accepted. (In fact, there is already a sh answer using cat which also contains a shorter solution using dd.) \$\endgroup\$ Commented Oct 31, 2015 at 20:25
  • 1
    \$\begingroup\$ If only it used standard methods of input and output: ///, 0 bytes. \$\endgroup\$
    – sporkl
    Commented Mar 31, 2017 at 19:33
  • 1
    \$\begingroup\$ @SparklePony Except, you'd have to escape slashes and backslashes. \$\endgroup\$ Commented Mar 31, 2017 at 20:35

336 Answers 336

1
2
3 4 5
12
5
\$\begingroup\$

FireType, 7 bytes

,
&
_
=

Requires some changes I just pushed. The rules say:

Unlike our usual rules, feel free to use a language (or language version) even if it's newer than this challenge.

so I'm in the clear!

\$\endgroup\$
5
\$\begingroup\$

Fission, 4 bytes

R?J!

Isn't it nice when you beat the sample programs in language's own repository? :) For reference, it has the 7-byte solution

R?J0;0!

Explanation

So, R starts the control-flow with a right-going atom. ? reads a character from STDIN into the atom's mass. As long as we're reading characters, the energy remains zero, so the Jump is a no-op and ! prints the character. The atom loops back to the start (R is now a no-op) and repeats the whole process.

When we hit EOF, ? will set the atom's energy to 1, so the Jump will now skip the print command. But when an atom hits ? after EOF has already been returned, it will destroy the atom instead, which terminates the program.

(The solution from the language's author uses an explicit ; to terminate the program, which is skipped with two 0-portals otherwise.)

\$\endgroup\$
5
\$\begingroup\$

Piet, 3 codels

enter image description here

First Piet program! Quick explanation: input chars, output chars.

\$\endgroup\$
0
5
\$\begingroup\$

Stack Cats, 0 bytes

The language cannot handle infinite input/output streams (since the program doesn't start until EOF is encountered, and output is printed from a finite memory source at the end of the program). It does handle null bytes.


Try it online!

This is not a case of "let's assign a random task to the empty program as a special case for golfing". Instead, the fact that this works is actually a result of several design decisions and is completely consistent with the overall language semantics.

Mainly, Stack Cats is a very pure reversible programming language, which means that every piece of code can be cleanly undone within the language. I/O does not fit within this model, because once you've printed something to STDOUT you can't undo it. In theory you could undo reading input by pushing it back to some buffer, but for symmetry reasons, input and output are treated the same. To make I/O work, we read all input at the beginning of the program and push it onto the initial stack, and at the end of the program, the contents of the final stack are printed to STDOUT.

Secondly, to undo any piece of code, we simply mirror it (reverse characters, swap all brackets and slashes). Furthermore, every program has to be symmetric itself. This implies that every even-length program is a valid cat program, provided it terminates, since even-length programs necessarily consist of some code together with the code that inverts it. It just so happens that the shortest even-length program is empty.

\$\endgroup\$
4
\$\begingroup\$

CJam, 1 byte

q

CJam has three ways to read from the input stream:

  • q reads it all as one big string.
  • l reads a single line, up until a newline.
  • r reads a token, which is a sequence of non-whitespace characters.

As such, it has no way to handle an infinite stream of non-whitespace characters. This should make q a valid solution.

\$\endgroup\$
4
\$\begingroup\$

Beam, 8 bytes

>rnH
\@/

Fairly simple and a little shorter than the one on the esolangs page.

\$\endgroup\$
4
\$\begingroup\$

C++, 65 61 bytes

#include<ios>
int main(){while(int i=~getchar())putchar(~i);}

Basically Dennis's C answer adapted for C++. g++ and clang++ give warnings, for me, but compile it just fine.

Saved some bytes thanks to Zereges!

\$\endgroup\$
3
  • 1
    \$\begingroup\$ I'm not surprised that clang is ringing warning bells. \$\endgroup\$ Commented Oct 30, 2015 at 17:04
  • 1
    \$\begingroup\$ Same amount of bytes, but if you change the second line to int main(){for(int i;i=~getchar();)putchar(~i);} you get one less warning. \$\endgroup\$
    – user530873
    Commented Oct 31, 2015 at 6:52
  • \$\begingroup\$ You can #include<ios> instead of <cstdio>. Also, change int main(int i){while(i=~getchar())putchar(~i);} to int main(){while(int i=~getchar())putchar(~i);}. It removes warnings and saves bytes. \$\endgroup\$
    – Zereges
    Commented Oct 31, 2015 at 22:51
4
\$\begingroup\$

awk, 9 1 byte

(thanks to a suggestion rewrite in the comments by Mauris)

1

Example:

echo "hello\nworld" | awk '1'
\$\endgroup\$
10
  • \$\begingroup\$ Does this/can awk handle infinite input? \$\endgroup\$ Commented Oct 31, 2015 at 0:21
  • \$\begingroup\$ @MartinBüttner yes infact... yes | awk '{print$0}' \$\endgroup\$
    – user530873
    Commented Oct 31, 2015 at 0:23
  • 3
    \$\begingroup\$ awk '1' works as a 1-byte solution. \$\endgroup\$
    – lynn
    Commented Oct 31, 2015 at 12:23
  • \$\begingroup\$ @Mauris awk 1 is a "shorter" still 1-byte solution. Quotes are useless here. \$\endgroup\$
    – jlliagre
    Commented Nov 2, 2015 at 23:18
  • \$\begingroup\$ @smpl yes | awk '1' only works because yes outputs a newline after each "yes" and awk's default record separator is a newline. This doesn't work for streams that contain no newlines, like yes | tr -d \\n | ./my_cat in the question, so it doesn't qualify. \$\endgroup\$ Commented Nov 12, 2015 at 18:47
4
\$\begingroup\$

ಠ_ಠ, 7 bytes

ಠ_ಠ

Try it now! ಠ_ಠ

This isn't even a code-golfing language.

\$\endgroup\$
4
\$\begingroup\$

Shtriped, 20 bytes

e )
"
 r )
 s )
 "
"

This cheekily demonstrates that nearly any printable ASCII string is a valid identifier in Shtriped.

How it works:

e )   \ declares a variable named )
"     \ defines a function with 0 arguments named "
 r )  \ gets a line of string input, saving it to )
 s )  \ prints ) as a string
 "    \ recursively calls ", effectively looping forever
"     \ calls " from the main scope to get things started

There's no real way to detect EOF, so this loops forever like the Python answer.

You can easily make it stop when an empty line is given though (30 bytes):

e )
"
 r )
 d ) \ tries to decrement ), if it was the empty string, aka 0, it can't, so 0 is returned all the way up
 i ) \ increment ) to put it back to normal after possibly decrementing
 s )
 "
"

Note that Shtriped I/O only supports printable ASCII, tabs, line feeds, carriage returns, vertical tabs, and form feeds (100 chars in total). This is because internally, strings are represented as non-negative arbitrary precision integers, and there must be a finite alphabet of characters to be able to encode all strings.

\$\endgroup\$
0
4
\$\begingroup\$

Lazy K, 1 0 bytes

As CatsAreFluffy pointed out, the empty program has the same semantics as the program I. From the grammar:

  Program  ::= CCExpr                     CCExpr

  CCExpr   ::= CCExpr Expr                (CCExpr Expr)
             | epsilon                    (lambda (x) x)

Old explanation (1 byte)

I

A Lazy K program is a function on Church lists of Church numerals, expressed in SKI combinator logic. I is the identity function, which simply equates the output with the input. As such, a cat program is essentially the "simplest" Lazy K program. If your Lazy K interpreter is any good, it even handles infinite streams!

\$\endgroup\$
3
  • \$\begingroup\$ Doesn't the empty program work? \$\endgroup\$ Commented Mar 18, 2016 at 2:39
  • \$\begingroup\$ Wow, you’re right. Thanks! \$\endgroup\$
    – lynn
    Commented Mar 18, 2016 at 9:25
  • \$\begingroup\$ So now we have sed, gs2, TeaScript, and LazyK with 0byte answers. Yay! \$\endgroup\$ Commented Mar 18, 2016 at 15:37
4
\$\begingroup\$

Sesos, 1 byte

Y

This program handles both infinite streams and null bytes.

Try it online! Check Debug to see the generated binary code.

How it works

The binary file above has been generated by assembling the following SASM code.

set mask ; Switch to unsigned 8-bit cells.

         ; (implicit jmp)
         ;     Set an entry marker and jump to the jne instruction.
    put  ; Print the byte in the current cell to STDOUT.
jnz      ; (implicitly promoted to jne)
         ;     Read a byte from STDIN and save it in the current cell.
         ;     If EOF has not been hit, jump to the previous instruction.
\$\endgroup\$
2
  • \$\begingroup\$ How does set mask have anything to do with null bytes? \$\endgroup\$ Commented Oct 5, 2016 at 16:31
  • \$\begingroup\$ set mask has nothing to do will null bytes. Using character-based I/O would only work with certain locales though. If the locale uses, e.g., UTF-8, an input consisting of a single 0xFF byte would error. \$\endgroup\$
    – Dennis
    Commented Oct 5, 2016 at 16:38
4
\$\begingroup\$

Ouroboros, 9 4 bytes

i.)o

The program outputs the exact input, with no extraneous characters. It theoretically would work on null bytes and infinite streams, but as the only interpreter for the language is HTML/JavaScript and the input comes from a text box, neither concept is really applicable.

  • i reads a character code or -1 for end of input.
  • . duplicates it.
  • ) is an absolutely nasty hack.
    • Control flow in Ouroboros is accomplished via the ( and ) commands, which swallow and regurgitate characters from the end of a line. The program ends when the instruction pointer is swallowed. Normally, this means you'll need a ( instruction somewhere, or else the code is an infinite loop. However, in the current implementation, if you use a negative number as the argument to ) (regurgitate), it actually swallows characters. (I.e., regurgitates backwards??)
    • So: if i read a character and pushed its nonnegative character code, ) regurgitates a number of characters equal to that value--which does nothing, because the snake is already at its maximum possible size. But if i hit EOF and pushed -1, ) "regurgitates" -1 characters, meaning it actually swallows one.
    • On EOF, the o gets swallowed. The program does not output anything and loops again; i again gives -1, and another character is swallowed--this time, the ). Now the program halts, since the instruction pointer was swallowed.
  • If nothing was swallowed, o outputs the character from the stack. Control then loops back to the beginning of the line.

See it in action:

// Define Stack class
function Stack() {
  this.stack = [];
  this.length = 0;
}
Stack.prototype.push = function(item) {
  this.stack.push(item);
  this.length++;
}
Stack.prototype.pop = function() {
  var result = 0;
  if (this.length > 0) {
    result = this.stack.pop();
    this.length--;
  }
  return result;
}
Stack.prototype.top = function() {
  var result = 0;
  if (this.length > 0) {
    result = this.stack[this.length - 1];
  }
  return result;
}
Stack.prototype.toString = function() {
  return "" + this.stack;
}

// Define Snake class
function Snake(code) {
  this.code = code;
  this.length = this.code.length;
  this.ip = 0;
  this.ownStack = new Stack();
  this.currStack = this.ownStack;
  this.alive = true;
  this.wait = 0;
  this.partialString = this.partialNumber = null;
}
Snake.prototype.step = function() {
  if (!this.alive) {
    return null;
  }
  if (this.wait > 0) {
    this.wait--;
    return null;
  }
  var instruction = this.code.charAt(this.ip);
  var output = null;
  console.log("Executing instruction " + instruction);
  if (this.partialString !== null) {
    // We're in the middle of a double-quoted string
    if (instruction == '"') {
      // Close the string and push its character codes in reverse order
      for (var i = this.partialString.length - 1; i >= 0; i--) {
        this.currStack.push(this.partialString.charCodeAt(i));
      }
      this.partialString = null;
    } else {
      this.partialString += instruction;
    }
  } else if (instruction == '"') {
    this.partialString = "";
  } else if ("0" <= instruction && instruction <= "9") {
    if (this.partialNumber !== null) {
      this.partialNumber = this.partialNumber + instruction;  // NB: concatenation!
    } else {
      this.partialNumber = instruction;
    }
    next = this.code.charAt((this.ip + 1) % this.length);
    if (next < "0" || "9" < next) {
      // Next instruction is non-numeric, so end number and push it
      this.currStack.push(+this.partialNumber);
      this.partialNumber = null;
    }
  } else if ("a" <= instruction && instruction <= "f") {
    // a-f push numbers 10 through 15
    var value = instruction.charCodeAt(0) - 87;
    this.currStack.push(value);
  } else if (instruction == "$") {
    // Toggle the current stack
    if (this.currStack === this.ownStack) {
      this.currStack = this.program.sharedStack;
    } else {
      this.currStack = this.ownStack;
    }
  } else if (instruction == "s") {
    this.currStack = this.ownStack;
  } else if (instruction == "S") {
    this.currStack = this.program.sharedStack;
  } else if (instruction == "l") {
    this.currStack.push(this.ownStack.length);
  } else if (instruction == "L") {
    this.currStack.push(this.program.sharedStack.length);
  } else if (instruction == ".") {
    var item = this.currStack.pop();
    this.currStack.push(item);
    this.currStack.push(item);
  } else if (instruction == "m") {
    var item = this.ownStack.pop();
    this.program.sharedStack.push(item);
  } else if (instruction == "M") {
    var item = this.program.sharedStack.pop();
    this.ownStack.push(item);
  } else if (instruction == "y") {
    var item = this.ownStack.top();
    this.program.sharedStack.push(item);
  } else if (instruction == "Y") {
    var item = this.program.sharedStack.top();
    this.ownStack.push(item);
  } else if (instruction == "\\") {
    var top = this.currStack.pop();
    var next = this.currStack.pop()
    this.currStack.push(top);
    this.currStack.push(next);
  } else if (instruction == "@") {
    var c = this.currStack.pop();
    var b = this.currStack.pop();
    var a = this.currStack.pop();
    this.currStack.push(c);
    this.currStack.push(a);
    this.currStack.push(b);
  } else if (instruction == ";") {
    this.currStack.pop();
  } else if (instruction == "+") {
    var b = this.currStack.pop();
    var a = this.currStack.pop();
    this.currStack.push(a + b);
  } else if (instruction == "-") {
    var b = this.currStack.pop();
    var a = this.currStack.pop();
    this.currStack.push(a - b);
  } else if (instruction == "*") {
    var b = this.currStack.pop();
    var a = this.currStack.pop();
    this.currStack.push(a * b);
  } else if (instruction == "/") {
    var b = this.currStack.pop();
    var a = this.currStack.pop();
    this.currStack.push(a / b);
  } else if (instruction == "%") {
    var b = this.currStack.pop();
    var a = this.currStack.pop();
    this.currStack.push(a % b);
  } else if (instruction == "_") {
    this.currStack.push(-this.currStack.pop());
  } else if (instruction == "I") {
    var value = this.currStack.pop();
    if (value < 0) {
      this.currStack.push(Math.ceil(value));
    } else {
      this.currStack.push(Math.floor(value));
    }
  } else if (instruction == ">") {
    var b = this.currStack.pop();
    var a = this.currStack.pop();
    this.currStack.push(+(a > b));
  } else if (instruction == "<") {
    var b = this.currStack.pop();
    var a = this.currStack.pop();
    this.currStack.push(+(a < b));
  } else if (instruction == "=") {
    var b = this.currStack.pop();
    var a = this.currStack.pop();
    this.currStack.push(+(a == b));
  } else if (instruction == "!") {
    this.currStack.push(+ !this.currStack.pop());
  } else if (instruction == "?") {
    this.currStack.push(Math.random());
  } else if (instruction == "n") {
    output = "" + this.currStack.pop();
  } else if (instruction == "o") {
    output = String.fromCharCode(this.currStack.pop());
  } else if (instruction == "r") {
    var input = this.program.io.getNumber();
    this.currStack.push(input);
  } else if (instruction == "i") {
    var input = this.program.io.getChar();
    this.currStack.push(input);
  } else if (instruction == "(") {
    this.length -= Math.floor(this.currStack.pop());
    this.length = Math.max(this.length, 0);
  } else if (instruction == ")") {
    this.length += Math.floor(this.currStack.pop());
    this.length = Math.min(this.length, this.code.length);
  } else if (instruction == "w") {
    this.wait = this.currStack.pop();
  }
  // Any unrecognized character is a no-op
  if (this.ip >= this.length) {
    // We've swallowed the IP, so this snake dies
    this.alive = false;
    this.program.snakesLiving--;
  } else {
    // Increment IP and loop if appropriate
    this.ip = (this.ip + 1) % this.length;
  }
  return output;
}
Snake.prototype.getHighlightedCode = function() {
  var result = "";
  for (var i = 0; i < this.code.length; i++) {
    if (i == this.length) {
      result += '<span class="swallowedCode">';
    }
    if (i == this.ip) {
      if (this.wait > 0) {
        result += '<span class="nextActiveToken">';
      } else {
        result += '<span class="activeToken">';
      }
      result += escapeEntities(this.code.charAt(i)) + '</span>';
    } else {
      result += escapeEntities(this.code.charAt(i));
    }
  }
  if (this.length < this.code.length) {
    result += '</span>';
  }
  return result;
}

// Define Program class
function Program(source, speed, io) {
  this.sharedStack = new Stack();
  this.snakes = source.split(/\r?\n/).map(function(snakeCode) {
    var snake = new Snake(snakeCode);
    snake.program = this;
    snake.sharedStack = this.sharedStack;
    return snake;
  }.bind(this));
  this.snakesLiving = this.snakes.length;
  this.io = io;
  this.speed = speed || 10;
  this.halting = false;
}
Program.prototype.run = function() {
  this.step();
  if (this.snakesLiving) {
    this.timeout = window.setTimeout(this.run.bind(this), 1000 / this.speed);
  }
}
Program.prototype.step = function() {
   for (var s = 0; s < this.snakes.length; s++) {
    var output = this.snakes[s].step();
    if (output) {
      this.io.print(output);
    }
  }
  this.io.displaySource(this.snakes.map(function (snake) {
      return snake.getHighlightedCode();
    }).join("<br>"));
 }
Program.prototype.halt = function() {
  window.clearTimeout(this.timeout);
}

var ioFunctions = {
  print: function (item) {
    var stdout = document.getElementById('stdout');
    stdout.value += "" + item;
  },
  getChar: function () {
    if (inputData) {
      var inputChar = inputData[0];
      inputData = inputData.slice(1);
      result = inputChar.charCodeAt(0);
    } else {
      result = -1;
    }
    var stdinDisplay = document.getElementById('stdin-display');
    stdinDisplay.innerHTML = escapeEntities(inputData);
    return result;
  },
  getNumber: function () {
    while (inputData && (inputData[0] < "0" || "9" < inputData[0])) {
      inputData = inputData.slice(1);
    }
    if (inputData) {
      var inputNumber = inputData.match(/\d+/)[0];
      inputData = inputData.slice(inputNumber.length);
      result = +inputNumber;
    } else {
      result = -1;
    }
    var stdinDisplay = document.getElementById('stdin-display');
    stdinDisplay.innerHTML = escapeEntities(inputData);
    return result;
  },
  displaySource: function (formattedCode) {
    var sourceDisplay = document.getElementById('source-display');
    sourceDisplay.innerHTML = formattedCode;
  }
};
var program = null;
var inputData = null;
function showEditor() {
  var source = document.getElementById('source'),
    sourceDisplayWrapper = document.getElementById('source-display-wrapper'),
    stdin = document.getElementById('stdin'),
    stdinDisplayWrapper = document.getElementById('stdin-display-wrapper');
  
  source.style.display = "block";
  stdin.style.display = "block";
  sourceDisplayWrapper.style.display = "none";
  stdinDisplayWrapper.style.display = "none";
  
  source.focus();
}
function hideEditor() {
  var source = document.getElementById('source'),
    sourceDisplay = document.getElementById('source-display'),
    sourceDisplayWrapper = document.getElementById('source-display-wrapper'),
    stdin = document.getElementById('stdin'),
    stdinDisplay = document.getElementById('stdin-display'),
    stdinDisplayWrapper = document.getElementById('stdin-display-wrapper');
  
  source.style.display = "none";
  stdin.style.display = "none";
  sourceDisplayWrapper.style.display = "block";
  stdinDisplayWrapper.style.display = "block";
  
  var sourceHeight = getComputedStyle(source).height,
    stdinHeight = getComputedStyle(stdin).height;
  sourceDisplayWrapper.style.minHeight = sourceHeight;
  sourceDisplayWrapper.style.maxHeight = sourceHeight;
  stdinDisplayWrapper.style.minHeight = stdinHeight;
  stdinDisplayWrapper.style.maxHeight = stdinHeight;
  sourceDisplay.textContent = source.value;
  stdinDisplay.textContent = stdin.value;
}
function escapeEntities(input) {
  return input.replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;');
}
function resetProgram() {
  var stdout = document.getElementById('stdout');
  stdout.value = null;
  if (program !== null) {
    program.halt();
  }
  program = null;
  inputData = null;
  showEditor();
}
function initProgram() {
  var source = document.getElementById('source'),
    stepsPerSecond = document.getElementById('steps-per-second'),
    stdin = document.getElementById('stdin');
  program = new Program(source.value, +stepsPerSecond.innerHTML, ioFunctions);
  hideEditor();
  inputData = stdin.value;
}
function runBtnClick() {
  if (program === null || program.snakesLiving == 0) {
    resetProgram();
    initProgram();
  } else {
    program.halt();
    var stepsPerSecond = document.getElementById('steps-per-second');
    program.speed = +stepsPerSecond.innerHTML;
  }
  program.run();
}
function stepBtnClick() {
  if (program === null) {
    initProgram();
  } else {
    program.halt();
  }
  program.step();
}
function sourceDisplayClick() {
  resetProgram();
}
.container {
    width: 100%;
}
.so-box {
    font-family:'Helvetica Neue', Arial, sans-serif;
    font-weight: bold;
    color: #fff;
    text-align: center;
    padding: .3em .7em;
    font-size: 1em;
    line-height: 1.1;
    border: 1px solid #c47b07;
    -webkit-box-shadow: 0 2px 2px rgba(0, 0, 0, 0.3), 0 2px 0 rgba(255, 255, 255, 0.15) inset;
    text-shadow: 0 0 2px rgba(0, 0, 0, 0.5);
    background: #f88912;
    box-shadow: 0 2px 2px rgba(0, 0, 0, 0.3), 0 2px 0 rgba(255, 255, 255, 0.15) inset;
}
.control {
    display: inline-block;
    border-radius: 6px;
    float: left;
    margin-right: 25px;
    cursor: pointer;
}
.option {
    padding: 10px 20px;
    margin-right: 25px;
    float: left;
}
h1 {
    text-align: center;
    font-family: Georgia, 'Times New Roman', serif;
}
a {
    text-decoration: none;
}
input, textarea {
    box-sizing: border-box;
}
textarea {
    display: block;
    white-space: pre;
    overflow: auto;
    height: 100px;
    width: 100%;
    max-width: 100%;
    min-height: 25px;
}
span[contenteditable] {
    padding: 2px 6px;
    background: #cc7801;
    color: #fff;
}
#stdout-container, #stdin-container {
    height: auto;
    padding: 6px 0;
}
#reset {
    float: right;
}
#source-display-wrapper , #stdin-display-wrapper{
    display: none;
    width: 100%;
    height: 100%;
    overflow: auto;
    border: 1px solid black;
    box-sizing: border-box;
}
#source-display , #stdin-display{
    font-family: monospace;
    white-space: pre;
    padding: 2px;
}
.activeToken {
    background: #f93;
}
.nextActiveToken {
    background: #bbb;
}
.swallowedCode{
    color: #999;
}
.clearfix:after {
    content:".";
    display: block;
    height: 0;
    clear: both;
    visibility: hidden;
}
.clearfix {
    display: inline-block;
}
* html .clearfix {
    height: 1%;
}
.clearfix {
    display: block;
}
<!--
Designed and written 2015 by D. Loscutoff
Much of the HTML and CSS was taken from this Befunge interpreter by Ingo Bürk: http://codegolf.stackexchange.com/a/40331/16766
-->
<div class="container">
<textarea id="source" placeholder="Enter your program here" wrap="off">i.)o</textarea>
<div id="source-display-wrapper" onclick="sourceDisplayClick()"><div id="source-display"></div></div></div><div id="stdin-container" class="container">
<textarea id="stdin" placeholder="Input" wrap="off">Hello, World!</textarea>
<div id="stdin-display-wrapper" onclick="stdinDisplayClick()"><div id="stdin-display"></div></div></div><div id="controls-container" class="container clearfix"><input type="button" id="run" class="control so-box" value="Run" onclick="runBtnClick()" /><input type="button" id="pause" class="control so-box" value="Pause" onclick="program.halt()" /><input type="button" id="step" class="control so-box" value="Step" onclick="stepBtnClick()" /><input type="button" id="reset" class="control so-box" value="Reset" onclick="resetProgram()" /></div><div id="stdout-container" class="container"><textarea id="stdout" placeholder="Output" wrap="off" readonly></textarea></div><div id="options-container" class="container"><div class="option so-box">Steps per Second:
<span id="steps-per-second" contenteditable>10</span></div></div>

\$\endgroup\$
4
\$\begingroup\$

Seriously, 7 bytes

	W+	W+R

Hexdump (reversible with xxd -r):

00000000: 0957 2b09 572b 52                        .W+.W+R

Explanation (tabs are replaced with \t for clarity):

\tW+\tW+R
\t         read a single byte of input
  W+\tW    while TOS is truthy:
   +         append
    \t       read a single byte of input
       +R  append, reverse, and implicitly print

Try it online!

\$\endgroup\$
4
  • 1
    \$\begingroup\$ Link not found for IDE \$\endgroup\$
    – jado
    Commented Nov 16, 2015 at 3:03
  • 1
    \$\begingroup\$ just don't go breaking my heat \$\endgroup\$
    – jado
    Commented Nov 16, 2015 at 3:06
  • \$\begingroup\$ Link is dead. Also, why do you swap the top two elements? Is it that there is an element other than the input byte? \$\endgroup\$ Commented Jan 14, 2017 at 11:55
  • \$\begingroup\$ @EriktheOutgolfer Seriously is stack-based, so without swapping, the output would be reversed. \$\endgroup\$
    – user45941
    Commented Jan 14, 2017 at 12:05
4
\$\begingroup\$

gs2, 0 bytes


The empty program echoes standard input. The language cannot possibly handle infinite streams.

\$\endgroup\$
4
\$\begingroup\$

Retina, 3 1 byte



That's a single linefeed.

Try it online!

The empty Retina program would count the number of matches of the empty regex in the input, so it can't compete with rs and sed here. There are several ways to implement a cat program, the shortest being a Replace stage that doesn't actually replace anything.

Retina cannot handle infinite streams (as it waits for EOF before starting any processing).

\$\endgroup\$
0
4
\$\begingroup\$

Pyramid Scheme, 199 116 bytes

Saved 83 bytes thanks to Khuldraeseth na'Barya! Clever idea to use the "nameless" variable, an empty triangle.

   ^
  /d\
 / o \
^-----^
-    ^-^
    ^-/ \
   ^-/out\
  / \-----^
 /set\    -
^-----^
-    /l\
    /ine\
    -----

Try it online!


Old version (functionally equivalent)

      ^
     / \
    /do \
   ^-----^
  /A\   / \
  ---  /   \
      /     \
     /       \
    ^---------^
   / \       / \
  /set\     /out\
 ^-----^   ^-----
/A\   /l\ /A\
---  /ine\---
     -----

Try it online!

Explanation

This might look like this in a scheme/lisp-like language:

(do (pair (set A read-line) (print A)) A)

Or, in a C-like language:

do {
    A = gets();
    puts(A);
} while(A);
\$\endgroup\$
5
  • \$\begingroup\$ 125 bytes \$\endgroup\$ Commented Jul 25, 2019 at 18:24
  • \$\begingroup\$ 116 \$\endgroup\$ Commented Jul 25, 2019 at 18:26
  • \$\begingroup\$ @Khuldraesethna'Barya Fascinating structure... Thanks! \$\endgroup\$ Commented Jul 26, 2019 at 0:35
  • \$\begingroup\$ Can you add some documentation for this language? I would like to try it out \$\endgroup\$
    – Jo King
    Commented Jul 26, 2019 at 6:23
  • 2
    \$\begingroup\$ @JoKing Sure thing! I'm going off to bed rn, I'll add it to my todo list and I'll ping you once I'm done. \$\endgroup\$ Commented Jul 26, 2019 at 6:24
4
\$\begingroup\$

NLRNIS, 12 bytes

&m>x
"_*m*x@

Explanation:

&#

Store input to m

>x
"

x = newline

_

if EOF then halt

*m*x

print variable m with newline

@

Repeat

\$\endgroup\$
4
\$\begingroup\$

unsure, 78 bytes

hm um err wait oops but um yeah err heh wait then well but oops okay well wait

I just invented this esolang, which is based off brain-flak. This program abuses a lot of control flow tricks, such as omitting the first but, which should start the first loop. It basically copies all of the input to the other stack (there's an active and non-active stack), and then outputs it all.

hm        Take input
um        Push 1 to the stack
err       Push the sum of the top 2 items
wait    Repeat if not 0
oops    Discard the top of the stack
but     Start another loop
um        Push 1 to the stack
yeah      Negate
err       Push the sum of the top 2 items
heh       Pop the active stack, push to the other one
wait    Repeat
then    Swap active stack
well    Push stack length
but     Start another loop
oops      Discard the top of the stack
okay      Output the top of the stack
well      Push the stack length
wait    Repeat   

unsure, 22 bytes (doesn't work with null bytes)

hm uh okay um err wait

This one repeatedly takes input, duplicates it, outputs it, and increments it (as EOF is -1, and the wait will only stop when the top of the stack is 0).

\$\endgroup\$
3
\$\begingroup\$

Perl, 18 bytes

print while$_=getc

Will handle null bytes and infinite streams.

\$\endgroup\$
2
  • 1
    \$\begingroup\$ Since the currently top answer consists of a sed invocation with no commands, you could also shorten this to perl -pe ''. However for the scope of the question your current solution is way more interesting, so if you do switch to the cheaty perl -pe '' please also leave your current solution. \$\endgroup\$
    – kos
    Commented Nov 1, 2015 at 18:33
  • \$\begingroup\$ The problem with perl -pe '' is that it would only work if the input was finite or contained occasional newlines. By using getc it can handle an infinite stream of input without newlines. \$\endgroup\$ Commented Jan 14, 2017 at 17:02
3
\$\begingroup\$

Macaroni 0.0.2, 44 chars

label l print set s read map slice s 0 1 1 l

Explanation:

label l           "define a label, which we need later"
print set s read  "read a line, set the variable s to it, and print it"
map
  slice s 0 1 1   "get the first element of the array s"
                  "this returns an array of either length 0 (if s was originally
                   empty) or 1"
  l               "map the resulting array over label l—essentially a
                   conditional goto"
\$\endgroup\$
3
\$\begingroup\$

D, 94 bytes

import std.stdio,std.algorithm;void main(){stdin.byChunk(1).copy(stdout.lockingTextWriter());}

I'm no D expert at all, so there might be a better way to do this.

\$\endgroup\$
1
  • \$\begingroup\$ I don't think you need the parens after stdout.lockingTextWriter. \$\endgroup\$
    – Adalynn
    Commented Nov 26, 2016 at 17:53
3
\$\begingroup\$

Python 2, 52 bytes

from sys import*
while 1:stdout.write(stdin.read(1))

Python will only echo when a newline has been pressed because by default the terminal only sends input to the program after a newline.

OR, 25 bytes

while 1:print raw_input()

In this program, the code explicitly waits for a newline before printing

\$\endgroup\$
6
  • \$\begingroup\$ @Mego the issue is on read... but that only applies when input is a terminal, and depends on the terminal's mode. Though you can press Ctrl-D in the middle of a line to make it output immediately. \$\endgroup\$
    – Random832
    Commented Oct 30, 2015 at 19:01
  • \$\begingroup\$ @Mego Not in the middle of the line unless you press it twice without typing anything else. Try it and see. \$\endgroup\$
    – Random832
    Commented Oct 30, 2015 at 20:52
  • \$\begingroup\$ good catch, sorry \$\endgroup\$
    – R Nar
    Commented Oct 30, 2015 at 20:59
  • \$\begingroup\$ No, this code is invalid in Python 2 as well. The semicolon should be a newline. \$\endgroup\$
    – lynn
    Commented Oct 30, 2015 at 23:46
  • \$\begingroup\$ @EriktheGolfer I'm doing stdin.read as well as stdout.write \$\endgroup\$
    – Blue
    Commented Sep 27, 2016 at 18:07
3
\$\begingroup\$

PDP-11 Unix Assembly, 38 bytes binary

s: xor r0, r0;      / set r0 to 0 (stdin)
   sys read; b; 1;  / read one byte
   tst r0; beq e;   / check return value, goto e if zero.
   sys write; b; 1; / fortuitously, r0 = 1 here. write one byte.
   br s;            / go to loop start.
e: sys exit;        / exit [r0 = 0]
.bss
b: .=.+1

I'll assemble it later to show the binary output (I haven't golfed the source yet either), but with symbols stripped this should come out to 36 bytes compiled: a 16-byte a.out header, and 2 bytes per instruction word (10, including arguments to system calls).

Note that the use of one-byte reads is not to save space (.bss variables take no space in the binary), it is so that the byte count argument to write can be hardcoded.

The OG is much larger by comparison. By my count, 60 instruction words, so 128 bytes. Of course, it has to loop through files on the command line (the original purpose of cat).

The binary output:

0000000 000407 000026 000000 000002 000000 000000 000000 000001
0000020 074000 104403 000026 000001 005700 001404 104404 000026
0000040 000001 000766 104401
0000046

38 bytes, as promised.

Source golfed: 59 bytes

s:74000
sys 3;b;1
5700;beq e
sys 4;b;1
br s
e:sys 1
b:.=.+1

Since I left out .bss, this generates a slightly larger binary at 40 bytes even.

\$\endgroup\$
3
\$\begingroup\$

Ruby, 19 bytes

This one handles arbitrary input like a champ:

print while gets 1

Ruby, 1 byte

An empty program run with the p flag behaves almost exactly like cat, but doesn't print until it hits a newline or EOF:

$ touch cat.rb
$ yes | ruby -p cat.rb
y
y
y
y

(...)

Ruby, 9 bytes

Basically the same, but doesn't need the p flag to be entered from the command line:

#!ruby -p

Not the most exciting entry, but I thought it should be in the catalogue.

\$\endgroup\$
4
  • 1
    \$\begingroup\$ touch echo.rb; (while true; do echo -n a; done) | ruby -p echo.rb never flushes for me. \$\endgroup\$
    – lynn
    Commented Oct 31, 2015 at 0:04
  • 1
    \$\begingroup\$ @Mauris never? You don't know that unless you've solved the halting problem (or it crashes?) :) Kidding, but omg this question is tl;dr. I'm sure you're right though. \$\endgroup\$
    – daniero
    Commented Oct 31, 2015 at 0:14
  • \$\begingroup\$ @Mauris there, 19 byte solution even works with your infinite stream of a's :) \$\endgroup\$
    – daniero
    Commented Oct 31, 2015 at 0:25
  • \$\begingroup\$ Ah, that one does the trick. Very cool! :) \$\endgroup\$
    – lynn
    Commented Oct 31, 2015 at 0:26
3
\$\begingroup\$

ngn APL, 7 bytes

{∇⍞←⍞}1

ngn APL only supports linewise input and has no actual looping constructs, so this recursive function is as good as it gets. It prints null bytes, but only if they do not occur on the last line.

How it works

{    }   Define a function.
  ⍞←⍞    Read and print a line.
 ∇       Call the function again.
      1  Call the function with dummy input.

exits automatically on EOF.

\$\endgroup\$
2
  • \$\begingroup\$ There is the looping construct . It's just not so procedural. \$\endgroup\$
    – jimmy23013
    Commented Nov 1, 2015 at 23:51
  • \$\begingroup\$ I haven't been able to get working for this task. Anyway, -⍣≡1 leaks memory, so the result would probably be the same. \$\endgroup\$
    – Dennis
    Commented Nov 2, 2015 at 4:44
3
\$\begingroup\$

Marbelous, 11 bytes

00
\\/\]]!!

How it works.

The 00 is a language literal, it represents 0, but could be exchanged for any hexadecimal value in this case. On the first tick, this value will fall down and hit \\ which is a deflector and will shove the marble to the right.

/\ is a cloner, which puts one marble to the right, back onto the deflector, this creates an infinite loop. The second copy will be placed to the right. This copy will hit the ]] device, which fetches the first character on STDIN and outputs its ascii code below. This will put the resulting marble off the botom of the board ; any marble that falls off the board gets printed to STDOUT.

In case there is nothing on STDIN, the ]] device will push the input marble too the right. There it will trigger the !! device, which terminates the board.

\$\endgroup\$
3
\$\begingroup\$

Befunge-93, 9 6 bytes

This solution (thanks to ninjalj!) depends on 0 % 0 throwing an error and halting, thus it will not work in all interpreters (like this one, where it's NaN instead and does not halt, though no more characters are outputted).

~:1+%,

~ reads in a character from input (-1 on EOF), then :1+ duplicates it and adds 1, so we now have either [0,0] or [n,n+1] on the stack. 0 % 0 is undefined, which (possibly) throws an error whereas n % (n+1) is simply n. , outputs as character.


Solution that does not depend on STDERR (9 bytes):

~:1+!#@_,

~ reads in a character from input (-1 on EOF), :1+ duplicates it and adds 1, ! "not"s this, then the # is a trampoline that jumps the program counter over the @. _ is a horizontal branch that goes right if the top of stack is 0, left otherwise. This is why I needed to ! the input + 1 earlier.


For what it's worth, you can try to get rid of the ! by reversing program flow. Unfortunately, to do this, you have to add a < and that simply produces another 9-byte solution:

<,_@#+1:~
\$\endgroup\$
2
  • \$\begingroup\$ Using the stderr rule, you can golf it to 6 bytes: ~:1+%,. This trick is used a lot in golf.shinh.org \$\endgroup\$
    – ninjalj
    Commented Nov 2, 2015 at 19:28
  • \$\begingroup\$ @ninjalj: Nice tip! Doesn't work in the Befunge interpreter I usually use though; 00% results in NaN. I'll include it anyway. \$\endgroup\$ Commented Nov 2, 2015 at 19:53
3
\$\begingroup\$

Carrot (version: ^3), 3 1 bytes

#

Explanation of code:

Basically prints the input to the output. The caret ^ is not needed because we do not wish to use any commands. Every instance of # is replaced with the input.


Carrot cannot handle infinite output yet as # is the only way to get the input in a string format.

\$\endgroup\$
0
3
\$\begingroup\$

Rail, 19 bytes

$'main'
@-i\
  \o-@

Rail is such a pain to golf... :D

This terminates with an error upon hitting EOF but handles null bytes and infinite streams without an issue.

The execution path starts from the $ going South-East. On - the train turns East, i reads a character. On \ the train turns South-East, and on - East again. @ reverses movement direction. The train now moves West, where o outputs the character again. \ turns the train North-West, - turns it West and @ reverses it once more. At this point we're in a loop between the two @, which terminates when i tries to read the end of the stream.

With a properly tail recursive interpreter, there is an 18-byte solution as well, but I can't currently test whether the reference implementation could handle it (which I doubt):

$'main'
 -io{main}
\$\endgroup\$
1
2
3 4 5
12

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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