175
\$\begingroup\$

A truth-machine (credits goes to this guy for coming up with it) is a very simple program designed to demonstrate the I/O and control flow of a language. Here's what a truth-machine does:

  • Gets a number (either 0 or 1) from STDIN.

  • If that number is 0, print out 0 and terminate.

  • If that number is 1, print out 1 forever.

Challenge

Write a truth-machine as described above in your language of choice. The truth-machine must be a full program that follows these rules:

  • take input from STDIN or an acceptable alternative
    • If your language cannot take input from STDIN, it may take input from a hardcoded variable or suitable equivalent in the program
  • must output to STDOUT or an acceptable alternative
    • If your language is incapable of outputting the characters 0 or 1, byte or unary I/O is acceptable.
  • when the input is 1, it must continually print 1s and only stop if the program is killed or runs out of memory
  • the output must only be either a 0 followed by either one or no newline or space, or infinite 1s with each 1 followed by either one or no newline or space. No other output can be generated, except constant output of your language's interpreter that cannot be suppressed (such as a greeting, ANSI color codes or indentation). Your usage of newlines or spaces must be consistent: for example, if you choose to output 1 with a newline after it all 1s must have a newline after them.

  • if and only if your language cannot possibly terminate on an input of 0 it is acceptable for the code to enter an infinite loop in which nothing is outputted.

Since this is a catalog, languages created after this challenge are allowed to compete. 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. Other than that, all the standard rules of must be obeyed. Submissions in most languages will be scored in bytes in an appropriate preexisting encoding (usually UTF-8).

Catalog

