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.


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 fulfil 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.

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.


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>

  • 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

330 Answers 330

2 3 4 5

sed, 0

The empty sed program does exactly what is required here:

$ printf "abc\ndef" | sed ''
  • 3
    \$\begingroup\$ What happens if one writes yes | tr -d \\n | sed ''? \$\endgroup\$ Commented Jan 14, 2017 at 17:17
  • 2
    \$\begingroup\$ @BenGoldberg By default sed works on a per-line basis, so in this case it will continue slurping up yeses into one pattern buffer until it runs out of memory. A caveat I suppose... \$\endgroup\$ Commented Jan 14, 2017 at 17:20
  • 2
    \$\begingroup\$ POSIX mandates that the pattern space must have a size of at least 8192 bytes, IIRC. I know the GNU implementation has a dynamic pattern space, limited only by the available memory, so you're fairly safe on that one. \$\endgroup\$ Commented May 9, 2018 at 14:03

Ziim, 222 201 196 185 182 bytes

    ↓ ↓

 ↓ ↓     ↓
 ↗ ↗↙↔↘↖ ↖
 ↓↓⤡⤢  ⤢↙
↘ ↖⤡ ↖
  ↕↘ ↑ ↙
→↘↖↑ ↙ ↑
→↖   ↑
→↖↘ ↙


This will probably not display correctly in your browser, so here is a diagram of the code:

enter image description here

I can't think of a simpler structure to solve the problem in Ziim, but I'm sure the actual code is still quite golfable.

Ziim cannot possibly handle infinite streams because it is only possible to print anything at the end of the program.


Since Ziim has a rather unique, declarative control flow model an imperative pseudocode algorithm won't cut it here. Instead, I'll explain the basics of Ziim and the present the tidied up structure of the above code (in a similar graphical manner) as ASCII art.

Control flow in Ziim happens all over the place: each arrow which isn't pointed at by another arrow initialises a "thread" which is processed independently of the others (not really in parallel, but there are no guarantees which order they are processed in, unless you sync them up via concatenation). Each such thread holds a list of binary digits, starting as {0}. Now each arrow in the code is some sort of command which has one or two inputs and one or two outputs. The exact command depends on how many arrows are pointing at it from which orientations.

Here is the list of the commands, where m -> n indicates that the command takes m inputs and produces n outputs.

  • 1 -> 1, no-op: simply redirects the thread.
  • 1 -> 1, invert: negates each bit in the thread (and also redirects it).
  • 1 -> 1, read: replaces the thread's value by the next bit from STDIN, or by the empty list if we've hit EOF.
  • 2 -> 1, concatenate: this is the only way to sync threads. When a thread hits one side of the arrow, it will be suspended until another thread hits the other side. At that point they will be concatenated into a single thread and continue execution.
  • 2 -> 1, label: this is the only way to join different execution paths. This is simply a no-op which has two possible inputs. So threads entering the "label" via either route will simply be redirected into the same direction.
  • 1 -> 2, split: takes a single thread, and sends two copies off in different directions.
  • 1 -> 1, isZero?: consumes the first bit of the thread, and sends the thread in one of two directions depending on whether the bit was 0 or 1.
  • 1 -> 1, isEmpty?: consumes the entire list (i.e. replaces it with an empty list), and sends the thread in one of two direction depending on whether the list was already empty or not.

So with that in mind, we can figure out a general strategy. Using concatenate we want to repeatedly append new bits to a string which represents the entire input. We can simply do this by looping the output of the concatenate back into one of its inputs (and we initialise this to an empty list, by clearing a {0} with isEmpty?). The question is how we can terminate this process.

In addition to appending the current bit we will also prepend a 0 or 1 indicating whether we've reached EOF. If we send our string through isZero?, it will get rid of that bit again, but let us distinguish the end of the stream, in which case we simply let the thread leave the edge of the grid (which causes Ziim to print the thread's contents to STDOUT and terminate the program).

Whether we've reached EOF or not can be determined by using isEmpty? on a copy of the input.

Here is the diagram I promised:

              +----------------------------+   {0} --> isEmpty --> label <--+
              |                            |                    n    |      |
              v                            |                         v      |
    {0} --> label --> read --> split --> split ------------------> concat   |
                                 |                                   |      |
                           n     v     y                             |      |
 inv --> label --> concat <-- isEmpty --> concat <-- label <-- {0}   |      |
  ^        ^          |                     |          ^             |      |
  |        |          v                     v          |             |      |
 {0}       +------- split ---> label <--- split -------+             |      |
                                 |                                   |      |
                                 +-------------> concat <------------+      |
                                                   |                        |
                                              y    v                        |
                         print and terminate <-- isZero --------------------+

