{"id":19486258,"url":"https://github.com/textbook/tdb","last_synced_at":"2026-05-01T23:34:23.899Z","repository":{"id":79361586,"uuid":"428430990","full_name":"textbook/tdb","owner":"textbook","description":"Test-driven Befunge","archived":false,"fork":false,"pushed_at":"2021-11-18T19:34:04.000Z","size":40,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":3,"default_branch":"main","last_synced_at":"2025-01-08T07:52:19.588Z","etag":null,"topics":["befunge","befunge-interpreter","chai","javascript","kata","mocha","mocha-chai","tdd","tdd-kata"],"latest_commit_sha":null,"homepage":"","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/textbook.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2021-11-15T21:46:19.000Z","updated_at":"2021-11-17T18:21:01.000Z","dependencies_parsed_at":"2023-03-12T07:54:01.953Z","dependency_job_id":null,"html_url":"https://github.com/textbook/tdb","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/textbook%2Ftdb","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/textbook%2Ftdb/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/textbook%2Ftdb/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/textbook%2Ftdb/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/textbook","download_url":"https://codeload.github.com/textbook/tdb/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":240723447,"owners_count":19847282,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["befunge","befunge-interpreter","chai","javascript","kata","mocha","mocha-chai","tdd","tdd-kata"],"created_at":"2024-11-10T20:36:06.534Z","updated_at":"2026-05-01T23:34:23.850Z","avatar_url":"https://github.com/textbook.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# TDB - test-driven Befunge\n\nIn this kata we're going to implement an interpreter for a simple programming language named [Befunge]. It's based on [this kata], but provides a more detailed test suite to allow you to test-drive your implementation.\n\n## Setup\n\nClone this repository to your local machine and run `npm install` to install the dependencies.\n\nYou will edit `index.js` with your implementation, and `index.test.js` to remove `.skip` from each test as you go along.\n\nYou can run `npm test` (or `npm run test`, `npm t`) to run the tests in `index.test.js`. Once you've un-`.skip`ped all of the tests and they all pass, run `npm run validate`.\n\n## Approach\n\nThis kata is set up to use a test-driven development (TDD) approach. Each iteration of the process looks like:\n\n- **Red** - write a failing test\n- **Green** - write the simplest code that gets the test to pass\n- **Refactor** - clean up the code, keeping all of the tests passing\n\nIt can be difficult when you're new to TDD to plot a course through all of the possible functionality and write high quality tests, so the full test suite is already provided. That means that the **Red** step here is actually: delete the next `.skip` to enable the  next test (the first test is already enabled, so your first action will be to write some implementation to get it passing).\n\n## Stack\n\nA Befunge interpreter stores state in a data structure called the _stack_. The [stack] is a last-in, first-out (LIFO) collection that needs to support two operations\\*:\n\n- **Push** a value to the top of the stack:\n    - `[ 1 2 3 ]` -\u003e push a `4` to the top -\u003e `[ 1 2 3 4 ]`\n- **Pop** a value from the top of the stack:\n    - `[ 1 2 3 ]` -\u003e pop the `3` from the top -\u003e `[ 1 2 ]`\n    - `[ ]` -\u003e pop from an empty stack gives `0` -\u003e `[ ]`\n\nIn this case we're not going to worry about the maximum size of the stack. The stack must _always_ contain numbers - don't store any strings in it.\n\n\\* _The stack you use may support other operations, but these are the only two that Befunge requires._\n\n## Code\n\nA Befunge program is a series of characters on a 2D grid. This is represented in our tests as a string, e.g. `\"74 |\\n   @\\n   #\\n   .\"` represents the program:\n\n| ↓ y \\ x → | 0 | 1 | 2 | 3 |\n|---|---|---|---|---|\n| 0 | `7` | `4` | ` ` | \u003ccode\u003e\u0026#124;\u003c/code\u003e |\n| 1 | ` ` | ` ` | ` ` | `@` |\n| 2 | ` ` | ` ` | ` ` | `#` |\n| 3 | ` ` | ` ` | ` ` | `.` |\n\n## Interpreter\n\nBy default, the interpreter traverses the code from left to right, starting with the first character of the first row (x=0, y=0). Each character is an \"instruction\" that controls the behaviour of the program. Each step of the program runs as follows:\n\n- Read the instruction from the current location\n- Execute the instruction\n- Move to the next location based on the current direction\n\nIf the new location is out of bounds, either horizontally or vertically, the interpreter \"wraps\" back around to the other side of the code.\n\nThe full instruction set is listed below, but to run through one of the examples from the test suite (from level 4, _\"can conditionally move vertically\"_):\n\n 0. Start:\n\n    ```none\n    [7]4   |\n           @\n           #\n           .\n    ```\n\n    Direction: `→`, stack: `[ ]`, output: `\"\"`\n\n 1. Push `7` to stack then move right:\n\n    ```\n     7[4]  |\n           @\n           #\n           .\n    ```\n\n    Direction: `→`, stack: `[ 7 ]`, output: `\"\"`\n\n 2. Push `4` to stack then move right\n\n    ```\n     7 4[ ]|\n           @\n           #\n           .\n    ```\n    Direction: `→`, stack: `[ 7 4 ]`, output: `\"\"`\n\n 3. Do nothing then move right\n\n    ```\n     7 4  [|]\n           @\n           #\n           .\n    ```\n\n    Direction: `→`, stack: `[ 7 4 ]`, output: `\"\"`\n\n 4. Pop `4` from stack, change direction to up then move up (wrapping around)\n\n    ```\n     7 4   |\n           @\n           #\n          [.]\n    ```\n\n    Direction: `↑`, stack: `[ 7 ]`, output: `\"\"`\n\n 5. Pop `7` from stack, send to output then move up\n\n    ```\n     7 4   |\n           @\n          [#]\n           .\n    ```\n\n    Direction: `↑`, stack: `[ ]`, output: `\"7\"`\n\n 6. Skip one cell in the current direction then move up\n\n    ```\n     7 4  [|]\n           @\n           #\n           .\n    ```\n\n    Direction: `↑`, stack: `[ ]`, output: `\"7\"`\n    \n 7. Pop `0` from stack, change direction to down then move down\n\n    ```\n     7 4   |\n          [@]\n           #\n           .\n    ```\n\n    Direction: `↓`, stack: `[ ]`, output: `\"7\"`\n    \n 8. End program and return output -\u003e `\"7\"`\n\n## Instruction set\n\nThe table below shows the full instruction set, in the order it's introduced by the test cases.\n\n\u003ctable\u003e\n  \u003cthead\u003e\n    \u003ctr\u003e\n      \u003cth\u003eInstruction\u003c/th\u003e\n      \u003cth\u003eDescription\u003c/th\u003e\n    \u003c/tr\u003e\n  \u003c/thead\u003e\n  \u003ctbody\u003e\n    \u003ctr\u003e\n      \u003ctd colspan=\"2\"\u003e\u003cstrong\u003eLevel 1\u003c/strong\u003e - horizontal movement\u003c/td\u003e\n    \u003c/tr\u003e\n    \u003ctr\u003e\n      \u003ctd\u003e\u003ccode\u003e@\u003c/code\u003e\u003c/td\u003e\n      \u003ctd\u003eEnd the program and return the output.\u003c/td\u003e\n    \u003c/tr\u003e\n    \u003ctr\u003e\n      \u003ctd\u003e\u003ccode\u003e \u003c/code\u003e\u0026nbsp;(empty space)\u003c/td\u003e\n      \u003ctd\u003eDo nothing.\u003c/td\u003e\n    \u003c/tr\u003e\n    \u003ctr\u003e\n      \u003ctd\u003e\u003ccode\u003e.\u003c/code\u003e\u003c/td\u003e\n      \u003ctd\u003ePop the top value from the stack and add it to the output.\u003c/td\u003e\n    \u003c/tr\u003e\n    \u003ctr\u003e\n      \u003ctd\u003e\u003ccode\u003e0\u003c/code\u003e-\u003ccode\u003e9\u003c/code\u003e (digits)\u003c/td\u003e\n      \u003ctd\u003ePush the value to the top of the stack, as a number.\u003c/td\u003e\n    \u003c/tr\u003e\n    \u003ctr\u003e\n      \u003ctd\u003e\u003ccode\u003e#\u003c/code\u003e\u003c/td\u003e\n      \u003ctd\u003eSkip the next instruction (i.e. move an extra step in the current direction).\u003c/td\u003e\n    \u003c/tr\u003e\n    \u003ctr\u003e\n      \u003ctd\u003e\u003ccode\u003e\u0026lt;\u003c/code\u003e\u003c/td\u003e\n      \u003ctd\u003eChange current direction to right-to-left.\u003c/td\u003e\n    \u003c/tr\u003e\n    \u003ctr\u003e\n      \u003ctd\u003e\u003ccode\u003e_\u003c/code\u003e\u003c/td\u003e\n      \u003ctd\u003ePop the top value from stack, change current direction to left-to-right if the value is 0 otherwise right-to-left.\u003c/td\u003e\n    \u003c/tr\u003e\n    \u003ctr\u003e\n      \u003ctd\u003e\u003ccode\u003e\u0026gt;\u003c/code\u003e\u003c/td\u003e\n      \u003ctd\u003eChange current direction to left-to-right.\u003c/td\u003e\n    \u003c/tr\u003e\n    \u003ctr\u003e\n      \u003ctd colspan=\"2\"\u003e\u003cstrong\u003eLevel 2\u003c/strong\u003e - stack manipulation\u003c/td\u003e\n    \u003c/tr\u003e\n    \u003ctr\u003e\n      \u003ctd\u003e\u003ccode\u003e$\u003c/code\u003e\u003c/td\u003e\n      \u003ctd\u003ePop the top value from the stack and discard it.\u003c/td\u003e\n    \u003c/tr\u003e\n    \u003ctr\u003e\n      \u003ctd\u003e\u003ccode\u003e!\u003c/code\u003e\u003c/td\u003e\n      \u003ctd\u003eLogical not - pop the top value from the stack and push 1 if the value is 0 otherwise 0 to the top of the stack.\u003c/td\u003e\n    \u003c/tr\u003e\n    \u003ctr\u003e\n      \u003ctd\u003e\u003ccode\u003e:\u003c/code\u003e\u003c/td\u003e\n      \u003ctd\u003eDuplicate the value at the top of the stack (e.g. \u003ccode\u003e[ 1 2 ]\u003c/code\u003e to \u003ccode\u003e[ 1 2 2 ]\u003c/code\u003e).\u003c/td\u003e\n    \u003c/tr\u003e\n    \u003ctr\u003e\n      \u003ctd\u003e\u003ccode\u003e\\\u003c/code\u003e\u003c/td\u003e\n      \u003ctd\u003eSwap the two values at the top of the stack (e.g. \u003ccode\u003e[ 1 2 3 ]\u003c/code\u003e to \u003ccode\u003e[ 1 3 2 ]\u003c/code\u003e).\u003c/td\u003e\n    \u003c/tr\u003e\n    \u003ctr\u003e\n      \u003ctd colspan=\"2\"\u003e\u003cstrong\u003eLevel 3\u003c/strong\u003e - arithmetic\u003c/td\u003e\n    \u003c/tr\u003e\n    \u003ctr\u003e\n      \u003ctd\u003e\u003ccode\u003e+\u003c/code\u003e\u003c/td\u003e\n      \u003ctd\u003ePop the top two values from the stack and push their sum to the top of the stack (e.g. \u003ccode\u003e[ 4 2 ]\u003c/code\u003e to \u003ccode\u003e[ 6 ]\u003c/code\u003e).\u003c/td\u003e\n    \u003c/tr\u003e\n    \u003ctr\u003e\n      \u003ctd\u003e\u003ccode\u003e*\u003c/code\u003e\u003c/td\u003e\n      \u003ctd\u003ePop the top two values from the stack and push their product to the top of the stack (e.g. \u003ccode\u003e[ 4 2 ]\u003c/code\u003e to \u003ccode\u003e[ 8 ]\u003c/code\u003e).\u003c/td\u003e\n    \u003c/tr\u003e\n    \u003ctr\u003e\n      \u003ctd\u003e\u003ccode\u003e-\u003c/code\u003e\u003c/td\u003e\n      \u003ctd\u003ePop the top two values from the stack and push their difference to the top of the stack (e.g. \u003ccode\u003e[ 4 2 ]\u003c/code\u003e to \u003ccode\u003e[ 2 ]\u003c/code\u003e).\u003c/td\u003e\n    \u003c/tr\u003e\n    \u003ctr\u003e\n      \u003ctd\u003e\u003ccode\u003e/\u003c/code\u003e\u003c/td\u003e\n      \u003ctd\u003ePop the top two values from the stack and push their ratio, as an integer and rounded towards zero, to the top of the stack (e.g. \u003ccode\u003e[ 5 2 ]\u003c/code\u003e to \u003ccode\u003e[ 2 ]\u003c/code\u003e).\u003c/td\u003e\n    \u003c/tr\u003e\n    \u003ctr\u003e\n      \u003ctd\u003e\u003ccode\u003e%\u003c/code\u003e\u003c/td\u003e\n      \u003ctd\u003ePop the top two values from the stack and push the remainder of their division to the top of the stack (e.g. \u003ccode\u003e[ 5 2 ]\u003c/code\u003e to \u003ccode\u003e[ 1 ]\u003c/code\u003e).\u003c/td\u003e\n    \u003c/tr\u003e\n    \u003ctr\u003e\n      \u003ctd\u003e\u003ccode\u003e`\u003c/code\u003e (backtick)\u003c/td\u003e\n      \u003ctd\u003ePop the top two values from the stack and push 1 if the second is larger than the first otherwise 0 to the top of the stack (e.g. \u003ccode\u003e[ 5 2 ]\u003c/code\u003e to \u003ccode\u003e[ 1 ]\u003c/code\u003e).\u003c/td\u003e\n    \u003c/tr\u003e\n    \u003ctr\u003e\n      \u003ctd colspan=\"2\"\u003e\u003cstrong\u003eLevel 4\u003c/strong\u003e - vertical movement\u003c/td\u003e\n    \u003c/tr\u003e\n    \u003ctr\u003e\n      \u003ctd\u003e\u003ccode\u003ev\u003c/code\u003e\u003c/td\u003e\n      \u003ctd\u003eChange current direction to top-to-bottom.\u003c/td\u003e\n    \u003c/tr\u003e\n    \u003ctr\u003e\n      \u003ctd\u003e\u003ccode\u003e^\u003c/code\u003e\u003c/td\u003e\n      \u003ctd\u003eChange current direction to bottom-to-top.\u003c/td\u003e\n    \u003c/tr\u003e\n    \u003ctr\u003e\n      \u003ctd\u003e\u003ccode\u003e|\u003c/code\u003e\u003c/td\u003e\n      \u003ctd\u003ePop the top value from stack, change current direction to top-to-bottom if the value is 0 otherwise bottom-to-top.\u003c/td\u003e\n    \u003c/tr\u003e\n    \u003ctr\u003e\n      \u003ctd\u003e\u003ccode\u003e?\u003c/code\u003e\u003c/td\u003e\n      \u003ctd\u003eChange current direction to a random selection from left-to-right, right-to-left, top-to-bottom and bottom-to-top.\u003c/td\u003e\n    \u003c/tr\u003e\n    \u003ctr\u003e\n      \u003ctd colspan=\"2\"\u003e\u003cstrong\u003eLevel 5\u003c/strong\u003e - string mode\u003c/td\u003e\n    \u003c/tr\u003e\n    \u003ctr\u003e\n      \u003ctd\u003e\u003ccode\u003e\"\u003c/code\u003e\u003c/td\u003e\n      \u003ctd\u003eToggle string mode on or off - in string mode, instead of reading characters as instructions, their ASCII codes are pushed to the top of the stack.\u003c/td\u003e\n    \u003c/tr\u003e\n    \u003ctr\u003e\n      \u003ctd colspan=\"2\"\u003e\u003cstrong\u003eLevel 6\u003c/strong\u003e - store and retrieve\u003c/td\u003e\n    \u003c/tr\u003e\n    \u003ctr\u003e\n      \u003ctd\u003e\u003ccode\u003eg\u003c/code\u003e\u003c/td\u003e\n      \u003ctd\u003ePop the top two values y and x from the stack and push the ASCII code of the character on row y, column x of the program to the top of the stack.\u003c/td\u003e\n    \u003c/tr\u003e\n    \u003ctr\u003e\n      \u003ctd\u003e\u003ccode\u003ep\u003c/code\u003e\u003c/td\u003e\n      \u003ctd\u003ePop the top three values y, x and v from the stack and set the character with the ASCII code of v as the instruction on row y, column x of the program.\u003c/td\u003e\n    \u003c/tr\u003e\n  \u003c/tbody\u003e\n\u003c/table\u003e\n\n  [Befunge]: https://en.wikipedia.org/wiki/Befunge\n  [stack]: https://en.wikipedia.org/wiki/Stack_(abstract_data_type)\n  [this kata]: https://www.codewars.com/kata/526c7b931666d07889000a3c/\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftextbook%2Ftdb","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ftextbook%2Ftdb","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftextbook%2Ftdb/lists"}