The Stack Snippet at the bottom of this post generates the catalog 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: 320px; 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 = 62732; var ANSWER_FILTER = "!t)IWYnsLAZle2tQ3KqrVveCRJfxcRLe"; var COMMENT_FILTER = "!)Q2B_A2kjfAiU78X(md6BoYk"; var OVERRIDE_USER = 12012; var answers = [], answers_hash, answer_ids, answer_page = 1, more_answers = true, comment_page; function answersUrl(index) { return "https://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 "https://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(), 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\$
19
  • 3
    \$\begingroup\$ Assuming any behaviour is fine for all invalid inputs? \$\endgroup\$
    – Cruncher
    Commented Nov 3, 2015 at 17:33
  • 3
    \$\begingroup\$ @Cruncher Yes, the only inputs you should expect to get are 0 and 1. \$\endgroup\$ Commented Nov 3, 2015 at 17:38
  • 5
    \$\begingroup\$ Catalog is borked. \$\endgroup\$ Commented Nov 6, 2015 at 15:18
  • 2
    \$\begingroup\$ Catalog appears to consider Bf and bf to be different languages. \$\endgroup\$ Commented Nov 10, 2015 at 1:13
  • 1
    \$\begingroup\$ Is one allowed to print an infinite number of 1s? That is, not print out 1s forever, but print out an infinite list of 1s all at once? This would be theoretically demonstrated, but the language has no notion of printing more than once. It just generates an output. So is it okay if it runs indefinitely, but would print infinite 1s given infinite time (to finish executing)? \$\endgroup\$
    – AviFS
    Commented Apr 26, 2020 at 1:42

502 Answers 502

1
2
3 4 5
17
7
\$\begingroup\$

MarioLANG, 11 8 bytes

;:
[^
=:

This prints a space after each 0 or 1 (as has been clarified is acceptable). The program was tested in the Ruby interpreter. It's not clear whether this behaviour of ^ is according to spec, but it works consistently in this implementation.

As usual, = is just some ground for Mario to walk on.

  • ; reads an integer from STDIN into the current tape cell.
  • [ is a conditional. If the tape cell is 0, Mario skips the next cell (the ^), which will make him fall through the : (printing the 0), off the bottom edge and terminate the program (poor Mario). If the tape cell is 1, this does nothing, and execution continues.
  • ^ is a jump command. It stops Mario from moving forward and sends him straight up one cell before he falls back down. For some reason (at least in this implementation) Mario can jump in mid-air provided there's another cell (even a space) below the jump. That means Mario repeatedly jumps into the top :, printing the 1, falls back down onto the ^ and performs another jump. This must be a feature from the popular Super Ninja Brothers spin-off.
\$\endgroup\$
1
  • 3
    \$\begingroup\$ Aww, poor mario. \$\endgroup\$
    – user54200
    Commented Jul 23, 2016 at 2:37
7
\$\begingroup\$

PlatyPar, 2 Bytes

wA

Explanation:

Implicit: push input to the stack.

w: while last item. A: alert last item.

If you give it something truthy, while(stack[-1]) goes on infinitely. If not, it skips that, and alerts the last item of the stack implicitly (falsy).

Try it online! Press cancel instead of ok on the alert if you want to stop the loop after giving a 1.

\$\endgroup\$
2
  • \$\begingroup\$ why Platy? Is it different from normal Par? \$\endgroup\$
    – cat
    Commented Dec 15, 2015 at 4:59
  • 3
    \$\begingroup\$ After extensive research, I failed to discover there was already a language named Par. I found this as someone had posted an answer in a language called Par (not mine), and I was getting credit for his answers, and vice-versa. I have renamed mine, as I am sure the other came first (mine is only a week old). \$\endgroup\$
    – Cyoce
    Commented Dec 15, 2015 at 5:41
6
\$\begingroup\$

Ouroboros, 11 7 bytes

Inspired by Sp3000's ><> answer.

r.*.n!(

Each line of code in an Ouroboros program represents a snake eating its tail.

r reads a number from input, or -1 for EOF. .* squares it, keeping 0 and 1 the same but mapping -1 to 1. .n outputs the number, leaving a copy on the stack. Finally, !( logically negates and eats that many characters of the end of the snake. If the number was 0, this eats one character, the (, which is also the current instruction. Since the instruction pointer was swallowed, the snake dies and the program ends. If the number was 1, this eats zero characters, and execution loops back to the beginning of the snake, repeating indefinitely.

Try it:

// 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: 50px;
    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: https://codegolf.stackexchange.com/a/40331/16766
-->
<div class="container">
<textarea id="source" placeholder="Enter your program here" wrap="off">r.*.n!(</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">1</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>20</span></div></div>


Previous two-snake solution:

rm1(
S.n.!(

Snake 1

r reads a number from input; m moves it to the shared stack. Then 1( causes the snake to eat its instruction pointer and die.

Snake 2

S switches to the shared stack. .n duplicates the value and outputs it as a number. .!( duplicates again, logically negates, and eats that many characters. If the number was 0, this eats one character, killing the second snake and ending the program. If the number was 1, this eats zero characters and execution loops back to the beginning of the snake, repeating indefinitely.

\$\endgroup\$
2
  • 1
    \$\begingroup\$ Did you just post the source code for an interpreter with the answer? Why not link to it? \$\endgroup\$
    – Cyoce
    Commented Jan 7, 2016 at 7:02
  • 1
    \$\begingroup\$ @Cyoce The interpreter was written as part of Helka Homba's stack snippet challenge. Per his own statement, "the point is to make something that can be easily copied and used in future PPCG questions and answers." The fact that it was done here means that Helka's plan worked perfectly. :) \$\endgroup\$
    – Alex A.
    Commented Aug 16, 2016 at 5:02
6
\$\begingroup\$

AutoHotkey, 20 bytes

I recently got into AutoHotkey and have been waiting for a suitable challenge to try my skills at.

$0::Send 0
1::Send

This takes input by listening for key presses and outputs via simulated key presses. The $ on the first line forces the first hotkey to take input through the keyboard only, so it just outputs 0 when the 0 key is pressed. The second is not so lucky though. When it detects the 1 key being pressed, it presses the 1 key, which it detects, so it presses 1, which it detects and so on. AutoHotkey unfortunately doesn't like this, but that can probably be fixed by adding #HotkeysInterval 1 to the top of the program. I am not brave enough to try this though, as it will probably crash my computer.

If input and output through key presses is invalid, here's a solution that avoids it:

InputBox, a
MsgBox %a%
While a{
MsgBox 1
}
\$\endgroup\$
1
  • \$\begingroup\$ This is the first answer I've seen in AutoHotkey. Have a +1 \$\endgroup\$
    – Cyoce
    Commented Jan 7, 2016 at 7:22
6
\$\begingroup\$

Woefully, 266 bytes

First answer in this language!

It's called woefully because the bytecounts are saddening

Woefully is a 2d language with no conditionals, except for the notz/bool command (pop a, push 1 if not zero, else push zero), and combining this with the move char pointer command yields control flow. In a truth machine, the values entered are already zero or one, and are only of two values, so is less complex than some other conditional programs, which kind of defeats the purpose of the truth machine :P

There are two pointers, the instruction pointer (ip), and the char pointer (cp), and it's hard to explain in one post, but the ip goes through the paths, cp stays stationary unless moved by instructions the ip executes.

Woefully has 2 stacks, all pushing is to A, except dupe and AtoB

| || ||||| |
|| |||||| |
||| |||| |
|||| || |
||||| || |
||||| ||| |
||||| |||| |
||||| ||||| |
||||| |||||| |
||||| |
|||||| |
||||||| |
|||||| |
||||| |
|||| |
||| |
|| |
| |
|| |
||| |
||| |
|||| |
||| |
|| |
| |
| |
| |
| |
| |
|| |
||| |
|||| |
||||| |
|||||| |

Try it online!

Explanation (difficult from the size) Execution starts at the v, at the A path:

V   FI    \/  V shows initial char pointer pos, F the pos after movement
|A||X|||||Z|   if input is zero, I if it is 1. The path marked by \/ won't
||A||||||Z|    be executed until the first part has been done, and then only
|||A||||Z|  #X path halts program                          if input is zero 
||||A||Z|   # A path pushes input     #Z path pushes one
|||||A||O|
|||||E|||O|
|||||E||||O|   #E path dupes, by peeking top of a stack, pushing to b stack
|||||E|||||O| #O path outputs TOS of A
|||||E||||||O|
|||||E|    ^End of path, go back to char pointer, still over this path
||||||F|      #F path pops a, moves the char pointer
|||||||F|
||||||G|
|||||G|
||||G|
|||G|      #G path pushes 4
||G|
|G|
||H|   #H pops a, moves char pointer by a. the char pointer is (again)
|||H|  #now over F or I, depending on input
|||X|  X are nops
||||X|
|||L|   L path pushes 1
||L|
|L|
|V| V path multiplies both TOS (A and B), pushes to A
|V|
|V|
|V|
||O|
|||O|    O path outputs tos of A
||||O|
|||||O|
||||||O|
End of path, go back to the char pointer. If input was zero, the char
pointer will be over the halting path, so program over, otherwise it's over
the next char, and goes to the infinite one river

Note this is somewhat simplified: paths overlap on the corners they meet at.

\$\endgroup\$
6
\$\begingroup\$

Acc! - 54 50 48 49 Bytes

N
Write _
Count q while _-48 {
Write _
}
\$\endgroup\$
1
  • \$\begingroup\$ Works in Acc!! too! ;) \$\endgroup\$
    – DLosc
    Commented Nov 3, 2015 at 19:15
6
\$\begingroup\$

Pyramid Scheme, 166 156 131 123 bytes

Saved 10 bytes thanks to Pavel! Saved 25 33 bytes thanks to Khuldraeseth na'Barya!

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

Try it online!

Try it online!

Old answer and explanation (functionally equivalent)

    ^        ^
   / \      / \
  /set\    /do \
 ^-----^  ^-----^
/a\   /#\/a\   / \
---  ^------  /out\
    /l\      ^-----
   /ine\    /a\
   -----    ---

Hehe. I love this language.

Explanation

There are two pyramid chains. The first is:

    ^
   / \
  /set\
 ^-----^
/a\   /#\
---  ^---
    /l\
   /ine\
   -----

This sets variable a to line (a line read from STDIN), as a value (#).

The second:

    ^
   / \
  /do \
 ^-----^
/a\   / \
---  /out\
    ^-----
   /a\
   ---

This is a do while loop, with the left pyramid being the condition, and the right one being the body. Equivalent to:

do {
    out(a);
} while(a);

which is what we want.

\$\endgroup\$
10
  • \$\begingroup\$ You could make the line pyramid one size smaller right? Since it ignores if its broken up with line breaks? \$\endgroup\$
    – Pavel
    Commented Jan 30, 2017 at 3:18
  • \$\begingroup\$ @Pavel Yes, that's true \$\endgroup\$ Commented Jan 30, 2017 at 3:30
  • \$\begingroup\$ @ETHproductions okay, will do! \$\endgroup\$ Commented Jan 30, 2017 at 3:31
  • \$\begingroup\$ @ETHproductions Added explanation! \$\endgroup\$ Commented Jan 30, 2017 at 3:36
  • \$\begingroup\$ Using the sneaky nameless variable gets you down to 131 \$\endgroup\$ Commented Jul 25, 2019 at 19:09
5
\$\begingroup\$

C, 39

main(){for(;putchar(getchar()&49)&1;);}

STDIN must be a 1-byte file. It will not work if there is a trailing newline. This is because the program relies on all calls to getchar following a 1 to return EOF, which is represented as -1 (all ones in binary).

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

QBasic, 23 bytes

INPUT x
1?x
IF x THEN 1

Gotos are the best way to loop. ;^) 1 is a label; ? is a shortcut for PRINT.

\$\endgroup\$
1
  • 1
    \$\begingroup\$ GOTOs are truely superior =D \$\endgroup\$
    – Jan
    Commented Nov 4, 2015 at 20:31
5
\$\begingroup\$

Java, 149 128 120 bytes

class A{public static void main(String[]a)throws Exception{int n=System.in.read()%2;do System.out.print(n);while(n>0);}}

Why 120 bytes? Because Java.

Edit: Saved 21 bytes thanks to Justin. Saved 8 bytes thanks to dohaqatar7.

\$\endgroup\$
5
  • 2
    \$\begingroup\$ See: Java \$\endgroup\$ Commented Nov 3, 2015 at 18:45
  • \$\begingroup\$ Scanner s=new Scanner(System.in);int n=s.nextInt(); can be instead int n=new Scanner(System.in).nextInt();. At that point, get rid of the import and do int n=new java.util.Scanner(System.in).nextInt(); Leaves you with 128 chars \$\endgroup\$
    – Justin
    Commented Nov 3, 2015 at 18:48
  • 1
    \$\begingroup\$ There's no need to use a scanner, just read from System.in directly. class A{public static void main(String[]a)throws Exception{int n=System.in.read()%2;do System.out.print(n);while(n>0);}} . You have to throw an Exception but it's shorter than all the crap with Scanner. \$\endgroup\$ Commented Nov 3, 2015 at 20:35
  • 1
    \$\begingroup\$ you could drop few charactrs if you use for(;;) loop instead do while \$\endgroup\$
    – user902383
    Commented Nov 5, 2015 at 11:43
  • \$\begingroup\$ @user902383 Actually no, because then it would print 0's indefinitely too. As it stands, it prints the 0 once, and 1 indefinitely, just as it should. \$\endgroup\$
    – Xynariz
    Commented Nov 11, 2015 at 17:49
5
\$\begingroup\$

JavaScript, 32 bytes

x=prompt();do{alert(x)}while(+x)

On input of 0, alerts 0 to the user; on input of 1, forever alerts 1. If alert is not a suitable alternative for STDOUT, replace it with console.log and add 6 to the byte count.

Edit: I've been solidly beat by @intrepidcoder; see this answer.

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

LaTeX, 97 bytes

\documentclass{proc}\begin{document}\typein[\q]{}\loop\typeout{\q}\ifnum\q=1\repeat\end{document}

I guess it's sort of a grey area since everything is generated at compile time. Prints 1s to "stdout" until it runs out of memory or one 0 depending on input.

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

Befunge-98, 7 bytes

&:.:j@#

Explanation:

&            Read integer
 :           Push copy
  .          Print the copy
   :         Push another copy
    j        Jump that many characters to the right
     q       Terminate program (jumped over if input was 1)
      #      Skip next instruction
             (And implicitly loop back to the start)
\$\endgroup\$
5
\$\begingroup\$

ResPlicate, 39 38 bytes

0 -49 12 1 48 9 0 49 4 2 0 49 4 2 48 0

This was one of the earliest examples I made after implementing this language, so I have simply copied it from the linked wiki article, which I largely wrote. Actually, having rewritten my old version to shorten it by a byte, I can now say this example was written for this catalogue.

ResPlicate in a Nutshell

Programs in ResPlicate are all comprised of a list of integers, which are inserted into a queue in order. Each step, the first two integers are popped as x and y. Then a list of x integers is popped (and padded with zeros if the queue had fewer than x elements) and re-enqueued y times. This is quite sufficient to ensure Turing-completeness. Indeed, it is even Turing-complete in the limited case that y is not allowed to exceed 2.

This simple language is extended with I/O in the following way: If x is zero and y is positive, y is output as a character. If x is zero and y is negative, a character is read from input, y+1 is added to it, and the result is enqueued.

Ungolfed:

Thus, the above program can be read like this:

0 -49                       Read a character from input, subtract 48 from its value.
                            If the input was 1 or 0, this will cause the corresponding 
                            integer value to be pushed onto the queue.
12 1 [48 9 ... 48 0]        Move the next 12 integers to the end of the queue. 
                            This brings the input integer to the front of the queue.

So now execution follows two completely different paths depending on the value of the input. If it was "0", it continues like this:

(0) 48                      The input zero and "48" are popped, causing the character
                            with value 48 ("0") to be printed.
9 0 [49 4 2 0 49 4 2 48 0]  Pop and discard the next 9 integers, emptying the queue.
                            An empty queue terminates the program.

If the input was "1", the program continues thusly:

(1) 48 [9]                  Enqueue 48 times the number 9.
0 [49]                      Print the character with value 49 ("1").
4 2 [0 49 4 2]              Place "0 49" (print "1") at the end of the queue,
                            followed by a copy of this command.
48 0 [9 9 ... 9 9]          Discard the 48 9's that were enqueued earlier.

At this point, the queue contains only "0 49 4 2 0 49 4 2", which will repeatedly print "1" and then restore the queue to precisely this state, ensuring that it will continue in this manner forever.

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

Marbelous, 22 bytes

00 .. ..
]] // ..
-O @1 ..
=O .. ..
+O /\ @1

All padding is superfluous in this program, spaces and dots can be removed.

The // sends the 00 marble through the ]] stdin device until there's a byte available, then it drops that byte. -O-O=0 or -O=O check for ascii 48 which is "0", then either the input gets output once or forever (through the @1 loop), incremented back up to the proper ascii value with a +O on the way out.

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

Groovy, 51 47 bytes

x=System.in.text as int;while(x)print x;print x

Radical.

\$\endgroup\$
5
  • \$\begingroup\$ That is nice how you're using the input. +1 \$\endgroup\$ Commented Nov 3, 2015 at 16:47
  • \$\begingroup\$ Does Groovy have a do-while? IE do print x;while(x); (maybe needs braces) \$\endgroup\$
    – Justin
    Commented Nov 3, 2015 at 18:13
  • \$\begingroup\$ @Justin No it doesn't sadly. \$\endgroup\$ Commented Nov 3, 2015 at 18:13
  • 3
    \$\begingroup\$ Funny that they don't list that in their list of major differences between Groovy and Java. I'd imagine this is a major difference. \$\endgroup\$
    – Justin
    Commented Nov 3, 2015 at 18:21
  • \$\begingroup\$ you can save two bytes by not casting the input and doing an equality check to the string "1" - Try it online! \$\endgroup\$
    – Ephphatha
    Commented May 27, 2017 at 6:09
5
\$\begingroup\$

Vitsy, 10 5 4 Bytes

New Versions! :D

[DN]
[  ]    Repeat while the top item is not 0
 D      Duplicate the top item
  N     Print it out.

I would put a try it online link here, but Vitsy's try it online doesn't output every line as it is output yet.

Try it online!

\$\endgroup\$
6
  • \$\begingroup\$ That's quite a golf... is input initially laid in the stack? \$\endgroup\$ Commented Nov 3, 2015 at 17:19
  • \$\begingroup\$ @CᴏɴᴏʀO'Bʀɪᴇɴ Turns out I was a version ahead - forgot to push my changes - in any case, I'll add the flag as part of the byte count. \$\endgroup\$ Commented Nov 3, 2015 at 18:13
  • 2
    \$\begingroup\$ You forgot to push your changes? (Bad stack-related pun) \$\endgroup\$ Commented Nov 3, 2015 at 18:20
  • 6
    \$\begingroup\$ ...ಠ_ಠ​​​​​​​​​ \$\endgroup\$ Commented Nov 3, 2015 at 18:24
  • \$\begingroup\$ The TIO link is broken :/ \$\endgroup\$ Commented Jun 6, 2017 at 21:56
5
\$\begingroup\$

TrumpScript, 54 53 bytes

Say i
As long as,i is "1"?;:
Say i!
America is great.

The longer version:

Tell them what TrumpSaid
As long as , Cruz i is not number "1"?; :
Say what TrumpSaid !
America is great.
\$\endgroup\$
2
  • 1
    \$\begingroup\$ "Just think of debugging as a fun little game." lol \$\endgroup\$
    – Lui
    Commented Jan 24, 2016 at 22:49
  • \$\begingroup\$ Just so you know this is a fork of the original TrumpScript for PPCG. github.com/samshadwell/TrumpScript \$\endgroup\$
    – J Atkin
    Commented Jan 24, 2016 at 23:07
5
\$\begingroup\$

Befunge-93+, 7

&>:.:_@

& takes integer input. :.: is a palindromic loop: it duplicates the top of the stack, prints it, and duplicates it again. _ will exit the the loop by moving to the right if the top of the stack is 0. Otherwise it executes the loop again, then > executes the loop again, and so on until the stack overflows. @ terminates the program.

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

Simplex v.0.8, 3 bytes

Try it here!

i¦o
i   ~~ take input
 ¦  ~~ repeat next character until zero byte met
  o ~~ output character
\$\endgroup\$
5
\$\begingroup\$

beeswax, 13 11 8 chars

I could golf the solution down by 3 more bytes. This solution is pretty much a literal translation of my Cardinal solution:

_T> "{'j

Explanation:

_         generate bee/IP
 T        enter integer, set lstack top value to this value
  >       redirect bee to right              
    "     if lstack top value>0, skip next instruction
     {    output lstack top value to STDOUT
      '   if lstack top value=0, skip next instruction
       j  mirror bee direction along | axis

If 0 is entered, the following instructions get executed:

     +———————————————————————————— output '0'
     ↓
_T> "{'

After execution of ' the IP leaves the honeycomb and the program terminates.

And in case of entering 1:

      +——————————————————————————— mirror bee direction of movement (to the left)
      | +————————————————————————— output '1'
      | |  +—————————————————————— redirect bee to the right
      | |  |   +—————————————————— mirror bee direction of movement
      | |  |   | +———————————————— output '1'
      | |  |   | |  +————————————— redirect bee to the right
      ↓ ↓  ↓   ↓ ↓  ↓
_T> "'j'{" > "'j'{" > .......      

... bouncing back and forth between > and j forever, printing an infinite string of ones.

Clone my beeswax interpreter (written in Julia), language specification and examples from my GitHub repository.

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

Sesos, 2 bytes

V0

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 numin  ; Switch to numeric input.
set numout ; Switch to numeric output.

get        ; Read an integer from STDIN and save in in the current cell.
nop        ; Set an entry marker.
    put    ; Print the integer in the current cell.
           ; (implicit jnz)
           ;     If the integer in the current cell is non-zero,
           ;     jump to the previous instruction.
\$\endgroup\$
5
\$\begingroup\$

JAISBaL, 15 6 bytes

˗Y1˄N0

Explanation:

# \# enable verbose parsing #\
while               \# [0] start while loop #\
    printnumln 1    \# [1] print 1 #\
end                 \# [2] end current language construct #\
printnum 0          \# [3] print 0 #\
\$\endgroup\$
5
\$\begingroup\$

Retina, 9 7 bytes

/1/+>G`

Try it online!

Explanation

The stage G` itself is really a no-op (it's a Grep stage with an empty regex, which always matches). So it's all in the configuration. > prints the result of this stage (which is just the input) and /1/+ wraps it in a loop which runs as long as the string contains a 1. There's also implicit output at the end of the program. So we go through these two possibilities:

  • If the input is 0, the /1/ condition fails, so the loop is never run. Instead, the program terminates, and the 0 is printed at the end.
  • If the input is 1, the /1/ condition matches, so the loop gets executed. The loop iteration itself does nothing but print that 1, so the string's value won't change and the loop will continue indefinitely.
\$\endgroup\$
5
\$\begingroup\$

Forte, 49 60 bytes

3LET5=5+(0*4)
4INPUT0:LET6=6-(0*4)
5PRINT0:LET3=3+(0*4)
6END

Try it online!

Forte is a weird and wonderful language with BASIC-like syntax and an execution model based on redefining integers. It has no conditional or looping constructs; to get conditional or looping behavior, you have to redefine the line numbers your program uses.

How?

Here's the code with better spacing:

3 LET 5=5+(0*4)
4 INPUT 0 : LET 6=6-(0*4)
5 PRINT 0 : LET 3=3+(0*4)
6 END

If the user inputs a zero to this program, the three LET statements don't change anything, and the program boils down to PRINT 0 : END.

If the user inputs a one... it gets interesting.

3 LET 5=5+(0*4)

The first time around, no numbers have been redefined yet; this line calculates 5+(0*4) and assigns that to 5. Nothing changes.

4 INPUT 0 : LET 6=6-(0*4)

INPUT 0 reads a number from the user and redefines 0 as that number. Suppose the user enters a 1. Every time 0, or a value of zero, occurs from now on, it will be changed to 1. For instance: LET 6=6-(0*4) now is calculated as LET 6=6-(1*4), which redefines 6 to be 2. This changes the END statement's line number to 2, which moves it out of the way of the program, allowing an infinite loop.

Redefinitions: 0->1; 6->2

5 PRINT 0 : LET 3=3+(0*4)

First, this line prints 1 (the value that 0 now represents). Then, 0*4 is now 1*4, so we have LET 3=7.

Redefinitions: 0->1; 6->2; 3->7

Next, we increment the instruction pointer and execute the command on line 3 7:

3 LET 5=5+(0*4)

which redefines 5 to be 5+4...

Redefinitions: 0->1; 6->2; 3->7; 5->9

... and we execute line 5 9:

5 PRINT 0 : LET 3=3+(0*4)

which should be read (with substitutions) as 9 PRINT 1 : LET 7=7+(1*4). We print another 1 and change 7 to 11, which means we execute the original line 3 again, and so forth.

For those who are still confused, read the Esolangs article or ping ais523 (the language's inventor!) in chat.

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

Brachylog, 4 bytes

Thanks to Fatalize for saving 1 byte.

w?1↰

Try it online!

Explanation

w     Write the input to STDOUT.
 ?1   Check whether the input equals 1.
   ↰  If so, recursively call the main predicate with 1 again.
\$\endgroup\$
1
  • \$\begingroup\$ What a pity that w's output isn't its input. \$\endgroup\$ Commented Feb 28, 2018 at 20:14
5
\$\begingroup\$

Whitespace, 46 37 bytes

Thanks to Kevin Cruijssen for golfing 1 byte off the first instruction, and 8 bytes by removing the last 2 instructions, which makes the program jumps to non-existent label and terminates with error but still output correctly in the output stream.

SS SL  # push 0
SLS    # dup
TLTT   # readn
TTT    # load
LSS L  # label L
SLS    #   dup
SLS    #   dup
TLST   #   prtn
LTS TL #   jmpz TL
LSL L  # jmp L

Demo on ideone

Previous safe version of the program which terminates normally has a proper label and the standard triple new line to end the program:

LSS TL # label TL
LLL    # end

Demo on ideone

Notation explanation:

  • # starts comment
  • L is newline
  • S is space
  • T is tab

I used this interpreter to develop the program and generate the comments.

Didn't expect the code to be this long. Whitespace requires the input to be read into heap, heap instructions consumes stack, printing instruction consumes the stack and even jump instruction consumes the stack, so it bloats the code with all the "duplicate top stack" instructions.

\$\endgroup\$
4
  • \$\begingroup\$ Is there anything wrong in my answer that warrants a downvote? \$\endgroup\$ Commented Dec 25, 2015 at 2:15
  • \$\begingroup\$ On this interpreter, SSL is a valid way to push 0 (which makes it as efficient as the duplicate instruction, heh). Also, LLL doesn't seem to be required to end execution there if it hits end-of-file. That would bring it down to 41 bytes. \$\endgroup\$ Commented Sep 4, 2017 at 5:07
  • \$\begingroup\$ I know it's been a while, but you can golf some parts: SS SSL (push 0) can be SS SL. After specifying it's positive with S (or negative with T), it's already implicit 0, so no need for an additional S for 0. In addition, you can remove the trailing LSSTL LLL. It will exit with an error (Undefined Label) for input 0, but that's allowed according to the meta. Try it online, or try it online raw 37 bytes. \$\endgroup\$ Commented Mar 16, 2018 at 15:18
  • \$\begingroup\$ @KevinCruijssen: Updated. \$\endgroup\$ Commented Mar 17, 2018 at 16:32
5
\$\begingroup\$

1+, 10 bytes

."#:[#":1#

Yay for comment abuse in a normal challenge (instead of a source-layout or polyglot one)! In 1+, the [ character that begins a comment is actually an instruction so it can be skipped with the goto command #.

For input 0:

.          Take input
 "#        Jump to the 0th hash tag
   :      Output 0
    [      Comment the rest of the program out

For input 1:

.          Take input
 "#        Jump to the 1th hash tag
     #     The 1th hash tag
      ":   Duplicate and output
        1# Jump to the 1th hash tag

I can replace the 1 with " as well so that we get a 1+ program without a 1 instruction... Wow!

Naive solution, 14 bytes

.1##":"1+1<1+#

A simple do-while loop.

\$\endgroup\$
2
  • \$\begingroup\$ @petStorm No, [ is a block comment. It only comment everything else here because there's no ]. Also why did I suddenly get 4 upvotes on tips for golfing in 1+? \$\endgroup\$ Commented Aug 3, 2020 at 13:25
  • \$\begingroup\$ I could remove the [ because STDERR is ignored by default, but 1. This comment trick is really neat and 2. That's trivial \$\endgroup\$ Commented Aug 20, 2020 at 6:28
5
\$\begingroup\$

Prelude, 6 bytes

Prelude is a bit tricky here. The language specification says I/O is via characters' byte values. That's what the C implementation does. Then there's the Python interpreter, which uses bytes for input but prints decimal integers. And then there's my own fork of that interpreter which does both input and output numerically (which I've published a few months ago). Since languages on PPCG are defined by their implementations, all of these constitute valid Prelude variants.

My fork gives the shortest solution at 6 bytes:

?(1!)!

? pushes the input. (...) is a Brainfuck-style while loop, which is skipped for 0 input. Then ! prints the zero. If the input was 1, we enter the loop, push another 1 and print that with ! (we need to push a new 1, because ! pops the top of the stack).

Next up is the original Python interpreter at 14 bytes:

?6^+^+^+-(1!)!

Since output is the same as in my fork, all we need to do is map the character codes to 0 or 1 which we do by subtracting 48. There are several ways to get 48 in 7 bytes, but I don't think it's possible to do it in less. This one pushes 6 and then doubles it 3 times, by duplicating it with ^ and adding the two copies with +.

Finally, the solution that works with the original C interpreter needs 16 bytes:

?^(#^!^6^+^+^+-)

This one has a slightly different structure. Since we also need to output 48 or 49 respectively, we now remember the input and obtain the 0 or 1 only for the loop condition. This also let's us get a way with a single ! because we can easily turn the loop into do-while. Again, ? reads the input and ^ makes a copy which we only need because the first thing in the loop is #, which discards the top of the stack (we need this to discard the condition from a previous iteration). Now ^! prints a copy of the input. Then ^6^+^+^+- computes input - 48 as before. If that is 0, we leave the loop immediately and exit after printing a single number. Otherwise, the loop will keep going, printing the input 49 each time.

\$\endgroup\$
4
  • \$\begingroup\$ By "fork" do you mean you toggled the option on that one line? \$\endgroup\$
    – feersum
    Commented Nov 4, 2015 at 3:01
  • \$\begingroup\$ @feersum I added it. \$\endgroup\$ Commented Nov 4, 2015 at 6:31
  • \$\begingroup\$ I was thinking of the NUMERIC_OUTPUT on line 5, but forgot it only affects one of I/O. I guess you had to add a numeric input option too for your modification. \$\endgroup\$
    – feersum
    Commented Nov 4, 2015 at 6:59
  • \$\begingroup\$ @feersum yeah, exactly. The original Prelude interpreter already has the output flag set. \$\endgroup\$ Commented Nov 4, 2015 at 7:00
5
\$\begingroup\$

Google Forms, 3 sections + 1 question

Try it online!

Google Forms has two features which I believe make it qualify as a (very limited) programming language:

  1. Multiple sections, which allow arbitrary rules for which sections redirect to which, allowing for uncontrolled infinite loops
  2. The ability to make different responses to a question take the user to a different section upon clicking "next", allowing for input/conditionals, and controlling loops based on input

Google Forms also has a back button, which may make it possible to store arbitrarily large amounts of information, though there's no way to make use of that information without the human running the program doing something.

\$\endgroup\$
1
2
3 4 5
17

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.