"<p>There are 100 doors in a row that are all initially closed. You make 100 passes by the doors. The first time through, visit every door and 'toggle' the door (if the door is closed, open it; if it is open, close it). The second time, only visit every 2nd door (i.e., door #2, #4, #6, ...) and toggle it. The third time, visit every 3rd door (i.e., door #3, #6, #9, ...), etc., until you only visit the 100th door.</p>",
"<p>Implement a function to determine the state of the doors after the last pass. Return the final result in an array, with only the door number included in the array if it is open.</p>"
],
"challengeSeed":[
"function getFinalOpenedDoors (numDoors) {",
" // Good luck!",
"}"
],
"solutions":[
"function getFinalOpenedDoors (numDoors) {\n // this is the final pattern (always squares).\n // thus, the most efficient solution simply returns an array of squares up to numDoors).\n const finalState = [];\n let i = 1;\n while (Math.pow(i, 2) <= numDoors) {\n finalState.push(Math.pow(i, 2));\n i++;\n }\n return finalState;\n}\n"
"assert(typeof getFinalOpenedDoors === 'function', 'message: <code>getFinalOpenedDoors</code> is a function.');",
"assert(Array.isArray(getFinalOpenedDoors(100)), 'message: <code>getFinalOpenedDoors</code> should return an array.');",
"assert.deepEqual(getFinalOpenedDoors(100), solution, 'message: <code>getFinalOpenedDoors</code> did not produce the correct results.');"
],
"id":"594810f028c0303b75339acb",
"challengeType":5,
"releasedOn":"August 5, 2017"
},
{
"title":"24 game",
"type":"Waypoint",
"description":[
"<p>Implement a function that takes a string of four digits as its argument, with each digit from 1 ──► 9 (inclusive) with repetitions allowed, and returns an arithmetic expression that evaluates to the number 24. If no such solution exists, return \"no solution exists.\"</p>",
"<p>Rules:</p>",
" Only the following operators/functions are allowed: multiplication, division, addition, subtraction",
" Division should use floating point or rational arithmetic, etc, to preserve remainders.",
" Forming multiple digit numbers from the supplied digits is disallowed. (So an answer of 12+12 when given 1, 2, 2, and 1 is wrong).",
" The order of the digits when given does not have to be preserved.",
"<p>Example inputs:</p>",
"<code>solve24(\"4878\");</code>",
"<code>solve24(\"1234\");</code>",
"<code>solve24(\"6789\");</code>",
"<code>solve24(\"1127\");</code>",
"<p>Example outputs (strings):</p>",
"<code>(7-8/8)*4</code>",
"<code>3*1*4*2</code>",
"<code>(6*8)/(9-7)</code>",
"<code>(1+7)*(2+1)</code>"
],
"challengeSeed":[
"function solve24 (numStr) {",
" // Good luck!",
" return true;",
"}"
],
"solutions":[
"// noprotect\n\nfunction solve24 (numStr) {\n const digitsArr = numStr.split('');\n const answers = [];\n\n const digitPermutations = [];\n const operatorPermutations = [];\n\n function generateDigitPermutations (digits, permutations = []) {\n if (digits.length === 0) {\n digitPermutations.push(permutations);\n }\n else {\n for (let i = 0; i < digits.length; i++) {\n const curr = digits.slice();\n const next = curr.splice(i, 1);\n generateDigitPermutations(curr.slice(), permutations.concat(next));\n }\n }\n }\n\n function generateOperatorPermutations (permutations = []) {\n const operators = ['+', '-', '*', '/'];\n if (permutations.length === 3) {\n operatorPermutations.push(permutations);\n }\n else {\n for (let i = 0; i < operators.length; i++) {\n const curr = permutations.slice();\n curr.push(operators[i]);\n generateOperatorPermutations(curr);\n }\n }\n }\n\n generateDigitPermutations(digitsArr);\n generateOperatorPermutations();\n\n interleave();\n\n return answers[0];\n\n function interleave () {\n for (let i = 0; i < digitPermutations.length; i++) {\n for (let j = 0; j < operatorPermutations.length; j++) {\n const d = digitPermutations[i];\n const o = operatorPermutations[j];\n const perm = [\n `${d[0]}${o[0]}${d[1]}${o[1]}${d[2]}${o[2]}${d[3]}`,\n `(${d[0]}${o[0]}${d[1]})${o[1]}${d[2]}${o[2]}${d[3]}`,\n `${d[0]}${o[0]}(${d[1]}${o[1]}${d[2]})${o[2]}${d[3]}`,\n `${d[0]}${o[0]}${d[1]}${o[1]}(${d[2]}${o[2]}${d[3]})`,\n `${d[0]}${o[0]}(${d[1]}${o[1]}${d[2]}${o[2]}${d[3]})`,\n `(${d[0]}${o[0]}${d[1]}${o[1]}${d[2]})${o[2]}${d[3]}`,\n `(${d[0]}${o[0]}${d[1]})${o[1]}(${d[2]}${o[2]}${d[3]})`\n ];\n\n perm.forEach(combination => {\n const res = eval(combination);\n\n if (res === 24) {\n return answers.push(combination);\n }\n });\n }\n }\n }\n}\n"
"assert(typeof solve24 === 'function', 'message: <code>solve24</code> is a function.');",
"assert(include(answers[0], solve24(testCases[0])), 'message: <code>solve24(\"4878\")</code> should return <code>(7-8/8)*4</code> or <code>4*(7-8/8)</code>');",
"assert(include(answers[1], solve24(testCases[1])), 'message: <code>solve24(\"1234\")</code> should return any arrangement of <code>1*2*3*4</code>');",
"assert(include(answers[2], solve24(testCases[2])), 'message: <code>solve24(\"6789\")</code> should return <code>(6*8)/(9-7)</code> or <code>(8*6)/(9-7)</code>');",
"assert(include(answers[3], solve24(testCases[3])), 'message: <code>solve24(\"1127\")</code> should return a permutation of <code>(1+7)*(1*2)</code>');"
],
"id":"5951e88f64ebf159166a1176",
"challengeType":5,
"releasedOn":"August 5, 2017"
},
{
"title":"9 billion names of God the integer",
"type":"Waypoint",
"description":[
"<p>This task is a variation of the <a href=\"https://en.wikipedia.org/wiki/The Nine Billion Names of God#Plot_summary\" title=\"wp: The Nine Billion Names of God#Plot_summary\">short story by Arthur C. Clarke</a>.</p>",
"<p>(Solvers should be aware of the consequences of completing this task.)</p>",
"<p>In detail, to specify what is meant by a “name”:</p>",
"<p>The integer 1 has 1 name “1”.</p>",
"<p>The integer 2 has 2 names “1+1”, and “2”.</p>",
"<p>The integer 3 has 3 names “1+1+1”, “2+1”, and “3”.</p>",
"<p>This can be visualized in the following form:</p>",
"<pre>",
" 1",
" 1 1",
" 1 1 1",
" 1 2 1 1",
" 1 2 2 1 1",
"1 3 3 2 1 1",
"</pre>",
"<p>Where row $n$ corresponds to integer $n$, and each column $C$ in row $m$ from left to right corresponds to the number of names beginning with $C$.</p>",
"<p>Optionally note that the sum of the $n$-th row $P(n)$ is the <a href=\"http://mathworld.wolfram.com/PartitionFunctionP.html\" title=\"link: http://mathworld.wolfram.com/PartitionFunctionP.html\">integer partition function</a>.</p>",
"Task",
"<p>Implement a function that returns the sum of the $n$-th row.</p>"
],
"challengeSeed":[
"function numberOfNames (num) {",
" // Good luck!",
" return true;",
"}"
],
"solutions":[
"function numberOfNames (num) {\n const cache = [\n [1]\n ];\n for (let l = cache.length; l < num + 1; l++) {\n let Aa;\n let Mi;\n const r = [0];\n for (let x = 1; x < l + 1; x++) {\n r.push(r[r.length - 1] + (Aa = cache[l - x < 0 ? cache.length - (l - x) : l - x])[(Mi = Math.min(x, l - x)) < 0 ? Aa.length - Mi : Mi]);\n }\n cache.push(r);\n }\n return cache[num][cache[num].length - 1];\n}\n"
],
"tests":[
"assert(typeof numberOfNames === 'function', 'message: <code>numberOfNames</code> is a function.');",
"assert.equal(numberOfNames(5), 7, 'message: <code>numberOfNames(5)</code> should equal 7.');",
"assert.equal(numberOfNames(12), 77, 'message: <code>numberOfNames(12)</code> should equal 77.');",
"assert.equal(numberOfNames(18), 385, 'message: <code>numberOfNames(18)</code> should equal 385.');",
"assert.equal(numberOfNames(23), 1255, 'message: <code>numberOfNames(23)</code> should equal 1255.');",
"assert.equal(numberOfNames(42), 53174, 'message: <code>numberOfNames(42)</code> should equal 53174.');",
"assert.equal(numberOfNames(123), 2552338241, 'message: <code>numberOfNames(123)</code> should equal 2552338241.');"
],
"id":"5949b579404977fbaefcd736",
"challengeType":5,
"releasedOn":"August 5, 2017"
},
{
"title":"ABC Problem",
"type":"Waypoint",
"description":[
"<p>You are given a collection of ABC blocks (e.g., childhood alphabet blocks). There are 20 blocks with two letters on each block. A complete alphabet is guaranteed amongst all sides of the blocks. The sample collection of blocks:</p>",
"<p>(B O)</p>",
"<p>(X K)</p>",
"<p>(D Q)</p>",
"<p>(C P)</p>",
"<p>(N A)</p>",
"<p>(G T)</p>",
"<p>(R E)</p>",
"<p>(T G)</p>",
"<p>(Q D)</p>",
"<p>(F S)</p>",
"<p>(J W)</p>",
"<p>(H U)</p>",
"<p>(V I)</p>",
"<p>(A N)</p>",
"<p>(O B)</p>",
"<p>(E R)</p>",
"<p>(F S)</p>",
"<p>(L Y)</p>",
"<p>(P C)</p>",
"<p>(Z M)</p>",
"<p>Some rules to keep in mind:</p>",
"Once a letter on a block is used, that block cannot be used again.",
"The function should be case-insensitive.",
"<p>Implement a function that takes a string (word) and determines whether the word can be spelled with the given collection of blocks.</p>"
],
"challengeSeed":[
"function canMakeWord (word) {",
" // Good luck!",
"}"
],
"solutions":[
"function canMakeWord (word) {\n const characters = 'BO XK DQ CP NA GT RE TG QD FS JW HU VI AN OB ER FS LY PC ZM';\n const blocks = characters.split(' ').map(pair => pair.split(''));\n\n const letters = [...word.toUpperCase()];\n let length = letters.length;\n const copy = new Set(blocks);\n\n letters.forEach(letter => {\n for (let block of copy) {\n const index = block.indexOf(letter);\n\n if (index !== -1) {\n length--;\n copy.delete(block);\n break;\n }\n }\n });\n return !length;\n}\n"
],
"tail":[
"const words = ['bark', 'BooK', 'TReAT', 'COMMON', 'squAD', 'conFUSE'];"
],
"tests":[
"assert(typeof canMakeWord === 'function', 'message: <code>canMakeWord</code> is a function.');",
"assert(typeof canMakeWord('hi') === 'boolean', 'message: <code>canMakeWord</code> should return a boolean.');",
"assert(canMakeWord(words[0]), 'message: <code>canMakeWord(\"bark\")</code> should return true.');",
"assert(!canMakeWord(words[1]), 'message: <code>canMakeWord(\"BooK\")</code> should return false.');",
"assert(canMakeWord(words[2]), 'message: <code>canMakeWord(\"TReAT\")</code> should return true.');",
"assert(!canMakeWord(words[3]), 'message: <code>canMakeWord(\"COMMON\")</code> should return false.');",
"assert(canMakeWord(words[4]), 'message: <code>canMakeWord(\"squAD\")</code> should return true.');",
"assert(canMakeWord(words[5]), 'message: <code>canMakeWord(\"conFUSE\")</code> should return true.');"
],
"id":"594810f028c0303b75339acc",
"challengeType":5,
"releasedOn":"August 5, 2017"
},
{
"title":"Abundant, deficient and perfect number classifications",
"type":"Waypoint",
"description":[
"<p>These define three classifications of positive integers based on their <a href=\"http://rosettacode.org/wiki/Proper divisors\" title=\"Proper divisors\">proper divisors</a>.</p>",
"<p>Let $P(n)$ be the sum of the proper divisors of n where proper divisors are all positive integers n other than n itself.</p>",
"<p>If <code>P(n) < n</code> then n is classed as \"deficient\"</p>",
"<p>If <code>P(n) === n</code> then n is classed as \"perfect\"</p>",
"<p>If <code>P(n) > n</code> then n is classed as \"abundant\"</p>",
"<p>Example:</p>",
"<p>6 has proper divisors of 1, 2, and 3.</p>",
"<p>1 + 2 + 3 = 6, so 6 is classed as a perfect number.</p>",
"<p>Implement a function that calculates how many of the integers from 1 to 20,000 (inclusive) are in each of the three classes. Output the result as an array in the following format <code>[deficient, perfect, abundant]</code>.</p>"
],
"challengeSeed":[
"function getDPA (num) {",
" // Good luck!",
"}"
],
"solutions":[
"function getDPA (num) {\n const dpa = [1, 0, 0];\n for (let n = 2; n <= num; n += 1) {\n let ds = 1;\n const e = Math.sqrt(n);\n for (let d = 2; d < e; d += 1) {\n if (n % d === 0) {\n ds += d + (n / d);\n }\n }\n if (n % e === 0) {\n ds += e;\n }\n dpa[ds < n ? 0 : ds === n ? 1 : 2] += 1;\n }\n return dpa;\n}\n"
],
"tail":[
"const solution = [15043, 4, 4953];"
],
"tests":[
"assert(typeof getDPA === 'function', 'message: <code>getDPA</code> is a function.');",
"assert(Array.isArray(getDPA(100)), 'message: <code>getDPA</code> should return an array.');",
"assert(getDPA(100).length === 3, 'message: <code>getDPA</code> return value should have a length of 3.');",
"assert.deepEqual(getDPA(20000), solution, 'message: <code>getDPA(20000)</code> should equal [15043, 4, 4953]');"
],
"id":"594810f028c0303b75339acd",
"challengeType":5,
"releasedOn":"August 5, 2017"
},
{
"title":"Accumulator factory",
"type":"Waypoint",
"description":[
"<p>Create a function that takes a single (numeric) argument and returns another function that is an accumulator. The returned accumulator function in turn also takes a single numeric argument, and returns the sum of all the numeric values passed in so far to that accumulator (including the initial value passed when the accumulator was created).</p>",
"<p>Rules:</p>",
"<p>Do not use global variables.</p>",
"<p>Hint:</p>",
"<p>Closures save outer state.</p>"
],
"challengeSeed":[
"function accumulator (sum) {",
" // Good luck!",
"}"
],
"solutions":[
"function accumulator (sum) {\n return function (n) {\n return sum += n;\n };\n}\n"
"assert(typeof accumulator === 'function', 'message: <code>accumulator</code> is a function.');",
"assert(typeof accumulator(0) === 'function', 'message: <code>accumulator(0)</code> should return a function.');",
"assert(typeof accumulator(0)(2) === 'number', 'message: <code>accumulator(0)(2)</code> should return a number.');",
"assert(testFn(5) === 5.5, 'message: Passing in the values 3, -4, 1.5, and 5 should return 5.5.');"
],
"id":"594810f028c0303b75339ace",
"challengeType":5,
"releasedOn":"August 5, 2017"
},
{
"title":"Ackermann function",
"type":"Waypoint",
"description":[
"<p>The Ackermann function is a classic example of a recursive function, notable especially because it is not a primitive recursive function. It grows very quickly in value, as does the size of its call tree.</p>",
"<p>The Ackermann function is usually defined as follows:</p>",
"$$A(m, n) =",
" \\begin{cases}",
" n+1 & \\mbox{if } m = 0 \\\\",
" A(m-1, 1) & \\mbox{if } m > 0 \\mbox{ and } n = 0 \\\\",
" A(m-1, A(m, n-1)) & \\mbox{if } m > 0 \\mbox{ and } n > 0.",
" \\end{cases}$$",
"<p>Its arguments are never negative and it always terminates. Write a function which returns the value of $A(m, n)$. Arbitrary precision is preferred (since the function grows so quickly), but not required.</p>"
],
"challengeSeed":[
"function ack (m, n) {",
" // Good luck!",
"}"
],
"solutions":[
"function ack (m, n) {\n return m === 0 ? n + 1 : ack(m - 1, n === 0 ? 1 : ack(m, n - 1));\n}\n"
],
"tests":[
"assert(typeof ack === 'function', 'message: <code>ack</code> is a function.');",
"assert(ack(0, 0) === 1, 'message: <code>ack(0, 0)</code> should return 1.');",
"assert(ack(1, 1) === 3, 'message: <code>ack(1, 1)</code> should return 3.');",
"assert(ack(2, 5) === 13, 'message: <code>ack(2, 5)</code> should return 13.');",
"assert(ack(3, 3) === 61, 'message: <code>ack(3, 3)</code> should return 61.');"
],
"id":"594810f028c0303b75339acf",
"challengeType":5,
"releasedOn":"August 5, 2017"
},
{
"title":"Align columns",
"type":"Waypoint",
"description":[
"<p>Given a text file of many lines, where fields within a line are delineated by a single <code>$</code> character, write a program that aligns each column of fields by ensuring that words in each column are separated by at least one space. Further, allow for each word in a column to be either left justified, right justified, or center justified within its column.</p>",
"<p>Use the following text to test your programs:</p>",
"const rightAligned = ` Given a text file of many lines",
" where fields within a line ",
" are delineated by a single \"dollar\" character",
" write a program",
" that aligns each column of fields ",
" by ensuring that words in each ",
" column are separated by at least one space.",
" Further, allow for each word in a column to be either left ",
"justified, right justified",
" or center justified within its column.`;",
"",
"const leftAligned = `Given a text file of many lines ",
"where fields within a line ",
"are delineated by a single \"dollar\" character",
"write a program ",
"that aligns each column of fields ",
"by ensuring that words in each ",
"column are separated by at least one space.",
"Further, allow for each word in a column to be either left ",
"justified, right justified",
"or center justified within its column. `;",
"",
"const centerAligned = ` Given a text file of many lines ",
" where fields within a line ",
" are delineated by a single \"dollar\" character",
" write a program ",
" that aligns each column of fields ",
" by ensuring that words in each ",
" column are separated by at least one space.",
" Further, allow for each word in a column to be either left ",
"justified, right justified",
" or center justified within its column. `;"
],
"tests":[
"assert(typeof formatText === 'function', 'message: <code>formatText</code> is a function.');",
"assert.strictEqual(formatText(testInput, 'right'), rightAligned, 'message: <code>formatText</code> with the above input and \"right\" justification should produce the following: ');",
"assert.strictEqual(formatText(testInput, 'left'), leftAligned, 'message: <code>formatText</code> with the above input and \"left\" justification should produce the following: ');",
"assert.strictEqual(formatText(testInput, 'center'), centerAligned, 'message: <code>formatText</code> with the above input and \"center\" justification should produce the following: ');"
],
"id":"594810f028c0303b75339ad0",
"challengeType":5,
"releasedOn":"August 5, 2017"
},
{
"title":"Amicable pairs",
"type":"Waypoint",
"description":[
"Two integers $N$ and $M$ are said to be <a href=\"https://en.wikipedia.org/wiki/Amicable numbers\" title=\"wp: Amicable numbers\">amicable pairs</a> if $N \\neq M$ and the sum of the <a href=\"http://rosettacode.org/wiki/Proper divisors\" title=\"Proper divisors\">proper divisors</a> of $N$ ($\\mathrm{sum}(\\mathrm{propDivs}(N))$) $= M$ as well as $\\mathrm{sum}(\\mathrm{propDivs}(M)) = N$.",
"Example:",
"1184 and 1210 are an amicable pair, with proper divisors:",
"<a href=\"http://rosettacode.org/wiki/Abundant, deficient and perfect number classifications\" title=\"Abundant, deficient and perfect number classifications\">Abundant, deficient and perfect number classifications</a>",
"<a href=\"http://rosettacode.org/wiki/Aliquot sequence classifications\" title=\"Aliquot sequence classifications\">Aliquot sequence classifications</a> and its amicable classification."
],
"challengeSeed":[
"function amicablePairsUpTo (maxNum) {",
" // Good luck!",
" return true;",
"}"
],
"solutions":[
"// amicablePairsUpTo :: Int -> [(Int, Int)]\nfunction amicablePairsUpTo (maxNum) {\n return range(1, maxNum)\n .map(x => properDivisors(x)\n .reduce((a, b) => a + b, 0))\n .reduce((a, m, i, lst) => {\n const n = i + 1;\n\n return (m > n) && lst[m - 1] === n ?\n a.concat([\n [n, m]\n ]) : a;\n }, []);\n}\n\n// properDivisors :: Int -> [Int]\nfunction properDivisors (n) {\n if (n < 2) return [];\n\n const rRoot = Math.sqrt(n);\n const intRoot = Math.floor(rRoot);\n const blnPerfectSquare = rRoot === intRoot;\n const lows = range(1, intRoot)\n .filter(x => (n % x) === 0);\n\n return lows.concat(lows.slice(1)\n .map(x => n / x)\n .reverse()\n .slice(blnPerfectSquare | 0));\n}\n\n// Int -> Int -> Maybe Int -> [Int]\nfunction range (m, n, step) {\n const d = (step || 1) * (n >= m ? 1 : -1);\n\n return Array.from({\n length: Math.floor((n - m) / d) + 1\n }, (_, i) => m + (i * d));\n}\n"
],
"tail":[
"const answer300 = [[220, 284]];",
"const answer3000 = [",
" [220, 284],",
" [1184, 1210],",
" [2620, 2924]",
"];",
"const answer20000 = [",
" [220, 284],",
" [1184, 1210],",
" [2620, 2924],",
" [5020, 5564],",
" [6232, 6368],",
" [10744, 10856],",
" [12285, 14595],",
" [17296, 18416]",
"];"
],
"tests":[
"assert(typeof amicablePairsUpTo === 'function', 'message: <code>amicablePairsUpTo</code> is a function.');",
"assert.deepEqual(amicablePairsUpTo(300), answer300, 'message: <code>amicablePairsUpTo(300)</code> should return <code>[[220,284]]</code>.');",
"assert.deepEqual(amicablePairsUpTo(3000), answer3000, 'message: <code>amicablePairsUpTo(3000)</code> should return <code>[[220,284],[1184,1210],[2620,2924]]</code>.');",
"assert.deepEqual(amicablePairsUpTo(20000), answer20000, 'message: <code>amicablePairsUpTo(20000)</code> should return <code>[[220,284],[1184,1210],[2620,2924],[5020,5564],[6232,6368],[10744,10856],[12285,14595],[17296,18416]]</code>.');"
],
"id":"5949b579404977fbaefcd737",
"challengeType":5,
"releasedOn":"August 5, 2017"
},
{
"title":"Averages/Mode",
"type":"Waypoint",
"description":[
"<p>Write a program to find the <a href=\"https://en.wikipedia.org/wiki/Mode (statistics)\" title=\"wp: Mode (statistics)\">mode</a> value of a collection.</p><p>The case where the collection is empty may be ignored. Care must be taken to handle the case where the mode is non-unique.</p><p>If it is not appropriate or possible to support a general collection, use a vector (array), if possible. If it is not appropriate or possible to support an unspecified value type, use integers.</p>"
],
"challengeSeed":[
"function mode (arr) {",
" // Good luck!",
" return true;",
"}"
],
"solutions":[
"function mode(arr) {\n const counter = {};\n let result = [];\n let max = 0;\n // for (const i in arr) {\n arr.forEach(el => {\n if (!(el in counter)) {\n counter[el] = 0;\n }\n counter[el]++;\n\n if (counter[el] === max) {\n result.push(el);\n }\n else if (counter[el] > max) {\n max = counter[el];\n result = [el];\n }\n });\n return result;\n}\n"
"<p class='rosetta__paragraph'>Compute all three of the <a class='rosetta__link--wiki' href='https://en.wikipedia.org/wiki/Pythagorean means' title='wp: Pythagorean means'>Pythagorean means</a> of the set of integers <big>1</big> through <big>10</big> (inclusive).</p><p class='rosetta__paragraph'>Show that <big>$A(x_1,\\ldots,x_n) \\geq G(x_1,\\ldots,x_n) \\geq H(x_1,\\ldots,x_n)$</big> for this set of positive integers.</p> The most common of the three means, the <a class='rosetta__link--rosetta' href='http://rosettacode.org/wiki/Averages/Arithmetic mean' title='Averages/Arithmetic mean'>arithmetic mean</a>, is the sum of the list divided by its length: <big>$ A(x_1, \\ldots, x_n) = \\frac{x_1 + \\cdots + x_n}{n}$</big>The <a class='rosetta__link--wiki' href='https://en.wikipedia.org/wiki/Geometric mean' title='wp: Geometric mean'>geometric mean</a> is the $n$th root of the product of the list: <big>$ G(x_1, \\ldots, x_n) = \\sqrt[n]{x_1 \\cdots x_n} $</big>The <a class='rosetta__link--wiki' href='https://en.wikipedia.org/wiki/Harmonic mean' title='wp: Harmonic mean'>harmonic mean</a> is $n$ divided by the sum of the reciprocal of each item in the list: <big>$ H(x_1, \\ldots, x_n) = \\frac{n}{\\frac{1}{x_1} + \\cdots + \\frac{1}{x_n}} $</big>",
"<p class='rosetta__paragraph'>Assume the input is an ordered array of all inclusive numbers.</p>",
"<p class='rosetta__paragraph'>For the answer, please output an object in the following format:</p>",
"<pre class='rosetta__pre'>",
"{",
" values: {",
" Arithmetic: 5.5,",
" Geometric: 4.528728688116765,",
" Harmonic: 3.414171521474055",
" },",
" test: 'is A >= G >= H ? yes'",
"}",
"</pre>"
],
"challengeSeed":[
"function pythagoreanMeans (rangeArr) {",
" // Good luck!",
"}"
],
"solutions":[
"function pythagoreanMeans (rangeArr) {\n // arithmeticMean :: [Number] -> Number\n const arithmeticMean = xs =>\n foldl((sum, n) => sum + n, 0, xs) / length(xs);\n\n // geometricMean :: [Number] -> Number\n const geometricMean = xs =>\n raise(foldl((product, x) => product * x, 1, xs), 1 / length(xs));\n\n // harmonicMean :: [Number] -> Number\n const harmonicMean = xs =>\n length(xs) / foldl((invSum, n) => invSum + (1 / n), 0, xs);\n\n // GENERIC FUNCTIONS ------------------------------------------------------\n\n // A list of functions applied to a list of arguments\n // <*> :: [(a -> b)] -> [a] -> [b]\n const ap = (fs, xs) => //\n Array.prototype.concat(...fs.map(f => //\n Array.prototype.concat(...xs.map(x => [f(x)]))));\n\n // foldl :: (b -> a -> b) -> b -> [a] -> b\n const foldl = (f, a, xs) => xs.reduce(f, a);\n\n // length :: [a] -> Int\n const length = xs => xs.length;\n\n // mapFromList :: [(k, v)] -> Dictionary\n const mapFromList = kvs =>\n foldl((a, [k, v]) =>\n (a[(typeof k === 'string' && k)] = v, a), {}, kvs);\n\n // raise :: Num -> Int -> Num\n const raise = (n, e) => Math.pow(n, e);\n/*\n // show :: a -> String\n // show :: a -> Int -> String\n const show = (...x) =>\n JSON.stringify.apply(\n null, x.length > 1 ? [x[0], null, x[1]] : x\n );\n*/\n // zip :: [a] -> [b] -> [(a,b)]\n const zip = (xs, ys) =>\n xs.slice(0, Math.min(xs.length, ys.length))\n .map((x, i) => [x, ys[i]]);\n\n // TEST -------------------------------------------------------------------\n // mean :: Dictionary\n const mean = mapFromList(zip(\n ['Arithmetic', 'Geometric', 'Harmonic'],\n ap([arithmeticMean, geometricMean, harmonicMean], [\n rangeArr\n ])\n ));\n\n return {\n values: mean,\n test: `is A >= G >= H ? ${mean.Arithmetic >= mean.Geometric &&\n mean.Geometric >= mean.Harmonic ? 'yes' : 'no'}`\n };\n}\n"
"assert(typeof pythagoreanMeans === 'function', 'message: <code>pythagoreanMeans</code> is a function.');",
"assert.deepEqual(pythagoreanMeans(range1), answer1, 'message: <code>pythagoreanMeans([1, 2, ..., 10])</code> should equal the same output above.');"
],
"id":"594d966a1467eb84194f0086",
"challengeType":5,
"releasedOn":"August 5, 2017"
},
{
"title":"Averages/Root mean square",
"type":"Waypoint",
"description":[
"<p>Compute the <a href=\"https://en.wikipedia.org/wiki/Root mean square\" title=\"wp: Root mean square\">Root mean square</a> of the numbers 1 through 10 inclusive.</p>",
"<p>The root mean square is also known by its initials RMS (or rms), and as the quadratic mean.</p><p>The RMS is calculated as the mean of the squares of the numbers, square-rooted:</p>",
"<p><a href=\"https://en.wikipedia.org/wiki/Charles_Babbage\" title=\"wp: Charles_Babbage\">Charles Babbage</a>, looking ahead to the sorts of problems his Analytical Engine would be able to solve, gave this example:</p>",
"<blockquote>What is the smallest positive integer whose square ends in the digits 269,696?</blockquote>",
" <p> - Babbage, letter to Lord Bowden, 1837; see Hollingdale and Tootill, <i>Electronic Computers</i>, second edition, 1970, p. 125.</p>",
"<p>He thought the answer might be 99,736, whose square is 9,947,269,696; but he couldn't be certain.</p>",
"<p>The task is to find out if Babbage had the right answer.</p>",
"<p>Implement a function to return the lowest integer that satisfies the Babbage problem. If Babbage was right, return Babbage's number.</p>"
],
"challengeSeed":[
"function babbage (babbageNum, endDigits) {",
" // Good luck!",
" return true;",
"}"
],
"solutions":[
"function babbage (babbageAns, endDigits) {\n const babbageNum = Math.pow(babbageAns, 2);\n const babbageStartDigits = parseInt(babbageNum.toString().replace('269696', ''));\n let answer = 99736;\n\n // count down from this answer and save any sqrt int result. return lowest one\n for (let i = babbageStartDigits; i >= 0; i--) {\n const num = parseInt(i.toString().concat('269696'));\n const result = Math.sqrt(num);\n if (result === Math.floor(Math.sqrt(num))) {\n answer = result;\n }\n }\n\n return answer;\n}\n"
],
"tail":[
"const babbageAns = 99736;",
"const endDigits = 269696;",
"const answer = 25264;"
],
"tests":[
"assert(typeof babbage === 'function', 'message: <code>babbage</code> is a function.');",
"assert.equal(babbage(babbageAns, endDigits), answer, 'message: <code>babbage(99736, 269696)</code> should not return 99736 (there is a smaller answer).');"
],
"id":"594db4d0dedb4c06a2a4cefd",
"challengeType":5,
"releasedOn":"August 5, 2017"
},
{
"title":"Balanced brackets",
"type":"Waypoint",
"description":[
"<p>Determine whether a generated string of brackets is balanced; that is, whether it consists entirely of pairs of opening/closing brackets (in that order), none of which mis-nest.</p>",
"function isBalanced (str) {\n if (str === '') return true;\n let a = str;\n let b;\n do {\n b = a;\n a = a.replace(/\\[\\]/g, '');\n } while (a !== b);\n return !a;\n}\n"
],
"tail":[
"const testCases = [",
" '[]',",
" ']][[[][][][]][',",
" '[][[[[][][[[]]]]]]',",
" '][',",
" '[[[]]]][[]',",
" '][[]',",
" '][[][]][[[]]',",
" '[[][]]][',",
" '[[[]]][[]]]][][[',",
" '[]][[]]][[[[][]]',",
" '][]][[][',",
" '[[]][[][]]',",
" '[[]]',",
" ']][]][[]][[[',",
" '][]][][[',",
" '][][',",
" '[[]]][][][[]][',",
" ''",
"];"
],
"tests":[
"assert(typeof isBalanced === 'function', 'message: <code>isBalanced</code> is a function.');",
"assert(isBalanced(testCases[0]), 'message: <code>isBalanced(\"[]\")</code> should return true.');",
"assert(!isBalanced(testCases[1]), 'message: <code>isBalanced(\"]][[[][][][]][\")</code> should return false.');",
"assert(isBalanced(testCases[2]), 'message: <code>isBalanced(\"[][[[[][][[[]]]]]]\")</code> should return true.');",
"assert(!isBalanced(testCases[3]), 'message: <code>isBalanced(\"][\")</code> should return true.');",
"assert(!isBalanced(testCases[4]), 'message: <code>isBalanced(\"[[[]]]][[]\")</code> should return true.');",
"assert(!isBalanced(testCases[5]), 'message: <code>isBalanced(\"][[]\")</code> should return true.');",
"assert(!isBalanced(testCases[6]), 'message: <code>isBalanced(\"][[][]][[[]]\")</code> should return true.');",
"assert(!isBalanced(testCases[7]), 'message: <code>isBalanced(\"[[][]]][\")</code> should return true.');",
"assert(!isBalanced(testCases[8]), 'message: <code>isBalanced(\"[[[]]][[]]]][][[\")</code> should return true.');",
"assert(!isBalanced(testCases[9]), 'message: <code>isBalanced(\"[]][[]]][[[[][]]\")</code> should return true.');",
"assert(!isBalanced(testCases[10]), 'message: <code>isBalanced(\"][]][[][\")</code> should return true.');",
"assert(isBalanced(testCases[11]), 'message: <code>isBalanced(\"[[]][[][]]\")</code> should return true.');",
"assert(isBalanced(testCases[12]), 'message: <code>isBalanced(\"[[]]\")</code> should return true.');",
"assert(!isBalanced(testCases[13]), 'message: <code>isBalanced(\"]][]][[]][[[\")</code> should return true.');",
"assert(!isBalanced(testCases[14]), 'message: <code>isBalanced(\"][]][][[\")</code> should return true.');",
"assert(!isBalanced(testCases[15]), 'message: <code>isBalanced(\"][][\")</code> should return true.');",
"assert(!isBalanced(testCases[16]), 'message: <code>isBalanced(\"[[]]][][][[]][\")</code> should return true.');",
"assert(isBalanced(testCases[17]), 'message: <code>isBalanced(\"\")</code> should return true.');"
],
"id":"594dc6c729e5700999302b45",
"challengeType":5,
"releasedOn":"August 5, 2017"
},
{
"title":"Circles of given radius through two points",
"type":"Waypoint",
"description":[
"<p>Given two points on a plane and a radius, usually two circles of given radius can be drawn through the points.</p>",
"Exceptions:",
"A radius of zero should be treated as never describing circles (except in the case where the points are coincident).",
"If the points are coincident then an infinite number of circles with the point on their circumference can be drawn, unless the radius is equal to zero as well which then collapses the circles to a point.",
"If the points form a diameter then return a single circle.",
"If the points are too far apart then no circles can be drawn.Task:",
"Implement a function that takes two points and a radius and returns the two circles through those points. For each resulting circle, provide the coordinates for the center of each circle rounded to four decimal digits. Return each coordinate as an array, and coordinates as an array of arrays.",
"For edge cases, return the following:",
"If points are on the diameter, return one point. If the radius is also zero however, return <code>\"Radius Zero\"</code>.",
"If points are coincident, return <code>\"Coincident point. Infinite solutions\"</code>.",
"If points are farther apart than the diameter, return <code>\"No intersection. Points further apart than circle diameter\"</code>.",
"Sample inputs:",
"<pre>",
" p1 p2 r",
"0.1234, 0.9876 0.8765, 0.2345 2.0",
"0.0000, 2.0000 0.0000, 0.0000 1.0",
"0.1234, 0.9876 0.1234, 0.9876 2.0",
"0.1234, 0.9876 0.8765, 0.2345 0.5",
"0.1234, 0.9876 0.1234, 0.9876 0.0",
"</pre>",
"Ref:",
"<a href=\"http://mathforum.org/library/drmath/view/53027.html\" title=\"link: http://mathforum.org/library/drmath/view/53027.html\">Finding the Center of a Circle from 2 Points and Radius</a> from Math forum @ Drexel"
],
"challengeSeed":[
"function getCircles (...args) {",
" // Good luck!",
" return true;",
"}"
],
"solutions":[
"const hDist = (p1, p2) => Math.hypot(...p1.map((e, i) => e - p2[i])) / 2;\nconst pAng = (p1, p2) => Math.atan(p1.map((e, i) => e - p2[i]).reduce((p, c) => c / p, 1));\nconst solveF = (p, r) => t => [parseFloat((r * Math.cos(t) + p[0]).toFixed(4)), parseFloat((r * Math.sin(t) + p[1]).toFixed(4))];\nconst diamPoints = (p1, p2) => p1.map((e, i) => parseFloat((e + (p2[i] - e) / 2).toFixed(4)));\n\nfunction getCircles (...args) {\n const [p1, p2, s] = args;\n const solve = solveF(p1, s);\n const halfDist = hDist(p1, p2);\n\n let msg = [];\n switch (Math.sign(s - halfDist)) {\n case 0:\n msg = s ? diamPoints(p1, p2) :\n 'Radius Zero';\n break;\n case 1:\n if (!halfDist) {\n msg = 'Coincident point. Infinite solutions';\n }\n else {\n const theta = pAng(p1, p2);\n const theta2 = Math.acos(halfDist / s);\n [1, -1].map(e => solve(theta + e * theta2)).forEach(\n e => msg.push(e));\n }\n break;\n case -1:\n msg = 'No intersection. Points further apart than circle diameter';\n break;\n default:\n msg = 'Reached the default';\n }\n return msg;\n}\n"
],
"tail":[
"const testCases = [",
" [[0.1234, 0.9876], [0.8765, 0.2345], 2.0],",
" [[0.0000, 2.0000], [0.0000, 0.0000], 1.0],",
" [[0.1234, 0.9876], [0.1234, 0.9876], 2.0],",
" [[0.1234, 0.9876], [0.8765, 0.2345], 0.5],",
" [[0.1234, 0.9876], [0.1234, 0.9876], 0.0]",
"];",
"const answers = [",
" [[1.8631, 1.9742], [-0.8632, -0.7521]],",
" [0, 1],",
" 'Coincident point. Infinite solutions',",
" 'No intersection. Points further apart than circle diameter',",
" 'Radius Zero'",
"];"
],
"tests":[
"assert(typeof getCircles === 'function', 'message: <code>getCircles</code> is a function.');",
"assert.deepEqual(getCircles(...testCases[3]), answers[3], 'message: <code>getCircles([0.1234, 0.9876], [0.8765, 0.2345], 0.5)</code> should return <code>No intersection. Points further apart than circle diameter</code>');",
"<p>Provide a function to find the closest two points among a set of given points in two dimensions, i.e. to solve the <a href=\"https://en.wikipedia.org/wiki/Closest pair of points problem\" title=\"wp: Closest pair of points problem\">Closest pair of points problem</a> in the planar case.</p><p>The straightforward solution is a O(n<sup>2</sup>) algorithm (which we can call brute-force algorithm); the pseudo-code (using indexes) could be simply:</p>",
"<pre>",
"bruteForceClosestPair of P(1), P(2), ... P(N)",
"if N < 2 then",
" return ∞",
"else",
" minDistance ← |P(1) - P(2)|",
" minPoints ← { P(1), P(2) }",
" foreach i ∈ [1, N-1]",
" foreach j ∈ [i+1, N]",
" if |P(i) - P(j)| < minDistance then",
" minDistance ← |P(i) - P(j)|",
" minPoints ← { P(i), P(j) }",
" endif",
" endfor",
" endfor",
" return minDistance, minPoints",
"endif",
"</pre>",
"<p>A better algorithm is based on the recursive divide&conquer approach, as explained also at <a href=\"https://en.wikipedia.org/wiki/Closest pair of points problem#Planar_case\" title=\"wp: Closest pair of points problem#Planar_case\">Wikipedia's Closest pair of points problem</a>, which is O(n log n); a pseudo-code could be:</p>",
"<pre>",
"closestPair of (xP, yP)",
" where xP is P(1) .. P(N) sorted by x coordinate, and",
" yP is P(1) .. P(N) sorted by y coordinate (ascending order)",
"if N ≤ 3 then",
" return closest points of xP using brute-force algorithm",
"<p>For the input, expect the argument to be an array of objects (points) with <code>x</code> and <code>y</code> members set to numbers. For the output, return an object containing the key:value pairs for <code>distance</code> and <code>pair</code> (i.e., the pair of two closest points).</p>"
"assert(typeof getClosestPair === 'function', 'message: <code>getClosestPair</code> is a function.');",
"assert.equal(getClosestPair(points1).distance, answer1.distance, 'message: Distance should be the following.');",
"assert.deepEqual(JSON.parse(JSON.stringify(getClosestPair(points1))).pair, answer1.pair, 'message: Points should be the following.');",
"assert.equal(getClosestPair(points2).distance, answer2.distance, 'message: Distance should be the following.');",
"assert.deepEqual(JSON.parse(JSON.stringify(getClosestPair(points2))).pair, answer2.pair, 'message: Points should be the following.');"
],
"id":"5951a53863c8a34f02bf1bdc",
"challengeType":5,
"releasedOn":"August 5, 2017"
},
{
"title":"Combinations",
"type":"Waypoint",
"description":[
"Task:",
"<p>Given non-negative integers <big> m </big> and <big> n</big>, generate all size <big> m </big> <a href=\"http://mathworld.wolfram.com/Combination.html\" title=\"link: http://mathworld.wolfram.com/Combination.html\">combinations</a> of the integers from <big> 0</big> (zero) to <big> n-1 </big> in sorted order (each combination is sorted and the entire table is sorted).</p>",
"Example:",
"<p><big>3</big> comb <big> 5 </big>is:</p>",
"<pre>",
"0 1 2",
"0 1 3",
"0 1 4",
"0 2 3",
"0 2 4",
"0 3 4",
"1 2 3",
"1 2 4",
"1 3 4",
"2 3 4",
"</pre>"
],
"challengeSeed":[
"function combinations (m, n) {",
" // Good luck!",
" return true;",
"}"
],
"solutions":[
"function combinations (m, n) {\n const nArr = [...Array(n).keys()];\n\n return (function generateCombinations (size, numArr) {\n const ret = [];\n\n for (let i = 0; i < numArr.length; i++) {\n if (size === 1) {\n ret.push([numArr[i]]);\n }\n else {\n const sub = generateCombinations(size - 1, numArr.slice(i + 1, numArr.length));\n for (let subI = 0; subI < sub.length; subI++) {\n const next = sub[subI];\n next.unshift(numArr[i]);\n ret.push(next);\n }\n }\n }\n return ret;\n }(m, nArr));\n}\n"
"<p>Comma quibbling is a task originally set by Eric Lippert in his <a href=\"http://blogs.msdn.com/b/ericlippert/archive/2009/04/15/comma-quibbling.aspx\" title=\"link: http://blogs.msdn.com/b/ericlippert/archive/2009/04/15/comma-quibbling.aspx\">blog</a>.</p>",
"Task:<p>Write a function to generate a string output which is the concatenation of input words from a list/sequence where:</p>",
"An input of no words produces the output string of just the two brace characters \"{}\".",
"An input of just one word, e.g. [\"ABC\"], produces the output string of the word inside the two braces, e.g. \"{ABC}\".",
"An input of two words, e.g. [\"ABC\", \"DEF\"], produces the output string of the two words inside the two braces with the words separated by the string \" and \", e.g. \"{ABC and DEF}\".",
"An input of three or more words, e.g. [\"ABC\", \"DEF\", \"G\", \"H\"], produces the output string of all but the last word separated by \", \" with the last word separated by \" and \" and all within braces; e.g. \"{ABC, DEF, G and H}\".",
"<p>Test your function with the following series of inputs showing your output here on this page:</p>",
"[] # (No input words).",
"[\"ABC\"]",
"[\"ABC\", \"DEF\"]",
"[\"ABC\", \"DEF\", \"G\", \"H\"]",
"<p>Note: Assume words are non-empty strings of uppercase characters for this task.</p>"
"const results = [\"{}\", \"{ABC}\", \"{ABC and DEF}\", \"{ABC,DEF,G and H}\"];"
],
"tests":[
"assert(typeof quibble === 'function', 'message: <code>quibble</code> is a function.');",
"assert(typeof quibble([\"ABC\"]) === 'string', 'message: <code>quibble([\"ABC\"])</code> should return a string.');",
"assert.equal(quibble(testCases[0]), results[0], 'message: <code>quibble([])</code> should return \"{}\".');",
"assert.equal(quibble(testCases[1]), results[1], 'message: <code>quibble([\"ABC\"])</code> should return \"{ABC}\".');",
"assert.equal(quibble(testCases[2]), results[2], 'message: <code>quibble([\"ABC\", \"DEF\"])</code> should return \"{ABC and DEF}\".');",
"assert.equal(quibble(testCases[3]), results[3], 'message: <code>quibble([\"ABC\", \"DEF\", \"G\", \"H\"])</code> should return \"{ABC,DEF,G and H}\".');"
],
"id":"596e414344c3b2872167f0fe",
"challengeType":5,
"releasedOn":"August 5, 2017"
},
{
"title":"Compare a list of strings",
"type":"Waypoint",
"description":[
"<p>Given a <a href=\"https://en.wikipedia.org/wiki/List_(abstract_data_type)\" title=\"wp: List_(abstract_data_type)\">list</a> of arbitrarily many strings, implement a function for each of the following conditions:</p> test if they are all lexically equal",
" test if every string is lexically less than the one after it (i.e. whether the list is in strict ascending order)"
],
"challengeSeed":[
"function allEqual (arr) {",
" // Good luck!",
" return true;",
"}",
"",
"function azSorted (arr) {",
" // Good luck!",
" return true;",
"}"
],
"solutions":[
"function allEqual(a) {\n let out = true;\n let i = 0;\n while (++i < a.length) {\n out = out && (a[i - 1] === a[i]);\n } return out;\n}\n\nfunction azSorted(a) {\n let out = true;\n let i = 0;\n while (++i < a.length) {\n out = out && (a[i - 1] < a[i]);\n } return out;\n}\n"
"takes a positive integer representing a duration in seconds as input (e.g., <code>100</code>), and",
"returns a string which shows the same duration decomposed into weeks, days, hours, minutes, and seconds as detailed below (e.g., \"<code>1 min, 40 sec</code>\").",
"<p>Demonstrate that it passes the following three test-cases:</p><p style=\"font-size:115%; margin:1em 0 0 0\">Test Cases</p>",
"However, only include quantities with non-zero values in the output (e.g., return \"<code>1 d</code>\" and not \"<code>0 wk, 1 d, 0 hr, 0 min, 0 sec</code>\").Give larger units precedence over smaller ones as much as possible (e.g., return <code>2 min, 10 sec</code> and not <code>1 min, 70 sec</code> or <code>130 sec</code>)Mimic the formatting shown in the test-cases (quantities sorted from largest unit to smallest and separated by comma+space; value and unit of each quantity separated by space).",
"<p>Create a function, or show a built-in function, to count the number of non-overlapping occurrences of a substring inside a string.</p><p>The function should take two arguments:</p>",
"the first argument being the string to search, and",
"the second a substring to be searched for.",
"<p>It should return an integer count.</p>",
"<p>The matching should yield the highest number of non-overlapping matches.</p><p>In general, this essentially means matching from left-to-right or right-to-left.</p>"
"const testCases = ['the three truths', 'ababababab', 'abaabba*bbaba*bbab'];",
"const searchString = ['th', 'abab', 'a*b'];",
"const results = [3, 2, 2];"
],
"tests":[
"assert(typeof countSubstring === 'function', 'message: <code>countSubstring</code> is a function.');",
"assert.equal(countSubstring(testCases[0], searchString[0]), results[0], 'message: <code>countSubstring(\"the three truths\", \"th\")</code> should return <code>3</code>.');",
"assert.equal(countSubstring(testCases[1], searchString[1]), results[1], 'message: <code>countSubstring(\"ababababab\", \"abab\")</code> should return <code>2</code>.');",
"assert.equal(countSubstring(testCases[2], searchString[2]), results[2], 'message: <code>countSubstring(\"abaabba*bbaba*bbab\", \"a*b\")</code> should return <code>2</code>.');"
],
"id":"596fda99c69f779975a1b67d",
"challengeType":5,
"releasedOn":"August 5, 2017"
},
{
"title":"Count the coins",
"type":"Waypoint",
"description":[
"<p>There are four types of common coins in <a href=\"https://en.wikipedia.org/wiki/United_States\" title=\"link: https://en.wikipedia.org/wiki/United_States\">US</a> currency:</p>",
"quarters (25 cents)",
"dimes (10 cents)",
"nickels (5 cents), and ",
"pennies (1 cent) ",
"<p>There are six ways to make change for 15 cents:</p>",
"A dime and a nickel ",
"A dime and 5 pennies",
"3 nickels",
"2 nickels and 5 pennies",
"A nickel and 10 pennies",
"15 pennies",
"Task:",
"<p>Implement a function to determine how many ways there are to make change for a dollar using these common coins? (1 dollar = 100 cents).</p>",
"Reference:",
" <a href=\"http://mitpress.mit.edu/sicp/full-text/book/book-Z-H-11.html#%_sec_Temp_52\" title=\"link: http://mitpress.mit.edu/sicp/full-text/book/book-Z-H-11.html#%_sec_Temp_52\">an algorithm from MIT Press</a>. "
],
"challengeSeed":[
"function countCoins () {",
" // Good luck!",
" return true;",
"}"
],
"solutions":[
"function countCoins () {\n let t = 100;\n const operands = [1, 5, 10, 25];\n const targetsLength = t + 1;\n const operandsLength = operands.length;\n t = [1];\n\n for (let a = 0; a < operandsLength; a++) {\n for (let b = 1; b < targetsLength; b++) {\n // initialise undefined target\n t[b] = t[b] ? t[b] : 0;\n\n // accumulate target + operand ways\n t[b] += (b < operands[a]) ? 0 : t[b - operands[a]];\n }\n }\n\n return t[targetsLength - 1];\n}\n"
],
"tests":[
"assert(typeof countCoins === 'function', 'message: <code>countCoins</code> is a function.');",
"assert.equal(countCoins(), 242, 'message: <code>countCoints()</code> should return 242.');"
],
"id":"59713bd26bdeb8a594fb9413",
"challengeType":5,
"releasedOn":"August 5, 2017"
},
{
"title":"Cramer's rule",
"type":"Waypoint",
"description":[
"<p>In <a href=\"https://en.wikipedia.org/wiki/linear algebra\" title=\"wp: linear algebra\">linear algebra</a>, <a href=\"https://en.wikipedia.org/wiki/Cramer's rule\" title=\"wp: Cramer's rule\">Cramer's rule</a> is an explicit formula for the solution of a <a href=\"https://en.wikipedia.org/wiki/system of linear equations\" title=\"wp: system of linear equations\">system of linear equations</a> with as many equations as unknowns, valid whenever the system has a unique solution. It expresses the solution in terms of the determinants of the (square) coefficient matrix and of matrices obtained from it by replacing one column by the vector of right hand sides of the equations.</p>",
"<p>Given the following system of equations:</p><p><big>",
"$\\begin{cases}",
"2w-x+5y+z=-3 \\\\",
"3w+2x+2y-6z=-32 \\\\",
"w+3x+3y-z=-47 \\\\",
"5w-2x-3y+3z=49 \\\\",
"\\end{cases}$",
"</big></p>",
"<p>solve for <big>$w$, $x$, $y$</big> and <big>$z$</big>, using Cramer's rule.</p>"
],
"challengeSeed":[
"function cramersRule (matrix, freeTerms) {",
" // Good luck!",
" return true;",
"}"
],
"solutions":[
"/**\n * Compute Cramer's Rule\n * @param {array} matrix x,y,z, etc. terms\n * @param {array} freeTerms\n * @return {array} solution for x,y,z, etc.\n */\nfunction cramersRule(matrix, freeTerms) {\n const det = detr(matrix);\n const returnArray = [];\n let i;\n\n for (i = 0; i < matrix[0].length; i++) {\n const tmpMatrix = insertInTerms(matrix, freeTerms, i);\n returnArray.push(detr(tmpMatrix) / det);\n }\n return returnArray;\n}\n\n/**\n * Inserts single dimensional array into\n * @param {array} matrix multidimensional array to have ins inserted into\n * @param {array} ins single dimensional array to be inserted vertically into matrix\n * @param {array} at zero based offset for ins to be inserted into matrix\n * @return {array} New multidimensional array with ins replacing the at column in matrix\n */\nfunction insertInTerms(matrix, ins, at) {\n const tmpMatrix = clone(matrix);\n let i;\n for (i = 0; i < matrix.length; i++) {\n tmpMatrix[i][at] = ins[i];\n }\n return tmpMatrix;\n}\n/**\n * Compute the determinate of a matrix. No protection, assumes square matrix\n * function borrowed, and adapted from MIT Licensed numericjs library (www.numericjs.com)\n * @param {array} m Input Matrix (multidimensional array)\n * @return {number} result rounded to 2 decimal\n */\nfunction detr(m) {\n let ret = 1;\n let j;\n let k;\n const A = clone(m);\n const n = m[0].length;\n let alpha;\n\n for (j = 0; j < n - 1; j++) {\n k = j;\n for (let i = j + 1; i < n; i++) { if (Math.abs(A[i][j]) > Math.abs(A[k][j])) { k = i; } }\n if (k !== j) {\n const temp = A[k]; A[k] = A[j]; A[j] = temp;\n ret *= -1;\n }\n const Aj = A[j];\n for (let i = j + 1; i < n; i++) {\n const Ai = A[i];\n alpha = Ai[j] / Aj[j];\n for (k = j + 1; k < n - 1; k += 2) {\n const k1 = k + 1;\n Ai[k] -= Aj[k] * alpha;\n Ai[k1] -= Aj[k1] * alpha;\n }\n if (k !== n) { Ai[k] -= Aj[k] * alpha; }\n }\n if (Aj[j] === 0) { return 0; }\n ret *= Aj[j];\n }\n return Math.round(ret * A[j][j] * 100) / 100;\n}\n\n/**\n * Clone two dimensional Array using ECMAScript 5 map function and EcmaScript 3 slice\n * @param {array} m Input matrix (multidimensional array) to clone\n * @return {array} New matrix copy\n */\nfunction clone(m) {\n return m.map(a => a.slice());\n}\n"
"assert(add12Hours(tests[1]) === answers[1], 'message: Should handel day change. <code>add12Hours(\"' + tests[1] + '\")</code> should return <code>\"' + answers[1] + '\"</code>');",
"assert(add12Hours(tests[2]) === answers[2], 'message: Should handel month change in a leap years. <code>add12Hours(\"' + tests[2] + '\")</code> should return <code>\"' + answers[2] + '\"</code>');",
"assert(add12Hours(tests[3]) === answers[3], 'message: Should handel month change in a common years. <code>add12Hours(\"' + tests[3] + '\")</code> should return <code>\"' + answers[3] + '\"</code>');",
"assert(add12Hours(tests[4]) === answers[4], 'message: Should handel year change. <code>add12Hours(\"' + tests[4] + '\")</code> should return <code>\"' + answers[4] + '\"</code>');"
],
"id":"5966c21cf732a95f1b67dd28",
"challengeType":5,
"releasedOn":"August 5, 2017"
},
{
"title":"Day of the week",
"type":"Waypoint",
"description":[
"<p>A company decides that whenever Xmas falls on a Sunday they will give their workers all extra paid holidays so that, together with any public holidays, workers will not have to work the following week (between the 25th of December and the first of January).</p>",
"<p>Task:</p>",
"<p>Write a function that takes a start year and an end year and return an array of all the years where the 25th of December will be a Sunday.</p>"
],
"challengeSeed":[
"function findXmasSunday (start, end) {",
" // Good luck!",
" return true;",
"}"
],
"solutions":[
"function findXmasSunday (start, end) {\n const xmasSunday = [];\n for (let year = start; year <= end; year++) {\n const xmas = new Date(year, 11, 25);\n if (xmas.getDay() === 0) {\n xmasSunday.push(year);\n }\n }\n return xmasSunday;\n}\n"
"<p>Free Cell is the solitaire card game that Paul Alfille introduced to the PLATO system in 1978. Jim Horne, at Microsoft, changed the name to FreeCell and reimplemented the game for <a href=\"http://rosettacode.org/wiki/DOS\" title=\"DOS\">DOS</a>, then <a href=\"http://rosettacode.org/wiki/Windows\" title=\"Windows\">Windows</a>. </p>",
"<p>This version introduced 32000 numbered deals. (The <a href=\"http://www.solitairelaboratory.com/fcfaq.html\" title=\"link: http://www.solitairelaboratory.com/fcfaq.html\">FreeCell FAQ</a> tells this history.)</p><p>As the game became popular, Jim Horne disclosed <a href=\"http://www.solitairelaboratory.com/mshuffle.txt\" title=\"link: http://www.solitairelaboratory.com/mshuffle.txt\">the algorithm</a>, and other implementations of FreeCell began to reproduce the Microsoft deals. </p>",
"<p>These deals are numbered from 1 to 32000.</p>",
"<p>Newer versions from Microsoft have 1 million deals, numbered from 1 to 1000000; some implementations allow numbers outside that range.</p><p>The algorithm uses this <a href=\"http://rosettacode.org/wiki/linear congruential generator\" title=\"linear congruential generator\">linear congruential generator</a> from Microsoft C:</p>$state_{n + 1} \\equiv 214013 \\times state_n + 2531011 \\pmod{2^{31}}$",
"$rand_n = state_n \\div 2^{16}$",
"$rand_n$ is in range 0 to 32767.",
"<p>The algorithm follows:</p>Seed the RNG with the number of the deal.",
"Create an <a href=\"http://rosettacode.org/wiki/array\" title=\"array\">array</a> of 52 cards: Ace of Clubs, Ace of Diamonds, Ace of Hearts, Ace of Spades, 2 of Clubs, 2 of Diamonds, and so on through the ranks: Ace, 2, 3, 4, 5, 6, 7, 8, 9, 10, Jack, Queen, King. The array indexes are 0 to 51, with Ace of Clubs at 0, and King of Spades at 51.",
"Until the array is empty:",
" Choose a random card at index ≡ next random number (mod array length). ",
" Swap this random card with the last card of the array.",
" Remove this random card from the array. (Array length goes down by 1.)",
" Deal this random card.",
"Deal all 52 cards, face up, across 8 columns. The first 8 cards go in 8 columns, the next 8 cards go on the first 8 cards, and so on.",
"<p>Write a function to take a deal number and deal cards in the same order as this algorithm.</p>",
"<p>The function must return a two dimentional array representing the FreeCell board.</p>",
"<p>Deals can also be checked against <a href=\"http://freecellgamesolutions.com/\" title=\"link: http://freecellgamesolutions.com/\">FreeCell solutions to 1000000 games</a>.</p>",
"<p>(Summon a video solution, and it displays the initial deal.)</p>"
],
"challengeSeed":[
"function dealFreeCell (seed) {",
" // Good luck!",
" return true;",
"}"
],
"solutions":[
"// RNG\nfunction FreeCellRNG (seed) {\n return {\n lastNum: seed,\n next() {\n this.lastNum = ((214013 * this.lastNum) + 2531011) % (Math.pow(2, 31));\n return this.lastNum >> 16;\n }\n };\n}\n// Get cards\nfunction getDeck() {\n const ranks = ['A', '2', '3', '4', '5', '6', '7', '8', '9', 'T', 'J', 'Q', 'K'];\n const suits = ['C', 'D', 'H', 'S'];\n const cards = [];\n for (let i = 0; i < ranks.length; i += 1) {\n for (let j = 0; j < suits.length; j += 1) {\n cards.push(`${ranks[i]}${suits[j]}`);\n }\n }\n return cards;\n}\nfunction dealFreeCell(seed) {\n const rng = FreeCellRNG(seed);\n const deck = getDeck();\n\n const deltCards = [[], [], [], [], [], [], []];\n let currentColumn = 0;\n let currentRow = 0;\n\n let rand;\n let temp;\n let card;\n while (deck.length > 0) {\n // Choose a random card\n rand = rng.next() % deck.length;\n\n // Swap this random card with the last card in the array\n temp = deck[deck.length - 1];\n deck[deck.length - 1] = deck[rand];\n deck[rand] = temp;\n\n // Remove this card from the array\n card = deck.pop();\n\n // Deal this card\n deltCards[currentRow].push(card);\n currentColumn += 1;\n if (currentColumn === 8) {\n currentColumn = 0;\n currentRow += 1;\n }\n }\n\n return deltCards;\n}\n"
"assert(typeof deepcopy === 'function', 'message: <code>deepcopy</code> should be a function.');",
"assert(typeof deepcopy(obj1) === 'object', 'message: <code>deepcopy({test: \"test\"})</code> should return an object.');",
"assert(deepcopy(obj2) != obj2, 'message: Should not return the same object that was provided.');",
"assert.deepEqual(deepcopy(obj2), obj2, 'message: When passed an object containing an array, should return a deep copy of the object.');",
"assert.deepEqual(deepcopy(obj3), obj3, 'message: When passed an object containing another object, should return a deep copy of the object.');"
],
"id":"596a8888ab7c01048de257d5",
"challengeType":5,
"releasedOn":"August 5, 2017"
},
{
"title":"Define a primitive data type",
"type":"Waypoint",
"description":[
"Task:",
"<p>Define a type that behaves like an integer but has a lowest valid value of 1 and a highest valid value of 10.</p>",
"Errors:",
"If you try to instantiate a <code>Num</code> with a value outside of 1 - 10",
"it should throw a <code>TypeError</code> with an error message of <code>'Out of range'</code>.",
"If you try to instantiate a <code>Num</code> with a value that is not a number",
"it should throw a <code>TypeError</code> with an error message of <code>'Not a Number'</code>."
],
"challengeSeed":[
"function Num (n) {",
" // Good luck!",
" return n;",
"}"
],
"solutions":[
"function Num(n) {\n const num = Math.floor(n);\n if (isNaN(num)) {\n throw new TypeError('Not a Number');\n }\n if (num < 1 || num > 10) {\n throw new TypeError('Out of range');\n }\n\n this._value = num;\n}\nNum.prototype.valueOf = function() { return this._value; };\nNum.prototype.toString = function () { return this._value.toString(); };\n\nfunction throws(func, errorType, msg) {\n let hasThrown = false;\n let errorMsg = '';\n let correctType = false;\n try {\n func();\n }\n catch (e) {\n hasThrown = true;\n errorMsg = e.message;\n if (e instanceof errorType) {\n correctType = true;\n }\n }\n return hasThrown && correctType && msg === errorMsg;\n}\n"
],
"tail":[],
"tests":[
"assert(typeof Num === 'function', 'message: <code>Num</code> should be a function.');",
"assert(typeof (new Num(4)) === 'object', 'message: <code>new Num(4)</code> should return an object.');",
"assert(throws(() => new Num('test'), TypeError, 'Not a Number'), 'message: <code>new Num(\\'test\\')</code> should throw a TypeError with message \\'Not a Number\\'.');",
"assert(throws(() => new Num(0), TypeError, 'Out of range'), 'message: <code>new Num(0)</code> should throw a TypeError with message \\'Out of range\\'.');",
"assert(throws(() => new Num(-5), TypeError, 'Out of range'), 'message: <code>new Num(-5)</code> should throw a TypeError with message \\'Out of range\\'.');",
"assert(throws(() => new Num(11), TypeError, 'Out of range'), 'message: <code>new Num(10)</code> should throw a TypeError with message \\'Out of range\\'.');",
"assert(throws(() => new Num(20), TypeError, 'Out of range'), 'message: <code>new Num(20)</code> should throw a TypeError with message \\'Out of range\\'.');",
"assert.equal(new Num(3) + new Num(4), 7, 'message: <code>new Num(3) + new Num(4)</code> should equal 7.');",
"assert.equal(new Num(3) - new Num(4), -1, 'message: <code>new Num(3) - new Num(4)</code> should equal -1.');",
"assert.equal(new Num(3) * new Num(4), 12, 'message: <code>new Num(3) * new Num(4)</code> should equal 12.');",
"assert.equal(new Num(3) / new Num(4), 0.75, 'message: <code>new Num(3) / new Num(4)</code> should equal 0.75.');",
"assert(new Num(3) < new Num(4), 'message: <code>new Num(3) < new Num(4)</code> should be true.');",
"assert(!(new Num(3) > new Num(4)), 'message: <code>new Num(3) > new Num(4)</code> should be false.');",
"assert.equal((new Num(5)).toString(), '5', 'message: <code>(new Num(5)).toString()</code> should return \\'5\\'');"
],
"id":"597089c87eec450c68aa1643",
"challengeType":5,
"releasedOn":"August 5, 2017"
},
{
"title":"Element-wise operations",
"type":"Waypoint",
"description":[
"<p>Implement basic element-wise matrix-matrix and scalar-matrix operations.</p><p>Implement:</p>",
"<p>::* addition</p>",
"<p>::* subtraction</p>",
"<p>::* multiplication</p>",
"<p>::* division</p>",
"<p>::* exponentiation</p>",
"<p>The first parameter will be the operation to be performed, for example : \"m_add\" for matrix addition and \"s_add\" for scalar addition. The second and third parameters will be the matrices on which the operations are to be performed."
],
"challengeSeed":[
"function operation (op, arr1, arr2) {",
" // Good luck!",
"}"
],
"solutions":[
"function operation(op, arr1, arr2) {\n const ops = {\n add: ((a, b) => a + b),\n sub: ((a, b) => a - b),\n mult: ((a, b) => a * b),\n div: ((a, b) => a / b),\n exp: ((a, b) => Math.pow(a, b))\n };\n const ifm = op.startsWith('m');\n const doOp = ops[op.substring(2)];\n for (let i = 0; i < arr1.length; i++) {\n for (let j = 0; j < arr1[0].length; j++) {\n arr1[i][j] = doOp(arr1[i][j], (ifm) ? (arr2[i][j]) : (arr2));\n }\n }\n return arr1;\n}\n"
],
"tests":[
"assert(typeof operation === 'function', 'message: <code>operation</code> is a function.');",
"<p>An emirp (prime spelled backwards) are primes that when reversed (in their decimal representation) are a different prime.</p>",
"<p>Write a function that should be able to : Show the first <b>n</b> eprimes numbers.Show the eprimes numbers in a range.Show the number of eprimes in a range.Show the <b>n<sup>th</sup></b> eprimes number.<p>The function should have two paramters. The first will recieve <b>n</b> or the range as an array. The second will recieve a boolean, that specifies if the function returns the eprimes as an array or a single number(the number of primes in the range or the <b>n<sup>th</sup></b> prime). According to the parameters the function should return an array or a number."
],
"null":[],
"challengeSeed":[
"function emirps(n) {",
" // Good luck!",
"}"
],
"solutions":[
"// noprotect\nfunction emirps(num, showEmirps)\n{\n const is_prime = function(n)\n\t{\n if (!(n % 2) || !(n % 3)) return false;\n let p = 1;\n while (p * p < n)\n\t\t\t { if (n % (p += 4) == 0 || n % (p += 2) == 0)\n\t\t\t { return false; } }\n return true;\n };\n const is_emirp = function(n) {\n const r = parseInt(n.toString().split('').reverse().join(''));\n return r != n && is_prime(n) && is_prime(r);\n };\n\n let i,\n arr = [];\n if (typeof num === 'number') {\n for (i = 0; arr.length < num; i++) if (is_emirp(i)) arr.push(i);\n // first x emirps\n if (showEmirps) return arr;\n // xth emirp\n return arr.pop();\n }\n\n if (Array.isArray(num)) {\n for (i = num[0]; i <= num[1]; i++) if (is_emirp(i)) arr.push(i);\n // emirps between x .. y\n if (showEmirps) return arr;\n // number of emirps between x .. y\n return arr.length;\n }\n}\n"
],
"tests":[
"assert(typeof emirps === 'function', 'message: <code>emirps</code> is a function.');",
"assert.deepEqual(emirps([7700, 8000], false), 11, 'message:<code>emirps([7700,8000],true)</code> should return <code>11</code>');"
],
"id":"599d0ba974141b0f508b37d5",
"challengeType":5,
"releasedOn":"August 5, 2017"
},
{
"title":"Entropy",
"type":"Waypoint",
"description":[
"Task:",
"<p>Calculate the Shannon entropy H of a given input string.</p><p>Given the discreet random variable $X$ that is a string of $N$ \"symbols\" (total characters) consisting of $n$ different characters (n=2 for binary), the Shannon entropy of X in bits/symbol is :</p>",
"<p>$H_2(X) = -\\sum_{i=1}^n \\frac{count_i}{N} \\log_2 \\left(\\frac{count_i}{N}\\right)$</p><p>where $count_i$ is the count of character $n_i$.</p>"
],
"challengeSeed":[
"function entropy (s) {",
" // Good luck!",
"}"
],
"solutions":[
"function entropy(s) {\n\t// Create a dictionary of character frequencies and iterate over it.\n function process(s, evaluator) {\n let h = Object.create(null),\n k;\n s.split('').forEach(c => {\n h[c] && h[c]++ || (h[c] = 1); });\n if (evaluator) for (k in h) evaluator(k, h[k]);\n return h;\n }\n\t// Measure the entropy of a string in bits per symbol.\n\n let sum = 0,\n len = s.length;\n process(s, (k, f) => {\n const p = f / len;\n sum -= p * Math.log(p) / Math.log(2);\n });\n return sum;\n}\n"
],
"tests":[
"assert(typeof entropy === 'function', 'message: <code>entropy</code> is a function.');",
"assert.equal(entropy('0'), 0, 'message: <code>entropy(\"0\")</code> should return <code>0</code>');",
"assert.equal(entropy('01'), 1, 'message: <code>entropy(\"01\")</code> should return <code>1</code>');",
"assert.equal(entropy('0123'), 2, 'message: <code>entropy(\"0123\")</code> should return <code>2</code>');",
"assert.equal(entropy('01234567'), 3, 'message: <code>entropy(\"01234567\")</code> should return <code>3</code>');",
"assert.equal(entropy('0123456789abcdef'), 4, 'message: <code>entropy(\"0123456789abcdef\")</code> should return <code>4</code>');",
"assert.equal(entropy('1223334444'), 1.8464393446710154, 'message: <code>entropy(\"1223334444\")</code> should return <code>1.8464393446710154</code>');"
],
"id":"599d15309e88c813a40baf58",
"challengeType":5,
"releasedOn":"August 5, 2017"
},
{
"title":"Equilibrium index",
"type":"Waypoint",
"description":[
"<p>An equilibrium index of a sequence is an index into the sequence such that the sum of elements at lower indices is equal to the sum of elements at higher indices.</p>",
"<p>For example, in a sequence <big>$A$</big>:</p><p>:::: <big>$A_0 = -7$</big></p>",
"<p>:::: <big>$A_1 = 1$</big></p>",
"<p>:::: <big>$A_2 = 5$</big></p>",
"<p>:::: <big>$A_3 = 2$</big></p>",
"<p>:::: <big>$A_4 = -4$</big></p>",
"<p>:::: <big>$A_5 = 3$</big></p>",
"<p>:::: <big>$A_6 = 0$</big></p><p>3 is an equilibrium index, because:</p><p>:::: <big>$A_0 + A_1 + A_2 = A_4 + A_5 + A_6$</big></p><p>6 is also an equilibrium index, because:</p><p>:::: <big>$A_0 + A_1 + A_2 + A_3 + A_4 + A_5 = 0$</big></p><p>(sum of zero elements is zero)</p><p>7 is not an equilibrium index, because it is not a valid index of sequence <big>$A$</big>.</p>",
"<p>Write a function that, given a sequence, returns its equilibrium indices (if any).</p><p>Assume that the sequence may be very long.</p>"
],
"challengeSeed":[
"function equilibrium (a) {",
" // Good luck!",
"}"
],
"solutions":[
"function equilibrium(a) {\n let N = a.length,\n i,\n l = [],\n r = [],\n e = [];\n for (l[0] = a[0], r[N - 1] = a[N - 1], i = 1; i < N; i++)\n { l[i] = l[i - 1] + a[i], r[N - i - 1] = r[N - i] + a[N - i - 1]; }\n for (i = 0; i < N; i++)\n { if (l[i] === r[i]) e.push(i); }\n return e;\n}\n"
"assert.deepEqual(equilibrium(tests[4]), ans[4], 'message: <code>equilibrium([1])</code> should return <code>[0]</code>.');",
"assert.deepEqual(equilibrium(tests[5]), ans[5], 'message: <code>equilibrium([])</code> should return <code>[]</code>.');"
],
"id":"5987fd532b954e0f21b5d3f6",
"challengeType":5,
"releasedOn":"August 5, 2017"
},
{
"title":"Ethiopian multiplication",
"type":"Waypoint",
"description":[
"<p>Ethiopian multiplication is a method of multiplying integers using only addition, doubling, and halving.</p>",
"<p>Method: </p>",
"Take two numbers to be multiplied and write them down at the top of two columns.",
"In the left-hand column repeatedly halve the last number, discarding any remainders, and write the result below the last in the same column, until you write a value of 1.",
"In the right-hand column repeatedly double the last number and write the result below. stop when you add a result in the same row as where the left hand column shows 1.",
"Examine the table produced and discard any row where the value in the left column is even.",
"Sum the values in the right-hand column that remain to produce the result of multiplying the original two numbers together",
"<p>For example: 17 × 34</p>",
"<p>17 34</p>",
"<p>Halving the first column:</p>",
"<p>17 34</p>",
"<p>8</p>",
"<p>4</p>",
"<p>2</p>",
"<p>1</p>",
"<p>Doubling the second column:</p>",
"<p>17 34</p>",
"<p>8 68</p>",
"<p>4 136</p>",
"<p>2 272</p>",
"<p>1 544</p>",
"<p>Strike-out rows whose first cell is even:</p>",
"<p>17 34</p>",
"<p>8 <strike>68</strike></p>",
"<p>4 <strike>136</strike></p>",
"<p>2 <strike>272</strike></p>",
"<p>1 544</p>",
"<p>Sum the remaining numbers in the right-hand column:</p>",
"<p>17 34</p>",
"<p>8 --</p>",
"<p>4 ---</p>",
"<p>2 ---</p>",
"<p>1 544</p>",
"<p>====</p>",
"<p>578</p>",
"<p>So 17 multiplied by 34, by the Ethiopian method is 578.</p>",
"Task:",
"<p>The task is to define three named functions/methods/procedures/subroutines:</p>",
"one to halve an integer,",
"one to double an integer, and",
"one to state if an integer is even.",
"<p>Use these functions to create a function that does Ethiopian multiplication.</p>"
],
"challengeSeed":[
"function eth_mult (a, b) {",
" // Good luck!",
"}"
],
"solutions":[
"function eth_mult(a, b) {\n let sum = 0; a = [a]; b = [b];\n\n let half = a => a / 2,\n double = a => a * 2,\n is_even = a => a % 2 == 0;\n\n while (a[0] !== 1) {\n a.unshift(Math.floor(half(a[0])));\n b.unshift(double(b[0]));\n }\n\n for (let i = a.length - 1; i > 0; i -= 1) {\n if (!is_even(a[i])) {\n sum += b[i];\n }\n }\n return sum + b[0];\n}"
],
"tests":[
"assert(typeof eth_mult === 'function', 'message: <code>eth_mult</code> is a function.');",
"assert.equal(eth_mult(17, 34), 578, 'message: <code>eth_mult(17,34)</code> should return <code>578</code>.');",
"assert.equal(eth_mult(23, 46), 1058, 'message: <code>eth_mult(23,46)</code> should return <code>1058</code>.');",
"assert.equal(eth_mult(12, 27), 324, 'message: <code>eth_mult(12,27)</code> should return <code>324</code>.');",
"assert.equal(eth_mult(56, 98), 5488, 'message: <code>eth_mult(56,98)</code> should return <code>5488</code>.');",
"assert.equal(eth_mult(63, 74), 4662, 'message: <code>eth_mult(63,74)</code> should return <code>4662</code>.');"
],
"id":"599d1566a02b571412643b84",
"challengeType":5,
"releasedOn":"August 5, 2017"
},
{
"title":"Euler method",
"type":"Waypoint",
"description":[
"<p>Euler's method numerically approximates solutions of first-order ordinary differential equations (ODEs) with a given initial value. It is an explicit method for solving initial value problems (IVPs), as described in <a href=\"https://en.wikipedia.org/wiki/Euler method\" title=\"wp: Euler method\">the wikipedia page</a>.</p><p>The ODE has to be provided in the following form:</p><p>:: <big>$\\frac{dy(t)}{dt} = f(t,y(t))$</big></p><p>with an initial value</p><p>:: <big>$y(t_0) = y_0$</big></p><p>To get a numeric solution, we replace the derivative on the LHS with a finite difference approximation:</p><p>:: <big>$\\frac{dy(t)}{dt} \\approx \\frac{y(t+h)-y(t)}{h}$</big></p><p>then solve for $y(t+h)$:</p><p>:: <big>$y(t+h) \\approx y(t) + h \\, \\frac{dy(t)}{dt}$</big></p><p>which is the same as</p><p>:: <big>$y(t+h) \\approx y(t) + h \\, f(t,y(t))$</big></p><p>The iterative solution rule is then:</p><p>:: <big>$y_{n+1} = y_n + h \\, f(t_n, y_n)$</big></p><p>where <big>$h$</big> is the step size, the most relevant parameter for accuracy of the solution. A smaller step size increases accuracy but also the computation cost, so it has always has to be hand-picked according to the problem at hand.</p>",
"<p>Example: Newton's Cooling Law</p><p>Newton's cooling law describes how an object of initial temperature <big>$T(t_0) = T_0$</big> cools down in an environment of temperature <big>$T_R$</big>:</p><p>:: <big>$\\frac{dT(t)}{dt} = -k \\, \\Delta T$</big></p>",
"<p>It says that the cooling rate <big>$\\frac{dT(t)}{dt}$</big> of the object is proportional to the current temperature difference <big>$\\Delta T = (T(t) - T_R)$</big> to the surrounding environment.</p><p>The analytical solution, which we will compare to the numerical approximation, is</p>",
"<p>Implement a routine of Euler's method and then to use it to solve the given example of Newton's cooling law with it for three different step sizes of:</p>",
"<p>::* 2 s</p>",
"<p>::* 5 s and </p>",
"<p>::* 10 s </p>",
"<p>and to compare with the analytical solution.</p>",
"Initial values:",
"<p>::* initial temperature <big>$T_0$</big> shall be 100 °C</p>",
"<p>::* room temperature <big>$T_R$</big> shall be 20 °C</p>",
"<p>::* cooling constant <big>$k$</big> shall be 0.07 </p>",
"<p>::* time interval to calculate shall be from 0 s ──► 100 s</p>"
],
"challengeSeed":[
"function eulersMethod (x1, y1, x2, h) {",
" // Good luck!",
"}"
],
"solutions":[
"function eulersMethod(x1, y1, x2, h) {\n let x = x1;\n let y = y1;\n\n while ((x < x2 && x1 < x2) || (x > x2 && x1 > x2)) {\n y += h * (-0.07 * (y - 20));\n x += h;\n }\n\n return y;\n}\n"
],
"tests":[
"assert(typeof eulersMethod === 'function', 'message: <code>eulersMethod</code> is a function.');",
"assert(typeof eulersMethod(0, 100, 100, 10) === 'number', 'message: <code>eulersMethod(0, 100, 100, 10)</code> should return a number.');",
"function binom(n, k) {\n let coeff = 1;\n for (let i = n - k + 1; i <= n; i++) coeff *= i;\n for (let i = 1; i <= k; i++) coeff /= i;\n return coeff;\n}\n"
],
"tests":[
"assert(typeof binom === 'function', 'message: <code>binom</code> is a function.');",
"assert.equal(binom(5, 3), 10, 'message: <code>binom(5,3)</code> should return 10.');",
"assert.equal(binom(7, 2), 21, 'message: <code>binom(7,2)</code> should return 21.');",
"assert.equal(binom(10, 4), 210, 'message: <code>binom(10,4)</code> should return 210.');",
"assert.equal(binom(6, 1), 6, 'message: <code>binom(6,1)</code> should return 6.');",
"assert.equal(binom(12, 8), 495, 'message: <code>binom(12,8)</code> should return 495.');"
],
"id":"598de241872ef8353c58a7a2",
"challengeType":5,
"releasedOn":"August 5, 2017"
},
{
"title":"Extensible prime generator",
"type":"Waypoint",
"description":[
"<p>Write a generator of prime numbers, in order, that will automatically adjust to accommodate the generation of any reasonably high prime.</p> The generator should be able to : Show the first <b>n</b> prime numbers.Show the prime numbers in a range.Show the number of primes in a range.Show the <b>n<sup>th</sup></b> prime number.<p>The function should have two paramters. The first will recieve <b>n</b> or the range as an array. The second will recieve a boolean, that specifies if the function returns the prime numbers as an array or a single number(the number of primes in the range or the <b>n<sup>th</sup></b> prime). According to the parameters the function should return an array."
],
"challengeSeed":[
"function primeGenerator (num, showPrimes) {",
" // Good luck!",
"}"
],
"solutions":[
"// noprotect\nfunction primeGenerator(num, showPrimes) {\n let i,\n arr = [];\n\n function isPrime(num) {\n // try primes <= 16\n if (num <= 16) { return (\n num == 2 || num == 3 || num == 5 || num == 7 || num == 11 || num == 13\n ); }\n // cull multiples of 2, 3, 5 or 7\n if (num % 2 == 0 || num % 3 == 0 || num % 5 == 0 || num % 7 == 0)\n { return false; }\n // cull square numbers ending in 1, 3, 7 or 9\n for (let i = 10; i * i <= num; i += 10) {\n if (num % (i + 1) == 0) return false;\n if (num % (i + 3) == 0) return false;\n if (num % (i + 7) == 0) return false;\n if (num % (i + 9) == 0) return false;\n }\n return true;\n }\n\n if (typeof num === 'number') {\n for (i = 0; arr.length < num; i++) if (isPrime(i)) arr.push(i);\n // first x primes\n if (showPrimes) return arr;\n // xth prime\n return arr.pop();\n }\n\n if (Array.isArray(num)) {\n for (i = num[0]; i <= num[1]; i++) if (isPrime(i)) arr.push(i);\n // primes between x .. y\n if (showPrimes) return arr;\n // number of primes between x .. y\n return arr.length;\n }\n}\n"
],
"tests":[
"assert(typeof primeGenerator === 'function', 'message: <code>primeGenerator</code> is a function.');",
"assert.deepEqual(primeGenerator([100, 150], true), [101, 103, 107, 109, 113, 127, 131, 137, 139, 149], 'message: <code>primeGenerator</code> is a function.');",
"assert.equal(primeGenerator([7700, 8000], false), 30, 'message: <code>primeGenerator</code> is a function.');",
"assert.equal(primeGenerator(10000, false), 104729, 'message: <code>primeGenerator</code> is a function.');"
],
"id":"598ee8b91b410510ae82efef",
"challengeType":5,
"releasedOn":"August 5, 2017"
},
{
"title":"Factorial",
"type":"Waypoint",
"description":[
"<p>Write a function to return the factorial of a number.</p>",
"<p>Factorial of a number is given by : </p>",
"n! = n * (n-1) * (n-2) * ..... * 1",
"<p>",
"For example :",
"3! = 3*2*1 = 6",
"4! = 4*3*2*1 = 24",
"</p>",
"<p>Note : ",
"0! = 1 ",
"</p>"
],
"challengeSeed":[
"function factorial (n) {",
" // Good luck!",
"}"
],
"solutions":[
"function factorial(n) {\n let sum = 1;\n while (n > 1) {\n sum *= n;\n n--;\n }\n return sum;\n}\n\n"
],
"tail":[
"const results=[6,120,3628800];"
],
"tests":[
"assert(typeof factorial === 'function', 'message: <code>factorial</code> is a function.');",
"assert(typeof factorial(2) === 'number', 'message: <code>factorial(2)</code> should return a number.');",
"assert.equal(factorial(3),results[0],\"message: <code>factorial(3)</code> should return 6.\");",
"assert.equal(factorial(5),results[1],\"message: <code>factorial(3)</code> should return 120.\");",
"assert.equal(factorial(10),results[2],\"message: <code>factorial(3)</code> should return 3,628,800.\");"
],
"id":"597b2b2a2702b44414742771",
"challengeType":5,
"releasedOn":"August 5, 2017"
},
{
"title":"Factors of an integer",
"type":"Waypoint",
"description":[
"<p>Write a function that returns the factors of a positive integer.</p><p>These factors are the positive integers by which the number being factored can be divided to yield a positive integer result.</p>",
"///"
],
"challengeSeed":[
"function factors (num) {",
" // Good luck!",
"}"
],
"solutions":[
"function factors(num)\n{\n let n_factors = [], i, sqr=Math.floor(Math.sqrt(num));\n\n for (i = 1; i <=sqr ; i += 1)\n if (num % i === 0)\n {\n n_factors.push(i);\n if (num / i !== i)\n n_factors.push(num / i);\n }\n n_factors.sort(function(a, b){return a - b;});\n return n_factors;\n}\n"
"///<p>The first two terms of the series are 0, 1.</p>",
"///<p>Hence, the series is : 0, 1, 1, 2, 3, 5, 8, 13...</p>",
"///"
],
"challengeSeed":[
"function fibonacci(n) {",
" // Good luck!",
"}"
],
"solutions":[
"function fibonacci(n) {\n let a = 0, b = 1, t;\n while (--n > 0) {\n t = a;\n a = b;\n b += t;\n }\n return a;\n}\n"
],
"tail":[],
"tests":[
"assert(typeof fibonacci === 'function', 'message: <code>fibonacci</code> is a function.');",
"assert(typeof fibonacci(2) == 'number', 'message: <code>fibonacci(2)</code> should return a number.');",
"assert.equal(fibonacci(3),1,\"message: <code>fibonacci(3)</code> should return 1.\");",
"assert.equal(fibonacci(5),3,\"message: <code>fibonacci(5)</code> should return 3.\");",
"assert.equal(fibonacci(10),34,\"message: <code>fibonacci(10)</code> should return 34.\");"
],
"id":"597f24c1dda4e70f53c79c81",
"challengeType":5,
"releasedOn":"August 5, 2017"
},
{
"title":"Hailstone sequence",
"type":"Waypoint",
"description":[
"<p>The Hailstone sequence of numbers can be generated from a starting positive integer, n by:</p>",
" If n is 1 then the sequence ends.",
" If n is even then the next n of the sequence <code> = n/2 </code>",
" If n is odd then the next n of the sequence <code> = (3 * n) + 1 </code><p>The (unproven) <a href=\"https://en.wikipedia.org/wiki/Collatz conjecture\" title=\"wp: Collatz conjecture\">Collatz conjecture</a> is that the hailstone sequence for any starting number always terminates.</p>",
"<p>The hailstone sequence is also known as hailstone numbers (because the values are usually subject to multiple descents and ascents like hailstones in a cloud), or as the Collatz sequence.</p>",
"Task:",
"Create a routine to generate the hailstone sequence for a number.",
"Use the routine to show that the hailstone sequence for the number 27 has 112 elements starting with <code>27, 82, 41, 124</code> and ending with <code>8, 4, 2, 1</code>",
"Show the number less than 100,000 which has the longest hailstone sequence together with that sequence's length. (But don't show the actual sequence!)See also:",
"assert(typeof hailstoneSequence === 'function', 'message: <code>hailstoneSequence</code> is a function.');",
"assert.deepEqual(hailstoneSequence(), res, 'message: <code>hailstoneSequence()</code> should return <code>[[27,82,41,124,8,4,2,1], [351, 77031]]</code>');"
],
"id":"595608ff8bcd7a50bd490181",
"challengeType":5,
"releasedOn":"August 5, 2017"
},
{
"title":"Happy numbers",
"type":"Waypoint",
"description":[
"<p>A happy number is defined by the following process:</p>",
"<p>Starting with any positive integer, replace the number by the sum of the squares of its digits, and repeat the process until the number equals 1 (where it will stay), or it loops endlessly in a cycle which does not include 1. Those numbers for which this process ends in 1 are happy numbers, while those that do not end in 1 are unhappy numbers.</p>",
"<p>Implement a function that returns true if the number is happy, or false if not.</p>"
],
"challengeSeed":[
"function happy (number) {",
" // Good luck!",
"}"
],
"solutions":[
"function happy (number) {\n let m;\n let digit;\n const cycle = [];\n\n while (number !== 1 && cycle[number] !== true) {\n cycle[number] = true;\n m = 0;\n while (number > 0) {\n digit = number % 10;\n m += Math.pow(digit, 2);\n number = (number - digit) / 10;\n }\n number = m;\n }\n return (number === 1);\n}\n"
],
"tests":[
"assert(typeof happy === 'function', 'message: <code>happy</code> is a function.');",
"assert(typeof happy(1) === 'boolean', 'message: <code>happy(1)</code> should return a boolean.');",
"assert(happy(1), 'message: <code>happy(1)</code> should return true.');",
"assert(!happy(2), 'message: <code>happy(2)</code> should return false.');",
"assert(happy(7), 'message: <code>happy(7)</code> should return true.');",
"assert(happy(10), 'message: <code>happy(10)</code> should return true.');",
"assert(happy(13), 'message: <code>happy(13)</code> should return true.');",
"assert(happy(19), 'message: <code>happy(19)</code> should return true.');",
"assert(happy(23), 'message: <code>happy(23)</code> should return true.');",
"assert(happy(28), 'message: <code>happy(28)</code> should return true.');",
"assert(happy(31), 'message: <code>happy(31)</code> should return true.');",
"assert(happy(32), 'message: <code>happy(32)</code> should return true:.');",
"assert(!happy(33), 'message: <code>happy(33)</code> should return false.');"
],
"id":"594810f028c0303b75339ad1",
"challengeType":5,
"releasedOn":"August 5, 2017"
},
{
"title":"Harshad or Niven series",
"type":"Waypoint",
"description":[
"<p>The <a href=\"http://mathworld.wolfram.com/HarshadNumber.html\" title=\"link: http://mathworld.wolfram.com/HarshadNumber.html\">Harshad</a> or Niven numbers are positive integers ≥ 1 that are divisible by the sum of their digits.</p><p>For example, 42 is a <a href=\"http://rosettacode.org/wiki/oeis:A005349\" title=\"oeis:A005349\">Harshad number</a> as 42 is divisible by (4 + 2) without remainder.</p>",
"Assume that the series is defined as the numbers in increasing order.",
"Task:",
"<p>Implement a function to generate successive members of the Harshad sequence.</p><p>Use it to list the first twenty members of the sequence and list the first Harshad number greater than 1000.</p>"
],
"challengeSeed":[
"function isHarshadOrNiven () {",
" const res = {",
" firstTwenty: [],",
" firstOver1000: undefined",
" };",
" // Change after this line",
"",
" return res;",
"}"
],
"solutions":[
"function isHarshadOrNiven() {\n const res = {\n firstTwenty: [],\n firstOver1000: undefined\n };\n\n function isHarshad(n) {\n let s = 0;\n const nStr = n.toString();\n for (let i = 0; i < nStr.length; ++i) {\n s += parseInt(nStr.charAt(i), 10);\n }\n return n % s === 0;\n }\n\n let count = 0;\n const harshads = [];\n\n for (let n = 1; count < 20; ++n) {\n if (isHarshad(n)) {\n count++;\n harshads.push(n);\n }\n }\n\n res.firstTwenty = harshads;\n\n let h = 1000;\n while (!isHarshad(++h));\n res.firstOver1000 = h;\n\n return res;\n}\n"
"<p>Using two Arrays of equal length, create a Hash object where the elements from one array (the keys) are linked to the elements of the other (the values)</p>",
"<p>An <a href=\"https://en.wikipedia.org/wiki/Join_(SQL)#Inner_join\" title=\"wp: Join_(SQL)#Inner_join\">inner join</a> is an operation that combines two data tables into one table, based on matching column values. The simplest way of implementing this operation is the <a href=\"https://en.wikipedia.org/wiki/Nested loop join\" title=\"wp: Nested loop join\">nested loop join</a> algorithm, but a more scalable alternative is the <a href=\"https://en.wikipedia.org/wiki/hash join\" title=\"wp: hash join\">hash join</a> algorithm.</p>",
"<p>Implement the \"hash join\" algorithm, and demonstrate that it passes the test-case listed below.</p><p>You should represent the tables as data structures that feel natural in your programming language.</p>",
"<p>The \"hash join\" algorithm consists of two steps:</p>",
"Hash phase: Create a <a href=\"https://en.wikipedia.org/wiki/Multimap\" title=\"wp: Multimap\">multimap</a> from one of the two tables, mapping from each join column value to all the rows that contain it.",
" The multimap must support hash-based lookup which scales better than a simple linear search, because that's the whole point of this algorithm.",
" Ideally we should create the multimap for the smaller table, thus minimizing its creation time and memory size.",
"Join phase: Scan the other table, and find matching rows by looking in the multimap created before.",
"<p>In pseudo-code, the algorithm could be expressed as follows:</p>",
"<pre>",
"let A = the first input table (or ideally, the larger one)",
"let B = the second input table (or ideally, the smaller one)",
"let j<sub>A</sub> = the join column ID of table A",
"let j<sub>B</sub> = the join column ID of table B",
"let M<sub>B</sub> = a multimap for mapping from single values to multiple rows of table B (starts out empty)",
"let C = the output table (starts out empty)",
"for each row b in table B:",
" place b in multimap M<sub>B</sub> under key b(j<sub>B</sub>)",
"for each row a in table A:",
" for each row b in multimap M<sub>B</sub> under key a(j<sub>A</sub>):",
"<p></p><p></p><p>The order of the rows in the output table is not significant.</p>",
"<p>If you're using numerically indexed arrays to represent table rows (rather than referring to columns by name), you could represent the output rows in the form <code style=\"white-space:nowrap\">[[27, \"Jonah\"], [\"Jonah\", \"Whales\"]]</code>.</p><hr>"
"<p><a href=\"https://en.wikipedia.org/wiki/Heron's formula\" title=\"wp: Heron's formula\">Hero's formula</a> for the area of a triangle given the length of its three sides <big> a,</big> <big>b,</big> and <big>c</big> is given by:</p><p><big>$$A = \\sqrt{s(s-a)(s-b)(s-c)},$$</big></p><p>where <big>s</big> is half the perimeter of the triangle; that is,</p><p><big>$$s=\\frac{a+b+c}{2}.$$</big></p>",
"<p><a href=\"http://www.had2know.com/academics/heronian-triangles-generator-calculator.html\" title=\"link: http://www.had2know.com/academics/heronian-triangles-generator-calculator.html\">Heronian triangles</a> are triangles whose sides and area are all integers.</p>",
"<p> An example is the triangle with sides 3, 4, 5 whose area is 6 (and whose perimeter is 12). </p>",
"<p>Note that any triangle whose sides are all an integer multiple of 3, 4, 5; such as 6, 8, 10, will also be a Heronian triangle.</p><p>Define a Primitive Heronian triangle as a Heronian triangle where the greatest common divisor</p>",
"<p>of all three sides is 1 (unity).</p><p>This will exclude, for example, triangle 6, 8, 10.</p>",
"Task:",
"<p>Implement a function based on Hero's formula that returns the first <code>n<sub>th</sub></code> ordered triangles in an array of arrays.</p>"
],
"challengeSeed":[
"// noprotect",
"function heronianTriangle (n) {",
" // Good luck!",
"",
" return [];",
"}"
],
"solutions":[
"// noprotect\nfunction heronianTriangle (n) {\n const list = [];\n const result = [];\n\n let j = 0;\n for (let c = 1; c <= 200; c++) {\n for (let b = 1; b <= c; b++) {\n for (let a = 1; a <= b; a++) {\n if (gcd(gcd(a, b), c) === 1 && isHeron(heronArea(a, b, c))) {\n list[j++] = new Array(a, b, c, heronArea(a, b, c));\n }\n }\n }\n }\n\n sort(list);\n\n for (let i = 0; i < n; i++) {\n result[i] = [list[i][0], list[i][1], list[i][2]];\n }\n\n return result;\n\n function heronArea(a, b, c) {\n const s = (a + b + c) / 2;\n return Math.sqrt(s * (s - a) * (s - b) * (s - c));\n }\n\n function isHeron(h) { return h % 1 === 0 && h > 0; }\n\n function gcd(a, b) {\n let leftover = 1;\n let dividend = a > b ? a : b;\n let divisor = a > b ? b : a;\n while (leftover !== 0) {\n leftover = dividend % divisor;\n if (leftover > 0) {\n dividend = divisor;\n divisor = leftover;\n }\n }\n return divisor;\n }\n\n function sort(arg) {\n let swapped = true;\n let temp = [];\n while (swapped) {\n swapped = false;\n for (let i = 1; i < arg.length; i++) {\n if (arg[i][4] < arg[i - 1][4] || arg[i][4] === arg[i - 1][4] && arg[i][3] < arg[i - 1][3]) {\n temp = arg[i];\n arg[i] = arg[i - 1];\n arg[i - 1] = temp;\n swapped = true;\n }\n }\n }\n }\n}\n"
"<p>The sequence <big>$S(n)$</big> is further defined as the sequence of positive integers not present in <big>$R(n)$</big>.</p><p>Sequence <big>$R$</big> starts:</p>",
"<p>1, 3, 7, 12, 18, ...</p>",
"<p>Sequence <big>$S$</big> starts:</p>",
"<p>2, 4, 5, 6, 8, ...</p>",
"Task:",
"Create two functions named ffr and ffs that when given n return R(n) or S(n) respectively.(Note that R(1) = 1 and S(1) = 2 to avoid off-by-one errors).",
"No maximum value for n should be assumed.",
"Sloane's <a href=\"http://oeis.org/A005228\" title=\"link: http://oeis.org/A005228\">A005228</a> and <a href=\"http://oeis.org/A030124\" title=\"link: http://oeis.org/A030124\">A030124</a>.",
"assert(typeof ffr === 'function', 'message: <code>ffr</code> is a function.');",
"assert(typeof ffs === 'function', 'message: <code>ffs</code> is a function.');",
"assert(Number.isInteger(ffr(1)), 'message: <code>ffr</code> should return integer.');",
"assert(Number.isInteger(ffs(1)), 'message: <code>ffs</code> should return integer.');",
"assert.equal(ffr(ffrParamRes[0][0]), ffrParamRes[0][1], 'message: <code>ffr()</code> should return <code>69</code>');",
"assert.equal(ffr(ffrParamRes[1][0]), ffrParamRes[1][1], 'message: <code>ffr()</code> should return <code>1509</code>');",
"assert.equal(ffr(ffrParamRes[2][0]), ffrParamRes[2][1], 'message: <code>ffr()</code> should return <code>5764</code>');",
"assert.equal(ffr(ffrParamRes[3][0]), ffrParamRes[3][1], 'message: <code>ffr()</code> should return <code>526334</code>');",
"assert.equal(ffs(ffsParamRes[0][0]), ffsParamRes[0][1], 'message: <code>ffs()</code> should return <code>14</code>');",
"assert.equal(ffs(ffsParamRes[1][0]), ffsParamRes[1][1], 'message: <code>ffs()</code> should return <code>59</code>');",
"assert.equal(ffs(ffsParamRes[2][0]), ffsParamRes[2][1], 'message: <code>ffs()</code> should return <code>112</code>');",
"assert.equal(ffs(ffsParamRes[3][0]), ffsParamRes[3][1], 'message: <code>ffs()</code> should return <code>1041</code>');"
],
"id":"59622f89e4e137560018a40e",
"challengeType":5,
"releasedOn":"August 5, 2017"
},
{
"title":"Hofstadter Q sequence",
"type":"Waypoint",
"description":[
"<p>The <a href=\"https://en.wikipedia.org/wiki/Hofstadter_sequence#Hofstadter_Q_sequence\" title=\"wp: Hofstadter_sequence#Hofstadter_Q_sequence\">Hofstadter Q sequence</a> is defined as:</p>",
"<p>It is defined like the <a href=\"http://rosettacode.org/wiki/Fibonacci sequence\" title=\"Fibonacci sequence\">Fibonacci sequence</a>, but whereas the next term in the Fibonacci sequence is the sum of the previous two terms, in the Q sequence the previous two terms tell you how far to go back in the Q sequence to find the two numbers to sum to make the next term of the sequence.</p>",
"Task:",
"Implement the Hofstadter Q Sequence equation into JavaScript"
],
"challengeSeed":[
"function hofstadterQ (n) {",
" // Good luck!",
" return n;",
"}"
],
"solutions":[
"function hofstadterQ (n) {\n const memo = [1, 1, 1];\n const Q = function (i) {\n let result = memo[i];\n if (typeof result !== 'number') {\n result = Q(i - Q(i - 1)) + Q(i - Q(i - 2));\n memo[i] = result;\n }\n return result;\n };\n return Q(n);\n}\n"
],
"tail":[
"const testCase = [1000, 1500, 2000, 2500];",
"const res = [502, 755, 1005, 1261];"
],
"tests":[
"assert(typeof hofstadterQ === 'function', 'message: <code>hofstadterQ</code> is a function.');",
"assert(Number.isInteger(hofstadterQ(1000)), 'message: <code>hofstadterQ()</code> should return <code>integer</code>');",
"assert.equal(hofstadterQ(testCase[0]), res[0], 'message: <code>hofstadterQ(1000)</code> should return <code>502</code>');",
"assert.equal(hofstadterQ(testCase[1]), res[1], 'message: <code>hofstadterQ(1500)</code> should return <code>755</code>');",
"assert.equal(hofstadterQ(testCase[2]), res[2], 'message: <code>hofstadterQ(2000)</code> should return <code>1005</code>');",
"assert.equal(hofstadterQ(testCase[3]), res[3], 'message: <code>hofstadterQ(2500)</code> should return <code>1261</code>');"
],
"id":"59637c4d89f6786115efd814",
"challengeType":5,
"releasedOn":"August 5, 2017"
},
{
"title":"S-Expressions",
"type":"Waypoint",
"description":[
"<p>",
"<a href=\"https://en.wikipedia.org/wiki/S-Expression\" title=\"wp: S-Expression\">S-Expressions</a> are one convenient way to parse and store data.",
"</p>",
"Task:",
"<p>",
" Write a simple reader/parser for S-Expressions that handles quoted and unquoted strings, integers and floats.",
"</p>",
"<p>",
"The function should read a single but nested S-Expression from a string and",
"return it as a (nested) array.",
"</p>",
"<p>",
" Newlines and other whitespace may be ignored unless contained within a quoted string.",
"</p>",
"<p>“<tt>()</tt>” inside quoted strings are not interpreted, but treated as part of the string.",
"</p>",
"<p>",
"Handling escaped quotes inside a string is optional; thus “<tt>(foo\"bar)</tt>” maybe treated as a string “<tt>foo\"bar</tt>”, or as an error.",
"</p>",
"<p>",
"For this, the reader need not recognize “<tt>\\</tt>” for escaping, but should, in addition, recognize numbers if the language has appropriate datatypes.",
"</p>",
"<p>",
"Note that with the exception of “<tt>()\"</tt>” (“<tt>\\</tt>” if escaping is supported) and whitespace there are no special characters. Anything else is allowed without quotes.",
"</p>",
"<p>The reader should be able to read the following input</p>",
"<p>",
"<pre>",
" ((data \"quoted data\" 123 4.5)",
" (data (!@# (4.5) \"(more\" \"data)\")))",
"</pre>",
"</p>",
"<p>",
"and turn it into a native datastructure. (see the",
"function parseSexpr(str) {\n const t = str.match(/\\s*(\"[^\"]*\"|\\(|\\)|\"|[^\\s()\"]+)/g);\n for (var o, c = 0, i = t.length - 1; i >= 0; i--) {\n var n,\n ti = t[i].trim();\n if (ti == '\"') return;\n else if (ti == '(') t[i] = '[', c += 1;\n else if (ti == ')') t[i] = ']', c -= 1;\n else if ((n = +ti) == ti) t[i] = n;\n else t[i] = `'${ti.replace('\\'', '\\\\\\'')}'`;\n if (i > 0 && ti != ']' && t[i - 1].trim() != '(') t.splice(i, 0, ',');\n if (!c) if (!o) o = true; else return;\n }\n return c ? undefined : eval(t.join(''));\n}\n"
"assert.deepEqual(parseSexpr(basicSExpr), basicSolution, \"message: <code>parseSexpr('(data1 data2 data3)')</code> should return an array with 3 elements\");"
],
"id":"59667989bf71cf555dd5d2ff",
"challengeType":5,
"releasedOn":"August 5, 2017"
},
{
"title":"Taxicab numbers",
"type":"Waypoint",
"description":[
"A <a href=\"https://en.wikipedia.org/wiki/Hardy–Ramanujan number\" title=\"wp: Hardy–Ramanujan number\">taxicab number</a>",
" (the definition that is being used here) is a positive integer that can be expressed as the sum of two positive cubes in more than one way.",
"The first taxicab number is 1729, which is:",
"Write a function that returns the lowest N taxicab numbers.",
"For each of the taxicab numbers, show the number as well as it's constituent cubes.",
"See also:",
"[http://oeis.org/A001235 A001235 taxicab numbers] on The On-Line Encyclopedia of Integer Sequences.",
" <a href=\"http://mathworld.wolfram.com/Hardy-RamanujanNumber.html\">Hardy-Ramanujan Number</a> on MathWorld.",
" <a href=\"http://mathworld.wolfram.com/TaxicabNumber.html\">taxicab number</a> on MathWorld.",
" <a href=\"https://en.wikipedia.org/wiki/Taxicab_number\">taxicab number</a> on Wikipedia."
],
"challengeSeed":[
"function taxicabNumbers (n) {",
" // Good luck!",
" return true;",
"}"
],
"solutions":[
"function taxicabNumbers(nNumbers) {\n const cubeN = [];\n const s3s = {};\n\n const e = 100;\n for (let n = 1; n < e; n += 1) {\n cubeN[n] = n * n * n;\n }\n\n for (let a = 1; a < e - 1; a += 1) {\n const a3 = cubeN[a];\n for (let b = a; b < e; b += 1) {\n const b3 = cubeN[b];\n const s3 = a3 + b3;\n\n let abs = s3s[s3];\n if (!abs) {\n s3s[s3] = abs = [];\n }\n abs.push([a, b]);\n }\n }\n\n let i = 0;\n const res = [];\n Object.keys(s3s).forEach(s3 => {\n const abs = s3s[s3];\n if (abs.length >= 2) { // No two cube pairs found\n i += 1;\n if (i <= nNumbers) {\n res.push(s3);\n }\n }\n });\n return res.map(item => parseInt(item, 10));\n}\n"
"assert.deepEqual(taxicabNumbers(39).slice(20, 29), res39From20To29, 'message: taxicabNumbers(39) resulting numbers from 20 - 29 should be [314496,320264,327763,373464,402597,439101,443889,513000,513856].');"
],
"id":"594ecc0d9a8cf816e3340187",
"challengeType":5,
"releasedOn":"August 5, 2017"
},
{
"title":"Tokenize a string with escaping",
"type":"Waypoint",
"description":[
"<p>",
"Write a function or program that can split a string at each non-escaped occurrence of a separator character.",
"</p>",
"<p>",
"It should accept three input parameters:",
"</p>",
" The <b>string</b>",
" The <b>separator character</b>",
" The <b>escape character</b>",
"<p>It should output a list of strings.</p>",
"<p>Rules for splitting:</p>",
" The fields that were separated by the separators, become the elements of the output list.",
" Empty fields should be preserved, even at the start and end.",
"<p>Rules for escaping:</p>",
" \"Escaped\" means preceded by an occurrence of the escape character that is not already escaped itself.",
" When the escape character precedes a character that has no special meaning, it still counts as an escape (but does not do anything special).",
" Each occurrences of the escape character that was used to escape something, should not become part of the output.",
"<p>Demonstrate that your function satisfies the following test-case:",
" Given string <pre>one^|uno||three^^^^|four^^^|^cuatro|</pre> and using",
" <pre>|</pre> as a separator and <pre>^</pre> as escape character, your",
"<small>Note: the above data would be un-orderable if, for example, <code>dw04</code> is added to the list of dependencies of <code>dw01</code>.</small>",
"</p>",
"C.f.:",
" ",
" <a href=\"http://rosettacode.org/wiki/Topological sort/Extracted top item\" title=\"Topological sort/Extracted top item\">Topological sort/Extracted top item</a>.",
" ",
"<p>There are two popular algorithms for topological sorting:</p>",
"<p>",
" Kahn's 1962 topological sort, and depth-first search:",
" \"Ten little algorithms, part 4: topological sort\"",
" </a>.",
"</p>"
],
"challengeSeed":[
"function topologicalSort(libs) {",
" // Good luck!",
" return true;",
"}"
],
"solutions":[
"function topologicalSort(libs) {\n // A map of the input data, with the keys as the packages, and the values as\n // and array of packages on which it depends.\n const D = libs\n .split('\\n')\n .map(e => e.split(' ').filter(ep => ep !== ''))\n .reduce((p, c) =>\n p.set(c[0], c.filter((e, i) => (i > 0 && e !== c[0] ? e : null))), new Map());\n [].concat(...D.values()).forEach(e => {\n D.set(e, D.get(e) || []);\n });\n\n // The above map rotated so that it represents a DAG of the form\n // Map {\n // A => [ A, B, C],\n // B => [C],\n // C => []\n // }\n // where each key represents a node, and the array contains the edges.\n const G = [...D.keys()].reduce((p, c) =>\n p.set(\n c,\n [...D.keys()].filter(e => D.get(e).includes(c))),\n new Map()\n );\n\n // An array of leaf nodes; nodes with 0 in degrees.\n const Q = [...D.keys()].filter(e => D.get(e).length === 0);\n\n // The result array.\n const S = [];\n while (Q.length) {\n const u = Q.pop();\n S.push(u);\n G.get(u).forEach(v => {\n D.set(v, D.get(v).filter(e => e !== u));\n if (D.get(v).length === 0) {\n Q.push(v);\n }\n });\n }\n\n return S;\n}\n"
"A vector is defined as having three dimensions as being represented by an ordered collection of three numbers: (X, Y, Z).",
"</p>",
"<p>",
"Task:",
" ",
" Write a function that takes any numbers of vectors (arrays) as input and computes their dot product.",
" ",
"Your function should return <code>null</code> on",
"invalid inputs (ie vectors of different lengths).",
"</p>"
],
"challengeSeed":[
"function dotProduct() {",
" // Good luck!",
"}"
],
"solutions":[
"function dotProduct(...vectors) {\n if (!vectors || !vectors.length) {\n return null;\n }\n if (!vectors[0] || !vectors[0].length) {\n return null;\n }\n const vectorLen = vectors[0].length;\n const numVectors = vectors.length;\n\n // If all vectors not same length, return null\n for (let i = 0; i < numVectors; i++) {\n if (vectors[i].length !== vectorLen) {\n return null; // return undefined\n }\n }\n\n let prod = 0;\n let sum = 0;\n let j = vectorLen;\n let i = numVectors;\n // Sum terms\n while (j--) {\n i = numVectors;\n prod = 1;\n\n while (i--) {\n prod *= vectors[i][j];\n }\n sum += prod;\n }\n return sum;\n}\n"
],
"tail":[
"const vectors5x5 = [];",
"for (let i = 0; i < 5; i++) {",
" vectors5x5[i] = [];",
" for (let j = 0; j < 5; j++) {",
" vectors5x5[i].push((i + 1) * j);",
" }",
"}",
"const vectorsWp = [[1, 3, -5], [4, -2, -1]];"
],
"tests":[
"assert.equal(typeof dotProduct, 'function', 'message: dotProduct must be a function');",
"assert.equal(dotProduct(), null, 'message: dotProduct() must return null');",
"assert.equal(dotProduct([1], [1]), 1, 'message: dotProduct([[1], [1]]) must return 1.');",
"the <a href=\"https://en.wikipedia.org/wiki/lambda calculus\" title=\"wp: lambda calculus\">lambda calculus</a>, ",
"functions (lambda expressions) don't have state and are only allowed to refer to arguments of enclosing functions. ",
"This rules out the usual definition of a recursive function wherein a function is associated with the state of a variable and this variable's state is used in the body of the function.",
"</p>",
"<p>",
"The <a href=\"http://mvanier.livejournal.com/2897.html\">Y combinator</a> is itself a stateless function that,",
"when applied to another stateless function, returns a recursive version of the function. The Y combinator is",
"the simplest of the class of such functions, called ",
"Obviously the boundary pixels of the image cannot have the full eight neighbours.",
" ",
" Define $A(P1)$ = the number of transitions from white to black, (0 -> 1) in the sequence P2,P3,P4,P5,P6,P7,P8,P9,P2. (Note the extra P2 at the end - it is circular).",
" ",
" ",
" Define $B(P1)$ = the number of black pixel neighbours of P1. ( = sum(P2 .. P9) )",
" ",
"<h3>Step 1:</h3>",
"All pixels are tested and pixels satisfying all the following conditions (simultaneously) are just noted at this stage.",
" (0) The pixel is black and has eight neighbours",
" (1) $2 <= B(P1) <= 6$",
" (2) $A(P1) = 1$",
" (3) At least one of P2 and P4 and P6 is white",
" (4) At least one of P4 and P6 and P8 is white",
"After iterating over the image and collecting all the pixels satisfying all step 1 conditions, all these condition satisfying pixels are set to white.",
"<h3>Step 2:</h3>",
"All pixels are again tested and pixels satisfying all the following conditions are just noted at this stage.",
" (0) The pixel is black and has eight neighbours",
" (1) $2 <= B(P1) <= 6$",
" (2) $A(P1) = 1$",
" (3) At least one of P2 and P4 and '''P8''' is white",
" (4) At least one of '''P2''' and P6 and P8 is white",
"After iterating over the image and collecting all the pixels satisfying all step 2 conditions, all these condition satisfying pixels are again set to white.",
"Iteration:",
"If any pixels were set in this round of either step 1 or step 2 then all steps are repeated until no image pixels are so changed.",
"<p>",
"Task:",
"Write a routine to perform Zhang-Suen thinning on an image matrix of ones and zeroes.",