{"id":22788539,"url":"https://github.com/moishinetzer/which-interview","last_synced_at":"2026-06-21T01:31:46.310Z","repository":{"id":266618797,"uuid":"742490533","full_name":"moishinetzer/which-interview","owner":"moishinetzer","description":null,"archived":false,"fork":false,"pushed_at":"2024-01-12T15:43:07.000Z","size":148,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-11-30T20:51:20.628Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"TypeScript","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/moishinetzer.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":"2024-01-12T15:43:06.000Z","updated_at":"2024-01-12T15:43:11.000Z","dependencies_parsed_at":"2024-12-05T08:13:52.033Z","dependency_job_id":"d8a19b7a-da72-4737-ae14-697c512eb903","html_url":"https://github.com/moishinetzer/which-interview","commit_stats":null,"previous_names":["moishinetzer/which-interview"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/moishinetzer/which-interview","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/moishinetzer%2Fwhich-interview","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/moishinetzer%2Fwhich-interview/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/moishinetzer%2Fwhich-interview/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/moishinetzer%2Fwhich-interview/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/moishinetzer","download_url":"https://codeload.github.com/moishinetzer/which-interview/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/moishinetzer%2Fwhich-interview/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":34591166,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-06-20T02:00:06.407Z","response_time":98,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"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":[],"created_at":"2024-12-12T01:32:30.562Z","updated_at":"2026-06-21T01:31:46.295Z","avatar_url":"https://github.com/moishinetzer.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Which? Engineering - Technical Exercise\n\n## Scenario\n\nWe have a robot in an arena. The robot can move forward, turn left, or turn right. The robot turns on the spot. It moves one unit at a time.\n\nWe can tell the robot where it is in the arena using coordinates. And we can tell it the direction it is facing. As the robot moves it knows where it is in the arena \u0026 which direction it is facing.\n\nWe can give the robot a sequence of movements that it will follow along a path. For example, we could tell it to move forward, turn left, move forward. If the robot encounters a movement it does not understand it errors \u0026 goes no further.\n\nThe arena is square and of limited size. If the robot runs into the walls of the arena it crashes \u0026 goes no further.\n\n## Problem\n\n**For this part of the technical exercise we'd like you to implement the robot.** We do not expect this to take more than a couple of hours to do. If it takes any longer then you're probably over thinking it.\n\nYou are free to work however you feel most comfortable. You can commit small changes. You can write unit-tests.\n\nWe ask that you write your implementation in Typescript.\n\nIf you're successful we'll work together to extend the functionality of our robot at the next stage of the interview process.\n\n## Constraints\n\nThe robot should read JSON input from stdin. The input will contain the following fields:\n\n- `arena` will be two coordinates defining opposite corners of the arena\n- `location` will be coordinates of the robot\n- `heading` will be one of `north`, `south`, `east`, `west`\n- `directions` will be an arbitrary length array containing movement commands: `forward`, `left`, `right`\n\nCoordinates are always a structure with `x` and `y` fields. Both these fields contain integers.\n\nWe expect the robot to output JSON to stdout. The output will contain the following fields:\n\n- `status` will be either `ok`, `error`, or `crash`\n- `location` will be the final location coordinates of the robot having followed the `input` path\n- `heading` will be the heading of the robot at the end of its path or the point of crashing\n- `path` will be the path the robot took to its final point\n\nIn the case of an `error` or a `crash`, then the last movement in the `path` should be the one that caused the situation.\n\nWe expect valid JSON but do not require it to be neatly formatted.\n\n## Running\n\nThis repository has been setup for you. You should only have to write the code.\n\nYou can run your robot using the following:\n\n```sh\nnpm run robot \u003c some-input-file.json\n```\n\nYou can build a `robot.js` file using:\n\n```sh\nnpm run build\n```\n\nWe've setup eslint \u0026 prettier too. You can lint \u0026 format your code using:\n\n```sh\nnpm run lint\n```\n\nAnd we've set Jest for tests:\n\n```sh\nnpm run test\n```\n\nThe tests do not cover everything we have asked for. They are there to get you started. You are welcome to add any more you see as necessary.\n\n## Submitting\n\nBefore submitting your solution we strongly encourage you to run both the tests (`npm run test`) and to test the command line robot (`npm run robot \u003c some-input-file.json`).\n\nIf you're happy that this is passing all of [the examples below](#examples) then you can send us your code as a ZIP file using:\n\n```sh\nnpm run submit --candidate='candidate@example.com'\n```\n\nPlease replace `candidate@example.com` with your email address so that we know whose submission it is!\n\nThis will create a ZIP file called `submission-candidate@example.com.zip` in the root of your repository. It will be packaged based on your currently active branch. It will only contain the necessary files.\n\nThis file will then be uploaded to our servers.\n\nOnce you have done this please send an email to our recruitment specialist (michael.kidd@which.co.uk). This just ensures that we know should anything go wrong with the upload.\n\n**NOTE: We only accept your first submission**. So please, make sure you're completely happy with it.\n\n## Examples\n\nThese examples can be found in the [examples](examples) directory of this repository. Each example header links to the associated entry in that directory. There are a few others in there too just to give you some test cases.\n\n### [Walk through](examples/01-walk-through)\n\nGiven the following input:\n\n```json\n{\n  \"arena\": {\n    \"corner1\": { \"x\": -3, \"y\": -3 },\n    \"corner2\": { \"x\": 3, \"y\": 3 }\n  },\n\n  \"location\": { \"x\": 0, \"y\": 0 },\n  \"heading\": \"north\",\n\n  \"directions\": [\"forward\", \"left\", \"forward\", \"right\", \"forward\", \"right\", \"forward\", \"forward\", \"forward\"]\n}\n```\n\nWe would expect the output to be:\n\n```json\n{\n  \"status\": \"ok\",\n  \"location\": { \"x\": 2, \"y\": 2 },\n  \"heading\": \"east\",\n\n  \"path\": [\"forward\", \"left\", \"forward\", \"right\", \"forward\", \"right\", \"forward\", \"forward\", \"forward\"]\n}\n```\n\n\u003cdetails\u003e\n  \u003csummary\u003eClick to reveal the steps\u003c/summary\u003e\n  \nThe arrow represents the robot.\n\n**`\"location\": { \"x\": 0, \"y\": 0 }, \"heading\": \"north\"`**\n\n![](images/0-2480fe4ac7126618855ed690ab3d40feead3da1be63ce19d728918d4603fed01.png)\n\n`\"directions\": [`**`\"forward\"`**`,\"left\",\"forward\",\"right\",\"forward\",\"right\",\"forward\",\"forward\",\"forward\"]`\n![](images/1-b441b377e0a344f60d40750fc8a4e451c6fb25a784402a98eb023dc5b73cac82.png)\n\n`\"directions\": [\"forward\",`**`\"left\"`**`,\"forward\",\"right\",\"forward\",\"right\",\"forward\",\"forward\",\"forward\"]`\n![](images/2-7a4cfe6c202a776535996d1719c18088830e20693b45b6a8274eed24ebedd99c.png)\n\n`\"directions\": [\"forward\",\"left\",`**`\"forward\"`**`,\"right\",\"forward\",\"right\",\"forward\",\"forward\",\"forward\"]`\n![](images/3-f9f499cebfc6f612229c06aa41aa4ba7fbbcfe64f723b6cea8a867e4769f03f5.png)\n\n`\"directions\": [\"forward\",\"left\",\"forward\",`**`\"right\"`**`,\"forward\",\"right\",\"forward\",\"forward\",\"forward\"]`\n![](images/4-d55971c5d217586c22ce84a5db36900eda9e786d70b14e7eae4a8421335d233a.png)\n\n`\"directions\": [\"forward\",\"left\",\"forward\",\"right\",`**`\"forward\"`**`,\"right\",\"forward\",\"forward\",\"forward\"]`\n![](images/5-02a44d74567164fdfb42f42523391921d6ca03fb54bf3c6fcb131a459cc056f9.png)\n\n`\"directions\": [\"forward\",\"left\",\"forward\",\"right\",\"forward\",`**`\"right\"`**`,\"forward\",\"forward\",\"forward\"]`\n![](images/6-7504a22dcfc391c94ab4f8841981808a674a5feb26d6e2beaa3481d0cd4601e6.png)\n\n`\"directions\": [\"forward\",\"left\",\"forward\",\"right\",\"forward\",\"right\",`**`\"forward\"`**`,\"forward\",\"forward\"]`\n![](images/7-48589977880e9aeaad3e5ed70b1676d042d53a5e79dee70c8b075c5a0c5f1cb6.png)\n\n`\"directions\": [\"forward\",\"left\",\"forward\",\"right\",\"forward\",\"right\",\"forward\",`**`\"forward\"`**`,\"forward\"]`\n![](images/8-11e87b72e65c499e65a36649353c04e3040d703e57dbb3e35c08e09a4a9ce028.png)\n\n`\"directions\": [\"forward\",\"left\",\"forward\",\"right\",\"forward\",\"right\",\"forward\",\"forward\",`**`\"forward\"`**`]`\n![](images/9-92eb10be35396f5cfa87eb6f4261d334b9c1758acc6ac6998f6204ae7f309631.png)\n\n\u003c/details\u003e\n\n### [Error](examples/02-error)\n\nGiven the following input:\n\n```json\n{\n  \"location\": { \"x\": 0, \"y\": 0 },\n  \"heading\": \"north\",\n\n  \"arena\": {\n    \"corner1\": { \"x\": -4, \"y\": -4 },\n    \"corner2\": { \"x\": 4, \"y\": 4 }\n  },\n\n  \"directions\": [\"forward\", \"jump\"]\n}\n```\n\nWe would expect the output to be:\n\n```json\n{\n  \"status\": \"error\",\n  \"location\": { \"x\": 0, \"y\": 1 },\n  \"heading\": \"north\",\n\n  \"path\": [\"forward\", \"jump\"]\n}\n```\n\n### [Crash](examples/03-crash)\n\nGiven the following input:\n\n```json\n{\n  \"location\": { \"x\": 0, \"y\": 0 },\n  \"heading\": \"north\",\n\n  \"arena\": {\n    \"corner1\": { \"x\": -4, \"y\": -4 },\n    \"corner2\": { \"x\": 4, \"y\": 4 }\n  },\n\n  \"directions\": [\"forward\", \"forward\", \"forward\", \"right\", \"forward\", \"left\", \"forward\", \"forward\", \"right\"]\n}\n```\n\nWe would expect the output to be:\n\n```json\n{\n  \"status\": \"crash\",\n  \"location\": { \"x\": 1, \"y\": 4 },\n  \"heading\": \"north\",\n\n  \"path\": [\"forward\", \"forward\", \"forward\", \"right\", \"forward\", \"left\", \"forward\", \"forward\"]\n}\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmoishinetzer%2Fwhich-interview","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmoishinetzer%2Fwhich-interview","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmoishinetzer%2Fwhich-interview/lists"}