Some notes about where to start reading:

  • The {0} in the top left corner is the initial trigger which starts the input loop.
  • The {0} towards the top right corner is immediately cleared to an empty list an represents the initial string which we'll gradually fill with the input.
  • The other two {0}s are fed into a "producer" loop (one inverted, one not), to give us an unlimited supply of 0s and 1s which we need to prepend to the string.
  • 40
    \$\begingroup\$ How can you even write a program like that without your brain exploding into a million little chunks of tissue. \$\endgroup\$ Commented Dec 28, 2015 at 16:15

Hexagony, 6 bytes

This used to be 3 bytes (see below), but that version no long works since the latest update of the language. As I never intentionally introduced the error that version made use of, I decided not to count it.

An error-free solution (i.e. one which works with the fixed interpreter) turns out to be much trickier. I've had some trouble squeezing it into a 2x2 grid, but I found one solution now, although I need the full 7 bytes:


After unfolding, we get:

enter image description here

Since the initial memory edge is 0, the < unconditionally deflects the instruction pointer into the North-East diagonal, where it wraps to the the grey path. The . is a no-op. Now , reads a byte, ) increments it such that valid bytes (including null bytes) are positive and EOF is 0.

So on EOF, the IP wraps to red path, where @ terminates the program. But if we still read a byte, then the IP wraps to the green path is instead where ( decrements the edge to the original value, before ; prints it to STDOUT. The IP now wraps unconditionally back to the grey path, repeating the process.

After writing a brute force script for my Truth Machine answer, I set it to find an error-free 6-byte solution for the cat program as well. Astonishingly, it did find one - yes, exactly one solution in all possible 6-byte Hexagony programs. After the 50 solutions from the truth machine, that was quite surprising. Here is the code:



enter image description here

The use of ~ (unary negation) instead of () is interesting, because a) it's a no-op on zero, b) it swaps the sides of the branch, c) in some codes a single ~ might be used twice to undo the operation with itself. So here is what's going on:

The first time (purple path) we pass through ~ it's a no-op. The / reflects the IP into the North-West diagonal. The grey path now reads a character and multiplies its character code by -1. This turns the EOF (-1) into a truthy (positive) value and all valid characters into falsy (non-positive) values. In the case of EOF, the IP takes the red path and the code terminates. In the case of a valid character, the IP takes the green path, where ~ undoes negation and ; prints the character. Repeat.

Finally, here is the 3-byte version which used to work in the original version Hexagony interpreter.


Like the Labyrinth answer, this terminates with an error if the input stream is finite.

After unfolding the code, it corresponds to the following hex grid:

enter image description here

The . are no-ops. Execution starts on the purple path.

, reads a byte, ; writes a byte. Then execution continues on the salmon(ish?) path. We need the & to reset the current memory edge to zero, such that the IP jumps back to the purple row when hitting the corner at the end of the second row. Once , hits EOF it will return -1, which causes an error when ; is trying to print it.

Diagrams generated with Timwi's amazing HexagonyColorer.

  • 3
    \$\begingroup\$ The 6-byte version is very, very clever. Brute-forcers can be incredibly awesome. \$\endgroup\$ Commented Mar 16, 2016 at 18:38
  • 1
    \$\begingroup\$ Do you have a link to your brute-forcer? \$\endgroup\$
    – MD XF
    Commented Feb 6, 2018 at 20:48
  • \$\begingroup\$ @MDXF I don't keep the various versions around, but it's always some modification of this Ruby script. \$\endgroup\$ Commented Feb 6, 2018 at 22:15

TeaScript, 0 bytes

TeaScript is a concise golfing language compiled to JavaScript

In a recent update the input is implicitly added as the first property.

Try it online

Alternatively, 1 byte


x contains the input in TeaScript. Output is implicit

  • \$\begingroup\$ I was about to post this :) \$\endgroup\$
    – user41805
    Commented Oct 30, 2015 at 17:06
  • 28
    \$\begingroup\$ Hah, I thought "Alternatively" was a language name... \$\endgroup\$
    – Quelklef
    Commented Sep 8, 2018 at 22:32

