feat(interview-prep): Adding Rosetta Code problems (#34710)
This commit is contained in:
committed by
Kristofer Koishigawa
parent
fef4651da6
commit
c820cdab80
@ -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"
|
||||
|
@ -0,0 +1,98 @@
|
||||
---
|
||||
id: 5a23c84252665b21eecc8017
|
||||
title: Soundex
|
||||
challengeType: 5
|
||||
---
|
||||
|
||||
## Description
|
||||
<section id='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 <a href="https://en.wikipedia.org/wiki/soundex">the WP article</a>).
|
||||
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 <a href="http://rosettacode.org/wiki/https://www.archives.gov/research/census/soundex.html">https://www.archives.gov/research/census/soundex.html</a>. So check for instance if <b>Ashcraft</b> is coded to <b>A-261</b>.
|
||||
<ul><li>If a vowel (A, E, I, O, U) separates two consonants that have the same soundex code, the consonant to the right of the vowel is coded. Tymczak is coded as T-522 (T, 5 for the M, 2 for the C, Z ignored (see "Side-by-Side" rule above), 2 for the K). Since the vowel "A" separates the Z and K, the K is coded.</li>
|
||||
<li>If "H" or "W" separate two consonants that have the same soundex code, the consonant to the right of the vowel is not coded. Example: Ashcraft is coded A-261 (A, 2 for the S, C ignored, 6 for the R, 1 for the F). It is not coded A-226.</li></ul>
|
||||
Write a function that takes a string as a parameter and returns the encoded string.
|
||||
</section>
|
||||
|
||||
## Instructions
|
||||
<section id='instructions'>
|
||||
|
||||
</section>
|
||||
|
||||
## Tests
|
||||
<section id='tests'>
|
||||
|
||||
``` yml
|
||||
tests:
|
||||
- text: <code>soundex</code> should be a function.
|
||||
testString: assert(typeof soundex == 'function', '<code>soundex</code> should be a function.');
|
||||
- text: <code>soundex("Soundex")</code> should return a string.
|
||||
testString: assert(typeof soundex("Soundex") == 'string', '<code>soundex("Soundex")</code> should return a string.');
|
||||
- text: <code>soundex("Soundex")</code> should return <code>"S532"</code>.
|
||||
testString: assert.equal(soundex("Soundex"), "S532", '<code>soundex("Soundex")</code> should return <code>"S532"</code>.');
|
||||
- text: <code>soundex("Example")</code> should return <code>"E251"</code>.
|
||||
testString: assert.equal(soundex("Example"), "E251", '<code>soundex("Example")</code> should return <code>"E251"</code>.');
|
||||
- text: <code>soundex("Sownteks")</code> should return <code>"S532"</code>.
|
||||
testString: assert.equal(soundex("Sownteks"), "S532", '<code>soundex("Sownteks")</code> should return <code>"S532"</code>.');
|
||||
- text: <code>soundex("Ekzampul")</code> should return <code>"E251"</code>.
|
||||
testString: assert.equal(soundex("Ekzampul"), "E251", '<code>soundex("Ekzampul")</code> should return <code>"E251"</code>.');
|
||||
- text: <code>soundex("Euler")</code> should return <code>"E460"</code>.
|
||||
testString: assert.equal(soundex("Euler"), "E460", '<code>soundex("Euler")</code> should return <code>"E460"</code>.');
|
||||
- text: <code>soundex("Gauss")</code> should return <code>"G200"</code>.
|
||||
testString: assert.equal(soundex("Gauss"), "G200", '<code>soundex("Gauss")</code> should return <code>"G200"</code>.');
|
||||
- text: <code>soundex("Hilbert")</code> should return <code>"H416"</code>.
|
||||
testString: assert.equal(soundex("Hilbert"), "H416", '<code>soundex("Hilbert")</code> should return <code>"H416"</code>.');
|
||||
- text: <code>soundex("Knuth")</code> should return <code>"K530"</code>.
|
||||
testString: assert.equal(soundex("Knuth"), "K530", '<code>soundex("Knuth")</code> should return <code>"K530"</code>.');
|
||||
- text: <code>soundex("Lloyd")</code> should return <code>"L300"</code>.
|
||||
testString: assert.equal(soundex("Lloyd"), "L300", '<code>soundex("Lloyd")</code> should return <code>"L300"</code>.');
|
||||
- text: <code>soundex("Lukasiewicz")</code> should return <code>"L222"</code>.
|
||||
testString: assert.equal(soundex("Lukasiewicz"), "L222", '<code>soundex("Lukasiewicz")</code> should return <code>"L222"</code>.');
|
||||
```
|
||||
|
||||
</section>
|
||||
|
||||
## Challenge Seed
|
||||
<section id='challengeSeed'>
|
||||
<div id='js-seed'>
|
||||
|
||||
```js
|
||||
function soundex (s) {
|
||||
// Good luck!
|
||||
}
|
||||
```
|
||||
|
||||
</div>
|
||||
</section>
|
||||
|
||||
## Solution
|
||||
<section id='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();
|
||||
}
|
||||
```
|
||||
|
||||
</section>
|
@ -0,0 +1,81 @@
|
||||
---
|
||||
id: 5a23c84252665b21eecc801c
|
||||
title: Spiral matrix
|
||||
challengeType: 5
|
||||
---
|
||||
|
||||
## Description
|
||||
<section id='description'>
|
||||
Produce a spiral array.
|
||||
A <i>spiral array</i> is a square arrangement of the first N<sup>2</sup> natural numbers, where the numbers increase sequentially as you go around the edges of the array spiraling inwards.
|
||||
For example, given <b>5</b>, produce this array:
|
||||
<pre>
|
||||
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
|
||||
</pre>
|
||||
</section>
|
||||
|
||||
## Instructions
|
||||
<section id='instructions'>
|
||||
|
||||
</section>
|
||||
|
||||
## Tests
|
||||
<section id='tests'>
|
||||
|
||||
``` yml
|
||||
tests:
|
||||
- text: <code>spiralArray</code> should be a function.
|
||||
testString: assert(typeof spiralArray=='function','<code>spiralArray</code> should be a function.');
|
||||
- text: <code>spiralArray(3)</code> should return a array.
|
||||
testString: assert(Array.isArray(spiralArray(3)), '<code>spiralArray(3)</code> should return a array.');
|
||||
- text: <code>spiralArray(3)</code> should return <code>[[0, 1, 2],[7, 8, 3],[6, 5, 4]]</code>.
|
||||
testString: assert.deepEqual(spiralArray(3), [[0, 1, 2], [7, 8, 3], [6, 5, 4]], '<code>spiralArray(3)</code> should return <code>[[0, 1, 2],[7, 8, 3],[6, 5, 4]]</code>.');
|
||||
- text: <code>spiralArray(4)</code> should return <code>[[0, 1, 2, 3],[11, 12, 13, 4],[10, 15, 14, 5],[9, 8, 7, 6]]</code>.
|
||||
testString: assert.deepEqual(spiralArray(4), [[0, 1, 2, 3], [11, 12, 13, 4], [10, 15, 14, 5], [9, 8, 7, 6]], '<code>spiralArray(4)</code> should return <code>[[0, 1, 2, 3],[11, 12, 13, 4],[10, 15, 14, 5],[9, 8, 7, 6]]</code>.');
|
||||
- text: <code>spiralArray(5)</code> should return <code>[[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]]</code>.
|
||||
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]], '<code>spiralArray(5)</code> should return <code>[[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]]</code>.');
|
||||
```
|
||||
|
||||
</section>
|
||||
|
||||
## Challenge Seed
|
||||
<section id='challengeSeed'>
|
||||
<div id='js-seed'>
|
||||
|
||||
```js
|
||||
function spiralArray (n) {
|
||||
// Good luck!
|
||||
}
|
||||
```
|
||||
|
||||
</div>
|
||||
</section>
|
||||
|
||||
## Solution
|
||||
<section id='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;
|
||||
}
|
||||
```
|
||||
|
||||
</section>
|
@ -0,0 +1,96 @@
|
||||
---
|
||||
id: 5a23c84252665b21eecc801d
|
||||
title: Split a character string based on change of character
|
||||
challengeType: 5
|
||||
---
|
||||
|
||||
## Description
|
||||
<section id='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", "++", "///", "\" ]
|
||||
</section>
|
||||
|
||||
## Instructions
|
||||
<section id='instructions'>
|
||||
|
||||
</section>
|
||||
|
||||
## Tests
|
||||
<section id='tests'>
|
||||
|
||||
``` yml
|
||||
tests:
|
||||
- text: <code>split</code> should be a function.
|
||||
testString: assert(typeof split == 'function', '<code>split</code> should be a function.');
|
||||
- text: <code>split("hello")</code> should return a array.
|
||||
testString: assert(Array.isArray(split("hello")), '<code>split("hello")</code> should return a array.');
|
||||
- text: <code>split("hello")</code> should return <code>["h", "e", "ll", "o"]</code>.
|
||||
testString: assert.deepEqual(split("hello"), ["h", "e", "ll", "o"], '<code>split("hello")</code> should return <code>["h", "e", "ll", "o"]</code>.');
|
||||
- text: <code>split("commission")</code> should return <code>["c", "o", "mm", "i", "ss", "i", "o", "n"]</code>.
|
||||
testString: assert.deepEqual(split("commission"), ["c", "o", "mm", "i", "ss", "i", "o", "n"], '<code>split("commission")</code> should return <code>["c", "o", "mm", "i", "ss", "i", "o", "n"]</code>.');
|
||||
- text: <code>split("ssss----====llloooo")</code> should return <code>["ssss", "----", "====", "lll", "oooo"]</code>.
|
||||
testString: assert.deepEqual(split("ssss----====llloooo"), ["ssss", "----", "====", "lll", "oooo"], '<code>split("ssss----====llloooo")</code> should return <code>["ssss", "----", "====", "lll", "oooo"]</code>.');
|
||||
- text: <code>split("sssmmmaaammmaaat")</code> should return <code>["sss", "mmm", "aaa", "mmm", "aaa", "t"]</code>.
|
||||
testString: assert.deepEqual(split("sssmmmaaammmaaat"), ["sss", "mmm", "aaa", "mmm", "aaa", "t"], '<code>split("sssmmmaaammmaaat")</code> should return <code>["sss", "mmm", "aaa", "mmm", "aaa", "t"]</code>.');
|
||||
- text: <code>split("gHHH5YY++///\")</code> should return <code>["g", "HHH", "5", "YY", "++", "///", "\\"]</code>.
|
||||
testString: assert.deepEqual(split("gHHH5YY++///\\"), ["g", "HHH", "5", "YY", "++", "///", "\\"], '<code>split("gHHH5YY++///\")</code> should return <code>["g", "HHH", "5", "YY", "++", "///", "\\"]</code>.');
|
||||
```
|
||||
|
||||
</section>
|
||||
|
||||
## Challenge Seed
|
||||
<section id='challengeSeed'>
|
||||
<div id='js-seed'>
|
||||
|
||||
```js
|
||||
function split (str) {
|
||||
// Good luck!
|
||||
}
|
||||
```
|
||||
|
||||
</div>
|
||||
</section>
|
||||
|
||||
## Solution
|
||||
<section id='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)))
|
||||
}
|
||||
```
|
||||
|
||||
</section>
|
@ -0,0 +1,104 @@
|
||||
---
|
||||
id: 5a23c84252665b21eecc8024
|
||||
title: State name puzzle
|
||||
challengeType: 5
|
||||
---
|
||||
|
||||
## Description
|
||||
<section id='description'>
|
||||
<b>Background</b>
|
||||
This task is inspired by <a href="http://drdobbs.com/windows/198701685">Mark Nelson's DDJ Column "Wordplay"</a> 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 <i>different</i> U.S. States (so that all four state names differ from one another).
|
||||
What states are these?
|
||||
The problem was reissued on <a href="https://tapestry.tucson.az.us/twiki/bin/view/Main/StateNamesPuzzle">the Unicon Discussion Web</a> which includes several solutions with analysis. Several techniques may be helpful and you may wish to refer to <a href="https://en.wikipedia.org/wiki/Goedel_numbering">Gödel numbering</a>, <a href="https://en.wikipedia.org/wiki/Equivalence_relation">equivalence relations</a>, and <a href="https://en.wikipedia.org/wiki/Equivalence_classes">equivalence classes</a>. 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.
|
||||
<b>Task:</b>
|
||||
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.
|
||||
</section>
|
||||
|
||||
## Instructions
|
||||
<section id='instructions'>
|
||||
|
||||
</section>
|
||||
|
||||
## Tests
|
||||
<section id='tests'>
|
||||
|
||||
``` yml
|
||||
tests:
|
||||
- text: <code>solve</code> should be a function.
|
||||
testString: assert(typeof solve == 'function', '<code>solve</code> should be a function.');
|
||||
- text: <code>solve(["New Mexico", "New York", "North Carolina ", "North Dakota", "Ohio", "Oklahoma", "Oregon", "Pennsylvania", "Rhode Island", "South Carolina", "South Dakota"])</code> 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"])), '<code>solve(["New Mexico", "New York", "North Carolina ", "North Dakota", "Ohio", "Oklahoma", "Oregon", "Pennsylvania", "Rhode Island", "South Carolina", "South Dakota"])</code> should return a array.');
|
||||
- text: '<code>solve(["New Mexico", "New York", "North Carolina ", "North Dakota", "Ohio", "Oklahoma", "Oregon", "Pennsylvania", "Rhode Island", "South Carolina", "South Dakota"])</code> should return <code>[{ from: ["North Carolina ", "South Dakota"], to: ["North Dakota", "South Carolina"] }]</code>.'
|
||||
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"] }], '<code>solve(["New Mexico", "New York", "North Carolina ", "North Dakota", "Ohio", "Oklahoma", "Oregon", "Pennsylvania", "Rhode Island", "South Carolina", "South Dakota"])</code> should return <code>[{ from:["North Carolina ", "South Dakota"], to:["North Dakota", "South Carolina"] }]</code>.');
|
||||
- text: '<code>solve(["New York", "New Kory", "Wen Kory", "York New", "Kory New", "New Kory"])</code> should return <code>[{ 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"] }]</code>.'
|
||||
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"] }], '<code>solve(["New York", "New Kory", "Wen Kory", "York New", "Kory New", "New Kory"])</code> should return <code>[{ 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"] }]</code>.');
|
||||
```
|
||||
|
||||
</section>
|
||||
|
||||
## Challenge Seed
|
||||
<section id='challengeSeed'>
|
||||
<div id='js-seed'>
|
||||
|
||||
```js
|
||||
function solve (input) {
|
||||
// Good luck!
|
||||
}
|
||||
```
|
||||
|
||||
</div>
|
||||
</section>
|
||||
|
||||
## Solution
|
||||
<section id='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;
|
||||
}
|
||||
```
|
||||
|
||||
</section>
|
@ -0,0 +1,96 @@
|
||||
---
|
||||
id: 5a23c84252665b21eecc8028
|
||||
title: Stern-Brocot sequence
|
||||
challengeType: 5
|
||||
---
|
||||
|
||||
## Description
|
||||
<section id='description'>
|
||||
For this task, the Stern-Brocot sequence is to be generated by an algorithm similar to that employed in generating the
|
||||
<a href="http://rosettacode.org/wiki/Fibonacci sequence">Fibonacci sequence</a>.
|
||||
<ol>
|
||||
<li>The first and second members of the sequence are both 1:</li>
|
||||
<ul><li>1, 1</li></ul>
|
||||
<li>Start by considering the second member of the sequence</li>
|
||||
<li>Sum the considered member of the sequence and its precedent, (1 + 1) = 2, and append it to the end of the
|
||||
sequence:</li>
|
||||
<ul><li>1, 1, 2</li></ul>
|
||||
<li>Append the considered member of the sequence to the end of the sequence:</li>
|
||||
<ul><li>1, 1, 2, 1</li></ul>
|
||||
<li>Consider the next member of the series, (the third member i.e. 2)</li>
|
||||
<li>GOTO 3 </li>
|
||||
<ul>
|
||||
<li></li>
|
||||
<li> ─── Expanding another loop we get: ───</li>
|
||||
<li></li>
|
||||
</ul>
|
||||
<li>Sum the considered member of the sequence and its precedent, (2 + 1) = 3, and append it to the end of the
|
||||
sequence:</li>
|
||||
<ul><li>1, 1, 2, 1, 3</li></ul>
|
||||
<li>Append the considered member of the sequence to the end of the sequence:</li>
|
||||
<ul><li>1, 1, 2, 1, 3, 2</li></ul>
|
||||
<li>Consider the next member of the series, (the fourth member i.e. 1)</li>
|
||||
</ol>
|
||||
Create a function that returns the $ n^{th} $ member of the sequence using the method outlined above.
|
||||
</section>
|
||||
|
||||
## Instructions
|
||||
<section id='instructions'>
|
||||
|
||||
</section>
|
||||
|
||||
## Tests
|
||||
<section id='tests'>
|
||||
|
||||
``` yml
|
||||
tests:
|
||||
- text: <code>sternBrocot</code> should be a function.
|
||||
testString: assert(typeof sternBrocot == 'function', '<code>sternBrocot</code> should be a function.');
|
||||
- text: <code>sternBrocot(2)</code> should return a number.
|
||||
testString: assert(typeof sternBrocot(2) == 'number', '<code>sternBrocot(2)</code> should return a number.');
|
||||
- text: <code>sternBrocot(2)</code> should return <code>3</code>.
|
||||
testString: assert.equal(sternBrocot(2), 3, '<code>sternBrocot(2)</code> should return <code>3</code>.');
|
||||
- text: <code>sternBrocot(3)</code> should return <code>5</code>.
|
||||
testString: assert.equal(sternBrocot(3), 5, '<code>sternBrocot(3)</code> should return <code>5</code>.');
|
||||
- text: <code>sternBrocot(5)</code> should return <code>11</code>.
|
||||
testString: assert.equal(sternBrocot(5), 11, '<code>sternBrocot(5)</code> should return <code>11</code>.');
|
||||
- text: <code>sternBrocot(7)</code> should return <code>19</code>.
|
||||
testString: assert.equal(sternBrocot(7), 19, '<code>sternBrocot(7)</code> should return <code>19</code>.');
|
||||
- text: <code>sternBrocot(10)</code> should return <code>39</code>.
|
||||
testString: assert.equal(sternBrocot(10), 39, '<code>sternBrocot(10)</code> should return <code>39</code>.');
|
||||
```
|
||||
|
||||
</section>
|
||||
|
||||
## Challenge Seed
|
||||
<section id='challengeSeed'>
|
||||
<div id='js-seed'>
|
||||
|
||||
```js
|
||||
function sternBrocot (num) {
|
||||
// Good luck!
|
||||
}
|
||||
```
|
||||
|
||||
</div>
|
||||
</section>
|
||||
|
||||
## Solution
|
||||
<section id='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;
|
||||
}
|
||||
```
|
||||
|
||||
</section>
|
@ -0,0 +1,107 @@
|
||||
---
|
||||
id: 5a23c84252665b21eecc8029
|
||||
title: Straddling checkerboard
|
||||
challengeType: 5
|
||||
---
|
||||
|
||||
## Description
|
||||
<section id='description'>
|
||||
Implement functions to encrypt and decrypt a message using the <a href="https://en.wikipedia.org/wiki/Straddling_checkerboard">straddling checkerboard</a> 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.
|
||||
</section>
|
||||
|
||||
## Instructions
|
||||
<section id='instructions'>
|
||||
|
||||
</section>
|
||||
|
||||
## Tests
|
||||
<section id='tests'>
|
||||
|
||||
``` yml
|
||||
tests:
|
||||
- text: <code>straddle</code> should be a function.
|
||||
testString: assert(typeof straddle == 'function', '<code>straddle</code> should be a function.');
|
||||
- text: <code>straddle("One night-it was on the twentieth of March, 1888-I was returning.",["ESTONIA R", "BCDFGHJKLM", "PQUVWXYZ./"])</code> 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', '<code>straddle("One night-it was on the twentieth of March, 1888-I was returning.",["ESTONIA R", "BCDFGHJKLM", "PQUVWXYZ./"])</code> should return a string.');
|
||||
- text: <code>straddle("One night-it was on the twentieth of March, 1888-I was returning.",["ESTONIA R", "BCDFGHJKLM", "PQUVWXYZ./"])</code> should return <code>"34045747525284613427502840425027537379697175891898898898584619028294547488"</code>.
|
||||
testString: assert.equal(straddle("One night-it was on the twentieth of March, 1888-I was returning.", ["ESTONIA R", "BCDFGHJKLM", "PQUVWXYZ./"]), "34045747525284613427502840425027537379697175891898898898584619028294547488", '<code>straddle("One night-it was on the twentieth of March, 1888-I was returning.",["ESTONIA R", "BCDFGHJKLM", "PQUVWXYZ./"])</code> should return <code>"34045747525284613427502840425027537379697175891898898898584619028294547488"</code>.');
|
||||
- text: <code>straddle("One night-it was on the twentieth of March, 1888-I was returning",["HOL MES RT", "ABCDFGIJKN", "PQUVWXYZ./"])</code> should return <code>"139539363509369743061399059745399365901344308320791798798798367430685972839363935"</code>.
|
||||
testString: assert.equal(straddle("One night-it was on the twentieth of March, 1888-I was returning", ["HOL MES RT", "ABCDFGIJKN", "PQUVWXYZ./"]), "139539363509369743061399059745399365901344308320791798798798367430685972839363935", '<code>straddle("One night-it was on the twentieth of March, 1888-I was returning",["HOL MES RT", "ABCDFGIJKN", "PQUVWXYZ./"])</code> should return <code>"139539363509369743061399059745399365901344308320791798798798367430685972839363935"</code>.');
|
||||
- text: <code>straddle("Thecheckerboardcakerecipespecifies3largeeggsand2.25cupsofflour.",["ET AON RIS", "BCDFGHJKLM", "PQ/UVWXYZ."])</code> should return <code>"125021250212707204372221327070218600960021823809623283724002424935226226962262521636094232328463769"</code>.
|
||||
testString: assert.equal(straddle("Thecheckerboardcakerecipespecifies3largeeggsand2.25cupsofflour.", ["ET AON RIS", "BCDFGHJKLM", "PQ/UVWXYZ."]), "125021250212707204372221327070218600960021823809623283724002424935226226962262521636094232328463769", '<code>straddle("Thecheckerboardcakerecipespecifies3largeeggsand2.25cupsofflour.",["ET AON RIS", "BCDFGHJKLM", "PQ/UVWXYZ."])</code> should return <code>"125021250212707204372221327070218600960021823809623283724002424935226226962262521636094232328463769"</code>.');
|
||||
- text: <code>unstraddle</code> should be a function.
|
||||
testString: assert(typeof unstraddle == 'function', '<code>unstraddle</code> should be a function.');
|
||||
- text: <code>unstraddle("34045747525284613427502840425027537379697175891898898898584619028294547488",["ESTONIA R", "BCDFGHJKLM", "PQUVWXYZ./"])</code> should return a string.
|
||||
testString: assert(typeof unstraddle("34045747525284613427502840425027537379697175891898898898584619028294547488", ["ESTONIA R", "BCDFGHJKLM", "PQUVWXYZ./"]) == 'string', '<code>unstraddle("34045747525284613427502840425027537379697175891898898898584619028294547488",["ESTONIA R", "BCDFGHJKLM", "PQUVWXYZ./"])</code> should return a string.');
|
||||
- text: <code>unstraddle("34045747525284613427502840425027537379697175891898898898584619028294547488",["ESTONIA R", "BCDFGHJKLM", "PQUVWXYZ./"])</code> should return <code>"ONENIGHTITWASONTHETWENTIETHOFMARCH1888IWASRETURNING."</code>.
|
||||
testString: assert.equal(unstraddle("34045747525284613427502840425027537379697175891898898898584619028294547488", ["ESTONIA R", "BCDFGHJKLM", "PQUVWXYZ./"]), "ONENIGHTITWASONTHETWENTIETHOFMARCH1888IWASRETURNING.", '<code>unstraddle("34045747525284613427502840425027537379697175891898898898584619028294547488",["ESTONIA R", "BCDFGHJKLM", "PQUVWXYZ./"])</code> should return <code>"ONENIGHTITWASONTHETWENTIETHOFMARCH1888IWASRETURNING."</code>.');
|
||||
- text: <code>unstraddle("139539363509369743061399059745399365901344308320791798798798367430685972839363935",["HOL MES RT", "ABCDFGIJKN", "PQUVWXYZ./"])</code> should return <code>"ONENIGHTITWASONTHETWENTIETHOFMARCH1888IWASRETURNING"</code>.
|
||||
testString: assert.equal(unstraddle("139539363509369743061399059745399365901344308320791798798798367430685972839363935", ["HOL MES RT", "ABCDFGIJKN", "PQUVWXYZ./"]), "ONENIGHTITWASONTHETWENTIETHOFMARCH1888IWASRETURNING", '<code>unstraddle("139539363509369743061399059745399365901344308320791798798798367430685972839363935",["HOL MES RT", "ABCDFGIJKN", "PQUVWXYZ./"])</code> should return <code>"ONENIGHTITWASONTHETWENTIETHOFMARCH1888IWASRETURNING"</code>.');
|
||||
- text: <code>unstraddle("125021250212707204372221327070218600960021823809623283724002424935226226962262521636094232328463769",["ET AON RIS", "BCDFGHJKLM", "PQ/UVWXYZ."])</code> should return <code>"THECHECKERBOARDCAKERECIPESPECIFIES3LARGEEGGSAND2.25CUPSOFFLOUR."</code>.
|
||||
testString: assert.equal(unstraddle("125021250212707204372221327070218600960021823809623283724002424935226226962262521636094232328463769", ["ET AON RIS", "BCDFGHJKLM", "PQ/UVWXYZ."]), "THECHECKERBOARDCAKERECIPESPECIFIES3LARGEEGGSAND2.25CUPSOFFLOUR.", '<code>unstraddle("125021250212707204372221327070218600960021823809623283724002424935226226962262521636094232328463769",["ET AON RIS", "BCDFGHJKLM", "PQ/UVWXYZ."])</code> should return <code>"THECHECKERBOARDCAKERECIPESPECIFIES3LARGEEGGSAND2.25CUPSOFFLOUR."</code>.');
|
||||
```
|
||||
|
||||
</section>
|
||||
|
||||
## Challenge Seed
|
||||
<section id='challengeSeed'>
|
||||
<div id='js-seed'>
|
||||
|
||||
```js
|
||||
function straddle (message, alphabet) {
|
||||
// Good luck!
|
||||
}
|
||||
function unstraddle (message, alphabet) {
|
||||
// Good luck!
|
||||
}
|
||||
```
|
||||
|
||||
</div>
|
||||
</section>
|
||||
|
||||
## Solution
|
||||
<section id='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
|
||||
}
|
||||
```
|
||||
|
||||
</section>
|
@ -0,0 +1,82 @@
|
||||
---
|
||||
id: 5a23c84252665b21eecc802a
|
||||
title: Stream Merge
|
||||
challengeType: 5
|
||||
---
|
||||
|
||||
## Description
|
||||
<section id='description'>
|
||||
Write a function that takes multiple sorted arrays of items, and returns one array of sorted items.
|
||||
</section>
|
||||
|
||||
## Instructions
|
||||
<section id='instructions'>
|
||||
|
||||
</section>
|
||||
|
||||
## Tests
|
||||
<section id='tests'>
|
||||
|
||||
``` yml
|
||||
tests:
|
||||
- text: <code>mergeLists</code> should be a function.
|
||||
testString: assert(typeof mergeLists == 'function', '<code>mergeLists</code> should be a function.');
|
||||
- text: <code>mergeLists([[1, 3, 5, 9, 10], [2, 4, 6, 7, 8]])</code> should return a array.
|
||||
testString: assert(Array.isArray(mergeLists([[1, 3, 5, 9, 10], [2, 4, 6, 7, 8]])), '<code>mergeLists([[1, 3, 5, 9, 10], [2, 4, 6, 7, 8]])</code> should return a array.');
|
||||
- text: <code>mergeLists([[1, 3, 5, 9, 10], [2, 4, 6, 7, 8]])</code> should return <code>[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]</code>.
|
||||
testString: assert.deepEqual(mergeLists([[1, 3, 5, 9, 10], [2, 4, 6, 7, 8]]), [1, 2, 3, 4, 5, 6, 7, 8, 9, 10], '<code>mergeLists([[1, 3, 5, 9, 10], [2, 4, 6, 7, 8]])</code> should return <code>[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]</code>.');
|
||||
- text: <code>mergeLists([[1, 4, 7, 10], [2, 5, 8, 11], [3, 6, 9, 12]])</code> should return <code>[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]</code>.
|
||||
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], '<code>mergeLists([[1, 4, 7, 10], [2, 5, 8, 11], [3, 6, 9, 12]])</code> should return <code>[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]</code>.');
|
||||
- text: <code>mergeLists([[1, 3, 9, 14, 15, 17, 28], [7, 8, 14, 14, 23, 26, 28, 29, 30], [9, 23, 25, 29]])</code> should return <code>[1, 3, 7, 8, 9, 9, 14, 14, 14, 15, 17, 23, 23, 25, 26, 28, 28, 29, 29, 30]</code>.
|
||||
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], '<code>mergeLists([[1, 3, 9, 14, 15, 17, 28], [7, 8, 14, 14, 23, 26, 28, 29, 30], [9, 23, 25, 29]])</code> should return <code>[1, 3, 7, 8, 9, 9, 14, 14, 14, 15, 17, 23, 23, 25, 26, 28, 28, 29, 29, 30]</code>.');
|
||||
- text: <code>mergeLists([[3, 14, 15], [2, 17, 18], [], [2, 3, 5, 7]])</code> should return <code>[2, 2, 3, 3, 5, 7, 14, 15, 17, 18]</code>.
|
||||
testString: assert.deepEqual(mergeLists([[3, 14, 15], [2, 17, 18], [], [2, 3, 5, 7]]), [2, 2, 3, 3, 5, 7, 14, 15, 17, 18], '<code>mergeLists([[3, 14, 15], [2, 17, 18], [], [2, 3, 5, 7]])</code> should return <code>[2, 2, 3, 3, 5, 7, 14, 15, 17, 18]</code>.');
|
||||
- text: <code>mergeLists([[1, 19, 1999], [17, 33, 2999, 3000], [8, 500, 3999]])</code> should return <code>[1, 8, 17, 19, 33, 500, 1999, 2999, 3000, 3999]</code>.
|
||||
testString: assert.deepEqual(mergeLists([[1, 19, 1999], [17, 33, 2999, 3000], [8, 500, 3999]]), [1, 8, 17, 19, 33, 500, 1999, 2999, 3000, 3999], '<code>mergeLists([[1, 19, 1999], [17, 33, 2999, 3000], [8, 500, 3999]])</code> should return <code>[1, 8, 17, 19, 33, 500, 1999, 2999, 3000, 3999]</code>.');
|
||||
```
|
||||
|
||||
</section>
|
||||
|
||||
## Challenge Seed
|
||||
<section id='challengeSeed'>
|
||||
<div id='js-seed'>
|
||||
|
||||
```js
|
||||
function mergeLists (lists) {
|
||||
// Good luck!
|
||||
}
|
||||
```
|
||||
|
||||
</div>
|
||||
</section>
|
||||
|
||||
## Solution
|
||||
<section id='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;
|
||||
}
|
||||
```
|
||||
|
||||
</section>
|
@ -0,0 +1,69 @@
|
||||
---
|
||||
id: 5a23c84252665b21eecc8036
|
||||
title: Strip control codes and extended characters from a string
|
||||
challengeType: 5
|
||||
---
|
||||
|
||||
## Description
|
||||
<section id='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.
|
||||
</section>
|
||||
|
||||
## Instructions
|
||||
<section id='instructions'>
|
||||
|
||||
</section>
|
||||
|
||||
## Tests
|
||||
<section id='tests'>
|
||||
|
||||
``` yml
|
||||
tests:
|
||||
- text: <code>strip</code> should be a function.
|
||||
testString: assert(typeof strip == 'function', '<code>strip</code> should be a function.');
|
||||
- text: <code>strip("abc")</code> should return a string.
|
||||
testString: assert(typeof strip("\ba\\x00b\n\rc\fd\xc3") == 'string', '<code>strip("abc")</code> should return a string.');
|
||||
- text: <code>strip("\\ba\\x00b\\n\\rc\\fd\\xc3")</code> should return <code>"abcd"</code>.
|
||||
testString: assert.equal(strip("\ba\x00b\n\rc\fd\xc3"), "abcd", '<code>strip("\\ba\\x00b\\n\\rc\\fd\\xc3")</code> should return <code>"abcd"</code>.');
|
||||
- text: <code>strip("\\u0000\\n abc\\u00E9def\\u007F")</code> should return <code>" abcdef"</code>.
|
||||
testString: assert.equal(strip("\u0000\n abc\u00E9def\u007F"), " abcdef", '<code>strip("\\u0000\\n abc\\u00E9def\\u007F")</code> should return <code>" abcdef"</code>.');
|
||||
- text: <code>strip("a\\n\\tb\\u2102d\\u2147f")</code> should return <code>"abdf"</code>.
|
||||
testString: assert.equal(strip("a\n\tb\u2102d\u2147f"), "abdf", '<code>strip("a\\n\\tb\\u2102d\\u2147f")</code> should return <code>"abdf"</code>.');
|
||||
- text: <code>strip("Français.")</code> should return <code>"Franais."</code>.
|
||||
testString: assert.equal(strip("Français."), "Franais.", '<code>strip("Français.")</code> should return <code>"Franais."</code>.');
|
||||
- text: <code>strip("123\\tabc\\u0007DEF\\u007F+-*/€æŧðłþ")</code> should return <code>"123abcDEF+-*/"</code>.
|
||||
testString: assert.equal(strip("123\tabc\u0007DEF\u007F+-*/€æŧðłþ"), "123abcDEF+-*/", '<code>strip("123\\tabc\\u0007DEF\\u007F+-*/€æŧðłþ")</code> should return <code>"123abcDEF+-*/"</code>.');
|
||||
```
|
||||
|
||||
</section>
|
||||
|
||||
## Challenge Seed
|
||||
<section id='challengeSeed'>
|
||||
<div id='js-seed'>
|
||||
|
||||
```js
|
||||
function strip (s) {
|
||||
// Good luck!
|
||||
}
|
||||
```
|
||||
|
||||
</div>
|
||||
</section>
|
||||
|
||||
## Solution
|
||||
<section id='solution'>
|
||||
|
||||
```js
|
||||
function strip (s) {
|
||||
return s.split('').filter(function(x) {
|
||||
var n = x.charCodeAt(0);
|
||||
|
||||
return 31 < n && 127 > n;
|
||||
}).join('');
|
||||
}
|
||||
```
|
||||
|
||||
</section>
|
@ -0,0 +1,110 @@
|
||||
---
|
||||
id: 5a23c84252665b21eecc8038
|
||||
title: Subleq
|
||||
challengeType: 5
|
||||
---
|
||||
|
||||
## Description
|
||||
<section id='description'>
|
||||
<a href="http://rosettacode.org/wiki/eso:Subleq">Subleq</a> is an example of a <a href="https://en.wikipedia.org/wiki/One_instruction_set_computer">One-Instruction
|
||||
Set Computer (OISC)</a>.
|
||||
It is named after its only instruction, which is <b>SU</b>btract and <b>B</b>ranch if <b>L</b>ess than or <b>EQ</b>ual
|
||||
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:
|
||||
<ol>
|
||||
<li>Let A, B, and C be the value stored in the three consecutive words in memory starting at the instruction pointer.</li>
|
||||
<li>Advance the instruction pointer 3 words to point at the address after the one containing C.</li>
|
||||
<li>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.</li>
|
||||
<li>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.</li>
|
||||
<li>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.</li>
|
||||
<li>If the instruction pointer becomes negative, execution halts.</li>
|
||||
</ol>
|
||||
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.)
|
||||
<pre>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</pre>
|
||||
Which corresponds to something like this in a hypothetical assembler language:
|
||||
<pre>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"</pre>
|
||||
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.
|
||||
</section>
|
||||
|
||||
## Instructions
|
||||
<section id='instructions'>
|
||||
|
||||
</section>
|
||||
|
||||
## Tests
|
||||
<section id='tests'>
|
||||
|
||||
``` yml
|
||||
tests:
|
||||
- text: <code>Subleq</code> should be a function.
|
||||
testString: assert(typeof Subleq == 'function', '<code>Subleq</code> should be a function.');
|
||||
- text: <code>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])</code> 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', '<code>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])</code> should return a string.');
|
||||
- text: <code>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])</code> should return <code>"Hello, world!"</code>.
|
||||
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!", '<code>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])</code> should return <code>"Hello, world!"</code>.');
|
||||
```
|
||||
|
||||
</section>
|
||||
|
||||
## Challenge Seed
|
||||
<section id='challengeSeed'>
|
||||
<div id='js-seed'>
|
||||
|
||||
```js
|
||||
function Subleq (mem) {
|
||||
// Good luck!
|
||||
}
|
||||
```
|
||||
|
||||
</div>
|
||||
</section>
|
||||
|
||||
## Solution
|
||||
<section id='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;
|
||||
}
|
||||
```
|
||||
|
||||
</section>
|
@ -0,0 +1,236 @@
|
||||
---
|
||||
id: 5a23c84252665b21eecc803c
|
||||
title: Sudoku
|
||||
challengeType: 5
|
||||
---
|
||||
|
||||
## Description
|
||||
<section id='description'>
|
||||
Write a function to solve a partially filled-in normal 9x9 <a href="https://en.wikipedia.org/wiki/Sudoku">Sudoku</a> grid and return the result. The blank fields are represented by 0s.
|
||||
<a href="https://en.wikipedia.org/wiki/Algorithmics_of_sudoku">Algorithmics of Sudoku</a> may help implement this.
|
||||
</section>
|
||||
|
||||
## Instructions
|
||||
<section id='instructions'>
|
||||
|
||||
</section>
|
||||
|
||||
## Tests
|
||||
<section id='tests'>
|
||||
|
||||
``` yml
|
||||
tests:
|
||||
- text: <code>solveSudoku</code> should be a function.
|
||||
testString: assert(typeof solveSudoku == 'function', '<code>solveSudoku</code> should be a function.');
|
||||
- text: <code>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]])</code> 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]])), '<code>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]])</code> should return a array.');
|
||||
- text: <code>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]])</code> should return <code>[[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]]</code>.
|
||||
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]], '<code>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]])</code> should return <code>[[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]]</code>.');
|
||||
- text: <code>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]])</code> should return <code>[[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]]</code>.
|
||||
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]], '<code>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]])</code> should return <code>[[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]]</code>.');
|
||||
- text: <code>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]])</code> should return <code>[[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]]</code>.
|
||||
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]], '<code>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]])</code> should return <code>[[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]]</code>.');
|
||||
```
|
||||
|
||||
</section>
|
||||
|
||||
## Challenge Seed
|
||||
<section id='challengeSeed'>
|
||||
<div id='js-seed'>
|
||||
|
||||
```js
|
||||
function solveSudoku (puzzle) {
|
||||
// Good luck!
|
||||
}
|
||||
```
|
||||
|
||||
</div>
|
||||
</section>
|
||||
|
||||
## Solution
|
||||
<section id='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;
|
||||
}
|
||||
```
|
||||
|
||||
</section>
|
@ -0,0 +1,72 @@
|
||||
---
|
||||
id: 5a23c84252665b21eecc803f
|
||||
title: Sum digits of an integer
|
||||
challengeType: 5
|
||||
---
|
||||
|
||||
## Description
|
||||
<section id='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.
|
||||
<ul>
|
||||
<li><b>1</b><sub>10</sub> sums to <b>1</b></li>
|
||||
<li><b>1234</b><sub>10</sub> sums to <b>10</b></li>
|
||||
<li><b>fe</b><sub>16</sub> sums to <b>29</b></li>
|
||||
<li><b>f0e</b><sub>16</sub> sums to <b>29</b></li>
|
||||
</ul>
|
||||
</section>
|
||||
|
||||
## Instructions
|
||||
<section id='instructions'>
|
||||
|
||||
</section>
|
||||
|
||||
## Tests
|
||||
<section id='tests'>
|
||||
|
||||
``` yml
|
||||
tests:
|
||||
- text: <code>sumDigits</code> should be a function.
|
||||
testString: assert(typeof sumDigits == 'function', '<code>sumDigits</code> should be a function.');
|
||||
- text: <code>sumDigits("1")</code> should return a number.
|
||||
testString: assert(typeof sumDigits("1") == 'number', '<code>sumDigits("1")</code> should return a number.');
|
||||
- text: <code>sumDigits("1")</code> should return <code>1</code>.
|
||||
testString: assert.equal(sumDigits("1"), 1, '<code>sumDigits("1")</code> should return <code>1</code>.');
|
||||
- text: <code>sumDigits("12345")</code> should return <code>15</code>.
|
||||
testString: assert.equal(sumDigits("12345"), 15, '<code>sumDigits("12345")</code> should return <code>15</code>.');
|
||||
- text: <code>sumDigits("254")</code> should return <code>11</code>.
|
||||
testString: assert.equal(sumDigits("254"), 11, '<code>sumDigits("254")</code> should return <code>11</code>.');
|
||||
- text: <code>sumDigits("fe")</code> should return <code>29</code>.
|
||||
testString: assert.equal(sumDigits("fe"), 29, '<code>sumDigits("fe")</code> should return <code>29</code>.');
|
||||
- text: <code>sumDigits("f0e")</code> should return <code>29</code>.
|
||||
testString: assert.equal(sumDigits("f0e"), 29, '<code>sumDigits("f0e")</code> should return <code>29</code>.');
|
||||
- text: <code>sumDigits("999ABCXYZ")</code> should return <code>162</code>.
|
||||
testString: assert.equal(sumDigits("999ABCXYZ"), 162, '<code>sumDigits("999ABCXYZ")</code> should return <code>162</code>.');
|
||||
```
|
||||
|
||||
</section>
|
||||
|
||||
## Challenge Seed
|
||||
<section id='challengeSeed'>
|
||||
<div id='js-seed'>
|
||||
|
||||
```js
|
||||
function sumDigits (n) {
|
||||
// Good luck!
|
||||
}
|
||||
```
|
||||
|
||||
</div>
|
||||
</section>
|
||||
|
||||
## Solution
|
||||
<section id='solution'>
|
||||
|
||||
```js
|
||||
function sumDigits (n) {
|
||||
n += ''
|
||||
for (var s=0, i=0, e=n.length; i<e; i+=1) s+=parseInt(n.charAt(i),36)
|
||||
return s
|
||||
}
|
||||
```
|
||||
|
||||
</section>
|
@ -0,0 +1,66 @@
|
||||
---
|
||||
id: 5a23c84252665b21eecc8040
|
||||
title: Sum multiples of 3 and 5
|
||||
challengeType: 5
|
||||
---
|
||||
|
||||
## Description
|
||||
<section id='description'>
|
||||
The objective is to write a function that finds the sum of all positive multiples of 3 or 5 below <i>n</i>.
|
||||
</section>
|
||||
|
||||
## Instructions
|
||||
<section id='instructions'>
|
||||
|
||||
</section>
|
||||
|
||||
## Tests
|
||||
<section id='tests'>
|
||||
|
||||
``` yml
|
||||
tests:
|
||||
- text: <code>sumMults</code> should be a function.
|
||||
testString: assert(typeof sumMults == 'function', '<code>sumMults</code> should be a function.');
|
||||
- text: <code>sumMults(10)</code> should return a number.
|
||||
testString: assert(typeof sumMults(10) == 'number', '<code>sumMults(10)</code> should return a number.');
|
||||
- text: <code>sumMults(10)</code> should return <code>23</code>.
|
||||
testString: assert.equal(sumMults(10), 23, '<code>sumMults(10)</code> should return <code>23</code>.');
|
||||
- text: <code>sumMults(100)</code> should return <code>2318</code>.
|
||||
testString: assert.equal(sumMults(100), 2318, '<code>sumMults(100)</code> should return <code>2318</code>.');
|
||||
- text: <code>sumMults(1000)</code> should return <code>233168</code>.
|
||||
testString: assert.equal(sumMults(1000), 233168, '<code>sumMults(1000)</code> should return <code>233168</code>.');
|
||||
- text: <code>sumMults(10000)</code> should return <code>23331668</code>.
|
||||
testString: assert.equal(sumMults(10000), 23331668, '<code>sumMults(10000)</code> should return <code>23331668</code>.');
|
||||
- text: <code>sumMults(100000)</code> should return <code>2333316668</code>.
|
||||
testString: assert.equal(sumMults(100000), 2333316668, '<code>sumMults(100000)</code> should return <code>2333316668</code>.');
|
||||
```
|
||||
|
||||
</section>
|
||||
|
||||
## Challenge Seed
|
||||
<section id='challengeSeed'>
|
||||
<div id='js-seed'>
|
||||
|
||||
```js
|
||||
function sumMults (n) {
|
||||
// Good luck!
|
||||
}
|
||||
```
|
||||
|
||||
</div>
|
||||
</section>
|
||||
|
||||
## Solution
|
||||
<section id='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;
|
||||
}
|
||||
```
|
||||
|
||||
</section>
|
@ -0,0 +1,75 @@
|
||||
---
|
||||
id: 5a23c84252665b21eecc8041
|
||||
title: Sum of a series
|
||||
challengeType: 5
|
||||
---
|
||||
|
||||
## Description
|
||||
<section id='description'>
|
||||
Compute the <b>n</b><sup>th</sup> term of a <a href="https://en.wikipedia.org/wiki/Series (mathematics)">series</a>, i.e. the sum of the <b>n</b> first terms of the corresponding <a href="https://en.wikipedia.org/wiki/sequence">sequence</a>.
|
||||
Informally this value, or its limit when <b>n</b> tends to infinity, is also called the <i>sum of the series</i>, 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 <a href="https://en.wikipedia.org/wiki/Riemann zeta function">zeta function</a> for S=2, whose exact value
|
||||
$\zeta(2) = {\pi^2\over 6}$
|
||||
is the solution of the <a href="https://en.wikipedia.org/wiki/Basel problem">Basel problem</a>.
|
||||
Write a function that take $a$ and $b$ as parameters and returns the sum of $a^{th}$ to $b^{th}$ members of the sequence.
|
||||
</section>
|
||||
|
||||
## Instructions
|
||||
<section id='instructions'>
|
||||
|
||||
</section>
|
||||
|
||||
## Tests
|
||||
<section id='tests'>
|
||||
|
||||
``` yml
|
||||
tests:
|
||||
- text: <code>sum</code> should be a function.
|
||||
testString: assert(typeof sum == 'function', '<code>sum</code> should be a function.');
|
||||
- text: <code>sum(1, 100)</code> should return a number.
|
||||
testString: assert(typeof sum(1, 100) == 'number', '<code>sum(1, 100)</code> should return a number.');
|
||||
- text: <code>sum(1, 100)</code> should return <code>1.6349839001848923</code>.
|
||||
testString: assert.equal(sum(1, 100), 1.6349839001848923, '<code>sum(1, 100)</code> should return <code>1.6349839001848923</code>.');
|
||||
- text: <code>sum(33, 46)</code> should return <code>0.009262256361481223</code>.
|
||||
testString: assert.equal(sum(33, 46), 0.009262256361481223, '<code>sum(33, 46)</code> should return <code>0.009262256361481223</code>.');
|
||||
- text: <code>sum(21, 213)</code> should return <code>0.044086990748706555</code>.
|
||||
testString: assert.equal(sum(21, 213), 0.044086990748706555, '<code>sum(21, 213)</code> should return <code>0.044086990748706555</code>.');
|
||||
- text: <code>sum(11, 111)</code> should return <code>0.08619778593108679</code>.
|
||||
testString: assert.equal(sum(11, 111), 0.08619778593108679, '<code>sum(11, 111)</code> should return <code>0.08619778593108679</code>.');
|
||||
- text: <code>sum(1, 10)</code> should return <code>1.5497677311665408</code>.
|
||||
testString: assert.equal(sum(1, 10), 1.5497677311665408, '<code>sum(1, 10)</code> should return <code>1.5497677311665408</code>.');
|
||||
```
|
||||
|
||||
</section>
|
||||
|
||||
## Challenge Seed
|
||||
<section id='challengeSeed'>
|
||||
<div id='js-seed'>
|
||||
|
||||
```js
|
||||
function sum (a, b) {
|
||||
// Good luck!
|
||||
}
|
||||
```
|
||||
|
||||
</div>
|
||||
</section>
|
||||
|
||||
## Solution
|
||||
<section id='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;
|
||||
}
|
||||
```
|
||||
|
||||
</section>
|
@ -0,0 +1,68 @@
|
||||
---
|
||||
id: 5a23c84252665b21eecc8042
|
||||
title: Sum of squares
|
||||
challengeType: 5
|
||||
---
|
||||
|
||||
## Description
|
||||
<section id='description'>
|
||||
Write a function to find the sum of squares of an array of integers.
|
||||
</section>
|
||||
|
||||
## Instructions
|
||||
<section id='instructions'>
|
||||
|
||||
</section>
|
||||
|
||||
## Tests
|
||||
<section id='tests'>
|
||||
|
||||
``` yml
|
||||
tests:
|
||||
- text: <code>sumsq</code> should be a function.
|
||||
testString: assert(typeof sumsq == 'function', '<code>sumsq</code> should be a function.');
|
||||
- text: <code>sumsq([1, 2, 3, 4, 5])</code> should return a number.
|
||||
testString: assert(typeof sumsq([1, 2, 3, 4, 5]) == 'number', '<code>sumsq([1, 2, 3, 4, 5])</code> should return a number.');
|
||||
- text: <code>sumsq([1, 2, 3, 4, 5])</code> should return <code>55</code>.
|
||||
testString: assert.equal(sumsq([1, 2, 3, 4, 5]), 55, '<code>sumsq([1, 2, 3, 4, 5])</code> should return <code>55</code>.');
|
||||
- text: <code>sumsq([25, 32, 12, 7, 20])</code> should return <code>2242</code>.
|
||||
testString: assert.equal(sumsq([25, 32, 12, 7, 20]), 2242, '<code>sumsq([25, 32, 12, 7, 20])</code> should return <code>2242</code>.');
|
||||
- text: <code>sumsq([38, 45, 35, 8, 13])</code> should return <code>4927</code>.
|
||||
testString: assert.equal(sumsq([38, 45, 35, 8, 13]), 4927, '<code>sumsq([38, 45, 35, 8, 13])</code> should return <code>4927</code>.');
|
||||
- text: <code>sumsq([43, 36, 20, 34, 24])</code> should return <code>5277</code>.
|
||||
testString: assert.equal(sumsq([43, 36, 20, 34, 24]), 5277, '<code>sumsq([43, 36, 20, 34, 24])</code> should return <code>5277</code>.');
|
||||
- text: <code>sumsq([12, 33, 26, 18, 1, 16, 3])</code> should return <code>2499</code>.
|
||||
testString: assert.equal(sumsq([12, 33, 26, 18, 1, 16, 3]), 2499, '<code>sumsq([12, 33, 26, 18, 1, 16, 3])</code> should return <code>2499</code>.');
|
||||
```
|
||||
|
||||
</section>
|
||||
|
||||
## Challenge Seed
|
||||
<section id='challengeSeed'>
|
||||
<div id='js-seed'>
|
||||
|
||||
```js
|
||||
function sumsq (array) {
|
||||
// Good luck!
|
||||
}
|
||||
```
|
||||
|
||||
</div>
|
||||
</section>
|
||||
|
||||
## Solution
|
||||
<section id='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;
|
||||
}
|
||||
```
|
||||
|
||||
</section>
|
@ -0,0 +1,149 @@
|
||||
---
|
||||
id: 5a23c84252665b21eecc8043
|
||||
title: Sum to 100
|
||||
challengeType: 5
|
||||
---
|
||||
|
||||
## Description
|
||||
<section id='description'>
|
||||
Find solutions to the <i>sum to one hundred</i> puzzle.
|
||||
Add (insert) the mathematical operators <b>+</b> or <b>─</b> (plus or minus) before any of the digits in the decimal numeric string <b>123456789</b> such that the resulting mathematical expression adds up to a particular sum (in this iconic case, <b>100</b>).
|
||||
Example:
|
||||
<pre><b>123 + 4 - 5 + 67 - 89 = 100</b></pre>
|
||||
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.
|
||||
</section>
|
||||
|
||||
## Instructions
|
||||
<section id='instructions'>
|
||||
|
||||
</section>
|
||||
|
||||
## Tests
|
||||
<section id='tests'>
|
||||
|
||||
``` yml
|
||||
tests:
|
||||
- text: <code>sumTo100</code> should be a function.
|
||||
testString: assert(typeof sumTo100 == 'function', '<code>sumTo100</code> should be a function.');
|
||||
- text: <code>sumTo100(199)</code> should return a array.
|
||||
testString: assert(Array.isArray(sumTo100(199)), '<code>sumTo100(199)</code> should return a array.');
|
||||
- text: <code>sumTo100(199)</code> should return <code>["-1+2-3+45+67+89", "123-4+5+6+78-9", "123-4+56+7+8+9"]</code>.
|
||||
testString: assert.deepEqual(sumTo100(199), ["-1+2-3+45+67+89", "123-4+5+6+78-9", "123-4+56+7+8+9"], '<code>sumTo100(199)</code> should return <code>["-1+2-3+45+67+89", "123-4+5+6+78-9", "123-4+56+7+8+9"]</code>.');
|
||||
- text: <code>sumTo100(209)</code> should return <code>["1+234+56+7-89"]</code>.
|
||||
testString: assert.deepEqual(sumTo100(209), ["1+234+56+7-89"], '<code>sumTo100(209)</code> should return <code>["1+234+56+7-89"]</code>.');
|
||||
- text: <code>sumTo100(243)</code> should return <code>["-1-234+567-89", "-12+345+6-7-89", "123+45+6+78-9"]</code>.
|
||||
testString: assert.deepEqual(sumTo100(243), ["-1-234+567-89", "-12+345+6-7-89", "123+45+6+78-9"], '<code>sumTo100(243)</code> should return <code>["-1-234+567-89", "-12+345+6-7-89", "123+45+6+78-9"]</code>.');
|
||||
- text: <code>sumTo100(199)</code> should return <code>["-1+2-3+45+67+89", "123-4+5+6+78-9", "123-4+56+7+8+9"]</code>.
|
||||
testString: assert.deepEqual(sumTo100(199), ["-1+2-3+45+67+89", "123-4+5+6+78-9", "123-4+56+7+8+9"], '<code>sumTo100(199)</code> should return <code>["-1+2-3+45+67+89", "123-4+5+6+78-9", "123-4+56+7+8+9"]</code>.');
|
||||
- text: <code>sumTo100(197)</code> should return <code>["1-2-3+45+67+89", "12+34-5+67+89", "123+4-5+6+78-9"]</code>.
|
||||
testString: assert.deepEqual(sumTo100(197), ["1-2-3+45+67+89", "12+34-5+67+89", "123+4-5+6+78-9"], '<code>sumTo100(197)</code> should return <code>["1-2-3+45+67+89", "12+34-5+67+89", "123+4-5+6+78-9"]</code>.');
|
||||
```
|
||||
|
||||
</section>
|
||||
|
||||
## Challenge Seed
|
||||
<section id='challengeSeed'>
|
||||
<div id='js-seed'>
|
||||
|
||||
```js
|
||||
function sumTo100 (n) {
|
||||
// Good luck!
|
||||
}
|
||||
```
|
||||
|
||||
</div>
|
||||
</section>
|
||||
|
||||
## Solution
|
||||
<section id='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()
|
||||
}
|
||||
```
|
||||
|
||||
</section>
|
@ -0,0 +1,97 @@
|
||||
---
|
||||
id: 5a23c84252665b21eecc8045
|
||||
title: Sutherland-Hodgman polygon clipping
|
||||
challengeType: 5
|
||||
---
|
||||
|
||||
## Description
|
||||
<section id='description'>
|
||||
The <a href="https://en.wikipedia.org/wiki/Sutherland-Hodgman clipping algorithm">Sutherland-Hodgman clipping algorithm</a> 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.
|
||||
</section>
|
||||
|
||||
## Instructions
|
||||
<section id='instructions'>
|
||||
|
||||
</section>
|
||||
|
||||
## Tests
|
||||
<section id='tests'>
|
||||
|
||||
``` yml
|
||||
tests:
|
||||
- text: <code>clip</code> should be a function.
|
||||
testString: assert(typeof clip == 'function', '<code>clip</code> should be a function.');
|
||||
- text: <code>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]])</code> 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]])), '<code>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]])</code> should return a array.');
|
||||
- text: <code>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]])</code> should return <code>[[100, 116.667], [125, 100], [275, 100], [300, 116.667], [300, 300], [250, 300], [200, 250], [175, 300], [125, 300], [100, 250]]</code>.
|
||||
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]], '<code>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]])</code> should return <code>[[100, 116.667], [125, 100], [275, 100], [300, 116.667], [300, 300], [250, 300], [200, 250], [175, 300], [125, 300], [100, 250]]</code>.');
|
||||
- text: <code>clip([[150, 200], [400, 450], [30, 50]], [[10, 10], [300, 200], [400, 600], [100, 300]])</code> should return <code>[[150, 200], [350, 400], [348.611, 394.444], [30, 50]]</code>.
|
||||
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]], '<code>clip([[150, 200], [400, 450], [30, 50]], [[10, 10], [300, 200], [400, 600], [100, 300]])</code> should return <code>[[150, 200], [350, 400], [348.611, 394.444], [30, 50]]</code>.');
|
||||
- text: <code>clip([[250, 200], [100, 450], [130, 250]], [[50, 60], [100, 230], [400, 600], [100, 300]])</code> should return <code>[[129.167, 329.167], [119.565, 319.565], [121.854, 304.305]]</code>.
|
||||
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]], '<code>clip([[250, 200], [100, 450], [130, 250]], [[50, 60], [100, 230], [400, 600], [100, 300]])</code> should return <code>[[129.167, 329.167], [119.565, 319.565], [121.854, 304.305]]</code>.');
|
||||
```
|
||||
|
||||
</section>
|
||||
|
||||
## Challenge Seed
|
||||
<section id='challengeSeed'>
|
||||
<div id='js-seed'>
|
||||
|
||||
```js
|
||||
function clip (subjectPolygon, clipPolygon) {
|
||||
// Good luck!
|
||||
}
|
||||
```
|
||||
|
||||
</div>
|
||||
</section>
|
||||
|
||||
## Solution
|
||||
<section id='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));
|
||||
}
|
||||
```
|
||||
|
||||
</section>
|
@ -0,0 +1,82 @@
|
||||
---
|
||||
id: 5a23c84252665b21eecc8046
|
||||
title: Symmetric difference
|
||||
challengeType: 5
|
||||
---
|
||||
|
||||
## Description
|
||||
<section id='description'>
|
||||
Given two <a href="http://rosettacode.org/wiki/set">set</a>s <i>A</i> and <i>B</i>, compute $(A \setminus B) \cup (B \setminus A).$
|
||||
That is, enumerate the items that are in <i>A</i> or <i>B</i> but not both. This set is called the <a href="https://en.wikipedia.org/wiki/Symmetric difference">symmetric difference</a> of <i>A</i> and <i>B</i>.
|
||||
In other words: $(A \cup B) \setminus (A \cap B)$ (the set of items that are in at least one of <i>A</i> or <i>B</i> minus the set of items that are in both <i>A</i> and <i>B</i>).
|
||||
Write a function that takes two arrays as parameters and returns the symmetric difference. Note: Sort the resultant array before returning it.
|
||||
</section>
|
||||
|
||||
## Instructions
|
||||
<section id='instructions'>
|
||||
|
||||
</section>
|
||||
|
||||
## Tests
|
||||
<section id='tests'>
|
||||
|
||||
``` yml
|
||||
tests:
|
||||
- text: <code>symmetricDifference</code> should be a function.
|
||||
testString: assert(typeof symmetricDifference == 'function', '<code>symmetricDifference</code> should be a function.');
|
||||
- text: <code>symmetricDifference(["John", "Bob", "Mary", "Serena"], ["Jim", "Mary", "John", "Bob"])</code> should return a array.
|
||||
testString: assert(Array.isArray(symmetricDifference(["John", "Bob", "Mary", "Serena"], ["Jim", "Mary", "John", "Bob"])), '<code>symmetricDifference(["John", "Bob", "Mary", "Serena"], ["Jim", "Mary", "John", "Bob"])</code> should return a array.');
|
||||
- text: <code>symmetricDifference(["John", "Bob", "Mary", "Serena"], ["Jim", "Mary", "John", "Bob"])</code> should return <code>["Jim", "Serena"]</code>.
|
||||
testString: assert.deepEqual(symmetricDifference(["John", "Bob", "Mary", "Serena"], ["Jim", "Mary", "John", "Bob"]), ["Jim", "Serena"], '<code>symmetricDifference(["John", "Bob", "Mary", "Serena"], ["Jim", "Mary", "John", "Bob"])</code> should return <code>["Jim", "Serena"]</code>.');
|
||||
- text: <code>symmetricDifference([1, 2, 3], [3, 4])</code> should return <code>[1, 2, 4]</code>.
|
||||
testString: assert.deepEqual(symmetricDifference([1, 2, 3], [3, 4]), [1, 2, 4], '<code>symmetricDifference([1, 2, 3], [3, 4])</code> should return <code>[1, 2, 4]</code>.');
|
||||
- text: <code>symmetricDifference([1, 2, 3, 4, 5], [3, 4, 8, 7])</code> should return <code>[1, 2, 5, 7, 8]</code>.
|
||||
testString: assert.deepEqual(symmetricDifference([1, 2, 3, 4, 5], [3, 4, 8, 7]), [1, 2, 5, 7, 8], '<code>symmetricDifference([1, 2, 3, 4, 5], [3, 4, 8, 7])</code> should return <code>[1, 2, 5, 7, 8]</code>.');
|
||||
- text: <code>symmetricDifference([1, 2, 3, 4, 5, 6, 7, 8], [1, 3, 5, 6, 7, 8, 9])</code> should return <code>[2, 4, 9]</code>.
|
||||
testString: assert.deepEqual(symmetricDifference([1, 2, 3, 4, 5, 6, 7, 8], [1, 3, 5, 6, 7, 8, 9]), [2, 4, 9], '<code>symmetricDifference([1, 2, 3, 4, 5, 6, 7, 8], [1, 3, 5, 6, 7, 8, 9])</code> should return <code>[2, 4, 9]</code>.');
|
||||
- text: <code>symmetricDifference([1, 2, 4, 7, 9], [2, 3, 7, 8, 9])</code> should return <code>[1, 3, 4, 8]</code>.
|
||||
testString: assert.deepEqual(symmetricDifference([1, 2, 4, 7, 9], [2, 3, 7, 8, 9]), [1, 3, 4, 8], '<code>symmetricDifference([1, 2, 4, 7, 9], [2, 3, 7, 8, 9])</code> should return <code>[1, 3, 4, 8]</code>.');
|
||||
```
|
||||
|
||||
</section>
|
||||
|
||||
## Challenge Seed
|
||||
<section id='challengeSeed'>
|
||||
<div id='js-seed'>
|
||||
|
||||
```js
|
||||
function symmetricDifference (A, B) {
|
||||
// Good luck!
|
||||
}
|
||||
```
|
||||
|
||||
</div>
|
||||
</section>
|
||||
|
||||
## Solution
|
||||
<section id='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();
|
||||
}
|
||||
```
|
||||
|
||||
</section>
|
Reference in New Issue
Block a user