diff --git a/config.json b/config.json index c7664b6..13a497c 100644 --- a/config.json +++ b/config.json @@ -127,6 +127,14 @@ "prerequisites": [], "difficulty": 4 }, + { + "slug": "resistor-color-duo", + "name": "Resistor Color Duo", + "uuid": "5d22390f-bce7-4920-b817-dc855ec2aacd", + "practices": [], + "prerequisites": [], + "difficulty": 4 + }, { "slug": "reverse-string", "name": "Reverse String", diff --git a/exercises/practice/resistor-color-duo/.docs/instructions.append.md b/exercises/practice/resistor-color-duo/.docs/instructions.append.md new file mode 100644 index 0000000..0e2a166 --- /dev/null +++ b/exercises/practice/resistor-color-duo/.docs/instructions.append.md @@ -0,0 +1,8 @@ +# Instruction append + +## Reserved Addresses + +The buffer for the first string uses bytes 1024-2047 of linear memory. +The buffer for the second string uses bytes 2048-3071 of linear memory. + +You should not have to modify these buffers or allocate additional memory. diff --git a/exercises/practice/resistor-color-duo/.docs/instructions.md b/exercises/practice/resistor-color-duo/.docs/instructions.md new file mode 100644 index 0000000..4ae694d --- /dev/null +++ b/exercises/practice/resistor-color-duo/.docs/instructions.md @@ -0,0 +1,33 @@ +# Instructions + +If you want to build something using a Raspberry Pi, you'll probably use _resistors_. +For this exercise, you need to know two things about them: + +- Each resistor has a resistance value. +- Resistors are small - so small in fact that if you printed the resistance value on them, it would be hard to read. + +To get around this problem, manufacturers print color-coded bands onto the resistors to denote their resistance values. +Each band has a position and a numeric value. + +The first 2 bands of a resistor have a simple encoding scheme: each color maps to a single number. +For example, if they printed a brown band (value 1) followed by a green band (value 5), it would translate to the number 15. + +In this exercise you are going to create a helpful program so that you don't have to remember the values of the bands. +The program will take color names as input and output a two digit number, even if the input is more than two colors! + +The band colors are encoded as follows: + +- black: 0 +- brown: 1 +- red: 2 +- orange: 3 +- yellow: 4 +- green: 5 +- blue: 6 +- violet: 7 +- grey: 8 +- white: 9 + +From the example above: +brown-green should return 15, and +brown-green-violet should return 15 too, ignoring the third color. diff --git a/exercises/practice/resistor-color-duo/.eslintrc b/exercises/practice/resistor-color-duo/.eslintrc new file mode 100644 index 0000000..1dbeac2 --- /dev/null +++ b/exercises/practice/resistor-color-duo/.eslintrc @@ -0,0 +1,18 @@ +{ + "root": true, + "extends": "@exercism/eslint-config-javascript", + "env": { + "jest": true + }, + "overrides": [ + { + "files": [ + "*.spec.js" + ], + "excludedFiles": [ + "custom.spec.js" + ], + "extends": "@exercism/eslint-config-javascript/maintainers" + } + ] +} diff --git a/exercises/practice/resistor-color-duo/.meta/config.json b/exercises/practice/resistor-color-duo/.meta/config.json new file mode 100644 index 0000000..d2e3222 --- /dev/null +++ b/exercises/practice/resistor-color-duo/.meta/config.json @@ -0,0 +1,28 @@ +{ + "authors": [ + "keiravillekode" + ], + "files": { + "solution": [ + "resistor-color-duo.wat" + ], + "test": [ + "resistor-color-duo.spec.js" + ], + "example": [ + ".meta/proof.ci.wat" + ], + "invalidator": [ + "package.json" + ] + }, + "blurb": "Convert color codes, as used on resistors, to a numeric value.", + "source": "Maud de Vries, Erik Schierboom", + "source_url": "https://github.com/exercism/problem-specifications/issues/1464", + "custom": { + "version.tests.compatibility": "jest-27", + "flag.tests.task-per-describe": false, + "flag.tests.may-run-long": false, + "flag.tests.includes-optional": false + } +} diff --git a/exercises/practice/resistor-color-duo/.meta/proof.ci.wat b/exercises/practice/resistor-color-duo/.meta/proof.ci.wat new file mode 100644 index 0000000..7d6206e --- /dev/null +++ b/exercises/practice/resistor-color-duo/.meta/proof.ci.wat @@ -0,0 +1,90 @@ +(module + (memory (export "mem") 1) + + (global $C i32 (i32.const 67)) + (global $G i32 (i32.const 71)) + (global $O i32 (i32.const 79)) + (global $R i32 (i32.const 82)) + (global $V i32 (i32.const 86)) + (global $W i32 (i32.const 87)) + (global $Y i32 (i32.const 89)) + + ;; + ;; Given a valid resistor color, returns the associated value + ;; + ;; @param {i32} offset - offset into the color buffer + ;; @param {i32} len - length of the color string + ;; + ;; @returns {i32} - the associated value + ;; + (func $colorCode (param $offset i32) (param $len i32) (result i32) + (local $first i32) + (local $fourth i32) + + ;; First letter in color buffer, forced to upper case + (local.set $first (i32.and + (i32.load8_u (local.get $offset)) + (i32.const 223) + )) + + ;; Fourth letter in color buffer, forced to upper case + (local.set $fourth (i32.and + (i32.load8_u (i32.add + (local.get $offset) + (i32.const 3) + )) + (i32.const 223) + )) + (if (i32.eq (local.get $first) (global.get $R)) (then + (return (i32.const 2)) + )) + (if (i32.eq (local.get $first) (global.get $O)) (then + (return (i32.const 3)) + )) + (if (i32.eq (local.get $first) (global.get $Y)) (then + (return (i32.const 4)) + )) + (if (i32.eq (local.get $first) (global.get $V)) (then + (return (i32.const 7)) + )) + (if (i32.eq (local.get $first) (global.get $W)) (then + (return (i32.const 9)) + )) + + (if (i32.eq (local.get $first) (global.get $G)) (then + (if (i32.eq (local.get $fourth) (global.get $Y)) (then + (return (i32.const 8)) + )) + (return (i32.const 5)) + )) + + (if (i32.eq (local.get $fourth) (global.get $C)) (then + (return (i32.const 0)) + )) + (if (i32.eq (local.get $fourth) (global.get $W)) (then + (return (i32.const 1)) + )) + (return (i32.const 6)) + ) + + ;; + ;; Converts a pair of color codes, as used on resistors, to a numeric value. + ;; + ;; @param {i32} firstOffset - The offset of the first string in linear memory. + ;; @param {i32} firstLength - The length of the first string in linear memory. + ;; @param {i32} secondOffset - The offset of the second string in linear memory. + ;; @param {i32} secondLength - The length of the second string in linear memory. + ;; + ;; @returns {i32} - The numeric value specified by the color codes. + ;; + (func (export "value") + (param $firstOffset i32) (param $firstLength i32) (param $secondOffset i32) (param $secondLength i32) (result i32) + (return (i32.add + (i32.mul + (call $colorCode (local.get $firstOffset) (local.get $firstLength)) + (i32.const 10) + ) + (call $colorCode (local.get $secondOffset) (local.get $secondLength)) + )) + ) +) diff --git a/exercises/practice/resistor-color-duo/.meta/tests.toml b/exercises/practice/resistor-color-duo/.meta/tests.toml new file mode 100644 index 0000000..9036fc7 --- /dev/null +++ b/exercises/practice/resistor-color-duo/.meta/tests.toml @@ -0,0 +1,31 @@ +# This is an auto-generated file. +# +# Regenerating this file via `configlet sync` will: +# - Recreate every `description` key/value pair +# - Recreate every `reimplements` key/value pair, where they exist in problem-specifications +# - Remove any `include = true` key/value pair (an omitted `include` key implies inclusion) +# - Preserve any other key/value pair +# +# As user-added comments (using the # character) will be removed when this file +# is regenerated, comments can be added via a `comment` key. + +[ce11995a-5b93-4950-a5e9-93423693b2fc] +description = "Brown and black" + +[7bf82f7a-af23-48ba-a97d-38d59406a920] +description = "Blue and grey" + +[f1886361-fdfd-4693-acf8-46726fe24e0c] +description = "Yellow and violet" + +[b7a6cbd2-ae3c-470a-93eb-56670b305640] +description = "White and red" + +[77a8293d-2a83-4016-b1af-991acc12b9fe] +description = "Orange and orange" + +[0c4fb44f-db7c-4d03-afa8-054350f156a8] +description = "Ignore additional colors" + +[4a8ceec5-0ab4-4904-88a4-daf953a5e818] +description = "Black and brown, one-digit" diff --git a/exercises/practice/resistor-color-duo/.npmrc b/exercises/practice/resistor-color-duo/.npmrc new file mode 100644 index 0000000..d26df80 --- /dev/null +++ b/exercises/practice/resistor-color-duo/.npmrc @@ -0,0 +1 @@ +audit=false diff --git a/exercises/practice/resistor-color-duo/LICENSE b/exercises/practice/resistor-color-duo/LICENSE new file mode 100644 index 0000000..90e73be --- /dev/null +++ b/exercises/practice/resistor-color-duo/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2021 Exercism + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/exercises/practice/resistor-color-duo/babel.config.js b/exercises/practice/resistor-color-duo/babel.config.js new file mode 100644 index 0000000..9c17ba5 --- /dev/null +++ b/exercises/practice/resistor-color-duo/babel.config.js @@ -0,0 +1,4 @@ +export default { + presets: ["@exercism/babel-preset-javascript"], + plugins: [], +}; diff --git a/exercises/practice/resistor-color-duo/package.json b/exercises/practice/resistor-color-duo/package.json new file mode 100644 index 0000000..0480e2f --- /dev/null +++ b/exercises/practice/resistor-color-duo/package.json @@ -0,0 +1,34 @@ +{ + "name": "@exercism/wasm-resistor-color-duo", + "description": "Exercism exercises in WebAssembly.", + "type": "module", + "private": true, + "license": "MIT", + "repository": { + "type": "git", + "url": "https://github.com/exercism/wasm", + "directory": "exercises/practice/resistor-color-duo" + }, + "jest": { + "maxWorkers": 1 + }, + "devDependencies": { + "@babel/core": "^7.23.3", + "@exercism/babel-preset-javascript": "^0.4.0", + "@exercism/eslint-config-javascript": "^0.6.0", + "@types/jest": "^29.5.8", + "@types/node": "^20.9.1", + "babel-jest": "^29.7.0", + "core-js": "^3.33.2", + "eslint": "^8.54.0", + "jest": "^29.7.0" + }, + "dependencies": { + "@exercism/wasm-lib": "^0.2.0" + }, + "scripts": { + "test": "node --experimental-vm-modules node_modules/jest/bin/jest.js ./*", + "watch": "node --experimental-vm-modules node_modules/jest/bin/jest.js --watch ./*", + "lint": "eslint ." + } +} diff --git a/exercises/practice/resistor-color-duo/resistor-color-duo.spec.js b/exercises/practice/resistor-color-duo/resistor-color-duo.spec.js new file mode 100644 index 0000000..38f11a7 --- /dev/null +++ b/exercises/practice/resistor-color-duo/resistor-color-duo.spec.js @@ -0,0 +1,110 @@ +import { compileWat, WasmRunner } from "@exercism/wasm-lib"; + +let wasmModule; +let currentInstance; + +function value(first, second) { + const firstBufferOffset = 1024; + const firstBufferCapacity = 1024; + + const firstLengthEncoded = new TextEncoder().encode(first).length; + if (firstLengthEncoded > firstBufferCapacity) { + throw new Error( + `String is too large for buffer of size ${firstBufferCapacity} bytes` + ); + } + + currentInstance.set_mem_as_utf8(firstBufferOffset, firstLengthEncoded, first); + + const secondBufferOffset = 2048; + const secondBufferCapacity = 1024; + + const secondLengthEncoded = new TextEncoder().encode(second).length; + if (secondLengthEncoded > secondBufferCapacity) { + throw new Error( + `String is too large for buffer of size ${secondBufferCapacity} bytes` + ); + } + + currentInstance.set_mem_as_utf8( + secondBufferOffset, + secondLengthEncoded, + second + ); + + return currentInstance.exports.value( + firstBufferOffset, + firstLengthEncoded, + secondBufferOffset, + secondLengthEncoded + ); +} + +beforeAll(async () => { + try { + const watPath = new URL("./resistor-color-duo.wat", import.meta.url); + const { buffer } = await compileWat(watPath); + wasmModule = await WebAssembly.compile(buffer); + } catch (err) { + console.log(`Error compiling *.wat: \n${err}`); + process.exit(1); + } +}); + +describe("Resistor Color Duo", () => { + beforeEach(async () => { + currentInstance = null; + if (!wasmModule) { + return Promise.reject(); + } + try { + currentInstance = await new WasmRunner(wasmModule); + return Promise.resolve(); + } catch (err) { + console.log(`Error instantiating WebAssembly module: ${err}`); + return Promise.reject(); + } + }); + + test("Brown and black", () => { + const expected = 10; + const actual = value("brown", "black"); + expect(actual).toEqual(expected); + }); + + xtest("Blue and grey", () => { + const expected = 68; + const actual = value("blue", "grey"); + expect(actual).toEqual(expected); + }); + + xtest("Yellow and violet", () => { + const expected = 47; + const actual = value("yellow", "violet"); + expect(actual).toEqual(expected); + }); + + xtest("White and red", () => { + const expected = 92; + const actual = value("white", "red"); + expect(actual).toEqual(expected); + }); + + xtest("Orange and orange", () => { + const expected = 33; + const actual = value("orange", "orange"); + expect(actual).toEqual(expected); + }); + + xtest("Ignore additional colors", () => { + const expected = 51; + const actual = value("green", "brown"); + expect(actual).toEqual(expected); + }); + + xtest("Black and brown, one-digit", () => { + const expected = 1; + const actual = value("black", "brown"); + expect(actual).toEqual(expected); + }); +}); diff --git a/exercises/practice/resistor-color-duo/resistor-color-duo.wat b/exercises/practice/resistor-color-duo/resistor-color-duo.wat new file mode 100644 index 0000000..b3cda13 --- /dev/null +++ b/exercises/practice/resistor-color-duo/resistor-color-duo.wat @@ -0,0 +1,18 @@ +(module + (memory (export "mem") 1) + + ;; + ;; Converts color codes, as used on resistors, to a numeric value. + ;; + ;; @param {i32} firstOffset - The offset of the first string in linear memory. + ;; @param {i32} firstLength - The length of the first string in linear memory. + ;; @param {i32} secondOffset - The offset of the second string in linear memory. + ;; @param {i32} secondLength - The length of the second string in linear memory. + ;; + ;; @returns {i32} - The numeric value specified by the color codes. + ;; + (func (export "value") + (param $firstOffset i32) (param $firstLength i32) (param $secondOffset i32) (param $secondLength i32) (result i32) + (i32.const 42) + ) +)