Brian & Chuck, 44 bytes


I originally created this language for Create a programming language that only appears to be unusable. It turns out to be a very nice exercise to golf simple problems in it though.

The Basics: Each of the two lines defines a Brainfuck-like program which operates on the other program's source code - the first program is called Brian and the second is called Chuck. Only Brian can read and only Chuck can write. Instead of Brainfuck's loops you have ? which passes control to the other program (and the roles of instruction pointer and tape head change as well). An addition to Brainfuck is { and } which scan the tape for the first non-zero cell (or the left end). Also, _ are replaced with null bytes.

While I don't think this is optimal yet, I'm quite happy with this solution. My first attempt was 84 bytes, and after several golfing sessions with Sp3000 (and taking some inspiration from his attempts), I managed to get it slowly down to 44, a few bytes at a time. Especially the brilliant +}+ trick was his idea (see below).


Input is read into the first cell on Chuck's tape, then painstakingly copied to the end of Brian's tape, where it's printed. By copying it to the end, we can save bytes on setting the previous character to zero.

The # is just a placeholder, because switching control does not execute the cell we switched on. {<{ ensures that the tape head is on Chuck's first cell. , reads a byte from STDIN or -1 if we hit EOF. So we increment that with + to make it zero for EOF and non-zero otherwise.

Let's assume for now we're not at EOF yet. So the cell is positive and ? will switch control to Chuck. }> moves the tape head (on Brian) to the + the _ and ? passes control back to Brian.

{- now decrements the first cell on Chuck. If it's not zero yet, we pass control to Chuck again with ?. This time }> moves the tape head on Brian two cells of the right of the last non-zero cell. Initially that's here:


But later on, we'll already have some characters there. For instance, if we've already read and printed abc, then it would look like this:


Where the 1s are actually 1-bytes (we'll see what that's about later).

This cell will always be zero, so this time ? won't change control. > moves yet another cell to the right and + increments that cell. This is why the first character in the input ends up three cells to the right of the ? (and each subsequent one three cells further right).

<<< moves back to the last character in that list (or the ? if it's the first character), and {> goes back to the + on Brian's tape to repeat the loop, which slowly transfers the input cell onto the end of Brian's tape.

Once that input cell is empty the ? after {- will not switch control any more. Then >}< moves the tape head on Chuck to the _ and switches control such that Chuck's second half is executed instead.

}>> moves to the cell we've now written past the end of Brian's tape, which is the byte we've read from STDIN, so we print it back with .. In order for } to run past this new character on the tape we need to close the gap of two null bytes, so we increment them to 1 with <+<+ (so that's why there are the 1-bytes between the actual characters on the final tape). Finally {<{ moves back to the beginning of Brian's tape and ? starts everything from the beginning.

You might wonder what happens if the character we read was a null-byte. In that case the newly written cell would itself be zero, but since it's at the end of Brian's tape and we don't care where that end is, we can simply ignore that. That means if the input was ab\0de, then Brian's tape would actually end up looking like:


Finally, once we hit EOF that first ? on Brian's tape will be a no-op. At this point we terminate the program. The naive solution would be to move to the end of Chuck's tape and switch control, such that the program termiantes: >}>}<?. This is where Sp3000's really clever idea saves three bytes:

+ turns Chuck's first cell into 1. That means } has a starting point and finds the _ in the middle of Chuck's tape. Instead of skipping past it, we simply close the gap by turning it into a 1 with + as well. Now let's see what the rest of Brian's code happens to do with this modified Chuck...

{ goes back to Chuck's first cell as usual, and - turns it back into a null-byte. That means that ? is a no-op. But now >}<, which usually moved the tape head to the middle of Chuck's tape, moves right past it to the end of Chuck's tape and ? then passes control to Chuck, terminating the code. It's nice when things just work out... :)


Haskell, 16 bytes

main=interact id

interact reads the input, passes it to the function given as its argument and prints the result it receives. id is the identity function, i.e. it returns its input unchanged. Thanks to Haskell's laziness interact can work with infinite input.


sh + binutils, 3 2 bytes


Well, not quite as obvious. From @Random832



