{ "name": "Rosetta Code", "order": 5, "time": "", "helpRoom": "", "nChallenges": 437, "challenges": [ { "title": "100 doors", "description": [ "
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.
", "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.
" ], "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" ], "tests": [ { "text": "getFinalOpenedDoors
is a function.",
"testString": "assert(typeof getFinalOpenedDoors === 'function', 'getFinalOpenedDoors
is a function.');"
},
{
"text": "getFinalOpenedDoors
should return an array.",
"testString": "assert(Array.isArray(getFinalOpenedDoors(100)), 'getFinalOpenedDoors
should return an array.');"
},
{
"text": "getFinalOpenedDoors
did not produce the correct results.",
"testString": "assert.deepEqual(getFinalOpenedDoors(100), solution, 'getFinalOpenedDoors
did not produce the correct results.');"
}
],
"id": "594810f028c0303b75339acb",
"challengeType": 5,
"releasedOn": "December 27, 2017",
"files": {
"indexjs": {
"key": "indexjs",
"ext": "js",
"name": "index",
"contents": [
"function getFinalOpenedDoors (numDoors) {",
" // Good luck!",
"}"
],
"head": [],
"tail": [
"const solution = [1, 4, 9, 16, 25, 36, 49, 64, 81, 100];"
]
}
}
},
{
"title": "24 game",
"description": [
"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.\"
", "Rules:
", " 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.", "Example inputs:
", "solve24(\"4878\");
",
"solve24(\"1234\");
",
"solve24(\"6789\");
",
"solve24(\"1127\");
",
"Example outputs (strings):
", "(7-8/8)*4
",
"3*1*4*2
",
"(6*8)/(9-7)
",
"(1+7)*(2+1)
"
],
"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"
],
"tests": [
{
"text": "solve24
is a function.",
"testString": "assert(typeof solve24 === 'function', 'solve24
is a function.');"
},
{
"text": "solve24(\"4878\")
should return (7-8/8)*4
or 4*(7-8/8)
",
"testString": "assert(include(answers[0], solve24(testCases[0])), 'solve24(\"4878\")
should return (7-8/8)*4
or 4*(7-8/8)
');"
},
{
"text": "solve24(\"1234\")
should return any arrangement of 1*2*3*4
",
"testString": "assert(include(answers[1], solve24(testCases[1])), 'solve24(\"1234\")
should return any arrangement of 1*2*3*4
');"
},
{
"text": "solve24(\"6789\")
should return (6*8)/(9-7)
or (8*6)/(9-7)
",
"testString": "assert(include(answers[2], solve24(testCases[2])), 'solve24(\"6789\")
should return (6*8)/(9-7)
or (8*6)/(9-7)
');"
},
{
"text": "solve24(\"1127\")
should return a permutation of (1+7)*(1*2)
",
"testString": "assert(include(answers[3], solve24(testCases[3])), 'solve24(\"1127\")
should return a permutation of (1+7)*(1*2)
');"
}
],
"id": "5951e88f64ebf159166a1176",
"challengeType": 5,
"releasedOn": "December 27, 2017",
"files": {
"indexjs": {
"key": "indexjs",
"ext": "js",
"name": "index",
"contents": [
"function solve24 (numStr) {",
" // Good luck!",
" return true;",
"}"
],
"head": [],
"tail": [
"const testCases = [",
" '4878',",
" '1234',",
" '6789',",
" '1127'",
"];",
"",
"const answers = [",
" ['(7-8/8)*4', '4*(7-8/8)', '(4-8+7)*8', '(4+7-8)*8', '(7+4-8)*8', '(7-8+4)*8', '8*(4-8+7)', '8*(4+7-8)', '8*(7+4-8)', '8*(7-8+4)'],",
" ['1*2*3*4', '1*2*4*3', '1*3*2*4', '1*3*4*2', '1*4*2*3', '1*4*3*2', '2*1*3*4', '2*1*4*3', '2*3*1*4', '2*3*4*1', '2*4*3*1', '2*4*1*3', '3*1*2*4', '3*1*4*2', '3*2*1*4', '3*2*4*1', '3*4*1*2', '3*4*2*1', '4*1*2*3', '4*1*3*2', '4*2*1*3', '4*2*3*1', '4*3*1*2', '4*3*2*1', '(1+2+3)*4', '(1+3+2)*4', '(2+1+3)*4', '(2+3+1)*4', '(3+1+2)*4', '(3+2+1)*4', '4*(1+2+3)', '4*(2+1+3)', '4*(2+3+1)', '4*(3+1+2)', '4*(3+2+1)'],",
" ['(6*8)/(9-7)', '(8*6)/(9-7)', '6*8/(9-7)', '8*6/(9-7)'],",
" ['(1+7)*(2+1)', '(1+7)*(1+2)', '(1+2)*(1+7)', '(1+2)*(7+1)', '(2+1)*(1+7)', '(7+1)*(2+1)']",
"];",
"",
"function include(ansArr, res) {",
" const index = ansArr.indexOf(res);",
" return index >= 0;",
"}"
]
}
}
},
{
"title": "9 billion names of God the integer",
"description": [
"This task is a variation of the short story by Arthur C. Clarke.
", "(Solvers should be aware of the consequences of completing this task.)
", "In detail, to specify what is meant by a “name”:
", "The integer 1 has 1 name “1”.
", "The integer 2 has 2 names “1+1”, and “2”.
", "The integer 3 has 3 names “1+1+1”, “2+1”, and “3”.
", "The integer 4 has 5 names “1+1+1+1”, “2+1+1”, “2+2”, “3+1”, “4”.
", "The integer 5 has 7 names “1+1+1+1+1”, “2+1+1+1”, “2+2+1”, “3+1+1”, “3+2”, “4+1”, “5”.
", "This can be visualized in the following form:
", "", " 1", " 1 1", " 1 1 1", " 1 2 1 1", " 1 2 2 1 1", "1 3 3 2 1 1", "", "
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$.
", "Optionally note that the sum of the $n$-th row $P(n)$ is the integer partition function.
", "Task", "Implement a function that returns the sum of the $n$-th row.
" ], "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": [ { "text": "numberOfNames
is a function.",
"testString": "assert(typeof numberOfNames === 'function', 'numberOfNames
is a function.');"
},
{
"text": "numberOfNames(5)
should equal 7.",
"testString": "assert.equal(numberOfNames(5), 7, 'numberOfNames(5)
should equal 7.');"
},
{
"text": "numberOfNames(12)
should equal 77.",
"testString": "assert.equal(numberOfNames(12), 77, 'numberOfNames(12)
should equal 77.');"
},
{
"text": "numberOfNames(18)
should equal 385.",
"testString": "assert.equal(numberOfNames(18), 385, 'numberOfNames(18)
should equal 385.');"
},
{
"text": "numberOfNames(23)
should equal 1255.",
"testString": "assert.equal(numberOfNames(23), 1255, 'numberOfNames(23)
should equal 1255.');"
},
{
"text": "numberOfNames(42)
should equal 53174.",
"testString": "assert.equal(numberOfNames(42), 53174, 'numberOfNames(42)
should equal 53174.');"
},
{
"text": "numberOfNames(123)
should equal 2552338241.",
"testString": "assert.equal(numberOfNames(123), 2552338241, 'numberOfNames(123)
should equal 2552338241.');"
}
],
"id": "5949b579404977fbaefcd736",
"challengeType": 5,
"releasedOn": "December 27, 2017",
"files": {
"indexjs": {
"key": "indexjs",
"ext": "js",
"name": "index",
"contents": [
"function numberOfNames (num) {",
" // Good luck!",
" return true;",
"}"
],
"head": [],
"tail": []
}
}
},
{
"title": "ABC Problem",
"description": [
"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:
", "(B O)
", "(X K)
", "(D Q)
", "(C P)
", "(N A)
", "(G T)
", "(R E)
", "(T G)
", "(Q D)
", "(F S)
", "(J W)
", "(H U)
", "(V I)
", "(A N)
", "(O B)
", "(E R)
", "(F S)
", "(L Y)
", "(P C)
", "(Z M)
", "Some rules to keep in mind:
", "Once a letter on a block is used, that block cannot be used again.", "The function should be case-insensitive.", "Implement a function that takes a string (word) and determines whether the word can be spelled with the given collection of blocks.
" ], "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" ], "tests": [ { "text": "canMakeWord
is a function.",
"testString": "assert(typeof canMakeWord === 'function', 'canMakeWord
is a function.');"
},
{
"text": "canMakeWord
should return a boolean.",
"testString": "assert(typeof canMakeWord('hi') === 'boolean', 'canMakeWord
should return a boolean.');"
},
{
"text": "canMakeWord(\"bark\")
should return true.",
"testString": "assert(canMakeWord(words[0]), 'canMakeWord(\"bark\")
should return true.');"
},
{
"text": "canMakeWord(\"BooK\")
should return false.",
"testString": "assert(!canMakeWord(words[1]), 'canMakeWord(\"BooK\")
should return false.');"
},
{
"text": "canMakeWord(\"TReAT\")
should return true.",
"testString": "assert(canMakeWord(words[2]), 'canMakeWord(\"TReAT\")
should return true.');"
},
{
"text": "canMakeWord(\"COMMON\")
should return false.",
"testString": "assert(!canMakeWord(words[3]), 'canMakeWord(\"COMMON\")
should return false.');"
},
{
"text": "canMakeWord(\"squAD\")
should return true.",
"testString": "assert(canMakeWord(words[4]), 'canMakeWord(\"squAD\")
should return true.');"
},
{
"text": "canMakeWord(\"conFUSE\")
should return true.",
"testString": "assert(canMakeWord(words[5]), 'canMakeWord(\"conFUSE\")
should return true.');"
}
],
"id": "594810f028c0303b75339acc",
"challengeType": 5,
"releasedOn": "December 27, 2017",
"files": {
"indexjs": {
"key": "indexjs",
"ext": "js",
"name": "index",
"contents": [
"function canMakeWord (word) {",
" // Good luck!",
"}"
],
"head": [],
"tail": [
"const words = ['bark', 'BooK', 'TReAT', 'COMMON', 'squAD', 'conFUSE'];"
]
}
}
},
{
"title": "Abundant, deficient and perfect number classifications",
"description": [
"These define three classifications of positive integers based on their proper divisors.
", "Let $P(n)$ be the sum of the proper divisors of n where proper divisors are all positive integers n other than n itself.
", "If P(n) < n
then n is classed as \"deficient\"
If P(n) === n
then n is classed as \"perfect\"
If P(n) > n
then n is classed as \"abundant\"
Example:
", "6 has proper divisors of 1, 2, and 3.
", "1 + 2 + 3 = 6, so 6 is classed as a perfect number.
", "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 [deficient, perfect, abundant]
.
getDPA
is a function.",
"testString": "assert(typeof getDPA === 'function', 'getDPA
is a function.');"
},
{
"text": "getDPA
should return an array.",
"testString": "assert(Array.isArray(getDPA(100)), 'getDPA
should return an array.');"
},
{
"text": "getDPA
return value should have a length of 3.",
"testString": "assert(getDPA(100).length === 3, 'getDPA
return value should have a length of 3.');"
},
{
"text": "getDPA(20000)
should equal [15043, 4, 4953]",
"testString": "assert.deepEqual(getDPA(20000), solution, 'getDPA(20000)
should equal [15043, 4, 4953]');"
}
],
"id": "594810f028c0303b75339acd",
"challengeType": 5,
"releasedOn": "December 27, 2017",
"files": {
"indexjs": {
"key": "indexjs",
"ext": "js",
"name": "index",
"contents": [
"function getDPA (num) {",
" // Good luck!",
"}"
],
"head": [],
"tail": [
"const solution = [15043, 4, 4953];"
]
}
}
},
{
"title": "Accumulator factory",
"description": [
"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).
", "Rules:
", "Do not use global variables.
", "Hint:
", "Closures save outer state.
" ], "solutions": [ "function accumulator (sum) {\n return function (n) {\n return sum += n;\n };\n}\n" ], "tests": [ { "text": "accumulator
is a function.",
"testString": "assert(typeof accumulator === 'function', 'accumulator
is a function.');"
},
{
"text": "accumulator(0)
should return a function.",
"testString": "assert(typeof accumulator(0) === 'function', 'accumulator(0)
should return a function.');"
},
{
"text": "accumulator(0)(2)
should return a number.",
"testString": "assert(typeof accumulator(0)(2) === 'number', 'accumulator(0)(2)
should return a number.');"
},
{
"text": "Passing in the values 3, -4, 1.5, and 5 should return 5.5.",
"testString": "assert(testFn(5) === 5.5, 'Passing in the values 3, -4, 1.5, and 5 should return 5.5.');"
}
],
"id": "594810f028c0303b75339ace",
"challengeType": 5,
"releasedOn": "December 27, 2017",
"files": {
"indexjs": {
"key": "indexjs",
"ext": "js",
"name": "index",
"contents": [
"function accumulator (sum) {",
" // Good luck!",
"}"
],
"head": [],
"tail": [
"const testFn = typeof accumulator(3) === 'function' && accumulator(3);",
"if (testFn) {",
" testFn(-4);",
" testFn(1.5);",
"}"
]
}
}
},
{
"title": "Ackermann function",
"description": [
"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.
", "The Ackermann function is usually defined as follows:
", "$$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}$$", "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.
" ], "solutions": [ "function ack (m, n) {\n return m === 0 ? n + 1 : ack(m - 1, n === 0 ? 1 : ack(m, n - 1));\n}\n" ], "tests": [ { "text": "ack
is a function.",
"testString": "assert(typeof ack === 'function', 'ack
is a function.');"
},
{
"text": "ack(0, 0)
should return 1.",
"testString": "assert(ack(0, 0) === 1, 'ack(0, 0)
should return 1.');"
},
{
"text": "ack(1, 1)
should return 3.",
"testString": "assert(ack(1, 1) === 3, 'ack(1, 1)
should return 3.');"
},
{
"text": "ack(2, 5)
should return 13.",
"testString": "assert(ack(2, 5) === 13, 'ack(2, 5)
should return 13.');"
},
{
"text": "ack(3, 3)
should return 61.",
"testString": "assert(ack(3, 3) === 61, 'ack(3, 3)
should return 61.');"
}
],
"id": "594810f028c0303b75339acf",
"challengeType": 5,
"releasedOn": "December 27, 2017",
"files": {
"indexjs": {
"key": "indexjs",
"ext": "js",
"name": "index",
"contents": [
"function ack (m, n) {",
" // Good luck!",
"}"
],
"head": [],
"tail": []
}
}
},
{
"title": "Align columns",
"description": [
"Given a text file of many lines, where fields within a line are delineated by a single $
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.
Use the following text to test your programs:
", "", "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.", "", "
Note that:
", "The example input texts lines may, or may not, have trailing dollar characters.", "All columns should share the same alignment.", "Consecutive space characters produced adjacent to the end of lines are insignificant for the purposes of the task.", "Output text will be viewed in a mono-spaced font on a plain text editor or basic terminal.", "The minimum space between columns should be computed from the text and not hard-coded.", "It is not a requirement to add separating characters between or around columns." ], "solutions": [ "const testArr = [\n 'Given$a$text$file$of$many$lines',\n 'where$fields$within$a$line$',\n 'are$delineated$by$a$single$\"dollar\"$character',\n 'write$a$program',\n 'that$aligns$each$column$of$fields$',\n 'by$ensuring$that$words$in$each$',\n 'column$are$separated$by$at$least$one$space.',\n 'Further,$allow$for$each$word$in$a$column$to$be$either$left$',\n 'justified,$right$justified',\n 'or$center$justified$within$its$column.'\n];\n\nString.prototype.repeat = function (n) { return new Array(1 + parseInt(n)).join(this); };\n\nfunction formatText (input, justification) {\n let x, y, max, cols = 0, diff, left, right;\n for (x = 0; x < input.length; x++) {\n input[x] = input[x].split('$');\n if (input[x].length > cols) {\n cols = input[x].length;\n }\n }\n for (x = 0; x < cols; x++) {\n max = 0;\n for (y = 0; y < input.length; y++) {\n if (input[y][x] && max < input[y][x].length) {\n max = input[y][x].length;\n }\n }\n for (y = 0; y < input.length; y++) {\n if (input[y][x]) {\n diff = (max - input[y][x].length) / 2;\n left = ' '.repeat(Math.floor(diff));\n right = ' '.repeat(Math.ceil(diff));\n if (justification === 'left') {\n right += left; left = '';\n }\n if (justification === 'right') {\n left += right; right = '';\n }\n input[y][x] = left + input[y][x] + right;\n }\n }\n }\n for (x = 0; x < input.length; x++) {\n input[x] = input[x].join(' ');\n }\n input = input.join('\\n');\n return input;\n}\n" ], "tests": [ { "text": "formatText
is a function.",
"testString": "assert(typeof formatText === 'function', 'formatText
is a function.');"
},
{
"text": "formatText
with the above input and \"right\" justification should produce the following: ",
"testString": "assert.strictEqual(formatText(testInput, 'right'), rightAligned, 'formatText
with the above input and \"right\" justification should produce the following: ');"
},
{
"text": "formatText
with the above input and \"left\" justification should produce the following: ",
"testString": "assert.strictEqual(formatText(testInput, 'left'), leftAligned, 'formatText
with the above input and \"left\" justification should produce the following: ');"
},
{
"text": "formatText
with the above input and \"center\" justification should produce the following: ",
"testString": "assert.strictEqual(formatText(testInput, 'center'), centerAligned, 'formatText
with the above input and \"center\" justification should produce the following: ');"
}
],
"id": "594810f028c0303b75339ad0",
"challengeType": 5,
"releasedOn": "December 27, 2017",
"files": {
"indexjs": {
"key": "indexjs",
"ext": "js",
"name": "index",
"contents": [
"const testArr = [",
" '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.'",
"];",
"",
"function formatText (input, justification) {",
" // Good luck!",
"}"
],
"head": [],
"tail": [
"const testInput = [",
" '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 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. `;"
]
}
}
},
{
"title": "Amicable pairs",
"description": [
"Two integers $N$ and $M$ are said to be amicable pairs if $N \\neq M$ and the sum of the proper divisors 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:",
" 1, 2, 4, 8, 16, 32, 37, 74, 148, 296, 592 and ",
" 1, 2, 5, 10, 11, 22, 55, 110, 121, 242, 605 respectively.",
"Task:",
"Calculate and show here the Amicable pairs below 20,000 (there are eight).",
"Related tasks",
"Proper divisors",
"Abundant, deficient and perfect number classifications",
"Aliquot sequence classifications and its amicable classification."
],
"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"
],
"tests": [
{
"text": "amicablePairsUpTo
is a function.",
"testString": "assert(typeof amicablePairsUpTo === 'function', 'amicablePairsUpTo
is a function.');"
},
{
"text": "amicablePairsUpTo(300)
should return [[220,284]]
.",
"testString": "assert.deepEqual(amicablePairsUpTo(300), answer300, 'amicablePairsUpTo(300)
should return [[220,284]]
.');"
},
{
"text": "amicablePairsUpTo(3000)
should return [[220,284],[1184,1210],[2620,2924]]
.",
"testString": "assert.deepEqual(amicablePairsUpTo(3000), answer3000, 'amicablePairsUpTo(3000)
should return [[220,284],[1184,1210],[2620,2924]]
.');"
},
{
"text": "amicablePairsUpTo(20000)
should return [[220,284],[1184,1210],[2620,2924],[5020,5564],[6232,6368],[10744,10856],[12285,14595],[17296,18416]]
.",
"testString": "assert.deepEqual(amicablePairsUpTo(20000), answer20000, 'amicablePairsUpTo(20000)
should return [[220,284],[1184,1210],[2620,2924],[5020,5564],[6232,6368],[10744,10856],[12285,14595],[17296,18416]]
.');"
}
],
"id": "5949b579404977fbaefcd737",
"challengeType": 5,
"releasedOn": "December 27, 2017",
"files": {
"indexjs": {
"key": "indexjs",
"ext": "js",
"name": "index",
"contents": [
"function amicablePairsUpTo (maxNum) {",
" // Good luck!",
" return true;",
"}"
],
"head": [],
"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]",
"];"
]
}
}
},
{
"title": "Averages/Mode",
"description": [
"Write a program to find the mode value of a collection.
The case where the collection is empty may be ignored. Care must be taken to handle the case where the mode is non-unique.
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.
" ], "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" ], "tests": [ { "text": "mode
is a function.",
"testString": "assert(typeof mode === 'function', 'mode
is a function.');"
},
{
"text": "mode([1, 3, 6, 6, 6, 6, 7, 7, 12, 12, 17])
should equal [6]
",
"testString": "assert.deepEqual(mode(arr1), [6], 'mode([1, 3, 6, 6, 6, 6, 7, 7, 12, 12, 17])
should equal [6]
');"
},
{
"text": "mode([1, 2, 4, 4, 1])
should equal [1, 4]
.",
"testString": "assert.deepEqual(mode(arr2).sort(), [1, 4], 'mode([1, 2, 4, 4, 1])
should equal [1, 4]
.');"
}
],
"id": "594d8d0ab97724821379b1e6",
"challengeType": 5,
"releasedOn": "December 27, 2017",
"files": {
"indexjs": {
"key": "indexjs",
"ext": "js",
"name": "index",
"contents": [
"function mode (arr) {",
" // Good luck!",
" return true;",
"}"
],
"head": [],
"tail": [
"const arr1 = [1, 3, 6, 6, 6, 6, 7, 7, 12, 12, 17];",
"const arr2 = [1, 2, 4, 4, 1];"
]
}
}
},
{
"title": "Averages/Pythagorean means",
"description": [
"Compute all three of the Pythagorean means of the set of integers 1 through 10 (inclusive).
Show that $A(x_1,\\ldots,x_n) \\geq G(x_1,\\ldots,x_n) \\geq H(x_1,\\ldots,x_n)$ for this set of positive integers.
The most common of the three means, the arithmetic mean, is the sum of the list divided by its length: $ A(x_1, \\ldots, x_n) = \\frac{x_1 + \\cdots + x_n}{n}$The geometric mean is the $n$th root of the product of the list: $ G(x_1, \\ldots, x_n) = \\sqrt[n]{x_1 \\cdots x_n} $The harmonic mean is $n$ divided by the sum of the reciprocal of each item in the list: $ H(x_1, \\ldots, x_n) = \\frac{n}{\\frac{1}{x_1} + \\cdots + \\frac{1}{x_n}} $", "Assume the input is an ordered array of all inclusive numbers.
", "For the answer, please output an object in the following format:
", "", "{", " values: {", " Arithmetic: 5.5,", " Geometric: 4.528728688116765,", " Harmonic: 3.414171521474055", " },", " test: 'is A >= G >= H ? yes'", "}", "" ], "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" ], "tests": [ { "text": "
pythagoreanMeans
is a function.",
"testString": "assert(typeof pythagoreanMeans === 'function', 'pythagoreanMeans
is a function.');"
},
{
"text": "pythagoreanMeans([1, 2, ..., 10])
should equal the same output above.",
"testString": "assert.deepEqual(pythagoreanMeans(range1), answer1, 'pythagoreanMeans([1, 2, ..., 10])
should equal the same output above.');"
}
],
"id": "594d966a1467eb84194f0086",
"challengeType": 5,
"releasedOn": "December 27, 2017",
"files": {
"indexjs": {
"key": "indexjs",
"ext": "js",
"name": "index",
"contents": [
"function pythagoreanMeans (rangeArr) {",
" // Good luck!",
"}"
],
"head": [],
"tail": [
"const range1 = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];",
"const answer1 = {",
" values: {",
" Arithmetic: 5.5,",
" Geometric: 4.528728688116765,",
" Harmonic: 3.414171521474055",
" },",
" test: 'is A >= G >= H ? yes'",
"};",
""
]
}
}
},
{
"title": "Averages/Root mean square",
"description": [
"Compute the Root mean square of the numbers 1 through 10 inclusive.
", "The root mean square is also known by its initials RMS (or rms), and as the quadratic mean.
The RMS is calculated as the mean of the squares of the numbers, square-rooted:
", "$$x_{\\mathrm{rms}} = \\sqrt {{{x_1}^2 + {x_2}^2 + \\cdots + {x_n}^2} \\over n}. $$
" ], "solutions": [ "function rms (arr) {\n const sumOfSquares = arr.reduce((s, x) => s + x * x, 0);\n return Math.sqrt(sumOfSquares / arr.length);\n}\n" ], "tests": [ { "text": "rms
is a function.",
"testString": "assert(typeof rms === 'function', 'rms
is a function.');"
},
{
"text": "rms([1, 2, 3, 4, 5, 6, 7, 8, 9, 10])
should equal 6.2048368229954285
.",
"testString": "assert.equal(rms(arr1), answer1, 'rms([1, 2, 3, 4, 5, 6, 7, 8, 9, 10])
should equal 6.2048368229954285
.');"
}
],
"id": "594da033de4190850b893874",
"challengeType": 5,
"releasedOn": "December 27, 2017",
"files": {
"indexjs": {
"key": "indexjs",
"ext": "js",
"name": "index",
"contents": [
"function rms (arr) {",
" // Good luck!",
"}"
],
"head": [],
"tail": [
"const arr1 = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];",
"const answer1 = 6.2048368229954285;"
]
}
}
},
{
"title": "Babbage problem",
"description": [
"Charles Babbage, looking ahead to the sorts of problems his Analytical Engine would be able to solve, gave this example:
", "What is the smallest positive integer whose square ends in the digits 269,696?", "
- Babbage, letter to Lord Bowden, 1837; see Hollingdale and Tootill, Electronic Computers, second edition, 1970, p. 125.
", "He thought the answer might be 99,736, whose square is 9,947,269,696; but he couldn't be certain.
", "The task is to find out if Babbage had the right answer.
", "Implement a function to return the lowest integer that satisfies the Babbage problem. If Babbage was right, return Babbage's number.
" ], "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" ], "tests": [ { "text": "babbage
is a function.",
"testString": "assert(typeof babbage === 'function', 'babbage
is a function.');"
},
{
"text": "babbage(99736, 269696)
should not return 99736 (there is a smaller answer).",
"testString": "assert.equal(babbage(babbageAns, endDigits), answer, 'babbage(99736, 269696)
should not return 99736 (there is a smaller answer).');"
}
],
"id": "594db4d0dedb4c06a2a4cefd",
"challengeType": 5,
"releasedOn": "December 27, 2017",
"files": {
"indexjs": {
"key": "indexjs",
"ext": "js",
"name": "index",
"contents": [
"function babbage (babbageNum, endDigits) {",
" // Good luck!",
" return true;",
"}"
],
"head": [],
"tail": [
"const babbageAns = 99736;",
"const endDigits = 269696;",
"const answer = 25264;"
]
}
}
},
{
"title": "Balanced brackets",
"description": [
"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.
", "Examples:", "(empty) true
", "[]
true
][
false
[][]
true
][][
false
[]][[]
false
[[[[]]]]
true
isBalanced
is a function.",
"testString": "assert(typeof isBalanced === 'function', 'isBalanced
is a function.');"
},
{
"text": "isBalanced(\"[]\")
should return true.",
"testString": "assert(isBalanced(testCases[0]), 'isBalanced(\"[]\")
should return true.');"
},
{
"text": "isBalanced(\"]][[[][][][]][\")
should return false.",
"testString": "assert(!isBalanced(testCases[1]), 'isBalanced(\"]][[[][][][]][\")
should return false.');"
},
{
"text": "isBalanced(\"[][[[[][][[[]]]]]]\")
should return true.",
"testString": "assert(isBalanced(testCases[2]), 'isBalanced(\"[][[[[][][[[]]]]]]\")
should return true.');"
},
{
"text": "isBalanced(\"][\")
should return true.",
"testString": "assert(!isBalanced(testCases[3]), 'isBalanced(\"][\")
should return true.');"
},
{
"text": "isBalanced(\"[[[]]]][[]\")
should return true.",
"testString": "assert(!isBalanced(testCases[4]), 'isBalanced(\"[[[]]]][[]\")
should return true.');"
},
{
"text": "isBalanced(\"][[]\")
should return true.",
"testString": "assert(!isBalanced(testCases[5]), 'isBalanced(\"][[]\")
should return true.');"
},
{
"text": "isBalanced(\"][[][]][[[]]\")
should return true.",
"testString": "assert(!isBalanced(testCases[6]), 'isBalanced(\"][[][]][[[]]\")
should return true.');"
},
{
"text": "isBalanced(\"[[][]]][\")
should return true.",
"testString": "assert(!isBalanced(testCases[7]), 'isBalanced(\"[[][]]][\")
should return true.');"
},
{
"text": "isBalanced(\"[[[]]][[]]]][][[\")
should return true.",
"testString": "assert(!isBalanced(testCases[8]), 'isBalanced(\"[[[]]][[]]]][][[\")
should return true.');"
},
{
"text": "isBalanced(\"[]][[]]][[[[][]]\")
should return true.",
"testString": "assert(!isBalanced(testCases[9]), 'isBalanced(\"[]][[]]][[[[][]]\")
should return true.');"
},
{
"text": "isBalanced(\"][]][[][\")
should return true.",
"testString": "assert(!isBalanced(testCases[10]), 'isBalanced(\"][]][[][\")
should return true.');"
},
{
"text": "isBalanced(\"[[]][[][]]\")
should return true.",
"testString": "assert(isBalanced(testCases[11]), 'isBalanced(\"[[]][[][]]\")
should return true.');"
},
{
"text": "isBalanced(\"[[]]\")
should return true.",
"testString": "assert(isBalanced(testCases[12]), 'isBalanced(\"[[]]\")
should return true.');"
},
{
"text": "isBalanced(\"]][]][[]][[[\")
should return true.",
"testString": "assert(!isBalanced(testCases[13]), 'isBalanced(\"]][]][[]][[[\")
should return true.');"
},
{
"text": "isBalanced(\"][]][][[\")
should return true.",
"testString": "assert(!isBalanced(testCases[14]), 'isBalanced(\"][]][][[\")
should return true.');"
},
{
"text": "isBalanced(\"][][\")
should return true.",
"testString": "assert(!isBalanced(testCases[15]), 'isBalanced(\"][][\")
should return true.');"
},
{
"text": "isBalanced(\"[[]]][][][[]][\")
should return true.",
"testString": "assert(!isBalanced(testCases[16]), 'isBalanced(\"[[]]][][][[]][\")
should return true.');"
},
{
"text": "isBalanced(\"\")
should return true.",
"testString": "assert(isBalanced(testCases[17]), 'isBalanced(\"\")
should return true.');"
}
],
"id": "594dc6c729e5700999302b45",
"challengeType": 5,
"releasedOn": "December 27, 2017",
"files": {
"indexjs": {
"key": "indexjs",
"ext": "js",
"name": "index",
"contents": [
"function isBalanced (str) {",
" // Good luck!",
" return true;",
"}"
],
"head": [],
"tail": [
"const testCases = [",
" '[]',",
" ']][[[][][][]][',",
" '[][[[[][][[[]]]]]]',",
" '][',",
" '[[[]]]][[]',",
" '][[]',",
" '][[][]][[[]]',",
" '[[][]]][',",
" '[[[]]][[]]]][][[',",
" '[]][[]]][[[[][]]',",
" '][]][[][',",
" '[[]][[][]]',",
" '[[]]',",
" ']][]][[]][[[',",
" '][]][][[',",
" '][][',",
" '[[]]][][][[]][',",
" ''",
"];"
]
}
}
},
{
"title": "Circles of given radius through two points",
"description": [
"Given two points on a plane and a radius, usually two circles of given radius can be drawn through the points.
", "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\"Radius Zero\"
.",
"If points are coincident, return \"Coincident point. Infinite solutions\"
.",
"If points are farther apart than the diameter, return \"No intersection. Points further apart than circle diameter\"
.",
"Sample inputs:",
"", " 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", "", "Ref:", "Finding the Center of a Circle from 2 Points and Radius from Math forum @ Drexel" ], "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" ], "tests": [ { "text": "
getCircles
is a function.",
"testString": "assert(typeof getCircles === 'function', 'getCircles
is a function.');"
},
{
"text": "getCircles([0.1234, 0.9876], [0.8765, 0.2345], 2.0)
should return [[1.8631, 1.9742], [-0.8632, -0.7521]]
.",
"testString": "assert.deepEqual(getCircles(...testCases[0]), answers[0], 'getCircles([0.1234, 0.9876], [0.8765, 0.2345], 2.0)
should return [[1.8631, 1.9742], [-0.8632, -0.7521]]
.');"
},
{
"text": "getCircles([0.0000, 2.0000], [0.0000, 0.0000], 1.0)
should return [0, 1]
",
"testString": "assert.deepEqual(getCircles(...testCases[1]), answers[1], 'getCircles([0.0000, 2.0000], [0.0000, 0.0000], 1.0)
should return [0, 1]
');"
},
{
"text": "getCircles([0.1234, 0.9876], [0.1234, 0.9876], 2.0)
should return Coincident point. Infinite solutions
",
"testString": "assert.deepEqual(getCircles(...testCases[2]), answers[2], 'getCircles([0.1234, 0.9876], [0.1234, 0.9876], 2.0)
should return Coincident point. Infinite solutions
');"
},
{
"text": "getCircles([0.1234, 0.9876], [0.8765, 0.2345], 0.5)
should return No intersection. Points further apart than circle diameter
",
"testString": "assert.deepEqual(getCircles(...testCases[3]), answers[3], 'getCircles([0.1234, 0.9876], [0.8765, 0.2345], 0.5)
should return No intersection. Points further apart than circle diameter
');"
},
{
"text": "getCircles([0.1234, 0.9876], [0.1234, 0.9876], 0.0)
should return Radius Zero
",
"testString": "assert.deepEqual(getCircles(...testCases[4]), answers[4], 'getCircles([0.1234, 0.9876], [0.1234, 0.9876], 0.0)
should return Radius Zero
');"
}
],
"id": "5951815dd895584b06884620",
"challengeType": 5,
"releasedOn": "December 27, 2017",
"files": {
"indexjs": {
"key": "indexjs",
"ext": "js",
"name": "index",
"contents": [
"function getCircles (...args) {",
" // Good luck!",
" return true;",
"}"
],
"head": [],
"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'",
"];"
]
}
}
},
{
"title": "Closest-pair problem",
"description": [
"Task:",
"Provide a function to find the closest two points among a set of given points in two dimensions, i.e. to solve the Closest pair of points problem in the planar case.
The straightforward solution is a O(n2) algorithm (which we can call brute-force algorithm); the pseudo-code (using indexes) could be simply:
", "", "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", "", "
A better algorithm is based on the recursive divide&conquer approach, as explained also at Wikipedia's Closest pair of points problem, which is O(n log n); a pseudo-code could be:
", "", "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", "else", " xL ← points of xP from 1 to ⌈N/2⌉", " xR ← points of xP from ⌈N/2⌉+1 to N", " xm ← xP(⌈N/2⌉)x", " yL ← { p ∈ yP : px ≤ xm }", " yR ← { p ∈ yP : px > xm }", " (dL, pairL) ← closestPair of (xL, yL)", " (dR, pairR) ← closestPair of (xR, yR)", " (dmin, pairMin) ← (dR, pairR)", " if dL < dR then", " (dmin, pairMin) ← (dL, pairL)", " endif", " yS ← { p ∈ yP : |xm - px| < dmin }", " nS ← number of points in yS", " (closest, closestPair) ← (dmin, pairMin)", " for i from 1 to nS - 1", " k ← i + 1", " while k ≤ nS and yS(k)y - yS(i)y < dmin", " if |yS(k) - yS(i)| < closest then", " (closest, closestPair) ← (|yS(k) - yS(i)|, {yS(k), yS(i)})", " endif", " k ← k + 1", " endwhile", " endfor", " return closest, closestPair", "endif", "", "References and further readings:", " Closest pair of points problem", " Closest Pair (McGill)", " Closest Pair (UCSB)", " Closest pair (WUStL)", " Closest pair (IUPUI) ", "
For the input, expect the argument to be an array of objects (points) with x
and y
members set to numbers. For the output, return an object containing the key:value pairs for distance
and pair
(i.e., the pair of two closest points).
getClosestPair
is a function.",
"testString": "assert(typeof getClosestPair === 'function', 'getClosestPair
is a function.');"
},
{
"text": "Distance should be the following.",
"testString": "assert.equal(getClosestPair(points1).distance, answer1.distance, 'Distance should be the following.');"
},
{
"text": "Points should be the following.",
"testString": "assert.deepEqual(JSON.parse(JSON.stringify(getClosestPair(points1))).pair, answer1.pair, 'Points should be the following.');"
},
{
"text": "Distance should be the following.",
"testString": "assert.equal(getClosestPair(points2).distance, answer2.distance, 'Distance should be the following.');"
},
{
"text": "Points should be the following.",
"testString": "assert.deepEqual(JSON.parse(JSON.stringify(getClosestPair(points2))).pair, answer2.pair, 'Points should be the following.');"
}
],
"id": "5951a53863c8a34f02bf1bdc",
"challengeType": 5,
"releasedOn": "December 27, 2017",
"files": {
"indexjs": {
"key": "indexjs",
"ext": "js",
"name": "index",
"contents": [
"const Point = function (x, y) {",
" this.x = x;",
" this.y = y;",
"};",
"Point.prototype.getX = function () {",
" return this.x;",
"};",
"Point.prototype.getY = function () {",
" return this.y;",
"};",
"",
"function getClosestPair (pointsArr) {",
" // Good luck!",
" return true;",
"}"
],
"head": [],
"tail": [
"const points1 = [",
"\tnew Point(0.748501, 4.09624),",
"\tnew Point(3.00302, 5.26164),",
"\tnew Point(3.61878, 9.52232),",
"\tnew Point(7.46911, 4.71611),",
"\tnew Point(5.7819, 2.69367),",
"\tnew Point(2.34709, 8.74782),",
"\tnew Point(2.87169, 5.97774),",
"\tnew Point(6.33101, 0.463131),",
"\tnew Point(7.46489, 4.6268),",
"\tnew Point(1.45428, 0.087596)",
"];",
"",
"const points2 = [",
" new Point(37100, 13118),",
" new Point(37134, 1963),",
" new Point(37181, 2008),",
" new Point(37276, 21611),",
" new Point(37307, 9320)",
"];",
"",
"const answer1 = {",
" distance: 0.0894096443343775,",
" pair: [",
" {",
" x: 7.46489,",
" y: 4.6268",
" },",
" {",
" x: 7.46911,",
" y: 4.71611",
" }",
" ]",
"};",
"",
"const answer2 = {",
" distance: 65.06919393998976,",
" pair: [",
" {",
" x: 37134,",
" y: 1963",
" },",
" {",
" x: 37181,",
" y: 2008",
" }",
" ]",
"};",
"",
"const benchmarkPoints = [",
" new Point(16909, 54699),",
" new Point(14773, 61107),",
" new Point(95547, 45344),",
" new Point(95951, 17573),",
" new Point(5824, 41072),",
" new Point(8769, 52562),",
" new Point(21182, 41881),",
" new Point(53226, 45749),",
" new Point(68180, 887),",
" new Point(29322, 44017),",
" new Point(46817, 64975),",
" new Point(10501, 483),",
" new Point(57094, 60703),",
" new Point(23318, 35472),",
" new Point(72452, 88070),",
" new Point(67775, 28659),",
" new Point(19450, 20518),",
" new Point(17314, 26927),",
" new Point(98088, 11164),",
" new Point(25050, 56835),",
" new Point(8364, 6892),",
" new Point(37868, 18382),",
" new Point(23723, 7701),",
" new Point(55767, 11569),",
" new Point(70721, 66707),",
" new Point(31863, 9837),",
" new Point(49358, 30795),",
" new Point(13041, 39745),",
" new Point(59635, 26523),",
" new Point(25859, 1292),",
" new Point(1551, 53890),",
" new Point(70316, 94479),",
" new Point(48549, 86338),",
" new Point(46413, 92747),",
" new Point(27186, 50426),",
" new Point(27591, 22655),",
" new Point(10905, 46153),",
" new Point(40408, 84202),",
" new Point(52821, 73520),",
" new Point(84865, 77388),",
" new Point(99819, 32527),",
" new Point(34404, 75657),",
" new Point(78457, 96615),",
" new Point(42140, 5564),",
" new Point(62175, 92342),",
" new Point(54958, 67112),",
" new Point(4092, 19709),",
" new Point(99415, 60298),",
" new Point(51090, 52158),",
" new Point(48953, 58567)",
"];"
]
}
}
},
{
"title": "Combinations",
"description": [
"Task:",
"Given non-negative integers m and n, generate all size m combinations of the integers from 0 (zero) to n-1 in sorted order (each combination is sorted and the entire table is sorted).
", "Example:", "3 comb 5 is:
", "", "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", "" ], "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" ], "tests": [ { "text": "
combinations
is a function.",
"testString": "assert(typeof combinations === 'function', 'combinations
is a function.');"
},
{
"text": "combinations(3, 5)
should return [[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]]
.",
"testString": "assert.deepEqual(combinations(testInput1[0], testInput1[1]), testOutput1, 'combinations(3, 5)
should return [[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]]
.');"
},
{
"text": "combinations(4, 6)
should return [[0,1,2,3], [0,1,2,4], [0,1,2,5], [0,1,3,4], [0,1,3,5], [0,1,4,5], [0,2,3,4], [0,2,3,5], [0,2,4,5], [0,3,4,5], [1,2,3,4], [1,2,3,5], [1,2,4,5], [1,3,4,5], [2,3,4,5]]
",
"testString": "assert.deepEqual(combinations(testInput2[0], testInput2[1]), testOutput2, 'combinations(4, 6)
should return [[0,1,2,3], [0,1,2,4], [0,1,2,5], [0,1,3,4], [0,1,3,5], [0,1,4,5], [0,2,3,4], [0,2,3,5], [0,2,4,5], [0,3,4,5], [1,2,3,4], [1,2,3,5], [1,2,4,5], [1,3,4,5], [2,3,4,5]]
');"
}
],
"id": "5958469238c0d8d2632f46db",
"challengeType": 5,
"releasedOn": "December 27, 2017",
"files": {
"indexjs": {
"key": "indexjs",
"ext": "js",
"name": "index",
"contents": [
"function combinations (m, n) {",
" // Good luck!",
" return true;",
"}"
],
"head": [],
"tail": [
"const testInput1 = [3, 5];",
"const testOutput1 = [[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]];",
"",
"const testInput2 = [4, 6];",
"const testOutput2 = [[0, 1, 2, 3], [0, 1, 2, 4], [0, 1, 2, 5], [0, 1, 3, 4], [0, 1, 3, 5], [0, 1, 4, 5], [0, 2, 3, 4], [0, 2, 3, 5], [0, 2, 4, 5], [0, 3, 4, 5], [1, 2, 3, 4], [1, 2, 3, 5], [1, 2, 4, 5], [1, 3, 4, 5], [2, 3, 4, 5]];"
]
}
}
},
{
"title": "Comma quibbling",
"description": [
"Comma quibbling is a task originally set by Eric Lippert in his blog.
", "Task:Write a function to generate a string output which is the concatenation of input words from a list/sequence where:
", "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}\".", "Test your function with the following series of inputs showing your output here on this page:
", "[] # (No input words).", "[\"ABC\"]", "[\"ABC\", \"DEF\"]", "[\"ABC\", \"DEF\", \"G\", \"H\"]", "Note: Assume words are non-empty strings of uppercase characters for this task.
" ], "solutions": [ "function quibble (words) {\n return \"{\" +\n words.slice(0, words.length - 1).join(\",\") +\n (words.length > 1 ? \" and \" : \"\") +\n (words[words.length - 1] || '') +\n \"}\";\n}\n" ], "tests": [ { "text": "quibble
is a function.",
"testString": "assert(typeof quibble === 'function', 'quibble
is a function.');"
},
{
"text": "quibble([\"ABC\"])
should return a string.",
"testString": "assert(typeof quibble([\"ABC\"]) === 'string', 'quibble([\"ABC\"])
should return a string.');"
},
{
"text": "quibble([])
should return \"{}\".",
"testString": "assert.equal(quibble(testCases[0]), results[0], 'quibble([])
should return \"{}\".');"
},
{
"text": "quibble([\"ABC\"])
should return \"{ABC}\".",
"testString": "assert.equal(quibble(testCases[1]), results[1], 'quibble([\"ABC\"])
should return \"{ABC}\".');"
},
{
"text": "quibble([\"ABC\", \"DEF\"])
should return \"{ABC and DEF}\".",
"testString": "assert.equal(quibble(testCases[2]), results[2], 'quibble([\"ABC\", \"DEF\"])
should return \"{ABC and DEF}\".');"
},
{
"text": "quibble([\"ABC\", \"DEF\", \"G\", \"H\"])
should return \"{ABC,DEF,G and H}\".",
"testString": "assert.equal(quibble(testCases[3]), results[3], 'quibble([\"ABC\", \"DEF\", \"G\", \"H\"])
should return \"{ABC,DEF,G and H}\".');"
}
],
"id": "596e414344c3b2872167f0fe",
"challengeType": 5,
"releasedOn": "December 27, 2017",
"files": {
"indexjs": {
"key": "indexjs",
"ext": "js",
"name": "index",
"contents": [
"function quibble (words) {",
" // Good luck!",
" return true;",
"}"
],
"head": [],
"tail": [
"const testCases = [[], [\"ABC\"], [\"ABC\", \"DEF\"], [\"ABC\", \"DEF\", \"G\", \"H\"]];",
"const results = [\"{}\", \"{ABC}\", \"{ABC and DEF}\", \"{ABC,DEF,G and H}\"];"
]
}
}
},
{
"title": "Compare a list of strings",
"description": [
"Given a list of arbitrarily many strings, implement a function for each of the following conditions:
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)" ], "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" ], "tests": [ { "text": "allEqual
is a function.",
"testString": "assert(typeof allEqual === 'function', 'allEqual
is a function.');"
},
{
"text": "azSorted
is a function.",
"testString": "assert(typeof azSorted === 'function', 'azSorted
is a function.');"
},
{
"text": "allEqual([\"AA\", \"AA\", \"AA\", \"AA\"])
returns true.",
"testString": "assert(allEqual(testCases[0]), 'allEqual([\"AA\", \"AA\", \"AA\", \"AA\"])
returns true.');"
},
{
"text": "azSorted([\"AA\", \"AA\", \"AA\", \"AA\"])
returns false.",
"testString": "assert(!azSorted(testCases[0]), 'azSorted([\"AA\", \"AA\", \"AA\", \"AA\"])
returns false.');"
},
{
"text": "allEqual([\"AA\", \"ACB\", \"BB\", \"CC\"])
returns false.",
"testString": "assert(!allEqual(testCases[1]), 'allEqual([\"AA\", \"ACB\", \"BB\", \"CC\"])
returns false.');"
},
{
"text": "azSorted([\"AA\", \"ACB\", \"BB\", \"CC\"])
returns true.",
"testString": "assert(azSorted(testCases[1]), 'azSorted([\"AA\", \"ACB\", \"BB\", \"CC\"])
returns true.');"
},
{
"text": "allEqual([])
returns true.",
"testString": "assert(allEqual(testCases[2]), 'allEqual([])
returns true.');"
},
{
"text": "azSorted([])
returns true.",
"testString": "assert(azSorted(testCases[2]), 'azSorted([])
returns true.');"
},
{
"text": "allEqual([\"AA\"])
returns true.",
"testString": "assert(allEqual(testCases[3]), 'allEqual([\"AA\"])
returns true.');"
},
{
"text": "azSorted([\"AA\"])
returns true.",
"testString": "assert(azSorted(testCases[3]), 'azSorted([\"AA\"])
returns true.');"
},
{
"text": "allEqual([\"BB\", \"AA\"])
returns false.",
"testString": "assert(!allEqual(testCases[4]), 'allEqual([\"BB\", \"AA\"])
returns false.');"
},
{
"text": "azSorted([\"BB\", \"AA\"])
returns false.",
"testString": "assert(!azSorted(testCases[4]), 'azSorted([\"BB\", \"AA\"])
returns false.');"
}
],
"id": "596e457071c35c882915b3e4",
"challengeType": 5,
"releasedOn": "December 27, 2017",
"files": {
"indexjs": {
"key": "indexjs",
"ext": "js",
"name": "index",
"contents": [
"function allEqual (arr) {",
" // Good luck!",
" return true;",
"}",
"",
"function azSorted (arr) {",
" // Good luck!",
" return true;",
"}"
],
"head": [],
"tail": [
"const testCases = [['AA', 'AA', 'AA', 'AA'], ['AA', 'ACB', 'BB', 'CC'], [], ['AA'], ['BB', 'AA']];"
]
}
}
},
{
"title": "Convert seconds to compound duration",
"description": [
"Task:",
"Implement a function which:
", "takes a positive integer representing a duration in seconds as input (e.g.,100
), and",
"returns a string which shows the same duration decomposed into weeks, days, hours, minutes, and seconds as detailed below (e.g., \"1 min, 40 sec
\").",
"Demonstrate that it passes the following three test-cases:
Test Cases
", "input number | ", "output number | ", "
---|---|
7259 | ", "2 hr, 59 sec | ",
"
86400 | ", "1 d | ",
"
6000000 | ", "9 wk, 6 d, 10 hr, 40 min | ",
"
Details
", "The following five units should be used:", "unit | ", "suffix used in output | ", "conversion | ", "
---|---|---|
week | ", "wk | ",
"1 week = 7 days | ", "
day | ", "d | ",
"1 day = 24 hours | ", "
hour | ", "hr | ",
"1 hour = 60 minutes | ", "
minute | ", "min | ",
"1 minute = 60 seconds | ", "
second | ", "sec | ",
"", " |
1 d
\" and not \"0 wk, 1 d, 0 hr, 0 min, 0 sec
\").Give larger units precedence over smaller ones as much as possible (e.g., return 2 min, 10 sec
and not 1 min, 70 sec
or 130 sec
)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).",
"convertSeconds
is a function.",
"testString": "assert(typeof convertSeconds === 'function', 'convertSeconds
is a function.');"
},
{
"text": "convertSeconds(7259)
should return 2 hr, 59 sec
.",
"testString": "assert.equal(convertSeconds(testCases[0]), results[0], 'convertSeconds(7259)
should return 2 hr, 59 sec
.');"
},
{
"text": "convertSeconds(86400)
should return 1 d
.",
"testString": "assert.equal(convertSeconds(testCases[1]), results[1], 'convertSeconds(86400)
should return 1 d
.');"
},
{
"text": "convertSeconds(6000000)
should return 9 wk, 6 d, 10 hr, 40 min
.",
"testString": "assert.equal(convertSeconds(testCases[2]), results[2], 'convertSeconds(6000000)
should return 9 wk, 6 d, 10 hr, 40 min
.');"
}
],
"id": "596fd036dc1ab896c5db98b1",
"challengeType": 5,
"releasedOn": "December 27, 2017",
"files": {
"indexjs": {
"key": "indexjs",
"ext": "js",
"name": "index",
"contents": [
"function convertSeconds (sec) {",
" // Good luck!",
" return true;",
"}"
],
"head": [],
"tail": [
"const testCases = [7259, 86400, 6000000];",
"const results = ['2 hr, 59 sec', '1 d', '9 wk, 6 d, 10 hr, 40 min'];"
]
}
}
},
{
"title": "Count occurrences of a substring",
"description": [
"Task:",
"Create a function, or show a built-in function, to count the number of non-overlapping occurrences of a substring inside a string.
The function should take two arguments:
", "the first argument being the string to search, and", "the second a substring to be searched for.", "It should return an integer count.
", "The matching should yield the highest number of non-overlapping matches.
In general, this essentially means matching from left-to-right or right-to-left.
" ], "solutions": [ "function countSubstring(str, subStr) {\n const escapedSubStr = subStr.replace(/[.+*?^$[\\]{}()|/]/g, '\\\\$&');\n const matches = str.match(new RegExp(escapedSubStr, 'g'));\n return matches ? matches.length : 0;\n}\n" ], "tests": [ { "text": "countSubstring
is a function.",
"testString": "assert(typeof countSubstring === 'function', 'countSubstring
is a function.');"
},
{
"text": "countSubstring(\"the three truths\", \"th\")
should return 3
.",
"testString": "assert.equal(countSubstring(testCases[0], searchString[0]), results[0], 'countSubstring(\"the three truths\", \"th\")
should return 3
.');"
},
{
"text": "countSubstring(\"ababababab\", \"abab\")
should return 2
.",
"testString": "assert.equal(countSubstring(testCases[1], searchString[1]), results[1], 'countSubstring(\"ababababab\", \"abab\")
should return 2
.');"
},
{
"text": "countSubstring(\"abaabba*bbaba*bbab\", \"a*b\")
should return 2
.",
"testString": "assert.equal(countSubstring(testCases[2], searchString[2]), results[2], 'countSubstring(\"abaabba*bbaba*bbab\", \"a*b\")
should return 2
.');"
}
],
"id": "596fda99c69f779975a1b67d",
"challengeType": 5,
"releasedOn": "December 27, 2017",
"files": {
"indexjs": {
"key": "indexjs",
"ext": "js",
"name": "index",
"contents": [
"function countSubstring (str, subStr) {",
" // Good luck!",
" return true;",
"}"
],
"head": [],
"tail": [
"const testCases = ['the three truths', 'ababababab', 'abaabba*bbaba*bbab'];",
"const searchString = ['th', 'abab', 'a*b'];",
"const results = [3, 2, 2];"
]
}
}
},
{
"title": "Count the coins",
"description": [
"There are four types of common coins in US currency:
", "quarters (25 cents)", "dimes (10 cents)", "nickels (5 cents), and ", "pennies (1 cent) ", "There are six ways to make change for 15 cents:
", "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:", "Implement a function to determine how many ways there are to make change for a dollar using these common coins? (1 dollar = 100 cents).
", "Reference:", " an algorithm from MIT Press. " ], "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": [ { "text": "countCoins
is a function.",
"testString": "assert(typeof countCoins === 'function', 'countCoins
is a function.');"
},
{
"text": "countCoints()
should return 242.",
"testString": "assert.equal(countCoins(), 242, 'countCoints()
should return 242.');"
}
],
"id": "59713bd26bdeb8a594fb9413",
"challengeType": 5,
"releasedOn": "December 27, 2017",
"files": {
"indexjs": {
"key": "indexjs",
"ext": "js",
"name": "index",
"contents": [
"function countCoins () {",
" // Good luck!",
" return true;",
"}"
],
"head": [],
"tail": []
}
}
},
{
"title": "Cramer's rule",
"description": [
"In linear algebra, Cramer's rule is an explicit formula for the solution of a system of linear equations 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.
", "Given
", "", "$\\left\\{\\begin{matrix}a_1x + b_1y + c_1z&= {\\color{red}d_1}\\\\a_2x + b_2y + c_2z&= {\\color{red}d_2}\\\\a_3x + b_3y + c_3z&= {\\color{red}d_3}\\end{matrix}\\right.$
", "which in matrix format is
", "$\\begin{bmatrix} a_1 & b_1 & c_1 \\\\ a_2 & b_2 & c_2 \\\\ a_3 & b_3 & c_3 \\end{bmatrix}\\begin{bmatrix} x \\\\ y \\\\ z \\end{bmatrix}=\\begin{bmatrix} {\\color{red}d_1} \\\\ {\\color{red}d_2} \\\\ {\\color{red}d_3} \\end{bmatrix}.$
", "Then the values of $x, y$ and $z$ can be found as follows:
", "$x = \\frac{\\begin{vmatrix} {\\color{red}d_1} & b_1 & c_1 \\\\ {\\color{red}d_2} & b_2 & c_2 \\\\ {\\color{red}d_3} & b_3 & c_3 \\end{vmatrix} } { \\begin{vmatrix} a_1 & b_1 & c_1 \\\\ a_2 & b_2 & c_2 \\\\ a_3 & b_3 & c_3 \\end{vmatrix}}, \\quad y = \\frac {\\begin{vmatrix} a_1 & {\\color{red}d_1} & c_1 \\\\ a_2 & {\\color{red}d_2} & c_2 \\\\ a_3 & {\\color{red}d_3} & c_3 \\end{vmatrix}} {\\begin{vmatrix} a_1 & b_1 & c_1 \\\\ a_2 & b_2 & c_2 \\\\ a_3 & b_3 & c_3 \\end{vmatrix}}, \\text{ and }z = \\frac { \\begin{vmatrix} a_1 & b_1 & {\\color{red}d_1} \\\\ a_2 & b_2 & {\\color{red}d_2} \\\\ a_3 & b_3 & {\\color{red}d_3} \\end{vmatrix}} {\\begin{vmatrix} a_1 & b_1 & c_1 \\\\ a_2 & b_2 & c_2 \\\\ a_3 & b_3 & c_3 \\end{vmatrix} }.$
", "", "Task", "Given the following system of equations:
", "$\\begin{cases}", "2w-x+5y+z=-3 \\\\", "3w+2x+2y-6z=-32 \\\\", "w+3x+3y-z=-47 \\\\", "5w-2x-3y+3z=49 \\\\", "\\end{cases}$", "
", "solve for $w$, $x$, $y$ and $z$, using Cramer's rule.
" ], "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" ], "tests": [ { "text": "cramersRule
is a function.",
"testString": "assert(typeof cramersRule === 'function', 'cramersRule
is a function.');"
},
{
"text": "cramersRule([[2, -1, 5, 1], [3, 2, 2, -6], [1, 3, 3, -1], [5, -2, -3, 3]], [-3, -32, -47, 49])
should return [2, -12, -4, 1]
.",
"testString": "assert.deepEqual(cramersRule(matrices[0], freeTerms[0]), answers[0], 'cramersRule([[2, -1, 5, 1], [3, 2, 2, -6], [1, 3, 3, -1], [5, -2, -3, 3]], [-3, -32, -47, 49])
should return [2, -12, -4, 1]
.');"
},
{
"text": "cramersRule([[3, 1, 1], [2, 2, 5], [1, -3, -4]], [3, -1, 2])
should return [1, 1, -1]
.",
"testString": "assert.deepEqual(cramersRule(matrices[1], freeTerms[1]), answers[1], 'cramersRule([[3, 1, 1], [2, 2, 5], [1, -3, -4]], [3, -1, 2])
should return [1, 1, -1]
.');"
}
],
"id": "59713da0a428c1a62d7db430",
"challengeType": 5,
"releasedOn": "December 27, 2017",
"files": {
"indexjs": {
"key": "indexjs",
"ext": "js",
"name": "index",
"contents": [
"function cramersRule (matrix, freeTerms) {",
" // Good luck!",
" return true;",
"}"
],
"head": [],
"tail": [
"const matrices = [",
" [",
" [2, -1, 5, 1],",
" [3, 2, 2, -6],",
" [1, 3, 3, -1],",
" [5, -2, -3, 3]",
" ],",
" [",
" [3, 1, 1],",
" [2, 2, 5],",
" [1, -3, -4]",
" ]",
"];",
"const freeTerms = [[-3, -32, -47, 49], [3, -1, 2]];",
"",
"const answers = [[2, -12, -4, 1], [1, 1, -1]];"
]
}
}
},
{
"title": "Date format",
"description": [
"Task:",
"Return an array with the current date in the formats:
", "- 2007-11-23 and
", "- Sunday, November 23, 2007
", "Example output: ['2007-11-23', 'Sunday, November 23, 2007']
getDateFormats
is a function.",
"testString": "assert(typeof getDateFormats === 'function', 'getDateFormats
is a function.');"
},
{
"text": "Should return an object.",
"testString": "assert(typeof getDateFormats() === 'object', 'Should return an object.');"
},
{
"text": "Should returned an array with 2 elements.",
"testString": "assert(getDateFormats().length === 2, 'Should returned an array with 2 elements.');"
},
{
"text": "Should return the correct date in the right format",
"testString": "assert.deepEqual(getDateFormats(), dates, equalsMessage);"
}
],
"id": "59669d08d75b60482359409f",
"challengeType": 5,
"releasedOn": "December 27, 2017",
"files": {
"indexjs": {
"key": "indexjs",
"ext": "js",
"name": "index",
"contents": [
"function getDateFormats () {",
" // Good luck!",
" return true;",
"}"
],
"head": [],
"tail": [
"const getDateSolution = () => {",
" const date = new Date();",
" const weekdays = ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'];",
" const months = ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'];",
" const fmt1 = `${date.getFullYear()}-${(1 + date.getMonth())}-${date.getDate()}`;",
" const fmt2 = `${weekdays[date.getDay()]}, ${months[date.getMonth()]} ${date.getDate()}, ${date.getFullYear()}`;",
" return [fmt1, fmt2];",
"};",
"",
"const dates = getDateSolution();",
"const equalsMessage = `message: getDataFormats()
should return [\"${dates[0]}\", \"${dates[1]}\"]
.`;"
]
}
}
},
{
"title": "Date manipulation",
"description": [
"Task:",
"Given a date string in EST, output the given date as a string with 12 hours added to the time.
", "Time zone should be preserved.
", "Example input:
", "\"March 7 2009 7:30pm EST\"
Example output:
", "\"March 8 2009 7:30am EST\"
add12Hours
is a function.",
"testString": "assert(typeof add12Hours === 'function', 'add12Hours
is a function.');"
},
{
"text": "add12Hours(dateString)
should return a string.",
"testString": "assert(typeof add12Hours(tests[0]) === 'string', 'add12Hours(dateString)
should return a string.');"
},
{
"text": "add12Hours(\"' + tests[0] + '\")
should return \"' + answers[0] + '\"
",
"testString": "assert(add12Hours(tests[0]) === answers[0], 'add12Hours(\"' + tests[0] + '\")
should return \"' + answers[0] + '\"
');"
},
{
"text": "Should handel day change. add12Hours(\"' + tests[1] + '\")
should return \"' + answers[1] + '\"
",
"testString": "assert(add12Hours(tests[1]) === answers[1], 'Should handel day change. add12Hours(\"' + tests[1] + '\")
should return \"' + answers[1] + '\"
');"
},
{
"text": "Should handel month change in a leap years. add12Hours(\"' + tests[2] + '\")
should return \"' + answers[2] + '\"
",
"testString": "assert(add12Hours(tests[2]) === answers[2], 'Should handel month change in a leap years. add12Hours(\"' + tests[2] + '\")
should return \"' + answers[2] + '\"
');"
},
{
"text": "Should handel month change in a common years. add12Hours(\"' + tests[3] + '\")
should return \"' + answers[3] + '\"
",
"testString": "assert(add12Hours(tests[3]) === answers[3], 'Should handel month change in a common years. add12Hours(\"' + tests[3] + '\")
should return \"' + answers[3] + '\"
');"
},
{
"text": "Should handel year change. add12Hours(\"' + tests[4] + '\")
should return \"' + answers[4] + '\"
",
"testString": "assert(add12Hours(tests[4]) === answers[4], 'Should handel year change. add12Hours(\"' + tests[4] + '\")
should return \"' + answers[4] + '\"
');"
}
],
"id": "5966c21cf732a95f1b67dd28",
"challengeType": 5,
"releasedOn": "December 27, 2017",
"files": {
"indexjs": {
"key": "indexjs",
"ext": "js",
"name": "index",
"contents": [
"function add12Hours (dateString) {",
" // Good luck!",
" return true;",
"}"
],
"head": [],
"tail": [
"const tests = [",
" 'January 17 2017 11:43am EST',",
" 'March 7 2009 7:30pm EST',",
" 'February 29 2004 9:15pm EST',",
" 'February 28 1999 3:15pm EST',",
" 'December 31 2020 1:45pm EST'",
"];",
"const answers = [",
" 'January 17 2017 11:43pm EST',",
" 'March 8 2009 7:30am EST',",
" 'March 1 2004 9:15am EST',",
" 'March 1 1999 3:15am EST',",
" 'January 1 2021 1:45am EST'",
"];"
]
}
}
},
{
"title": "Day of the week",
"description": [
"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).
", "Task:
", "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.
" ], "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" ], "tests": [ { "text": "findXmasSunday
is a function.",
"testString": "assert(typeof findXmasSunday === 'function', 'findXmasSunday
is a function.');"
},
{
"text": "findChristmasSunday(2000, 2100)
should return an array.",
"testString": "assert(typeof findXmasSunday(2000, 2100) === 'object', 'findChristmasSunday(2000, 2100)
should return an array.');"
},
{
"text": "findChristmasSunday(2008, 2121
should return [1977, 1983, 1988, 1994, 2005, 2011, 2016]",
"testString": "assert.deepEqual(findXmasSunday(1970, 2017), firstSolution, 'findChristmasSunday(2008, 2121
should return [1977, 1983, 1988, 1994, 2005, 2011, 2016]');"
},
{
"text": "findChristmasSunday(2008, 2121
should return [2011, 2016, 2022, 2033, 2039, 2044, 2050, 2061, 2067, 2072, 2078, 2089, 2095, 2101, 2107, 2112, 2118]",
"testString": "assert.deepEqual(findXmasSunday(2008, 2121), secondSolution, 'findChristmasSunday(2008, 2121
should return [2011, 2016, 2022, 2033, 2039, 2044, 2050, 2061, 2067, 2072, 2078, 2089, 2095, 2101, 2107, 2112, 2118]');"
}
],
"id": "5966f99c45e8976909a85575",
"challengeType": 5,
"releasedOn": "December 27, 2017",
"files": {
"indexjs": {
"key": "indexjs",
"ext": "js",
"name": "index",
"contents": [
"function findXmasSunday (start, end) {",
" // Good luck!",
" return true;",
"}"
],
"head": [],
"tail": [
"const firstSolution = [1977, 1983, 1988, 1994, 2005, 2011, 2016];",
"const secondSolution = [2011, 2016, 2022, 2033, 2039, 2044, 2050, 2061, 2067, 2072, 2078, 2089, 2095, 2101, 2107, 2112, 2118];"
]
}
}
},
{
"title": "Deal cards for FreeCell",
"description": [
"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 DOS, then Windows.
", "This version introduced 32000 numbered deals. (The FreeCell FAQ tells this history.)
As the game became popular, Jim Horne disclosed the algorithm, and other implementations of FreeCell began to reproduce the Microsoft deals.
", "These deals are numbered from 1 to 32000.
", "Newer versions from Microsoft have 1 million deals, numbered from 1 to 1000000; some implementations allow numbers outside that range.
The algorithm uses this linear congruential generator from Microsoft C:
$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.", "The algorithm follows:
Seed the RNG with the number of the deal.", "Create an array 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.", "Example:", "Order to deal cards
", "1 2 3 4 5 6 7 8", " 9 10 11 12 13 14 15 16", "17 18 19 20 21 22 23 24", "25 26 27 28 29 30 31 32", "33 34 35 36 37 38 39 40", "41 42 43 44 45 46 47 48", "49 50 51 52", "
Game #1
", "[", "['JD', '2D', '9H', 'JC', '5D', '7H', '7C', '5H'],", "['KD', 'KC', '9S', '5S', 'AD', 'QC', 'KH', '3H'],", "['2S', 'KS', '9D', 'QD', 'JS', 'AS', 'AH', '3C'],", "['4C', '5C', 'TS', 'QH', '4H', 'AC', '4D', '7S'],", "['3S', 'TD', '4S', 'TH', '8H', '2C', 'JH', '7D'],", "['6D', '8S', '8D', 'QS', '6C', '3D', '8C', 'TC'],", "['6S', '9C', '2H', '6H']", "]", "
Game #617
", "[", "['7D', 'AD', '5C', '3S', '5S', '8C', '2D', 'AH'],", "['TD', '7S', 'QD', 'AC', '6D', '8H', 'AS', 'KH'],", "['TH', 'QC', '3H', '9D', '6S', '8D', '3D', 'TC'],", "['KD', '5H', '9S', '3C', '8S', '7H', '4D', 'JS'],", "['4C', 'QS', '9C', '9H', '7C', '6H', '2C', '2S'],", "['4S', 'TS', '2H', '5D', 'JC', '6C', 'JH', 'QH'],", "['JD', 'KS', 'KC', '4H']", "]", "Task:", "
Write a function to take a deal number and deal cards in the same order as this algorithm.
", "The function must return a two dimensional array representing the FreeCell board.
", "Deals can also be checked against FreeCell solutions to 1000000 games.
", "(Summon a video solution, and it displays the initial deal.)
" ], "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" ], "tests": [ { "text": "dealFreeCell
is a function.",
"testString": "assert(typeof dealFreeCell === 'function', 'dealFreeCell
is a function.');"
},
{
"text": "dealFreeCell(seed)
should return an object.",
"testString": "assert(typeof dealFreeCell(1) === 'object', 'dealFreeCell(seed)
should return an object.');"
},
{
"text": "dealFreeCell(seed)
should return an array of length 7.",
"testString": "assert(dealFreeCell(1).length === 7, 'dealFreeCell(seed)
should return an array of length 7.');"
},
{
"text": "dealFreeCell(1)
should return an array identical to example \"Game #1\"",
"testString": "assert.deepEqual(dealFreeCell(1), game1, 'dealFreeCell(1)
should return an array identical to example \"Game #1\"');"
},
{
"text": "dealFreeCell(617)
should return an array identical to example \"Game #617\"",
"testString": "assert.deepEqual(dealFreeCell(617), game617, 'dealFreeCell(617)
should return an array identical to example \"Game #617\"');"
}
],
"id": "59694356a6e7011f7f1c5f4e",
"challengeType": 5,
"releasedOn": "December 27, 2017",
"files": {
"indexjs": {
"key": "indexjs",
"ext": "js",
"name": "index",
"contents": [
"function dealFreeCell (seed) {",
" // Good luck!",
" return true;",
"}"
],
"head": [],
"tail": [
"const replaceThis = 3;",
"const game1 = [",
" ['JD', '2D', '9H', 'JC', '5D', '7H', '7C', '5H'],",
" ['KD', 'KC', '9S', '5S', 'AD', 'QC', 'KH', '3H'],",
" ['2S', 'KS', '9D', 'QD', 'JS', 'AS', 'AH', '3C'],",
" ['4C', '5C', 'TS', 'QH', '4H', 'AC', '4D', '7S'],",
" ['3S', 'TD', '4S', 'TH', '8H', '2C', 'JH', '7D'],",
" ['6D', '8S', '8D', 'QS', '6C', '3D', '8C', 'TC'],",
" ['6S', '9C', '2H', '6H']",
"];",
"const game617 = [",
" ['7D', 'AD', '5C', '3S', '5S', '8C', '2D', 'AH'],",
" ['TD', '7S', 'QD', 'AC', '6D', '8H', 'AS', 'KH'],",
" ['TH', 'QC', '3H', '9D', '6S', '8D', '3D', 'TC'],",
" ['KD', '5H', '9S', '3C', '8S', '7H', '4D', 'JS'],",
" ['4C', 'QS', '9C', '9H', '7C', '6H', '2C', '2S'],",
" ['4S', 'TS', '2H', '5D', 'JC', '6C', 'JH', 'QH'],",
" ['JD', 'KS', 'KC', '4H']",
"];"
]
}
}
},
{
"title": "Deepcopy",
"description": [
"Task:",
"Write a function that returns a deep copy of a given object.
", "The copy must not be the same object that was given.
", "This task will not test for:
", "Objects with properties that are functions", "Date objects or object with properties that are Date objects", "RegEx or object with properties that are RegEx objects", "Prototype copying" ], "null": [], "solutions": [ "function deepcopy(obj) {\n return JSON.parse(JSON.stringify(obj));\n}\n\n" ], "tests": [ { "text": "deepcopy
should be a function.",
"testString": "assert(typeof deepcopy === 'function', 'deepcopy
should be a function.');"
},
{
"text": "deepcopy({test: \"test\"})
should return an object.",
"testString": "assert(typeof deepcopy(obj1) === 'object', 'deepcopy({test: \"test\"})
should return an object.');"
},
{
"text": "Should not return the same object that was provided.",
"testString": "assert(deepcopy(obj2) != obj2, 'Should not return the same object that was provided.');"
},
{
"text": "When passed an object containing an array, should return a deep copy of the object.",
"testString": "assert.deepEqual(deepcopy(obj2), obj2, 'When passed an object containing an array, should return a deep copy of the object.');"
},
{
"text": "When passed an object containing another object, should return a deep copy of the object.",
"testString": "assert.deepEqual(deepcopy(obj3), obj3, 'When passed an object containing another object, should return a deep copy of the object.');"
}
],
"id": "596a8888ab7c01048de257d5",
"challengeType": 5,
"releasedOn": "December 27, 2017",
"files": {
"indexjs": {
"key": "indexjs",
"ext": "js",
"name": "index",
"contents": [
"function deepcopy (obj) {",
" // Good luck!",
" return true;",
"}"
],
"head": [],
"tail": [
"const obj1 = { test: 'test' };",
"const obj2 = {",
" t: 'test',",
" a: ['an', 'array']",
"};",
"const obj3 = {",
" t: 'try',",
" o: obj2",
"};"
]
}
}
},
{
"title": "Define a primitive data type",
"description": [
"Task:",
"Define a type that behaves like an integer but has a lowest valid value of 1 and a highest valid value of 10.
", "Errors:", "If you try to instantiate aNum
with a value outside of 1 - 10",
"it should throw a TypeError
with an error message of 'Out of range'
.",
"If you try to instantiate a Num
with a value that is not a number",
"it should throw a TypeError
with an error message of 'Not a Number'
."
],
"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"
],
"tests": [
{
"text": "Num
should be a function.",
"testString": "assert(typeof Num === 'function', 'Num
should be a function.');"
},
{
"text": "new Num(4)
should return an object.",
"testString": "assert(typeof (new Num(4)) === 'object', 'new Num(4)
should return an object.');"
},
{
"text": "new Num(\\'test\\')
should throw a TypeError with message \\'Not a Number\\'.",
"testString": "assert(throws(() => new Num('test'), TypeError, 'Not a Number'), 'new Num(\\'test\\')
should throw a TypeError with message \\'Not a Number\\'.');"
},
{
"text": "new Num(0)
should throw a TypeError with message \\'Out of range\\'.",
"testString": "assert(throws(() => new Num(0), TypeError, 'Out of range'), 'new Num(0)
should throw a TypeError with message \\'Out of range\\'.');"
},
{
"text": "new Num(-5)
should throw a TypeError with message \\'Out of range\\'.",
"testString": "assert(throws(() => new Num(-5), TypeError, 'Out of range'), 'new Num(-5)
should throw a TypeError with message \\'Out of range\\'.');"
},
{
"text": "new Num(10)
should throw a TypeError with message \\'Out of range\\'.",
"testString": "assert(throws(() => new Num(11), TypeError, 'Out of range'), 'new Num(10)
should throw a TypeError with message \\'Out of range\\'.');"
},
{
"text": "new Num(20)
should throw a TypeError with message \\'Out of range\\'.",
"testString": "assert(throws(() => new Num(20), TypeError, 'Out of range'), 'new Num(20)
should throw a TypeError with message \\'Out of range\\'.');"
},
{
"text": "new Num(3) + new Num(4)
should equal 7.",
"testString": "assert.equal(new Num(3) + new Num(4), 7, 'new Num(3) + new Num(4)
should equal 7.');"
},
{
"text": "new Num(3) - new Num(4)
should equal -1.",
"testString": "assert.equal(new Num(3) - new Num(4), -1, 'new Num(3) - new Num(4)
should equal -1.');"
},
{
"text": "new Num(3) * new Num(4)
should equal 12.",
"testString": "assert.equal(new Num(3) * new Num(4), 12, 'new Num(3) * new Num(4)
should equal 12.');"
},
{
"text": "new Num(3) / new Num(4)
should equal 0.75.",
"testString": "assert.equal(new Num(3) / new Num(4), 0.75, 'new Num(3) / new Num(4)
should equal 0.75.');"
},
{
"text": "new Num(3) < new Num(4)
should be true.",
"testString": "assert(new Num(3) < new Num(4), 'new Num(3) < new Num(4)
should be true.');"
},
{
"text": "new Num(3) > new Num(4)
should be false.",
"testString": "assert(!(new Num(3) > new Num(4)), 'new Num(3) > new Num(4)
should be false.');"
},
{
"text": "(new Num(5)).toString()
should return \\'5\\'",
"testString": "assert.equal((new Num(5)).toString(), '5', '(new Num(5)).toString()
should return \\'5\\'');"
}
],
"id": "597089c87eec450c68aa1643",
"challengeType": 5,
"releasedOn": "December 27, 2017",
"files": {
"indexjs": {
"key": "indexjs",
"ext": "js",
"name": "index",
"contents": [
"function Num (n) {",
" // Good luck!",
" return n;",
"}"
],
"head": [],
"tail": []
}
}
},
{
"title": "Department Numbers",
"description": [
"There is a highly organized city that has decided to assign a number to each of their departments:
", "Police department", "Sanitation department", "Fire department ", "Each department can have a number between 1 and 7 (inclusive).
The three department numbers are to be unique (different from each other) and must add up to the number 12.
The Chief of the Police doesn't like odd numbers and wants to have an even number for his department.
", "Task:", "Write a program which outputs all valid combinations:
", "[2, 3, 7]
", "[2, 4, 6]
", "[2, 6, 4]
", "[2, 7, 3]
", "[4, 1, 7]
", "[4, 2, 6]
", "[4, 3, 5]
", "[4, 5, 3]
", "[4, 6, 2]
", "[4, 7, 1]
", "[6, 1, 5]
", "[6, 2, 4]
", "[6, 4, 2]
", "[6, 5, 1]
" ], "solutions": [ "function combinations (possibleNumbers, total) {\n let firstNumber;\n let secondNumber;\n let thridNumber;\n const allCombinations = [];\n\n for (let i = 0; i < possibleNumbers.length; i += 1) {\n firstNumber = possibleNumbers[i];\n\n if (firstNumber % 2 === 0) {\n for (let j = 0; j < possibleNumbers.length; j += 1) {\n secondNumber = possibleNumbers[j];\n\n if (j !== i && firstNumber + secondNumber <= total) {\n thridNumber = total - firstNumber - secondNumber;\n\n if (thridNumber !== firstNumber && thridNumber !== secondNumber && possibleNumbers.includes(thridNumber)) {\n allCombinations.push([firstNumber, secondNumber, thridNumber]);\n }\n }\n }\n }\n }\n return allCombinations;\n}\n" ], "tests": [ { "text": "combinations
should be a function.",
"testString": "assert(typeof combinations === 'function', 'combinations
should be a function.');"
},
{
"text": "combinations([1, 2, 3], 6)
should return an Array.",
"testString": "assert(Array.isArray(combinations([1, 2, 3], 6)), 'combinations([1, 2, 3], 6)
should return an Array.');"
},
{
"text": "combinations([1, 2, 3, 4, 5, 6, 7], 12)
should return an array of length 14.",
"testString": "assert(combinations(nums, total).length === len, 'combinations([1, 2, 3, 4, 5, 6, 7], 12)
should return an array of length 14.');"
},
{
"text": "combinations([1, 2, 3, 4, 5, 6, 7], 12)
should return all valid combinations.",
"testString": "assert.deepEqual(combinations(nums, total), result, 'combinations([1, 2, 3, 4, 5, 6, 7], 12)
should return all valid combinations.');"
}
],
"id": "59f40b17e79dbf1ab720ed7a",
"challengeType": 5,
"releasedOn": "December 27, 2017",
"files": {
"indexjs": {
"key": "indexjs",
"ext": "js",
"name": "index",
"contents": [
"function combinations (possibleNumbers, total) {",
" // Good luck!",
" return true;",
"}"
],
"head": [],
"tail": [
"const nums = [1, 2, 3, 4, 5, 6, 7];",
"const total = 12;",
"const len = 14;",
"const result = [",
" [2, 3, 7],",
" [2, 4, 6],",
" [2, 6, 4],",
" [2, 7, 3],",
" [4, 1, 7],",
" [4, 2, 6],",
" [4, 3, 5],",
" [4, 5, 3],",
" [4, 6, 2],",
" [4, 7, 1],",
" [6, 1, 5],",
" [6, 2, 4],",
" [6, 4, 2],",
" [6, 5, 1]",
"];"
]
}
}
},
{
"title": "Discordian date",
"description": [
"Task:",
"Convert a given date from the Gregorian calendar to the Discordian calendar.
" ], "solutions": [ "/**\n * All Hail Discordia! - this script prints Discordian date using system date.\n *\n * lang: JavaScript\n * author: jklu\n * contributors: JamesMcGuigan\n *\n * source: https://rosettacode.org/wiki/Discordian_date#JavaScript\n */\nconst seasons = [\n 'Chaos', 'Discord', 'Confusion',\n 'Bureaucracy', 'The Aftermath'\n];\nconst weekday = [\n 'Sweetmorn', 'Boomtime', 'Pungenday',\n 'Prickle-Prickle', 'Setting Orange'\n];\n\nconst apostle = [\n 'Mungday', 'Mojoday', 'Syaday',\n 'Zaraday', 'Maladay'\n];\n\nconst holiday = [\n 'Chaoflux', 'Discoflux', 'Confuflux',\n 'Bureflux', 'Afflux'\n];\n\n\nDate.prototype.isLeapYear = function() {\n const year = this.getFullYear();\n if ((year & 3) !== 0) { return false; }\n return ((year % 100) !== 0 || (year % 400) === 0);\n};\n\n// Get Day of Year\nDate.prototype.getDOY = function() {\n const dayCount = [0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334];\n const mn = this.getMonth();\n const dn = this.getDate();\n let dayOfYear = dayCount[mn] + dn;\n if (mn > 1 && this.isLeapYear()) { dayOfYear += 1; }\n return dayOfYear;\n};\n\nDate.prototype.isToday = function() {\n const today = new Date();\n return this.getDate() === today.getDate()\n && this.getMonth() === today.getMonth()\n && this.getFullYear() === today.getFullYear()\n ;\n};\n\nfunction discordianDate(date) {\n if (!date) { date = new Date(); }\n\n const y = date.getFullYear();\n const yold = y + 1166;\n let dayOfYear = date.getDOY();\n let celebrateHoliday = null;\n\n if (date.isLeapYear()) {\n if (dayOfYear === 60) {\n celebrateHoliday = 'St. Tib\\'s Day';\n }\n else if (dayOfYear > 60) {\n dayOfYear--;\n }\n }\n dayOfYear--;\n\n const divDay = Math.floor(dayOfYear / 73);\n\n const seasonDay = (dayOfYear % 73) + 1;\n if (seasonDay === 5) {\n celebrateHoliday = apostle[divDay];\n }\n if (seasonDay === 50) {\n celebrateHoliday = holiday[divDay];\n }\n\n const season = seasons[divDay];\n const dayOfWeek = weekday[dayOfYear % 5];\n\n const nth = (seasonDay % 10 === 1) ? 'st'\n : (seasonDay % 10 === 2) ? 'nd'\n : (seasonDay % 10 === 3) ? 'rd'\n : 'th';\n\n return ''\n + dayOfWeek\n + ', the ' + seasonDay + nth\n + ' day of ' + season\n + ' in the YOLD ' + yold\n + (celebrateHoliday ? '. Celebrate ' + celebrateHoliday + '!' : '')\n ;\n}\n\n" ], "tests": [ { "text": "discordianDate
is a function.",
"testString": "assert(typeof discordianDate === 'function', 'discordianDate
is a function.');"
},
{
"text": "discordianDate(new Date(2010, 6, 22))
should return \"Pungenday, the 57th day of Confusion in the YOLD 3176\"
.",
"testString": "assert(discordianDate(new Date(2010, 6, 22)) === 'Pungenday, the 57th day of Confusion in the YOLD 3176', 'discordianDate(new Date(2010, 6, 22))
should return \"Pungenday, the 57th day of Confusion in the YOLD 3176\"
.');"
},
{
"text": "discordianDate(new Date(2012, 1, 28))
should return \"Prickle-Prickle, the 59th day of Chaos in the YOLD 3178\"
.",
"testString": "assert(discordianDate(new Date(2012, 1, 28)) === 'Prickle-Prickle, the 59th day of Chaos in the YOLD 3178', 'discordianDate(new Date(2012, 1, 28))
should return \"Prickle-Prickle, the 59th day of Chaos in the YOLD 3178\"
.');"
},
{
"text": "discordianDate(new Date(2012, 1, 29))
should return \"Setting Orange, the 60th day of Chaos in the YOLD 3178. Celebrate St. Tib\\'s Day!\"
.",
"testString": "assert(discordianDate(new Date(2012, 1, 29)) === 'Setting Orange, the 60th day of Chaos in the YOLD 3178. Celebrate St. Tib\\'s Day!', 'discordianDate(new Date(2012, 1, 29))
should return \"Setting Orange, the 60th day of Chaos in the YOLD 3178. Celebrate St. Tib\\'s Day!\"
.');"
},
{
"text": "discordianDate(new Date(2012, 2, 1))
should return \"Setting Orange, the 60th day of Chaos in the YOLD 3178\"
.",
"testString": "assert(discordianDate(new Date(2012, 2, 1)) === 'Setting Orange, the 60th day of Chaos in the YOLD 3178', 'discordianDate(new Date(2012, 2, 1))
should return \"Setting Orange, the 60th day of Chaos in the YOLD 3178\"
.');"
},
{
"text": "discordianDate(new Date(2010, 0, 5))
should return \"Setting Orange, the 5th day of Chaos in the YOLD 3176. Celebrate Mungday!\"
.",
"testString": "assert(discordianDate(new Date(2010, 0, 5)) === 'Setting Orange, the 5th day of Chaos in the YOLD 3176. Celebrate Mungday!', 'discordianDate(new Date(2010, 0, 5))
should return \"Setting Orange, the 5th day of Chaos in the YOLD 3176. Celebrate Mungday!\"
.');"
},
{
"text": "discordianDate(new Date(2011, 4, 3))
should return \"Pungenday, the 50th day of Discord in the YOLD 3177. Celebrate Discoflux!\"
.",
"testString": "assert(discordianDate(new Date(2011, 4, 3)) === 'Pungenday, the 50th day of Discord in the YOLD 3177. Celebrate Discoflux!', 'discordianDate(new Date(2011, 4, 3))
should return \"Pungenday, the 50th day of Discord in the YOLD 3177. Celebrate Discoflux!\"
.');"
},
{
"text": "discordianDate(new Date(2015, 9, 19))
should return \"Boomtime, the 73rd day of Bureaucracy in the YOLD 3181\"
.",
"testString": "assert(discordianDate(new Date(2015, 9, 19)) === 'Boomtime, the 73rd day of Bureaucracy in the YOLD 3181', 'discordianDate(new Date(2015, 9, 19))
should return \"Boomtime, the 73rd day of Bureaucracy in the YOLD 3181\"
.');"
}
],
"id": "59f4eafba0343628bb682785",
"challengeType": 5,
"releasedOn": "December 27, 2017",
"files": {
"indexjs": {
"key": "indexjs",
"ext": "js",
"name": "index",
"contents": [
"function discordianDate (date) {",
" // Good luck!",
" return true;",
"}"
],
"head": [],
"tail": []
}
}
},
{
"title": "Element-wise operations",
"description": [
"Implement basic element-wise matrix-matrix and scalar-matrix operations.
Implement:
", "::* addition
", "::* subtraction
", "::* multiplication
", "::* division
", "::* exponentiation
", "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."
],
"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": [
{
"text": "operation
is a function.",
"testString": "assert(typeof operation === 'function', 'operation
is a function.');"
},
{
"text": "operation(\"m_add\",[[1,2],[3,4]],[[1,2],[3,4]])
should return [[2,4],[6,8]]
.",
"testString": "assert.deepEqual(operation('m_add', [[1, 2], [3, 4]], [[1, 2], [3, 4]]), [[2, 4], [6, 8]], 'operation(\"m_add\",[[1,2],[3,4]],[[1,2],[3,4]])
should return [[2,4],[6,8]]
.');"
},
{
"text": "operation(\"s_add\",[[1,2],[3,4]],[[1,2],[3,4]])
should return [[3,4],[5,6]]
.",
"testString": "assert.deepEqual(operation('s_add', [[1, 2], [3, 4]], 2), [[3, 4], [5, 6]], 'operation(\"s_add\",[[1,2],[3,4]],[[1,2],[3,4]])
should return [[3,4],[5,6]]
.');"
},
{
"text": "operation(\"m_sub\",[[1,2],[3,4]],[[1,2],[3,4]])
should return [[0,0],[0,0]]
.",
"testString": "assert.deepEqual(operation('m_sub', [[1, 2], [3, 4]], [[1, 2], [3, 4]]), [[0, 0], [0, 0]], 'operation(\"m_sub\",[[1,2],[3,4]],[[1,2],[3,4]])
should return [[0,0],[0,0]]
.');"
},
{
"text": "operation(\"m_mult\",[[1,2],[3,4]],[[1,2],[3,4]])
should return [[1,4],[9,16]]
.",
"testString": "assert.deepEqual(operation('m_mult', [[1, 2], [3, 4]], [[1, 2], [3, 4]]), [[1, 4], [9, 16]], 'operation(\"m_mult\",[[1,2],[3,4]],[[1,2],[3,4]])
should return [[1,4],[9,16]]
.');"
},
{
"text": "operation(\"m_div\",[[1,2],[3,4]],[[1,2],[3,4]])
should return [[1,1],[1,1]]
.",
"testString": "assert.deepEqual(operation('m_div', [[1, 2], [3, 4]], [[1, 2], [3, 4]]), [[1, 1], [1, 1]], 'operation(\"m_div\",[[1,2],[3,4]],[[1,2],[3,4]])
should return [[1,1],[1,1]]
.');"
},
{
"text": "operation(\"m_exp\",[[1,2],[3,4]],[[1,2],[3,4]])
should return [[1,4],[27,256]]
.",
"testString": "assert.deepEqual(operation('m_exp', [[1, 2], [3, 4]], [[1, 2], [3, 4]]), [[1, 4], [27, 256]], 'operation(\"m_exp\",[[1,2],[3,4]],[[1,2],[3,4]])
should return [[1,4],[27,256]]
.');"
},
{
"text": "operation(\"m_add\",[[1,2,3,4],[5,6,7,8]],[[9,10,11,12],[13,14,15,16]])
should return [[10,12,14,16],[18,20,22,24]]
.",
"testString": "assert.deepEqual(operation('m_add', [[1, 2, 3, 4], [5, 6, 7, 8]], [[9, 10, 11, 12], [13, 14, 15, 16]]), [[10, 12, 14, 16], [18, 20, 22, 24]], 'operation(\"m_add\",[[1,2,3,4],[5,6,7,8]],[[9,10,11,12],[13,14,15,16]])
should return [[10,12,14,16],[18,20,22,24]]
.');"
}
],
"id": "599c333915e0ea32d04d4bec",
"challengeType": 5,
"releasedOn": "December 27, 2017",
"files": {
"indexjs": {
"key": "indexjs",
"ext": "js",
"name": "index",
"contents": [
"function operation (op, arr1, arr2) {",
" // Good luck!",
"}"
],
"head": [],
"tail": []
}
}
},
{
"title": "Emirp primes",
"description": [
"
An emirp (prime spelled backwards) are primes that when reversed (in their decimal representation) are a different prime.
", "Write a function that should be able to : Show the first n eprimes numbers.Show the eprimes numbers in a range.Show the number of eprimes in a range.Show the nth eprimes number.
The function should have two parameters. The first will receive n or the range as an array. The second will receive 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 nth prime). According to the parameters the function should return an array or a number."
],
"null": [],
"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": [
{
"text": "emirps
is a function.",
"testString": "assert(typeof emirps === 'function', 'emirps
is a function.');"
},
{
"text": "emirps(20,true)
should return [13,17,31,37,71,73,79,97,107,113,149,157,167,179,199,311,337,347,359,389]
",
"testString": "assert.deepEqual(emirps(20, true), [13, 17, 31, 37, 71, 73, 79, 97, 107, 113, 149, 157, 167, 179, 199, 311, 337, 347, 359, 389], 'emirps(20,true)
should return [13,17,31,37,71,73,79,97,107,113,149,157,167,179,199,311,337,347,359,389]
');"
},
{
"text": "emirps(10000)
should return 948349
",
"testString": "assert.deepEqual(emirps(10000), 948349, 'emirps(10000)
should return 948349
');"
},
{
"text": "emirps([7700,8000],true)
should return [7717,7757,7817,7841,7867,7879,7901,7927,7949,7951,7963]
",
"testString": "assert.deepEqual(emirps([7700, 8000], true), [7717, 7757, 7817, 7841, 7867, 7879, 7901, 7927, 7949, 7951, 7963], 'emirps([7700,8000],true)
should return [7717,7757,7817,7841,7867,7879,7901,7927,7949,7951,7963]
');"
},
{
"text": "emirps([7700,8000],true)
should return 11
",
"testString": "assert.deepEqual(emirps([7700, 8000], false), 11, 'emirps([7700,8000],true)
should return 11
');"
}
],
"id": "599d0ba974141b0f508b37d5",
"challengeType": 5,
"releasedOn": "December 27, 2017",
"files": {
"indexjs": {
"key": "indexjs",
"ext": "js",
"name": "index",
"contents": [
"function emirps(n) {",
" // Good luck!",
"}"
],
"head": [],
"tail": []
}
}
},
{
"title": "Entropy",
"description": [
"Task:",
"
Calculate the Shannon entropy H of a given input string.
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 :
", "$H_2(X) = -\\sum_{i=1}^n \\frac{count_i}{N} \\log_2 \\left(\\frac{count_i}{N}\\right)$
where $count_i$ is the count of character $n_i$.
" ], "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": [ { "text": "entropy
is a function.",
"testString": "assert(typeof entropy === 'function', 'entropy
is a function.');"
},
{
"text": "entropy(\"0\")
should return 0
",
"testString": "assert.equal(entropy('0'), 0, 'entropy(\"0\")
should return 0
');"
},
{
"text": "entropy(\"01\")
should return 1
",
"testString": "assert.equal(entropy('01'), 1, 'entropy(\"01\")
should return 1
');"
},
{
"text": "entropy(\"0123\")
should return 2
",
"testString": "assert.equal(entropy('0123'), 2, 'entropy(\"0123\")
should return 2
');"
},
{
"text": "entropy(\"01234567\")
should return 3
",
"testString": "assert.equal(entropy('01234567'), 3, 'entropy(\"01234567\")
should return 3
');"
},
{
"text": "entropy(\"0123456789abcdef\")
should return 4
",
"testString": "assert.equal(entropy('0123456789abcdef'), 4, 'entropy(\"0123456789abcdef\")
should return 4
');"
},
{
"text": "entropy(\"1223334444\")
should return 1.8464393446710154
",
"testString": "assert.equal(entropy('1223334444'), 1.8464393446710154, 'entropy(\"1223334444\")
should return 1.8464393446710154
');"
}
],
"id": "599d15309e88c813a40baf58",
"challengeType": 5,
"releasedOn": "December 27, 2017",
"files": {
"indexjs": {
"key": "indexjs",
"ext": "js",
"name": "index",
"contents": [
"function entropy (s) {",
" // Good luck!",
"}"
],
"head": [],
"tail": []
}
}
},
{
"title": "Equilibrium index",
"description": [
"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.
", "For example, in a sequence $A$:
:::: $A_0 = -7$
", ":::: $A_1 = 1$
", ":::: $A_2 = 5$
", ":::: $A_3 = 2$
", ":::: $A_4 = -4$
", ":::: $A_5 = 3$
", ":::: $A_6 = 0$
3 is an equilibrium index, because:
:::: $A_0 + A_1 + A_2 = A_4 + A_5 + A_6$
6 is also an equilibrium index, because:
:::: $A_0 + A_1 + A_2 + A_3 + A_4 + A_5 = 0$
(sum of zero elements is zero)
7 is not an equilibrium index, because it is not a valid index of sequence $A$.
", "Write a function that, given a sequence, returns its equilibrium indices (if any).
Assume that the sequence may be very long.
" ], "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" ], "tests": [ { "text": "equilibrium
is a function.",
"testString": "assert(typeof equilibrium === 'function', 'equilibrium
is a function.');"
},
{
"text": "equilibrium([-7, 1, 5, 2, -4, 3, 0])
should return [3,6]
.",
"testString": "assert.deepEqual(equilibrium(tests[0]), ans[0], 'equilibrium([-7, 1, 5, 2, -4, 3, 0])
should return [3,6]
.');"
},
{
"text": "equilibrium([2, 4, 6])
should return []
.",
"testString": "assert.deepEqual(equilibrium(tests[1]), ans[1], 'equilibrium([2, 4, 6])
should return []
.');"
},
{
"text": "equilibrium([2, 9, 2])
should return [1]
.",
"testString": "assert.deepEqual(equilibrium(tests[2]), ans[2], 'equilibrium([2, 9, 2])
should return [1]
.');"
},
{
"text": "equilibrium([1, -1, 1, -1, 1, -1, 1])
should return [0,1,2,3,4,5,6]
.",
"testString": "assert.deepEqual(equilibrium(tests[3]), ans[3], 'equilibrium([1, -1, 1, -1, 1, -1, 1])
should return [0,1,2,3,4,5,6]
.');"
},
{
"text": "equilibrium([1])
should return [0]
.",
"testString": "assert.deepEqual(equilibrium(tests[4]), ans[4], 'equilibrium([1])
should return [0]
.');"
},
{
"text": "equilibrium([])
should return []
.",
"testString": "assert.deepEqual(equilibrium(tests[5]), ans[5], 'equilibrium([])
should return []
.');"
}
],
"id": "5987fd532b954e0f21b5d3f6",
"challengeType": 5,
"releasedOn": "December 27, 2017",
"files": {
"indexjs": {
"key": "indexjs",
"ext": "js",
"name": "index",
"contents": [
"function equilibrium (a) {",
" // Good luck!",
"}"
],
"head": [],
"tail": [
"const tests =",
" [[-7, 1, 5, 2, -4, 3, 0], // 3, 6",
" [2, 4, 6], // empty",
" [2, 9, 2], // 1",
" [1, -1, 1, -1, 1, -1, 1], // 0,1,2,3,4,5,6",
" [1], // 0",
" [] // empty",
" ];",
"const ans = [[3, 6], [], [1], [0, 1, 2, 3, 4, 5, 6], [0], []];"
]
}
}
},
{
"title": "Ethiopian multiplication",
"description": [
"Ethiopian multiplication is a method of multiplying integers using only addition, doubling, and halving.
", "Method:
", "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", "For example: 17 × 34
", "17 34
", "Halving the first column:
", "17 34
", "8
", "4
", "2
", "1
", "Doubling the second column:
", "17 34
", "8 68
", "4 136
", "2 272
", "1 544
", "Strike-out rows whose first cell is even:
", "17 34
", "8 68
4 136
2 272
1 544
", "Sum the remaining numbers in the right-hand column:
", "17 34
", "8 --
", "4 ---
", "2 ---
", "1 544
", "====
", "578
", "So 17 multiplied by 34, by the Ethiopian method is 578.
", "Task:", "The task is to define three named functions/methods/procedures/subroutines:
", "one to halve an integer,", "one to double an integer, and", "one to state if an integer is even.", "Use these functions to create a function that does Ethiopian multiplication.
" ], "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": [ { "text": "eth_mult
is a function.",
"testString": "assert(typeof eth_mult === 'function', 'eth_mult
is a function.');"
},
{
"text": "eth_mult(17,34)
should return 578
.",
"testString": "assert.equal(eth_mult(17, 34), 578, 'eth_mult(17,34)
should return 578
.');"
},
{
"text": "eth_mult(23,46)
should return 1058
.",
"testString": "assert.equal(eth_mult(23, 46), 1058, 'eth_mult(23,46)
should return 1058
.');"
},
{
"text": "eth_mult(12,27)
should return 324
.",
"testString": "assert.equal(eth_mult(12, 27), 324, 'eth_mult(12,27)
should return 324
.');"
},
{
"text": "eth_mult(56,98)
should return 5488
.",
"testString": "assert.equal(eth_mult(56, 98), 5488, 'eth_mult(56,98)
should return 5488
.');"
},
{
"text": "eth_mult(63,74)
should return 4662
.",
"testString": "assert.equal(eth_mult(63, 74), 4662, 'eth_mult(63,74)
should return 4662
.');"
}
],
"id": "599d1566a02b571412643b84",
"challengeType": 5,
"releasedOn": "December 27, 2017",
"files": {
"indexjs": {
"key": "indexjs",
"ext": "js",
"name": "index",
"contents": [
"function eth_mult (a, b) {",
" // Good luck!",
"}"
],
"head": [],
"tail": []
}
}
},
{
"title": "Euler method",
"description": [
"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 the wikipedia page.
The ODE has to be provided in the following form:
:: $\\frac{dy(t)}{dt} = f(t,y(t))$
with an initial value
:: $y(t_0) = y_0$
To get a numeric solution, we replace the derivative on the LHS with a finite difference approximation:
:: $\\frac{dy(t)}{dt} \\approx \\frac{y(t+h)-y(t)}{h}$
then solve for $y(t+h)$:
:: $y(t+h) \\approx y(t) + h \\, \\frac{dy(t)}{dt}$
which is the same as
:: $y(t+h) \\approx y(t) + h \\, f(t,y(t))$
The iterative solution rule is then:
:: $y_{n+1} = y_n + h \\, f(t_n, y_n)$
where $h$ 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.
", "Example: Newton's Cooling Law
Newton's cooling law describes how an object of initial temperature $T(t_0) = T_0$ cools down in an environment of temperature $T_R$:
:: $\\frac{dT(t)}{dt} = -k \\, \\Delta T$
", "or
", ":: $\\frac{dT(t)}{dt} = -k \\, (T(t) - T_R)$
", "It says that the cooling rate $\\frac{dT(t)}{dt}$ of the object is proportional to the current temperature difference $\\Delta T = (T(t) - T_R)$ to the surrounding environment.
The analytical solution, which we will compare to the numerical approximation, is
", ":: $T(t) = T_R + (T_0 - T_R) \\; e^{-k t}$
", "Task:", "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:
", "::* 2 s
", "::* 5 s and
", "::* 10 s
", "and to compare with the analytical solution.
", "Initial values:", "::* initial temperature $T_0$ shall be 100 °C
", "::* room temperature $T_R$ shall be 20 °C
", "::* cooling constant $k$ shall be 0.07
", "::* time interval to calculate shall be from 0 s ──► 100 s
" ], "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": [ { "text": "eulersMethod
is a function.",
"testString": "assert(typeof eulersMethod === 'function', 'eulersMethod
is a function.');"
},
{
"text": "eulersMethod(0, 100, 100, 10)
should return a number.",
"testString": "assert(typeof eulersMethod(0, 100, 100, 10) === 'number', 'eulersMethod(0, 100, 100, 10)
should return a number.');"
},
{
"text": "eulersMethod(0, 100, 100, 10)
should return 20.0424631833732.",
"testString": "assert.equal(eulersMethod(0, 100, 100, 2), 20.0424631833732, 'eulersMethod(0, 100, 100, 10)
should return 20.0424631833732.');"
},
{
"text": "eulersMethod(0, 100, 100, 10)
should return 20.01449963666907.",
"testString": "assert.equal(eulersMethod(0, 100, 100, 5), 20.01449963666907, 'eulersMethod(0, 100, 100, 10)
should return 20.01449963666907.');"
},
{
"text": "eulersMethod(0, 100, 100, 10)
should return 20.000472392.",
"testString": "assert.equal(eulersMethod(0, 100, 100, 10), 20.000472392, 'eulersMethod(0, 100, 100, 10)
should return 20.000472392.');"
}
],
"id": "59880443fb36441083c6c20e",
"challengeType": 5,
"releasedOn": "December 27, 2017",
"files": {
"indexjs": {
"key": "indexjs",
"ext": "js",
"name": "index",
"contents": [
"function eulersMethod (x1, y1, x2, h) {",
" // Good luck!",
"}"
],
"head": [],
"tail": []
}
}
},
{
"title": "Evaluate binomial coefficients",
"description": [
"Write a function to calculate the binomial coefficient for the given value of n and k.
This formula is recommended:
", "$\\binom{n}{k} = \\frac{n!}{(n-k)!k!} = \\frac{n(n-1)(n-2)\\ldots(n-k+1)}{k(k-1)(k-2)\\ldots 1}$" ], "solutions": [ "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": [ { "text": "binom
is a function.",
"testString": "assert(typeof binom === 'function', 'binom
is a function.');"
},
{
"text": "binom(5,3)
should return 10.",
"testString": "assert.equal(binom(5, 3), 10, 'binom(5,3)
should return 10.');"
},
{
"text": "binom(7,2)
should return 21.",
"testString": "assert.equal(binom(7, 2), 21, 'binom(7,2)
should return 21.');"
},
{
"text": "binom(10,4)
should return 210.",
"testString": "assert.equal(binom(10, 4), 210, 'binom(10,4)
should return 210.');"
},
{
"text": "binom(6,1)
should return 6.",
"testString": "assert.equal(binom(6, 1), 6, 'binom(6,1)
should return 6.');"
},
{
"text": "binom(12,8)
should return 495.",
"testString": "assert.equal(binom(12, 8), 495, 'binom(12,8)
should return 495.');"
}
],
"id": "598de241872ef8353c58a7a2",
"challengeType": 5,
"releasedOn": "December 27, 2017",
"files": {
"indexjs": {
"key": "indexjs",
"ext": "js",
"name": "index",
"contents": [
"function binom (n, k) {",
" // Good luck!",
"}"
],
"head": [],
"tail": []
}
}
},
{
"title": "Execute a Markov algorithm",
"description": [
"Task:",
"Create an interpreter for a Markov Algorithm.
Rules have the syntax:
", "There is one rule per line.
If there is a . (period) present before the
A ruleset consists of a sequence of rules, with optional comments.
", "Rulesets
Use the following tests on entries:
", "Ruleset 1:", "", "This rules file is extracted from Wikipedia:", "http://en.wikipedia.org/wiki/Markov_AlgorithmA -> apple", "B -> bag", "S -> shop", "T -> the", "the shop -> my brother", "a never used -> .terminating rule", "", "
Sample text of:
", " I bought a B of As from T S.
Should generate the output:
", " I bought a bag of apples from my brother.
A test of the terminating rule
", "", "Slightly modified from the rules on WikipediaA -> apple", "B -> bag", "S -> .shop", "T -> the", "the shop -> my brother", "a never used -> .terminating rule", "
Sample text of:
", " I bought a B of As from T S.
Should generate:
", " I bought a bag of apples from T shop.
This tests for correct substitution order and may trap simple regexp based replacement routines if special regexp characters are not escaped.
", "", "BNF Syntax testing rulesA -> apple", "WWWW -> with", "Bgage -> ->.*", "B -> bag", "->.* -> money", "W -> WW", "S -> .shop", "T -> the", "the shop -> my brother", "a never used -> .terminating rule", "", "
Sample text of:
", " I bought a B of As W my Bgage from T S.
Should generate:
", " I bought a bag of apples with my money from T shop.
This tests for correct order of scanning of rules, and may trap replacement routines that scan in the wrong order. It implements a general unary multiplication engine. (Note that the input expression must be placed within underscores in this implementation.)
", "", "## Unary Multiplication Engine, for testing Markov Algorithm implementations", "## By Donal Fellows.", "Unary addition engine_+1 -> _1+", "1+1 -> 11+", "Pass for converting from the splitting of multiplication into ordinary", "addition1! -> !1", ",! -> !+", "_! -> _", "Unary multiplication by duplicating left side, right side times1*1 -> x,@y", "1x -> xX", "X, -> 1,1", "X1 -> 1X", "_x -> _X", ",x -> ,X", "y1 -> 1y", "y_ -> _", "Next phase of applying1@1 -> x,@y", "1@_ -> @_", ",@_ -> !_", "++ -> +", "Termination cleanup for addition_1 -> 1", "1+_ -> 1", "_+_ -> ", "", "
Sample text of:
", " _1111*11111_
should generate the output:
", " 11111111111111111111
A simple Turing machine,
", "implementing a three-state busy beaver.
The tape consists of 0s and 1s, the states are A, B, C and H (for Halt), and the head position is indicated by writing the state letter before the character where the head is.
", "All parts of the initial tape the machine operates on have to be given in the input.
Besides demonstrating that the Markov algorithm is Turing-complete, it also made me catch a bug in the C++ implementation which wasn't caught by the first four rulesets.
", "", "Turing machine: three-state busy beaver", "# state A, symbol 0 => write 1, move right, new state BA0 -> 1B", "state A, symbol 1 => write 1, move left, new state C0A1 -> C01", "1A1 -> C11", "state B, symbol 0 => write 1, move left, new state A0B0 -> A01", "1B0 -> A11", "state B, symbol 1 => write 1, move right, new state BB1 -> 1B", "state C, symbol 0 => write 1, move left, new state B0C0 -> B01", "1C0 -> B11", "state C, symbol 1 => write 1, move left, halt0C1 -> H01", "1C1 -> H11", "", "
This ruleset should turn
", " 000000A000000
into
", " 00011H1111000
markov
is a function.",
"testString": "assert(typeof markov === 'function', 'markov
is a function.');"
},
{
"text": "markov([\"A -> apple\",\"B -> bag\",\"S -> shop\",\"T -> the\",\"the shop -> my brother\",\"a never used -> .terminating rule\"],\"I bought a B of As from T S.\")
should return \"I bought a bag of apples from my brother.\".",
"testString": "assert.deepEqual(markov(rules[0],tests[0]),outputs[0],'markov([\"A -> apple\",\"B -> bag\",\"S -> shop\",\"T -> the\",\"the shop -> my brother\",\"a never used -> .terminating rule\"],\"I bought a B of As from T S.\")
should return \"I bought a bag of apples from my brother.\".');"
},
{
"text": "markov([\"A -> apple\",\"B -> bag\",\"S -> .shop\",\"T -> the\",\"the shop -> my brother\",\"a never used -> .terminating rule\"],\"I bought a B of As from T S.\")
should return \"I bought a bag of apples from T shop.\".",
"testString": "assert.deepEqual(markov(rules[1],tests[1]),outputs[1],'markov([\"A -> apple\",\"B -> bag\",\"S -> .shop\",\"T -> the\",\"the shop -> my brother\",\"a never used -> .terminating rule\"],\"I bought a B of As from T S.\")
should return \"I bought a bag of apples from T shop.\".');"
},
{
"text": "markov([\"A -> apple\",\"WWWW -> with\",\"Bgage -> ->.*\",\"B -> bag\",\"->.* -> money\",\"W -> WW\",\"S -> .shop\",\"T -> the\",\"the shop -> my brother\",\"a never used -> .terminating rule\"],\"I bought a B of As W my Bgage from T S.\")
should return \"I bought a bag of apples with my money from T shop.\".",
"testString": "assert.deepEqual(markov(rules[2],tests[2]),outputs[2],'markov([\"A -> apple\",\"WWWW -> with\",\"Bgage -> ->.*\",\"B -> bag\",\"->.* -> money\",\"W -> WW\",\"S -> .shop\",\"T -> the\",\"the shop -> my brother\",\"a never used -> .terminating rule\"],\"I bought a B of As W my Bgage from T S.\")
should return \"I bought a bag of apples with my money from T shop.\".');"
},
{
"text": "markov([\"_+1 -> _1+\",\"1+1 -> 11+\",\"1! -> !1\",\",! -> !+\",\"_! -> _\",\"1*1 -> x,@y\",\"1x -> xX\",\"X, -> 1,1\",\"X1 -> 1X\",\"_x -> _X\",\",x -> ,X\",\"y1 -> 1y\",\"y_ -> _\",\"1@1 -> x,@y\",\"1@_ -> @_\",\",@_ -> !_\",\"++ -> +\",\"_1 -> 1\",\"1+_ -> 1\",\"_+_ -> \"],\"_1111*11111_\")
should return \"11111111111111111111\".",
"testString": "assert.deepEqual(markov(rules[3],tests[3]),outputs[3],'markov([\"_+1 -> _1+\",\"1+1 -> 11+\",\"1! -> !1\",\",! -> !+\",\"_! -> _\",\"1*1 -> x,@y\",\"1x -> xX\",\"X, -> 1,1\",\"X1 -> 1X\",\"_x -> _X\",\",x -> ,X\",\"y1 -> 1y\",\"y_ -> _\",\"1@1 -> x,@y\",\"1@_ -> @_\",\",@_ -> !_\",\"++ -> +\",\"_1 -> 1\",\"1+_ -> 1\",\"_+_ -> \"],\"_1111*11111_\")
should return \"11111111111111111111\".');"
},
{
"text": "markov([\"A0 -> 1B\",\"0A1 -> C01\",\"1A1 -> C11\",\"0B0 -> A01\",\"1B0 -> A11\",\"B1 -> 1B\",\"0C0 -> B01\",\"1C0 -> B11\",\"0C1 -> H01\",\"1C1 -> H11\"],\"\")
should return \"00011H1111000\".",
"testString": "assert.deepEqual(markov(rules[4],tests[4]),outputs[4],'markov([\"A0 -> 1B\",\"0A1 -> C01\",\"1A1 -> C11\",\"0B0 -> A01\",\"1B0 -> A11\",\"B1 -> 1B\",\"0C0 -> B01\",\"1C0 -> B11\",\"0C1 -> H01\",\"1C1 -> H11\"],\"\")
should return \"00011H1111000\".');"
}
],
"id": "59e09e6d412c5939baa02d16",
"challengeType": 5,
"releasedOn": "December 27, 2017",
"files": {
"indexjs": {
"key": "indexjs",
"ext": "js",
"name": "index",
"contents": [
"function markov (rules,test) {",
" // Good luck!",
"}"
],
"head": [],
"tail": []
}
}
},
{
"title": "Execute Brain****",
"description": [
"Write a function to implement a Brain**** interpreter. The function will take a string as a parameter and should return a string as the output. More details are given below :
", "RCBF is a set of Brainf*** compilers and interpreters written for Rosetta Code in a variety of languages.
Below are links to each of the versions of RCBF.
An implementation need only properly implement the following instructions:
", "{|
", "!Command
", "!Description
", "|-
", "| style=\"text-align:center\"| >
|| Move the pointer to the right
|-
", "| style=\"text-align:center\"| <
|| Move the pointer to the left
|-
", "| style=\"text-align:center\"| +
|| Increment the memory cell under the pointer
|-
", "| style=\"text-align:center\"| -
|| Decrement the memory cell under the pointer
|-
", "| style=\"text-align:center\"| .
|| Output the character signified by the cell at the pointer
|-
", "| style=\"text-align:center\"| ,
|| Input a character and store it in the cell at the pointer
|-
", "| style=\"text-align:center\"| [
|| Jump past the matching ]
if the cell under the pointer is 0
|-
", "| style=\"text-align:center\"| ]
|| Jump back to the matching [
if the cell under the pointer is nonzero
|}
", "Any cell size is allowed, EOF (End-O-File) support is optional, as is whether you have bounded or unbounded memory.
", "" ], "solutions": [ "function brain(prog){\n var output=\"\";\n\tvar code; // formatted code\n var ip = 0; // current instruction within code\n var nest = 0; // current bracket nesting (for Out button)\n var ahead = []; // locations of matching brackets\n\n var data = [0]; // data array (mod by +, -)\n var dp = 0; // index into data (mod by <, >)\n\n var inp = 0; // current input character (fetch with ,)\n var quit = 0;\n\tvar commands = {\n\t'>':function() { if (++dp >= data.length) data[dp]=0 },\n\t'<':function() { if (--dp < 0) quit++ },\n\t'+':function() { ++data[dp] },\n\t'-':function() { --data[dp] },\n\t'[':function() { if (!data[dp]) ip = ahead[ip]; else ++nest },\n\t']':function() { if ( data[dp]) ip = ahead[ip]; else --nest },\n\t',':function() {\n\t\tvar c = document.getElementById(\"input\").value.charCodeAt(inp++);\n\t\tdata[dp] = isNaN(c) ? 0 : c; // EOF: other options are -1 or no change\n\t},\n\t'.':function() {\n \t\toutput+=String.fromCharCode(data[dp]);\n \t\t/*var s = document.getElementById(\"output\").innerHTML)\n \t\t + String.fromCharCode(data[dp]);\n \t\ts = s.replace(/\\n/g,\"brain(bye)
should return a string');"
},
{
"text": "brain(\"++++++[>++++++++++<-]>+++++.\")
++++++++++<-]>+++++.\"),\"A\", 'brain(\"++++++[>++++++++++<-]>+++++.\")
brain(bye) should return Goodbye, World!\\\\r\\\\n
",
"testString": "assert.equal(brain(bye), 'Goodbye, World!\\r\\n', 'brain(bye)
should return Goodbye, World!\\\\r\\\\n
');"
},
{
"text": "brain(hello)
should return Hello World!\\\\n
'",
"testString": "assert.equal(brain(hello), \"Hello World!\\n\", 'brain(hello)
should return Hello World!\\\\n
');"
},
{
"text": "brain(fib)
should return 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89
",
"testString": "assert.equal(brain(fib), \"1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89\", 'brain(fib)
should return 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89
');"
}
],
"id": "59e0a8df964e4540d5abe599",
"challengeType": 5,
"releasedOn": "December 27, 2017",
"files": {
"indexjs": {
"key": "indexjs",
"ext": "js",
"name": "index",
"contents": [
"function brain (prog) {",
" // Good luck!",
"}"
],
"head": [
"let fib=`+\n\n++\n\n+++\n\n++++\n\n+>+>>\n\n>>++++\n\n+++++++\n\n++++++++\n\n+++++++++\n\n++++++++++\n\n++++++>++++\n\n++++++++++++\n\n+++++++++++++\n\n+++<<<<<<[>[>>\n\n>>>>+>+<<<<<<<-\n\n]>>>>>>>[<<<<<<<\n\n+>>>>>>>-]<[>++++\n\n++++++[-<-[>>+>+<<\n\n<-]>>>[<<<+>>>-]+<[\n\n>[-]<[-]]>[<<[>>>+<<\n\n<-]>>[-]]<<]>>>[>>+>+\n\n<<<-]>>>[<<<+>>>-]+<[>\n\n[-]<[-]]>[<<+>>[-]]<<<<\n\n<<<]>>>>>[++++++++++++++\n\n+++++++++++++++++++++++++\n\n+++++++++.[-]]++++++++++<[\n\n->-<]>+++++++++++++++++++++\n\n+++++++++++++++++++++++++++.\n\n[-]<<<<<<<<<<<<[>>>+>+<<<<-]>\n\n>>>[<<<<+>>>>-]<-[>>.>.<<<[-]]\n\n<<[>>+>+<<<-]>>>[<<<+>>>-]<<[<+\n\n>-]>[<+>-]<<<-]`;",
"let hello='++++++++[>++++[>++>+++>+++>+<<<<-]>+>+>->>+[<]<-]>>.>---.+++++++..+++.>>.<-.<.+++.------.--------.>>+.>++.'",
"let bye='++++++++++[>+>+++>++++>+++++++>++++++++>+++++++++>++++++++++>+++++++++++>++++++++++++<<<<<<<<<-]>>>>+.>>>>+..<.<++++++++.>>>+.<<+.<<<<++++.<++.>>>+++++++.>>>.+++.<+++++++.--------.<<<<<+.<+++.---.';"
],
"tail": []
}
}
},
{
"title": "Extensible prime generator",
"description": [
"Write a generator of prime numbers, in order, that will automatically adjust to accommodate the generation of any reasonably high prime.
The generator should be able to : Show the first n prime numbers.Show the prime numbers in a range.Show the number of primes in a range.Show the nth prime number.The function should have two parameters. The first will receive n or the range as an array. The second will receive 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 nth prime). According to the parameters the function should return an array."
],
"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": [
{
"text": "primeGenerator
is a function.",
"testString": "assert(typeof primeGenerator === 'function', 'primeGenerator
is a function.');"
},
{
"text": "primeGenerator
is a function.",
"testString": "assert.deepEqual(primeGenerator(20, true), [2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71], 'primeGenerator
is a function.');"
},
{
"text": "primeGenerator
is a function.",
"testString": "assert.deepEqual(primeGenerator([100, 150], true), [101, 103, 107, 109, 113, 127, 131, 137, 139, 149], 'primeGenerator
is a function.');"
},
{
"text": "primeGenerator
is a function.",
"testString": "assert.equal(primeGenerator([7700, 8000], false), 30, 'primeGenerator
is a function.');"
},
{
"text": "primeGenerator
is a function.",
"testString": "assert.equal(primeGenerator(10000, false), 104729, 'primeGenerator
is a function.');"
}
],
"id": "598ee8b91b410510ae82efef",
"challengeType": 5,
"releasedOn": "December 27, 2017",
"files": {
"indexjs": {
"key": "indexjs",
"ext": "js",
"name": "index",
"contents": [
"function primeGenerator (num, showPrimes) {",
" // Good luck!",
"}"
],
"head": [],
"tail": []
}
}
},
{
"title": "Factorial",
"description": [
"
Write a function to return the factorial of a number.
", "Factorial of a number is given by :
", "n! = n * (n-1) * (n-2) * ..... * 1", "", "For example :", "3! = 3*2*1 = 6", "4! = 4*3*2*1 = 24", "
", "Note : ", "0! = 1 ", "
" ], "solutions": [ "function factorial(n) {\n let sum = 1;\n while (n > 1) {\n sum *= n;\n n--;\n }\n return sum;\n}\n\n" ], "tests": [ { "text": "factorial
is a function.",
"testString": "assert(typeof factorial === 'function', 'factorial
is a function.');"
},
{
"text": "factorial(2)
should return a number.",
"testString": "assert(typeof factorial(2) === 'number', 'factorial(2)
should return a number.');"
},
{
"text": "factorial(3)
should return 6.\")",
"testString": "assert.equal(factorial(3),results[0],\"factorial(3)
should return 6.\");"
},
{
"text": "factorial(3)
should return 120.\")",
"testString": "assert.equal(factorial(5),results[1],\"factorial(3)
should return 120.\");"
},
{
"text": "factorial(3)
should return 3,628,800.\")",
"testString": "assert.equal(factorial(10),results[2],\"factorial(3)
should return 3,628,800.\");"
}
],
"id": "597b2b2a2702b44414742771",
"challengeType": 5,
"releasedOn": "December 27, 2017",
"files": {
"indexjs": {
"key": "indexjs",
"ext": "js",
"name": "index",
"contents": [
"function factorial (n) {",
" // Good luck!",
"}"
],
"head": [],
"tail": [
"const results=[6,120,3628800];"
]
}
}
},
{
"title": "Factors of a Mersenne number",
"description": [
"A Mersenne number is a number in the form of 2P-1.
If P is prime, the Mersenne number may be a Mersenne prime
", "(if P is not prime, the Mersenne number is also not prime).
In the search for Mersenne prime numbers it is advantageous to eliminate exponents by finding a small factor before starting a, potentially lengthy, Lucas-Lehmer test.
There are very efficient algorithms for determining if a number divides 2P-1 (or equivalently, if 2P mod (the number) = 1).
", "Some languages already have built-in implementations of this exponent-and-mod operation (called modPow or similar).
The following is how to implement this modPow yourself:
For example, let's compute 223 mod 47.
", "Convert the exponent 23 to binary, you get 10111. Starting with square = 1, repeatedly square it.
", "Remove the top bit of the exponent, and if it's 1 multiply square by the base of the exponentiation (2), then compute square modulo 47.
", "Use the result of the modulo from the last step as the initial value of square in the next step:
Remove Optional
", "square top bit multiply by 2 mod 47
", "------------ ------- ------------- ------
", "1*1 = 1 1 0111 1*2 = 2 2
", "2*2 = 4 0 111 no 4
", "4*4 = 16 1 11 16*2 = 32 32
", "32*32 = 1024 1 1 1024*2 = 2048 27
", "27*27 = 729 1 729*2 = 1458 1
Since 223 mod 47 = 1, 47 is a factor of 2P-1.
", "(To see this, subtract 1 from both sides: 223-1 = 0 mod 47.)
", "Since we've shown that 47 is a factor, 223-1 is not prime.
", "Further properties of Mersenne numbers allow us to refine the process even more.
", "Any factor q of 2P-1 must be of the form 2kP+1, k being a positive integer or zero. Furthermore, q must be 1 or 7 mod 8.
", "Finally any potential factor q must be prime.
", "As in other trial division algorithms, the algorithm stops when 2kP+1 > sqrt(N).
These primality tests only work on Mersenne numbers where P is prime. For example, M4=15 yields no factors using these techniques, but factors into 3 and 5, neither of which fit 2kP+1.
", "Task:", "Using the above method find a factor of 2929-1 (aka M929)
", "Related tasks:", " count in factors", " prime decomposition", " factors of an integer", " Sieve of Eratosthenes", " primality by trial division", " trial factoring of a Mersenne number", " partition an integer X into N primes", " sequence of primes by Trial Division", " Computers in 1948: 2¹²⁷-1" ], "solutions": [ "function check_mersenne(p){ \n\tfunction isPrime(value){\n\t for (let i=2; i < value; i++){\n\t\tif (value % i == 0){\n\t\t return false;\n\t\t}\n\t\tif (value % i != 0){\n\t\t return true;\n\t\t }\n\t }\n\t}\n\t\n\tfunction trial_factor(base, exp, mod){\n\t let square, bits;\n\t square = 1;\n\t bits = exp.toString(2).split('');\n\t for (let i=0,ln=bits.length; icheck_mersenne
is a function.');"
},
{
"text": "check_mersenne(3)
should return a string.",
"testString": "assert(typeof check_mersenne(3) == 'string', 'check_mersenne(3)
should return a string.');"
},
{
"text": "check_mersenne(3)
should return \"M3 = 2^3-1 is prime\".",
"testString": "assert.equal(check_mersenne(3),\"M3 = 2^3-1 is prime\",'check_mersenne(3)
should return \"M3 = 2^3-1 is prime\".');"
},
{
"text": "check_mersenne(23)
should return \"M23 = 2^23-1 is composite with factor 47\".",
"testString": "assert.equal(check_mersenne(23),\"M23 = 2^23-1 is composite with factor 47\",'check_mersenne(23)
should return \"M23 = 2^23-1 is composite with factor 47\".');"
},
{
"text": "check_mersenne(929)
should return \"M929 = 2^929-1 is composite with factor 13007",
"testString": "assert.equal(check_mersenne(929),\"M929 = 2^929-1 is composite with factor 13007\",'check_mersenne(929)
should return \"M929 = 2^929-1 is composite with factor 13007');"
}
],
"id": "598eea87e5cf4b116c3ff81a",
"challengeType": 5,
"releasedOn": "December 27, 2017",
"files": {
"indexjs": {
"key": "indexjs",
"ext": "js",
"name": "index",
"contents": [
"function check_mersenne (p) {",
" // Good luck!",
"}"
],
"head": [],
"tail": []
}
}
},
{
"title": "Factors of an integer",
"description": [
"Write a function that returns the factors of a positive integer.
These factors are the positive integers by which the number being factored can be divided to yield a positive integer result.
", "///" ], "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" ], "tests": [ { "text": "factors
is a function.",
"testString": "assert(typeof factors === 'function', 'factors
is a function.');"
},
{
"text": "factors(45)
should return [1,3,5,9,15,45]
.",
"testString": "assert.deepEqual(factors(45), ans[0], 'factors(45)
should return [1,3,5,9,15,45]
.');"
},
{
"text": "factors(53)
should return [1,53]
.",
"testString": "assert.deepEqual(factors(53), ans[1], 'factors(53)
should return [1,53]
.');"
},
{
"text": "factors(64)
should return [1,2,4,8,16,32,64]
.",
"testString": "assert.deepEqual(factors(64), ans[2], 'factors(64)
should return [1,2,4,8,16,32,64]
.');"
}
],
"id": "597f1e7fbc206f0e9ba95dc4",
"challengeType": 5,
"releasedOn": "December 27, 2017",
"files": {
"indexjs": {
"key": "indexjs",
"ext": "js",
"name": "index",
"contents": [
"function factors (num) {",
" // Good luck!",
"}"
],
"head": [],
"tail": [
"const ans=[[1,3,5,9,15,45],[1,53],[1,2,4,8,16,32,64]];"
]
}
}
},
{
"title": "Farey sequence",
"description": [
"Write a function that returns the Farey sequence of order n. The function should have one parameter that is n. It should return the sequence as an array. Read the following for more details :
The Farey sequence Fn of order n is the sequence of completely reduced fractions between 0 and 1 which, when in lowest terms, have denominators less than or equal to n, arranged in order of increasing size.
The Farey sequence is sometimes incorrectly called a Farey series.
", "Each Farey sequence:
", "::* starts with the value 0, denoted by the fraction $ \\frac{0}{1} $
", "::* ends with the value 1, denoted by the fraction $ \\frac{1}{1}$.
", "The Farey sequences of orders 1 to 5 are:
${\\bf\\it{F}}_1 = \\frac{0}{1}, \\frac{1}{1}$
", "", "${\\bf\\it{F}}_2 = \\frac{0}{1}, \\frac{1}{2}, \\frac{1}{1}$
", "", "${\\bf\\it{F}}_3 = \\frac{0}{1}, \\frac{1}{3}, \\frac{1}{2}, \\frac{2}{3}, \\frac{1}{1}$
", "", "${\\bf\\it{F}}_4 = \\frac{0}{1}, \\frac{1}{4}, \\frac{1}{3}, \\frac{1}{2}, \\frac{2}{3}, \\frac{3}{4}, \\frac{1}{1}$
", "", "${\\bf\\it{F}}_5 = \\frac{0}{1}, \\frac{1}{5}, \\frac{1}{4}, \\frac{1}{3}, \\frac{2}{5}, \\frac{1}{2}, \\frac{3}{5}, \\frac{2}{3}, \\frac{3}{4}, \\frac{4}{5}, \\frac{1}{1}$
" ], "solutions": [ "function farey(n){\n\tlet farSeq=[];\n\tfor(let den = 1; den <= n; den++){\n\t\tfor(let num = 1; num < den; num++){\n\t\t\tfarSeq.push({\n\t\t\t\tstr:num+\"/\"+den,\n\t\t\t\tval:num/den});\n\t\t}\n\t}\n\tfarSeq.sort(function(a,b){\n\t\treturn a.val-b.val;\n\t});\n\tfarSeq=farSeq.map(function(a){\n\t\treturn a.str;\n\t});\n\treturn farSeq;\n}\n" ], "tests": [ { "text": "farey
is a function.",
"testString": "assert(typeof farey === 'function', 'farey
is a function.');"
},
{
"text": "farey(3)
should return an array",
"testString": "assert(Array.isArray(farey(3)), 'farey(3)
should return an array');"
},
{
"text": "farey(3)
should return [\"1/3\",\"1/2\",\"2/3\"]
",
"testString": "assert.deepEqual(farey(3), [\"1/3\",\"1/2\",\"2/3\"], 'farey(3)
should return [\"1/3\",\"1/2\",\"2/3\"]
');"
},
{
"text": "farey(4)
should return [\"1/4\",\"1/3\",\"1/2\",\"2/4\",\"2/3\",\"3/4\"]
",
"testString": "assert.deepEqual(farey(4), [\"1/4\",\"1/3\",\"1/2\",\"2/4\",\"2/3\",\"3/4\"], 'farey(4)
should return [\"1/4\",\"1/3\",\"1/2\",\"2/4\",\"2/3\",\"3/4\"]
');"
},
{
"text": "farey(5)
should return [\"1/5\",\"1/4\",\"1/3\",\"2/5\",\"1/2\",\"2/4\",\"3/5\",\"2/3\",\"3/4\",\"4/5\"]
",
"testString": "assert.deepEqual(farey(5), [\"1/5\",\"1/4\",\"1/3\",\"2/5\",\"1/2\",\"2/4\",\"3/5\",\"2/3\",\"3/4\",\"4/5\"], 'farey(5)
should return [\"1/5\",\"1/4\",\"1/3\",\"2/5\",\"1/2\",\"2/4\",\"3/5\",\"2/3\",\"3/4\",\"4/5\"]
');"
}
],
"id": "59c3ec9f15068017c96eb8a3",
"challengeType": 5,
"releasedOn": "December 27, 2017",
"files": {
"indexjs": {
"key": "indexjs",
"ext": "js",
"name": "index",
"contents": [
"function farey (n) {",
" // Good luck!",
"}"
],
"head": [],
"tail": []
}
}
},
{
"title": "Fibonacci n-step number sequences",
"description": [
"Write a function to generate Fibonacci n-step number sequences and Lucas sequences. The first parameter will be n. The second parameter will be the number of elements to be returned. The third parameter will specify whether to output the Fibonacci sequence or the Lucas sequence. If the parameter is \"f\" then return the Fibonacci sequence and if it is \"l\", then return the Lucas sequence. The sequences must be returned as an array. More details are given below :
These number series are an expansion of the ordinary Fibonacci sequence where:
", "For $n = 2$ we have the Fibonacci sequence; with initial values $[1, 1]$ and $F_k^2 = F_{k-1}^2 + F_{k-2}^2$", "For $n = 3$ we have the tribonacci sequence; with initial values $[1, 1, 2]$ and $F_k^3 = F_{k-1}^3 + F_{k-2}^3 + F_{k-3}^3$", "For $n = 4$ we have the tetranacci sequence; with initial values $[1, 1, 2, 4]$ and $F_k^4 = F_{k-1}^4 + F_{k-2}^4 + F_{k-3}^4 + F_{k-4}^4$...", "For general $n>2$ we have the Fibonacci $n$-step sequence - $F_k^n$; with initial values of the first $n$ values of the $(n-1)$'th Fibonacci $n$-step sequence $F_k^{n-1}$; and $k$'th value of this $n$'th sequence being $F_k^n = \\sum_{i=1}^{(n)} {F_{k-i}^{(n)}}$", "For small values of $n$, Greek numeric prefixes are sometimes used to individually name each series.
{| style=\"text-align: left;\" border=\"4\" cellpadding=\"2\" cellspacing=\"2\"
", "|+ Fibonacci $n$-step sequences
", "|- style=\"background-color: rgb(255, 204, 255);\"
", "! $n$ !! Series name !! Values
", "|-
", "| 2 || fibonacci || 1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 ...
", "|-
", "| 3 || tribonacci || 1 1 2 4 7 13 24 44 81 149 274 504 927 1705 3136 ...
", "|-
", "| 4 || tetranacci || 1 1 2 4 8 15 29 56 108 208 401 773 1490 2872 5536 ...
", "|-
", "| 5 || pentanacci || 1 1 2 4 8 16 31 61 120 236 464 912 1793 3525 6930 ...
", "|-
", "| 6 || hexanacci || 1 1 2 4 8 16 32 63 125 248 492 976 1936 3840 7617 ...
", "|-
", "| 7 || heptanacci || 1 1 2 4 8 16 32 64 127 253 504 1004 2000 3984 7936 ...
", "|-
", "| 8 || octonacci || 1 1 2 4 8 16 32 64 128 255 509 1016 2028 4048 8080 ...
", "|-
", "| 9 || nonanacci || 1 1 2 4 8 16 32 64 128 256 511 1021 2040 4076 8144 ...
", "|-
", "| 10 || decanacci || 1 1 2 4 8 16 32 64 128 256 512 1023 2045 4088 8172 ...
", "|}
Allied sequences can be generated where the initial values are changed:
", "The Lucas series sums the two preceding values like the fibonacci series for $n=2$ but uses $[2, 1]$ as its initial values.
" ], "solutions": [ "function fib_luc(n, len, w) {\n\tfunction nacci(a, n, len) {\n\t\twhile (a.length < len) {\n\t\t let sum = 0;\n\t\t for (let i = Math.max(0, a.length - n); i < a.length; i++)\n\t\t sum += a[i];\n\t\t a.push(sum);\n\t\t}\n\t\treturn a;\n\t}\n\tif(w==\"f\"){\n \treturn nacci(nacci([1,1], n, n), n, len);\n\t}else{\n \treturn nacci(nacci([2,1], n, n), n, len);\n\t}\n}\n" ], "tests": [ { "text": "fib_luc
is a function.",
"testString": "assert(typeof fib_luc === 'function', 'fib_luc
is a function.');"
},
{
"text": "fib_luc(2,10,\"f\")
should return [1,1,2,3,5,8,13,21,34,55]
.",
"testString": "assert.deepEqual(fib_luc(2,10,\"f\"),ans[0],'fib_luc(2,10,\"f\")
should return [1,1,2,3,5,8,13,21,34,55]
.');"
},
{
"text": "fib_luc(3,15,\"f\")
should return [1,1,2,4,7,13,24,44,81,149,274,504,927,1705,3136]
.",
"testString": "assert.deepEqual(fib_luc(3,15,\"f\"),ans[1],'fib_luc(3,15,\"f\")
should return [1,1,2,4,7,13,24,44,81,149,274,504,927,1705,3136]
.');"
},
{
"text": "fib_luc(4,15,\"f\")
should return [1,1,2,4,8,15,29,56,108,208,401,773,1490,2872,5536]
.",
"testString": "assert.deepEqual(fib_luc(4,15,\"f\"),ans[2],'fib_luc(4,15,\"f\")
should return [1,1,2,4,8,15,29,56,108,208,401,773,1490,2872,5536]
.');"
},
{
"text": "fib_luc(2,10,\"l\")
should return [ 2, 1, 3, 4, 7, 11, 18, 29, 47, 76]
.",
"testString": "assert.deepEqual(fib_luc(2,10,\"l\"),ans[3],'fib_luc(2,10,\"l\")
should return [ 2, 1, 3, 4, 7, 11, 18, 29, 47, 76]
.');"
},
{
"text": "fib_luc(3,15,\"l\")
should return [ 2, 1, 3, 6, 10, 19, 35, 64, 118, 217, 399, 734, 1350, 2483, 4567 ]
.",
"testString": "assert.deepEqual(fib_luc(3,15,\"l\"),ans[4],'fib_luc(3,15,\"l\")
should return [ 2, 1, 3, 6, 10, 19, 35, 64, 118, 217, 399, 734, 1350, 2483, 4567 ]
.');"
},
{
"text": "fib_luc(4,15,\"l\")
should return [ 2, 1, 3, 6, 12, 22, 43, 83, 160, 308, 594, 1145, 2207, 4254, 8200 ]
.",
"testString": "assert.deepEqual(fib_luc(4,15,\"l\"),ans[5],'fib_luc(4,15,\"l\")
should return [ 2, 1, 3, 6, 12, 22, 43, 83, 160, 308, 594, 1145, 2207, 4254, 8200 ]
.');"
},
{
"text": "fib_luc(5,15,\"l\")
should return [ 2, 1, 3, 6, 12, 24, 46, 91, 179, 352, 692, 1360, 2674, 5257, 10335 ]
.",
"testString": "assert.deepEqual(fib_luc(5,15,\"l\"),ans[6],'fib_luc(5,15,\"l\")
should return [ 2, 1, 3, 6, 12, 24, 46, 91, 179, 352, 692, 1360, 2674, 5257, 10335 ]
.');"
}
],
"id": "598eef80ba501f1268170e1e",
"challengeType": 5,
"releasedOn": "December 27, 2017",
"files": {
"indexjs": {
"key": "indexjs",
"ext": "js",
"name": "index",
"contents": [
"function fib_luc (n, len, w) {",
" // Good luck!",
"}"
],
"head": [],
"tail": [
"const ans = [[1,1,2,3,5,8,13,21,34,55],",
"[1,1,2,4,7,13,24,44,81,149,274,504,927,1705,3136],",
"[1,1,2,4,8,15,29,56,108,208,401,773,1490,2872,5536],",
"[ 2, 1, 3, 4, 7, 11, 18, 29, 47, 76],",
"[ 2, 1, 3, 6, 10, 19, 35, 64, 118, 217, 399, 734, 1350, 2483, 4567 ],",
"[ 2, 1, 3, 6, 12, 22, 43, 83, 160, 308, 594, 1145, 2207, 4254, 8200 ],",
"[ 2, 1, 3, 6, 12, 24, 46, 91, 179, 352, 692, 1360, 2674, 5257, 10335 ]];"
]
}
}
},
{
"title": "Fibonacci sequence",
"description": [
"Write a function to generate the nth Fibonacci number.
", "///The nth Fibonacci number is given by :", "///
Fn = Fn-1 + Fn-2
", "///The first two terms of the series are 0, 1.
", "///Hence, the series is : 0, 1, 1, 2, 3, 5, 8, 13...
", "///" ], "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" ], "tests": [ { "text": "fibonacci
is a function.",
"testString": "assert(typeof fibonacci === 'function', 'fibonacci
is a function.');"
},
{
"text": "fibonacci(2)
should return a number.",
"testString": "assert(typeof fibonacci(2) == 'number', 'fibonacci(2)
should return a number.');"
},
{
"text": "fibonacci(3)
should return 1.\")",
"testString": "assert.equal(fibonacci(3),1,\"fibonacci(3)
should return 1.\");"
},
{
"text": "fibonacci(5)
should return 3.\")",
"testString": "assert.equal(fibonacci(5),3,\"fibonacci(5)
should return 3.\");"
},
{
"text": "fibonacci(10)
should return 34.\")",
"testString": "assert.equal(fibonacci(10),34,\"fibonacci(10)
should return 34.\");"
}
],
"id": "597f24c1dda4e70f53c79c81",
"challengeType": 5,
"releasedOn": "December 27, 2017",
"files": {
"indexjs": {
"key": "indexjs",
"ext": "js",
"name": "index",
"contents": [
"function fibonacci(n) {",
" // Good luck!",
"}"
],
"head": [],
"tail": []
}
}
},
{
"title": "Fibonacci word",
"description": [
"Write a function to return the Fibonacci Words upto N. N will be provided as a parameter to the function. The function should return an array of objects. The objects should be of the form : { N: 1, Length: 1, Entropy: 0, Word: '1' }. More details are given below :
The Fibonacci Word may be created in a manner analogous to the Fibonacci Sequence as described here:
Define F_Word1 as 1
", "Define F_Word2 as 0
", "Form F_Word3 as F_Word2 concatenated with F_Word1 i.e.: 01
", "Form F_Wordn as F_Wordn-1 concatenated with F_wordn-2
" ], "solutions": [ "function fibWord(n) {\n function entropy(s) {\n //create an object containing each individual char\n //and the amount of iterations per char \n function prob(s) {\n var h = Object.create(null);\n s.split('').forEach(function(c) {\n h[c] && h[c]++ || (h[c] = 1); \n });\n return h;\n }\n\n s = s.toString(); //just in case \n var e = 0, l = s.length, h = prob(s);\n\n for (var i in h ) {\n var p = h[i]/l;\n e -= p * Math.log(p) / Math.log(2);\n }\n return e;\n }\n var wOne = \"1\", wTwo = \"0\", wNth = [wOne, wTwo], w = \"\", o = [];\n \n for (var i = 0; i < n; i++) {\n if (i === 0 || i === 1) {\n w = wNth[i];\n } else {\n w = wNth[i - 1] + wNth[i - 2];\n wNth.push(w);\n }\n var l = w.length;\n var e = entropy(w);\n \n if (l <= 21) {\n \to.push({\n \tN: i + 1,\n \tLength: l,\n \tEntropy: e,\n \tWord: w\n \t});\n } else {\n \to.push({\n \tN: i + 1,\n \tLength: l,\n \tEntropy: e,\n \tWord: \"...\"\n \t});\n } \n }\n return o;\n}\n" ], "tests": [ { "text": "fibWord
is a function.",
"testString": "assert(typeof fibWord === 'function', 'fibWord
is a function.');"
},
{
"text": "fibWord(5)
should return an array.",
"testString": "assert(Array.isArray(fibWord(5)),'fibWord(5)
should return an array.');"
},
{
"text": "fibWord(5)
should return '+JSON.stringify(ans)+'
.",
"testString": "assert.deepEqual(fibWord(5),ans,'fibWord(5)
should return '+JSON.stringify(ans)+'
.');"
}
],
"id": "5992e222d397f00d21122931",
"challengeType": 5,
"releasedOn": "December 27, 2017",
"files": {
"indexjs": {
"key": "indexjs",
"ext": "js",
"name": "index",
"contents": [
"function fibWord (n) {",
" // Good luck!",
"}"
],
"head": [],
"tail": [
"let ans=[ { N: 1, Length: 1, Entropy: 0, Word: '1' },",
"",
" { N: 2, Length: 1, Entropy: 0, Word: '0' },",
"",
" { N: 3, Length: 2, Entropy: 1, Word: '01' },",
"",
" { N: 4, Length: 3, Entropy: 0.9182958340544896, Word: '010' },",
"",
" { N: 5, Length: 5, Entropy: 0.9709505944546688, Word: '01001' }];"
]
}
}
},
{
"title": "Hailstone sequence",
"description": [
"The Hailstone sequence of numbers can be generated from a starting positive integer, n by:
", " If n is 1 then the sequence ends.", " If n is even then the next n of the sequence = n/2
",
" If n is odd then the next n of the sequence = (3 * n) + 1
The (unproven) Collatz conjecture is that the hailstone sequence for any starting number always terminates.
", "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.
", "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 with27, 82, 41, 124
and ending with 8, 4, 2, 1
",
"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:",
" xkcd (humourous)."
],
"solutions": [
"// noprotect\nfunction hailstoneSequence () {\n const res = [];\n\n function hailstone(n) {\n const seq = [n];\n while (n > 1) {\n n = n % 2 ? 3 * n + 1 : n / 2;\n seq.push(n);\n }\n return seq;\n }\n\n const h = hailstone(27);\n const hLen = h.length;\n res.push([...h.slice(0, 4), ...h.slice(hLen - 4, hLen)]);\n\n let n = 0;\n let max = 0;\n for (let i = 100000; --i;) {\n const seq = hailstone(i);\n const sLen = seq.length;\n\n if (sLen > max) {\n n = i;\n max = sLen;\n }\n }\n res.push([max, n]);\n\n return res;\n}\n"
],
"tests": [
{
"text": "hailstoneSequence
is a function.",
"testString": "assert(typeof hailstoneSequence === 'function', 'hailstoneSequence
is a function.');"
},
{
"text": "hailstoneSequence()
should return [[27,82,41,124,8,4,2,1], [351, 77031]]
",
"testString": "assert.deepEqual(hailstoneSequence(), res, 'hailstoneSequence()
should return [[27,82,41,124,8,4,2,1], [351, 77031]]
');"
}
],
"id": "595608ff8bcd7a50bd490181",
"challengeType": 5,
"releasedOn": "December 27, 2017",
"files": {
"indexjs": {
"key": "indexjs",
"ext": "js",
"name": "index",
"contents": [
"// noprotect",
"function hailstoneSequence () {",
" const res = [];",
" // Good luck!",
"",
" return res;",
"}"
],
"head": [],
"tail": [
"const res = [[27, 82, 41, 124, 8, 4, 2, 1], [351, 77031]];"
]
}
}
},
{
"title": "Happy numbers",
"description": [
"A happy number is defined by the following process:
", "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.
", "Implement a function that returns true if the number is happy, or false if not.
" ], "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": [ { "text": "happy
is a function.",
"testString": "assert(typeof happy === 'function', 'happy
is a function.');"
},
{
"text": "happy(1)
should return a boolean.",
"testString": "assert(typeof happy(1) === 'boolean', 'happy(1)
should return a boolean.');"
},
{
"text": "happy(1)
should return true.",
"testString": "assert(happy(1), 'happy(1)
should return true.');"
},
{
"text": "happy(2)
should return false.",
"testString": "assert(!happy(2), 'happy(2)
should return false.');"
},
{
"text": "happy(7)
should return true.",
"testString": "assert(happy(7), 'happy(7)
should return true.');"
},
{
"text": "happy(10)
should return true.",
"testString": "assert(happy(10), 'happy(10)
should return true.');"
},
{
"text": "happy(13)
should return true.",
"testString": "assert(happy(13), 'happy(13)
should return true.');"
},
{
"text": "happy(19)
should return true.",
"testString": "assert(happy(19), 'happy(19)
should return true.');"
},
{
"text": "happy(23)
should return true.",
"testString": "assert(happy(23), 'happy(23)
should return true.');"
},
{
"text": "happy(28)
should return true.",
"testString": "assert(happy(28), 'happy(28)
should return true.');"
},
{
"text": "happy(31)
should return true.",
"testString": "assert(happy(31), 'happy(31)
should return true.');"
},
{
"text": "happy(32)
should return true:.",
"testString": "assert(happy(32), 'happy(32)
should return true:.');"
},
{
"text": "happy(33)
should return false.",
"testString": "assert(!happy(33), 'happy(33)
should return false.');"
}
],
"id": "594810f028c0303b75339ad1",
"challengeType": 5,
"releasedOn": "December 27, 2017",
"files": {
"indexjs": {
"key": "indexjs",
"ext": "js",
"name": "index",
"contents": [
"function happy (number) {",
" // Good luck!",
"}"
],
"head": [],
"tail": []
}
}
},
{
"title": "Harshad or Niven series",
"description": [
"The Harshad or Niven numbers are positive integers ≥ 1 that are divisible by the sum of their digits.
For example, 42 is a Harshad number as 42 is divisible by (4 + 2) without remainder.
", "Assume that the series is defined as the numbers in increasing order.", "Task:", "Implement a function to generate successive members of the Harshad sequence.
Use it to list the first twenty members of the sequence and list the first Harshad number greater than 1000.
" ], "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" ], "tests": [ { "text": "isHarshadOrNiven
is a function.",
"testString": "assert(typeof isHarshadOrNiven === 'function', 'isHarshadOrNiven
is a function.');"
},
{
"text": "isHarshadOrNiven()
should return {\"firstTwenty\": [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 12, 18, 20, 21, 24, 27, 30, 36, 40, 42],\"firstOver1000\": 1002}
",
"testString": "assert.deepEqual(isHarshadOrNiven(), res, 'isHarshadOrNiven()
should return {\"firstTwenty\": [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 12, 18, 20, 21, 24, 27, 30, 36, 40, 42],\"firstOver1000\": 1002}
');"
}
],
"id": "595668ca4cfe1af2fb9818d4",
"challengeType": 5,
"releasedOn": "December 27, 2017",
"files": {
"indexjs": {
"key": "indexjs",
"ext": "js",
"name": "index",
"contents": [
"function isHarshadOrNiven () {",
" const res = {",
" firstTwenty: [],",
" firstOver1000: undefined",
" };",
" // Change after this line",
"",
" return res;",
"}"
],
"head": [],
"tail": [
"const res = {",
" firstTwenty: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 12, 18, 20, 21, 24, 27, 30, 36, 40, 42],",
" firstOver1000: 1002",
"};"
]
}
}
},
{
"title": "Hash from two arrays",
"description": [
"Task:",
"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)
", "Related task:", " Associative arrays/Creation" ], "solutions": [ "function arrToObj (keys, vals) {\n return keys.reduce((map, key, index) => {\n map[key] = vals[index];\n return map;\n }, {});\n}" ], "tests": [ { "text": "arrToObj
is a function.",
"testString": "assert(typeof arrToObj === 'function', 'arrToObj
is a function.');"
},
{
"text": "arrToObj([1, 2, 3, 4, 5], [\"a\", \"b\", \"c\", \"d\", \"e\"])
should return { 1: \"a\", 2: \"b\", 3: \"c\", 4: \"d\", 5: \"e\" }
",
"testString": "assert.deepEqual(arrToObj(...testCases[0]), res[0], 'arrToObj([1, 2, 3, 4, 5], [\"a\", \"b\", \"c\", \"d\", \"e\"])
should return { 1: \"a\", 2: \"b\", 3: \"c\", 4: \"d\", 5: \"e\" }
');"
},
{
"text": "arrToObj([1, 2, 3, 4, 5], [\"a\", \"b\", \"c\", \"d\"])
should return { 1: \"a\", 2: \"b\", 3: \"c\", 4: \"d\", 5: undefined }
",
"testString": "assert.deepEqual(arrToObj(...testCases[1]), res[1], 'arrToObj([1, 2, 3, 4, 5], [\"a\", \"b\", \"c\", \"d\"])
should return { 1: \"a\", 2: \"b\", 3: \"c\", 4: \"d\", 5: undefined }
');"
},
{
"text": "arrToObj([1, 2, 3], [\"a\", \"b\", \"c\", \"d\", \"e\"])
should return { 1: \"a\", 2: \"b\", 3: \"c\" }
",
"testString": "assert.deepEqual(arrToObj(...testCases[2]), res[2], 'arrToObj([1, 2, 3], [\"a\", \"b\", \"c\", \"d\", \"e\"])
should return { 1: \"a\", 2: \"b\", 3: \"c\" }
');"
},
{
"text": "arrToObj([\"a\", \"b\", \"c\", \"d\", \"e\"], [1, 2, 3, 4, 5])
should return { \"a\": 1, \"b\": 2, \"c\": 3 , \"d\": 4, \"e\": 5 }
",
"testString": "assert.deepEqual(arrToObj(...testCases[3]), res[3], 'arrToObj([\"a\", \"b\", \"c\", \"d\", \"e\"], [1, 2, 3, 4, 5])
should return { \"a\": 1, \"b\": 2, \"c\": 3 , \"d\": 4, \"e\": 5 }
');"
},
{
"text": "arrToObj([\"a\", \"b\", \"c\", \"d\", \"e\"], [1, 2, 3, 4])
should return { \"a\": 1, \"b\": 2, \"c\": 3 , \"d\": 4, \"e\": undefined }
",
"testString": "assert.deepEqual(arrToObj(...testCases[4]), res[4], 'arrToObj([\"a\", \"b\", \"c\", \"d\", \"e\"], [1, 2, 3, 4])
should return { \"a\": 1, \"b\": 2, \"c\": 3 , \"d\": 4, \"e\": undefined }
');"
},
{
"text": "arrToObj([\"a\", \"b\", \"c\"], [1, 2, 3, 4, 5])
should return { \"a\": 1, \"b\": 2, \"c\": 3 }
",
"testString": "assert.deepEqual(arrToObj(...testCases[5]), res[5], 'arrToObj([\"a\", \"b\", \"c\"], [1, 2, 3, 4, 5])
should return { \"a\": 1, \"b\": 2, \"c\": 3 }
');"
}
],
"id": "595671d4d2cdc305f0d5b36f",
"challengeType": 5,
"releasedOn": "December 27, 2017",
"files": {
"indexjs": {
"key": "indexjs",
"ext": "js",
"name": "index",
"contents": [
"function arrToObj (keys, vals) {",
" // Good luck!",
" return true;",
"}"
],
"head": [],
"tail": [
"const testCases = [",
" [[1, 2, 3, 4, 5], ['a', 'b', 'c', 'd', 'e']],",
" [[1, 2, 3, 4, 5], ['a', 'b', 'c', 'd']],",
" [[1, 2, 3], ['a', 'b', 'c', 'd', 'e']],",
" [['a', 'b', 'c', 'd', 'e'], [1, 2, 3, 4, 5]],",
" [['a', 'b', 'c', 'd', 'e'], [1, 2, 3, 4]],",
" [['a', 'b', 'c'], [1, 2, 3, 4, 5]]",
"];",
"",
"const res = [",
" { 1: 'a', 2: 'b', 3: 'c', 4: 'd', 5: 'e' },",
" { 1: 'a', 2: 'b', 3: 'c', 4: 'd', 5: undefined },",
" { 1: 'a', 2: 'b', 3: 'c' },",
" { a: 1, b: 2, c: 3, d: 4, e: 5 },",
" { a: 1, b: 2, c: 3, d: 4, e: undefined },",
" { a: 1, b: 2, c: 3 }",
"];"
]
}
}
},
{
"title": "Hash join",
"description": [
"An inner join 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 nested loop join algorithm, but a more scalable alternative is the hash join algorithm.
", "Implement the \"hash join\" algorithm, and demonstrate that it passes the test-case listed below.
You should represent the tables as data structures that feel natural in your programming language.
", "The \"hash join\" algorithm consists of two steps:
", "Hash phase: Create a multimap 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.", "In pseudo-code, the algorithm could be expressed as follows:
", "", "let A = the first input table (or ideally, the larger one)", "let B = the second input table (or ideally, the smaller one)", "let jA = the join column ID of table A", "let jB = the join column ID of table B", "let MB = 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 MB under key b(jB)", "for each row a in table A:", " for each row b in multimap MB under key a(jA):", " let c = the concatenation of row a and row b", " place row c in table C", "", "Test-case", "
Input
", "",
"
| ",
"", " |
Output
", "A.Age | ", "A.Name | ", "B.Character | ", "B.Nemesis", " |
---|---|---|---|
27 | ", "Jonah | ", "Jonah | ", "Whales", " |
27 | ", "Jonah | ", "Jonah | ", "Spiders", " |
18 | ", "Alan | ", "Alan | ", "Ghosts", " |
18 | ", "Alan | ", "Alan | ", "Zombies", " |
28 | ", "Glory | ", "Glory | ", "Buffy", " |
28 | ", "Alan | ", "Alan | ", "Ghosts", " |
28 | ", "Alan | ", "Alan | ", "Zombies", " |
The order of the rows in the output table is not significant.
", "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 [[27, \"Jonah\"], [\"Jonah\", \"Whales\"]]
.
hashJoin
is a function.",
"testString": "assert(typeof hashJoin === 'function', 'hashJoin
is a function.');"
},
{
"text": "hashJoin([{ age: 27, name: \"Jonah\" }, { age: 18, name: \"Alan\" }, { age: 28, name: \"Glory\" }, { age: 18, name: \"Popeye\" }, { age: 28, name: \"Alan\" }], [{ character: \"Jonah\", nemesis: \"Whales\" }, { character: \"Jonah\", nemesis: \"Spiders\" }, { character: \"Alan\", nemesis: \"Ghosts\" }, { character:\"Alan\", nemesis: \"Zombies\" }, { character: \"Glory\", nemesis: \"Buffy\" }, { character: \"Bob\", nemesis: \"foo\" }])
should return [{\"A_age\": 27,\"A_name\": \"Jonah\", \"B_character\": \"Jonah\", \"B_nemesis\": \"Whales\"}, {\"A_age\": 27,\"A_name\": \"Jonah\", \"B_character\": \"Jonah\", \"B_nemesis\": \"Spiders\"}, {\"A_age\": 18,\"A_name\": \"Alan\", \"B_character\": \"Alan\", \"B_nemesis\": \"Ghosts\"}, {\"A_age\": 18,\"A_name\": \"Alan\", \"B_character\": \"Alan\", \"B_nemesis\": \"Zombies\"}, {\"A_age\": 28,\"A_name\": \"Glory\", \"B_character\": \"Glory\", \"B_nemesis\": \"Buffy\"}, {\"A_age\": 28,\"A_name\": \"Alan\", \"B_character\": \"Alan\", \"B_nemesis\": \"Ghosts\"}, {\"A_age\": 28,\"A_name\": \"Alan\", \"B_character\": \"Alan\", \"B_nemesis\": \"Zombies\"}]
",
"testString": "assert.deepEqual(hashJoin(hash1, hash2), res, 'hashJoin([{ age: 27, name: \"Jonah\" }, { age: 18, name: \"Alan\" }, { age: 28, name: \"Glory\" }, { age: 18, name: \"Popeye\" }, { age: 28, name: \"Alan\" }], [{ character: \"Jonah\", nemesis: \"Whales\" }, { character: \"Jonah\", nemesis: \"Spiders\" }, { character: \"Alan\", nemesis: \"Ghosts\" }, { character:\"Alan\", nemesis: \"Zombies\" }, { character: \"Glory\", nemesis: \"Buffy\" }, { character: \"Bob\", nemesis: \"foo\" }])
should return [{\"A_age\": 27,\"A_name\": \"Jonah\", \"B_character\": \"Jonah\", \"B_nemesis\": \"Whales\"}, {\"A_age\": 27,\"A_name\": \"Jonah\", \"B_character\": \"Jonah\", \"B_nemesis\": \"Spiders\"}, {\"A_age\": 18,\"A_name\": \"Alan\", \"B_character\": \"Alan\", \"B_nemesis\": \"Ghosts\"}, {\"A_age\": 18,\"A_name\": \"Alan\", \"B_character\": \"Alan\", \"B_nemesis\": \"Zombies\"}, {\"A_age\": 28,\"A_name\": \"Glory\", \"B_character\": \"Glory\", \"B_nemesis\": \"Buffy\"}, {\"A_age\": 28,\"A_name\": \"Alan\", \"B_character\": \"Alan\", \"B_nemesis\": \"Ghosts\"}, {\"A_age\": 28,\"A_name\": \"Alan\", \"B_character\": \"Alan\", \"B_nemesis\": \"Zombies\"}]
');"
}
],
"id": "5956795bc9e2c415eb244de1",
"challengeType": 5,
"releasedOn": "December 27, 2017",
"files": {
"indexjs": {
"key": "indexjs",
"ext": "js",
"name": "index",
"contents": [
"function hashJoin (hash1, hash2) {",
" // Good luck!",
" return [];",
"}"
],
"head": [],
"tail": [
"const hash1 = [",
" { age: 27, name: 'Jonah' },",
" { age: 18, name: 'Alan' },",
" { age: 28, name: 'Glory' },",
" { age: 18, name: 'Popeye' },",
" { age: 28, name: 'Alan' }",
"];",
"",
"const hash2 = [",
" { character: 'Jonah', nemesis: 'Whales' },",
" { character: 'Jonah', nemesis: 'Spiders' },",
" { character: 'Alan', nemesis: 'Ghosts' },",
" { character: 'Alan', nemesis: 'Zombies' },",
" { character: 'Glory', nemesis: 'Buffy' },",
" { character: 'Bob', nemesis: 'foo' }",
"];",
"",
"const res = [",
" { A_age: 27, A_name: 'Jonah', B_character: 'Jonah', B_nemesis: 'Whales' },",
" { A_age: 27, A_name: 'Jonah', B_character: 'Jonah', B_nemesis: 'Spiders' },",
" { A_age: 18, A_name: 'Alan', B_character: 'Alan', B_nemesis: 'Ghosts' },",
" { A_age: 18, A_name: 'Alan', B_character: 'Alan', B_nemesis: 'Zombies' },",
" { A_age: 28, A_name: 'Glory', B_character: 'Glory', B_nemesis: 'Buffy' },",
" { A_age: 28, A_name: 'Alan', B_character: 'Alan', B_nemesis: 'Ghosts' },",
" { A_age: 28, A_name: 'Alan', B_character: 'Alan', B_nemesis: 'Zombies' }",
"];",
"",
"const bench1 = [{ name: 'u2v7v', num: 1 }, { name: 'n53c8', num: 10 }, { name: 'oysce', num: 9 }, { name: '0mto2s', num: 1 }, { name: 'vkh5id', num: 4 }, { name: '5od0cf', num: 8 }, { name: 'uuulue', num: 10 }, { name: '3rgsbi', num: 9 }, { name: 'kccv35r', num: 4 }, { name: '80un74', num: 9 }, { name: 'h4pp3', num: 6 }, { name: '51bit', num: 7 }, { name: 'j9ndf', num: 8 }, { name: 'vf3u1', num: 10 }, { name: 'g0bw0om', num: 10 }, { name: 'j031x', num: 7 }, { name: 'ij3asc', num: 9 }, { name: 'byv83y', num: 8 }, { name: 'bjzp4k', num: 4 }, { name: 'f3kbnm', num: 10 }];",
"const bench2 = [{ friend: 'o8b', num: 8 }, { friend: 'ye', num: 2 }, { friend: '32i', num: 5 }, { friend: 'uz', num: 3 }, { friend: 'a5k', num: 4 }, { friend: 'uad', num: 7 }, { friend: '3w5', num: 10 }, { friend: 'vw', num: 10 }, { friend: 'ah', num: 4 }, { friend: 'qv', num: 7 }, { friend: 'ozv', num: 2 }, { friend: '9ri', num: 10 }, { friend: '7nu', num: 4 }, { friend: 'w3', num: 9 }, { friend: 'tgp', num: 8 }, { friend: 'ibs', num: 1 }, { friend: 'ss7', num: 6 }, { friend: 'g44', num: 9 }, { friend: 'tab', num: 9 }, { friend: 'zem', num: 10 }];"
]
}
}
},
{
"title": "Heronian triangles",
"description": [
"Hero's formula for the area of a triangle given the length of its three sides a, b, and c is given by:
$$A = \\sqrt{s(s-a)(s-b)(s-c)},$$
where s is half the perimeter of the triangle; that is,
$$s=\\frac{a+b+c}{2}.$$
", "Heronian triangles are triangles whose sides and area are all integers.
", "An example is the triangle with sides 3, 4, 5 whose area is 6 (and whose perimeter is 12).
", "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.
Define a Primitive Heronian triangle as a Heronian triangle where the greatest common divisor
", "of all three sides is 1 (unity).
This will exclude, for example, triangle 6, 8, 10.
", "Task:", "Implement a function based on Hero's formula that returns the first nth
ordered triangles in an array of arrays.
heronianTriangle
is a function.",
"testString": "assert(typeof heronianTriangle === 'function', 'heronianTriangle
is a function.');"
},
{
"text": "heronianTriangle()
should return [[3, 4, 5], [5, 5, 6], [5, 5, 8], [4, 13, 15], [5, 12, 13], [9, 10, 17], [3, 25, 26], [7, 15, 20], [10, 13, 13], [8, 15, 17]]
",
"testString": "assert.deepEqual(heronianTriangle(testCases[0]), res[0], 'heronianTriangle()
should return [[3, 4, 5], [5, 5, 6], [5, 5, 8], [4, 13, 15], [5, 12, 13], [9, 10, 17], [3, 25, 26], [7, 15, 20], [10, 13, 13], [8, 15, 17]]
');"
},
{
"text": "heronianTriangle()
should return [[3, 4, 5], [5, 5, 6], [5, 5, 8], [4, 13, 15], [5, 12, 13], [9, 10, 17], [3, 25, 26], [7, 15, 20], [10, 13, 13], [8, 15, 17], [13, 13, 24], [6, 25, 29], [11, 13, 20], [5, 29, 30], [13, 14, 15]],
",
"testString": "assert.deepEqual(heronianTriangle(testCases[1]), res[1], 'heronianTriangle()
should return [[3, 4, 5], [5, 5, 6], [5, 5, 8], [4, 13, 15], [5, 12, 13], [9, 10, 17], [3, 25, 26], [7, 15, 20], [10, 13, 13], [8, 15, 17], [13, 13, 24], [6, 25, 29], [11, 13, 20], [5, 29, 30], [13, 14, 15]],
');"
},
{
"text": "heronianTriangle()
should return [[3, 4, 5], [5, 5, 6], [5, 5, 8], [4, 13, 15], [5, 12, 13], [9, 10, 17], [3, 25, 26], [7, 15, 20], [10, 13, 13], [8, 15, 17], [13, 13, 24], [6, 25, 29], [11, 13, 20], [5, 29, 30], [13, 14, 15], [10, 17, 21], [7, 24, 25], [8, 29, 35], [12, 17, 25], [4, 51, 53]],
",
"testString": "assert.deepEqual(heronianTriangle(testCases[2]), res[2], 'heronianTriangle()
should return [[3, 4, 5], [5, 5, 6], [5, 5, 8], [4, 13, 15], [5, 12, 13], [9, 10, 17], [3, 25, 26], [7, 15, 20], [10, 13, 13], [8, 15, 17], [13, 13, 24], [6, 25, 29], [11, 13, 20], [5, 29, 30], [13, 14, 15], [10, 17, 21], [7, 24, 25], [8, 29, 35], [12, 17, 25], [4, 51, 53]],
');"
},
{
"text": "heronianTriangle()
should return [[3, 4, 5], [5, 5, 6], [5, 5, 8], [4, 13, 15], [5, 12, 13], [9, 10, 17], [3, 25, 26], [7, 15, 20], [10, 13, 13], [8, 15, 17], [13, 13, 24], [6, 25, 29], [11, 13, 20], [5, 29, 30], [13, 14, 15], [10, 17, 21], [7, 24, 25], [8, 29, 35], [12, 17, 25], [4, 51, 53], [19, 20, 37],[16, 17, 17], [17, 17, 30], [16, 25, 39], [13, 20, 21]]
",
"testString": "assert.deepEqual(heronianTriangle(testCases[3]), res[3], 'heronianTriangle()
should return [[3, 4, 5], [5, 5, 6], [5, 5, 8], [4, 13, 15], [5, 12, 13], [9, 10, 17], [3, 25, 26], [7, 15, 20], [10, 13, 13], [8, 15, 17], [13, 13, 24], [6, 25, 29], [11, 13, 20], [5, 29, 30], [13, 14, 15], [10, 17, 21], [7, 24, 25], [8, 29, 35], [12, 17, 25], [4, 51, 53], [19, 20, 37],[16, 17, 17], [17, 17, 30], [16, 25, 39], [13, 20, 21]]
');"
}
],
"id": "595b98f8b5a2245e243aa831",
"challengeType": 5,
"releasedOn": "December 27, 2017",
"files": {
"indexjs": {
"key": "indexjs",
"ext": "js",
"name": "index",
"contents": [
"// noprotect",
"function heronianTriangle (n) {",
" // Good luck!",
"",
" return [];",
"}"
],
"head": [],
"tail": [
"const testCases = [10, 15, 20, 25];",
"",
"const res = [",
" [[3, 4, 5], [5, 5, 6], [5, 5, 8], [4, 13, 15], [5, 12, 13], [9, 10, 17], [3, 25, 26], [7, 15, 20], [10, 13, 13], [8, 15, 17]],",
" [[3, 4, 5], [5, 5, 6], [5, 5, 8], [4, 13, 15], [5, 12, 13], [9, 10, 17], [3, 25, 26], [7, 15, 20], [10, 13, 13], [8, 15, 17], [13, 13, 24], [6, 25, 29], [11, 13, 20], [5, 29, 30], [13, 14, 15]],",
" [[3, 4, 5], [5, 5, 6], [5, 5, 8], [4, 13, 15], [5, 12, 13], [9, 10, 17], [3, 25, 26], [7, 15, 20], [10, 13, 13], [8, 15, 17], [13, 13, 24], [6, 25, 29], [11, 13, 20], [5, 29, 30], [13, 14, 15], [10, 17, 21], [7, 24, 25], [8, 29, 35], [12, 17, 25], [4, 51, 53]],",
" [[3, 4, 5], [5, 5, 6], [5, 5, 8], [4, 13, 15], [5, 12, 13], [9, 10, 17], [3, 25, 26], [7, 15, 20], [10, 13, 13], [8, 15, 17], [13, 13, 24], [6, 25, 29], [11, 13, 20], [5, 29, 30], [13, 14, 15], [10, 17, 21], [7, 24, 25], [8, 29, 35], [12, 17, 25], [4, 51, 53], [19, 20, 37], [16, 17, 17], [17, 17, 30], [16, 25, 39], [13, 20, 21]]",
"];"
]
}
}
},
{
"title": "Hofstadter Figure-Figure sequences",
"description": [
"These two sequences of positive integers are defined as:
", "$$R(1)=1\\ ;\\ S(1)=2 \\\\R(n)=R(n-1)+S(n-1), \\quad n>1.$$
", "The sequence $S(n)$ is further defined as the sequence of positive integers not present in $R(n)$.
Sequence $R$ starts:
", "1, 3, 7, 12, 18, ...
", "Sequence $S$ starts:
", "2, 4, 5, 6, 8, ...
", "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 A005228 and A030124.", "Wolfram MathWorld", "Wikipedia: Hofstadter Figure-Figure sequences." ], "solutions": [ "// noprotect\nconst R = [null, 1];\nconst S = [null, 2];\n\nfunction extendSequences (n) {\n let current = Math.max(R[R.length - 1], S[S.length - 1]);\n let i;\n while (R.length <= n || S.length <= n) {\n i = Math.min(R.length, S.length) - 1;\n current += 1;\n if (current === R[i] + S[i]) {\n R.push(current);\n } else {\n S.push(current);\n }\n }\n}\n\nfunction ffr (n) {\n extendSequences(n);\n return R[n];\n}\n\nfunction ffs (n) {\n extendSequences(n);\n return S[n];\n}\n" ], "tests": [ { "text": "ffr
is a function.",
"testString": "assert(typeof ffr === 'function', 'ffr
is a function.');"
},
{
"text": "ffs
is a function.",
"testString": "assert(typeof ffs === 'function', 'ffs
is a function.');"
},
{
"text": "ffr
should return integer.",
"testString": "assert(Number.isInteger(ffr(1)), 'ffr
should return integer.');"
},
{
"text": "ffs
should return integer.",
"testString": "assert(Number.isInteger(ffs(1)), 'ffs
should return integer.');"
},
{
"text": "ffr()
should return 69
",
"testString": "assert.equal(ffr(ffrParamRes[0][0]), ffrParamRes[0][1], 'ffr()
should return 69
');"
},
{
"text": "ffr()
should return 1509
",
"testString": "assert.equal(ffr(ffrParamRes[1][0]), ffrParamRes[1][1], 'ffr()
should return 1509
');"
},
{
"text": "ffr()
should return 5764
",
"testString": "assert.equal(ffr(ffrParamRes[2][0]), ffrParamRes[2][1], 'ffr()
should return 5764
');"
},
{
"text": "ffr()
should return 526334
",
"testString": "assert.equal(ffr(ffrParamRes[3][0]), ffrParamRes[3][1], 'ffr()
should return 526334
');"
},
{
"text": "ffs()
should return 14
",
"testString": "assert.equal(ffs(ffsParamRes[0][0]), ffsParamRes[0][1], 'ffs()
should return 14
');"
},
{
"text": "ffs()
should return 59
",
"testString": "assert.equal(ffs(ffsParamRes[1][0]), ffsParamRes[1][1], 'ffs()
should return 59
');"
},
{
"text": "ffs()
should return 112
",
"testString": "assert.equal(ffs(ffsParamRes[2][0]), ffsParamRes[2][1], 'ffs()
should return 112
');"
},
{
"text": "ffs()
should return 1041
",
"testString": "assert.equal(ffs(ffsParamRes[3][0]), ffsParamRes[3][1], 'ffs()
should return 1041
');"
}
],
"id": "59622f89e4e137560018a40e",
"challengeType": 5,
"releasedOn": "December 27, 2017",
"files": {
"indexjs": {
"key": "indexjs",
"ext": "js",
"name": "index",
"contents": [
"// noprotect",
"function ffr(n) {",
" return n;",
"}",
"",
"function ffs(n) {",
" return n;",
"}"
],
"head": [],
"tail": [
"const ffrParamRes = [[10, 69], [50, 1509], [100, 5764], [1000, 526334]];",
"const ffsParamRes = [[10, 14], [50, 59], [100, 112], [1000, 1041]];",
""
]
}
}
},
{
"title": "Hofstadter Q sequence",
"description": [
"The Hofstadter Q sequence is defined as:
", "$Q(1)=Q(2)=1, \\\\ Q(n)=Q\\big(n-Q(n-1)\\big)+Q\\big(n-Q(n-2)), \\quad n>2.$
", "It is defined like the Fibonacci sequence, 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.
", "Task:", "Implement the Hofstadter Q Sequence equation into JavaScript" ], "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" ], "tests": [ { "text": "hofstadterQ
is a function.",
"testString": "assert(typeof hofstadterQ === 'function', 'hofstadterQ
is a function.');"
},
{
"text": "hofstadterQ()
should return integer
",
"testString": "assert(Number.isInteger(hofstadterQ(1000)), 'hofstadterQ()
should return integer
');"
},
{
"text": "hofstadterQ(1000)
should return 502
",
"testString": "assert.equal(hofstadterQ(testCase[0]), res[0], 'hofstadterQ(1000)
should return 502
');"
},
{
"text": "hofstadterQ(1500)
should return 755
",
"testString": "assert.equal(hofstadterQ(testCase[1]), res[1], 'hofstadterQ(1500)
should return 755
');"
},
{
"text": "hofstadterQ(2000)
should return 1005
",
"testString": "assert.equal(hofstadterQ(testCase[2]), res[2], 'hofstadterQ(2000)
should return 1005
');"
},
{
"text": "hofstadterQ(2500)
should return 1261
",
"testString": "assert.equal(hofstadterQ(testCase[3]), res[3], 'hofstadterQ(2500)
should return 1261
');"
}
],
"id": "59637c4d89f6786115efd814",
"challengeType": 5,
"releasedOn": "December 27, 2017",
"files": {
"indexjs": {
"key": "indexjs",
"ext": "js",
"name": "index",
"contents": [
"function hofstadterQ (n) {",
" // Good luck!",
" return n;",
"}"
],
"head": [],
"tail": [
"const testCase = [1000, 1500, 2000, 2500];",
"const res = [502, 755, 1005, 1261];"
]
}
}
},
{
"title": "Sailors, coconuts and a monkey problem",
"description": [
" ", " Five sailors are shipwrecked on an island and", " collect a large pile of coconuts during the day.", "
", "That night the first sailor wakes up and decides", " to take his first share early so tries to divide the pile of coconuts equally", " into five piles but finds that there is one coconut left over, so he tosses it", " to a monkey and then hides \"his\" one of the five equally sized piles of", " coconuts and pushes the other four piles together to form a single visible pile", " of coconuts again and goes to bed.", "
", "", " To cut a long story short, each of the sailors in", " turn gets up once during the night and performs the same actions of dividing", " the coconut pile into five, finding that one coconut is left over and giving", " that single remainder coconut to the monkey.", "
", "", " In the morning (after the surreptitious and", " separate action of each of the five sailors during the night), the remaining", " coconuts are divided into five equal piles for each of the sailors, whereupon", " it is found that the pile of coconuts divides equally amongst the sailors with", " no remainder. (Nothing for the monkey in the morning.)", "
", "", " The task:", "", "", " Create a function that returns the", " the minimum possible size", " of the initial pile of coconuts collected during the day for N", " sailors.", "", "", " Note:", "", "", " Of course the tale is told in a", " world where the collection of any amount of coconuts in a day and multiple", " divisions of the pile, etc can occur in time fitting the story line, so as", " not to affect the mathematics.", "", "", "", " C.f:", "", " ", " Monkeys and Coconuts - Numberphile (Video) Analytical solution.", "", "", " A002021 Pile of coconuts problem The On-Line", " Encyclopedia of Integer Sequences. (Although some of its references may use", " the alternate form of the tale).", "", "", "" ], "solutions": [ "// noprotect\nfunction splitCoconuts(intSailors) {\n let intNuts = intSailors;\n let result = splitCoconutsHelper(intNuts, intSailors);\n while (!result) {\n intNuts += 1;\n result = splitCoconutsHelper(intNuts, intSailors);\n }\n\n return intNuts;\n}\n\nfunction splitCoconutsHelper(intNuts, intSailors, intDepth) {\n const nDepth = intDepth !== undefined ? intDepth : intSailors;\n const portion = Math.floor(intNuts / intSailors);\n const remain = intNuts % intSailors;\n\n if (portion <= 0 || remain !== (nDepth ? 1 : 0)) {\n return null;\n }\n\n if (nDepth) {\n return splitCoconutsHelper(\n intNuts - portion - remain, intSailors, nDepth - 1\n );\n }\n\n return intNuts;\n}\n" ], "tests": [ { "text": "splitCoconuts
is a function.",
"testString": "assert(typeof splitCoconuts === 'function', 'splitCoconuts
is a function.');"
},
{
"text": "splitCoconuts(5)
should return 3121.",
"testString": "assert(splitCoconuts(5) === 3121, 'splitCoconuts(5)
should return 3121.');"
},
{
"text": "splitCoconuts(6)
should return 233275.",
"testString": "assert(splitCoconuts(6) === 233275, 'splitCoconuts(6)
should return 233275.');"
},
{
"text": "splitCoconuts(7)
should return 823537.",
"testString": "assert(splitCoconuts(7) === 823537, 'splitCoconuts(7)
should return 823537.');"
}
],
"id": "59da22823d04c95919d46269",
"challengeType": 5,
"releasedOn": "December 27, 2017",
"files": {
"indexjs": {
"key": "indexjs",
"ext": "js",
"name": "index",
"contents": [
"// noprotect",
"function splitCoconuts(intSailors) {",
" // Good luck!",
" return true;",
"}"
],
"head": [],
"tail": []
}
}
},
{
"title": "SEDOLs",
"null": [],
"description": [
" Task:",
"",
" ", " For each number list of 6-digit ", " SEDOLs,", " calculate and append the checksum digit.", "
", "", "", " That is, given the input string on the left, your function should return the", " corresponding string on the right:", "
", "", "", " 710889 => 7108899", " B0YBKJ => B0YBKJ7", " 406566 => 4065663", " B0YBLH => B0YBLH2", " 228276 => 2282765", " B0YBKL => B0YBKL9", " 557910 => 5579107", " B0YBKR => B0YBKR5", " 585284 => 5852842", " B0YBKT => B0YBKT7", " B00030 => B000300", "", "", "
",
" Check also that each input is correctly formed, especially",
" with respect to valid characters allowed in a SEDOL string. Your function",
" should return null
on invalid input.",
"
sedol
is a function.",
"testString": "assert(typeof sedol === 'function', 'sedol
is a function.');"
},
{
"text": "sedol('a')
should return null.\")",
"testString": "assert(sedol('a') === null, \"sedol('a')
should return null.\");"
},
{
"text": "sedol('710889')
should return '7108899'.\")",
"testString": "assert(sedol('710889') === '7108899', \"sedol('710889')
should return '7108899'.\");"
},
{
"text": "sedol('BOATER')
should return null.\")",
"testString": "assert(sedol('BOATER') === null, \"sedol('BOATER')
should return null.\");"
},
{
"text": "sedol('228276')
should return '2282765'.\")",
"testString": "assert(sedol('228276') === '2282765', \"sedol('228276')
should return '2282765'.\");"
}
],
"id": "59d9c6bc214c613ba73ff012",
"challengeType": 5,
"releasedOn": "December 27, 2017",
"files": {
"indexjs": {
"key": "indexjs",
"ext": "js",
"name": "index",
"contents": [
"function sedol (input) {",
" // Good luck!",
" return true;",
"}"
],
"head": [],
"tail": []
}
}
},
{
"title": "S-Expressions",
"description": [
"", "S-Expressions are one convenient way to parse and store data.", "
", "Task:", "", " Write a simple reader/parser for S-Expressions that handles quoted and unquoted strings, integers and floats.", "
", "", "The function should read a single but nested S-Expression from a string and", "return it as a (nested) array.", "
", "", " Newlines and other whitespace may be ignored unless contained within a quoted string.", "
", "“()” inside quoted strings are not interpreted, but treated as part of the string.", "
", "", "Handling escaped quotes inside a string is optional; thus “(foo\"bar)” maybe treated as a string “foo\"bar”, or as an error.", "
", "", "For this, the reader need not recognize “\\” for escaping, but should, in addition, recognize numbers if the language has appropriate datatypes.", "
", "", "Note that with the exception of “()\"” (“\\” if escaping is supported) and whitespace there are no special characters. Anything else is allowed without quotes.", "
", "The reader should be able to read the following input
", "", "
", " ((data \"quoted data\" 123 4.5)", " (data (!@# (4.5) \"(more\" \"data)\")))", "", "", "
", "and turn it into a native datastructure. (see the", "Pike, ", "Python and", "Ruby implementations", "for examples of native data structures.)", "
" ], "solutions": [ "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" ], "tests": [ { "text": "parseSexpr
is a function.",
"testString": "assert(typeof parseSexpr === 'function', 'parseSexpr
is a function.');"
},
{
"text": "parseSexpr('(data1 data2 data3)')
should return ['data1', 'data2', 'data3']\")",
"testString": "assert.deepEqual(parseSexpr(simpleSExpr), simpleSolution, \"parseSexpr('(data1 data2 data3)')
should return ['data1', 'data2', 'data3']\");"
},
{
"text": "parseSexpr('(data1 data2 data3)')
should return an array with 3 elements\")",
"testString": "assert.deepEqual(parseSexpr(basicSExpr), basicSolution, \"parseSexpr('(data1 data2 data3)')
should return an array with 3 elements\");"
}
],
"id": "59667989bf71cf555dd5d2ff",
"challengeType": 5,
"releasedOn": "December 27, 2017",
"files": {
"indexjs": {
"key": "indexjs",
"ext": "js",
"name": "index",
"contents": [
"function parseSexpr(str) {",
" // Good luck!",
" return true;",
"}"
],
"head": [],
"tail": [
"const simpleSExpr = '(data1 data2 data3)';",
"const simpleSolution = ['data1', 'data2', 'data3'];",
"",
"const basicSExpr = '((data \"quoted data\" 123 4.5) (data (!@# (4.5) \"(more\" \"data)\")))';",
"const basicSolution = [[\"data\",\"\\\"quoted data\\\"\",123,4.5],[\"data\",[\"!@#\",[4.5],\"\\\"(more\\\"\",\"\\\"data)\\\"\"]]];"
]
}
}
},
{
"title": "Taxicab numbers",
"description": [
"A taxicab number",
" (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:",
"13 + 123 and",
"93 + 103.",
"Taxicab numbers are also known as:",
" * taxi numbers",
" * taxi-cab numbers",
" * taxi cab numbers",
" * Hardy-Ramanujan numbers",
"Task:",
"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.",
" Hardy-Ramanujan Number on MathWorld.",
" taxicab number on MathWorld.",
" taxicab number on Wikipedia."
],
"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"
],
"tests": [
{
"text": "taxicabNumbers
is a function.",
"testString": "assert(typeof taxicabNumbers === 'function', 'taxicabNumbers
is a function.');"
},
{
"text": "taxicabNumbers
should return an array.",
"testString": "assert(typeof taxicabNumbers(2) === 'object', 'taxicabNumbers
should return an array.');"
},
{
"text": "taxicabNumbers
should return an array of numbers.",
"testString": "assert(typeof taxicabNumbers(100)[0] === 'number', 'taxicabNumbers
should return an array of numbers.');"
},
{
"text": "taxicabNumbers(4)
must return [1729, 4104, 13832, 20683].",
"testString": "assert.deepEqual(taxicabNumbers(4), res4, 'taxicabNumbers(4)
must return [1729, 4104, 13832, 20683].');"
},
{
"text": "taxicabNumbers(25) should return [1729, 4104, 13832, 20683, 32832, 39312, 40033, 46683, 64232, 65728, 110656, 110808, 134379, 149389, 165464, 171288, 195841, 216027, 216125, 262656, 314496, 320264, 327763, 373464, 402597]",
"testString": "assert.deepEqual(taxicabNumbers(25), res25, 'taxicabNumbers(25) should return [1729, 4104, 13832, 20683, 32832, 39312, 40033, 46683, 64232, 65728, 110656, 110808, 134379, 149389, 165464, 171288, 195841, 216027, 216125, 262656, 314496, 320264, 327763, 373464, 402597]');"
},
{
"text": "taxicabNumbers(39) resulting numbers from 20 - 29 should be [314496,320264,327763,373464,402597,439101,443889,513000,513856].",
"testString": "assert.deepEqual(taxicabNumbers(39).slice(20, 29), res39From20To29, 'taxicabNumbers(39) resulting numbers from 20 - 29 should be [314496,320264,327763,373464,402597,439101,443889,513000,513856].');"
}
],
"id": "594ecc0d9a8cf816e3340187",
"challengeType": 5,
"releasedOn": "December 27, 2017",
"files": {
"indexjs": {
"key": "indexjs",
"ext": "js",
"name": "index",
"contents": [
"function taxicabNumbers (n) {",
" // Good luck!",
" return true;",
"}"
],
"head": [],
"tail": [
"const res4 = [1729, 4104, 13832, 20683];",
"const res25 = [",
" 1729, 4104, 13832, 20683, 32832, 39312, 40033, 46683, 64232, 65728, 110656,",
" 110808, 134379, 149389, 165464, 171288, 195841, 216027, 216125, 262656, 314496, 320264, 327763,",
" 373464, 402597",
"];",
"",
"const res39From20To29 = [314496, 320264, 327763, 373464, 402597, 439101, 443889, 513000, 513856];"
]
}
}
},
{
"title": "Tokenize a string with escaping",
"description": [
"", "Write a function or program that can split a string at each non-escaped occurrence of a separator character.", "
", "", "It should accept three input parameters:", "
", " The string", " The separator character", " The escape character", "It should output a list of strings.
", "Rules for splitting:
", " 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.", "Rules for escaping:
", " \"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.", "Demonstrate that your function satisfies the following test-case:", " Given string
one^|uno||three^^^^|four^^^|^cuatro|and using", "
|as a separator and
^as escape character, your", " function should output the following array:", "", "
", " ['one|uno', '', 'three^^', 'four^|quatro', '']", "" ], "solutions": [ "// tokenize :: String -> Character -> Character -> [String]\nfunction tokenize(str, charDelim, charEsc) {\n const dctParse = str.split('')\n .reduce((a, x) => {\n const blnEsc = a.esc;\n const blnBreak = !blnEsc && x === charDelim;\n const blnEscChar = !blnEsc && x === charEsc;\n\n return {\n esc: blnEscChar,\n token: blnBreak ? '' : (\n a.token + (blnEscChar ? '' : x)\n ),\n list: a.list.concat(blnBreak ? a.token : [])\n };\n }, {\n esc: false,\n token: '',\n list: []\n });\n\n return dctParse.list.concat(\n dctParse.token\n );\n}\n" ], "tests": [ { "text": "
tokenize
is a function.",
"testString": "assert(typeof tokenize === 'function', 'tokenize
is a function.');"
},
{
"text": "tokenize
should return an array.",
"testString": "assert(typeof tokenize('a', 'b', 'c') === 'object', 'tokenize
should return an array.');"
},
{
"text": "tokenize('one^|uno||three^^^^|four^^^|^cuatro|', '|', '^')
should return ['one|uno', '', 'three^^', 'four^|cuatro', '']\")",
"testString": "assert.deepEqual(tokenize(testStr1, '|', '^'), res1, \"tokenize('one^|uno||three^^^^|four^^^|^cuatro|', '|', '^')
should return ['one|uno', '', 'three^^', 'four^|cuatro', '']\");"
},
{
"text": "tokenize('a@&bcd&ef&&@@hi', '&', '@')
should return ['a&bcd', 'ef', '', '@hi']
",
"testString": "assert.deepEqual(tokenize(testStr2, '&', '@'), res2, 'tokenize(\"a@&bcd&ef&&@@hi\", \"&\", \"@\")
should return [\"a&bcd\", \"ef\", \"\", \"@hi\"]
');"
}
],
"id": "594faaab4e2a8626833e9c3d",
"challengeType": 5,
"releasedOn": "December 27, 2017",
"files": {
"indexjs": {
"key": "indexjs",
"ext": "js",
"name": "index",
"contents": [
"function tokenize(str, esc, sep) {",
" return true;",
"}"
],
"head": [],
"tail": [
"const testStr1 = 'one^|uno||three^^^^|four^^^|^cuatro|';",
"const res1 = ['one|uno', '', 'three^^', 'four^|cuatro', ''];",
"",
"// TODO add more tests",
"const testStr2 = 'a@&bcd&ef&&@@hi';",
"const res2 = ['a&bcd', 'ef', '', '@hi'];"
]
}
}
},
{
"title": "Topological sort",
"description": [
"", "Given a mapping between items, and items they depend on, a ", "topological sort orders ", "items so that no item precedes an item it depends upon.", "
", "", "The compiling of a library in the ", "VHDL language", "has the constraint that a library must be compiled after any library it depends on.", "
", "Task:", "", "Write a function that will return a valid compile order of VHDL libraries from their dependencies.", "
", " Assume library names are single words. ", " Items mentioned as only dependents have no dependents of their own, but their order of compiling must be given.", " Any self dependencies should be ignored. ", " Any un-orderable dependencies should be ignored.", "Use the following data as an example:
", "", "LIBRARY LIBRARY DEPENDENCIES", "======= ====================", "des_system_lib std synopsys std_cell_lib des_system_lib dw02 dw01 ramlib ieee", "dw01 ieee dw01 dware gtech", "dw02 ieee dw02 dware", "dw03 std synopsys dware dw03 dw02 dw01 ieee gtech", "dw04 dw04 ieee dw01 dware gtech", "dw05 dw05 ieee dware", "dw06 dw06 ieee dware", "dw07 ieee dware", "dware ieee dware", "gtech ieee gtech", "ramlib std ieee", "std_cell_lib ieee std_cell_lib", "synopsys", "", "
",
"Note: the above data would be un-orderable if, for example, dw04
is added to the list of dependencies of dw01
.",
"
There are two popular algorithms for topological sorting:
", "", " Kahn's 1962 topological sort, and depth-first search:", " topological sort", "
", "", " Jason Sachs:", " ", " \"Ten little algorithms, part 4: topological sort\"", " .", "
" ], "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" ], "tests": [ { "text": "topologicalSort
is a function.",
"testString": "assert(typeof topologicalSort === 'function', 'topologicalSort
is a function.');"
},
{
"text": "topologicalSort
must return correct library order..",
"testString": "assert.deepEqual(topologicalSort(libsSimple), ['bbb', 'aaa'], 'topologicalSort
must return correct library order..');"
},
{
"text": "topologicalSort
must return correct library order..",
"testString": "assert.deepEqual(topologicalSort(libsVHDL), solutionVHDL, 'topologicalSort
must return correct library order..');"
},
{
"text": "topologicalSort
must return correct library order..",
"testString": "assert.deepEqual(topologicalSort(libsCustom), solutionCustom, 'topologicalSort
must return correct library order..');"
},
{
"text": "topologicalSort
must ignore unorderable dependencies..",
"testString": "assert.deepEqual(topologicalSort(libsUnorderable), solutionUnorderable, 'topologicalSort
must ignore unorderable dependencies..');"
}
],
"id": "594fa2746886f41f7d8bf225",
"challengeType": 5,
"releasedOn": "December 27, 2017",
"files": {
"indexjs": {
"key": "indexjs",
"ext": "js",
"name": "index",
"contents": [
"function topologicalSort(libs) {",
" // Good luck!",
" return true;",
"}"
],
"head": [],
"tail": [
"const libsSimple =",
" `aaa bbb",
" bbb`;",
"",
"const libsVHDL =",
" `des_system_lib std synopsys std_cell_lib des_system_lib dw02 dw01 ramlib ieee",
" dw01 ieee dw01 dware gtech",
" dw02 ieee dw02 dware",
" dw03 std synopsys dware dw03 dw02 dw01 ieee gtech",
" dw04 dw04 ieee dw01 dware gtech",
" dw05 dw05 ieee dware",
" dw06 dw06 ieee dware",
" dw07 ieee dware",
" dware ieee dware",
" gtech ieee gtech",
" ramlib std ieee",
" std_cell_lib ieee std_cell_lib",
" synopsys`;",
"",
"const solutionVHDL = [",
" 'ieee', 'std_cell_lib', 'gtech', 'dware', 'dw07', 'dw06',",
" 'dw05', 'dw02', 'dw01', 'dw04', 'std', 'ramlib', 'synopsys',",
" 'dw03', 'des_system_lib'",
"];",
"",
"const libsCustom =",
" `a b c d",
" b c d",
" d c",
" c base",
" base`;",
"const solutionCustom = ['base', 'c', 'd', 'b', 'a'];",
"",
"const libsUnorderable =",
" `TestLib Base MainLib",
" MainLib TestLib",
" Base`;",
"",
"const solutionUnorderable = ['Base'];"
]
}
}
},
{
"title": "Top rank per group",
"description": [
"Task:",
"Find the top N ranked data in each group, where N is provided as a parameter. Name of the rank and the group are also provided as parameter.
", "Given the following data:", "", "[", " { name: 'Tyler Bennett', id: 'E10297', salary: 32000, dept: 'D101' },", " { name: 'John Rappl', id: 'E21437', salary: 47000, dept: 'D050' },", " { name: 'George Woltman', id: 'E00127', salary: 53500, dept: 'D101' },", " { name: 'Adam Smith', id: 'E63535', salary: 18000, dept: 'D202' },", " { name: 'Claire Buckman', id: 'E39876', salary: 27800, dept: 'D202' },", " { name: 'David McClellan', id: 'E04242', salary: 41500, dept: 'D101' },", " { name: 'Rich Holcomb', id: 'E01234', salary: 49500, dept: 'D202' },", " { name: 'Nathan Adams', id: 'E41298', salary: 21900, dept: 'D050' },", " { name: 'Richard Potter', id: 'E43128', salary: 15900, dept: 'D101' },", " { name: 'David Motsinger', id: 'E27002', salary: 19250, dept: 'D202' },", " { name: 'Tim Sampair', id: 'E03033', salary: 27000, dept: 'D101' },", " { name: 'Kim Arlich', id: 'E10001', salary: 57000, dept: 'D190' },", " { name: 'Timothy Grove', id: 'E16398', salary: 29900, dept: 'D190' }", "];", "", "one could rank top 10 employees in each department by calling", "
topRankPerGroup(10, data, 'dept', 'salary')
",
"Given the following data:",
"", "[", " { name: 'Friday 13th', genre: 'horror', rating: 9.9 },", " { name: \"Nightmare on Elm's Street\", genre: 'horror', rating: 5.7 },", " { name: 'Titanic', genre: 'drama', rating: 7.3 },", " { name: 'Maze Runner', genre: 'scifi', rating: 7.1 },", " { name: 'Blade runner', genre: 'scifi', rating: 8.9 }", "];", "", "one could rank the top-rated movie in each genre by calling", "
topRankPerGroup(1, data, 'genre', 'rating')
"
],
"solutions": [
"const collectDept = function (arrOfObj, groupName) {\n const collect = arrOfObj.reduce((rtnObj, obj) => {\n if (rtnObj[obj[groupName]] === undefined) {\n rtnObj[obj[groupName]] = [];\n }\n rtnObj[obj[groupName]].push(obj);\n return rtnObj;\n }, {} // initial value to reduce\n );\n\n return Object.keys(collect).sort().map(key => collect[key]);\n};\n\nconst sortRank = function (arrOfRankArrs, rankName) {\n return arrOfRankArrs.map(item => item.sort((a, b) => {\n if (a[rankName] > b[rankName]) { return -1; }\n if (a[rankName] < b[rankName]) { return 1; }\n return 0;\n }));\n};\n\nfunction topRankPerGroup(n, data, groupName, rankName) {\n if (n < 0) { return; }\n return sortRank(collectDept(data, groupName),\n rankName).map(list => list.slice(0, n));\n}\n"
],
"tests": [
{
"text": "topRankPerGroup
is a function.",
"testString": "assert(typeof topRankPerGroup === 'function', 'topRankPerGroup
is a function.');"
},
{
"text": "topRankPerGroup
returns undefined on negative n values.",
"testString": "assert(typeof topRankPerGroup(-1, []) === 'undefined', 'topRankPerGroup
returns undefined on negative n values.');"
},
{
"text": "First department must be D050",
"testString": "assert.equal(res1[0][0].dept, 'D050', 'First department must be D050');"
},
{
"text": "First department must be D050",
"testString": "assert.equal(res1[0][1].salary, 21900, 'First department must be D050');"
},
{
"text": "The last department must be D202",
"testString": "assert.equal(res1[3][3].dept, 'D202', 'The last department must be D202');"
},
{
"text": "topRankPerGroup(1, ...)
must return only top ranking result per group.",
"testString": "assert.equal(res2[2].length, 1, 'topRankPerGroup(1, ...)
must return only top ranking result per group.');"
},
{
"text": "topRankPerGroup(1, ...)
must return only top ranking result per group.",
"testString": "assert.equal(res3[2][1].name, 'Maze Runner', 'topRankPerGroup(1, ...)
must return only top ranking result per group.');"
}
],
"id": "595011cba5a81735713873bd",
"challengeType": 5,
"releasedOn": "December 27, 2017",
"files": {
"indexjs": {
"key": "indexjs",
"ext": "js",
"name": "index",
"contents": [
"function topRankPerGroup(n, data, groupName, rankName) {",
" // Good luck!",
" return true;",
"}"
],
"head": [],
"tail": [
"const testData1 = [",
" { name: 'Tyler Bennett', id: 'E10297', salary: 32000, dept: 'D101' },",
" { name: 'John Rappl', id: 'E21437', salary: 47000, dept: 'D050' },",
" { name: 'George Woltman', id: 'E00127', salary: 53500, dept: 'D101' },",
" { name: 'Adam Smith', id: 'E63535', salary: 18000, dept: 'D202' },",
" { name: 'Claire Buckman', id: 'E39876', salary: 27800, dept: 'D202' },",
" { name: 'David McClellan', id: 'E04242', salary: 41500, dept: 'D101' },",
" { name: 'Rich Holcomb', id: 'E01234', salary: 49500, dept: 'D202' },",
" { name: 'Nathan Adams', id: 'E41298', salary: 21900, dept: 'D050' },",
" { name: 'Richard Potter', id: 'E43128', salary: 15900, dept: 'D101' },",
" { name: 'David Motsinger', id: 'E27002', salary: 19250, dept: 'D202' },",
" { name: 'Tim Sampair', id: 'E03033', salary: 27000, dept: 'D101' },",
" { name: 'Kim Arlich', id: 'E10001', salary: 57000, dept: 'D190' },",
" { name: 'Timothy Grove', id: 'E16398', salary: 29900, dept: 'D190' }",
"];",
"",
"const res1 = topRankPerGroup(10, testData1, 'dept', 'salary');",
"",
"const testData2 = [",
" { name: 'Friday 13th', genre: 'horror', rating: 9.9 },",
" { name: \"Nightmare on Elm's Street\", genre: 'horror', rating: 5.7 },",
" { name: 'Titanic', genre: 'drama', rating: 7.3 },",
" { name: 'Maze Runner', genre: 'scifi', rating: 7.1 },",
" { name: 'Blade runner', genre: 'scifi', rating: 8.9 }",
"];",
"",
"const res2 = topRankPerGroup(1, testData2, 'genre', 'rating');",
"const res3 = topRankPerGroup(2, testData2, 'genre', 'rating');",
"",
"//console.log(JSON.stringify(topRankPerGroup(10, testData1)));"
]
}
}
},
{
"title": "Towers of Hanoi",
"description": [
" Task:",
"Solve the Towers of Hanoi problem.
", "",
"Your solution should accept the number of discs as the first parameters, and",
"three string used to identify each of the three stacks of discs, for example",
"towerOfHanoi(4, 'A', 'B', 'C')
. The function should return an",
"array of arrays containing the list of moves, source -> destination. For",
"example, the array [['A', 'C'], ['B', 'A']]
indicates that the",
"1st move was to move a disc from stack A to C, and the 2nd move was to move a",
"disc from stack B to A.",
"
towerOfHanoi
is a function.",
"testString": "assert(typeof towerOfHanoi === 'function', 'towerOfHanoi
is a function.');"
},
{
"text": "towerOfHanoi(3, ...)
should return 7 moves.",
"testString": "assert(res3.length === 7, 'towerOfHanoi(3, ...)
should return 7 moves.');"
},
{
"text": "towerOfHanoi(3, 'A', 'B', 'C')
should return [['A','B'],['A','C'],['B','C'],['A','B'],['C','A'],['C','B'],['A','B']].\")",
"testString": "assert.deepEqual(towerOfHanoi(3, 'A', 'B', 'C'), res3Moves, \"towerOfHanoi(3, 'A', 'B', 'C')
should return [['A','B'],['A','C'],['B','C'],['A','B'],['C','A'],['C','B'],['A','B']].\");"
},
{
"text": "towerOfHanoi(5, \"X\", \"Y\", \"Z\")
10th move should be Y -> X.",
"testString": "assert.deepEqual(res5[9], ['Y', 'X'], 'towerOfHanoi(5, \"X\", \"Y\", \"Z\")
10th move should be Y -> X.');"
},
{
"text": "towerOfHanoi(7, 'A', 'B', 'C')
first ten moves are [['A','B'],['A','C'],['B','C'],['A','B'],['C','A'],['C','B'],['A','B'],['A','C'],['B','C'],['B','A']].\")",
"testString": "assert.deepEqual(towerOfHanoi(7, 'A', 'B', 'C').slice(0, 10), res7First10Moves, \"towerOfHanoi(7, 'A', 'B', 'C')
first ten moves are [['A','B'],['A','C'],['B','C'],['A','B'],['C','A'],['C','B'],['A','B'],['A','C'],['B','C'],['B','A']].\");"
}
],
"id": "5951ed8945deab770972ae56",
"challengeType": 5,
"releasedOn": "December 27, 2017",
"files": {
"indexjs": {
"key": "indexjs",
"ext": "js",
"name": "index",
"contents": [
"function towerOfHanoi (n, a, b, c) {",
" // Good luck!",
" return [[]];",
"}"
],
"head": [],
"tail": [
"const res3 = towerOfHanoi(3, 'A', 'B', 'C');",
"const res3Moves = [['A', 'B'], ['A', 'C'], ['B', 'C'], ['A', 'B'], ['C', 'A'], ['C', 'B'], ['A', 'B']];",
"const res5 = towerOfHanoi(5, 'X', 'Y', 'Z');",
"const res7First10Moves = [['A', 'B'], ['A', 'C'], ['B', 'C'], ['A', 'B'], ['C', 'A'], ['C', 'B'], ['A', 'B'], ['A', 'C'], ['B', 'C'], ['B', 'A']];"
]
}
}
},
{
"title": "Vector cross product",
"description": [
"A vector is defined as having three dimensions as being represented by an ordered collection of three numbers: (X, Y, Z).",
"",
"Task:",
"",
" Write a function that takes two vectors (arrays) as input and computes their cross product.",
"",
"Your function should return null
on",
"invalid inputs (ie vectors of different lengths).",
"
", "A vector is defined as having three dimensions as being represented by an ordered collection of three numbers: (X, Y, Z).", "
", "",
"Task:",
"",
" Write a function that takes any numbers of vectors (arrays) as input and computes their dot product.",
"",
"Your function should return null
on",
"invalid inputs (ie vectors of different lengths).",
"
dotProduct(...nVectors)
should return 156000",
"testString": "assert.equal(dotProduct([ 0, 1, 2, 3, 4 ], [ 0, 2, 4, 6, 8 ], [ 0, 3, 6, 9, 12 ], [ 0, 4, 8, 12, 16 ], [ 0, 5, 10, 15, 20 ]), 156000, 'dotProduct(...nVectors)
should return 156000');"
}
],
"id": "594810f028c0303b75339ad3",
"challengeType": 5,
"releasedOn": "December 27, 2017",
"files": {
"indexjs": {
"key": "indexjs",
"ext": "js",
"name": "index",
"contents": [
"function dotProduct() {",
" // Good luck!",
"}"
],
"head": [],
"tail": []
}
}
},
{
"title": "Word wrap",
"description": [
"", "Even today, with proportional fonts and complex layouts, there are still", "cases where you need to wrap text at a specified", "column. The basic task is to wrap a paragraph of text in a simple way.", "Example text:", "
", "", "Wrap text using a more sophisticated algorithm such as the Knuth and Plass TeX algorithm.", "If your language provides this, you get easy extra credit,", "but you ''must reference documentation'' indicating that the algorithm", "is something better than a simple minimimum length algorithm.", "", "
", "Task:", "", " Write a function that can wrap this text to any number of characters.", "", "As an example, the text wrapped to 80 characters should look like the following:", "
", "", "Wrap text using a more sophisticated algorithm such as the Knuth and Plass TeX", "algorithm. If your language provides this, you get easy extra credit, but you", "must reference documentation indicating that the algorithm is something better", "than a simple minimimum length algorithm.", "" ], "solutions": [ "function wrap (text, limit) {\n const noNewlines = text.replace('\\n', '');\n if (noNewlines.length > limit) {\n // find the last space within limit\n const edge = noNewlines.slice(0, limit).lastIndexOf(' ');\n if (edge > 0) {\n const line = noNewlines.slice(0, edge);\n const remainder = noNewlines.slice(edge + 1);\n return line + '\\n' + wrap(remainder, limit);\n }\n }\n return text;\n}\n" ], "tests": [ { "text": "wrap must be a function.", "testString": "assert.equal(typeof wrap, 'function', 'wrap must be a function.');" }, { "text": "wrap must return a string.", "testString": "assert.equal(typeof wrap('abc', 10), 'string', 'wrap must return a string.');" }, { "text": "wrap(80) must return 4 lines.", "testString": "assert(wrapped80.split('\\n').length === 4, 'wrap(80) must return 4 lines.');" }, { "text": "Your
wrap
function should return our expected text",
"testString": "assert.equal(wrapped80.split('\\n')[0], firstRow80, 'Your wrap
function should return our expected text');"
},
{
"text": "wrap(42) must return 7 lines.",
"testString": "assert(wrapped42.split('\\n').length === 7, 'wrap(42) must return 7 lines.');"
},
{
"text": "Your wrap
function should return our expected text",
"testString": "assert.equal(wrapped42.split('\\n')[0], firstRow42, 'Your wrap
function should return our expected text');"
}
],
"id": "594810f028c0303b75339ad4",
"challengeType": 5,
"releasedOn": "December 27, 2017",
"files": {
"indexjs": {
"key": "indexjs",
"ext": "js",
"name": "index",
"contents": [
"function wrap (text, limit) {",
" return text;",
"}"
],
"head": [],
"tail": [
"const text =",
"`Wrap text using a more sophisticated algorithm such as the Knuth and Plass TeX algorithm.",
"If your language provides this, you get easy extra credit,",
"but you ''must reference documentation'' indicating that the algorithm",
"is something better than a simple minimimum length algorithm.`;",
"",
"const wrapped80 = wrap(text, 80);",
"const wrapped42 = wrap(text, 42);",
"",
"const firstRow80 =",
" 'Wrap text using a more sophisticated algorithm such as the Knuth and Plass TeX';",
"",
"const firstRow42 = 'Wrap text using a more sophisticated';"
]
}
}
},
{
"title": "Y combinator",
"description": [
"", "In strict ", "functional programming and", "the lambda calculus, ", "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.", "
", "", "The Y combinator 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 ", "fixed-point combinators.", "
", "Task:", "", " Define the stateless Y combinator function and use it to compute", " factorial.", "", "factorial(N)
function is already given to you.",
"See also Jim Weirich: Adventures in Functional Programming."
],
"solutions": [
"var Y = f => (x => x(x))(y => f(x => y(y)(x)));\n"
],
"tests": [
{
"text": "Y must return a function",
"testString": "assert.equal(typeof Y(f => n => n), 'function', 'Y must return a function');"
},
{
"text": "factorial(1) must return 1.",
"testString": "assert.equal(factorial(1), 1, 'factorial(1) must return 1.');"
},
{
"text": "factorial(2) must return 2.",
"testString": "assert.equal(factorial(2), 2, 'factorial(2) must return 2.');"
},
{
"text": "factorial(3) must return 6.",
"testString": "assert.equal(factorial(3), 6, 'factorial(3) must return 6.');"
},
{
"text": "factorial(4) must return 24.",
"testString": "assert.equal(factorial(4), 24, 'factorial(4) must return 24.');"
},
{
"text": "factorial(10) must return 3628800.",
"testString": "assert.equal(factorial(10), 3628800, 'factorial(10) must return 3628800.');"
}
],
"id": "594810f028c0303b75339ad5",
"challengeType": 5,
"releasedOn": "December 27, 2017",
"files": {
"indexjs": {
"key": "indexjs",
"ext": "js",
"name": "index",
"contents": [
"function Y(f) {",
" return function() {",
" // Good luck!",
" };",
"}",
"",
"var factorial = Y(function(f) {",
" return function (n) {",
" return n > 1 ? n * f(n - 1) : 1;",
" };",
"});"
],
"head": [],
"tail": [
"var factorial = Y(f => n => (n > 1 ? n * f(n - 1) : 1));"
]
}
}
},
{
"title": "Zeckendorf number representation",
"description": [
"", "Just as numbers can be represented in a", "positional notation as sums of multiples of the powers of ten (decimal)", "or two (binary); all the positive integers can be represented as the sum", "of one or zero times the distinct members of the Fibonacci series.", "
", "",
"Recall that the first six distinct Fibonacci",
"numbers are: 1, 2, 3, 5, 8, 13
. The decimal number eleven can",
"be written as 0*13 + 1*8 + 0*5 + 1*3 + 0*2 + 0*1
or",
"010100
in positional notation where the columns represent",
"multiplication by a particular member of the sequence. Leading zeroes are",
"dropped so that 11 decimal becomes 10100
.",
"
",
"10100 is not the only way to make 11 from the Fibonacci numbers however",
"0*13 + 1*8 + 0*5 + 0*3 + 1*2 + 1*1
or 010011 would also",
"represent decimal 11. For a true Zeckendorf number there is the added",
"restriction that ''no two consecutive Fibonacci numbers can be used''",
"which leads to the former unique solution.",
"
", " Task:", " Write a function that generates and returns an array of first N Zeckendorf numbers in order.", "
" ], "solutions": [ "// zeckendorf :: Int -> String\nfunction zeckendorf(n) {\n const f = (m, x) => (m < x ? [m, 0] : [m - x, 1]);\n return (n === 0 ? ([0]) :\n mapAccumL(f, n, reverse(\n tail(fibUntil(n))\n ))[1]).join('');\n}\n\n// fibUntil :: Int -> [Int]\nlet fibUntil = n => {\n const xs = [];\n until(\n ([a]) => a > n,\n ([a, b]) => (xs.push(a), [b, a + b]), [1, 1]\n );\n return xs;\n};\n\nlet mapAccumL = (f, acc, xs) => (\n xs.reduce((a, x) => {\n const pair = f(a[0], x);\n\n return [pair[0], a[1].concat(pair[1])];\n }, [acc, []])\n);\n\nlet until = (p, f, x) => {\n let v = x;\n while (!p(v)) v = f(v);\n return v;\n};\n\nconst tail = xs => (\n xs.length ? xs.slice(1) : undefined\n);\n\nconst reverse = xs => xs.slice(0).reverse();\n" ], "tests": [ { "text": "zeckendorf must be function", "testString": "assert.equal(typeof zeckendorf, 'function', 'zeckendorf must be function');" }, { "text": "Yourzeckendorf
function should return the correct answer",
"testString": "assert.deepEqual(answer, solution20, 'Your zeckendorf
function should return the correct answer');"
}
],
"id": "594810f028c0303b75339ad6",
"challengeType": 5,
"releasedOn": "December 27, 2017",
"files": {
"indexjs": {
"key": "indexjs",
"ext": "js",
"name": "index",
"contents": [
"function zeckendorf(n) {",
" // good luck!",
"}"
],
"head": [],
"tail": [
"const range = (m, n) => (",
" Array.from({",
" length: Math.floor(n - m) + 1",
" }, (_, i) => m + i)",
");",
"",
"const solution20 = [",
" '1', '10', '100', '101', '1000', '1001', '1010', '10000', '10001',",
" '10010', '10100', '10101', '100000', '100001', '100010', '100100', '100101',",
" '101000', '101001', '101010'",
"];",
"",
"const answer = range(1, 20).map(zeckendorf);"
]
}
}
},
{
"title": "Zhang-Suen thinning algorithm",
"description": [
"This is an algorithm used to thin a black and white i.e. one bit per pixel images.",
"For example, with an input image of:",
"", " ################# #############", " ################## ################", " ################### ##################", " ######## ####### ###################", " ###### ####### ####### ######", " ###### ####### #######", " ################# #######", " ################ #######", " ################# #######", " ###### ####### #######", " ###### ####### #######", " ###### ####### ####### ######", " ######## ####### ###################", " ######## ####### ###### ################## ######", " ######## ####### ###### ################ ######", " ######## ####### ###### ############# ######", "", "It produces the thinned output:", "
", "", " # ########## #######", " ## # #### #", " # # ##", " # # #", " # # #", " # # #", " ############ #", " # # #", " # # #", " # # #", " # # #", " # ##", " # ############", " ### ###", "", "", "
P9 | P2 | P3 |
P8 | P1 | P4 |
P7 | P6 | P5 |
", "Task:", "Write a routine to perform Zhang-Suen thinning on an image matrix of ones and zeroes.", "
" ], "solutions": [ "function Point(x, y) {\n this.x = x;\n this.y = y;\n}\n\nconst ZhangSuen = (function () {\n function ZhangSuen() {\n }\n\n ZhangSuen.nbrs = [[0, -1], [1, -1], [1, 0], [1, 1], [0, 1], [-1, 1], [-1, 0], [-1, -1], [0, -1]];\n\n ZhangSuen.nbrGroups = [[[0, 2, 4], [2, 4, 6]], [[0, 2, 6], [0, 4, 6]]];\n\n ZhangSuen.toWhite = [];\n\n ZhangSuen.main = function (image) {\n ZhangSuen.grid = new Array(image);\n for (let r = 0; r < image.length; r++) {\n ZhangSuen.grid[r] = image[r].split('');\n }\n ZhangSuen.thinImage();\n return ZhangSuen.getResult();\n };\n\n ZhangSuen.thinImage = function () {\n let firstStep = false;\n let hasChanged;\n do {\n hasChanged = false;\n firstStep = !firstStep;\n for (let r = 1; r < ZhangSuen.grid.length - 1; r++) {\n for (let c = 1; c < ZhangSuen.grid[0].length - 1; c++) {\n if (ZhangSuen.grid[r][c] !== '#') {\n continue;\n }\n const nn = ZhangSuen.numNeighbors(r, c);\n if (nn < 2 || nn > 6) {\n continue;\n }\n if (ZhangSuen.numTransitions(r, c) !== 1) {\n continue;\n }\n if (!ZhangSuen.atLeastOneIsWhite(r, c, firstStep ? 0 : 1)) {\n continue;\n }\n ZhangSuen.toWhite.push(new Point(c, r));\n hasChanged = true;\n }\n }\n for (let i = 0; i < ZhangSuen.toWhite.length; i++) {\n const p = ZhangSuen.toWhite[i];\n ZhangSuen.grid[p.y][p.x] = ' ';\n }\n ZhangSuen.toWhite = [];\n } while ((firstStep || hasChanged));\n };\n\n ZhangSuen.numNeighbors = function (r, c) {\n let count = 0;\n for (let i = 0; i < ZhangSuen.nbrs.length - 1; i++) {\n if (ZhangSuen.grid[r + ZhangSuen.nbrs[i][1]][c + ZhangSuen.nbrs[i][0]] === '#') {\n count++;\n }\n }\n return count;\n };\n\n ZhangSuen.numTransitions = function (r, c) {\n let count = 0;\n for (let i = 0; i < ZhangSuen.nbrs.length - 1; i++) {\n if (ZhangSuen.grid[r + ZhangSuen.nbrs[i][1]][c + ZhangSuen.nbrs[i][0]] === ' ') {\n if (ZhangSuen.grid[r + ZhangSuen.nbrs[i + 1][1]][c + ZhangSuen.nbrs[i + 1][0]] === '#') {\n count++;\n }\n }\n }\n return count;\n };\n\n ZhangSuen.atLeastOneIsWhite = function (r, c, step) {\n let count = 0;\n const group = ZhangSuen.nbrGroups[step];\n for (let i = 0; i < 2; i++) {\n for (let j = 0; j < group[i].length; j++) {\n const nbr = ZhangSuen.nbrs[group[i][j]];\n if (ZhangSuen.grid[r + nbr[1]][c + nbr[0]] === ' ') {\n count++;\n break;\n }\n }\n }\n return count > 1;\n };\n\n ZhangSuen.getResult = function () {\n const result = [];\n for (let i = 0; i < ZhangSuen.grid.length; i++) {\n const row = ZhangSuen.grid[i].join('');\n result.push(row);\n }\n return result;\n };\n return ZhangSuen;\n}());\n\nfunction thinImage(image) {\n return ZhangSuen.main(image);\n}\n" ], "tests": [ { "text": "thinImage
must be a function",
"testString": "assert.equal(typeof thinImage, 'function', 'thinImage
must be a function');"
},
{
"text": "thinImage
must return an array",
"testString": "assert(Array.isArray(result), 'thinImage
must return an array');"
},
{
"text": "thinImage
must return an array of strings",
"testString": "assert.equal(typeof result[0], 'string', 'thinImage
must return an array of strings');"
},
{
"text": "thinImage
must return an array of strings",
"testString": "assert.deepEqual(result, expected, 'thinImage
must return an array of strings');"
}
],
"id": "594810f028c0303b75339ad7",
"challengeType": 5,
"releasedOn": "December 27, 2017",
"files": {
"indexjs": {
"key": "indexjs",
"ext": "js",
"name": "index",
"contents": [
"const testImage = [",
" ' ',",
" ' ################# ############# ',",
" ' ################## ################ ',",
" ' ################### ################## ',",
" ' ######## ####### ################### ',",
" ' ###### ####### ####### ###### ',",
" ' ###### ####### ####### ',",
" ' ################# ####### ',",
" ' ################ ####### ',",
" ' ################# ####### ',",
" ' ###### ####### ####### ',",
" ' ###### ####### ####### ',",
" ' ###### ####### ####### ###### ',",
" ' ######## ####### ################### ',",
" ' ######## ####### ###### ################## ###### ',",
" ' ######## ####### ###### ################ ###### ',",
" ' ######## ####### ###### ############# ###### ',",
" ' '];",
"",
"function thinImage(image) {",
" // Good luck!",
"}"
],
"head": [],
"tail": [
"const imageForTests = [",
" ' ',",
" ' ################# ############# ',",
" ' ################## ################ ',",
" ' ################### ################## ',",
" ' ######## ####### ################### ',",
" ' ###### ####### ####### ###### ',",
" ' ###### ####### ####### ',",
" ' ################# ####### ',",
" ' ################ ####### ',",
" ' ################# ####### ',",
" ' ###### ####### ####### ',",
" ' ###### ####### ####### ',",
" ' ###### ####### ####### ###### ',",
" ' ######## ####### ################### ',",
" ' ######## ####### ###### ################## ###### ',",
" ' ######## ####### ###### ################ ###### ',",
" ' ######## ####### ###### ############# ###### ',",
" ' '];",
"const expected = [",
" ' ',",
" ' ',",
" ' # ########## ####### ',",
" ' ## # #### # ',",
" ' # # ## ',",
" ' # # # ',",
" ' # # # ',",
" ' # # # ',",
" ' ############ # ',",
" ' # # # ',",
" ' # # # ',",
" ' # # # ',",
" ' # # # ',",
" ' # ## ',",
" ' # ############ ',",
" ' ### ### ',",
" ' ',",
" ' '",
"];",
"const result = thinImage(imageForTests);"
]
}
}
},
{
"title": "Zig-zag matrix",
"description": [
"A ''zig-zag'' array is a square arrangement of the first ",
"$N^2$ integers, where the",
"numbers increase sequentially as you zig-zag along the array's ",
"anti-diagonals.",
"For example, given '''5''', produce this array:",
"", " 0 1 5 6 14", " 2 4 7 13 15", " 3 8 12 16 21", " 9 11 17 20 22", "10 18 19 23 24", "", "Write a function that takes the size of the zig-zag matrix, and returns the", "corresponding matrix as two-dimensional array." ], "solutions": [ "function ZigZagMatrix(n) {\n const mtx = [];\n for (let i = 0; i < n; i++) {\n mtx[i] = [];\n }\n\n let i = 1;\n let j = 1;\n for (let e = 0; e < n * n; e++) {\n mtx[i - 1][j - 1] = e;\n if ((i + j) % 2 === 0) {\n // Even stripes\n if (j < n) j++;\n else i += 2;\n if (i > 1) i--;\n } else {\n // Odd stripes\n if (i < n) i++;\n else j += 2;\n if (j > 1) j--;\n }\n }\n return mtx;\n}\n" ], "tests": [ { "text": "ZigZagMatrix must be a function", "testString": "assert.equal(typeof ZigZagMatrix, 'function', 'ZigZagMatrix must be a function');" }, { "text": "ZigZagMatrix should return array", "testString": "assert.equal(typeof ZigZagMatrix(1), 'object', 'ZigZagMatrix should return array');" }, { "text": "ZigZagMatrix should return an array of nestes arrays", "testString": "assert.equal(typeof ZigZagMatrix(1)[0], 'object', 'ZigZagMatrix should return an array of nestes arrays');" }, { "text": "ZigZagMatrix(1) should return [[0]]", "testString": "assert.deepEqual(ZigZagMatrix(1), zm1, 'ZigZagMatrix(1) should return [[0]]');" }, { "text": "ZigZagMatrix(2) should return [[0, 1], [2, 3]]", "testString": "assert.deepEqual(ZigZagMatrix(2), zm2, 'ZigZagMatrix(2) should return [[0, 1], [2, 3]]');" }, { "text": "ZigZagMatrix(5) must return specified matrix", "testString": "assert.deepEqual(ZigZagMatrix(5), zm5, 'ZigZagMatrix(5) must return specified matrix');" } ], "id": "594810f028c0303b75339ad8", "challengeType": 5, "releasedOn": "December 27, 2017", "files": { "indexjs": { "key": "indexjs", "ext": "js", "name": "index", "contents": [ "function ZigZagMatrix(n) {", " // Good luck!", " return [[], []];", "}" ], "head": [], "tail": [ "const zm1 = [[0]];", "const zm2 = [[0, 1], [2, 3]];", "const zm5 = [", " [0, 1, 5, 6, 14],", " [2, 4, 7, 13, 15],", " [3, 8, 12, 16, 21],", " [9, 11, 17, 20, 22],", " [10, 18, 19, 23, 24]", "];" ] } } } ] }