diff --git a/curriculum/challenges/_meta/rosetta-code/meta.json b/curriculum/challenges/_meta/rosetta-code/meta.json index 3e2c3538a0..d57fdfc966 100644 --- a/curriculum/challenges/_meta/rosetta-code/meta.json +++ b/curriculum/challenges/_meta/rosetta-code/meta.json @@ -396,6 +396,74 @@ "5a23c84252665b21eecc8013", "Sorting algorithms/Strand sort" ], + [ + "5a23c84252665b21eecc8017", + "Soundex" + ], + [ + "5a23c84252665b21eecc801c", + "Spiral matrix" + ], + [ + "5a23c84252665b21eecc801d", + "Split a character string based on change of character" + ], + [ + "5a23c84252665b21eecc8024", + "State name puzzle" + ], + [ + "5a23c84252665b21eecc8028", + "Stern-Brocot sequence" + ], + [ + "5a23c84252665b21eecc8029", + "Straddling checkerboard" + ], + [ + "5a23c84252665b21eecc802a", + "Stream Merge" + ], + [ + "5a23c84252665b21eecc8036", + "Strip control codes and extended characters from a string" + ], + [ + "5a23c84252665b21eecc8038", + "Subleq" + ], + [ + "5a23c84252665b21eecc803c", + "Sudoku" + ], + [ + "5a23c84252665b21eecc803f", + "Sum digits of an integer" + ], + [ + "5a23c84252665b21eecc8040", + "Sum multiples of 3 and 5" + ], + [ + "5a23c84252665b21eecc8041", + "Sum of a series" + ], + [ + "5a23c84252665b21eecc8042", + "Sum of squares" + ], + [ + "5a23c84252665b21eecc8043", + "Sum to 100" + ], + [ + "5a23c84252665b21eecc8045", + "Sutherland-Hodgman polygon clipping" + ], + [ + "5a23c84252665b21eecc8046", + "Symmetric difference" + ], [ "594ecc0d9a8cf816e3340187", "Taxicab numbers" diff --git a/curriculum/challenges/english/08-coding-interview-prep/rosetta-code/soundex.md b/curriculum/challenges/english/08-coding-interview-prep/rosetta-code/soundex.md new file mode 100644 index 0000000000..58ca7e3147 --- /dev/null +++ b/curriculum/challenges/english/08-coding-interview-prep/rosetta-code/soundex.md @@ -0,0 +1,98 @@ +--- +id: 5a23c84252665b21eecc8017 +title: Soundex +challengeType: 5 +--- + +## Description +
+Soundex is an algorithm for creating indices for words based on their pronunciation. +The goal is for homophones to be encoded to the same representation so that they can be matched despite minor differences in spelling (from the WP article). +There is a major issue in many of the implementations concerning the separation of two consonants that have the same soundex code! According to the official Rules https://www.archives.gov/research/census/soundex.html. So check for instance if Ashcraft is coded to A-261. + +Write a function that takes a string as a parameter and returns the encoded string. +
+ +## Instructions +
+ +
+ +## Tests +
+ +``` yml +tests: + - text: soundex should be a function. + testString: assert(typeof soundex == 'function', 'soundex should be a function.'); + - text: soundex("Soundex") should return a string. + testString: assert(typeof soundex("Soundex") == 'string', 'soundex("Soundex") should return a string.'); + - text: soundex("Soundex") should return "S532". + testString: assert.equal(soundex("Soundex"), "S532", 'soundex("Soundex") should return "S532".'); + - text: soundex("Example") should return "E251". + testString: assert.equal(soundex("Example"), "E251", 'soundex("Example") should return "E251".'); + - text: soundex("Sownteks") should return "S532". + testString: assert.equal(soundex("Sownteks"), "S532", 'soundex("Sownteks") should return "S532".'); + - text: soundex("Ekzampul") should return "E251". + testString: assert.equal(soundex("Ekzampul"), "E251", 'soundex("Ekzampul") should return "E251".'); + - text: soundex("Euler") should return "E460". + testString: assert.equal(soundex("Euler"), "E460", 'soundex("Euler") should return "E460".'); + - text: soundex("Gauss") should return "G200". + testString: assert.equal(soundex("Gauss"), "G200", 'soundex("Gauss") should return "G200".'); + - text: soundex("Hilbert") should return "H416". + testString: assert.equal(soundex("Hilbert"), "H416", 'soundex("Hilbert") should return "H416".'); + - text: soundex("Knuth") should return "K530". + testString: assert.equal(soundex("Knuth"), "K530", 'soundex("Knuth") should return "K530".'); + - text: soundex("Lloyd") should return "L300". + testString: assert.equal(soundex("Lloyd"), "L300", 'soundex("Lloyd") should return "L300".'); + - text: soundex("Lukasiewicz") should return "L222". + testString: assert.equal(soundex("Lukasiewicz"), "L222", 'soundex("Lukasiewicz") should return "L222".'); +``` + +
+ +## Challenge Seed +
+
+ +```js +function soundex (s) { + // Good luck! +} +``` + +
+
+ +## Solution +
+ +```js +function soundex (s) { + var a = s.toLowerCase().split('') + var f = a.shift(), + r = '', + codes = { + a: '', e: '', i: '', o: '', u: '', + b: 1, f: 1, p: 1, v: 1, + c: 2, g: 2, j: 2, k: 2, q: 2, s: 2, x: 2, z: 2, + d: 3, t: 3, + l: 4, + m: 5, n: 5, + r: 6 + }; + r = f + a + .map(function(v, i, a) { + return codes[v] + }) + .filter(function(v, i, a) { + return ((i === 0) ? v !== codes[f] : v !== a[i - 1]); + }) + .join(''); + + return (r + '000').slice(0, 4).toUpperCase(); +} +``` + +
\ No newline at end of file diff --git a/curriculum/challenges/english/08-coding-interview-prep/rosetta-code/spiral-matrix.md b/curriculum/challenges/english/08-coding-interview-prep/rosetta-code/spiral-matrix.md new file mode 100644 index 0000000000..8f85e187cc --- /dev/null +++ b/curriculum/challenges/english/08-coding-interview-prep/rosetta-code/spiral-matrix.md @@ -0,0 +1,81 @@ +--- +id: 5a23c84252665b21eecc801c +title: Spiral matrix +challengeType: 5 +--- + +## Description +
+Produce a spiral array. +A spiral array is a square arrangement of the first N2 natural numbers, where the numbers increase sequentially as you go around the edges of the array spiraling inwards. +For example, given 5, produce this array: +
+0  1  2  3  4
+15 16 17 18 5
+14 23 24 19 6
+13 22 21 20 7
+12 11 10  9 8
+
+
+ +## Instructions +
+ +
+ +## Tests +
+ +``` yml +tests: + - text: spiralArray should be a function. + testString: assert(typeof spiralArray=='function','spiralArray should be a function.'); + - text: spiralArray(3) should return a array. + testString: assert(Array.isArray(spiralArray(3)), 'spiralArray(3) should return a array.'); + - text: spiralArray(3) should return [[0, 1, 2],[7, 8, 3],[6, 5, 4]]. + testString: assert.deepEqual(spiralArray(3), [[0, 1, 2], [7, 8, 3], [6, 5, 4]], 'spiralArray(3) should return [[0, 1, 2],[7, 8, 3],[6, 5, 4]].'); + - text: spiralArray(4) should return [[0, 1, 2, 3],[11, 12, 13, 4],[10, 15, 14, 5],[9, 8, 7, 6]]. + testString: assert.deepEqual(spiralArray(4), [[0, 1, 2, 3], [11, 12, 13, 4], [10, 15, 14, 5], [9, 8, 7, 6]], 'spiralArray(4) should return [[0, 1, 2, 3],[11, 12, 13, 4],[10, 15, 14, 5],[9, 8, 7, 6]].'); + - text: spiralArray(5) should return [[0, 1, 2, 3, 4],[15, 16, 17, 18, 5],[14, 23, 24, 19, 6],[13, 22, 21, 20, 7],[12, 11, 10, 9, 8]]. + testString: assert.deepEqual(spiralArray(5), [[0, 1, 2, 3, 4], [15, 16, 17, 18, 5], [14, 23, 24, 19, 6], [13, 22, 21, 20, 7], [12, 11, 10, 9, 8]], 'spiralArray(5) should return [[0, 1, 2, 3, 4],[15, 16, 17, 18, 5],[14, 23, 24, 19, 6],[13, 22, 21, 20, 7],[12, 11, 10, 9, 8]].'); +``` + +
+ +## Challenge Seed +
+
+ +```js +function spiralArray (n) { + // Good luck! +} +``` + +
+
+ +## Solution +
+ +```js +function spiralArray (n) { + var arr = Array(n), + x = 0, y = n, + total = n * n--, + dx = 1, dy = 0, + i = 0, j = 0; + while (y) arr[--y] = []; + while (i < total) { + arr[y][x] = i++; + x += dx; y += dy; + if (++j == n) { + if (dy < 0) {x++; y++; n -= 2} + j = dx; dx = -dy; dy = j; j = 0; + } + } + return arr; +} +``` + +
\ No newline at end of file diff --git a/curriculum/challenges/english/08-coding-interview-prep/rosetta-code/split-a-character-string-based-on-change-of-character.md b/curriculum/challenges/english/08-coding-interview-prep/rosetta-code/split-a-character-string-based-on-change-of-character.md new file mode 100644 index 0000000000..06874eaf9f --- /dev/null +++ b/curriculum/challenges/english/08-coding-interview-prep/rosetta-code/split-a-character-string-based-on-change-of-character.md @@ -0,0 +1,96 @@ +--- +id: 5a23c84252665b21eecc801d +title: Split a character string based on change of character +challengeType: 5 +--- + +## Description +
+Split a (character) string into comma (plus a blank) delimited strings based on a change of character (left to right). +Blanks should be treated as any other character (except they are problematic to display clearly). The same applies to commas. +For instance, the string: +"gHHH5YY++///\" +should be split as: +["g", "HHH", "5", "YY", "++", "///", "\" ] +
+ +## Instructions +
+ +
+ +## Tests +
+ +``` yml +tests: + - text: split should be a function. + testString: assert(typeof split == 'function', 'split should be a function.'); + - text: split("hello") should return a array. + testString: assert(Array.isArray(split("hello")), 'split("hello") should return a array.'); + - text: split("hello") should return ["h", "e", "ll", "o"]. + testString: assert.deepEqual(split("hello"), ["h", "e", "ll", "o"], 'split("hello") should return ["h", "e", "ll", "o"].'); + - text: split("commission") should return ["c", "o", "mm", "i", "ss", "i", "o", "n"]. + testString: assert.deepEqual(split("commission"), ["c", "o", "mm", "i", "ss", "i", "o", "n"], 'split("commission") should return ["c", "o", "mm", "i", "ss", "i", "o", "n"].'); + - text: split("ssss----====llloooo") should return ["ssss", "----", "====", "lll", "oooo"]. + testString: assert.deepEqual(split("ssss----====llloooo"), ["ssss", "----", "====", "lll", "oooo"], 'split("ssss----====llloooo") should return ["ssss", "----", "====", "lll", "oooo"].'); + - text: split("sssmmmaaammmaaat") should return ["sss", "mmm", "aaa", "mmm", "aaa", "t"]. + testString: assert.deepEqual(split("sssmmmaaammmaaat"), ["sss", "mmm", "aaa", "mmm", "aaa", "t"], 'split("sssmmmaaammmaaat") should return ["sss", "mmm", "aaa", "mmm", "aaa", "t"].'); + - text: split("gHHH5YY++///\") should return ["g", "HHH", "5", "YY", "++", "///", "\\"]. + testString: assert.deepEqual(split("gHHH5YY++///\\"), ["g", "HHH", "5", "YY", "++", "///", "\\"], 'split("gHHH5YY++///\") should return ["g", "HHH", "5", "YY", "++", "///", "\\"].'); +``` + +
+ +## Challenge Seed +
+
+ +```js +function split (str) { + // Good luck! +} +``` + +
+
+ +## Solution +
+ +```js +function split (str) { + const concat = xs => + xs.length > 0 ? (() => { + const unit = typeof xs[0] === 'string' ? '' : []; + return unit.concat.apply(unit, xs); + })() : []; + + const group = xs => groupBy((a, b) => a === b, xs); + + const groupBy = (f, xs) => { + const dct = xs.slice(1) + .reduce((a, x) => { + const + h = a.active.length > 0 ? a.active[0] : undefined, + blnGroup = h !== undefined && f(h, x); + return { + active: blnGroup ? a.active.concat([x]) : [x], + sofar: blnGroup ? a.sofar : a.sofar.concat([a.active]) + }; + }, { + active: xs.length > 0 ? [xs[0]] : [], + sofar: [] + }); + return dct.sofar.concat(dct.active.length > 0 ? [dct.active] : []); + }; + + const map = (f, xs) => xs.map(f); + + const stringChars = s => s.split(''); + + return map(concat, group(stringChars(str))) +} +``` + +
\ No newline at end of file diff --git a/curriculum/challenges/english/08-coding-interview-prep/rosetta-code/state-name-puzzle.md b/curriculum/challenges/english/08-coding-interview-prep/rosetta-code/state-name-puzzle.md new file mode 100644 index 0000000000..601a235904 --- /dev/null +++ b/curriculum/challenges/english/08-coding-interview-prep/rosetta-code/state-name-puzzle.md @@ -0,0 +1,104 @@ +--- +id: 5a23c84252665b21eecc8024 +title: State name puzzle +challengeType: 5 +--- + +## Description +
+Background +This task is inspired by Mark Nelson's DDJ Column "Wordplay" and one of the weekly puzzle challenges from Will Shortz on NPR Weekend Edition [http://www.npr.org/templates/story/story.php?storyId=9264290] and originally attributed to David Edelheit. +The challenge was to take the names of two U.S. States, mix them all together, then rearrange the letters to form the names of two different U.S. States (so that all four state names differ from one another). +What states are these? +The problem was reissued on the Unicon Discussion Web which includes several solutions with analysis. Several techniques may be helpful and you may wish to refer to Gödel numbering, equivalence relations, and equivalence classes. The basic merits of these were discussed in the Unicon Discussion Web. +A second challenge in the form of a set of fictitious new states was also presented. +Task: +Write a function to solve the challenge for the given array of names of states. The function should return an array. Each element should be an object in this form: {"from":[],"to":[]}. The "from" array should contain the original names and the "to" array should contain the resultant names. +
+ +## Instructions +
+ +
+ +## Tests +
+ +``` yml +tests: + - text: solve should be a function. + testString: assert(typeof solve == 'function', 'solve should be a function.'); + - text: solve(["New Mexico", "New York", "North Carolina ", "North Dakota", "Ohio", "Oklahoma", "Oregon", "Pennsylvania", "Rhode Island", "South Carolina", "South Dakota"]) should return a array. + testString: assert(Array.isArray(solve(["New Mexico", "New York", "North Carolina ", "North Dakota", "Ohio", "Oklahoma", "Oregon", "Pennsylvania", "Rhode Island", "South Carolina", "South Dakota"])), 'solve(["New Mexico", "New York", "North Carolina ", "North Dakota", "Ohio", "Oklahoma", "Oregon", "Pennsylvania", "Rhode Island", "South Carolina", "South Dakota"]) should return a array.'); + - text: 'solve(["New Mexico", "New York", "North Carolina ", "North Dakota", "Ohio", "Oklahoma", "Oregon", "Pennsylvania", "Rhode Island", "South Carolina", "South Dakota"]) should return [{ from: ["North Carolina ", "South Dakota"], to: ["North Dakota", "South Carolina"] }].' + testString: assert.deepEqual(solve(["New Mexico", "New York", "North Carolina ", "North Dakota", "Ohio", "Oklahoma", "Oregon", "Pennsylvania", "Rhode Island", "South Carolina", "South Dakota"]), [{ from:["North Carolina ", "South Dakota"], to:["North Dakota", "South Carolina"] }], 'solve(["New Mexico", "New York", "North Carolina ", "North Dakota", "Ohio", "Oklahoma", "Oregon", "Pennsylvania", "Rhode Island", "South Carolina", "South Dakota"]) should return [{ from:["North Carolina ", "South Dakota"], to:["North Dakota", "South Carolina"] }].'); + - text: 'solve(["New York", "New Kory", "Wen Kory", "York New", "Kory New", "New Kory"]) should return [{ from: ["New Kory", "New York"], to: ["Wen Kory", "York New"] }, { from: ["New Kory", "New York"], to: ["Kory New", "Wen Kory"] }, { from: ["New Kory", "New York"], to: ["Kory New", "York New"] }, { from: ["New York", "Wen Kory"], to: ["New Kory", "York New"] }, { from: ["New York", "Wen Kory"], to: ["Kory New", "New Kory"] }, { from: ["New York", "Wen Kory"], to: ["Kory New", "York New"] }, { from: ["New York", "York New"], to: ["New Kory", "Wen Kory"] }, { from: ["New York", "York New"], to: ["Kory New", "New Kory"] }, { from: ["New York", "York New"], to: ["Kory New", "Wen Kory"] }, { from: ["Kory New", "New York"], to: ["New Kory", "Wen Kory"] }, { from: ["Kory New", "New York"], to: ["New Kory", "York New"] }, { from: ["Kory New", "New York"], to: ["Wen Kory", "York New"] }, { from: ["New Kory", "Wen Kory"], to: ["Kory New", "York New"] }, { from: ["New Kory", "York New"], to: ["Kory New", "Wen Kory"] }, { from: ["Kory New", "New Kory"], to: ["Wen Kory", "York New"] }].' + testString: assert.deepEqual(solve(["New York", "New Kory", "Wen Kory", "York New", "Kory New", "New Kory"]), [{ from:["New Kory", "New York"], to:["Wen Kory", "York New"] }, { from:["New Kory", "New York"], to:["Kory New", "Wen Kory"] }, { from:["New Kory", "New York"], to:["Kory New", "York New"] }, { from:["New York", "Wen Kory"], to:["New Kory", "York New"] }, { from:["New York", "Wen Kory"], to:["Kory New", "New Kory"] }, { from:["New York", "Wen Kory"], to:["Kory New", "York New"] }, { from:["New York", "York New"], to:["New Kory", "Wen Kory"] }, { from:["New York", "York New"], to:["Kory New", "New Kory"] }, { from:["New York", "York New"], to:["Kory New", "Wen Kory"] }, { from:["Kory New", "New York"], to:["New Kory", "Wen Kory"] }, { from:["Kory New", "New York"], to:["New Kory", "York New"] }, { from:["Kory New", "New York"], to:["Wen Kory", "York New"] }, { from:["New Kory", "Wen Kory"], to:["Kory New", "York New"] }, { from:["New Kory", "York New"], to:["Kory New", "Wen Kory"] }, { from:["Kory New", "New Kory"], to:["Wen Kory", "York New"] }], 'solve(["New York", "New Kory", "Wen Kory", "York New", "Kory New", "New Kory"]) should return [{ from:["New Kory", "New York"], to:["Wen Kory", "York New"] }, { from:["New Kory", "New York"], to:["Kory New", "Wen Kory"] }, { from:["New Kory", "New York"], to:["Kory New", "York New"] }, { from:["New York", "Wen Kory"], to:["New Kory", "York New"] }, { from:["New York", "Wen Kory"], to:["Kory New", "New Kory"] }, { from:["New York", "Wen Kory"], to:["Kory New", "York New"] }, { from:["New York", "York New"], to:["New Kory", "Wen Kory"] }, { from:["New York", "York New"], to:["Kory New", "New Kory"] }, { from:["New York", "York New"], to:["Kory New", "Wen Kory"] }, { from:["Kory New", "New York"], to:["New Kory", "Wen Kory"] }, { from:["Kory New", "New York"], to:["New Kory", "York New"] }, { from:["Kory New", "New York"], to:["Wen Kory", "York New"] }, { from:["New Kory", "Wen Kory"], to:["Kory New", "York New"] }, { from:["New Kory", "York New"], to:["Kory New", "Wen Kory"] }, { from:["Kory New", "New Kory"], to:["Wen Kory", "York New"] }].'); +``` + +
+ +## Challenge Seed +
+
+ +```js +function solve (input) { + // Good luck! +} +``` + +
+
+ +## Solution +
+ +```js +function solve (input) { + var orig = {}; + input.forEach(function(e) { + orig[e.replace(/\s/g, "").toLowerCase()] = e; + }) + + input = Object.keys(orig) + var map = {}; + for (var i = 0; i < input.length - 1; i++) { + var pair0 = input[i]; + for (var j = i + 1; j < input.length; j++) { + + var pair = [pair0, input[j]]; + var s = pair0 + pair[1]; + var key = s.split("").sort(); + + var val = map[key] ? map[key] : []; + val.push(pair); + map[key] = val; + } + } + + var result = []; + Object.keys(map).forEach((key) => { + + for (var i = 0; i < map[key].length - 1; i++) { + var a = map[key][i]; + for (var j = i + 1; j < map[key].length; j++) { + var b = map[key][j]; + + if ((new Set([a[0], b[0], a[1], b[1]])).size < 4) + continue; + var from = [orig[a[0]], orig[a[1]]].sort() + var to = [orig[b[0]], orig[b[1]]].sort() + result.push({ + from, + to + }) + } + } + }); + + return result; +} +``` + +
\ No newline at end of file diff --git a/curriculum/challenges/english/08-coding-interview-prep/rosetta-code/stern-brocot-sequence.md b/curriculum/challenges/english/08-coding-interview-prep/rosetta-code/stern-brocot-sequence.md new file mode 100644 index 0000000000..a6bb5ef3b2 --- /dev/null +++ b/curriculum/challenges/english/08-coding-interview-prep/rosetta-code/stern-brocot-sequence.md @@ -0,0 +1,96 @@ +--- +id: 5a23c84252665b21eecc8028 +title: Stern-Brocot sequence +challengeType: 5 +--- + +## Description +
+For this task, the Stern-Brocot sequence is to be generated by an algorithm similar to that employed in generating the +Fibonacci sequence. +
    +
  1. The first and second members of the sequence are both 1:
  2. + +
  3. Start by considering the second member of the sequence
  4. +
  5. Sum the considered member of the sequence and its precedent, (1 + 1) = 2, and append it to the end of the + sequence:
  6. + +
  7. Append the considered member of the sequence to the end of the sequence:
  8. + +
  9. Consider the next member of the series, (the third member i.e. 2)
  10. +
  11. GOTO 3
  12. + +
  13. Sum the considered member of the sequence and its precedent, (2 + 1) = 3, and append it to the end of the + sequence:
  14. + +
  15. Append the considered member of the sequence to the end of the sequence:
  16. + +
  17. Consider the next member of the series, (the fourth member i.e. 1)
  18. +
+Create a function that returns the $ n^{th} $ member of the sequence using the method outlined above. +
+ +## Instructions +
+ +
+ +## Tests +
+ +``` yml +tests: + - text: sternBrocot should be a function. + testString: assert(typeof sternBrocot == 'function', 'sternBrocot should be a function.'); + - text: sternBrocot(2) should return a number. + testString: assert(typeof sternBrocot(2) == 'number', 'sternBrocot(2) should return a number.'); + - text: sternBrocot(2) should return 3. + testString: assert.equal(sternBrocot(2), 3, 'sternBrocot(2) should return 3.'); + - text: sternBrocot(3) should return 5. + testString: assert.equal(sternBrocot(3), 5, 'sternBrocot(3) should return 5.'); + - text: sternBrocot(5) should return 11. + testString: assert.equal(sternBrocot(5), 11, 'sternBrocot(5) should return 11.'); + - text: sternBrocot(7) should return 19. + testString: assert.equal(sternBrocot(7), 19, 'sternBrocot(7) should return 19.'); + - text: sternBrocot(10) should return 39. + testString: assert.equal(sternBrocot(10), 39, 'sternBrocot(10) should return 39.'); +``` + +
+ +## Challenge Seed +
+
+ +```js +function sternBrocot (num) { + // Good luck! +} +``` + +
+
+ +## Solution +
+ +```js +function sternBrocot (num) { + function f(n) { + return n < 2 ? n : (n & 1) ? f(Math.floor(n / 2)) + f(Math.floor(n / 2 + 1)) : f(Math.floor(n / 2)); + } + + function gcd(a, b) { + return a ? a < b ? gcd(b % a, a) : gcd(a % b, b) : b; + } + var n; + for (n = 1; f(n) != num; n++); + return n; +} +``` + +
diff --git a/curriculum/challenges/english/08-coding-interview-prep/rosetta-code/straddling-checkerboard.md b/curriculum/challenges/english/08-coding-interview-prep/rosetta-code/straddling-checkerboard.md new file mode 100644 index 0000000000..8001f98c62 --- /dev/null +++ b/curriculum/challenges/english/08-coding-interview-prep/rosetta-code/straddling-checkerboard.md @@ -0,0 +1,107 @@ +--- +id: 5a23c84252665b21eecc8029 +title: Straddling checkerboard +challengeType: 5 +--- + +## Description +
+Implement functions to encrypt and decrypt a message using the straddling checkerboard method. The functions will take a string and an array as parameters. The array has 3 strings representing the 3 rows of the checkerboard. The output will be a series of decimal digits. +Numbers should be encrypted by inserting the escape character before each digit, then including the digit unencrypted. This should be reversed for decryption. +
+ +## Instructions +
+ +
+ +## Tests +
+ +``` yml +tests: + - text: straddle should be a function. + testString: assert(typeof straddle == 'function', 'straddle should be a function.'); + - text: straddle("One night-it was on the twentieth of March, 1888-I was returning.",["ESTONIA R", "BCDFGHJKLM", "PQUVWXYZ./"]) should return a string. + testString: assert(typeof straddle("One night-it was on the twentieth of March, 1888-I was returning.", ["ESTONIA R", "BCDFGHJKLM", "PQUVWXYZ./"]) == 'string', 'straddle("One night-it was on the twentieth of March, 1888-I was returning.",["ESTONIA R", "BCDFGHJKLM", "PQUVWXYZ./"]) should return a string.'); + - text: straddle("One night-it was on the twentieth of March, 1888-I was returning.",["ESTONIA R", "BCDFGHJKLM", "PQUVWXYZ./"]) should return "34045747525284613427502840425027537379697175891898898898584619028294547488". + testString: assert.equal(straddle("One night-it was on the twentieth of March, 1888-I was returning.", ["ESTONIA R", "BCDFGHJKLM", "PQUVWXYZ./"]), "34045747525284613427502840425027537379697175891898898898584619028294547488", 'straddle("One night-it was on the twentieth of March, 1888-I was returning.",["ESTONIA R", "BCDFGHJKLM", "PQUVWXYZ./"]) should return "34045747525284613427502840425027537379697175891898898898584619028294547488".'); + - text: straddle("One night-it was on the twentieth of March, 1888-I was returning",["HOL MES RT", "ABCDFGIJKN", "PQUVWXYZ./"]) should return "139539363509369743061399059745399365901344308320791798798798367430685972839363935". + testString: assert.equal(straddle("One night-it was on the twentieth of March, 1888-I was returning", ["HOL MES RT", "ABCDFGIJKN", "PQUVWXYZ./"]), "139539363509369743061399059745399365901344308320791798798798367430685972839363935", 'straddle("One night-it was on the twentieth of March, 1888-I was returning",["HOL MES RT", "ABCDFGIJKN", "PQUVWXYZ./"]) should return "139539363509369743061399059745399365901344308320791798798798367430685972839363935".'); + - text: straddle("Thecheckerboardcakerecipespecifies3largeeggsand2.25cupsofflour.",["ET AON RIS", "BCDFGHJKLM", "PQ/UVWXYZ."]) should return "125021250212707204372221327070218600960021823809623283724002424935226226962262521636094232328463769". + testString: assert.equal(straddle("Thecheckerboardcakerecipespecifies3largeeggsand2.25cupsofflour.", ["ET AON RIS", "BCDFGHJKLM", "PQ/UVWXYZ."]), "125021250212707204372221327070218600960021823809623283724002424935226226962262521636094232328463769", 'straddle("Thecheckerboardcakerecipespecifies3largeeggsand2.25cupsofflour.",["ET AON RIS", "BCDFGHJKLM", "PQ/UVWXYZ."]) should return "125021250212707204372221327070218600960021823809623283724002424935226226962262521636094232328463769".'); + - text: unstraddle should be a function. + testString: assert(typeof unstraddle == 'function', 'unstraddle should be a function.'); + - text: unstraddle("34045747525284613427502840425027537379697175891898898898584619028294547488",["ESTONIA R", "BCDFGHJKLM", "PQUVWXYZ./"]) should return a string. + testString: assert(typeof unstraddle("34045747525284613427502840425027537379697175891898898898584619028294547488", ["ESTONIA R", "BCDFGHJKLM", "PQUVWXYZ./"]) == 'string', 'unstraddle("34045747525284613427502840425027537379697175891898898898584619028294547488",["ESTONIA R", "BCDFGHJKLM", "PQUVWXYZ./"]) should return a string.'); + - text: unstraddle("34045747525284613427502840425027537379697175891898898898584619028294547488",["ESTONIA R", "BCDFGHJKLM", "PQUVWXYZ./"]) should return "ONENIGHTITWASONTHETWENTIETHOFMARCH1888IWASRETURNING.". + testString: assert.equal(unstraddle("34045747525284613427502840425027537379697175891898898898584619028294547488", ["ESTONIA R", "BCDFGHJKLM", "PQUVWXYZ./"]), "ONENIGHTITWASONTHETWENTIETHOFMARCH1888IWASRETURNING.", 'unstraddle("34045747525284613427502840425027537379697175891898898898584619028294547488",["ESTONIA R", "BCDFGHJKLM", "PQUVWXYZ./"]) should return "ONENIGHTITWASONTHETWENTIETHOFMARCH1888IWASRETURNING.".'); + - text: unstraddle("139539363509369743061399059745399365901344308320791798798798367430685972839363935",["HOL MES RT", "ABCDFGIJKN", "PQUVWXYZ./"]) should return "ONENIGHTITWASONTHETWENTIETHOFMARCH1888IWASRETURNING". + testString: assert.equal(unstraddle("139539363509369743061399059745399365901344308320791798798798367430685972839363935", ["HOL MES RT", "ABCDFGIJKN", "PQUVWXYZ./"]), "ONENIGHTITWASONTHETWENTIETHOFMARCH1888IWASRETURNING", 'unstraddle("139539363509369743061399059745399365901344308320791798798798367430685972839363935",["HOL MES RT", "ABCDFGIJKN", "PQUVWXYZ./"]) should return "ONENIGHTITWASONTHETWENTIETHOFMARCH1888IWASRETURNING".'); + - text: unstraddle("125021250212707204372221327070218600960021823809623283724002424935226226962262521636094232328463769",["ET AON RIS", "BCDFGHJKLM", "PQ/UVWXYZ."]) should return "THECHECKERBOARDCAKERECIPESPECIFIES3LARGEEGGSAND2.25CUPSOFFLOUR.". + testString: assert.equal(unstraddle("125021250212707204372221327070218600960021823809623283724002424935226226962262521636094232328463769", ["ET AON RIS", "BCDFGHJKLM", "PQ/UVWXYZ."]), "THECHECKERBOARDCAKERECIPESPECIFIES3LARGEEGGSAND2.25CUPSOFFLOUR.", 'unstraddle("125021250212707204372221327070218600960021823809623283724002424935226226962262521636094232328463769",["ET AON RIS", "BCDFGHJKLM", "PQ/UVWXYZ."]) should return "THECHECKERBOARDCAKERECIPESPECIFIES3LARGEEGGSAND2.25CUPSOFFLOUR.".'); +``` + +
+ +## Challenge Seed +
+
+ +```js +function straddle (message, alphabet) { + // Good luck! +} +function unstraddle (message, alphabet) { + // Good luck! +} +``` + +
+
+ +## Solution +
+ +```js +function straddle (message, alphabet) { + var prefixes = new Array("", alphabet[0].indexOf(" "), alphabet[0].lastIndexOf(" ")) + + var out = "" + message = message.toUpperCase() + message = message.replace(/([0-9])/g, "/$1") // dumb way to escape numbers + for (var i = 0; i < message.length; i++) { + var chr = message[i] + if (chr == " ") continue + for (var j = 0; j < 3; j++) { + var k = alphabet[j].indexOf(chr) + if (k < 0) continue + out += prefixes[j].toString() + k + } + if (chr == "/") out += message[++i] + } + return out +} +function unstraddle (message, alphabet) { + var prefixes = new Array("", alphabet[0].indexOf(" "), alphabet[0].lastIndexOf(" ")) + var out = "" + var n, o + for (var i = 0; i < message.length; i++) { + n = message[i] * 1 + switch (n) { + case prefixes[1]: + o = alphabet[1][message[++i]]; + break + case prefixes[2]: + o = alphabet[2][message[++i]]; + break + default: + o = alphabet[0][n] + } + o == "/" ? out += message[++i] : out += o + } + return out +} +``` + +
\ No newline at end of file diff --git a/curriculum/challenges/english/08-coding-interview-prep/rosetta-code/stream-merge.md b/curriculum/challenges/english/08-coding-interview-prep/rosetta-code/stream-merge.md new file mode 100644 index 0000000000..86b1ed700c --- /dev/null +++ b/curriculum/challenges/english/08-coding-interview-prep/rosetta-code/stream-merge.md @@ -0,0 +1,82 @@ +--- +id: 5a23c84252665b21eecc802a +title: Stream Merge +challengeType: 5 +--- + +## Description +
+Write a function that takes multiple sorted arrays of items, and returns one array of sorted items. +
+ +## Instructions +
+ +
+ +## Tests +
+ +``` yml +tests: + - text: mergeLists should be a function. + testString: assert(typeof mergeLists == 'function', 'mergeLists should be a function.'); + - text: mergeLists([[1, 3, 5, 9, 10], [2, 4, 6, 7, 8]]) should return a array. + testString: assert(Array.isArray(mergeLists([[1, 3, 5, 9, 10], [2, 4, 6, 7, 8]])), 'mergeLists([[1, 3, 5, 9, 10], [2, 4, 6, 7, 8]]) should return a array.'); + - text: mergeLists([[1, 3, 5, 9, 10], [2, 4, 6, 7, 8]]) should return [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]. + testString: assert.deepEqual(mergeLists([[1, 3, 5, 9, 10], [2, 4, 6, 7, 8]]), [1, 2, 3, 4, 5, 6, 7, 8, 9, 10], 'mergeLists([[1, 3, 5, 9, 10], [2, 4, 6, 7, 8]]) should return [1, 2, 3, 4, 5, 6, 7, 8, 9, 10].'); + - text: mergeLists([[1, 4, 7, 10], [2, 5, 8, 11], [3, 6, 9, 12]]) should return [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]. + testString: assert.deepEqual(mergeLists([[1, 4, 7, 10], [2, 5, 8, 11], [3, 6, 9, 12]]), [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12], 'mergeLists([[1, 4, 7, 10], [2, 5, 8, 11], [3, 6, 9, 12]]) should return [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12].'); + - text: mergeLists([[1, 3, 9, 14, 15, 17, 28], [7, 8, 14, 14, 23, 26, 28, 29, 30], [9, 23, 25, 29]]) should return [1, 3, 7, 8, 9, 9, 14, 14, 14, 15, 17, 23, 23, 25, 26, 28, 28, 29, 29, 30]. + testString: assert.deepEqual(mergeLists([[1, 3, 9, 14, 15, 17, 28], [7, 8, 14, 14, 23, 26, 28, 29, 30], [9, 23, 25, 29]]), [1, 3, 7, 8, 9, 9, 14, 14, 14, 15, 17, 23, 23, 25, 26, 28, 28, 29, 29, 30], 'mergeLists([[1, 3, 9, 14, 15, 17, 28], [7, 8, 14, 14, 23, 26, 28, 29, 30], [9, 23, 25, 29]]) should return [1, 3, 7, 8, 9, 9, 14, 14, 14, 15, 17, 23, 23, 25, 26, 28, 28, 29, 29, 30].'); + - text: mergeLists([[3, 14, 15], [2, 17, 18], [], [2, 3, 5, 7]]) should return [2, 2, 3, 3, 5, 7, 14, 15, 17, 18]. + testString: assert.deepEqual(mergeLists([[3, 14, 15], [2, 17, 18], [], [2, 3, 5, 7]]), [2, 2, 3, 3, 5, 7, 14, 15, 17, 18], 'mergeLists([[3, 14, 15], [2, 17, 18], [], [2, 3, 5, 7]]) should return [2, 2, 3, 3, 5, 7, 14, 15, 17, 18].'); + - text: mergeLists([[1, 19, 1999], [17, 33, 2999, 3000], [8, 500, 3999]]) should return [1, 8, 17, 19, 33, 500, 1999, 2999, 3000, 3999]. + testString: assert.deepEqual(mergeLists([[1, 19, 1999], [17, 33, 2999, 3000], [8, 500, 3999]]), [1, 8, 17, 19, 33, 500, 1999, 2999, 3000, 3999], 'mergeLists([[1, 19, 1999], [17, 33, 2999, 3000], [8, 500, 3999]]) should return [1, 8, 17, 19, 33, 500, 1999, 2999, 3000, 3999].'); +``` + +
+ +## Challenge Seed +
+
+ +```js +function mergeLists (lists) { + // Good luck! +} +``` + +
+
+ +## Solution +
+ +```js +function mergeLists (lists) { + function merge (l1, l2) { + var result = [], i=0, j=0; + while (l1.length && l2.length) { + if(l1[i]<=l2[j]){ + result.push(l1.shift()); + }else{ + result.push(l2.shift()); + } + } + + result.push.apply(result, l1); + result.push.apply(result, l2); + return result; + } + + var result=lists[0]; + for (var i = 1; i < lists.length; i++) { + result=merge(result, lists[i]); + } + + return result; +} +``` + +
\ No newline at end of file diff --git a/curriculum/challenges/english/08-coding-interview-prep/rosetta-code/strip-control-codes-and-extended-characters-from-a-string.md b/curriculum/challenges/english/08-coding-interview-prep/rosetta-code/strip-control-codes-and-extended-characters-from-a-string.md new file mode 100644 index 0000000000..d976626163 --- /dev/null +++ b/curriculum/challenges/english/08-coding-interview-prep/rosetta-code/strip-control-codes-and-extended-characters-from-a-string.md @@ -0,0 +1,69 @@ +--- +id: 5a23c84252665b21eecc8036 +title: Strip control codes and extended characters from a string +challengeType: 5 +--- + +## Description +
+The task is to strip control codes and extended characters from a string. The solution should demonstrate how to achieve each of the following results: +A string with control codes and extended characters stripped. +In ASCII, the control codes have decimal codes 0 through to 31 and 127. On an ASCII based system, if the control codes are stripped, the resultant string would have all of its characters within the range of 32 to 126 decimal on the ASCII table. +On a non-ASCII based system, we consider characters that do not have a corresponding glyph on the ASCII table (within the ASCII range of 32 to 126 decimal) to be an extended character for the purpose of this task. +
+ +## Instructions +
+ +
+ +## Tests +
+ +``` yml +tests: + - text: strip should be a function. + testString: assert(typeof strip == 'function', 'strip should be a function.'); + - text: strip("abc") should return a string. + testString: assert(typeof strip("\ba\\x00b\n\rc\fd\xc3") == 'string', 'strip("abc") should return a string.'); + - text: strip("\\ba\\x00b\\n\\rc\\fd\\xc3") should return "abcd". + testString: assert.equal(strip("\ba\x00b\n\rc\fd\xc3"), "abcd", 'strip("\\ba\\x00b\\n\\rc\\fd\\xc3") should return "abcd".'); + - text: strip("\\u0000\\n abc\\u00E9def\\u007F") should return " abcdef". + testString: assert.equal(strip("\u0000\n abc\u00E9def\u007F"), " abcdef", 'strip("\\u0000\\n abc\\u00E9def\\u007F") should return " abcdef".'); + - text: strip("a\\n\\tb\\u2102d\\u2147f") should return "abdf". + testString: assert.equal(strip("a\n\tb\u2102d\u2147f"), "abdf", 'strip("a\\n\\tb\\u2102d\\u2147f") should return "abdf".'); + - text: strip("Français.") should return "Franais.". + testString: assert.equal(strip("Français."), "Franais.", 'strip("Français.") should return "Franais.".'); + - text: strip("123\\tabc\\u0007DEF\\u007F+-*/€æŧðłþ") should return "123abcDEF+-*/". + testString: assert.equal(strip("123\tabc\u0007DEF\u007F+-*/€æŧðłþ"), "123abcDEF+-*/", 'strip("123\\tabc\\u0007DEF\\u007F+-*/€æŧðłþ") should return "123abcDEF+-*/".'); +``` + +
+ +## Challenge Seed +
+
+ +```js +function strip (s) { + // Good luck! +} +``` + +
+
+ +## Solution +
+ +```js +function strip (s) { + return s.split('').filter(function(x) { + var n = x.charCodeAt(0); + + return 31 < n && 127 > n; + }).join(''); +} +``` + +
\ No newline at end of file diff --git a/curriculum/challenges/english/08-coding-interview-prep/rosetta-code/subleq.md b/curriculum/challenges/english/08-coding-interview-prep/rosetta-code/subleq.md new file mode 100644 index 0000000000..eaee485dd4 --- /dev/null +++ b/curriculum/challenges/english/08-coding-interview-prep/rosetta-code/subleq.md @@ -0,0 +1,110 @@ +--- +id: 5a23c84252665b21eecc8038 +title: Subleq +challengeType: 5 +--- + +## Description +
+Subleq is an example of a One-Instruction + Set Computer (OISC). +It is named after its only instruction, which is SUbtract and Branch if Less than or EQual +to zero. +Your task is to create an interpreter which emulates such a machine. +The machine's memory consists of an array of signed integers. Any reasonable word size is fine, but the memory must be +able to hold negative as well as positive numbers. +Execution begins with the instruction pointer aimed at the first word, which is address 0. It proceeds as follows: +
    +
  1. Let A, B, and C be the value stored in the three consecutive words in memory starting at the instruction pointer.
  2. +
  3. Advance the instruction pointer 3 words to point at the address after the one containing C.
  4. +
  5. If A is -1, then a character is read from standard input and its code point stored in the address given by B. C + is unused.
  6. +
  7. If B is -1, then the number contained in the address given by A is interpreted as a code point and the + corresponding character output. C is again unused.
  8. +
  9. Otherwise, both A and B are treated as the addresses of memory locations. The number contained in the address + given by A is subtracted from the number at the address given by B (and the result stored back in address B). If + the result is zero or negative, the value C becomes the new instruction pointer.
  10. +
  11. If the instruction pointer becomes negative, execution halts.
  12. +
+Other negative addresses besides -1 may be treated as equivalent to -1, or generate an error, as you see fit. +Your solution should accept a program to execute on the machine, separately from the input fed to the program itself. +This program should be in raw subleq "machine code" - whitespace-separated decimal numbers, with no symbolic names or +other assembly-level extensions, to be loaded into memory starting at address 0. Show the output of your solution when +fed this "Hello, world!" program. (Note that the example assumes ASCII or a superset of it, such as any of the Latin-N +character sets or Unicode. You may translate it into another character set if your implementation is on a +non-ASCiI-compatible environment.) +
15 17 -1 17 -1 -1 16 1 -1 16 3 -1 15 15 0 0 -1 72 101 108 108 111 44 32 119 111 114 108 100 33 10 0
+Which corresponds to something like this in a hypothetical assembler language: +
start:
+    zero, message, -1
+    message, -1, -1
+    neg1, start+1, -1
+    neg1, start+3, -1
+    zero, zero, start
+zero: 0
+neg1: -1
+message: "Hello, world!\n\0"
+Write a function that takes an array of integers as a parameter. This represents the memory elements. The function +should interpret the sequence and return the output string. For this task, assume that there is no standard input. +
+ +## Instructions +
+ +
+ +## Tests +
+ +``` yml +tests: + - text: Subleq should be a function. + testString: assert(typeof Subleq == 'function', 'Subleq should be a function.'); + - text: Subleq([15, 17, -1, 17, -1, -1, 16, 1, -1, 16, 3, -1, 15, 15, 0, 0, -1, 72, 101, 108, 108, 111, 44, 32, 119, 111, 114, 108, 100, 33, 0]) should return a string. + testString: assert(typeof Subleq([15, 17, -1, 17, -1, -1, 16, 1, -1, 16, 3, -1, 15, 15, 0, 0, -1, 72, 101, 108, 108, 111, 44, 32, 119, 111, 114, 108, 100, 33, 0]) == 'string', 'Subleq([15, 17, -1, 17, -1, -1, 16, 1, -1, 16, 3, -1, 15, 15, 0, 0, -1, 72, 101, 108, 108, 111, 44, 32, 119, 111, 114, 108, 100, 33, 0]) should return a string.'); + - text: Subleq([15, 17, -1, 17, -1, -1, 16, 1, -1, 16, 3, -1, 15, 15, 0, 0, -1, 72, 101, 108, 108, 111, 44, 32, 119, 111, 114, 108, 100, 33, 0]) should return "Hello, world!". + testString: assert.equal(Subleq([15, 17, -1, 17, -1, -1, 16, 1, -1, 16, 3, -1, 15, 15, 0, 0, -1, 72, 101, 108, 108, 111, 44, 32, 119, 111, 114, 108, 100, 33, 0]), "Hello, world!", 'Subleq([15, 17, -1, 17, -1, -1, 16, 1, -1, 16, 3, -1, 15, 15, 0, 0, -1, 72, 101, 108, 108, 111, 44, 32, 119, 111, 114, 108, 100, 33, 0]) should return "Hello, world!".'); +``` + +
+ +## Challenge Seed +
+
+ +```js +function Subleq (mem) { + // Good luck! +} +``` + +
+
+ +## Solution +
+ +```js +function Subleq (mem) { + var out = ""; + var instructionPointer = 0; + do { + var a = mem[instructionPointer]; + var b = mem[instructionPointer + 1]; + if (a === -1) {} else if (b === -1) { + out += String.fromCharCode(mem[a]); + } else { + mem[b] -= mem[a]; + if (mem[b] < 1) { + instructionPointer = mem[instructionPointer + 2]; + continue; + } + } + instructionPointer += 3; + } while ((instructionPointer >= 0)); + + return out; +} +``` + +
diff --git a/curriculum/challenges/english/08-coding-interview-prep/rosetta-code/sudoku.md b/curriculum/challenges/english/08-coding-interview-prep/rosetta-code/sudoku.md new file mode 100644 index 0000000000..1da23b47e4 --- /dev/null +++ b/curriculum/challenges/english/08-coding-interview-prep/rosetta-code/sudoku.md @@ -0,0 +1,236 @@ +--- +id: 5a23c84252665b21eecc803c +title: Sudoku +challengeType: 5 +--- + +## Description +
+Write a function to solve a partially filled-in normal 9x9 Sudoku grid and return the result. The blank fields are represented by 0s. +Algorithmics of Sudoku may help implement this. +
+ +## Instructions +
+ +
+ +## Tests +
+ +``` yml +tests: + - text: solveSudoku should be a function. + testString: assert(typeof solveSudoku == 'function', 'solveSudoku should be a function.'); + - text: solveSudoku([[8, 1, 9, -1, -1, 5, -1, -1, -1],[-1, -1, 2, -1, -1, -1, 7, 5, -1],[-1, 3, 7, 1, -1, 4, -1, 6, -1],[4, -1, -1, 5, 9, -1, 1, -1, -1],[7, -1, -1, 3, -1, 8, -1, -1, 2],[-1, -1, 3, -1, 6, 2, -1, -1, 7],[-1, 5, -1, 7, -1, 9, 2, 1, -1],[-1, 6, 4, -1, -1, -1, 9, -1, -1],[-1, -1, -1, 2, -1, -1, 4, 3, 8]]) should return a array. + testString: assert(Array.isArray(solveSudoku([[8, 1, 9, -1, -1, 5, -1, -1, -1], [-1, -1, 2, -1, -1, -1, 7, 5, -1], [-1, 3, 7, 1, -1, 4, -1, 6, -1], [4, -1, -1, 5, 9, -1, 1, -1, -1], [7, -1, -1, 3, -1, 8, -1, -1, 2], [-1, -1, 3, -1, 6, 2, -1, -1, 7], [-1, 5, -1, 7, -1, 9, 2, 1, -1], [-1, 6, 4, -1, -1, -1, 9, -1, -1], [-1, -1, -1, 2, -1, -1, 4, 3, 8]])), 'solveSudoku([[8, 1, 9, -1, -1, 5, -1, -1, -1],[-1, -1, 2, -1, -1, -1, 7, 5, -1],[-1, 3, 7, 1, -1, 4, -1, 6, -1],[4, -1, -1, 5, 9, -1, 1, -1, -1],[7, -1, -1, 3, -1, 8, -1, -1, 2],[-1, -1, 3, -1, 6, 2, -1, -1, 7],[-1, 5, -1, 7, -1, 9, 2, 1, -1],[-1, 6, 4, -1, -1, -1, 9, -1, -1],[-1, -1, -1, 2, -1, -1, 4, 3, 8]]) should return a array.'); + - text: solveSudoku([[8, 1, 9, -1, -1, 5, -1, -1, -1],[-1, -1, 2, -1, -1, -1, 7, 5, -1],[-1, 3, 7, 1, -1, 4, -1, 6, -1],[4, -1, -1, 5, 9, -1, 1, -1, -1],[7, -1, -1, 3, -1, 8, -1, -1, 2],[-1, -1, 3, -1, 6, 2, -1, -1, 7],[-1, 5, -1, 7, -1, 9, 2, 1, -1],[-1, 6, 4, -1, -1, -1, 9, -1, -1],[-1, -1, -1, 2, -1, -1, 4, 3, 8]]) should return [[8, 1, 9, 6, 7, 5, 3, 2, 4],[6, 4, 2, 9, 8, 3, 7, 5, 1],[5, 3, 7, 1, 2, 4, 8, 6, 9],[4, 2, 6, 5, 9, 7, 1, 8, 3],[7, 9, 5, 3, 1, 8, 6, 4, 2],[1, 8, 3, 4, 6, 2, 5, 9, 7],[3, 5, 8, 7, 4, 9, 2, 1, 6],[2, 6, 4, 8, 3, 1, 9, 7, 5],[9, 7, 1, 2, 5, 6, 4, 3, 8]]. + testString: assert.deepEqual(solveSudoku([[8, 1, 9, -1, -1, 5, -1, -1, -1], [-1, -1, 2, -1, -1, -1, 7, 5, -1], [-1, 3, 7, 1, -1, 4, -1, 6, -1], [4, -1, -1, 5, 9, -1, 1, -1, -1], [7, -1, -1, 3, -1, 8, -1, -1, 2], [-1, -1, 3, -1, 6, 2, -1, -1, 7], [-1, 5, -1, 7, -1, 9, 2, 1, -1], [-1, 6, 4, -1, -1, -1, 9, -1, -1], [-1, -1, -1, 2, -1, -1, 4, 3, 8]]), [[8, 1, 9, 6, 7, 5, 3, 2, 4], [6, 4, 2, 9, 8, 3, 7, 5, 1], [5, 3, 7, 1, 2, 4, 8, 6, 9], [4, 2, 6, 5, 9, 7, 1, 8, 3], [7, 9, 5, 3, 1, 8, 6, 4, 2], [1, 8, 3, 4, 6, 2, 5, 9, 7], [3, 5, 8, 7, 4, 9, 2, 1, 6], [2, 6, 4, 8, 3, 1, 9, 7, 5], [9, 7, 1, 2, 5, 6, 4, 3, 8]], 'solveSudoku([[8, 1, 9, -1, -1, 5, -1, -1, -1],[-1, -1, 2, -1, -1, -1, 7, 5, -1],[-1, 3, 7, 1, -1, 4, -1, 6, -1],[4, -1, -1, 5, 9, -1, 1, -1, -1],[7, -1, -1, 3, -1, 8, -1, -1, 2],[-1, -1, 3, -1, 6, 2, -1, -1, 7],[-1, 5, -1, 7, -1, 9, 2, 1, -1],[-1, 6, 4, -1, -1, -1, 9, -1, -1],[-1, -1, -1, 2, -1, -1, 4, 3, 8]]) should return [[8, 1, 9, 6, 7, 5, 3, 2, 4],[6, 4, 2, 9, 8, 3, 7, 5, 1],[5, 3, 7, 1, 2, 4, 8, 6, 9],[4, 2, 6, 5, 9, 7, 1, 8, 3],[7, 9, 5, 3, 1, 8, 6, 4, 2],[1, 8, 3, 4, 6, 2, 5, 9, 7],[3, 5, 8, 7, 4, 9, 2, 1, 6],[2, 6, 4, 8, 3, 1, 9, 7, 5],[9, 7, 1, 2, 5, 6, 4, 3, 8]].'); + - text: solveSudoku([[5, 3, -1, -1, 2, 4, 7, -1, -1],[-1, -1, 2, -1, -1, -1, 8, -1, -1],[1, -1, -1, 7, -1, 3, 9, -1, 2],[-1, -1, 8, -1, 7, 2, -1, 4, 9],[-1, 2, -1, 9, 8, -1, -1, 7, -1],[7, 9, -1, -1, -1, -1, -1, 8, -1],[-1, -1, -1, -1, 3, -1, 5, -1, 6],[9, 6, -1, -1, 1, -1, 3, -1, -1],[-1, 5, -1, 6, 9, -1, -1, 1, -1]]) should return [[5, 3, 9, 8, 2, 4, 7, 6, 1],[6, 7, 2, 1, 5, 9, 8, 3, 4],[1, 8, 4, 7, 6, 3, 9, 5, 2],[3, 1, 8, 5, 7, 2, 6, 4, 9],[4, 2, 5, 9, 8, 6, 1, 7, 3],[7, 9, 6, 3, 4, 1, 2, 8, 5],[8, 4, 1, 2, 3, 7, 5, 9, 6],[9, 6, 7, 4, 1, 5, 3, 2, 8],[2, 5, 3, 6, 9, 8, 4, 1, 7]]. + testString: assert.deepEqual(solveSudoku([[5, 3, -1, -1, 2, 4, 7, -1, -1], [-1, -1, 2, -1, -1, -1, 8, -1, -1], [1, -1, -1, 7, -1, 3, 9, -1, 2], [-1, -1, 8, -1, 7, 2, -1, 4, 9], [-1, 2, -1, 9, 8, -1, -1, 7, -1], [7, 9, -1, -1, -1, -1, -1, 8, -1], [-1, -1, -1, -1, 3, -1, 5, -1, 6], [9, 6, -1, -1, 1, -1, 3, -1, -1], [-1, 5, -1, 6, 9, -1, -1, 1, -1]]), [[5, 3, 9, 8, 2, 4, 7, 6, 1], [6, 7, 2, 1, 5, 9, 8, 3, 4], [1, 8, 4, 7, 6, 3, 9, 5, 2], [3, 1, 8, 5, 7, 2, 6, 4, 9], [4, 2, 5, 9, 8, 6, 1, 7, 3], [7, 9, 6, 3, 4, 1, 2, 8, 5], [8, 4, 1, 2, 3, 7, 5, 9, 6], [9, 6, 7, 4, 1, 5, 3, 2, 8], [2, 5, 3, 6, 9, 8, 4, 1, 7]], 'solveSudoku([[5, 3, -1, -1, 2, 4, 7, -1, -1],[-1, -1, 2, -1, -1, -1, 8, -1, -1],[1, -1, -1, 7, -1, 3, 9, -1, 2],[-1, -1, 8, -1, 7, 2, -1, 4, 9],[-1, 2, -1, 9, 8, -1, -1, 7, -1],[7, 9, -1, -1, -1, -1, -1, 8, -1],[-1, -1, -1, -1, 3, -1, 5, -1, 6],[9, 6, -1, -1, 1, -1, 3, -1, -1],[-1, 5, -1, 6, 9, -1, -1, 1, -1]]) should return [[5, 3, 9, 8, 2, 4, 7, 6, 1],[6, 7, 2, 1, 5, 9, 8, 3, 4],[1, 8, 4, 7, 6, 3, 9, 5, 2],[3, 1, 8, 5, 7, 2, 6, 4, 9],[4, 2, 5, 9, 8, 6, 1, 7, 3],[7, 9, 6, 3, 4, 1, 2, 8, 5],[8, 4, 1, 2, 3, 7, 5, 9, 6],[9, 6, 7, 4, 1, 5, 3, 2, 8],[2, 5, 3, 6, 9, 8, 4, 1, 7]].'); + - text: solveSudoku([[-1, -1, 3, -1, 2, -1, 6, -1, -1],[9, -1, -1, 3, -1, 5, -1, -1, 1],[-1, -1, 1, 8, -1, 6, 4, -1, -1],[-1, -1, 8, 1, -1, 2, 9, -1, -1],[7, -1, -1, -1, -1, -1, -1, -1, 8],[-1, -1, 6, 7, -1, 8, 2, -1, -1],[-1, -1, 2, 6, -1, 9, 5, -1, -1],[8, -1, -1, 2, -1, 3, -1, -1, 9],[-1, -1, 5, -1, 1, -1, 3, -1, -1]]) should return [[4, 8, 3, 9, 2, 1, 6, 5, 7],[9, 6, 7, 3, 4, 5, 8, 2, 1],[2, 5, 1, 8, 7, 6, 4, 9, 3],[5, 4, 8, 1, 3, 2, 9, 7, 6],[7, 2, 9, 5, 6, 4, 1, 3, 8],[1, 3, 6, 7, 9, 8, 2, 4, 5],[3, 7, 2, 6, 8, 9, 5, 1, 4],[8, 1, 4, 2, 5, 3, 7, 6, 9],[6, 9, 5, 4, 1, 7, 3, 8, 2]]. + testString: assert.deepEqual(solveSudoku([[-1, -1, 3, -1, 2, -1, 6, -1, -1], [9, -1, -1, 3, -1, 5, -1, -1, 1], [-1, -1, 1, 8, -1, 6, 4, -1, -1], [-1, -1, 8, 1, -1, 2, 9, -1, -1], [7, -1, -1, -1, -1, -1, -1, -1, 8], [-1, -1, 6, 7, -1, 8, 2, -1, -1], [-1, -1, 2, 6, -1, 9, 5, -1, -1], [8, -1, -1, 2, -1, 3, -1, -1, 9], [-1, -1, 5, -1, 1, -1, 3, -1, -1]]), [[4, 8, 3, 9, 2, 1, 6, 5, 7], [9, 6, 7, 3, 4, 5, 8, 2, 1], [2, 5, 1, 8, 7, 6, 4, 9, 3], [5, 4, 8, 1, 3, 2, 9, 7, 6], [7, 2, 9, 5, 6, 4, 1, 3, 8], [1, 3, 6, 7, 9, 8, 2, 4, 5], [3, 7, 2, 6, 8, 9, 5, 1, 4], [8, 1, 4, 2, 5, 3, 7, 6, 9], [6, 9, 5, 4, 1, 7, 3, 8, 2]], 'solveSudoku([[-1, -1, 3, -1, 2, -1, 6, -1, -1],[9, -1, -1, 3, -1, 5, -1, -1, 1],[-1, -1, 1, 8, -1, 6, 4, -1, -1],[-1, -1, 8, 1, -1, 2, 9, -1, -1],[7, -1, -1, -1, -1, -1, -1, -1, 8],[-1, -1, 6, 7, -1, 8, 2, -1, -1],[-1, -1, 2, 6, -1, 9, 5, -1, -1],[8, -1, -1, 2, -1, 3, -1, -1, 9],[-1, -1, 5, -1, 1, -1, 3, -1, -1]]) should return [[4, 8, 3, 9, 2, 1, 6, 5, 7],[9, 6, 7, 3, 4, 5, 8, 2, 1],[2, 5, 1, 8, 7, 6, 4, 9, 3],[5, 4, 8, 1, 3, 2, 9, 7, 6],[7, 2, 9, 5, 6, 4, 1, 3, 8],[1, 3, 6, 7, 9, 8, 2, 4, 5],[3, 7, 2, 6, 8, 9, 5, 1, 4],[8, 1, 4, 2, 5, 3, 7, 6, 9],[6, 9, 5, 4, 1, 7, 3, 8, 2]].'); +``` + +
+ +## Challenge Seed +
+
+ +```js +function solveSudoku (puzzle) { + // Good luck! +} +``` + +
+
+ +## Solution +
+ +```js +function solveSudoku (puzzle) { + var solution; + + class DoX { + constructor(V, H) { + this.V = V; + this.L = this; + this.R = this; + this.U = this; + this.D = this; + this.S = 1; + this.H = H || this; + H && (H.S += 1); + } + } + + const addRight = (e, n) => { + n.R = e.R; + n.L = e; + e.R.L = n; + return e.R = n; + }; + + const addBelow = (e, n) => { + n.D = e.D; + n.U = e; + e.D.U = n; + return e.D = n; + }; + + const search = function(h, s) { + if (h.R == h) { + printSol(s); + } else { + let c = chooseColumn(h); + cover(c); + for (let r = c.D; r != c; r = r.D) { + s.push(r); + for (let j = r.R; r != j; j = j.R) { + cover(j.H); + } + search(h, s); + r = s.pop(); + for (let j = r.R; j != r; j = j.R) { + uncover(j.H); + } + } + uncover(c); + } + }; + + const chooseColumn = h => { + let s = Number.POSITIVE_INFINITY; + let c = h; + for (let j = h.R; j != h; j = j.R) { + if (j.S < s) { + c = j; + s = j.S; + } + } + return c; + }; + + const cover = c => { + c.L.R = c.R; + c.R.L = c.L; + for (let i = c.D; i != c; i = i.D) { + for (let j = i.R; j != i; j = j.R) { + j.U.D = j.D; + j.D.U = j.U; + j.H.S = j.H.S - 1; + } + } + }; + + const uncover = c => { + for (let i = c.U; i != c; i = i.U) { + for (let j = i.L; i != j; j = j.L) { + j.H.S = j.H.S + 1; + j.U.D = j; + j.D.U = j; + } + } + c.L.R = c; + c.R.L = c; + }; + + const printSol = a => { + solution = a.reduce((p, c) => { + let [i, v] = c.V.split(':'); + p[i * 1] = v; + return p; + }, new Array(a.length).fill('.')); + }; + + const gridMeta = s => { + const g = s.split(''); + const cellCount = g.length; + const tokenCount = Math.sqrt(cellCount); + const N = Math.sqrt(tokenCount); + const g2D = g.map(e => isNaN(e * 1) ? + new Array(tokenCount).fill(1).map((_, i) => i + 1) : [e * 1]); + return [cellCount, N, tokenCount, g2D]; + }; + + const indexesN = n => i => { + let c = Math.floor(i / (n * n)); + i %= n * n; + return [c, i, Math.floor(c / n) * n + Math.floor(i / n)]; + }; + + const reduceGrid = puzString => { + + const [ + numCells, // The total number of cells in a grid (81 for a 9x9 grid) + N, // the 'n' value of the grid. (3 for a 9x9 grid) + U, // The total number of unique tokens to be placed. + g2D // A 2D array representation of the grid, with each element + // being an array of candidates for a cell. Known cells are + // single element arrays. + ] = gridMeta(puzString); + + const getIndex = indexesN(N); + + const headRow = new Array(4 * numCells) + .fill('') + .map((_, i) => new DoX(`H${i}`)); + + let H = new DoX('ROOT'); + headRow.reduce((p, c) => addRight(p, c), H); + + for (let i = 0; i < numCells; i++) { + const [ri, ci, bi] = getIndex(i); + g2D[i].forEach(num => { + let id = `${i}:${num}`; + let candIdx = num - 1; + + // The 4 columns that we will populate. + const A = headRow[i]; + const B = headRow[numCells + candIdx + (ri * U)]; + const C = headRow[(numCells * 2) + candIdx + (ci * U)]; + const D = headRow[(numCells * 3) + candIdx + (bi * U)]; + + // The Row-Column Constraint + let rcc = addBelow(A.U, new DoX(id, A)); + + // The Row-Number Constraint + let rnc = addBelow(B.U, addRight(rcc, new DoX(id, B))); + + // The Column-Number Constraint + let cnc = addBelow(C.U, addRight(rnc, new DoX(id, C))); + + // The Block-Number Constraint + addBelow(D.U, addRight(cnc, new DoX(id, D))); + }); + } + search(H, []); + }; + + var stringPuzzle = ""; + + for (var i = 0; i < puzzle.length; i++) { + puzzle[i].forEach(function(e) { + if (e == -1) + stringPuzzle += "."; + else + stringPuzzle += e; + }) + } + + reduceGrid(stringPuzzle) + + var result = []; + + for (var i = 0; i < 9; i++) { + result.push(solution.slice(i * 9, (i + 1) * 9).map(e => parseInt(e))) + } + + return result; +} +``` + +
\ No newline at end of file diff --git a/curriculum/challenges/english/08-coding-interview-prep/rosetta-code/sum-digits-of-an-integer.md b/curriculum/challenges/english/08-coding-interview-prep/rosetta-code/sum-digits-of-an-integer.md new file mode 100644 index 0000000000..24a5dc19b4 --- /dev/null +++ b/curriculum/challenges/english/08-coding-interview-prep/rosetta-code/sum-digits-of-an-integer.md @@ -0,0 +1,72 @@ +--- +id: 5a23c84252665b21eecc803f +title: Sum digits of an integer +challengeType: 5 +--- + +## Description +
+Write a function that takes a string as a parameter. This string represents a number that can be in any base (less than 37) and return the sum of its digits. + +
+ +## Instructions +
+ +
+ +## Tests +
+ +``` yml +tests: + - text: sumDigits should be a function. + testString: assert(typeof sumDigits == 'function', 'sumDigits should be a function.'); + - text: sumDigits("1") should return a number. + testString: assert(typeof sumDigits("1") == 'number', 'sumDigits("1") should return a number.'); + - text: sumDigits("1") should return 1. + testString: assert.equal(sumDigits("1"), 1, 'sumDigits("1") should return 1.'); + - text: sumDigits("12345") should return 15. + testString: assert.equal(sumDigits("12345"), 15, 'sumDigits("12345") should return 15.'); + - text: sumDigits("254") should return 11. + testString: assert.equal(sumDigits("254"), 11, 'sumDigits("254") should return 11.'); + - text: sumDigits("fe") should return 29. + testString: assert.equal(sumDigits("fe"), 29, 'sumDigits("fe") should return 29.'); + - text: sumDigits("f0e") should return 29. + testString: assert.equal(sumDigits("f0e"), 29, 'sumDigits("f0e") should return 29.'); + - text: sumDigits("999ABCXYZ") should return 162. + testString: assert.equal(sumDigits("999ABCXYZ"), 162, 'sumDigits("999ABCXYZ") should return 162.'); +``` + +
+ +## Challenge Seed +
+
+ +```js +function sumDigits (n) { + // Good luck! +} +``` + +
+
+ +## Solution +
+ +```js +function sumDigits (n) { + n += '' + for (var s=0, i=0, e=n.length; i diff --git a/curriculum/challenges/english/08-coding-interview-prep/rosetta-code/sum-multiples-of-3-and-5.md b/curriculum/challenges/english/08-coding-interview-prep/rosetta-code/sum-multiples-of-3-and-5.md new file mode 100644 index 0000000000..ce84fe3a40 --- /dev/null +++ b/curriculum/challenges/english/08-coding-interview-prep/rosetta-code/sum-multiples-of-3-and-5.md @@ -0,0 +1,66 @@ +--- +id: 5a23c84252665b21eecc8040 +title: Sum multiples of 3 and 5 +challengeType: 5 +--- + +## Description +
+The objective is to write a function that finds the sum of all positive multiples of 3 or 5 below n. +
+ +## Instructions +
+ +
+ +## Tests +
+ +``` yml +tests: + - text: sumMults should be a function. + testString: assert(typeof sumMults == 'function', 'sumMults should be a function.'); + - text: sumMults(10) should return a number. + testString: assert(typeof sumMults(10) == 'number', 'sumMults(10) should return a number.'); + - text: sumMults(10) should return 23. + testString: assert.equal(sumMults(10), 23, 'sumMults(10) should return 23.'); + - text: sumMults(100) should return 2318. + testString: assert.equal(sumMults(100), 2318, 'sumMults(100) should return 2318.'); + - text: sumMults(1000) should return 233168. + testString: assert.equal(sumMults(1000), 233168, 'sumMults(1000) should return 233168.'); + - text: sumMults(10000) should return 23331668. + testString: assert.equal(sumMults(10000), 23331668, 'sumMults(10000) should return 23331668.'); + - text: sumMults(100000) should return 2333316668. + testString: assert.equal(sumMults(100000), 2333316668, 'sumMults(100000) should return 2333316668.'); +``` + +
+ +## Challenge Seed +
+
+ +```js +function sumMults (n) { + // Good luck! +} +``` + +
+
+ +## Solution +
+ +```js +function sumMults (n) { + var sum = 0; + for (var i = 1; i < n; i++) { + if (i % 3 == 0 || i % 5 == 0) sum += i; + } + return sum; +} +``` + +
\ No newline at end of file diff --git a/curriculum/challenges/english/08-coding-interview-prep/rosetta-code/sum-of-a-series.md b/curriculum/challenges/english/08-coding-interview-prep/rosetta-code/sum-of-a-series.md new file mode 100644 index 0000000000..28e73ce66b --- /dev/null +++ b/curriculum/challenges/english/08-coding-interview-prep/rosetta-code/sum-of-a-series.md @@ -0,0 +1,75 @@ +--- +id: 5a23c84252665b21eecc8041 +title: Sum of a series +challengeType: 5 +--- + +## Description +
+Compute the nth term of a series, i.e. the sum of the n first terms of the corresponding sequence. +Informally this value, or its limit when n tends to infinity, is also called the sum of the series, thus the title of this task. +For this task, use: +$S_n = \sum_{k=1}^n \frac{1}{k^2}$ +and compute $S_{1000}$ +This approximates the zeta function for S=2, whose exact value +$\zeta(2) = {\pi^2\over 6}$ +is the solution of the Basel problem. +Write a function that take $a$ and $b$ as parameters and returns the sum of $a^{th}$ to $b^{th}$ members of the sequence. +
+ +## Instructions +
+ +
+ +## Tests +
+ +``` yml +tests: + - text: sum should be a function. + testString: assert(typeof sum == 'function', 'sum should be a function.'); + - text: sum(1, 100) should return a number. + testString: assert(typeof sum(1, 100) == 'number', 'sum(1, 100) should return a number.'); + - text: sum(1, 100) should return 1.6349839001848923. + testString: assert.equal(sum(1, 100), 1.6349839001848923, 'sum(1, 100) should return 1.6349839001848923.'); + - text: sum(33, 46) should return 0.009262256361481223. + testString: assert.equal(sum(33, 46), 0.009262256361481223, 'sum(33, 46) should return 0.009262256361481223.'); + - text: sum(21, 213) should return 0.044086990748706555. + testString: assert.equal(sum(21, 213), 0.044086990748706555, 'sum(21, 213) should return 0.044086990748706555.'); + - text: sum(11, 111) should return 0.08619778593108679. + testString: assert.equal(sum(11, 111), 0.08619778593108679, 'sum(11, 111) should return 0.08619778593108679.'); + - text: sum(1, 10) should return 1.5497677311665408. + testString: assert.equal(sum(1, 10), 1.5497677311665408, 'sum(1, 10) should return 1.5497677311665408.'); +``` + +
+ +## Challenge Seed +
+
+ +```js +function sum (a, b) { + // Good luck! +} +``` + +
+
+ +## Solution +
+ +```js +function sum (a, b) { + function fn(x) { + return 1 / (x * x) + } + var s = 0; + for (; a <= b; a++) s += fn(a); + return s; +} +``` + +
\ No newline at end of file diff --git a/curriculum/challenges/english/08-coding-interview-prep/rosetta-code/sum-of-squares.md b/curriculum/challenges/english/08-coding-interview-prep/rosetta-code/sum-of-squares.md new file mode 100644 index 0000000000..c6f73e4ade --- /dev/null +++ b/curriculum/challenges/english/08-coding-interview-prep/rosetta-code/sum-of-squares.md @@ -0,0 +1,68 @@ +--- +id: 5a23c84252665b21eecc8042 +title: Sum of squares +challengeType: 5 +--- + +## Description +
+Write a function to find the sum of squares of an array of integers. +
+ +## Instructions +
+ +
+ +## Tests +
+ +``` yml +tests: + - text: sumsq should be a function. + testString: assert(typeof sumsq == 'function', 'sumsq should be a function.'); + - text: sumsq([1, 2, 3, 4, 5]) should return a number. + testString: assert(typeof sumsq([1, 2, 3, 4, 5]) == 'number', 'sumsq([1, 2, 3, 4, 5]) should return a number.'); + - text: sumsq([1, 2, 3, 4, 5]) should return 55. + testString: assert.equal(sumsq([1, 2, 3, 4, 5]), 55, 'sumsq([1, 2, 3, 4, 5]) should return 55.'); + - text: sumsq([25, 32, 12, 7, 20]) should return 2242. + testString: assert.equal(sumsq([25, 32, 12, 7, 20]), 2242, 'sumsq([25, 32, 12, 7, 20]) should return 2242.'); + - text: sumsq([38, 45, 35, 8, 13]) should return 4927. + testString: assert.equal(sumsq([38, 45, 35, 8, 13]), 4927, 'sumsq([38, 45, 35, 8, 13]) should return 4927.'); + - text: sumsq([43, 36, 20, 34, 24]) should return 5277. + testString: assert.equal(sumsq([43, 36, 20, 34, 24]), 5277, 'sumsq([43, 36, 20, 34, 24]) should return 5277.'); + - text: sumsq([12, 33, 26, 18, 1, 16, 3]) should return 2499. + testString: assert.equal(sumsq([12, 33, 26, 18, 1, 16, 3]), 2499, 'sumsq([12, 33, 26, 18, 1, 16, 3]) should return 2499.'); +``` + +
+ +## Challenge Seed +
+
+ +```js +function sumsq (array) { + // Good luck! +} +``` + +
+
+ +## Solution +
+ +```js +function sumsq (array) { + var sum = 0; + var i, iLen; + + for (i = 0, iLen = array.length; i < iLen; i++) { + sum += array[i] * array[i]; + } + return sum; +} +``` + +
\ No newline at end of file diff --git a/curriculum/challenges/english/08-coding-interview-prep/rosetta-code/sum-to-100.md b/curriculum/challenges/english/08-coding-interview-prep/rosetta-code/sum-to-100.md new file mode 100644 index 0000000000..cc5471e3cb --- /dev/null +++ b/curriculum/challenges/english/08-coding-interview-prep/rosetta-code/sum-to-100.md @@ -0,0 +1,149 @@ +--- +id: 5a23c84252665b21eecc8043 +title: Sum to 100 +challengeType: 5 +--- + +## Description +
+Find solutions to the sum to one hundred puzzle. +Add (insert) the mathematical operators + or (plus or minus) before any of the digits in the decimal numeric string 123456789 such that the resulting mathematical expression adds up to a particular sum (in this iconic case, 100). +Example: +
123 + 4 - 5 + 67 - 89   =   100
+Write a function that takes a number as parameter. The function should return an array containing all solutions for the given number. The solutions should be strings representing the expressions. For example: "1+23-456+78-9". Note: sort the array before returning it. +
+ +## Instructions +
+ +
+ +## Tests +
+ +``` yml +tests: + - text: sumTo100 should be a function. + testString: assert(typeof sumTo100 == 'function', 'sumTo100 should be a function.'); + - text: sumTo100(199) should return a array. + testString: assert(Array.isArray(sumTo100(199)), 'sumTo100(199) should return a array.'); + - text: sumTo100(199) should return ["-1+2-3+45+67+89", "123-4+5+6+78-9", "123-4+56+7+8+9"]. + testString: assert.deepEqual(sumTo100(199), ["-1+2-3+45+67+89", "123-4+5+6+78-9", "123-4+56+7+8+9"], 'sumTo100(199) should return ["-1+2-3+45+67+89", "123-4+5+6+78-9", "123-4+56+7+8+9"].'); + - text: sumTo100(209) should return ["1+234+56+7-89"]. + testString: assert.deepEqual(sumTo100(209), ["1+234+56+7-89"], 'sumTo100(209) should return ["1+234+56+7-89"].'); + - text: sumTo100(243) should return ["-1-234+567-89", "-12+345+6-7-89", "123+45+6+78-9"]. + testString: assert.deepEqual(sumTo100(243), ["-1-234+567-89", "-12+345+6-7-89", "123+45+6+78-9"], 'sumTo100(243) should return ["-1-234+567-89", "-12+345+6-7-89", "123+45+6+78-9"].'); + - text: sumTo100(199) should return ["-1+2-3+45+67+89", "123-4+5+6+78-9", "123-4+56+7+8+9"]. + testString: assert.deepEqual(sumTo100(199), ["-1+2-3+45+67+89", "123-4+5+6+78-9", "123-4+56+7+8+9"], 'sumTo100(199) should return ["-1+2-3+45+67+89", "123-4+5+6+78-9", "123-4+56+7+8+9"].'); + - text: sumTo100(197) should return ["1-2-3+45+67+89", "12+34-5+67+89", "123+4-5+6+78-9"]. + testString: assert.deepEqual(sumTo100(197), ["1-2-3+45+67+89", "12+34-5+67+89", "123+4-5+6+78-9"], 'sumTo100(197) should return ["1-2-3+45+67+89", "12+34-5+67+89", "123+4-5+6+78-9"].'); +``` + +
+ +## Challenge Seed +
+
+ +```js +function sumTo100 (n) { + // Good luck! +} +``` + +
+
+ +## Solution +
+ +```js +function sumTo100 (n) { + var permutationsWithRepetition = function(n, as) { + return as.length > 0 ? + foldl1(curry(cartesianProduct)(as), replicate(n, as)) : []; + }; + + var cartesianProduct = function(xs, ys) { + return [].concat.apply([], xs.map(function(x) { + return [].concat.apply([], ys.map(function(y) { + return [ + [x].concat(y) + ]; + })); + })); + }; + + var curry = function(f) { + return function(a) { + return function(b) { + return f(a, b); + }; + }; + }; + + var flip = function(f) { + return function(a, b) { + return f.apply(null, [b, a]); + }; + }; + + var foldl1 = function(f, xs) { + return xs.length > 0 ? xs.slice(1) + .reduce(f, xs[0]) : []; + }; + + var replicate = function(n, a) { + var v = [a], + o = []; + if (n < 1) return o; + while (n > 1) { + if (n & 1) o = o.concat(v); + n >>= 1; + v = v.concat(v); + } + return o.concat(v); + }; + + var asSum = function(xs) { + var dct = xs.reduceRight(function(a, sign, i) { + var d = i + 1; // zero-based index to [1-9] positions + if (sign !== 0) { + // Sum increased, digits cleared + return { + digits: [], + n: a.n + sign * parseInt([d].concat(a.digits) + .join(''), 10) + }; + } else return { // Digits extended, sum unchanged + digits: [d].concat(a.digits), + n: a.n + }; + }, { + digits: [], + n: 0 + }); + return dct.n + ( + dct.digits.length > 0 ? parseInt(dct.digits.join(''), 10) : 0 + ); + }; + + var asString = function(xs) { + var ns = xs.reduce(function(a, sign, i) { + var d = (i + 1) + .toString(); + return sign === 0 ? a + d : a + (sign > 0 ? '+' : '-') + d; + }, ''); + + return ns[0] === '+' ? tail(ns) : ns; + }; + + var universe = permutationsWithRepetition(9, [0, 1, -1]) + .filter(function(x) { + return x[0] !== 1 && asSum(x) === n; + }).map(asString); + return universe.sort() +} +``` + +
diff --git a/curriculum/challenges/english/08-coding-interview-prep/rosetta-code/sutherland-hodgman-polygon-clipping.md b/curriculum/challenges/english/08-coding-interview-prep/rosetta-code/sutherland-hodgman-polygon-clipping.md new file mode 100644 index 0000000000..1cde765c84 --- /dev/null +++ b/curriculum/challenges/english/08-coding-interview-prep/rosetta-code/sutherland-hodgman-polygon-clipping.md @@ -0,0 +1,97 @@ +--- +id: 5a23c84252665b21eecc8045 +title: Sutherland-Hodgman polygon clipping +challengeType: 5 +--- + +## Description +
+The Sutherland-Hodgman clipping algorithm finds the polygon that is the intersection between an arbitrary polygon (the “subject polygon”) and a convex polygon (the “clip polygon”). +It is used in computer graphics (especially 2D graphics) to reduce the complexity of a scene being displayed by eliminating parts of a polygon that do not need to be displayed. +Take the closed polygon defined by the points: +$[(50, 150), (200, 50), (350, 150), (350, 300), (250, 300), (200, 250), (150, 350), (100, 250), (100, 200)]$ +and clip it by the rectangle defined by the points: +$[(100, 100), (300, 100), (300, 300), (100, 300)]$ +Write a function that takes 2 arrays as parameters. The first array contains the points of the subject polygon and the second array contains the points of the clipping polygon. The function should return an array containing the points of the clipped polygon. Each number should be rounded to 3 decimal places. +
+ +## Instructions +
+ +
+ +## Tests +
+ +``` yml +tests: + - text: clip should be a function. + testString: assert(typeof clip == 'function', 'clip should be a function.'); + - text: clip([[50, 150], [200, 50], [350, 150], [350, 300], [250, 300], [200, 250], [150, 350], [100, 250], [100, 200]], [[100, 100], [300, 100], [300, 300], [100, 300]]) should return a array. + testString: assert(Array.isArray(clip([[50, 150], [200, 50], [350, 150], [350, 300], [250, 300], [200, 250], [150, 350], [100, 250], [100, 200]], [[100, 100], [300, 100], [300, 300], [100, 300]])), 'clip([[50, 150], [200, 50], [350, 150], [350, 300], [250, 300], [200, 250], [150, 350], [100, 250], [100, 200]], [[100, 100], [300, 100], [300, 300], [100, 300]]) should return a array.'); + - text: clip([[50, 150], [200, 50], [350, 150], [350, 300], [250, 300], [200, 250], [150, 350], [100, 250], [100, 200]], [[100, 100], [300, 100], [300, 300], [100, 300]]) should return [[100, 116.667], [125, 100], [275, 100], [300, 116.667], [300, 300], [250, 300], [200, 250], [175, 300], [125, 300], [100, 250]]. + testString: assert.deepEqual(clip([[50, 150], [200, 50], [350, 150], [350, 300], [250, 300], [200, 250], [150, 350], [100, 250], [100, 200]], [[100, 100], [300, 100], [300, 300], [100, 300]]), [[100, 116.667], [125, 100], [275, 100], [300, 116.667], [300, 300], [250, 300], [200, 250], [175, 300], [125, 300], [100, 250]], 'clip([[50, 150], [200, 50], [350, 150], [350, 300], [250, 300], [200, 250], [150, 350], [100, 250], [100, 200]], [[100, 100], [300, 100], [300, 300], [100, 300]]) should return [[100, 116.667], [125, 100], [275, 100], [300, 116.667], [300, 300], [250, 300], [200, 250], [175, 300], [125, 300], [100, 250]].'); + - text: clip([[150, 200], [400, 450], [30, 50]], [[10, 10], [300, 200], [400, 600], [100, 300]]) should return [[150, 200], [350, 400], [348.611, 394.444], [30, 50]]. + testString: assert.deepEqual(clip([[150, 200], [400, 450], [30, 50]], [[10, 10], [300, 200], [400, 600], [100, 300]]), [[150, 200], [350, 400], [348.611, 394.444], [30, 50]], 'clip([[150, 200], [400, 450], [30, 50]], [[10, 10], [300, 200], [400, 600], [100, 300]]) should return [[150, 200], [350, 400], [348.611, 394.444], [30, 50]].'); + - text: clip([[250, 200], [100, 450], [130, 250]], [[50, 60], [100, 230], [400, 600], [100, 300]]) should return [[129.167, 329.167], [119.565, 319.565], [121.854, 304.305]]. + testString: assert.deepEqual(clip([[250, 200], [100, 450], [130, 250]], [[50, 60], [100, 230], [400, 600], [100, 300]]), [[129.167, 329.167], [119.565, 319.565], [121.854, 304.305]], 'clip([[250, 200], [100, 450], [130, 250]], [[50, 60], [100, 230], [400, 600], [100, 300]]) should return [[129.167, 329.167], [119.565, 319.565], [121.854, 304.305]].'); +``` + +
+ +## Challenge Seed +
+
+ +```js +function clip (subjectPolygon, clipPolygon) { + // Good luck! +} +``` + +
+
+ +## Solution +
+ +```js +function clip (subjectPolygon, clipPolygon) { + var cp1, cp2, s, e, i, j; + var inside = function(p) { + return (cp2[0] - cp1[0]) * (p[1] - cp1[1]) > (cp2[1] - cp1[1]) * (p[0] - cp1[0]); + }; + var intersection = function() { + var dc = [cp1[0] - cp2[0], cp1[1] - cp2[1]], + dp = [s[0] - e[0], s[1] - e[1]], + n1 = cp1[0] * cp2[1] - cp1[1] * cp2[0], + n2 = s[0] * e[1] - s[1] * e[0], + n3 = 1.0 / (dc[0] * dp[1] - dc[1] * dp[0]); + return [(n1 * dp[0] - n2 * dc[0]) * n3, (n1 * dp[1] - n2 * dc[1]) * n3]; + }; + var outputList = subjectPolygon; + cp1 = clipPolygon[clipPolygon.length - 1]; + for (j in clipPolygon) { + var cp2 = clipPolygon[j]; + var inputList = outputList; + outputList = []; + s = inputList[inputList.length - 1]; //last on the input list + for (i in inputList) { + var e = inputList[i]; + if (inside(e)) { + if (!inside(s)) { + outputList.push(intersection()); + } + outputList.push(e); + } else if (inside(s)) { + outputList.push(intersection()); + } + s = e; + } + cp1 = cp2; + } + return outputList.map(e => e.map(f => Math.round(f * 1000) / 1000)); +} +``` + +
\ No newline at end of file diff --git a/curriculum/challenges/english/08-coding-interview-prep/rosetta-code/symmetric-difference.md b/curriculum/challenges/english/08-coding-interview-prep/rosetta-code/symmetric-difference.md new file mode 100644 index 0000000000..a98889f1fb --- /dev/null +++ b/curriculum/challenges/english/08-coding-interview-prep/rosetta-code/symmetric-difference.md @@ -0,0 +1,82 @@ +--- +id: 5a23c84252665b21eecc8046 +title: Symmetric difference +challengeType: 5 +--- + +## Description +
+Given two sets A and B, compute $(A \setminus B) \cup (B \setminus A).$ +That is, enumerate the items that are in A or B but not both. This set is called the symmetric difference of A and B. +In other words: $(A \cup B) \setminus (A \cap B)$ (the set of items that are in at least one of A or B minus the set of items that are in both A and B). +Write a function that takes two arrays as parameters and returns the symmetric difference. Note: Sort the resultant array before returning it. +
+ +## Instructions +
+ +
+ +## Tests +
+ +``` yml +tests: + - text: symmetricDifference should be a function. + testString: assert(typeof symmetricDifference == 'function', 'symmetricDifference should be a function.'); + - text: symmetricDifference(["John", "Bob", "Mary", "Serena"], ["Jim", "Mary", "John", "Bob"]) should return a array. + testString: assert(Array.isArray(symmetricDifference(["John", "Bob", "Mary", "Serena"], ["Jim", "Mary", "John", "Bob"])), 'symmetricDifference(["John", "Bob", "Mary", "Serena"], ["Jim", "Mary", "John", "Bob"]) should return a array.'); + - text: symmetricDifference(["John", "Bob", "Mary", "Serena"], ["Jim", "Mary", "John", "Bob"]) should return ["Jim", "Serena"]. + testString: assert.deepEqual(symmetricDifference(["John", "Bob", "Mary", "Serena"], ["Jim", "Mary", "John", "Bob"]), ["Jim", "Serena"], 'symmetricDifference(["John", "Bob", "Mary", "Serena"], ["Jim", "Mary", "John", "Bob"]) should return ["Jim", "Serena"].'); + - text: symmetricDifference([1, 2, 3], [3, 4]) should return [1, 2, 4]. + testString: assert.deepEqual(symmetricDifference([1, 2, 3], [3, 4]), [1, 2, 4], 'symmetricDifference([1, 2, 3], [3, 4]) should return [1, 2, 4].'); + - text: symmetricDifference([1, 2, 3, 4, 5], [3, 4, 8, 7]) should return [1, 2, 5, 7, 8]. + testString: assert.deepEqual(symmetricDifference([1, 2, 3, 4, 5], [3, 4, 8, 7]), [1, 2, 5, 7, 8], 'symmetricDifference([1, 2, 3, 4, 5], [3, 4, 8, 7]) should return [1, 2, 5, 7, 8].'); + - text: symmetricDifference([1, 2, 3, 4, 5, 6, 7, 8], [1, 3, 5, 6, 7, 8, 9]) should return [2, 4, 9]. + testString: assert.deepEqual(symmetricDifference([1, 2, 3, 4, 5, 6, 7, 8], [1, 3, 5, 6, 7, 8, 9]), [2, 4, 9], 'symmetricDifference([1, 2, 3, 4, 5, 6, 7, 8], [1, 3, 5, 6, 7, 8, 9]) should return [2, 4, 9].'); + - text: symmetricDifference([1, 2, 4, 7, 9], [2, 3, 7, 8, 9]) should return [1, 3, 4, 8]. + testString: assert.deepEqual(symmetricDifference([1, 2, 4, 7, 9], [2, 3, 7, 8, 9]), [1, 3, 4, 8], 'symmetricDifference([1, 2, 4, 7, 9], [2, 3, 7, 8, 9]) should return [1, 3, 4, 8].'); +``` + +
+ +## Challenge Seed +
+
+ +```js +function symmetricDifference (A, B) { + // Good luck! +} +``` + +
+
+ +## Solution +
+ +```js +function symmetricDifference (A, B) { + function relative_complement(A, B) { + return A.filter(function(elem) { + return B.indexOf(elem) == -1 + }); + } + + function unique(ary) { + var u = ary.concat().sort(); + for (var i = 1; i < u.length;) { + if (u[i - 1] === u[i]) + u.splice(i, 1); + else + i++; + } + return u; + } + + return unique(relative_complement(A, B).concat(relative_complement(B, A))).sort(); +} +``` + +
\ No newline at end of file