The painfully obvious... :D

  • 18
    \$\begingroup\$ I'll do one better: dd. \$\endgroup\$
    – Random832
    Commented Oct 30, 2015 at 18:58
  • \$\begingroup\$ I was going to do cat... D: \$\endgroup\$
    – user46167
    Commented Nov 6, 2015 at 0:08
  • 3
    \$\begingroup\$ Yes, this is great and all... but 170 rep for typing cat??? \$\endgroup\$
    – MD XF
    Commented Jun 10, 2017 at 23:59
  • 2
    \$\begingroup\$ @MDXF what about who knows how much rep from a segfault? ;) \$\endgroup\$ Commented Sep 3, 2017 at 14:21

Motorola MC14500B Machine Code, 1.5 bytes

Written in hexadecimal:


Written in binary:

0001 1000 1111


1   Read from I/O pin
8   Output to I/O pin
F   Loop back to start

The opcodes are 4 bits each.

  • 1
    \$\begingroup\$ -1 no screenshot, example or Try It Online link :P (jk) \$\endgroup\$
    – MD XF
    Commented Jun 11, 2017 at 0:04
  • 3
    \$\begingroup\$ +1. The only way I can think of to optimise this further would be to just solder the input pin to the output pin and take the chip out of it's socket :P \$\endgroup\$
    – Wossname
    Commented Jun 19, 2017 at 8:35

Funciton, 16 bytes


(Encoded as UTF-16 with a BOM)


The box returns the contents of STDIN. The loose end outputs it.


Mornington Crescent, 41 bytes

Take Northern Line to Mornington Crescent

I have no idea whether Mornington Crescent can handle null bytes, and all input is read before the program starts, as that is the nature of the language.


Brainfuck, 5 bytes


Equivalent to the pseudocode:

x = getchar()
while x != EOF:
    x = getchar()

This handles infinite streams, but treats null bytes as EOF. Whether or not BF can handle null bytes correctly varies from implementation to implementation, but this assumes the most common approach.

  • 1
    \$\begingroup\$ DARN! You beat me to it by 5 mins! \$\endgroup\$ Commented Oct 30, 2015 at 16:29
  • \$\begingroup\$ If the first character is NULL then this won't run correctly. So it should be +[,.] right? \$\endgroup\$
    – Shelvacu
    Commented Oct 30, 2015 at 17:41
  • 6
    \$\begingroup\$ @Shel This is using 0x00 as the EOF byte. If the first character is EOF, it prints nothing, working as expected. \$\endgroup\$
    – user45941
    Commented Oct 30, 2015 at 20:52
  • 3
    \$\begingroup\$ "pseudocode" oh come on that's clearly just un-bracketed, un-semicolon-ed C :P \$\endgroup\$
    – MD XF
    Commented Jun 11, 2017 at 0:03

Labyrinth, 2 bytes


If the stream is finite, this will terminate with an error, but all the output produce by the error goes to STDERR, so the standard output stream is correct.

As in Brainfuck , reads a byte (pushing it onto Labyrinth's main stack) and . writes a byte (popping it from Labyrinth's main stack).

The reason this loops is that both , and . are "dead ends" in the (very trivial) maze represented by the source code, such that the instruction pointer simply turns around on the spot and moves back to the other command.

When we hit EOF , pushes -1 instead and . throws an error because -1 is not a valid character code. This might actually change in the future, but I haven't decided on this yet.

For reference, we can solve this without an error in 6 bytes as follows


Here, the ) increments the byte we read, which gives 0 at EOF and something positive otherwise. If the value is 0, the IP moves straight on, hitting the @ which terminates the program. If the value was positive, the IP will instead take a right-turn towards the ( which decrements the top of the stack back to its original value. The IP is now in a corner and will simply keep making right turns, printing with ., reading a new byte with ., before it hits the fork at ) once again.


X86 assembly, 70 bytes

Disassembly with objdump:

00000000 <.data>:
   0:   66 83 ec 01             sub    sp,0x1
   4:   66 b8 03 00             mov    ax,0x3
   8:   00 00                   add    BYTE PTR [eax],al
   a:   66 31 db                xor    bx,bx
   d:   66 67 8d 4c 24          lea    cx,[si+0x24]
  12:   ff 66 ba                jmp    DWORD PTR [esi-0x46]
  15:   01 00                   add    DWORD PTR [eax],eax
  17:   00 00                   add    BYTE PTR [eax],al
  19:   cd 80                   int    0x80
  1b:   66 48                   dec    ax
  1d:   78 1c                   js     0x3b
  1f:   66 b8 04 00             mov    ax,0x4
  23:   00 00                   add    BYTE PTR [eax],al
  25:   66 bb 01 00             mov    bx,0x1
  29:   00 00                   add    BYTE PTR [eax],al
  2b:   66 67 8d 4c 24          lea    cx,[si+0x24]
  30:   ff 66 ba                jmp    DWORD PTR [esi-0x46]
  33:   01 00                   add    DWORD PTR [eax],eax
  35:   00 00                   add    BYTE PTR [eax],al
  37:   cd 80                   int    0x80
  39:   eb c9                   jmp    0x4
  3b:   66 b8 01 00             mov    ax,0x1
  3f:   00 00                   add    BYTE PTR [eax],al
  41:   66 31 db                xor    bx,bx
  44:   cd 80                   int    0x80

The source:

sub esp, 1
mov eax,3
xor ebx,ebx
lea ecx,[esp-1]
mov edx,1
int 0x80
dec eax
js e
mov eax,4
mov ebx,1
lea ecx,[esp-1]
mov edx,1
int 0x80
jmp t
mov eax,1
xor ebx,ebx
int 0x80
  • 1
    \$\begingroup\$ So, objdump disassembled it as 32-bit code, while you seem to have compiled as 16-bit. What to believe? Since you use int 0x80, I guess it's meant for Linux, but why compile as 16-bit then? \$\endgroup\$
    – Ruslan
    Commented Nov 2, 2015 at 13:08
  • 1
    \$\begingroup\$ @Ruslan I didn't even realize it was compiled in 16-bit... \$\endgroup\$ Commented Nov 2, 2015 at 14:35

><>, 7 bytes


Try it here. Explanation:

i        Take a character from input, pushing -1 if the input is empty
 :0(     Check if the input is less than 0, pushing 1 if true, 0 if false
    ?;   Pop a value of the top of the stack, ending the program if the value is non-zero
      o  Otherwise, output then loop around to the left and repeat

If you want it to keep going until you give it more input, replace the ; with !.

  • \$\begingroup\$ Aww man, I was hoping to post the ><> answer... :P (+1!) \$\endgroup\$ Commented Oct 30, 2015 at 19:20
  • 1
    \$\begingroup\$ io (2 bytes) does the same, but crashes and writes something smells fishy... to STDERR at the end of execution, which is allowed. \$\endgroup\$
    – lynn
    Commented Oct 31, 2015 at 12:25
  • \$\begingroup\$ @Mauris the online interpreter just outputs null bytes instead of ending with an error. \$\endgroup\$
    – DanTheMan
    Commented Nov 2, 2015 at 12:28

Universal Lambda, 1 byte


A Universal Lambda program is an encoding of a lambda term in binary, chopped into chunks of 8 bits, padding incomplete chunks with any bits, converted to a byte stream.

The bits are translated into a lambda term as follows:

  • 00 introduces a lambda abstraction.
  • 01 represents an application of two subsequent terms.
  • 111..10, with n repetitions of the bit 1, refers to the variable of the nth parent lambda; i.e. it is a De Bruijn index in unary.

By this conversion, 0010 is the identity function λa.a, which means any single-byte program of the form 0010xxxx is a cat program.

  • 1
    \$\begingroup\$ But ! is 0x21, not 0x4_? \$\endgroup\$
    – wchargin
    Commented Nov 1, 2015 at 21:07
  • \$\begingroup\$ Fixed. -------- \$\endgroup\$
    – lynn
    Commented Nov 1, 2015 at 21:08

C, 40 bytes

  • \$\begingroup\$ main(){while(255-putchar(getchar()));} is a couple of bytes shorter. \$\endgroup\$
    – Alchymist
    Commented Nov 3, 2015 at 13:50
  • 1
    \$\begingroup\$ Sadly, that exits prematurely on 0xFF bytes and appends a 0xFF byte to the input if it doesn't contain it. \$\endgroup\$
    – Dennis
    Commented Nov 3, 2015 at 13:58
  • \$\begingroup\$ What about the following, 36 bytes: main(){for(;;putchar(getchar()));}; \$\endgroup\$
    – jdt
    Commented Feb 18, 2016 at 18:06
  • \$\begingroup\$ @user2943932 When it hits EOF, getchar returns -1, so your code will print an infinite stream of 0xFF bytes after the (finite) input. \$\endgroup\$
    – Dennis
    Commented Feb 18, 2016 at 18:12

Cubix, 6 5 bytes

Now handles null bytes!


Cubix is a 2-dimensional, stack-based esolang. Cubix is different from other 2D langs in that the source code is wrapped around the outside of a cube.

Test it online! Note: there's a 50 ms delay between iterations.


The first thing the interpreter does is figure out the smallest cube that the code will fit onto. In this case, the edge-length is 1. Then the code is padded with no-ops . until all six sides are filled. Whitespace is removed before processing, so this code is identical to the above:

_ i ? o

Now the code is run. The IP (instruction pointer) starts out on the far left face, pointing east.

The first char the IP encounters is _, which is a mirror that turns the IP around if it's facing north or south; it's currently facing east, so this does nothing. Next is i, which inputs a byte from STDIN. ? turns the IP left if the top item is negative, or right if it's positive. There are three possible paths here:

  • If the inputted byte is -1 (EOF), the IP turns left and hits @, which terminates the program.
  • If the inputted byte is 0 (null byte), the IP simply continues straight, outputting the byte with o.
  • Otherwise, the IP turns right, travels across the bottom face and hits the mirror _. This turns it around, sending it back to the ?, which turns it right again and outputs the byte.

I think this program is optimal. Before Cubix could handle null bytes (EOF was 0, not -1), this program worked for everything but null bytes:


I've written a brute-forcer to find all 5-byte cat programs. Though it takes ~5 minutes to finish, the latest version has found 5 programs:

@_i?o   (works as expected)
@i?o_   (works in exactly the same way as the above)
iW?@o   (works as expected)
?i^o@   (false positive; prints U+FFFF forever on empty input)
?iWo@   (works as expected)
  • \$\begingroup\$ Please don't edit a dozen posts at once. You're flooding the front page. 3 at a time is not an issue, but if you have to do more than that then please do your edits in small batches every 12 hours or so. \$\endgroup\$ Commented Sep 7, 2016 at 9:48
  • \$\begingroup\$ @MartinEnder Sorry, I just noticed that. I'll space them out in the future. \$\endgroup\$ Commented Sep 7, 2016 at 9:49

PowerShell, 88 41 30 Bytes


EDIT -- forgot that I can use the $input automatic variable for pipeline input ... EDIT2 -- don't need to test for existence of $input

Yeah, so ... STDIN in PowerShell is ... weird, shall we say. With the assumption that we need to accept input from all types of STDIN, this is one possible answer to this catalogue, and I'm sure there are others.1

Pipeline input in PowerShell doesn't work as you'd think, though. Since piping in PowerShell is a function of the language, and not a function of the environment/shell (and PowerShell isn't really solely a language anyway), there are some quirks to behavior.

For starters, and most relevant to this entry, the pipe isn't evaluated instantaneously (most of the time). Meaning, if we have command1 | command2 | command3 in our shell, command2 will not take input or start processing until command1 completes ... unless you encapsulate your command1 with a ForEach-Object ... which is different than ForEach. (even though ForEach is an alias for ForEach-Object, but that's a separate issue, since I'm talking ForEach as the statement, not alias)

This would mean that something like yes | .\simple-cat-program.ps1 (even though yes doesn't really exist, but whatever) wouldn't work because yes would never complete. If we could do ForEach-Object -InputObject(yes) | .\simple-cat-program.ps1 that should (in theory) work.

Getting to Know ForEach and ForEach-Object on the Microsoft "Hey, Scripting Guy!" blog.

So, all those paragraphs are explaining why if($input){$input} exists. We take an input parameter that's specially created automatically if pipeline input is present, test if it exists, and if so, output it.

Then, we take input from the user (read-host) via what's essentially a separate STDIN stream, and write-host it back out, with the -n flag (short for -NoNewLine). Note that this does not support arbitrary length input, as read-host will only complete when a linefeed is entered (technically when the user presses "Enter", but functionally equivalent).


1But there are other options:

For example, if we were concerned with only pipeline input, and we didn't require a full program, you could do something like | $_ which would just output whatever was input. (In general, that's somewhat redundant, since PowerShell has an implicit output of things "left behind" after calculations, but that's an aside.)

If we're concerned with only interactive user input, we could use just write-host(read-host)-n.

Additionally, this function has the quirk feature of accepting command-line input, for example .\simple-cat-program.ps1 "test" would populate (and then output) the $a variable.

  • \$\begingroup\$ don't forget your built in aliases! \$\endgroup\$ Commented Oct 6, 2016 at 16:19

MarioLANG, 11 bytes


I'm not entirely sure this is optimal, but it's the shortest I found.

This supports infinite streams and will terminate with an error upon reaching EOF (at least the Ruby reference implementation does).

There's another version of this which turns Mario into a ninja who can double jump:


In either case, Mario starts falling down the left column, where , reads a byte and . writes a byte (which throws an error at EOF because , doesn't return a valid character). > ensures that Mario walks to the right (= is just a ground for him to walk on). Then he moves up, either via a double jump with ^ or via an elevator (the " and # pair) before the < tells him to move back to the left column.


INTERCALL, 133 bytes


  • 1
    \$\begingroup\$ It looks like someone really golfed in a purely anti-golfing language... 133-116=17 \$\endgroup\$ Commented Jun 16, 2016 at 10:13
  • \$\begingroup\$ @EʀɪᴋᴛʜᴇGᴏʟғᴇʀ Since the cat program is pretty simple, this is'nt the case of all programs... codegolf.stackexchange.com/a/82748/53745 \$\endgroup\$ Commented Jun 16, 2016 at 13:36
  • \$\begingroup\$ The person who made the language intended to use roman numerals, but if it was the case to print 500 (not sure), it would be PRINT D, right? (excluding the header) \$\endgroup\$ Commented Jun 16, 2016 at 13:52
  • \$\begingroup\$ @EʀɪᴋᴛʜᴇGᴏʟғᴇʀ Nope, INTERCALL can only print ASCII characters and use a stack, so for example to print the caracter with ascii value 20 the code is PUSH XX<newline>PRINT or PUSH XX AND PRINT. Oh and i am the creator of INTERCALL \$\endgroup\$ Commented Jun 16, 2016 at 13:55

rs, 0 bytes

Seriously. rs just prints whatever it gets if the given script is completely empty.


Vitsy, 2 bytes


z gets all of the input stack and pushes it to the active program stack. Z prints out all of the active stack to STDOUT.

Alternate method:

I\      Repeat the next character for input stack's length.
  i     Grab an item from the input.
   l\   Repeat the next character for the currently active program stack's length.
     O  Output the top item of the stack as a character.
  • 2
    \$\begingroup\$ ^_^ Have a +1 anyway! :) \$\endgroup\$ Commented Oct 30, 2015 at 16:35
  • \$\begingroup\$ Pity votes, my favorite! \$\endgroup\$ Commented Oct 30, 2015 at 16:36
  • \$\begingroup\$ Why the downvotes? This seems to be a perfectly valid entry \$\endgroup\$ Commented Oct 30, 2015 at 23:25
  • 1
    \$\begingroup\$ It is valid by all specs. \$\endgroup\$ Commented Oct 30, 2015 at 23:44

V, 0 bytes

Try it online!

V's idea of "memory" is just a gigantic 2D array of characters. Before any program is ran, all input it loaded into this array (known as "The Buffer"). Then, at the end of any program, all text in the buffer is printed.

In other words, the empty program is a cat program.


Half-Broken Car in Heavy Traffic, 9 + 3 = 12 bytes


Half-Broken Car in Heavy Traffic (HBCHT) takes input as command line args, so run like

py -3 hbcht cat.hbc -s "candy corn"

Note that the +3 is for the -s flag, which outputs as chars. Also, HBCHT doesn't seem handle NULs, as all zeroes are dropped from the output (e.g. 97 0 98 is output as two chars ab).


In HBCHT, your car starts at the o and your goal is the exit #. ^>v< direct the car's movement, while simultaneously modifying a BF-like tape (^>v< translate to +>-<). However, as the language name suggests, your car can only turn right – any attempts to turn left are ignored completely (including their memory effects). Note that this is only for turning – your car is perfectly capable of driving forward/reversing direction.

Other interesting parts about HBCHT are that your car's initial direction is randomised, and the grid is toroidal. Thus we just need the car to make it to the exit without modifying the tape for all four initial directions:

  • Up and down are straightforward, heading directly to the exit.

  • For left, we wrap and execute < and increment with ^. We can't turn left at the next < so we wrap and decrement with v, negating out previous increment. Since we're heading downwards now we can turn right at the < and exit, having moved the pointer twice and modifying no cell values.

  • For right, we do the same thing as left but skip the first ^ since we can't turn left.

Edit: It turns out that the HBCHT interpreter does let you execute just a single path via a command line flag, e.g.

py -3 hbcht -d left cat.hbc

However, not only is the flag too expensive for this particular question (at least 5 bytes for " -d u"), it seems that all paths still need to be able to make it to the exit for the code to execute.


Seed, 3883 3864 10 bytes

4 35578594

Try it online!

This is one of the stupidest things I have ever done.

  • \$\begingroup\$ i like that you probably could have just gone through the programs sequentially and found this one within a reasonable time \$\endgroup\$
    – Jo King
    Commented Dec 9, 2022 at 2:49
  • 1
    \$\begingroup\$ @JoKing This is pretty much exactly what I did. \$\endgroup\$
    – apollyon
    Commented Dec 10, 2022 at 17:57

GolfScript, 3 bytes


The empty program echoes standard input. The language cannot possibly handle infinite streams. However, it appends a newline, as @Dennis mentioned. It does so by wrapping the whole stack in an array and calling puts, which is defined as print n print, where n is a newline. However, we can redefine n to be STDIN, and then empty the stack, which is precisely what :n; does.

  • \$\begingroup\$ Isn't GolfScript in TIO? \$\endgroup\$
    – Someone
    Commented Feb 4, 2021 at 19:08

Snowman 1.0.2, 15 chars


Taken directly from Snowman's examples directory. Reads a line, prints a line, reads a line, prints a line...

Note that due to an implementation detail, when STDIN is empty, vg will return the same thing as it would for an empty line. Therefore, this will repeatedly print newlines in an infinite loop once STDIN is closed. This may be fixed in a future version.

Explanation of the code:

(        // set two variables (a and f) to active—this is all we need
:...;bD  // a "do-loop" which continues looping as long as its "return value"
         // is truthy
  vGsP   // read a line, print the line
  10wRsp // print a newline—"print" is called in nonconsuming mode; therefore,
         // that same newline will actually end up being the "return value" from
         // the do-loop, causing it to loop infinitely

Minkolang, 5 bytes


Try it here.


o reads in a character from input and pushes its ASCII code onto the stack (0 if the input is empty). d then duplicates the top of stack (the character that was just read in). ? is a conditional trampoline, which jumps the next instruction of the top of stack is not 0. If the input was empty, then the . is not jumped and the program halts. Otherwise, O outputs the top of stack as a character. The toroidal nature of Minkolang means that this loops around to the beginning.

  • 2
    \$\begingroup\$ Grar! You beat my language! UNACCEPTABLE! +1 \$\endgroup\$ Commented Oct 30, 2015 at 16:35
  • \$\begingroup\$ Which one is yours? \$\endgroup\$
    – Someone
    Commented Feb 4, 2021 at 19:07

Vyxal, 0 bytes

Try it Online!

Implicitly inputs then implicitly outputs. Stretching the rules a teeny bit. Specifically the following rule:

The only exception being if your language absolutely always prints a trailing newline after execution.

In Vyxal, "printing after execution" (implicit, not explicit printing) always prints with a newline.


05AB1E, 50 38 bytes

[“€¬((a=IO.‚Ø 9)!=:eof)€· IO.‡í€…„–“.E

Try it online or test an infinite stream.


This is probably the first real 05AB1E cat posted here. While my previous answer (?) mostly worked...

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.

And while there seems to be no way of doing this in 05AB1E, making ? the shortest possible answer, there is one not very commonly used command that does the trick. .E pops a string and runs it as an Elixir program.

In this case, we use the following Elixir code:

a = IO.read(x)
if a != :eof do

…where x is the number of bytes to read each time — the greater it is, the faster the program runs. It can be anything but :all, as that would be equivalent to my previous submission, invalidating it.

We can golf this down to:

if((a=IO.read x)!=:eof)do IO.write a end

By now, you might've realized that this program only ever outputs the first x bytes of input. But running the Elixir code isn't the only thing the program does. It runs it over and over in an infinite loop ([)!

The weird symbols you see in the 05AB1E program are dictionary compression – compressing English words or other common letter combinations into just two bytes each. By substituting in 9 for x in the Elixir program (making the program as fast as it can be while not raising the bytecount), we get the final program!

2 3 4 5

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.