chore(i8n,learn): processed translations
This commit is contained in:
committed by
Mrugesh Mohapatra
parent
15047f2d90
commit
e5c44a3ae5
@ -0,0 +1,67 @@
|
||||
---
|
||||
id: 594810f028c0303b75339acb
|
||||
title: 100 doors
|
||||
challengeType: 5
|
||||
forumTopicId: 302217
|
||||
dashedName: 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.
|
||||
|
||||
# --instructions--
|
||||
|
||||
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.
|
||||
|
||||
# --hints--
|
||||
|
||||
`getFinalOpenedDoors` should be a function.
|
||||
|
||||
```js
|
||||
assert(typeof getFinalOpenedDoors === 'function');
|
||||
```
|
||||
|
||||
`getFinalOpenedDoors` should return an array.
|
||||
|
||||
```js
|
||||
assert(Array.isArray(getFinalOpenedDoors(100)));
|
||||
```
|
||||
|
||||
`getFinalOpenedDoors` should produce the correct result.
|
||||
|
||||
```js
|
||||
assert.deepEqual(getFinalOpenedDoors(100), solution);
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --after-user-code--
|
||||
|
||||
```js
|
||||
const solution = [1, 4, 9, 16, 25, 36, 49, 64, 81, 100];
|
||||
```
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```js
|
||||
function getFinalOpenedDoors(numDoors) {
|
||||
|
||||
}
|
||||
```
|
||||
|
||||
# --solutions--
|
||||
|
||||
```js
|
||||
function getFinalOpenedDoors(numDoors) {
|
||||
// this is the final pattern (always squares).
|
||||
// thus, the most efficient solution simply returns an array of squares up to numDoors).
|
||||
const finalState = [];
|
||||
let i = 1;
|
||||
while (Math.pow(i, 2) <= numDoors) {
|
||||
finalState.push(Math.pow(i, 2));
|
||||
i++;
|
||||
}
|
||||
return finalState;
|
||||
}
|
||||
```
|
@ -0,0 +1,203 @@
|
||||
---
|
||||
id: 5951e88f64ebf159166a1176
|
||||
title: 24 game
|
||||
challengeType: 5
|
||||
forumTopicId: 302218
|
||||
dashedName: 24-game
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
The [24 Game](https://en.wikipedia.org/wiki/24_Game) tests a person's mental arithmetic.
|
||||
|
||||
The aim of the game is to arrange four numbers in a way that when evaluated, the result is 24
|
||||
|
||||
# --instructions--
|
||||
|
||||
Implement a function that takes a string of four digits as its argument, with each digit from 1 to 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:**
|
||||
<ul>
|
||||
<li> Only the following operators/functions are allowed: multiplication, division, addition, subtraction. </li>
|
||||
<li> Division should use floating point or rational arithmetic, etc, to preserve remainders. </li>
|
||||
<li> 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). </li>
|
||||
<li> The order of the digits when given does not have to be preserved. </li>
|
||||
</ul>
|
||||
|
||||
| Example input | Example output |
|
||||
| ------------------------- | ------------------------- |
|
||||
| <code>solve24("4878");</code> | <code>(7-8/8)\*4</code> |
|
||||
| <code>solve24("1234");</code> | <code>3\*1\*4\*2</code> |
|
||||
| <code>solve24("6789");</code> | <code>(6\*8)/(9-7)</code> |
|
||||
| <code>solve24("1127");</code> | <code>(1+7)\*(2+1)</code> |
|
||||
|
||||
# --hints--
|
||||
|
||||
`solve24` should be a function.
|
||||
|
||||
```js
|
||||
assert(typeof solve24 === 'function');
|
||||
```
|
||||
|
||||
`solve24("4878")` should return `(7-8/8)*4` or `4*(7-8/8)`
|
||||
|
||||
```js
|
||||
assert(include(answers[0], removeParentheses(solve24(testCases[0]))));
|
||||
```
|
||||
|
||||
`solve24("1234")` should return any arrangement of `1*2*3*4`
|
||||
|
||||
```js
|
||||
assert(include(answers[1], removeParentheses(solve24(testCases[1]))));
|
||||
```
|
||||
|
||||
`solve24("6789")` should return `(6*8)/(9-7)` or `(8*6)/(9-7)`
|
||||
|
||||
```js
|
||||
assert(include(answers[2], removeParentheses(solve24(testCases[2]))));
|
||||
```
|
||||
|
||||
`solve24("1127")` should return a permutation of `(1+7)*(1+2)`
|
||||
|
||||
```js
|
||||
assert(include(answers[3], removeParentheses(solve24(testCases[3]))));
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --after-user-code--
|
||||
|
||||
```js
|
||||
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;
|
||||
}
|
||||
|
||||
//The main method for detecting single parentheses
|
||||
function removeParentheses(ans) {
|
||||
for (let i = 0; i < ans.length; i++) {
|
||||
if (!isNaN(ans[i])) {
|
||||
ans = removeParenthesesHelper(ans, i);
|
||||
}
|
||||
}
|
||||
return ans;
|
||||
}
|
||||
|
||||
//Helper to remove left and right parantheses
|
||||
function removeParenthesesHelper(ans, i) {
|
||||
while (i > 0 && i < ans.length - 1) {
|
||||
if (ans[i - 1] === '(' && ans[i + 1] === ')') {
|
||||
//Paranthesis detected. Remove them.
|
||||
ans = replaceChar(ans, '', i - 1);
|
||||
ans = replaceChar(ans, '', i);
|
||||
i--;
|
||||
} else {
|
||||
return ans;
|
||||
}
|
||||
}
|
||||
return ans;
|
||||
}
|
||||
|
||||
//Replace a character at a given index for the provided character
|
||||
function replaceChar(origString, replaceChar, index) {
|
||||
let firstPart = origString.substr(0, index);
|
||||
let lastPart = origString.substr(index + 1);
|
||||
let newString = firstPart + replaceChar + lastPart;
|
||||
return newString;
|
||||
}
|
||||
```
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```js
|
||||
function solve24 (numStr) {
|
||||
|
||||
return true;
|
||||
}
|
||||
```
|
||||
|
||||
# --solutions--
|
||||
|
||||
```js
|
||||
function solve24(numStr) {
|
||||
const digitsArr = numStr.split('');
|
||||
const answers = [];
|
||||
|
||||
const digitPermutations = [];
|
||||
const operatorPermutations = [];
|
||||
|
||||
function generateDigitPermutations (digits, permutations = []) {
|
||||
if (digits.length === 0) {
|
||||
digitPermutations.push(permutations);
|
||||
}
|
||||
else {
|
||||
for (let i = 0; i < digits.length; i++) {
|
||||
const curr = digits.slice();
|
||||
const next = curr.splice(i, 1);
|
||||
generateDigitPermutations(curr.slice(), permutations.concat(next));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function generateOperatorPermutations (permutations = []) {
|
||||
const operators = ['+', '-', '*', '/'];
|
||||
if (permutations.length === 3) {
|
||||
operatorPermutations.push(permutations);
|
||||
}
|
||||
else {
|
||||
for (let i = 0; i < operators.length; i++) {
|
||||
const curr = permutations.slice();
|
||||
curr.push(operators[i]);
|
||||
generateOperatorPermutations(curr);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
generateDigitPermutations(digitsArr);
|
||||
generateOperatorPermutations();
|
||||
|
||||
interleave();
|
||||
|
||||
return answers[0];
|
||||
|
||||
function interleave () {
|
||||
for (let i = 0; i < digitPermutations.length; i++) {
|
||||
for (let j = 0; j < operatorPermutations.length; j++) {
|
||||
const d = digitPermutations[i];
|
||||
const o = operatorPermutations[j];
|
||||
const perm = [
|
||||
`${d[0]}${o[0]}${d[1]}${o[1]}${d[2]}${o[2]}${d[3]}`,
|
||||
`(${d[0]}${o[0]}${d[1]})${o[1]}${d[2]}${o[2]}${d[3]}`,
|
||||
`${d[0]}${o[0]}(${d[1]}${o[1]}${d[2]})${o[2]}${d[3]}`,
|
||||
`${d[0]}${o[0]}${d[1]}${o[1]}(${d[2]}${o[2]}${d[3]})`,
|
||||
`${d[0]}${o[0]}(${d[1]}${o[1]}${d[2]}${o[2]}${d[3]})`,
|
||||
`(${d[0]}${o[0]}${d[1]}${o[1]}${d[2]})${o[2]}${d[3]}`,
|
||||
`(${d[0]}${o[0]}${d[1]})${o[1]}(${d[2]}${o[2]}${d[3]})`
|
||||
];
|
||||
|
||||
perm.forEach(combination => {
|
||||
const res = eval(combination);
|
||||
|
||||
if (res === 24) {
|
||||
return answers.push(combination);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
@ -0,0 +1,116 @@
|
||||
---
|
||||
id: 5949b579404977fbaefcd736
|
||||
title: 9 billion names of God the integer
|
||||
challengeType: 5
|
||||
forumTopicId: 302219
|
||||
dashedName: 9-billion-names-of-god-the-integer
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
This task is a variation of the [short story by Arthur C. Clarke](https://en.wikipedia.org/wiki/The Nine Billion Names of God#Plot_summary "wp: The Nine Billion Names of God#Plot_summary").
|
||||
|
||||
(Solvers should be aware of the consequences of completing this task.)
|
||||
|
||||
In detail, to specify what is meant by a "name":
|
||||
|
||||
<ul>
|
||||
<li>The integer 1 has 1 name "1".</li>
|
||||
<li>The integer 2 has 2 names "1+1" and "2".</li>
|
||||
<li>The integer 3 has 3 names "1+1+1", "2+1", and "3".</li>
|
||||
<li>The integer 4 has 5 names "1+1+1+1", "2+1+1", "2+2", "3+1", "4".</li>
|
||||
<li>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".</li>
|
||||
</ul>
|
||||
|
||||
This can be visualized in the following form:
|
||||
|
||||
<pre> 1
|
||||
1 1
|
||||
1 1 1
|
||||
1 2 1 1
|
||||
1 2 2 1 1
|
||||
1 3 3 2 1 1
|
||||
</pre>
|
||||
|
||||
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.
|
||||
|
||||
# --instructions--
|
||||
|
||||
Implement a function that returns the sum of the $n$-th row.
|
||||
|
||||
# --hints--
|
||||
|
||||
`numberOfNames` should be function.
|
||||
|
||||
```js
|
||||
assert(typeof numberOfNames === 'function');
|
||||
```
|
||||
|
||||
`numberOfNames(5)` should equal 7.
|
||||
|
||||
```js
|
||||
assert.equal(numberOfNames(5), 7);
|
||||
```
|
||||
|
||||
`numberOfNames(12)` should equal 77.
|
||||
|
||||
```js
|
||||
assert.equal(numberOfNames(12), 77);
|
||||
```
|
||||
|
||||
`numberOfNames(18)` should equal 385.
|
||||
|
||||
```js
|
||||
assert.equal(numberOfNames(18), 385);
|
||||
```
|
||||
|
||||
`numberOfNames(23)` should equal 1255.
|
||||
|
||||
```js
|
||||
assert.equal(numberOfNames(23), 1255);
|
||||
```
|
||||
|
||||
`numberOfNames(42)` should equal 53174.
|
||||
|
||||
```js
|
||||
assert.equal(numberOfNames(42), 53174);
|
||||
```
|
||||
|
||||
`numberOfNames(123)` should equal 2552338241.
|
||||
|
||||
```js
|
||||
assert.equal(numberOfNames(123), 2552338241);
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```js
|
||||
function numberOfNames(num) {
|
||||
|
||||
return true;
|
||||
}
|
||||
```
|
||||
|
||||
# --solutions--
|
||||
|
||||
```js
|
||||
function numberOfNames(num) {
|
||||
const cache = [
|
||||
[1]
|
||||
];
|
||||
for (let l = cache.length; l < num + 1; l++) {
|
||||
let Aa;
|
||||
let Mi;
|
||||
const r = [0];
|
||||
for (let x = 1; x < l + 1; x++) {
|
||||
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]);
|
||||
}
|
||||
cache.push(r);
|
||||
}
|
||||
return cache[num][cache[num].length - 1];
|
||||
}
|
||||
```
|
@ -0,0 +1,136 @@
|
||||
---
|
||||
id: 594810f028c0303b75339acc
|
||||
title: ABC Problem
|
||||
challengeType: 5
|
||||
forumTopicId: 302220
|
||||
dashedName: 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:
|
||||
|
||||
<pre>(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)
|
||||
</pre>
|
||||
|
||||
# --instructions--
|
||||
|
||||
Implement a function that takes a string (word) and determines whether the word can be spelled with the given collection of blocks.
|
||||
|
||||
Some rules to keep in mind:
|
||||
|
||||
<ul>
|
||||
<li>Once a letter on a block is used, that block cannot be used again.</li>
|
||||
<li>The function should be case-insensitive.</li>
|
||||
</ul>
|
||||
|
||||
# --hints--
|
||||
|
||||
`canMakeWord` should be a function.
|
||||
|
||||
```js
|
||||
assert(typeof canMakeWord === 'function');
|
||||
```
|
||||
|
||||
`canMakeWord` should return a boolean.
|
||||
|
||||
```js
|
||||
assert(typeof canMakeWord('hi') === 'boolean');
|
||||
```
|
||||
|
||||
`canMakeWord("bark")` should return true.
|
||||
|
||||
```js
|
||||
assert(canMakeWord(words[0]));
|
||||
```
|
||||
|
||||
`canMakeWord("BooK")` should return false.
|
||||
|
||||
```js
|
||||
assert(!canMakeWord(words[1]));
|
||||
```
|
||||
|
||||
`canMakeWord("TReAT")` should return true.
|
||||
|
||||
```js
|
||||
assert(canMakeWord(words[2]));
|
||||
```
|
||||
|
||||
`canMakeWord("COMMON")` should return false.
|
||||
|
||||
```js
|
||||
assert(!canMakeWord(words[3]));
|
||||
```
|
||||
|
||||
`canMakeWord("squAD")` should return true.
|
||||
|
||||
```js
|
||||
assert(canMakeWord(words[4]));
|
||||
```
|
||||
|
||||
`canMakeWord("conFUSE")` should return true.
|
||||
|
||||
```js
|
||||
assert(canMakeWord(words[5]));
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --after-user-code--
|
||||
|
||||
```js
|
||||
const words = ['bark', 'BooK', 'TReAT', 'COMMON', 'squAD', 'conFUSE'];
|
||||
```
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```js
|
||||
function canMakeWord(word) {
|
||||
|
||||
}
|
||||
```
|
||||
|
||||
# --solutions--
|
||||
|
||||
```js
|
||||
function canMakeWord(word) {
|
||||
const characters = 'BO XK DQ CP NA GT RE TG QD FS JW HU VI AN OB ER FS LY PC ZM';
|
||||
const blocks = characters.split(' ').map(pair => pair.split(''));
|
||||
|
||||
const letters = [...word.toUpperCase()];
|
||||
let length = letters.length;
|
||||
const copy = new Set(blocks);
|
||||
|
||||
letters.forEach(letter => {
|
||||
for (let block of copy) {
|
||||
const index = block.indexOf(letter);
|
||||
|
||||
if (index !== -1) {
|
||||
length--;
|
||||
copy.delete(block);
|
||||
break;
|
||||
}
|
||||
}
|
||||
});
|
||||
return !length;
|
||||
}
|
||||
```
|
@ -0,0 +1,89 @@
|
||||
---
|
||||
id: 594810f028c0303b75339acd
|
||||
title: 'Abundant, deficient and perfect number classifications'
|
||||
challengeType: 5
|
||||
forumTopicId: 302221
|
||||
dashedName: abundant-deficient-and-perfect-number-classifications
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
These define three classifications of positive integers based on their [proper divisors](https://rosettacode.org/wiki/Proper divisors "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.
|
||||
|
||||
# --instructions--
|
||||
|
||||
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]`.
|
||||
|
||||
# --hints--
|
||||
|
||||
`getDPA` should be a function.
|
||||
|
||||
```js
|
||||
assert(typeof getDPA === 'function');
|
||||
```
|
||||
|
||||
`getDPA` should return an array.
|
||||
|
||||
```js
|
||||
assert(Array.isArray(getDPA(100)));
|
||||
```
|
||||
|
||||
`getDPA` return value should have a length of 3.
|
||||
|
||||
```js
|
||||
assert(getDPA(100).length === 3);
|
||||
```
|
||||
|
||||
`getDPA(20000)` should equal [15043, 4, 4953]
|
||||
|
||||
```js
|
||||
assert.deepEqual(getDPA(20000), solution);
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --after-user-code--
|
||||
|
||||
```js
|
||||
const solution = [15043, 4, 4953];
|
||||
```
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```js
|
||||
function getDPA(num) {
|
||||
|
||||
}
|
||||
```
|
||||
|
||||
# --solutions--
|
||||
|
||||
```js
|
||||
function getDPA(num) {
|
||||
const dpa = [1, 0, 0];
|
||||
for (let n = 2; n <= num; n += 1) {
|
||||
let ds = 1;
|
||||
const e = Math.sqrt(n);
|
||||
for (let d = 2; d < e; d += 1) {
|
||||
if (n % d === 0) {
|
||||
ds += d + (n / d);
|
||||
}
|
||||
}
|
||||
if (n % e === 0) {
|
||||
ds += e;
|
||||
}
|
||||
dpa[ds < n ? 0 : ds === n ? 1 : 2] += 1;
|
||||
}
|
||||
return dpa;
|
||||
}
|
||||
```
|
@ -0,0 +1,79 @@
|
||||
---
|
||||
id: 594810f028c0303b75339ace
|
||||
title: Accumulator factory
|
||||
challengeType: 5
|
||||
forumTopicId: 302222
|
||||
dashedName: accumulator-factory
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
A problem posed by [Paul Graham](https://en.wikipedia.org/wiki/Paul_Graham_(programmer)) is that of creating a function that takes a single (numeric) argument and which 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).
|
||||
|
||||
# --instructions--
|
||||
|
||||
Create a function that takes a number $n$ and generates accumulator functions that return the sum of every number ever passed to them.
|
||||
|
||||
**Rules:**
|
||||
|
||||
Do not use global variables.
|
||||
|
||||
**Hint:**
|
||||
|
||||
Closures save outer state.
|
||||
|
||||
# --hints--
|
||||
|
||||
`accumulator` should be a function.
|
||||
|
||||
```js
|
||||
assert(typeof accumulator === 'function');
|
||||
```
|
||||
|
||||
`accumulator(0)` should return a function.
|
||||
|
||||
```js
|
||||
assert(typeof accumulator(0) === 'function');
|
||||
```
|
||||
|
||||
`accumulator(0)(2)` should return a number.
|
||||
|
||||
```js
|
||||
assert(typeof accumulator(0)(2) === 'number');
|
||||
```
|
||||
|
||||
Passing in the values 3, -4, 1.5, and 5 should return 5.5.
|
||||
|
||||
```js
|
||||
assert(testFn(5) === 5.5);
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --after-user-code--
|
||||
|
||||
```js
|
||||
const testFn = typeof accumulator(3) === 'function' && accumulator(3);
|
||||
if (testFn) {
|
||||
testFn(-4);
|
||||
testFn(1.5);
|
||||
}
|
||||
```
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```js
|
||||
function accumulator(sum) {
|
||||
|
||||
}
|
||||
```
|
||||
|
||||
# --solutions--
|
||||
|
||||
```js
|
||||
function accumulator(sum) {
|
||||
return function(n) {
|
||||
return sum += n;
|
||||
};
|
||||
}
|
||||
```
|
@ -0,0 +1,71 @@
|
||||
---
|
||||
id: 594810f028c0303b75339acf
|
||||
title: Ackermann function
|
||||
challengeType: 5
|
||||
forumTopicId: 302223
|
||||
dashedName: 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.
|
||||
|
||||
# --instructions--
|
||||
|
||||
Write a function which returns the value of $A(m, n)$. Arbitrary precision is preferred (since the function grows so quickly), but not required.
|
||||
|
||||
# --hints--
|
||||
|
||||
`ack` should be a function.
|
||||
|
||||
```js
|
||||
assert(typeof ack === 'function');
|
||||
```
|
||||
|
||||
`ack(0, 0)` should return 1.
|
||||
|
||||
```js
|
||||
assert(ack(0, 0) === 1);
|
||||
```
|
||||
|
||||
`ack(1, 1)` should return 3.
|
||||
|
||||
```js
|
||||
assert(ack(1, 1) === 3);
|
||||
```
|
||||
|
||||
`ack(2, 5)` should return 13.
|
||||
|
||||
```js
|
||||
assert(ack(2, 5) === 13);
|
||||
```
|
||||
|
||||
`ack(3, 3)` should return 61.
|
||||
|
||||
```js
|
||||
assert(ack(3, 3) === 61);
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```js
|
||||
function ack(m, n) {
|
||||
|
||||
}
|
||||
```
|
||||
|
||||
# --solutions--
|
||||
|
||||
```js
|
||||
function ack(m, n) {
|
||||
return m === 0 ? n + 1 : ack(m - 1, n === 0 ? 1 : ack(m, n - 1));
|
||||
}
|
||||
```
|
@ -0,0 +1,194 @@
|
||||
---
|
||||
id: 594810f028c0303b75339ad0
|
||||
title: Align columns
|
||||
challengeType: 5
|
||||
forumTopicId: 302224
|
||||
dashedName: 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.
|
||||
|
||||
# --instructions--
|
||||
|
||||
Use the following text to test your programs:
|
||||
|
||||
<pre>
|
||||
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.
|
||||
</pre>
|
||||
|
||||
**Note that:**
|
||||
|
||||
<ul>
|
||||
<li>The example input texts lines may, or may not, have trailing dollar characters.</li>
|
||||
<li>All columns should share the same alignment.</li>
|
||||
<li>Consecutive space characters produced adjacent to the end of lines are insignificant for the purposes of the task.</li>
|
||||
<li>Output text will be viewed in a mono-spaced font on a plain text editor or basic terminal.</li>
|
||||
<li>The minimum space between columns should be computed from the text and not hard-coded.</li>
|
||||
<li>It is not a requirement to add separating characters between or around columns.</li>
|
||||
</ul>
|
||||
|
||||
# --hints--
|
||||
|
||||
`formatText` should be a function.
|
||||
|
||||
```js
|
||||
assert(typeof formatText === 'function');
|
||||
```
|
||||
|
||||
`formatText` with the above input and "right" justification should produce the following:
|
||||
|
||||
```js
|
||||
assert.strictEqual(formatText(testInput, 'right'), rightAligned);
|
||||
```
|
||||
|
||||
`formatText` with the above input and "left" justification should produce the following:
|
||||
|
||||
```js
|
||||
assert.strictEqual(formatText(testInput, 'left'), leftAligned);
|
||||
```
|
||||
|
||||
`formatText` with the above input and "center" justification should produce the following:
|
||||
|
||||
```js
|
||||
assert.strictEqual(formatText(testInput, 'center'), centerAligned);
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --after-user-code--
|
||||
|
||||
```js
|
||||
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\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.';
|
||||
|
||||
const leftAligned = '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. ';
|
||||
|
||||
const centerAligned = ' 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. ';
|
||||
```
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```js
|
||||
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) {
|
||||
|
||||
}
|
||||
```
|
||||
|
||||
# --solutions--
|
||||
|
||||
```js
|
||||
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.'
|
||||
];
|
||||
|
||||
String.prototype.repeat = function (n) { return new Array(1 + parseInt(n)).join(this); };
|
||||
|
||||
function formatText(input, justification) {
|
||||
let x, y, max, cols = 0, diff, left, right;
|
||||
for (x = 0; x < input.length; x++) {
|
||||
input[x] = input[x].split('$');
|
||||
if (input[x].length > cols) {
|
||||
cols = input[x].length;
|
||||
}
|
||||
}
|
||||
for (x = 0; x < cols; x++) {
|
||||
max = 0;
|
||||
for (y = 0; y < input.length; y++) {
|
||||
if (input[y][x] && max < input[y][x].length) {
|
||||
max = input[y][x].length;
|
||||
}
|
||||
}
|
||||
for (y = 0; y < input.length; y++) {
|
||||
if (input[y][x]) {
|
||||
diff = (max - input[y][x].length) / 2;
|
||||
left = ' '.repeat(Math.floor(diff));
|
||||
right = ' '.repeat(Math.ceil(diff));
|
||||
if (justification === 'left') {
|
||||
right += left; left = '';
|
||||
}
|
||||
if (justification === 'right') {
|
||||
left += right; right = '';
|
||||
}
|
||||
input[y][x] = left + input[y][x] + right;
|
||||
}
|
||||
}
|
||||
}
|
||||
for (x = 0; x < input.length; x++) {
|
||||
input[x] = input[x].join(' ');
|
||||
}
|
||||
input = input.join('\n');
|
||||
return input;
|
||||
}
|
||||
```
|
@ -0,0 +1,126 @@
|
||||
---
|
||||
id: 5949b579404977fbaefcd737
|
||||
title: Amicable pairs
|
||||
challengeType: 5
|
||||
forumTopicId: 302225
|
||||
dashedName: amicable-pairs
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
Two integers $N$ and $M$ are said to be [amicable pairs](https://en.wikipedia.org/wiki/Amicable numbers "wp: Amicable numbers") if $N \\neq M$ and the sum of the [proper divisors](https://rosettacode.org/wiki/Proper divisors "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:
|
||||
|
||||
<ul>
|
||||
<li>1, 2, 4, 8, 16, 32, 37, 74, 148, 296, 592 and</li>
|
||||
<li>1, 2, 5, 10, 11, 22, 55, 110, 121, 242, 605 respectively.</li>
|
||||
</ul>
|
||||
|
||||
# --instructions--
|
||||
|
||||
Calculate and show here the Amicable pairs below 20,000 (there are eight).
|
||||
|
||||
# --hints--
|
||||
|
||||
`amicablePairsUpTo` should be a function.
|
||||
|
||||
```js
|
||||
assert(typeof amicablePairsUpTo === 'function');
|
||||
```
|
||||
|
||||
`amicablePairsUpTo(300)` should return `[[220,284]]`.
|
||||
|
||||
```js
|
||||
assert.deepEqual(amicablePairsUpTo(300), answer300);
|
||||
```
|
||||
|
||||
`amicablePairsUpTo(3000)` should return `[[220,284],[1184,1210],[2620,2924]]`.
|
||||
|
||||
```js
|
||||
assert.deepEqual(amicablePairsUpTo(3000), answer3000);
|
||||
```
|
||||
|
||||
`amicablePairsUpTo(20000)` should return `[[220,284],[1184,1210],[2620,2924],[5020,5564],[6232,6368],[10744,10856],[12285,14595],[17296,18416]]`.
|
||||
|
||||
```js
|
||||
assert.deepEqual(amicablePairsUpTo(20000), answer20000);
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --after-user-code--
|
||||
|
||||
```js
|
||||
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]
|
||||
];
|
||||
```
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```js
|
||||
function amicablePairsUpTo(maxNum) {
|
||||
|
||||
return true;
|
||||
}
|
||||
```
|
||||
|
||||
# --solutions--
|
||||
|
||||
```js
|
||||
// amicablePairsUpTo :: Int -> [(Int, Int)]
|
||||
function amicablePairsUpTo(maxNum) {
|
||||
return range(1, maxNum)
|
||||
.map(x => properDivisors(x)
|
||||
.reduce((a, b) => a + b, 0))
|
||||
.reduce((a, m, i, lst) => {
|
||||
const n = i + 1;
|
||||
|
||||
return (m > n) && lst[m - 1] === n ?
|
||||
a.concat([
|
||||
[n, m]
|
||||
]) : a;
|
||||
}, []);
|
||||
}
|
||||
|
||||
// properDivisors :: Int -> [Int]
|
||||
function properDivisors(n) {
|
||||
if (n < 2) return [];
|
||||
|
||||
const rRoot = Math.sqrt(n);
|
||||
const intRoot = Math.floor(rRoot);
|
||||
const blnPerfectSquare = rRoot === intRoot;
|
||||
const lows = range(1, intRoot)
|
||||
.filter(x => (n % x) === 0);
|
||||
|
||||
return lows.concat(lows.slice(1)
|
||||
.map(x => n / x)
|
||||
.reverse()
|
||||
.slice(blnPerfectSquare | 0));
|
||||
}
|
||||
|
||||
// Int -> Int -> Maybe Int -> [Int]
|
||||
function range(m, n, step) {
|
||||
const d = (step || 1) * (n >= m ? 1 : -1);
|
||||
|
||||
return Array.from({
|
||||
length: Math.floor((n - m) / d) + 1
|
||||
}, (_, i) => m + (i * d));
|
||||
}
|
||||
```
|
@ -0,0 +1,79 @@
|
||||
---
|
||||
id: 594d8d0ab97724821379b1e6
|
||||
title: Averages/Mode
|
||||
challengeType: 5
|
||||
forumTopicId: 302226
|
||||
dashedName: averagesmode
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
Write a program to find the [mode](https://en.wikipedia.org/wiki/Mode (statistics) "wp: Mode (statistics)") 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.
|
||||
|
||||
# --hints--
|
||||
|
||||
`mode` should be a function.
|
||||
|
||||
```js
|
||||
assert(typeof mode === 'function');
|
||||
```
|
||||
|
||||
`mode([1, 3, 6, 6, 6, 6, 7, 7, 12, 12, 17])` should equal `[6]`
|
||||
|
||||
```js
|
||||
assert.deepEqual(mode(arr1), [6]);
|
||||
```
|
||||
|
||||
`mode([1, 2, 4, 4, 1])` should equal `[1, 4]`.
|
||||
|
||||
```js
|
||||
assert.deepEqual(mode(arr2).sort(), [1, 4]);
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --after-user-code--
|
||||
|
||||
```js
|
||||
const arr1 = [1, 3, 6, 6, 6, 6, 7, 7, 12, 12, 17];
|
||||
const arr2 = [1, 2, 4, 4, 1];
|
||||
```
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```js
|
||||
function mode(arr) {
|
||||
|
||||
return true;
|
||||
}
|
||||
```
|
||||
|
||||
# --solutions--
|
||||
|
||||
```js
|
||||
function mode(arr) {
|
||||
const counter = {};
|
||||
let result = [];
|
||||
let max = 0;
|
||||
// for (const i in arr) {
|
||||
arr.forEach(el => {
|
||||
if (!(el in counter)) {
|
||||
counter[el] = 0;
|
||||
}
|
||||
counter[el]++;
|
||||
|
||||
if (counter[el] === max) {
|
||||
result.push(el);
|
||||
}
|
||||
else if (counter[el] > max) {
|
||||
max = counter[el];
|
||||
result = [el];
|
||||
}
|
||||
});
|
||||
return result;
|
||||
}
|
||||
```
|
@ -0,0 +1,144 @@
|
||||
---
|
||||
id: 594d966a1467eb84194f0086
|
||||
title: Averages/Pythagorean means
|
||||
challengeType: 5
|
||||
forumTopicId: 302227
|
||||
dashedName: averagespythagorean-means
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
Compute all three of the [Pythagorean means](https://en.wikipedia.org/wiki/Pythagorean means "wp: 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.
|
||||
|
||||
<ul>
|
||||
<li>The most common of the three means, the <a class='rosetta__link--rosetta' href='https://rosettacode.org/wiki/Averages/Arithmetic mean' title='Averages/Arithmetic mean' target='_blank'>arithmetic mean</a>, is the sum of the list divided by its length:<br>
|
||||
<big>$ A(x_1, \ldots, x_n) = \frac{x_1 + \cdots + x_n}{n}$</big></li>
|
||||
<li>The <a class='rosetta__link--wiki' href='https://en.wikipedia.org/wiki/Geometric mean' title='wp: Geometric mean' target='_blank'>geometric mean</a> is the $n$th root of the product of the list:<br>
|
||||
<big>$ G(x_1, \ldots, x_n) = \sqrt[n]{x_1 \cdots x_n} $</big></li>
|
||||
<li>The <a class='rosetta__link--wiki' href='https://en.wikipedia.org/wiki/Harmonic mean' title='wp: Harmonic mean' target='_blank'>harmonic mean</a> is $n$ divided by the sum of the reciprocal of each item in the list:<br>
|
||||
<big>$ H(x_1, \ldots, x_n) = \frac{n}{\frac{1}{x_1} + \cdots + \frac{1}{x_n}} $</big></li>
|
||||
</ul>
|
||||
|
||||
# --instructions--
|
||||
|
||||
When writing your function, assume the input is an ordered array of all inclusive numbers.
|
||||
|
||||
For the answer, please output an object in the following format:
|
||||
|
||||
```js
|
||||
{
|
||||
values: {
|
||||
Arithmetic: 5.5,
|
||||
Geometric: 4.528728688116765,
|
||||
Harmonic: 3.414171521474055
|
||||
},
|
||||
test: 'is A >= G >= H ? yes'
|
||||
}
|
||||
```
|
||||
|
||||
# --hints--
|
||||
|
||||
`pythagoreanMeans` should be a function.
|
||||
|
||||
```js
|
||||
assert(typeof pythagoreanMeans === 'function');
|
||||
```
|
||||
|
||||
`pythagoreanMeans([1, 2, ..., 10])` should equal the same output above.
|
||||
|
||||
```js
|
||||
assert.deepEqual(pythagoreanMeans(range1), answer1);
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --after-user-code--
|
||||
|
||||
```js
|
||||
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'
|
||||
};
|
||||
```
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```js
|
||||
function pythagoreanMeans(rangeArr) {
|
||||
|
||||
}
|
||||
```
|
||||
|
||||
# --solutions--
|
||||
|
||||
```js
|
||||
function pythagoreanMeans(rangeArr) {
|
||||
// arithmeticMean :: [Number] -> Number
|
||||
const arithmeticMean = xs =>
|
||||
foldl((sum, n) => sum + n, 0, xs) / length(xs);
|
||||
|
||||
// geometricMean :: [Number] -> Number
|
||||
const geometricMean = xs =>
|
||||
raise(foldl((product, x) => product * x, 1, xs), 1 / length(xs));
|
||||
|
||||
// harmonicMean :: [Number] -> Number
|
||||
const harmonicMean = xs =>
|
||||
length(xs) / foldl((invSum, n) => invSum + (1 / n), 0, xs);
|
||||
|
||||
// GENERIC FUNCTIONS ------------------------------------------------------
|
||||
|
||||
// A list of functions applied to a list of arguments
|
||||
// <*> :: [(a -> b)] -> [a] -> [b]
|
||||
const ap = (fs, xs) => //
|
||||
Array.prototype.concat(...fs.map(f => //
|
||||
Array.prototype.concat(...xs.map(x => [f(x)]))));
|
||||
|
||||
// foldl :: (b -> a -> b) -> b -> [a] -> b
|
||||
const foldl = (f, a, xs) => xs.reduce(f, a);
|
||||
|
||||
// length :: [a] -> Int
|
||||
const length = xs => xs.length;
|
||||
|
||||
// mapFromList :: [(k, v)] -> Dictionary
|
||||
const mapFromList = kvs =>
|
||||
foldl((a, [k, v]) =>
|
||||
(a[(typeof k === 'string' && k)] = v, a), {}, kvs);
|
||||
|
||||
// raise :: Num -> Int -> Num
|
||||
const raise = (n, e) => Math.pow(n, e);
|
||||
/*
|
||||
// show :: a -> String
|
||||
// show :: a -> Int -> String
|
||||
const show = (...x) =>
|
||||
JSON.stringify.apply(
|
||||
null, x.length > 1 ? [x[0], null, x[1]] : x
|
||||
);
|
||||
*/
|
||||
// zip :: [a] -> [b] -> [(a,b)]
|
||||
const zip = (xs, ys) =>
|
||||
xs.slice(0, Math.min(xs.length, ys.length))
|
||||
.map((x, i) => [x, ys[i]]);
|
||||
|
||||
// TEST -------------------------------------------------------------------
|
||||
// mean :: Dictionary
|
||||
const mean = mapFromList(zip(
|
||||
['Arithmetic', 'Geometric', 'Harmonic'],
|
||||
ap([arithmeticMean, geometricMean, harmonicMean], [
|
||||
rangeArr
|
||||
])
|
||||
));
|
||||
|
||||
return {
|
||||
values: mean,
|
||||
test: `is A >= G >= H ? ${mean.Arithmetic >= mean.Geometric &&
|
||||
mean.Geometric >= mean.Harmonic ? 'yes' : 'no'}`
|
||||
};
|
||||
}
|
||||
```
|
@ -0,0 +1,57 @@
|
||||
---
|
||||
id: 594da033de4190850b893874
|
||||
title: Averages/Root mean square
|
||||
challengeType: 5
|
||||
forumTopicId: 302228
|
||||
dashedName: averagesroot-mean-square
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
Compute the [Root mean square](https://en.wikipedia.org/wiki/Root mean square "wp: 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}. $$
|
||||
|
||||
# --hints--
|
||||
|
||||
`rms` should be a function.
|
||||
|
||||
```js
|
||||
assert(typeof rms === 'function');
|
||||
```
|
||||
|
||||
`rms([1, 2, 3, 4, 5, 6, 7, 8, 9, 10])` should equal `6.2048368229954285`.
|
||||
|
||||
```js
|
||||
assert.equal(rms(arr1), answer1);
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --after-user-code--
|
||||
|
||||
```js
|
||||
const arr1 = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
|
||||
const answer1 = 6.2048368229954285;
|
||||
```
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```js
|
||||
function rms(arr) {
|
||||
|
||||
}
|
||||
```
|
||||
|
||||
# --solutions--
|
||||
|
||||
```js
|
||||
function rms(arr) {
|
||||
const sumOfSquares = arr.reduce((s, x) => s + x * x, 0);
|
||||
return Math.sqrt(sumOfSquares / arr.length);
|
||||
}
|
||||
```
|
@ -0,0 +1,78 @@
|
||||
---
|
||||
id: 594db4d0dedb4c06a2a4cefd
|
||||
title: Babbage problem
|
||||
challengeType: 5
|
||||
forumTopicId: 302229
|
||||
dashedName: babbage-problem
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
[Charles Babbage](https://en.wikipedia.org/wiki/Charles_Babbage "wp: Charles_Babbage"), looking ahead to the sorts of problems his Analytical Engine would be able to solve, gave this example:
|
||||
|
||||
<blockquote>
|
||||
What is the smallest positive integer whose square ends in the digits 269,696?
|
||||
<footer style='margin-left: 2em;'>Babbage, letter to Lord Bowden, 1837; see Hollingdale and Tootill, <i>Electronic Computers</i>, second edition, 1970, p. 125.</footer>
|
||||
</blockquote>
|
||||
|
||||
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.
|
||||
|
||||
# --instructions--
|
||||
|
||||
Implement a function to return the lowest integer that satisfies the Babbage problem. If Babbage was right, return Babbage's number.
|
||||
|
||||
# --hints--
|
||||
|
||||
`babbage` should be a function.
|
||||
|
||||
```js
|
||||
assert(typeof babbage === 'function');
|
||||
```
|
||||
|
||||
`babbage(99736, 269696)` should not return 99736 (there is a smaller answer).
|
||||
|
||||
```js
|
||||
assert.equal(babbage(babbageAns, endDigits), answer);
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --after-user-code--
|
||||
|
||||
```js
|
||||
const babbageAns = 99736;
|
||||
const endDigits = 269696;
|
||||
const answer = 25264;
|
||||
```
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```js
|
||||
function babbage(babbageNum, endDigits) {
|
||||
|
||||
return true;
|
||||
}
|
||||
```
|
||||
|
||||
# --solutions--
|
||||
|
||||
```js
|
||||
function babbage(babbageAns, endDigits) {
|
||||
const babbageNum = Math.pow(babbageAns, 2);
|
||||
const babbageStartDigits = parseInt(babbageNum.toString().replace('269696', ''));
|
||||
let answer = 99736;
|
||||
|
||||
// count down from this answer and save any sqrt int result. return lowest one
|
||||
for (let i = babbageStartDigits; i >= 0; i--) {
|
||||
const num = parseInt(i.toString().concat('269696'));
|
||||
const result = Math.sqrt(num);
|
||||
if (result === Math.floor(Math.sqrt(num))) {
|
||||
answer = result;
|
||||
}
|
||||
}
|
||||
|
||||
return answer;
|
||||
}
|
||||
```
|
@ -0,0 +1,188 @@
|
||||
---
|
||||
id: 594dc6c729e5700999302b45
|
||||
title: Balanced brackets
|
||||
challengeType: 5
|
||||
forumTopicId: 302230
|
||||
dashedName: 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:**
|
||||
| Input | Output |
|
||||
| ------------------------- | ------ |
|
||||
| <code>\[]</code> | true |
|
||||
| <code>]\[</code> | false |
|
||||
| <code>[][]</code> | true |
|
||||
| <code>]\[]</code> | false |
|
||||
| <code>\[]]\[\[]</code> | false |
|
||||
| <code>\[\[\[\[]]]]</code> | true |
|
||||
|
||||
# --hints--
|
||||
|
||||
`isBalanced` should be a function.
|
||||
|
||||
```js
|
||||
assert(typeof isBalanced === 'function');
|
||||
```
|
||||
|
||||
`isBalanced("[]")` should return true.
|
||||
|
||||
```js
|
||||
assert(isBalanced(testCases[0]));
|
||||
```
|
||||
|
||||
`isBalanced("]][[[][][][]][")` should return false.
|
||||
|
||||
```js
|
||||
assert(!isBalanced(testCases[1]));
|
||||
```
|
||||
|
||||
`isBalanced("[][[[[][][[[]]]]]]")` should return true.
|
||||
|
||||
```js
|
||||
assert(isBalanced(testCases[2]));
|
||||
```
|
||||
|
||||
`isBalanced("][")` should return false.
|
||||
|
||||
```js
|
||||
assert(!isBalanced(testCases[3]));
|
||||
```
|
||||
|
||||
`isBalanced("[[[]]]][[]")` should return false.
|
||||
|
||||
```js
|
||||
assert(!isBalanced(testCases[4]));
|
||||
```
|
||||
|
||||
`isBalanced("][[]")` should return false.
|
||||
|
||||
```js
|
||||
assert(!isBalanced(testCases[5]));
|
||||
```
|
||||
|
||||
`isBalanced("][[][]][[[]]")` should return false.
|
||||
|
||||
```js
|
||||
assert(!isBalanced(testCases[6]));
|
||||
```
|
||||
|
||||
`isBalanced("[[][]]][")` should return false.
|
||||
|
||||
```js
|
||||
assert(!isBalanced(testCases[7]));
|
||||
```
|
||||
|
||||
`isBalanced("[[[]]][[]]]][][[")` should return false.
|
||||
|
||||
```js
|
||||
assert(!isBalanced(testCases[8]));
|
||||
```
|
||||
|
||||
`isBalanced("[]][[]]][[[[][]]")` should return false.
|
||||
|
||||
```js
|
||||
assert(!isBalanced(testCases[9]));
|
||||
```
|
||||
|
||||
`isBalanced("][]][[][")` should return false.
|
||||
|
||||
```js
|
||||
assert(!isBalanced(testCases[10]));
|
||||
```
|
||||
|
||||
`isBalanced("[[]][[][]]")` should return true.
|
||||
|
||||
```js
|
||||
assert(isBalanced(testCases[11]));
|
||||
```
|
||||
|
||||
`isBalanced("[[]]")` should return true.
|
||||
|
||||
```js
|
||||
assert(isBalanced(testCases[12]));
|
||||
```
|
||||
|
||||
`isBalanced("]][]][[]][[[")` should return false.
|
||||
|
||||
```js
|
||||
assert(!isBalanced(testCases[13]));
|
||||
```
|
||||
|
||||
`isBalanced("][]][][[")` should return false.
|
||||
|
||||
```js
|
||||
assert(!isBalanced(testCases[14]));
|
||||
```
|
||||
|
||||
`isBalanced("][][")` should return false.
|
||||
|
||||
```js
|
||||
assert(!isBalanced(testCases[15]));
|
||||
```
|
||||
|
||||
`isBalanced("[]]]")` should return false.
|
||||
|
||||
```js
|
||||
assert(!isBalanced(testCases[16]));
|
||||
```
|
||||
|
||||
`isBalanced("")` should return true.
|
||||
|
||||
```js
|
||||
assert(isBalanced(testCases[17]));
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --after-user-code--
|
||||
|
||||
```js
|
||||
const testCases = [
|
||||
'[]',
|
||||
']][[[][][][]][',
|
||||
'[][[[[][][[[]]]]]]',
|
||||
'][',
|
||||
'[[[]]]][[]',
|
||||
'][[]',
|
||||
'][[][]][[[]]',
|
||||
'[[][]]][',
|
||||
'[[[]]][[]]]][][[',
|
||||
'[]][[]]][[[[][]]',
|
||||
'][]][[][',
|
||||
'[[]][[][]]',
|
||||
'[[]]',
|
||||
']][]][[]][[[',
|
||||
'][]][][[',
|
||||
'][][',
|
||||
'[]]]',
|
||||
''
|
||||
];
|
||||
```
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```js
|
||||
function isBalanced(str) {
|
||||
|
||||
return true;
|
||||
}
|
||||
```
|
||||
|
||||
# --solutions--
|
||||
|
||||
```js
|
||||
function isBalanced(str) {
|
||||
if (str === '') return true;
|
||||
let a = str;
|
||||
let b;
|
||||
do {
|
||||
b = a;
|
||||
a = a.replace(/\[\]/g, '');
|
||||
} while (a !== b);
|
||||
return !a;
|
||||
}
|
||||
```
|
@ -0,0 +1,150 @@
|
||||
---
|
||||
id: 5951815dd895584b06884620
|
||||
title: Circles of given radius through two points
|
||||
challengeType: 5
|
||||
forumTopicId: 302231
|
||||
dashedName: 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:**
|
||||
|
||||
<ul>
|
||||
<li>A radius of zero should be treated as never describing circles (except in the case where the points are coincident).</li>
|
||||
<li>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.</li>
|
||||
<li>If the points form a diameter then return a single circle.</li>
|
||||
<li>If the points are too far apart then no circles can be drawn.</li>
|
||||
</ul>
|
||||
|
||||
# --instructions--
|
||||
|
||||
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:**
|
||||
|
||||
<ul>
|
||||
<li>If points are on the diameter, return one point. If the radius is also zero however, return <code>"Radius Zero"</code>.</li>
|
||||
<li>If points are coincident, return <code>"Coincident point. Infinite solutions"</code>.</li>
|
||||
<li>If points are farther apart than the diameter, return <code>"No intersection. Points further apart than circle diameter"</code>.</li>
|
||||
</ul>
|
||||
|
||||
**Sample inputs:**
|
||||
|
||||
<pre> p1 p2 r
|
||||
0.1234, 0.9876 0.8765, 0.2345 2.0
|
||||
0.0000, 2.0000 0.0000, 0.0000 1.0
|
||||
0.1234, 0.9876 0.1234, 0.9876 2.0
|
||||
0.1234, 0.9876 0.8765, 0.2345 0.5
|
||||
0.1234, 0.9876 0.1234, 0.9876 0.0
|
||||
</pre>
|
||||
|
||||
# --hints--
|
||||
|
||||
`getCircles` should be a function.
|
||||
|
||||
```js
|
||||
assert(typeof getCircles === 'function');
|
||||
```
|
||||
|
||||
`getCircles([0.1234, 0.9876], [0.8765, 0.2345], 2.0)` should return `[[1.8631, 1.9742], [-0.8632, -0.7521]]`.
|
||||
|
||||
```js
|
||||
assert.deepEqual(getCircles(...testCases[0]), answers[0]);
|
||||
```
|
||||
|
||||
`getCircles([0.0000, 2.0000], [0.0000, 0.0000], 1.0)` should return `[0, 1]`
|
||||
|
||||
```js
|
||||
assert.deepEqual(getCircles(...testCases[1]), answers[1]);
|
||||
```
|
||||
|
||||
`getCircles([0.1234, 0.9876], [0.1234, 0.9876], 2.0)` should return `Coincident point. Infinite solutions`
|
||||
|
||||
```js
|
||||
assert.deepEqual(getCircles(...testCases[2]), answers[2]);
|
||||
```
|
||||
|
||||
`getCircles([0.1234, 0.9876], [0.8765, 0.2345], 0.5)` should return `No intersection. Points further apart than circle diameter`
|
||||
|
||||
```js
|
||||
assert.deepEqual(getCircles(...testCases[3]), answers[3]);
|
||||
```
|
||||
|
||||
`getCircles([0.1234, 0.9876], [0.1234, 0.9876], 0.0)` should return `Radius Zero`
|
||||
|
||||
```js
|
||||
assert.deepEqual(getCircles(...testCases[4]), answers[4]);
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --after-user-code--
|
||||
|
||||
```js
|
||||
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'
|
||||
];
|
||||
```
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```js
|
||||
function getCircles(...args) {
|
||||
|
||||
return true;
|
||||
}
|
||||
```
|
||||
|
||||
# --solutions--
|
||||
|
||||
```js
|
||||
const hDist = (p1, p2) => Math.hypot(...p1.map((e, i) => e - p2[i])) / 2;
|
||||
const pAng = (p1, p2) => Math.atan(p1.map((e, i) => e - p2[i]).reduce((p, c) => c / p, 1));
|
||||
const solveF = (p, r) => t => [parseFloat((r * Math.cos(t) + p[0]).toFixed(4)), parseFloat((r * Math.sin(t) + p[1]).toFixed(4))];
|
||||
const diamPoints = (p1, p2) => p1.map((e, i) => parseFloat((e + (p2[i] - e) / 2).toFixed(4)));
|
||||
|
||||
function getCircles(...args) {
|
||||
const [p1, p2, s] = args;
|
||||
const solve = solveF(p1, s);
|
||||
const halfDist = hDist(p1, p2);
|
||||
|
||||
let msg = [];
|
||||
switch (Math.sign(s - halfDist)) {
|
||||
case 0:
|
||||
msg = s ? diamPoints(p1, p2) :
|
||||
'Radius Zero';
|
||||
break;
|
||||
case 1:
|
||||
if (!halfDist) {
|
||||
msg = 'Coincident point. Infinite solutions';
|
||||
}
|
||||
else {
|
||||
const theta = pAng(p1, p2);
|
||||
const theta2 = Math.acos(halfDist / s);
|
||||
[1, -1].map(e => solve(theta + e * theta2)).forEach(
|
||||
e => msg.push(e));
|
||||
}
|
||||
break;
|
||||
case -1:
|
||||
msg = 'No intersection. Points further apart than circle diameter';
|
||||
break;
|
||||
default:
|
||||
msg = 'Reached the default';
|
||||
}
|
||||
return msg;
|
||||
}
|
||||
```
|
@ -0,0 +1,363 @@
|
||||
---
|
||||
id: 5951a53863c8a34f02bf1bdc
|
||||
title: Closest-pair problem
|
||||
challengeType: 5
|
||||
forumTopicId: 302232
|
||||
dashedName: closest-pair-problem
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
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](https://en.wikipedia.org/wiki/Closest pair of points problem "wp: Closest pair of points problem") in the *planar* case.
|
||||
|
||||
The straightforward solution is a O(n<sup>2</sup>) algorithm (which we can call *brute-force algorithm*); the pseudo-code (using indexes) could be simply:
|
||||
|
||||
<pre><strong>bruteForceClosestPair</strong> of P(1), P(2), ... P(N)
|
||||
<strong>if</strong> N < 2 <strong>then</strong>
|
||||
<strong>return</strong> ∞
|
||||
<strong>else</strong>
|
||||
minDistance ← |P(1) - P(2)|
|
||||
minPoints ← { P(1), P(2) }
|
||||
<strong>foreach</strong> i ∈ [1, N-1]
|
||||
<strong>foreach</strong> j ∈ [i+1, N]
|
||||
<strong>if</strong> |P(i) - P(j)| < minDistance <strong>then</strong>
|
||||
minDistance ← |P(i) - P(j)|
|
||||
minPoints ← { P(i), P(j) }
|
||||
<strong>endif</strong>
|
||||
<strong>endfor</strong>
|
||||
<strong>endfor</strong>
|
||||
<strong>return</strong> minDistance, minPoints
|
||||
<strong>endif</strong>
|
||||
</pre>
|
||||
|
||||
A better algorithm is based on the recursive divide and conquer approach, as explained also at [Wikipedia's Closest pair of points problem](https://en.wikipedia.org/wiki/Closest pair of points problem#Planar_case "wp: Closest pair of points problem#Planar_case"), which is `O(nlog(n))` a pseudo-code could be:
|
||||
|
||||
<pre><strong>closestPair</strong> 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)
|
||||
<strong>if</strong> N ≤ 3 <strong>then</strong>
|
||||
<strong>return</strong> closest points of xP using brute-force algorithm
|
||||
<strong>else</strong>
|
||||
xL ← points of xP from 1 to ⌈N/2⌉
|
||||
xR ← points of xP from ⌈N/2⌉+1 to N
|
||||
xm ← xP(⌈N/2⌉)<sub>x</sub>
|
||||
yL ← { p ∈ yP : p<sub>x</sub> ≤ xm }
|
||||
yR ← { p ∈ yP : p<sub>x</sub> > xm }
|
||||
(dL, pairL) ← closestPair of (xL, yL)
|
||||
(dR, pairR) ← closestPair of (xR, yR)
|
||||
(dmin, pairMin) ← (dR, pairR)
|
||||
<strong>if</strong> dL < dR <strong>then</strong>
|
||||
(dmin, pairMin) ← (dL, pairL)
|
||||
<strong>endif</strong>
|
||||
yS ← { p ∈ yP : |xm - p<sub>x</sub>| < dmin }
|
||||
nS ← number of points in yS
|
||||
(closest, closestPair) ← (dmin, pairMin)
|
||||
<strong>for</strong> i <strong>from</strong> 1 <strong>to</strong> nS - 1
|
||||
k ← i + 1
|
||||
<strong>while</strong> k ≤ nS <strong>and</strong> yS(k)<sub>y</sub> - yS(i)<sub>y</sub> < dmin
|
||||
<strong>if</strong> |yS(k) - yS(i)| < closest <strong>then</strong>
|
||||
(closest, closestPair) ← (|yS(k) - yS(i)|, {yS(k), yS(i)})
|
||||
<strong>endif</strong>
|
||||
k ← k + 1
|
||||
<strong>endwhile</strong>
|
||||
<strong>endfor</strong>
|
||||
<strong>return</strong> closest, closestPair
|
||||
<strong>endif</strong>
|
||||
</pre>
|
||||
|
||||
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` (the pair of two closest points).
|
||||
|
||||
**References and further readings:**
|
||||
|
||||
<ul>
|
||||
<li><a href='https://en.wikipedia.org/wiki/Closest pair of points problem' title='wp: Closest pair of points problem' target='_blank'>Closest pair of points problem</a></li>
|
||||
<li><a href='https://www.cs.mcgill.ca/~cs251/ClosestPair/ClosestPairDQ.html' target='_blank'>Closest Pair (McGill)</a></li>
|
||||
<li><a href='https://www.cs.ucsb.edu/~suri/cs235/ClosestPair.pdf' target='_blank'>Closest Pair (UCSB)</a></li>
|
||||
<li><a href='https://classes.cec.wustl.edu/~cse241/handouts/closestpair.pdf' target='_blank'>Closest pair (WUStL)</a></li>
|
||||
</ul>
|
||||
|
||||
# --hints--
|
||||
|
||||
`getClosestPair` should be a function.
|
||||
|
||||
```js
|
||||
assert(typeof getClosestPair === 'function');
|
||||
```
|
||||
|
||||
Distance should be the following.
|
||||
|
||||
```js
|
||||
assert.equal(getClosestPair(points1).distance, answer1.distance);
|
||||
```
|
||||
|
||||
Points should be the following.
|
||||
|
||||
```js
|
||||
assert.deepEqual(
|
||||
JSON.parse(JSON.stringify(getClosestPair(points1))).pair,
|
||||
answer1.pair
|
||||
);
|
||||
```
|
||||
|
||||
Distance should be the following.
|
||||
|
||||
```js
|
||||
assert.equal(getClosestPair(points2).distance, answer2.distance);
|
||||
```
|
||||
|
||||
Points should be the following.
|
||||
|
||||
```js
|
||||
assert.deepEqual(
|
||||
JSON.parse(JSON.stringify(getClosestPair(points2))).pair,
|
||||
answer2.pair
|
||||
);
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --after-user-code--
|
||||
|
||||
```js
|
||||
const points1 = [
|
||||
new Point(0.748501, 4.09624),
|
||||
new Point(3.00302, 5.26164),
|
||||
new Point(3.61878, 9.52232),
|
||||
new Point(7.46911, 4.71611),
|
||||
new Point(5.7819, 2.69367),
|
||||
new Point(2.34709, 8.74782),
|
||||
new Point(2.87169, 5.97774),
|
||||
new Point(6.33101, 0.463131),
|
||||
new Point(7.46489, 4.6268),
|
||||
new 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)
|
||||
];
|
||||
```
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```js
|
||||
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) {
|
||||
|
||||
return true;
|
||||
}
|
||||
```
|
||||
|
||||
# --solutions--
|
||||
|
||||
```js
|
||||
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;
|
||||
};
|
||||
|
||||
const mergeSort = function mergeSort(points, comp) {
|
||||
if(points.length < 2) return points;
|
||||
|
||||
var n = points.length,
|
||||
i = 0,
|
||||
j = 0,
|
||||
leftN = Math.floor(n / 2),
|
||||
rightN = leftN;
|
||||
|
||||
var leftPart = mergeSort( points.slice(0, leftN), comp),
|
||||
rightPart = mergeSort( points.slice(rightN), comp );
|
||||
|
||||
var sortedPart = [];
|
||||
|
||||
while((i < leftPart.length) && (j < rightPart.length)) {
|
||||
if(comp(leftPart[i], rightPart[j]) < 0) {
|
||||
sortedPart.push(leftPart[i]);
|
||||
i += 1;
|
||||
}
|
||||
else {
|
||||
sortedPart.push(rightPart[j]);
|
||||
j += 1;
|
||||
}
|
||||
}
|
||||
while(i < leftPart.length) {
|
||||
sortedPart.push(leftPart[i]);
|
||||
i += 1;
|
||||
}
|
||||
while(j < rightPart.length) {
|
||||
sortedPart.push(rightPart[j]);
|
||||
j += 1;
|
||||
}
|
||||
return sortedPart;
|
||||
};
|
||||
|
||||
const closestPair = function _closestPair(Px, Py) {
|
||||
if(Px.length < 2) return { distance: Infinity, pair: [ new Point(0, 0), new Point(0, 0) ] };
|
||||
if(Px.length < 3) {
|
||||
//find euclid distance
|
||||
var d = Math.sqrt( Math.pow(Math.abs(Px[1].x - Px[0].x), 2) + Math.pow(Math.abs(Px[1].y - Px[0].y), 2) );
|
||||
return {
|
||||
distance: d,
|
||||
pair: [ Px[0], Px[1] ]
|
||||
};
|
||||
}
|
||||
|
||||
var n = Px.length,
|
||||
leftN = Math.floor(n / 2),
|
||||
rightN = leftN;
|
||||
|
||||
var Xl = Px.slice(0, leftN),
|
||||
Xr = Px.slice(rightN),
|
||||
Xm = Xl[leftN - 1],
|
||||
Yl = [],
|
||||
Yr = [];
|
||||
//separate Py
|
||||
for(var i = 0; i < Py.length; i += 1) {
|
||||
if(Py[i].x <= Xm.x)
|
||||
Yl.push(Py[i]);
|
||||
else
|
||||
Yr.push(Py[i]);
|
||||
}
|
||||
|
||||
var dLeft = _closestPair(Xl, Yl),
|
||||
dRight = _closestPair(Xr, Yr);
|
||||
|
||||
var minDelta = dLeft.distance,
|
||||
closestPair = dLeft.pair;
|
||||
if(dLeft.distance > dRight.distance) {
|
||||
minDelta = dRight.distance;
|
||||
closestPair = dRight.pair;
|
||||
}
|
||||
|
||||
//filter points around Xm within delta (minDelta)
|
||||
var closeY = [];
|
||||
for(i = 0; i < Py.length; i += 1) {
|
||||
if(Math.abs(Py[i].x - Xm.x) < minDelta) closeY.push(Py[i]);
|
||||
}
|
||||
//find min within delta. 8 steps max
|
||||
for(i = 0; i < closeY.length; i += 1) {
|
||||
for(var j = i + 1; j < Math.min( (i + 8), closeY.length ); j += 1) {
|
||||
var d = Math.sqrt( Math.pow(Math.abs(closeY[j].x - closeY[i].x), 2) + Math.pow(Math.abs(closeY[j].y - closeY[i].y), 2) );
|
||||
if(d < minDelta) {
|
||||
minDelta = d;
|
||||
closestPair = [ closeY[i], closeY[j] ]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
distance: minDelta,
|
||||
pair: closestPair
|
||||
};
|
||||
};
|
||||
|
||||
function getClosestPair(points) {
|
||||
const sortX = function(a, b) { return (a.x < b.x) ? -1 : ((a.x > b.x) ? 1 : 0); }
|
||||
const sortY = function(a, b) { return (a.y < b.y) ? -1 : ((a.y > b.y) ? 1 : 0); }
|
||||
|
||||
const Px = mergeSort(points, sortX);
|
||||
const Py = mergeSort(points, sortY);
|
||||
|
||||
return closestPair(Px, Py);
|
||||
}
|
||||
```
|
@ -0,0 +1,95 @@
|
||||
---
|
||||
id: 5958469238c0d8d2632f46db
|
||||
title: Combinations
|
||||
challengeType: 5
|
||||
forumTopicId: 302233
|
||||
dashedName: combinations
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
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:
|
||||
|
||||
<pre>0 1 2
|
||||
0 1 3
|
||||
0 1 4
|
||||
0 2 3
|
||||
0 2 4
|
||||
0 3 4
|
||||
1 2 3
|
||||
1 2 4
|
||||
1 3 4
|
||||
2 3 4
|
||||
</pre>
|
||||
|
||||
# --hints--
|
||||
|
||||
`combinations` should be a function.
|
||||
|
||||
```js
|
||||
assert(typeof combinations === 'function');
|
||||
```
|
||||
|
||||
`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]]`.
|
||||
|
||||
```js
|
||||
assert.deepEqual(combinations(testInput1[0], testInput1[1]), testOutput1);
|
||||
```
|
||||
|
||||
`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]]`
|
||||
|
||||
```js
|
||||
assert.deepEqual(combinations(testInput2[0], testInput2[1]), testOutput2);
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --after-user-code--
|
||||
|
||||
```js
|
||||
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]];
|
||||
```
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```js
|
||||
function combinations(m, n) {
|
||||
|
||||
return true;
|
||||
}
|
||||
```
|
||||
|
||||
# --solutions--
|
||||
|
||||
```js
|
||||
function combinations(m, n) {
|
||||
const nArr = [...Array(n).keys()];
|
||||
|
||||
return (function generateCombinations (size, numArr) {
|
||||
const ret = [];
|
||||
|
||||
for (let i = 0; i < numArr.length; i++) {
|
||||
if (size === 1) {
|
||||
ret.push([numArr[i]]);
|
||||
}
|
||||
else {
|
||||
const sub = generateCombinations(size - 1, numArr.slice(i + 1, numArr.length));
|
||||
for (let subI = 0; subI < sub.length; subI++) {
|
||||
const next = sub[subI];
|
||||
next.unshift(numArr[i]);
|
||||
ret.push(next);
|
||||
}
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}(m, nArr));
|
||||
}
|
||||
```
|
@ -0,0 +1,101 @@
|
||||
---
|
||||
id: 596e414344c3b2872167f0fe
|
||||
title: Comma quibbling
|
||||
challengeType: 5
|
||||
forumTopicId: 302234
|
||||
dashedName: comma-quibbling
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
Comma quibbling is a task originally set by Eric Lippert in his [blog](https://blogs.msdn.com/b/ericlippert/archive/2009/04/15/comma-quibbling.aspx).
|
||||
|
||||
# --instructions--
|
||||
|
||||
Write a function to generate a string output which is the concatenation of input words from a list/sequence where:
|
||||
|
||||
<ol>
|
||||
<li>An input of no words produces the output string of just the two brace characters (<code>"{}"</code>)</li>
|
||||
<li>An input of just one word, e.g. <code>["ABC"]</code>, produces the output string of the word inside the two braces, e.g. <code>"{ABC}"</code></li>
|
||||
<li>An input of two words, e.g. <code>["ABC", "DEF"]</code>, produces the output string of the two words inside the two braces with the words separated by the string <code>" and "</code>, e.g. <code>"{ABC and DEF}"</code></li>
|
||||
<li>An input of three or more words, e.g. <code>["ABC", "DEF", "G", "H"]</code>, produces the output string of all but the last word separated by <code>", "</code> with the last word separated by <code>" and "</code> and all within braces; e.g. <code>"{ABC, DEF, G and H}"</code></li>
|
||||
</ol>
|
||||
|
||||
Test your function with the following series of inputs showing your output here on this page:
|
||||
|
||||
<ul>
|
||||
<li>[] # (No input words).</li>
|
||||
<li>["ABC"]</li>
|
||||
<li>["ABC", "DEF"]</li>
|
||||
<li>["ABC", "DEF", "G", "H"]</li>
|
||||
</ul>
|
||||
|
||||
**Note:** Assume words are non-empty strings of uppercase characters for this task.
|
||||
|
||||
# --hints--
|
||||
|
||||
`quibble` should be a function.
|
||||
|
||||
```js
|
||||
assert(typeof quibble === 'function');
|
||||
```
|
||||
|
||||
`quibble(["ABC"])` should return a string.
|
||||
|
||||
```js
|
||||
assert(typeof quibble(['ABC']) === 'string');
|
||||
```
|
||||
|
||||
`quibble([])` should return "{}".
|
||||
|
||||
```js
|
||||
assert.equal(quibble(testCases[0]), results[0]);
|
||||
```
|
||||
|
||||
`quibble(["ABC"])` should return "{ABC}".
|
||||
|
||||
```js
|
||||
assert.equal(quibble(testCases[1]), results[1]);
|
||||
```
|
||||
|
||||
`quibble(["ABC", "DEF"])` should return "{ABC and DEF}".
|
||||
|
||||
```js
|
||||
assert.equal(quibble(testCases[2]), results[2]);
|
||||
```
|
||||
|
||||
`quibble(["ABC", "DEF", "G", "H"])` should return "{ABC,DEF,G and H}".
|
||||
|
||||
```js
|
||||
assert.equal(quibble(testCases[3]), results[3]);
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --after-user-code--
|
||||
|
||||
```js
|
||||
const testCases = [[], ["ABC"], ["ABC", "DEF"], ["ABC", "DEF", "G", "H"]];
|
||||
const results = ["{}", "{ABC}", "{ABC and DEF}", "{ABC,DEF,G and H}"];
|
||||
```
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```js
|
||||
function quibble(words) {
|
||||
|
||||
return true;
|
||||
}
|
||||
```
|
||||
|
||||
# --solutions--
|
||||
|
||||
```js
|
||||
function quibble(words) {
|
||||
return "{" +
|
||||
words.slice(0, words.length - 1).join(",") +
|
||||
(words.length > 1 ? " and " : "") +
|
||||
(words[words.length - 1] || '') +
|
||||
"}";
|
||||
}
|
||||
```
|
@ -0,0 +1,132 @@
|
||||
---
|
||||
id: 596e457071c35c882915b3e4
|
||||
title: Compare a list of strings
|
||||
challengeType: 5
|
||||
forumTopicId: 302235
|
||||
dashedName: compare-a-list-of-strings
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
Given a [list](https://en.wikipedia.org/wiki/List_(abstract_data_type) "wp: List\_(abstract_data_type)") of arbitrarily many strings, implement a function for each of the following conditions:
|
||||
|
||||
<ul>
|
||||
<li>test if they are all lexically equal</li>
|
||||
<li>test if every string is lexically less than the one after it (i.e. whether the list is in strict ascending order)</li>
|
||||
</ul>
|
||||
|
||||
# --hints--
|
||||
|
||||
`allEqual` should be a function.
|
||||
|
||||
```js
|
||||
assert(typeof allEqual === 'function');
|
||||
```
|
||||
|
||||
`azSorted` should be a function.
|
||||
|
||||
```js
|
||||
assert(typeof azSorted === 'function');
|
||||
```
|
||||
|
||||
`allEqual(["AA", "AA", "AA", "AA"])` should return true.
|
||||
|
||||
```js
|
||||
assert(allEqual(testCases[0]));
|
||||
```
|
||||
|
||||
`azSorted(["AA", "AA", "AA", "AA"])` should return false.
|
||||
|
||||
```js
|
||||
assert(!azSorted(testCases[0]));
|
||||
```
|
||||
|
||||
`allEqual(["AA", "ACB", "BB", "CC"])` should return false.
|
||||
|
||||
```js
|
||||
assert(!allEqual(testCases[1]));
|
||||
```
|
||||
|
||||
`azSorted(["AA", "ACB", "BB", "CC"])` should return true.
|
||||
|
||||
```js
|
||||
assert(azSorted(testCases[1]));
|
||||
```
|
||||
|
||||
`allEqual([])` should return true.
|
||||
|
||||
```js
|
||||
assert(allEqual(testCases[2]));
|
||||
```
|
||||
|
||||
`azSorted([])` should return true.
|
||||
|
||||
```js
|
||||
assert(azSorted(testCases[2]));
|
||||
```
|
||||
|
||||
`allEqual(["AA"])` should return true.
|
||||
|
||||
```js
|
||||
assert(allEqual(testCases[3]));
|
||||
```
|
||||
|
||||
`azSorted(["AA"])` should return true.
|
||||
|
||||
```js
|
||||
assert(azSorted(testCases[3]));
|
||||
```
|
||||
|
||||
`allEqual(["BB", "AA"])` should return false.
|
||||
|
||||
```js
|
||||
assert(!allEqual(testCases[4]));
|
||||
```
|
||||
|
||||
`azSorted(["BB", "AA"])` should return false.
|
||||
|
||||
```js
|
||||
assert(!azSorted(testCases[4]));
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --after-user-code--
|
||||
|
||||
```js
|
||||
const testCases = [['AA', 'AA', 'AA', 'AA'], ['AA', 'ACB', 'BB', 'CC'], [], ['AA'], ['BB', 'AA']];
|
||||
```
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```js
|
||||
function allEqual(arr) {
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
function azSorted(arr) {
|
||||
|
||||
return true;
|
||||
}
|
||||
```
|
||||
|
||||
# --solutions--
|
||||
|
||||
```js
|
||||
function allEqual(a) {
|
||||
let out = true;
|
||||
let i = 0;
|
||||
while (++i < a.length) {
|
||||
out = out && (a[i - 1] === a[i]);
|
||||
} return out;
|
||||
}
|
||||
|
||||
function azSorted(a) {
|
||||
let out = true;
|
||||
let i = 0;
|
||||
while (++i < a.length) {
|
||||
out = out && (a[i - 1] < a[i]);
|
||||
} return out;
|
||||
}
|
||||
```
|
@ -0,0 +1,129 @@
|
||||
---
|
||||
id: 596fd036dc1ab896c5db98b1
|
||||
title: Convert seconds to compound duration
|
||||
challengeType: 5
|
||||
forumTopicId: 302236
|
||||
dashedName: convert-seconds-to-compound-duration
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
Implement a function which:
|
||||
|
||||
<ul>
|
||||
<li>takes a positive integer representing a duration in seconds as input (e.g., <code>100</code>), and</li>
|
||||
<li>returns a string which shows the same duration decomposed into weeks, days, hours, minutes, and seconds as detailed below (e.g., <code>1 min, 40 sec</code>).</li>
|
||||
</ul>
|
||||
|
||||
Demonstrate that it passes the following three test-cases:
|
||||
|
||||
<div style='font-size:115%; font-weight: bold;'>Test Cases</div>
|
||||
|
||||
| Input number | Output number |
|
||||
| ------------ | ------------------------- |
|
||||
| 7259 | <code>2 hr, 59 sec</code> |
|
||||
| 728640059 | <code>1 d</code> |
|
||||
| 6000000 | <code>9 wk, 6 d, 10 hr, 40 min</code> |
|
||||
|
||||
<div style="font-size:115%; font-weight: bold;">Details</div>
|
||||
<ul>
|
||||
<li>
|
||||
The following five units should be used:
|
||||
|
||||
| Unit | Suffix used in Output | Conversion |
|
||||
| ------ | --------------------- | --------------------- |
|
||||
| week |!!crwdBlockTags_18_sgaTkcolBdwrc!! | 1 week = 7 days |
|
||||
| day |!!crwdBlockTags_19_sgaTkcolBdwrc!! | 1 day = 24 hours |
|
||||
| hour |!!crwdBlockTags_20_sgaTkcolBdwrc!! | 1 hour = 60 minutes |
|
||||
| minute |!!crwdBlockTags_21_sgaTkcolBdwrc!! | 1 minute = 60 seconds |
|
||||
| second |!!crwdBlockTags_22_sgaTkcolBdwrc!! | --- |
|
||||
|
||||
</li>
|
||||
<li>
|
||||
However, <strong>only</strong> include quantities with non-zero values in the output (e.g., return <code>1 d</code> and not <code>0 wk, 1 d, 0 hr, 0 min, 0 sec</code>).
|
||||
</li>
|
||||
<li>
|
||||
Give larger units precedence over smaller ones as much as possible (e.g., return <code>2 min, 10 sec</code> and not <code>1 min, 70 sec</code> or <code>130 sec</code>).
|
||||
</li>
|
||||
<li>
|
||||
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).
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
# --hints--
|
||||
|
||||
`convertSeconds` should be a function.
|
||||
|
||||
```js
|
||||
assert(typeof convertSeconds === 'function');
|
||||
```
|
||||
|
||||
`convertSeconds(7259)` should return `2 hr, 59 sec`.
|
||||
|
||||
```js
|
||||
assert.equal(convertSeconds(testCases[0]), results[0]);
|
||||
```
|
||||
|
||||
`convertSeconds(86400)` should return `1 d`.
|
||||
|
||||
```js
|
||||
assert.equal(convertSeconds(testCases[1]), results[1]);
|
||||
```
|
||||
|
||||
`convertSeconds(6000000)` should return `9 wk, 6 d, 10 hr, 40 min`.
|
||||
|
||||
```js
|
||||
assert.equal(convertSeconds(testCases[2]), results[2]);
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --after-user-code--
|
||||
|
||||
```js
|
||||
const testCases = [7259, 86400, 6000000];
|
||||
const results = ['2 hr, 59 sec', '1 d', '9 wk, 6 d, 10 hr, 40 min'];
|
||||
```
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```js
|
||||
function convertSeconds(sec) {
|
||||
|
||||
return true;
|
||||
}
|
||||
```
|
||||
|
||||
# --solutions--
|
||||
|
||||
```js
|
||||
function convertSeconds(sec) {
|
||||
const localNames = ['wk', 'd', 'hr', 'min', 'sec'];
|
||||
// compoundDuration :: [String] -> Int -> String
|
||||
const compoundDuration = (labels, intSeconds) =>
|
||||
weekParts(intSeconds)
|
||||
.map((v, i) => [v, labels[i]])
|
||||
.reduce((a, x) =>
|
||||
a.concat(x[0] ? [`${x[0]} ${x[1] || '?'}`] : []), []
|
||||
)
|
||||
.join(', ');
|
||||
|
||||
// weekParts :: Int -> [Int]
|
||||
const weekParts = intSeconds => [0, 7, 24, 60, 60]
|
||||
.reduceRight((a, x) => {
|
||||
const r = a.rem;
|
||||
const mod = x !== 0 ? r % x : r;
|
||||
|
||||
return {
|
||||
rem: (r - mod) / (x || 1),
|
||||
parts: [mod].concat(a.parts)
|
||||
};
|
||||
}, {
|
||||
rem: intSeconds,
|
||||
parts: []
|
||||
})
|
||||
.parts;
|
||||
|
||||
return compoundDuration(localNames, sec);
|
||||
}
|
||||
```
|
@ -0,0 +1,79 @@
|
||||
---
|
||||
id: 596fda99c69f779975a1b67d
|
||||
title: Count occurrences of a substring
|
||||
challengeType: 5
|
||||
forumTopicId: 302237
|
||||
dashedName: count-occurrences-of-a-substring
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
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:
|
||||
|
||||
<ul>
|
||||
<li>the first argument being the string to search, and</li>
|
||||
<li>the second a substring to be searched for.</li>
|
||||
</ul>
|
||||
|
||||
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.
|
||||
|
||||
# --hints--
|
||||
|
||||
`countSubstring` should be a function.
|
||||
|
||||
```js
|
||||
assert(typeof countSubstring === 'function');
|
||||
```
|
||||
|
||||
`countSubstring("the three truths", "th")` should return `3`.
|
||||
|
||||
```js
|
||||
assert.equal(countSubstring(testCases[0], searchString[0]), results[0]);
|
||||
```
|
||||
|
||||
`countSubstring("ababababab", "abab")` should return `2`.
|
||||
|
||||
```js
|
||||
assert.equal(countSubstring(testCases[1], searchString[1]), results[1]);
|
||||
```
|
||||
|
||||
`countSubstring("abaabba*bbaba*bbab", "a*b")` should return `2`.
|
||||
|
||||
```js
|
||||
assert.equal(countSubstring(testCases[2], searchString[2]), results[2]);
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --after-user-code--
|
||||
|
||||
```js
|
||||
const testCases = ['the three truths', 'ababababab', 'abaabba*bbaba*bbab'];
|
||||
const searchString = ['th', 'abab', 'a*b'];
|
||||
const results = [3, 2, 2];
|
||||
```
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```js
|
||||
function countSubstring(str, subStr) {
|
||||
|
||||
return true;
|
||||
}
|
||||
```
|
||||
|
||||
# --solutions--
|
||||
|
||||
```js
|
||||
function countSubstring(str, subStr) {
|
||||
const escapedSubStr = subStr.replace(/[.+*?^$[\]{}()|/]/g, '\\$&');
|
||||
const matches = str.match(new RegExp(escapedSubStr, 'g'));
|
||||
return matches ? matches.length : 0;
|
||||
}
|
||||
```
|
@ -0,0 +1,82 @@
|
||||
---
|
||||
id: 59713bd26bdeb8a594fb9413
|
||||
title: Count the coins
|
||||
challengeType: 5
|
||||
forumTopicId: 302238
|
||||
dashedName: count-the-coins
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
There are four types of common coins in [US](https://en.wikipedia.org/wiki/United_States) currency:
|
||||
|
||||
<ul>
|
||||
<li>quarters (25 cents)</li>
|
||||
<li>dimes (10 cents)</li>
|
||||
<li>nickels (5 cents), and</li>
|
||||
<li>pennies (1 cent)</li>
|
||||
</ul>
|
||||
|
||||
<p>There are six ways to make change for 15 cents:</p>
|
||||
|
||||
<ul>
|
||||
<li>A dime and a nickel</li>
|
||||
<li>A dime and 5 pennies</li>
|
||||
<li>3 nickels</li>
|
||||
<li>2 nickels and 5 pennies</li>
|
||||
<li>A nickel and 10 pennies</li>
|
||||
<li>15 pennies</li>
|
||||
</ul>
|
||||
|
||||
# --instructions--
|
||||
|
||||
Implement a function to determine how many ways there are to make change for a dollar using these common coins (1 dollar = 100 cents)
|
||||
|
||||
# --hints--
|
||||
|
||||
`countCoins` should be a function.
|
||||
|
||||
```js
|
||||
assert(typeof countCoins === 'function');
|
||||
```
|
||||
|
||||
`countCoins()` should return 242.
|
||||
|
||||
```js
|
||||
assert.equal(countCoins(), 242);
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```js
|
||||
function countCoins() {
|
||||
|
||||
return true;
|
||||
}
|
||||
```
|
||||
|
||||
# --solutions--
|
||||
|
||||
```js
|
||||
function countCoins() {
|
||||
let t = 100;
|
||||
const operands = [1, 5, 10, 25];
|
||||
const targetsLength = t + 1;
|
||||
const operandsLength = operands.length;
|
||||
t = [1];
|
||||
|
||||
for (let a = 0; a < operandsLength; a++) {
|
||||
for (let b = 1; b < targetsLength; b++) {
|
||||
// initialise undefined target
|
||||
t[b] = t[b] ? t[b] : 0;
|
||||
|
||||
// accumulate target + operand ways
|
||||
t[b] += (b < operands[a]) ? 0 : t[b - operands[a]];
|
||||
}
|
||||
}
|
||||
|
||||
return t[targetsLength - 1];
|
||||
}
|
||||
```
|
@ -0,0 +1,167 @@
|
||||
---
|
||||
id: 59713da0a428c1a62d7db430
|
||||
title: Cramer's rule
|
||||
challengeType: 5
|
||||
forumTopicId: 302239
|
||||
dashedName: cramers-rule
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
In [linear algebra](https://en.wikipedia.org/wiki/linear algebra "wp: linear algebra"), [Cramer's rule](https://en.wikipedia.org/wiki/Cramer's rule "wp: Cramer's rule") is an explicit formula for the solution of a [system of linear equations](https://en.wikipedia.org/wiki/system of linear equations "wp: 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} }.$
|
||||
|
||||
# --instructions--
|
||||
|
||||
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.
|
||||
|
||||
# --hints--
|
||||
|
||||
`cramersRule` should be a function.
|
||||
|
||||
```js
|
||||
assert(typeof cramersRule === 'function');
|
||||
```
|
||||
|
||||
`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]`.
|
||||
|
||||
```js
|
||||
assert.deepEqual(cramersRule(matrices[0], freeTerms[0]), answers[0]);
|
||||
```
|
||||
|
||||
`cramersRule([[3, 1, 1], [2, 2, 5], [1, -3, -4]], [3, -1, 2])` should return `[1, 1, -1]`.
|
||||
|
||||
```js
|
||||
assert.deepEqual(cramersRule(matrices[1], freeTerms[1]), answers[1]);
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --after-user-code--
|
||||
|
||||
```js
|
||||
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]];
|
||||
```
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```js
|
||||
function cramersRule(matrix, freeTerms) {
|
||||
|
||||
return true;
|
||||
}
|
||||
```
|
||||
|
||||
# --solutions--
|
||||
|
||||
```js
|
||||
/**
|
||||
* Compute Cramer's Rule
|
||||
* @param {array} matrix x,y,z, etc. terms
|
||||
* @param {array} freeTerms
|
||||
* @return {array} solution for x,y,z, etc.
|
||||
*/
|
||||
function cramersRule(matrix, freeTerms) {
|
||||
const det = detr(matrix);
|
||||
const returnArray = [];
|
||||
let i;
|
||||
|
||||
for (i = 0; i < matrix[0].length; i++) {
|
||||
const tmpMatrix = insertInTerms(matrix, freeTerms, i);
|
||||
returnArray.push(detr(tmpMatrix) / det);
|
||||
}
|
||||
return returnArray;
|
||||
}
|
||||
|
||||
/**
|
||||
* Inserts single dimensional array into
|
||||
* @param {array} matrix multidimensional array to have ins inserted into
|
||||
* @param {array} ins single dimensional array to be inserted vertically into matrix
|
||||
* @param {array} at zero based offset for ins to be inserted into matrix
|
||||
* @return {array} New multidimensional array with ins replacing the at column in matrix
|
||||
*/
|
||||
function insertInTerms(matrix, ins, at) {
|
||||
const tmpMatrix = clone(matrix);
|
||||
let i;
|
||||
for (i = 0; i < matrix.length; i++) {
|
||||
tmpMatrix[i][at] = ins[i];
|
||||
}
|
||||
return tmpMatrix;
|
||||
}
|
||||
/**
|
||||
* Compute the determinate of a matrix. No protection, assumes square matrix
|
||||
* function borrowed, and adapted from MIT Licensed numericjs library (www.numericjs.com)
|
||||
* @param {array} m Input Matrix (multidimensional array)
|
||||
* @return {number} result rounded to 2 decimal
|
||||
*/
|
||||
function detr(m) {
|
||||
let ret = 1;
|
||||
let j;
|
||||
let k;
|
||||
const A = clone(m);
|
||||
const n = m[0].length;
|
||||
let alpha;
|
||||
|
||||
for (j = 0; j < n - 1; j++) {
|
||||
k = j;
|
||||
for (let i = j + 1; i < n; i++) { if (Math.abs(A[i][j]) > Math.abs(A[k][j])) { k = i; } }
|
||||
if (k !== j) {
|
||||
const temp = A[k]; A[k] = A[j]; A[j] = temp;
|
||||
ret *= -1;
|
||||
}
|
||||
const Aj = A[j];
|
||||
for (let i = j + 1; i < n; i++) {
|
||||
const Ai = A[i];
|
||||
alpha = Ai[j] / Aj[j];
|
||||
for (k = j + 1; k < n - 1; k += 2) {
|
||||
const k1 = k + 1;
|
||||
Ai[k] -= Aj[k] * alpha;
|
||||
Ai[k1] -= Aj[k1] * alpha;
|
||||
}
|
||||
if (k !== n) { Ai[k] -= Aj[k] * alpha; }
|
||||
}
|
||||
if (Aj[j] === 0) { return 0; }
|
||||
ret *= Aj[j];
|
||||
}
|
||||
return Math.round(ret * A[j][j] * 100) / 100;
|
||||
}
|
||||
|
||||
/**
|
||||
* Clone two dimensional Array using ECMAScript 5 map function and EcmaScript 3 slice
|
||||
* @param {array} m Input matrix (multidimensional array) to clone
|
||||
* @return {array} New matrix copy
|
||||
*/
|
||||
function clone(m) {
|
||||
return m.map(a => a.slice());
|
||||
}
|
||||
```
|
@ -0,0 +1,101 @@
|
||||
---
|
||||
id: 5a23c84252665b21eecc7e03
|
||||
title: Cumulative standard deviation
|
||||
challengeType: 5
|
||||
forumTopicId: 302240
|
||||
dashedName: cumulative-standard-deviation
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
Write a function that takes an array of numbers as parameter and returns the [standard deviation](https://en.wikipedia.org/wiki/Standard Deviation) of the series.
|
||||
|
||||
# --hints--
|
||||
|
||||
`standardDeviation` should be a function.
|
||||
|
||||
```js
|
||||
assert(typeof standardDeviation == 'function');
|
||||
```
|
||||
|
||||
`standardDeviation([2, 4, 4, 4, 5, 5, 7, 9])` should return a number.
|
||||
|
||||
```js
|
||||
assert(typeof standardDeviation([2, 4, 4, 4, 5, 5, 7, 9]) == 'number');
|
||||
```
|
||||
|
||||
`standardDeviation([2, 4, 4, 4, 5, 5, 7, 9])` should return `2`.
|
||||
|
||||
```js
|
||||
assert.equal(standardDeviation([2, 4, 4, 4, 5, 5, 7, 9]), 2);
|
||||
```
|
||||
|
||||
`standardDeviation([600, 470, 170, 430, 300])` should return `147.323`.
|
||||
|
||||
```js
|
||||
assert.equal(standardDeviation([600, 470, 170, 430, 300]), 147.323);
|
||||
```
|
||||
|
||||
`standardDeviation([75, 83, 96, 100, 121, 125])` should return `18.239`.
|
||||
|
||||
```js
|
||||
assert.equal(standardDeviation([75, 83, 96, 100, 121, 125]), 18.239);
|
||||
```
|
||||
|
||||
`standardDeviation([23, 37, 45, 49, 56, 63, 63, 70, 72, 82])` should return `16.87`.
|
||||
|
||||
```js
|
||||
assert.equal(
|
||||
standardDeviation([23, 37, 45, 49, 56, 63, 63, 70, 72, 82]),
|
||||
16.87
|
||||
);
|
||||
```
|
||||
|
||||
`standardDeviation([271, 354, 296, 301, 333, 326, 285, 298, 327, 316, 287, 314])` should return `22.631`.
|
||||
|
||||
```js
|
||||
assert.equal(
|
||||
standardDeviation([
|
||||
271,
|
||||
354,
|
||||
296,
|
||||
301,
|
||||
333,
|
||||
326,
|
||||
285,
|
||||
298,
|
||||
327,
|
||||
316,
|
||||
287,
|
||||
314
|
||||
]),
|
||||
22.631
|
||||
);
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```js
|
||||
function standardDeviation(arr) {
|
||||
|
||||
}
|
||||
```
|
||||
|
||||
# --solutions--
|
||||
|
||||
```js
|
||||
function standardDeviation(arr) {
|
||||
var sum = 0,
|
||||
sum_sq = 0,
|
||||
n = arr.length;
|
||||
arr.forEach(function(e) {
|
||||
sum += e;
|
||||
sum_sq += e * e;
|
||||
});
|
||||
|
||||
var std_dev = Math.sqrt(sum_sq / n - Math.pow(sum / n, 2));
|
||||
return Math.round(std_dev * 1000) / 1000;
|
||||
}
|
||||
```
|
@ -0,0 +1,118 @@
|
||||
---
|
||||
id: 5a23c84252665b21eecc7e05
|
||||
title: CUSIP
|
||||
challengeType: 5
|
||||
forumTopicId: 302241
|
||||
dashedName: cusip
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
A **CUSIP** is a nine-character alphanumeric code that identifies a North American financial security for the purposes of facilitating clearing and settlement of trades. The CUSIP was adopted as an American National Standard under Accredited Standards X9.6.
|
||||
|
||||
# --instructions--
|
||||
|
||||
Write a function that takes a string as a parameter and checks if the string is valid CUSIP.
|
||||
|
||||
# --hints--
|
||||
|
||||
`isCusip` should be a function.
|
||||
|
||||
```js
|
||||
assert(typeof isCusip == 'function');
|
||||
```
|
||||
|
||||
`isCusip("037833100")` should return a boolean.
|
||||
|
||||
```js
|
||||
assert(typeof isCusip('037833100') == 'boolean');
|
||||
```
|
||||
|
||||
`isCusip("037833100")` should return `true`.
|
||||
|
||||
```js
|
||||
assert.equal(isCusip('037833100'), true);
|
||||
```
|
||||
|
||||
`isCusip("17275R102")` should return `true`.
|
||||
|
||||
```js
|
||||
assert.equal(isCusip('17275R102'), true);
|
||||
```
|
||||
|
||||
`isCusip("38259P50a")` should return `false`.
|
||||
|
||||
```js
|
||||
assert.equal(isCusip('38259P50a'), false);
|
||||
```
|
||||
|
||||
`isCusip("38259P508")` should return `true`.
|
||||
|
||||
```js
|
||||
assert.equal(isCusip('38259P508'), true);
|
||||
```
|
||||
|
||||
`isCusip("38259P50#")` should return `false`.
|
||||
|
||||
```js
|
||||
assert.equal(isCusip('38259P50#'), false);
|
||||
```
|
||||
|
||||
`isCusip("68389X105")` should return `true`.
|
||||
|
||||
```js
|
||||
assert.equal(isCusip('68389X105'), true);
|
||||
```
|
||||
|
||||
`isCusip("68389X106")` should return `false`.
|
||||
|
||||
```js
|
||||
assert.equal(isCusip('68389X106'), false);
|
||||
```
|
||||
|
||||
`isCusip("5949181")` should return `false`.
|
||||
|
||||
```js
|
||||
assert.equal(isCusip('5949181'), false);
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```js
|
||||
function isCusip(s) {
|
||||
|
||||
}
|
||||
```
|
||||
|
||||
# --solutions--
|
||||
|
||||
```js
|
||||
function isCusip(s) {
|
||||
if (s.length != 9) return false;
|
||||
var sum = 0;
|
||||
var ASCII = x => x.charCodeAt(0);
|
||||
for (var i = 0; i < 7; i++) {
|
||||
var c = s.charCodeAt(i);
|
||||
|
||||
var v;
|
||||
if (c >= ASCII('0') && c <= ASCII('9')) {
|
||||
v = c - 48;
|
||||
} else if (c >= ASCII('A') && c <= ASCII('Z')) {
|
||||
v = c - 64; // lower case letters apparently invalid
|
||||
} else if (c == ASCII('*')) {
|
||||
v = 36;
|
||||
} else if (c == ASCII('@')) {
|
||||
v = 37;
|
||||
} else if (c == ASCII('#')) {
|
||||
v = 38;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
if (i % 2 == 1) v *= 2; // check if odd as using 0-based indexing
|
||||
sum += Math.floor(v / 10) + (v % 10);
|
||||
}
|
||||
return s.charCodeAt(8) - 48 == (10 - (sum % 10)) % 10;
|
||||
}
|
||||
```
|
@ -0,0 +1,172 @@
|
||||
---
|
||||
id: 5a23c84252665b21eecc7e06
|
||||
title: Cut a rectangle
|
||||
challengeType: 5
|
||||
forumTopicId: 302242
|
||||
dashedName: cut-a-rectangle
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
A given rectangle is made from *m* × *n* squares. If *m* and *n* are not both odd, then it is possible to cut a path through the rectangle along the square edges such that the rectangle splits into two connected pieces with the same shape (after rotating one of the pieces by 180°). All such paths for 2 × 2 and 4 × 3 rectangles are shown below.
|
||||
|
||||
<div style="width: 100%; text-align: center;">
|
||||
<svg xmlns="https://www.w3.org/2000/svg" xmlns:xlink="https://www.w3.org/1999/xlink" width="520" height="170" aria-hidden="true" alt="Diagram showing the possible paths for 2 by 2 and 4 by 3 rectangles">
|
||||
<style>
|
||||
.g { fill: none; stroke: #ccc }
|
||||
.s, .s2 { fill: #bff; stroke: black; fill-opacity: .4 }
|
||||
.s2 { fill: #fbf }
|
||||
.d { stroke:black; fill:none}
|
||||
</style>
|
||||
<defs> <g id="m">
|
||||
<g id="h4"><g id="h2">
|
||||
<path id="h" d="m0 10h 640" class="g"/>
|
||||
<use xlink:href="#h" transform="translate(0,20)"/></g>
|
||||
<use xlink:href="#h2" transform="translate(0, 40)"/></g>
|
||||
<use xlink:href="#h4" transform="translate(0,80)"/>
|
||||
<g id="v8"><g id="v4"><g id="v2">
|
||||
<path id="v" d="m10 0v160 m 20 0 v-160" class="g"/>
|
||||
<use xlink:href="#v" transform="translate(40,0)"/></g>
|
||||
<use xlink:href="#v2" transform="translate(80,0)"/></g>
|
||||
<use xlink:href="#v4" transform="translate(160,0)"/></g>
|
||||
<use xlink:href="#v8" transform="translate(320,0)"/></g>
|
||||
<path id="b" d="m0 0h80v60h-80z" class="s"/>
|
||||
</defs>
|
||||
<g transform="translate(.5,.5)">
|
||||
<use xlink:href="#m"/>
|
||||
<g transform="translate(10,10)">
|
||||
<path d="m0 0v40h40v-40z" class="s2"/><path d="m20 0v40" class="d"/>
|
||||
<path d="m60 0v40h40v-40z" class="s2"/><path d="m60 20h40" class="d"/>
|
||||
<g transform="translate(120, 0)">
|
||||
<use xlink:href="#b"/><path d="m0 20h40v20h40" class="d"/></g>
|
||||
<g transform="translate(220, 0)">
|
||||
<use xlink:href="#b"/><path d="m0 40h40v-20h40" class="d"/></g>
|
||||
<g transform="translate(320, 0)">
|
||||
<use xlink:href="#b"/><path d="m20 0v40h20v-20h20v40" class="d"/></g>
|
||||
<g transform="translate(420, 0)">
|
||||
<use xlink:href="#b"/><path d="m60 0v40h-20v-20h-20v40" class="d"/></g>
|
||||
<g transform="translate(20, 80)">
|
||||
<use xlink:href="#b"/><path d="m40 0v60" class="d"/></g>
|
||||
<g transform="translate(120, 80)">
|
||||
<use xlink:href="#b"/><path d="m60 0v20h-20v20h-20v20" class="d"/></g>
|
||||
<g transform="translate(220, 80)">
|
||||
<use xlink:href="#b"/><path d="m20 0v20h20v20h20v20" class="d"/></g>
|
||||
<g transform="translate(320, 80)">
|
||||
<use xlink:href="#b"/><path d="m0 20h20v20h20v-20h20v20h20" class="d"/></g>
|
||||
<g transform="translate(420, 80)">
|
||||
<use xlink:href="#b"/><path d="m0 40h20v-20h20v20h20v-20h20" class="d"/></g>
|
||||
</g></g>
|
||||
</svg>
|
||||
</div>
|
||||
|
||||
# --instructions--
|
||||
|
||||
Write a function that calculates the number of different ways to cut an *m* × *n* rectangle.
|
||||
|
||||
# --hints--
|
||||
|
||||
`cutRectangle` should be a function.
|
||||
|
||||
```js
|
||||
assert(typeof cutRectangle == 'function');
|
||||
```
|
||||
|
||||
`cutRectangle(2, 2)` should return a number.
|
||||
|
||||
```js
|
||||
assert(typeof cutRectangle(2, 2) == 'number');
|
||||
```
|
||||
|
||||
`cutRectangle(2, 2)` should return `2`.
|
||||
|
||||
```js
|
||||
assert.equal(cutRectangle(2, 2), 2);
|
||||
```
|
||||
|
||||
`cutRectangle(4, 3)` should return `9`.
|
||||
|
||||
```js
|
||||
assert.equal(cutRectangle(4, 3), 9);
|
||||
```
|
||||
|
||||
`cutRectangle(4, 4)` should return `22`.
|
||||
|
||||
```js
|
||||
assert.equal(cutRectangle(4, 4), 22);
|
||||
```
|
||||
|
||||
`cutRectangle(8, 3)` should return `53`.
|
||||
|
||||
```js
|
||||
assert.equal(cutRectangle(8, 3), 53);
|
||||
```
|
||||
|
||||
`cutRectangle(7, 4)` should return `151`.
|
||||
|
||||
```js
|
||||
assert.equal(cutRectangle(7, 4), 151);
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```js
|
||||
function cutRectangle(w, h) {
|
||||
|
||||
}
|
||||
```
|
||||
|
||||
# --solutions--
|
||||
|
||||
```js
|
||||
function cutRectangle(w, h) {
|
||||
if (w % 2 == 1 && h % 2 == 1) return;
|
||||
|
||||
var dirs = [[0, -1], [-1, 0], [0, 1], [1, 0]];
|
||||
|
||||
var grid = new Array(h);
|
||||
for (var i = 0; i < grid.length; i++) grid[i] = new Array(w);
|
||||
var stack = [];
|
||||
|
||||
var half = Math.floor((w * h) / 2);
|
||||
var bits = Math.pow(2, half) - 1;
|
||||
var result = 0;
|
||||
for (; bits > 0; bits -= 2) {
|
||||
for (var i = 0; i < half; i++) {
|
||||
var r = Math.floor(i / w);
|
||||
var c = i % w;
|
||||
grid[r][c] = (bits & (1 << i)) != 0 ? 1 : 0;
|
||||
grid[h - r - 1][w - c - 1] = 1 - grid[r][c];
|
||||
}
|
||||
|
||||
stack.push(0);
|
||||
grid[0][0] = 2;
|
||||
var count = 1;
|
||||
while (stack.length != 0) {
|
||||
var pos = stack.pop();
|
||||
var r = Math.floor(pos / w);
|
||||
var c = pos % w;
|
||||
|
||||
for (var dir of dirs) {
|
||||
var nextR = r + dir[0];
|
||||
var nextC = c + dir[1];
|
||||
|
||||
if (nextR >= 0 && nextR < h && nextC >= 0 && nextC < w) {
|
||||
if (grid[nextR][nextC] == 1) {
|
||||
stack.push(nextR * w + nextC);
|
||||
grid[nextR][nextC] = 2;
|
||||
count++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (count == half) {
|
||||
result++;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
```
|
@ -0,0 +1,84 @@
|
||||
---
|
||||
id: 59669d08d75b60482359409f
|
||||
title: Date format
|
||||
challengeType: 5
|
||||
forumTopicId: 302243
|
||||
dashedName: date-format
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
Return an array with the current date in the formats:
|
||||
|
||||
<ul>
|
||||
<li>2007-11-23</li>
|
||||
<li>Friday, November 23, 2007</li>
|
||||
</ul>
|
||||
|
||||
Example output: `['2007-11-23', 'Friday, November 23, 2007']`
|
||||
|
||||
# --hints--
|
||||
|
||||
`getDateFormats` should be a function.
|
||||
|
||||
```js
|
||||
assert(typeof getDateFormats === 'function');
|
||||
```
|
||||
|
||||
`getDateFormats` should return an object.
|
||||
|
||||
```js
|
||||
assert(typeof getDateFormats() === 'object');
|
||||
```
|
||||
|
||||
`getDateFormats` should return an array with 2 elements.
|
||||
|
||||
```js
|
||||
assert(getDateFormats().length === 2);
|
||||
```
|
||||
|
||||
`getDateFormats` should return the correct date in the right format
|
||||
|
||||
```js
|
||||
assert.deepEqual(getDateFormats(), dates, equalsMessage);
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --after-user-code--
|
||||
|
||||
```js
|
||||
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: <code>getDataFormats()</code> should return <code>["${dates[0]}", "${dates[1]}"]</code>.`;
|
||||
```
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```js
|
||||
function getDateFormats() {
|
||||
|
||||
return true;
|
||||
}
|
||||
```
|
||||
|
||||
# --solutions--
|
||||
|
||||
```js
|
||||
function getDateFormats() {
|
||||
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];
|
||||
}
|
||||
```
|
@ -0,0 +1,109 @@
|
||||
---
|
||||
id: 5966c21cf732a95f1b67dd28
|
||||
title: Date manipulation
|
||||
challengeType: 5
|
||||
forumTopicId: 302244
|
||||
dashedName: date-manipulation
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
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 6 2009 7:30pm EST"`
|
||||
|
||||
Example output: `"March 7 2009 7:30am EST"`
|
||||
|
||||
# --hints--
|
||||
|
||||
`add12Hours` should be a function.
|
||||
|
||||
```js
|
||||
assert(typeof add12Hours === 'function');
|
||||
```
|
||||
|
||||
`add12Hours(dateString)` should return a string.
|
||||
|
||||
```js
|
||||
assert(typeof add12Hours('January 17 2017 11:43am EST') === 'string');
|
||||
```
|
||||
|
||||
`add12Hours("January 17 2017 11:43am EST")` should return `"January 17 2017 11:43pm EST"`
|
||||
|
||||
```js
|
||||
assert(
|
||||
add12Hours('January 17 2017 11:43am EST') === 'January 17 2017 11:43pm EST'
|
||||
);
|
||||
```
|
||||
|
||||
Should handle day change. `add12Hours("March 6 2009 7:30pm EST")` should return `"March 7 2009 7:30am EST"`
|
||||
|
||||
```js
|
||||
assert(add12Hours('March 6 2009 7:30pm EST') === 'March 7 2009 7:30am EST');
|
||||
```
|
||||
|
||||
Should handle month change in a leap years. `add12Hours("February 29 2004 9:15pm EST")` should return `"March 1 2004 9:15am EST"`
|
||||
|
||||
```js
|
||||
assert(add12Hours('February 29 2004 9:15pm EST') === 'March 1 2004 9:15am EST');
|
||||
```
|
||||
|
||||
Should handle month change in a common years. `add12Hours("February 28 1999 3:15pm EST")` should return `"March 1 1999 3:15am EST"`
|
||||
|
||||
```js
|
||||
assert(add12Hours('February 28 1999 3:15pm EST') === 'March 1 1999 3:15am EST');
|
||||
```
|
||||
|
||||
Should handle year change. `add12Hours("December 31 2020 1:45pm EST")` should return `"January 1 2021 1:45am EST"`
|
||||
|
||||
```js
|
||||
assert(
|
||||
add12Hours('December 31 2020 1:45pm EST') === 'January 1 2021 1:45am EST'
|
||||
);
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```js
|
||||
function add12Hours(dateString) {
|
||||
|
||||
return true;
|
||||
}
|
||||
```
|
||||
|
||||
# --solutions--
|
||||
|
||||
```js
|
||||
function add12Hours(dateString) {
|
||||
const months = ['January', 'February', 'March', 'April', 'May', 'June',
|
||||
'July', 'August', 'September', 'October', 'November', 'December'];
|
||||
// Get the parts of the string
|
||||
const parts = dateString.split(' ');
|
||||
const month = months.indexOf(parts[0]);
|
||||
const day = parseInt(parts[1], 10);
|
||||
const year = parseInt(parts[2], 10);
|
||||
const time = parts[3].split(':');
|
||||
let hours = parseInt(time[0], 10);
|
||||
if (time[1].slice(-2) === 'pm') {
|
||||
hours += 12;
|
||||
}
|
||||
const minutes = parseInt(time[1].slice(0, -2), 10);
|
||||
|
||||
// Create a date with given parts, and updated hours
|
||||
const date = new Date();
|
||||
date.setFullYear(year, month, day);
|
||||
date.setHours(hours + 12); // Add 12 hours
|
||||
date.setMinutes(minutes);
|
||||
|
||||
let hoursOutput = date.getHours();
|
||||
let abbreviation = 'am';
|
||||
if (hoursOutput > 12) {
|
||||
hoursOutput -= 12;
|
||||
abbreviation = 'pm';
|
||||
}
|
||||
|
||||
return `${months[date.getMonth()]} ${date.getDate()} ${date.getFullYear()} ${hoursOutput}:${date.getMinutes()}${abbreviation} EST`;
|
||||
}
|
||||
```
|
@ -0,0 +1,74 @@
|
||||
---
|
||||
id: 5966f99c45e8976909a85575
|
||||
title: Day of the week
|
||||
challengeType: 5
|
||||
forumTopicId: 302245
|
||||
dashedName: 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).
|
||||
|
||||
# --instructions--
|
||||
|
||||
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.
|
||||
|
||||
# --hints--
|
||||
|
||||
`findXmasSunday` should be a function.
|
||||
|
||||
```js
|
||||
assert(typeof findXmasSunday === 'function');
|
||||
```
|
||||
|
||||
`findXmasSunday(2000, 2100)` should return an array.
|
||||
|
||||
```js
|
||||
assert(typeof findXmasSunday(2000, 2100) === 'object');
|
||||
```
|
||||
|
||||
`findXmasSunday(1970, 2017)` should return `[1977, 1983, 1988, 1994, 2005, 2011, 2016]`
|
||||
|
||||
```js
|
||||
assert.deepEqual(findXmasSunday(1970, 2017), firstSolution);
|
||||
```
|
||||
|
||||
`findXmasSunday(2008, 2121)` should return `[2011, 2016, 2022, 2033, 2039, 2044, 2050, 2061, 2067, 2072, 2078, 2089, 2095, 2101, 2107, 2112, 2118]`
|
||||
|
||||
```js
|
||||
assert.deepEqual(findXmasSunday(2008, 2121), secondSolution);
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --after-user-code--
|
||||
|
||||
```js
|
||||
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];
|
||||
```
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```js
|
||||
function findXmasSunday(start, end) {
|
||||
|
||||
return true;
|
||||
}
|
||||
```
|
||||
|
||||
# --solutions--
|
||||
|
||||
```js
|
||||
function findXmasSunday(start, end) {
|
||||
const xmasSunday = [];
|
||||
for (let year = start; year <= end; year++) {
|
||||
const xmas = new Date(year, 11, 25);
|
||||
if (xmas.getDay() === 0) {
|
||||
xmasSunday.push(year);
|
||||
}
|
||||
}
|
||||
return xmasSunday;
|
||||
}
|
||||
```
|
@ -0,0 +1,210 @@
|
||||
---
|
||||
id: 59694356a6e7011f7f1c5f4e
|
||||
title: Deal cards for FreeCell
|
||||
challengeType: 5
|
||||
forumTopicId: 302246
|
||||
dashedName: deal-cards-for-freecell
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
*FreeCell* 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](https://rosettacode.org/wiki/DOS "DOS"), then [Windows](https://rosettacode.org/wiki/Windows "Windows"). This version introduced 32000 numbered deals.
|
||||
|
||||
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](https://rosettacode.org/wiki/linear congruential generator "linear congruential generator") from Microsoft C:
|
||||
|
||||
<ul>
|
||||
<li>$state_{n + 1} \equiv 214013 \times state_n + 2531011 \pmod{2^{31}}$</li>
|
||||
<li>$rand_n = state_n \div 2^{16}$</li>
|
||||
<li>$rand_n$ is in range 0 to 32767.</li>
|
||||
</ul>
|
||||
|
||||
The algorithm follows:
|
||||
|
||||
<ol>
|
||||
<li>Seed the RNG with the number of the deal.
|
||||
</li><li>Create an <a href='https://rosettacode.org/wiki/array' title='array' target='_blank'>array</a> of 52 cards: Ace of Clubs, Ace of Diamonds, Ace of Hearts, Ace of Spades, 2 of Clubs, 2 of Diamonds, and so on through the ranks: Ace, 2, 3, 4, 5, 6, 7, 8, 9, 10, Jack, Queen, King. The array indexes are 0 to 51, with Ace of Clubs at 0, and King of Spades at 51.</li>
|
||||
<li>Until the array is empty:</li>
|
||||
<li>Choose a random card at index ≡ next random number (mod array length).</li>
|
||||
<ul>
|
||||
<li>Swap this random card with the last card of the array.</li>
|
||||
<li>Remove this random card from the array. (Array length goes down by 1.)</li>
|
||||
<li>Deal this random card.</li>
|
||||
</ul>
|
||||
<li>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.</li>
|
||||
</ol>
|
||||
|
||||
**Example:**
|
||||
|
||||
**Order to deal cards**
|
||||
|
||||
<pre> 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</pre>
|
||||
|
||||
**Game #1**
|
||||
|
||||
```js
|
||||
[
|
||||
['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**
|
||||
|
||||
```js
|
||||
[
|
||||
['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']
|
||||
]
|
||||
```
|
||||
|
||||
# --instructions--
|
||||
|
||||
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](https://freecellgamesolutions.com/). (Summon a video solution, and it displays the initial deal.)
|
||||
|
||||
# --hints--
|
||||
|
||||
`dealFreeCell` should be a function.
|
||||
|
||||
```js
|
||||
assert(typeof dealFreeCell === 'function');
|
||||
```
|
||||
|
||||
`dealFreeCell(seed)` should return an object.
|
||||
|
||||
```js
|
||||
assert(typeof dealFreeCell(1) === 'object');
|
||||
```
|
||||
|
||||
`dealFreeCell(seed)` should return an array of length 7.
|
||||
|
||||
```js
|
||||
assert(dealFreeCell(1).length === 7);
|
||||
```
|
||||
|
||||
`dealFreeCell(1)` should return an array identical to example "Game #1"
|
||||
|
||||
```js
|
||||
assert.deepEqual(dealFreeCell(1), game1);
|
||||
```
|
||||
|
||||
`dealFreeCell(617)` should return an array identical to example "Game #617"
|
||||
|
||||
```js
|
||||
assert.deepEqual(dealFreeCell(617), game617);
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --after-user-code--
|
||||
|
||||
```js
|
||||
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']
|
||||
];
|
||||
```
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```js
|
||||
function dealFreeCell(seed) {
|
||||
|
||||
return true;
|
||||
}
|
||||
```
|
||||
|
||||
# --solutions--
|
||||
|
||||
```js
|
||||
// RNG
|
||||
function FreeCellRNG(seed) {
|
||||
return {
|
||||
lastNum: seed,
|
||||
next() {
|
||||
this.lastNum = ((214013 * this.lastNum) + 2531011) % (Math.pow(2, 31));
|
||||
return this.lastNum >> 16;
|
||||
}
|
||||
};
|
||||
}
|
||||
// Get cards
|
||||
function getDeck() {
|
||||
const ranks = ['A', '2', '3', '4', '5', '6', '7', '8', '9', 'T', 'J', 'Q', 'K'];
|
||||
const suits = ['C', 'D', 'H', 'S'];
|
||||
const cards = [];
|
||||
for (let i = 0; i < ranks.length; i += 1) {
|
||||
for (let j = 0; j < suits.length; j += 1) {
|
||||
cards.push(`${ranks[i]}${suits[j]}`);
|
||||
}
|
||||
}
|
||||
return cards;
|
||||
}
|
||||
function dealFreeCell(seed) {
|
||||
const rng = FreeCellRNG(seed);
|
||||
const deck = getDeck();
|
||||
|
||||
const deltCards = [[], [], [], [], [], [], []];
|
||||
let currentColumn = 0;
|
||||
let currentRow = 0;
|
||||
|
||||
let rand;
|
||||
let temp;
|
||||
let card;
|
||||
while (deck.length > 0) {
|
||||
// Choose a random card
|
||||
rand = rng.next() % deck.length;
|
||||
|
||||
// Swap this random card with the last card in the array
|
||||
temp = deck[deck.length - 1];
|
||||
deck[deck.length - 1] = deck[rand];
|
||||
deck[rand] = temp;
|
||||
|
||||
// Remove this card from the array
|
||||
card = deck.pop();
|
||||
|
||||
// Deal this card
|
||||
deltCards[currentRow].push(card);
|
||||
currentColumn += 1;
|
||||
if (currentColumn === 8) {
|
||||
currentColumn = 0;
|
||||
currentRow += 1;
|
||||
}
|
||||
}
|
||||
|
||||
return deltCards;
|
||||
}
|
||||
```
|
@ -0,0 +1,85 @@
|
||||
---
|
||||
id: 596a8888ab7c01048de257d5
|
||||
title: Deepcopy
|
||||
challengeType: 5
|
||||
forumTopicId: 302247
|
||||
dashedName: deepcopy
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
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:
|
||||
|
||||
<ul>
|
||||
<li>Objects with properties that are functions</li>
|
||||
<li>Date objects or object with properties that are Date objects</li>
|
||||
<li>RegEx or object with properties that are RegEx objects</li>
|
||||
<li>Prototype copying</li>
|
||||
</ul>
|
||||
|
||||
# --hints--
|
||||
|
||||
`deepcopy` should be a function.
|
||||
|
||||
```js
|
||||
assert(typeof deepcopy === 'function');
|
||||
```
|
||||
|
||||
`deepcopy({test: "test"})` should return an object.
|
||||
|
||||
```js
|
||||
assert(typeof deepcopy(obj1) === 'object');
|
||||
```
|
||||
|
||||
`deepcopy` should not return the same object that was provided.
|
||||
|
||||
```js
|
||||
assert(deepcopy(obj2) != obj2);
|
||||
```
|
||||
|
||||
When passed an object containing an array, `deepcopy` should return a deep copy of the object.
|
||||
|
||||
```js
|
||||
assert.deepEqual(deepcopy(obj2), obj2);
|
||||
```
|
||||
|
||||
When passed an object containing another object, `deepcopy` should return a deep copy of the object.
|
||||
|
||||
```js
|
||||
assert.deepEqual(deepcopy(obj3), obj3);
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --after-user-code--
|
||||
|
||||
```js
|
||||
const obj1 = { test: 'test' };
|
||||
const obj2 = {
|
||||
t: 'test',
|
||||
a: ['an', 'array']
|
||||
};
|
||||
const obj3 = {
|
||||
t: 'try',
|
||||
o: obj2
|
||||
};
|
||||
```
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```js
|
||||
function deepcopy(obj) {
|
||||
|
||||
return true;
|
||||
}
|
||||
```
|
||||
|
||||
# --solutions--
|
||||
|
||||
```js
|
||||
function deepcopy(obj) {
|
||||
return JSON.parse(JSON.stringify(obj));
|
||||
}
|
||||
```
|
@ -0,0 +1,132 @@
|
||||
---
|
||||
id: 597089c87eec450c68aa1643
|
||||
title: Define a primitive data type
|
||||
challengeType: 5
|
||||
forumTopicId: 302248
|
||||
dashedName: define-a-primitive-data-type
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
Define a type that behaves like an integer but has a lowest valid value of 1 and a highest valid value of 10.
|
||||
|
||||
Error handling:
|
||||
|
||||
<ul>
|
||||
<li>If you try to instantiate a <code>Num</code> with a value outside of 1 - 10, it should throw a <code>TypeError</code> with an error message of <code>'Out of range'</code>.</li>
|
||||
<li>If you try to instantiate a <code>Num</code> with a value that is not a number, it should throw a <code>TypeError</code> with an error message of <code>'Not a Number'</code>.</li>
|
||||
</ul>
|
||||
|
||||
# --hints--
|
||||
|
||||
`Num` should be a function.
|
||||
|
||||
```js
|
||||
assert(typeof Num === 'function');
|
||||
```
|
||||
|
||||
`new Num(4)` should return an object.
|
||||
|
||||
```js
|
||||
assert(typeof new Num(4) === 'object');
|
||||
```
|
||||
|
||||
`new Num('test')` should throw a TypeError with message 'Not a Number'.
|
||||
|
||||
```js
|
||||
assert.throws(() => new Num('test'), TypeError);
|
||||
```
|
||||
|
||||
`new Num(0)` should throw a TypeError with message 'Out of range'.
|
||||
|
||||
```js
|
||||
assert.throws(() => new Num(0), TypeError);
|
||||
```
|
||||
|
||||
`new Num(-5)` should throw a TypeError with message 'Out of range'.
|
||||
|
||||
```js
|
||||
assert.throws(() => new Num(-5), TypeError);
|
||||
```
|
||||
|
||||
`new Num(10)` should throw a TypeError with message 'Out of range'.
|
||||
|
||||
```js
|
||||
assert.throws(() => new Num(11), TypeError);
|
||||
```
|
||||
|
||||
`new Num(20)` should throw a TypeError with message 'Out of range'.
|
||||
|
||||
```js
|
||||
assert.throws(() => new Num(20), TypeError);
|
||||
```
|
||||
|
||||
`new Num(3) + new Num(4)` should equal 7.
|
||||
|
||||
```js
|
||||
assert.equal(new Num(3) + new Num(4), 7);
|
||||
```
|
||||
|
||||
`new Num(3) - new Num(4)` should equal -1.
|
||||
|
||||
```js
|
||||
assert.equal(new Num(3) - new Num(4), -1);
|
||||
```
|
||||
|
||||
`new Num(3) * new Num(4)` should equal 12.
|
||||
|
||||
```js
|
||||
assert.equal(new Num(3) * new Num(4), 12);
|
||||
```
|
||||
|
||||
`new Num(3) / new Num(4)` should equal 0.75.
|
||||
|
||||
```js
|
||||
assert.equal(new Num(3) / new Num(4), 0.75);
|
||||
```
|
||||
|
||||
`new Num(3) < new Num(4)` should be true.
|
||||
|
||||
```js
|
||||
assert(new Num(3) < new Num(4));
|
||||
```
|
||||
|
||||
`new Num(3) > new Num(4)` should be false.
|
||||
|
||||
```js
|
||||
assert(!(new Num(3) > new Num(4)));
|
||||
```
|
||||
|
||||
`(new Num(5)).toString()` should return '5'
|
||||
|
||||
```js
|
||||
assert.equal(new Num(5).toString(), '5');
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```js
|
||||
function Num(n) {
|
||||
|
||||
return n;
|
||||
}
|
||||
```
|
||||
|
||||
# --solutions--
|
||||
|
||||
```js
|
||||
function Num(n) {
|
||||
if (isNaN(n)) {
|
||||
throw new TypeError('Not a Number');
|
||||
}
|
||||
if (n < 1 || n > 10) {
|
||||
throw new TypeError('Out of range');
|
||||
}
|
||||
|
||||
this._value = +n;
|
||||
}
|
||||
Num.prototype.valueOf = function() { return this._value; };
|
||||
Num.prototype.toString = function () { return this._value.toString(); };
|
||||
```
|
@ -0,0 +1,126 @@
|
||||
---
|
||||
id: 59f40b17e79dbf1ab720ed7a
|
||||
title: Department Numbers
|
||||
challengeType: 5
|
||||
forumTopicId: 302249
|
||||
dashedName: department-numbers
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
There is a highly organized city that has decided to assign a number to each of their departments:
|
||||
|
||||
<ul>
|
||||
<li>Police department</li>
|
||||
<li>Sanitation department</li>
|
||||
<li>Fire department</li>
|
||||
</ul>
|
||||
|
||||
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.
|
||||
|
||||
# --instructions--
|
||||
|
||||
Write a program which outputs all valid combinations as an array.
|
||||
|
||||
```js
|
||||
[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]
|
||||
```
|
||||
|
||||
# --hints--
|
||||
|
||||
`combinations` should be a function.
|
||||
|
||||
```js
|
||||
assert(typeof combinations === 'function');
|
||||
```
|
||||
|
||||
`combinations([1, 2, 3], 6)` should return an Array.
|
||||
|
||||
```js
|
||||
assert(Array.isArray(combinations([1, 2, 3], 6)));
|
||||
```
|
||||
|
||||
`combinations([1, 2, 3, 4, 5, 6, 7], 12)` should return an array of length 14.
|
||||
|
||||
```js
|
||||
assert(combinations(nums, total).length === len);
|
||||
```
|
||||
|
||||
`combinations([1, 2, 3, 4, 5, 6, 7], 12)` should return all valid combinations.
|
||||
|
||||
```js
|
||||
assert.deepEqual(combinations(nums, total), result);
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --after-user-code--
|
||||
|
||||
```js
|
||||
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]
|
||||
];
|
||||
```
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```js
|
||||
function combinations(possibleNumbers, total) {
|
||||
|
||||
return true;
|
||||
}
|
||||
```
|
||||
|
||||
# --solutions--
|
||||
|
||||
```js
|
||||
function combinations(possibleNumbers, total) {
|
||||
let firstNumber;
|
||||
let secondNumber;
|
||||
let thridNumber;
|
||||
const allCombinations = [];
|
||||
|
||||
for (let i = 0; i < possibleNumbers.length; i += 1) {
|
||||
firstNumber = possibleNumbers[i];
|
||||
|
||||
if (firstNumber % 2 === 0) {
|
||||
for (let j = 0; j < possibleNumbers.length; j += 1) {
|
||||
secondNumber = possibleNumbers[j];
|
||||
|
||||
if (j !== i && firstNumber + secondNumber <= total) {
|
||||
thridNumber = total - firstNumber - secondNumber;
|
||||
|
||||
if (thridNumber !== firstNumber && thridNumber !== secondNumber && possibleNumbers.includes(thridNumber)) {
|
||||
allCombinations.push([firstNumber, secondNumber, thridNumber]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return allCombinations;
|
||||
}
|
||||
```
|
@ -0,0 +1,195 @@
|
||||
---
|
||||
id: 59f4eafba0343628bb682785
|
||||
title: Discordian date
|
||||
challengeType: 5
|
||||
forumTopicId: 302250
|
||||
dashedName: discordian-date
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
Convert a given date from the [Gregorian calendar](https://en.wikipedia.org/wiki/Gregorian calendar "wp: Gregorian calendar") to the [Discordian calendar](https://en.wikipedia.org/wiki/Discordian calendar "wp: Discordian calendar").
|
||||
|
||||
# --hints--
|
||||
|
||||
`discordianDate` should be a function.
|
||||
|
||||
```js
|
||||
assert(typeof discordianDate === 'function');
|
||||
```
|
||||
|
||||
`discordianDate(new Date(2010, 6, 22))` should return `"Pungenday, the 57th day of Confusion in the YOLD 3176"`.
|
||||
|
||||
```js
|
||||
assert(
|
||||
discordianDate(new Date(2010, 6, 22)) ===
|
||||
'Pungenday, the 57th day of Confusion in the YOLD 3176'
|
||||
);
|
||||
```
|
||||
|
||||
`discordianDate(new Date(2012, 1, 28))` should return `"Prickle-Prickle, the 59th day of Chaos in the YOLD 3178"`.
|
||||
|
||||
```js
|
||||
assert(
|
||||
discordianDate(new Date(2012, 1, 28)) ===
|
||||
'Prickle-Prickle, the 59th day of Chaos in the YOLD 3178'
|
||||
);
|
||||
```
|
||||
|
||||
`discordianDate(new Date(2012, 1, 29))` should return `"Setting Orange, the 60th day of Chaos in the YOLD 3178. Celebrate St. Tib\'s Day!"`.
|
||||
|
||||
```js
|
||||
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, 2, 1))` should return `"Setting Orange, the 60th day of Chaos in the YOLD 3178"`.
|
||||
|
||||
```js
|
||||
assert(
|
||||
discordianDate(new Date(2012, 2, 1)) ===
|
||||
'Setting Orange, the 60th day of Chaos in the YOLD 3178'
|
||||
);
|
||||
```
|
||||
|
||||
`discordianDate(new Date(2010, 0, 5))` should return `"Setting Orange, the 5th day of Chaos in the YOLD 3176. Celebrate Mungday!"`.
|
||||
|
||||
```js
|
||||
assert(
|
||||
discordianDate(new Date(2010, 0, 5)) ===
|
||||
'Setting Orange, the 5th day of Chaos in the YOLD 3176. Celebrate Mungday!'
|
||||
);
|
||||
```
|
||||
|
||||
`discordianDate(new Date(2011, 4, 3))` should return `"Pungenday, the 50th day of Discord in the YOLD 3177. Celebrate Discoflux!"`.
|
||||
|
||||
```js
|
||||
assert(
|
||||
discordianDate(new Date(2011, 4, 3)) ===
|
||||
'Pungenday, the 50th day of Discord in the YOLD 3177. Celebrate Discoflux!'
|
||||
);
|
||||
```
|
||||
|
||||
`discordianDate(new Date(2015, 9, 19))` should return `"Boomtime, the 73rd day of Bureaucracy in the YOLD 3181"`.
|
||||
|
||||
```js
|
||||
assert(
|
||||
discordianDate(new Date(2015, 9, 19)) ===
|
||||
'Boomtime, the 73rd day of Bureaucracy in the YOLD 3181'
|
||||
);
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```js
|
||||
function discordianDate(date) {
|
||||
|
||||
return true;
|
||||
}
|
||||
```
|
||||
|
||||
# --solutions--
|
||||
|
||||
```js
|
||||
/**
|
||||
* All Hail Discordia! - this script prints Discordian date using system date.
|
||||
*
|
||||
* lang: JavaScript
|
||||
* author: jklu
|
||||
* contributors: JamesMcGuigan
|
||||
*
|
||||
* source: https://rosettacode.org/wiki/Discordian_date#JavaScript
|
||||
*/
|
||||
const seasons = [
|
||||
'Chaos', 'Discord', 'Confusion',
|
||||
'Bureaucracy', 'The Aftermath'
|
||||
];
|
||||
const weekday = [
|
||||
'Sweetmorn', 'Boomtime', 'Pungenday',
|
||||
'Prickle-Prickle', 'Setting Orange'
|
||||
];
|
||||
|
||||
const apostle = [
|
||||
'Mungday', 'Mojoday', 'Syaday',
|
||||
'Zaraday', 'Maladay'
|
||||
];
|
||||
|
||||
const holiday = [
|
||||
'Chaoflux', 'Discoflux', 'Confuflux',
|
||||
'Bureflux', 'Afflux'
|
||||
];
|
||||
|
||||
|
||||
Date.prototype.isLeapYear = function() {
|
||||
const year = this.getFullYear();
|
||||
if ((year & 3) !== 0) { return false; }
|
||||
return ((year % 100) !== 0 || (year % 400) === 0);
|
||||
};
|
||||
|
||||
// Get Day of Year
|
||||
Date.prototype.getDOY = function() {
|
||||
const dayCount = [0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334];
|
||||
const mn = this.getMonth();
|
||||
const dn = this.getDate();
|
||||
let dayOfYear = dayCount[mn] + dn;
|
||||
if (mn > 1 && this.isLeapYear()) { dayOfYear += 1; }
|
||||
return dayOfYear;
|
||||
};
|
||||
|
||||
Date.prototype.isToday = function() {
|
||||
const today = new Date();
|
||||
return this.getDate() === today.getDate()
|
||||
&& this.getMonth() === today.getMonth()
|
||||
&& this.getFullYear() === today.getFullYear()
|
||||
;
|
||||
};
|
||||
|
||||
function discordianDate(date) {
|
||||
if (!date) { date = new Date(); }
|
||||
|
||||
const y = date.getFullYear();
|
||||
const yold = y + 1166;
|
||||
let dayOfYear = date.getDOY();
|
||||
let celebrateHoliday = null;
|
||||
|
||||
if (date.isLeapYear()) {
|
||||
if (dayOfYear === 60) {
|
||||
celebrateHoliday = 'St. Tib\'s Day';
|
||||
}
|
||||
else if (dayOfYear > 60) {
|
||||
dayOfYear--;
|
||||
}
|
||||
}
|
||||
dayOfYear--;
|
||||
|
||||
const divDay = Math.floor(dayOfYear / 73);
|
||||
|
||||
const seasonDay = (dayOfYear % 73) + 1;
|
||||
if (seasonDay === 5) {
|
||||
celebrateHoliday = apostle[divDay];
|
||||
}
|
||||
if (seasonDay === 50) {
|
||||
celebrateHoliday = holiday[divDay];
|
||||
}
|
||||
|
||||
const season = seasons[divDay];
|
||||
const dayOfWeek = weekday[dayOfYear % 5];
|
||||
|
||||
const nth = (seasonDay % 10 === 1) ? 'st'
|
||||
: (seasonDay % 10 === 2) ? 'nd'
|
||||
: (seasonDay % 10 === 3) ? 'rd'
|
||||
: 'th';
|
||||
|
||||
return ''
|
||||
+ dayOfWeek
|
||||
+ ', the ' + seasonDay + nth
|
||||
+ ' day of ' + season
|
||||
+ ' in the YOLD ' + yold
|
||||
+ (celebrateHoliday ? '. Celebrate ' + celebrateHoliday + '!' : '')
|
||||
;
|
||||
}
|
||||
```
|
@ -0,0 +1,75 @@
|
||||
---
|
||||
id: 5a23c84252665b21eecc7e1e
|
||||
title: Dot product
|
||||
challengeType: 5
|
||||
forumTopicId: 302251
|
||||
dashedName: dot-product
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
Create a function, to compute the **[dot product](https://en.wikipedia.org/wiki/Dot product)**, also known as the **scalar product** of two vectors.
|
||||
|
||||
# --hints--
|
||||
|
||||
`dotProduct` should be a function.
|
||||
|
||||
```js
|
||||
assert(typeof dotProduct == 'function');
|
||||
```
|
||||
|
||||
`dotProduct([1, 3, -5], [4, -2, -1])` should return a number.
|
||||
|
||||
```js
|
||||
assert(typeof dotProduct([1, 3, -5], [4, -2, -1]) == 'number');
|
||||
```
|
||||
|
||||
`dotProduct([1, 3, -5], [4, -2, -1])` should return `3`.
|
||||
|
||||
```js
|
||||
assert.equal(dotProduct([1, 3, -5], [4, -2, -1]), 3);
|
||||
```
|
||||
|
||||
`dotProduct([1, 2, 3, 4, 5], [6, 7, 8, 9, 10])` should return `130`.
|
||||
|
||||
```js
|
||||
assert.equal(dotProduct([1, 2, 3, 4, 5], [6, 7, 8, 9, 10]), 130);
|
||||
```
|
||||
|
||||
`dotProduct([5, 4, 3, 2], [7, 8, 9, 6])` should return `106`.
|
||||
|
||||
```js
|
||||
assert.equal(dotProduct([5, 4, 3, 2], [7, 8, 9, 6]), 106);
|
||||
```
|
||||
|
||||
`dotProduct([-5, 4, -3, 2], [-7, -8, 9, -6])` should return `-36`.
|
||||
|
||||
```js
|
||||
assert.equal(dotProduct([-5, 4, -3, 2], [-7, -8, 9, -6]), -36);
|
||||
```
|
||||
|
||||
`dotProduct([17, 27, 34, 43, 15], [62, 73, 48, 95, 110])` should return `10392`.
|
||||
|
||||
```js
|
||||
assert.equal(dotProduct([17, 27, 34, 43, 15], [62, 73, 48, 95, 110]), 10392);
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```js
|
||||
function dotProduct(ary1, ary2) {
|
||||
|
||||
}
|
||||
```
|
||||
|
||||
# --solutions--
|
||||
|
||||
```js
|
||||
function dotProduct(ary1, ary2) {
|
||||
var dotprod = 0;
|
||||
for (var i = 0; i < ary1.length; i++) dotprod += ary1[i] * ary2[i];
|
||||
return dotprod;
|
||||
}
|
||||
```
|
@ -0,0 +1,214 @@
|
||||
---
|
||||
id: 599c333915e0ea32d04d4bec
|
||||
title: Element-wise operations
|
||||
challengeType: 5
|
||||
forumTopicId: 302252
|
||||
dashedName: element-wise-operations
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
Implement basic element-wise matrix-matrix and scalar-matrix operations.
|
||||
|
||||
**Implement:**
|
||||
|
||||
<ul>
|
||||
<li>addition</li>
|
||||
<li>subtraction</li>
|
||||
<li>multiplication</li>
|
||||
<li>division</li>
|
||||
<li>exponentiation</li>
|
||||
</ul>
|
||||
|
||||
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.
|
||||
|
||||
# --hints--
|
||||
|
||||
`operation` should be a function.
|
||||
|
||||
```js
|
||||
assert(typeof operation === 'function');
|
||||
```
|
||||
|
||||
`operation("m_add",[[1,2],[3,4]],[[1,2],[3,4]])` should return `[[2,4],[6,8]]`.
|
||||
|
||||
```js
|
||||
assert.deepEqual(
|
||||
operation(
|
||||
'm_add',
|
||||
[
|
||||
[1, 2],
|
||||
[3, 4]
|
||||
],
|
||||
[
|
||||
[1, 2],
|
||||
[3, 4]
|
||||
]
|
||||
),
|
||||
[
|
||||
[2, 4],
|
||||
[6, 8]
|
||||
]
|
||||
);
|
||||
```
|
||||
|
||||
`operation("s_add",[[1,2],[3,4]],2)` should return `[[3,4],[5,6]]`.
|
||||
|
||||
```js
|
||||
assert.deepEqual(
|
||||
operation(
|
||||
's_add',
|
||||
[
|
||||
[1, 2],
|
||||
[3, 4]
|
||||
],
|
||||
2
|
||||
),
|
||||
[
|
||||
[3, 4],
|
||||
[5, 6]
|
||||
]
|
||||
);
|
||||
```
|
||||
|
||||
`operation("m_sub",[[1,2],[3,4]],[[1,2],[3,4]])` should return `[[0,0],[0,0]]`.
|
||||
|
||||
```js
|
||||
assert.deepEqual(
|
||||
operation(
|
||||
'm_sub',
|
||||
[
|
||||
[1, 2],
|
||||
[3, 4]
|
||||
],
|
||||
[
|
||||
[1, 2],
|
||||
[3, 4]
|
||||
]
|
||||
),
|
||||
[
|
||||
[0, 0],
|
||||
[0, 0]
|
||||
]
|
||||
);
|
||||
```
|
||||
|
||||
`operation("m_mult",[[1,2],[3,4]],[[1,2],[3,4]])` should return `[[1,4],[9,16]]`.
|
||||
|
||||
```js
|
||||
assert.deepEqual(
|
||||
operation(
|
||||
'm_mult',
|
||||
[
|
||||
[1, 2],
|
||||
[3, 4]
|
||||
],
|
||||
[
|
||||
[1, 2],
|
||||
[3, 4]
|
||||
]
|
||||
),
|
||||
[
|
||||
[1, 4],
|
||||
[9, 16]
|
||||
]
|
||||
);
|
||||
```
|
||||
|
||||
`operation("m_div",[[1,2],[3,4]],[[1,2],[3,4]])` should return `[[1,1],[1,1]]`.
|
||||
|
||||
```js
|
||||
assert.deepEqual(
|
||||
operation(
|
||||
'm_div',
|
||||
[
|
||||
[1, 2],
|
||||
[3, 4]
|
||||
],
|
||||
[
|
||||
[1, 2],
|
||||
[3, 4]
|
||||
]
|
||||
),
|
||||
[
|
||||
[1, 1],
|
||||
[1, 1]
|
||||
]
|
||||
);
|
||||
```
|
||||
|
||||
`operation("m_exp",[[1,2],[3,4]],[[1,2],[3,4]])` should return `[[1,4],[27,256]]`.
|
||||
|
||||
```js
|
||||
assert.deepEqual(
|
||||
operation(
|
||||
'm_exp',
|
||||
[
|
||||
[1, 2],
|
||||
[3, 4]
|
||||
],
|
||||
[
|
||||
[1, 2],
|
||||
[3, 4]
|
||||
]
|
||||
),
|
||||
[
|
||||
[1, 4],
|
||||
[27, 256]
|
||||
]
|
||||
);
|
||||
```
|
||||
|
||||
`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]]`.
|
||||
|
||||
```js
|
||||
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]
|
||||
]
|
||||
);
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```js
|
||||
function operation(op, arr1, arr2) {
|
||||
|
||||
}
|
||||
```
|
||||
|
||||
# --solutions--
|
||||
|
||||
```js
|
||||
function operation(op, arr1, arr2) {
|
||||
const ops = {
|
||||
add: ((a, b) => a + b),
|
||||
sub: ((a, b) => a - b),
|
||||
mult: ((a, b) => a * b),
|
||||
div: ((a, b) => a / b),
|
||||
exp: ((a, b) => Math.pow(a, b))
|
||||
};
|
||||
const ifm = op.startsWith('m');
|
||||
const doOp = ops[op.substring(2)];
|
||||
for (let i = 0; i < arr1.length; i++) {
|
||||
for (let j = 0; j < arr1[0].length; j++) {
|
||||
arr1[i][j] = doOp(arr1[i][j], (ifm) ? (arr2[i][j]) : (arr2));
|
||||
}
|
||||
}
|
||||
return arr1;
|
||||
}
|
||||
```
|
@ -0,0 +1,138 @@
|
||||
---
|
||||
id: 599d0ba974141b0f508b37d5
|
||||
title: Emirp primes
|
||||
challengeType: 5
|
||||
forumTopicId: 302253
|
||||
dashedName: emirp-primes
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
An emirp (**prime** spelled backwards) are primes that when reversed (in their decimal representation) are a different prime.
|
||||
|
||||
# --instructions--
|
||||
|
||||
Write a function that:
|
||||
|
||||
<ul>
|
||||
<li>Shows the first <code>n</code> emirp numbers.</li>
|
||||
<li>Shows the emirp numbers in a range.</li>
|
||||
<li>Shows the number of emirps in a range.</li>
|
||||
<li>Shows the <code>n<sup>th</sup></code> emirp number.</li>
|
||||
</ul>
|
||||
|
||||
The function should accept 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 emirps as an array or a single number (the number of primes in the range or the <code>n<sup>th</sup></code> prime). According to the parameters the function should return an array or a number.
|
||||
|
||||
# --hints--
|
||||
|
||||
`emirps` should be a function.
|
||||
|
||||
```js
|
||||
assert(typeof emirps === 'function');
|
||||
```
|
||||
|
||||
`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]`
|
||||
|
||||
```js
|
||||
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(1000)` should return `70529`
|
||||
|
||||
```js
|
||||
assert.deepEqual(emirps(1000), 70529);
|
||||
```
|
||||
|
||||
`emirps([7700,8000],true)` should return `[7717,7757,7817,7841,7867,7879,7901,7927,7949,7951,7963]`
|
||||
|
||||
```js
|
||||
assert.deepEqual(emirps([7700, 8000], true), [
|
||||
7717,
|
||||
7757,
|
||||
7817,
|
||||
7841,
|
||||
7867,
|
||||
7879,
|
||||
7901,
|
||||
7927,
|
||||
7949,
|
||||
7951,
|
||||
7963
|
||||
]);
|
||||
```
|
||||
|
||||
`emirps([7700,8000],true)` should return `11`
|
||||
|
||||
```js
|
||||
assert.deepEqual(emirps([7700, 8000], false), 11);
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```js
|
||||
function emirps(n) {
|
||||
|
||||
}
|
||||
```
|
||||
|
||||
# --solutions--
|
||||
|
||||
```js
|
||||
function emirps(num, showEmirps)
|
||||
{
|
||||
const is_prime = function(n)
|
||||
{
|
||||
if (!(n % 2) || !(n % 3)) return false;
|
||||
let p = 1;
|
||||
while (p * p < n)
|
||||
{ if (n % (p += 4) == 0 || n % (p += 2) == 0)
|
||||
{ return false; } }
|
||||
return true;
|
||||
};
|
||||
const is_emirp = function(n) {
|
||||
const r = parseInt(n.toString().split('').reverse().join(''));
|
||||
return r != n && is_prime(n) && is_prime(r);
|
||||
};
|
||||
|
||||
let i,
|
||||
arr = [];
|
||||
if (typeof num === 'number') {
|
||||
for (i = 0; arr.length < num; i++) if (is_emirp(i)) arr.push(i);
|
||||
// first x emirps
|
||||
if (showEmirps) return arr;
|
||||
// xth emirp
|
||||
return arr.pop();
|
||||
}
|
||||
|
||||
if (Array.isArray(num)) {
|
||||
for (i = num[0]; i <= num[1]; i++) if (is_emirp(i)) arr.push(i);
|
||||
// emirps between x .. y
|
||||
if (showEmirps) return arr;
|
||||
// number of emirps between x .. y
|
||||
return arr.length;
|
||||
}
|
||||
}
|
||||
```
|
@ -0,0 +1,96 @@
|
||||
---
|
||||
id: 599d15309e88c813a40baf58
|
||||
title: Entropy
|
||||
challengeType: 5
|
||||
forumTopicId: 302254
|
||||
dashedName: entropy
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
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$.
|
||||
|
||||
# --hints--
|
||||
|
||||
`entropy` should be a function.
|
||||
|
||||
```js
|
||||
assert(typeof entropy === 'function');
|
||||
```
|
||||
|
||||
`entropy("0")` should return `0`
|
||||
|
||||
```js
|
||||
assert.equal(entropy('0'), 0);
|
||||
```
|
||||
|
||||
`entropy("01")` should return `1`
|
||||
|
||||
```js
|
||||
assert.equal(entropy('01'), 1);
|
||||
```
|
||||
|
||||
`entropy("0123")` should return `2`
|
||||
|
||||
```js
|
||||
assert.equal(entropy('0123'), 2);
|
||||
```
|
||||
|
||||
`entropy("01234567")` should return `3`
|
||||
|
||||
```js
|
||||
assert.equal(entropy('01234567'), 3);
|
||||
```
|
||||
|
||||
`entropy("0123456789abcdef")` should return `4`
|
||||
|
||||
```js
|
||||
assert.equal(entropy('0123456789abcdef'), 4);
|
||||
```
|
||||
|
||||
`entropy("1223334444")` should return `1.8464393446710154`
|
||||
|
||||
```js
|
||||
assert.equal(entropy('1223334444'), 1.8464393446710154);
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```js
|
||||
function entropy(s) {
|
||||
|
||||
}
|
||||
```
|
||||
|
||||
# --solutions--
|
||||
|
||||
```js
|
||||
function entropy(s) {
|
||||
// Create a dictionary of character frequencies and iterate over it.
|
||||
function process(s, evaluator) {
|
||||
let h = Object.create(null),
|
||||
k;
|
||||
s.split('').forEach(c => {
|
||||
h[c] && h[c]++ || (h[c] = 1); });
|
||||
if (evaluator) for (k in h) evaluator(k, h[k]);
|
||||
return h;
|
||||
}
|
||||
// Measure the entropy of a string in bits per symbol.
|
||||
|
||||
let sum = 0,
|
||||
len = s.length;
|
||||
process(s, (k, f) => {
|
||||
const p = f / len;
|
||||
sum -= p * Math.log(p) / Math.log(2);
|
||||
});
|
||||
return sum;
|
||||
}
|
||||
```
|
@ -0,0 +1,130 @@
|
||||
---
|
||||
id: 5987fd532b954e0f21b5d3f6
|
||||
title: Equilibrium index
|
||||
challengeType: 5
|
||||
forumTopicId: 302255
|
||||
dashedName: 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$:
|
||||
|
||||
<ul style='list-style: none;'>
|
||||
<li><big>$A_0 = -7$</big></li>
|
||||
<li><big>$A_1 = 1$</big></li>
|
||||
<li><big>$A_2 = 5$</big></li>
|
||||
<li><big>$A_3 = 2$</big></li>
|
||||
<li><big>$A_4 = -4$</big></li>
|
||||
<li><big>$A_5 = 3$</big></li>
|
||||
<li><big>$A_6 = 0$</big></li>
|
||||
</ul>
|
||||
|
||||
`3` is an equilibrium index, because:
|
||||
|
||||
<ul style='list-style: none;'>
|
||||
<li><big>$A_0 + A_1 + A_2 = A_4 + A_5 + A_6$</big></li>
|
||||
</ul>
|
||||
|
||||
`6` is also an equilibrium index, because:
|
||||
|
||||
<ul style='list-style: none;'>
|
||||
<li><big>$A_0 + A_1 + A_2 + A_3 + A_4 + A_5 = 0$</big></li>
|
||||
</ul>
|
||||
|
||||
(sum of zero elements is zero)
|
||||
|
||||
`7` is not an equilibrium index, because it is not a valid index of sequence $A$.
|
||||
|
||||
# --instructions--
|
||||
|
||||
Write a function that, given a sequence, returns its equilibrium indices (if any).
|
||||
|
||||
Assume that the sequence may be very long.
|
||||
|
||||
# --hints--
|
||||
|
||||
`equilibrium` should be a function.
|
||||
|
||||
```js
|
||||
assert(typeof equilibrium === 'function');
|
||||
```
|
||||
|
||||
`equilibrium([-7, 1, 5, 2, -4, 3, 0])` should return `[3,6]`.
|
||||
|
||||
```js
|
||||
assert.deepEqual(equilibrium(equilibriumTests[0]), ans[0]);
|
||||
```
|
||||
|
||||
`equilibrium([2, 4, 6])` should return `[]`.
|
||||
|
||||
```js
|
||||
assert.deepEqual(equilibrium(equilibriumTests[1]), ans[1]);
|
||||
```
|
||||
|
||||
`equilibrium([2, 9, 2])` should return `[1]`.
|
||||
|
||||
```js
|
||||
assert.deepEqual(equilibrium(equilibriumTests[2]), ans[2]);
|
||||
```
|
||||
|
||||
`equilibrium([1, -1, 1, -1, 1, -1, 1])` should return `[0,1,2,3,4,5,6]`.
|
||||
|
||||
```js
|
||||
assert.deepEqual(equilibrium(equilibriumTests[3]), ans[3]);
|
||||
```
|
||||
|
||||
`equilibrium([1])` should return `[0]`.
|
||||
|
||||
```js
|
||||
assert.deepEqual(equilibrium(equilibriumTests[4]), ans[4]);
|
||||
```
|
||||
|
||||
`equilibrium([])` should return `[]`.
|
||||
|
||||
```js
|
||||
assert.deepEqual(equilibrium(equilibriumTests[5]), ans[5]);
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --after-user-code--
|
||||
|
||||
```js
|
||||
const equilibriumTests =
|
||||
[[-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], []];
|
||||
```
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```js
|
||||
function equilibrium(a) {
|
||||
|
||||
}
|
||||
```
|
||||
|
||||
# --solutions--
|
||||
|
||||
```js
|
||||
function equilibrium(a) {
|
||||
let N = a.length,
|
||||
i,
|
||||
l = [],
|
||||
r = [],
|
||||
e = [];
|
||||
for (l[0] = a[0], r[N - 1] = a[N - 1], i = 1; i < N; i++)
|
||||
{ l[i] = l[i - 1] + a[i], r[N - i - 1] = r[N - i] + a[N - i - 1]; }
|
||||
for (i = 0; i < N; i++)
|
||||
{ if (l[i] === r[i]) e.push(i); }
|
||||
return e;
|
||||
}
|
||||
```
|
@ -0,0 +1,156 @@
|
||||
---
|
||||
id: 599d1566a02b571412643b84
|
||||
title: Ethiopian multiplication
|
||||
challengeType: 5
|
||||
forumTopicId: 302257
|
||||
dashedName: ethiopian-multiplication
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
Ethiopian multiplication is a method of multiplying integers using only addition, doubling, and halving.
|
||||
|
||||
**Method:**
|
||||
|
||||
<ol>
|
||||
<li>Take two numbers to be multiplied and write them down at the top of two columns</li>
|
||||
<li>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 <code>1</code></li>
|
||||
<li>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 <code>1</code></li>
|
||||
<li>Examine the table produced and discard any row where the value in the left column is even</li>
|
||||
<li>Sum the values in the right-hand column that remain to produce the result of multiplying the original two numbers together</li>
|
||||
</ol>
|
||||
|
||||
**For example:** `17 × 34`
|
||||
|
||||
<pre>17 34
|
||||
</pre>
|
||||
|
||||
Halving the first column:
|
||||
|
||||
<pre>17 34
|
||||
8
|
||||
4
|
||||
2
|
||||
1
|
||||
</pre>
|
||||
|
||||
Doubling the second column:
|
||||
|
||||
<pre>17 34
|
||||
8 68
|
||||
4 136
|
||||
2 272
|
||||
1 544
|
||||
</pre>
|
||||
|
||||
Strike-out rows whose first cell is even:
|
||||
|
||||
<pre>17 34
|
||||
8 <strike>68</strike>
|
||||
4 <strike>136</strike>
|
||||
2 <strike>272</strike>
|
||||
1 544
|
||||
</pre>
|
||||
|
||||
Sum the remaining numbers in the right-hand column:
|
||||
|
||||
<!-- markdownlint-disable MD003 -->
|
||||
|
||||
<pre>17 34
|
||||
8 --
|
||||
4 ---
|
||||
2 ---
|
||||
1 544
|
||||
====
|
||||
578
|
||||
</pre>
|
||||
|
||||
<!-- markdownlint-enable MD003 -->
|
||||
|
||||
So `17` multiplied by `34`, by the Ethiopian method is `578`.
|
||||
|
||||
# --instructions--
|
||||
|
||||
The task is to define three named functions/methods/procedures/subroutines:
|
||||
|
||||
<ol>
|
||||
<li>one to halve an integer,</li>
|
||||
<li>one to double an integer, and</li>
|
||||
<li>one to state if an integer is even</li>
|
||||
</ol>
|
||||
|
||||
Use these functions to create a function that does Ethiopian multiplication.
|
||||
|
||||
<!-- markdownlint-disable MD046-->
|
||||
|
||||
# --hints--
|
||||
|
||||
`eth_mult` should be a function.
|
||||
|
||||
```js
|
||||
assert(typeof eth_mult === 'function');
|
||||
```
|
||||
|
||||
`eth_mult(17,34)` should return `578`.
|
||||
|
||||
```js
|
||||
assert.equal(eth_mult(17, 34), 578);
|
||||
```
|
||||
|
||||
`eth_mult(23,46)` should return `1058`.
|
||||
|
||||
```js
|
||||
assert.equal(eth_mult(23, 46), 1058);
|
||||
```
|
||||
|
||||
`eth_mult(12,27)` should return `324`.
|
||||
|
||||
```js
|
||||
assert.equal(eth_mult(12, 27), 324);
|
||||
```
|
||||
|
||||
`eth_mult(56,98)` should return `5488`.
|
||||
|
||||
```js
|
||||
assert.equal(eth_mult(56, 98), 5488);
|
||||
```
|
||||
|
||||
`eth_mult(63,74)` should return `4662`.
|
||||
|
||||
```js
|
||||
assert.equal(eth_mult(63, 74), 4662);
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```js
|
||||
function eth_mult(a, b) {
|
||||
|
||||
}
|
||||
```
|
||||
|
||||
# --solutions--
|
||||
|
||||
```js
|
||||
function eth_mult(a, b) {
|
||||
let sum = 0; a = [a]; b = [b];
|
||||
|
||||
let half = a => a / 2,
|
||||
double = a => a * 2,
|
||||
is_even = a => a % 2 == 0;
|
||||
|
||||
while (a[0] !== 1) {
|
||||
a.unshift(Math.floor(half(a[0])));
|
||||
b.unshift(double(b[0]));
|
||||
}
|
||||
|
||||
for (let i = a.length - 1; i > 0; i -= 1) {
|
||||
if (!is_even(a[i])) {
|
||||
sum += b[i];
|
||||
}
|
||||
}
|
||||
return sum + b[0];
|
||||
}
|
||||
```
|
@ -0,0 +1,152 @@
|
||||
---
|
||||
id: 59880443fb36441083c6c20e
|
||||
title: Euler method
|
||||
challengeType: 5
|
||||
forumTopicId: 302258
|
||||
dashedName: 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](https://en.wikipedia.org/wiki/Euler method "wp: Euler method").
|
||||
|
||||
The ODE has to be provided in the following form:
|
||||
|
||||
<ul style='list-style: none;'>
|
||||
<li><big>$\frac{dy(t)}{dt} = f(t,y(t))$</big></li>
|
||||
</ul>
|
||||
|
||||
with an initial value
|
||||
|
||||
<ul style='list-style: none;'>
|
||||
<li><big>$y(t_0) = y_0$</big></li>
|
||||
</ul>
|
||||
|
||||
To get a numeric solution, we replace the derivative on the LHS with a finite difference approximation:
|
||||
|
||||
<ul style='list-style: none;'>
|
||||
<li><big>$\frac{dy(t)}{dt} \approx \frac{y(t+h)-y(t)}{h}$</big></li>
|
||||
</ul>
|
||||
|
||||
then solve for $y(t+h)$:
|
||||
|
||||
<ul style='list-style: none;'>
|
||||
<li><big>$y(t+h) \approx y(t) + h \, \frac{dy(t)}{dt}$</big></li>
|
||||
</ul>
|
||||
|
||||
which is the same as
|
||||
|
||||
<ul style='list-style: none;'>
|
||||
<li><big>$y(t+h) \approx y(t) + h \, f(t,y(t))$</big></li>
|
||||
</ul>
|
||||
|
||||
The iterative solution rule is then:
|
||||
|
||||
<ul style='list-style: none;'>
|
||||
<li><big>$y_{n+1} = y_n + h \, f(t_n, y_n)$</big></li>
|
||||
</ul>
|
||||
|
||||
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$:
|
||||
|
||||
<ul style='list-style: none;'>
|
||||
<li><big>$\frac{dT(t)}{dt} = -k \, \Delta T$</big></li>
|
||||
</ul>
|
||||
|
||||
or
|
||||
|
||||
<ul style='list-style: none;'>
|
||||
<li><big>$\frac{dT(t)}{dt} = -k \, (T(t) - T_R)$</big></li>
|
||||
</ul>
|
||||
|
||||
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
|
||||
|
||||
<ul style='list-style: none;'>
|
||||
<li><big>$T(t) = T_R + (T_0 - T_R) \; e^{-k t}$</big></li>
|
||||
</ul>
|
||||
|
||||
# --instructions--
|
||||
|
||||
Implement a routine of Euler's method and then use it to solve the given example of Newton's cooling law for three different step sizes of:
|
||||
|
||||
<ul>
|
||||
<li><code>2 s</code></li>
|
||||
<li><code>5 s</code> and</li>
|
||||
<li><code>10 s</code></li>
|
||||
</ul>
|
||||
|
||||
and compare with the analytical solution.
|
||||
|
||||
**Initial values:**
|
||||
|
||||
<ul>
|
||||
<li>initial temperature <big>$T_0$</big> shall be <code>100 °C</code></li>
|
||||
<li>room temperature <big>$T_R$</big> shall be <code>20 °C</code></li>
|
||||
<li>cooling constant <big>$k$</big> shall be <code>0.07</code></li>
|
||||
<li>time interval to calculate shall be from <code>0 s</code> to <code>100 s</code></li>
|
||||
</ul>
|
||||
|
||||
First parameter to the function is initial time, second parameter is initial temperature, third parameter is elapsed time and fourth parameter is step size.
|
||||
|
||||
# --hints--
|
||||
|
||||
`eulersMethod` should be a function.
|
||||
|
||||
```js
|
||||
assert(typeof eulersMethod === 'function');
|
||||
```
|
||||
|
||||
`eulersMethod(0, 100, 100, 2)` should return a number.
|
||||
|
||||
```js
|
||||
assert(typeof eulersMethod(0, 100, 100, 2) === 'number');
|
||||
```
|
||||
|
||||
`eulersMethod(0, 100, 100, 2)` should return 20.0424631833732.
|
||||
|
||||
```js
|
||||
assert.equal(eulersMethod(0, 100, 100, 2), 20.0424631833732);
|
||||
```
|
||||
|
||||
`eulersMethod(0, 100, 100, 5)` should return 20.01449963666907.
|
||||
|
||||
```js
|
||||
assert.equal(eulersMethod(0, 100, 100, 5), 20.01449963666907);
|
||||
```
|
||||
|
||||
`eulersMethod(0, 100, 100, 10)` should return 20.000472392.
|
||||
|
||||
```js
|
||||
assert.equal(eulersMethod(0, 100, 100, 10), 20.000472392);
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```js
|
||||
function eulersMethod(x1, y1, x2, h) {
|
||||
|
||||
}
|
||||
```
|
||||
|
||||
# --solutions--
|
||||
|
||||
```js
|
||||
function eulersMethod(x1, y1, x2, h) {
|
||||
let x = x1;
|
||||
let y = y1;
|
||||
|
||||
while ((x < x2 && x1 < x2) || (x > x2 && x1 > x2)) {
|
||||
y += h * (-0.07 * (y - 20));
|
||||
x += h;
|
||||
}
|
||||
|
||||
return y;
|
||||
}
|
||||
```
|
@ -0,0 +1,74 @@
|
||||
---
|
||||
id: 598de241872ef8353c58a7a2
|
||||
title: Evaluate binomial coefficients
|
||||
challengeType: 5
|
||||
forumTopicId: 302259
|
||||
dashedName: 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}$
|
||||
|
||||
# --hints--
|
||||
|
||||
`binom` should be a function.
|
||||
|
||||
```js
|
||||
assert(typeof binom === 'function');
|
||||
```
|
||||
|
||||
`binom(5,3)` should return 10.
|
||||
|
||||
```js
|
||||
assert.equal(binom(5, 3), 10);
|
||||
```
|
||||
|
||||
`binom(7,2)` should return 21.
|
||||
|
||||
```js
|
||||
assert.equal(binom(7, 2), 21);
|
||||
```
|
||||
|
||||
`binom(10,4)` should return 210.
|
||||
|
||||
```js
|
||||
assert.equal(binom(10, 4), 210);
|
||||
```
|
||||
|
||||
`binom(6,1)` should return 6.
|
||||
|
||||
```js
|
||||
assert.equal(binom(6, 1), 6);
|
||||
```
|
||||
|
||||
`binom(12,8)` should return 495.
|
||||
|
||||
```js
|
||||
assert.equal(binom(12, 8), 495);
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```js
|
||||
function binom(n, k) {
|
||||
|
||||
}
|
||||
```
|
||||
|
||||
# --solutions--
|
||||
|
||||
```js
|
||||
function binom(n, k) {
|
||||
let coeff = 1;
|
||||
for (let i = n - k + 1; i <= n; i++) coeff *= i;
|
||||
for (let i = 1; i <= k; i++) coeff /= i;
|
||||
return coeff;
|
||||
}
|
||||
```
|
@ -0,0 +1,276 @@
|
||||
---
|
||||
id: 59e09e6d412c5939baa02d16
|
||||
title: Execute a Markov algorithm
|
||||
challengeType: 5
|
||||
forumTopicId: 302260
|
||||
dashedName: execute-a-markov-algorithm
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
Create an interpreter for a [Markov Algorithm](https://en.wikipedia.org/wiki/Markov algorithm "wp: Markov algorithm").
|
||||
|
||||
Rules have the syntax:
|
||||
|
||||
<pre>[ruleset] ::= (([comment] | [rule]) [newline]+)*
|
||||
[comment] ::= # {[any character]}
|
||||
[rule] ::= [pattern] [whitespace] -> [whitespace] [.] [replacement]
|
||||
[whitespace] ::= ([tab] | [space]) [[whitespace]]
|
||||
</pre>
|
||||
|
||||
There is one rule per line.
|
||||
|
||||
If there is a `.` (period) present before the \[replacement], then this is a terminating rule in which case the interpreter must halt execution.
|
||||
|
||||
A ruleset consists of a sequence of rules, with optional comments.
|
||||
|
||||
Rulesets
|
||||
|
||||
Use the following tests on entries:
|
||||
|
||||
**Ruleset 1:**
|
||||
|
||||
<pre># This rules file is extracted from Wikipedia:
|
||||
# <code>http://en.wikipedia.org/wiki/Markov_Algorithm</code>
|
||||
A -> apple
|
||||
B -> bag
|
||||
S -> shop
|
||||
T -> the
|
||||
the shop -> my brother
|
||||
a never used -> .terminating rule
|
||||
</pre>
|
||||
|
||||
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.`
|
||||
|
||||
**Ruleset 2:**
|
||||
|
||||
A test of the terminating rule
|
||||
|
||||
<pre># Slightly modified from the rules on Wikipedia
|
||||
A -> apple
|
||||
B -> bag
|
||||
S -> .shop
|
||||
T -> the
|
||||
the shop -> my brother
|
||||
a never used -> .terminating rule
|
||||
</pre>
|
||||
|
||||
Sample text of:
|
||||
|
||||
`I bought a B of As from T S.`
|
||||
|
||||
Should generate:
|
||||
|
||||
`I bought a bag of apples from T shop.`
|
||||
|
||||
**Ruleset 3:**
|
||||
|
||||
This tests for correct substitution order and may trap simple regexp based replacement routines if special regexp characters are not escaped.
|
||||
|
||||
<pre># BNF Syntax testing rules
|
||||
A -> apple
|
||||
WWWW -> with
|
||||
Bgage -> ->.*
|
||||
B -> bag
|
||||
->.* -> money
|
||||
W -> WW
|
||||
S -> .shop
|
||||
T -> the
|
||||
the shop -> my brother
|
||||
a never used -> .terminating rule
|
||||
</pre>
|
||||
|
||||
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.`
|
||||
|
||||
**Ruleset 4:**
|
||||
|
||||
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.)
|
||||
|
||||
<pre>### 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
|
||||
# addition
|
||||
1! -> !1
|
||||
,! -> !+
|
||||
_! -> _
|
||||
# Unary multiplication by duplicating left side, right side times
|
||||
1*1 -> x,@y
|
||||
1x -> xX
|
||||
X, -> 1,1
|
||||
X1 -> 1X
|
||||
_x -> _X
|
||||
,x -> ,X
|
||||
y1 -> 1y
|
||||
y_ -> _
|
||||
# Next phase of applying
|
||||
1@1 -> x,@y
|
||||
1@_ -> @_
|
||||
,@_ -> !_
|
||||
++ -> +
|
||||
# Termination cleanup for addition
|
||||
_1 -> 1
|
||||
1+_ -> 1
|
||||
_+_ ->
|
||||
</pre>
|
||||
|
||||
Sample text of:
|
||||
|
||||
`_1111*11111_`
|
||||
|
||||
should generate the output:
|
||||
|
||||
`11111111111111111111`
|
||||
|
||||
**Ruleset 5:**
|
||||
|
||||
A simple [Turing machine](http://en.wikipedia.org/wiki/Turing_machine "link: http://en.wikipedia.org/wiki/Turing_machine"), implementing a three-state [busy beaver](http://en.wikipedia.org/wiki/Busy_beaver "link: http://en.wikipedia.org/wiki/Busy_beaver").
|
||||
|
||||
The tape consists of `0`s and `1`s, the states are `A`, `B`, `C` and `H` (for `H`alt), 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.
|
||||
|
||||
<pre># Turing machine: three-state busy beaver
|
||||
#
|
||||
# state A, symbol 0 => write 1, move right, new state B
|
||||
A0 -> 1B
|
||||
# state A, symbol 1 => write 1, move left, new state C
|
||||
0A1 -> C01
|
||||
1A1 -> C11
|
||||
# state B, symbol 0 => write 1, move left, new state A
|
||||
0B0 -> A01
|
||||
1B0 -> A11
|
||||
# state B, symbol 1 => write 1, move right, new state B
|
||||
B1 -> 1B
|
||||
# state C, symbol 0 => write 1, move left, new state B
|
||||
0C0 -> B01
|
||||
1C0 -> B11
|
||||
# state C, symbol 1 => write 1, move left, halt
|
||||
0C1 -> H01
|
||||
1C1 -> H11
|
||||
</pre>
|
||||
|
||||
This ruleset should turn
|
||||
|
||||
`000000A000000`
|
||||
|
||||
into
|
||||
|
||||
`00011H1111000`
|
||||
|
||||
# --hints--
|
||||
|
||||
`markov` should be a function.
|
||||
|
||||
```js
|
||||
assert(typeof markov === 'function');
|
||||
```
|
||||
|
||||
`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.".
|
||||
|
||||
```js
|
||||
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 T shop.".
|
||||
|
||||
```js
|
||||
assert.deepEqual(markov(rules[1], tests[1]), outputs[1]);
|
||||
```
|
||||
|
||||
`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.".
|
||||
|
||||
```js
|
||||
assert.deepEqual(markov(rules[2], tests[2]), outputs[2]);
|
||||
```
|
||||
|
||||
`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".
|
||||
|
||||
```js
|
||||
assert.deepEqual(markov(rules[3], tests[3]), outputs[3]);
|
||||
```
|
||||
|
||||
`markov(["A0 -> 1B","0A1 -> C01","1A1 -> C11","0B0 -> A01","1B0 -> A11","B1 -> 1B","0C0 -> B01","1C0 -> B11","0C1 -> H01","1C1 -> H11"],"")` should return "00011H1111000".
|
||||
|
||||
```js
|
||||
assert.deepEqual(markov(rules[4], tests[4]), outputs[4]);
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --after-user-code--
|
||||
|
||||
```js
|
||||
|
||||
let rules=[["A -> apple","B -> bag","S -> shop","T -> the","the shop -> my brother","a never used -> .terminating rule"],
|
||||
["A -> apple","B -> bag","S -> .shop","T -> the","the shop -> my brother","a never used -> .terminating rule"],
|
||||
["A -> apple","WWWW -> with","Bgage -> ->.*","B -> bag","->.* -> money","W -> WW","S -> .shop","T -> the","the shop -> my brother","a never used -> .terminating rule"],
|
||||
["_+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","_+_ -> "],
|
||||
["A0 -> 1B","0A1 -> C01","1A1 -> C11","0B0 -> A01","1B0 -> A11","B1 -> 1B","0C0 -> B01","1C0 -> B11","0C1 -> H01","1C1 -> H11"]];
|
||||
let tests=["I bought a B of As from T S.",
|
||||
"I bought a B of As from T S.",
|
||||
"I bought a B of As W my Bgage from T S.",
|
||||
"_1111*11111_",
|
||||
"000000A000000"];
|
||||
let outputs=["I bought a bag of apples from my brother.",
|
||||
"I bought a bag of apples from T shop.",
|
||||
"I bought a bag of apples with my money from T shop.",
|
||||
"11111111111111111111",
|
||||
"00011H1111000"]
|
||||
|
||||
```
|
||||
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```js
|
||||
function markov(rules,test) {
|
||||
|
||||
}
|
||||
```
|
||||
|
||||
# --solutions--
|
||||
|
||||
```js
|
||||
function markov(rules,test) {
|
||||
let pattern = new RegExp("^([^#]*?)\\s+->\\s+(\\.?)(.*)");
|
||||
let origTest = test;
|
||||
|
||||
let captures = [];
|
||||
|
||||
rules.forEach(function(rule){
|
||||
let m = pattern.exec(rule);
|
||||
for (let j = 0; j < m.length; j++)
|
||||
m[j] = m[j + 1];
|
||||
captures.push(m);
|
||||
});
|
||||
|
||||
test = origTest;
|
||||
let copy = test;
|
||||
for (let j = 0; j < captures.length; j++) {
|
||||
let c = captures[j];
|
||||
test = test.replace(c[0], c[2]);
|
||||
if (c[1]==".")
|
||||
break;
|
||||
if (test!=copy) {
|
||||
j = -1;
|
||||
copy = test;
|
||||
}
|
||||
}
|
||||
return test;
|
||||
}
|
||||
```
|
@ -0,0 +1,202 @@
|
||||
---
|
||||
id: 59e0a8df964e4540d5abe599
|
||||
title: Execute Brain****
|
||||
challengeType: 5
|
||||
forumTopicId: 302261
|
||||
dashedName: 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\*\*\*](https://rosettacode.org/wiki/Brainf*** "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 |
|
||||
| ------------------------- | ------------------------------------------------------------------------------------------ |
|
||||
| <code>></code> | Move the pointer to the right |
|
||||
| <code><</code> | Move the pointer to the left |
|
||||
| <code>+</code> | Increment the memory cell under the pointer |
|
||||
| <code>-</code> | Decrement the memory cell under the pointer |
|
||||
| <code>.</code> | Output the character signified by the cell at the pointer |
|
||||
| <code>,</code> | Input a character and store it in the cell at the pointer |
|
||||
| <code>\[</code> | Jump past the matching <code>]</code> if the cell under the pointer is 0 |
|
||||
| <code>]</code> | Jump back to the matching <code>\[</code> if the cell under the pointer is nonzero |
|
||||
|
||||
Any cell size is allowed, EOF (*E*nd-*O*-*F*ile) support is optional, as is whether you have bounded or unbounded memory.
|
||||
|
||||
# --hints--
|
||||
|
||||
`brain(bye)` should return a string
|
||||
|
||||
```js
|
||||
assert(typeof brain(bye) === 'string');
|
||||
```
|
||||
|
||||
`brain("++++++[>++++++++++<-]>+++++.")` should return "A"
|
||||
|
||||
```js
|
||||
assert.equal(brain('++++++[>++++++++++<-]>+++++.'), 'A');
|
||||
```
|
||||
|
||||
`brain(bye)` should return `Goodbye, World!\r\n`
|
||||
|
||||
```js
|
||||
assert.equal(brain(bye), 'Goodbye, World!\r\n');
|
||||
```
|
||||
|
||||
`brain(hello)` should return `Hello World!\n`
|
||||
|
||||
```js
|
||||
assert.equal(brain(hello), 'Hello World!\n');
|
||||
```
|
||||
|
||||
`brain(fib)` should return `1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89`
|
||||
|
||||
```js
|
||||
assert.equal(brain(fib), '1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89');
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --before-user-code--
|
||||
|
||||
```js
|
||||
let fib=`+
|
||||
|
||||
++
|
||||
|
||||
+++
|
||||
|
||||
++++
|
||||
|
||||
+>+>>
|
||||
|
||||
>>++++
|
||||
|
||||
+++++++
|
||||
|
||||
++++++++
|
||||
|
||||
+++++++++
|
||||
|
||||
++++++++++
|
||||
|
||||
++++++>++++
|
||||
|
||||
++++++++++++
|
||||
|
||||
+++++++++++++
|
||||
|
||||
+++<<<<<<[>[>>
|
||||
|
||||
>>>>+>+<<<<<<<-
|
||||
|
||||
]>>>>>>>[<<<<<<<
|
||||
|
||||
+>>>>>>>-]<[>++++
|
||||
|
||||
++++++[-<-[>>+>+<<
|
||||
|
||||
<-]>>>[<<<+>>>-]+<[
|
||||
|
||||
>[-]<[-]]>[<<[>>>+<<
|
||||
|
||||
<-]>>[-]]<<]>>>[>>+>+
|
||||
|
||||
<<<-]>>>[<<<+>>>-]+<[>
|
||||
|
||||
[-]<[-]]>[<<+>>[-]]<<<<
|
||||
|
||||
<<<]>>>>>[++++++++++++++
|
||||
|
||||
+++++++++++++++++++++++++
|
||||
|
||||
+++++++++.[-]]++++++++++<[
|
||||
|
||||
->-<]>+++++++++++++++++++++
|
||||
|
||||
+++++++++++++++++++++++++++.
|
||||
|
||||
[-]<<<<<<<<<<<<[>>>+>+<<<<-]>
|
||||
|
||||
>>>[<<<<+>>>>-]<-[>>.>.<<<[-]]
|
||||
|
||||
<<[>>+>+<<<-]>>>[<<<+>>>-]<<[<+
|
||||
|
||||
>-]>[<+>-]<<<-]`;
|
||||
let hello='++++++++[>++++[>++>+++>+++>+<<<<-]>+>+>->>+[<]<-]>>.>---.+++++++..+++.>>.<-.<.+++.------.--------.>>+.>++.'
|
||||
let bye='++++++++++[>+>+++>++++>+++++++>++++++++>+++++++++>++++++++++>+++++++++++>++++++++++++<<<<<<<<<-]>>>>+.>>>>+..<.<++++++++.>>>+.<<+.<<<<++++.<++.>>>+++++++.>>>.+++.<+++++++.--------.<<<<<+.<+++.---.';
|
||||
```
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```js
|
||||
function brain(prog) {
|
||||
|
||||
}
|
||||
```
|
||||
|
||||
# --solutions--
|
||||
|
||||
```js
|
||||
function brain(prog){
|
||||
var output="";
|
||||
var code; // formatted code
|
||||
var ip = 0; // current instruction within code
|
||||
var nest = 0; // current bracket nesting (for Out button)
|
||||
var ahead = []; // locations of matching brackets
|
||||
|
||||
var data = [0]; // data array (mod by +, -)
|
||||
var dp = 0; // index into data (mod by <, >)
|
||||
|
||||
var inp = 0; // current input character (fetch with ,)
|
||||
var quit = 0;
|
||||
var commands = {
|
||||
'>':function() { if (++dp >= data.length) data[dp]=0 },
|
||||
'<':function() { if (--dp < 0) quit++ },
|
||||
'+':function() { ++data[dp] },
|
||||
'-':function() { --data[dp] },
|
||||
'[':function() { if (!data[dp]) ip = ahead[ip]; else ++nest },
|
||||
']':function() { if ( data[dp]) ip = ahead[ip]; else --nest },
|
||||
',':function() {
|
||||
var c = document.getElementById("input").value.charCodeAt(inp++);
|
||||
data[dp] = isNaN(c) ? 0 : c; // EOF: other options are -1 or no change
|
||||
},
|
||||
'.':function() {
|
||||
output+=String.fromCharCode(data[dp]);
|
||||
/*var s = document.getElementById("output").innerHTML)
|
||||
+ String.fromCharCode(data[dp]);
|
||||
s = s.replace(/\n/g,"<br>").replace(/ /g,"&nbsp;");
|
||||
document.getElementById("output").innerHTML = s;*/
|
||||
},
|
||||
};
|
||||
|
||||
let ar=prog.split('');
|
||||
var st = [], back, error = -1;
|
||||
for (ip=0; ip<ar.length; ip++) {
|
||||
switch(ar[ip]) {
|
||||
case '[':
|
||||
st.push(ip);
|
||||
break;
|
||||
case ']':
|
||||
if (st.length == 0) error = ip;
|
||||
back = st.pop();
|
||||
ahead[ip] = back;
|
||||
ahead[back] = ip;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
for(ip=0;ip<ar.length;ip++){
|
||||
if(commands.hasOwnProperty(ar[ip]))
|
||||
commands[ar[ip]]();
|
||||
}
|
||||
|
||||
return output;
|
||||
}
|
||||
```
|
@ -0,0 +1,139 @@
|
||||
---
|
||||
id: 598ee8b91b410510ae82efef
|
||||
title: Extensible prime generator
|
||||
challengeType: 5
|
||||
forumTopicId: 302262
|
||||
dashedName: 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:
|
||||
|
||||
<ul>
|
||||
<li>Show the first <code>n</code> prime numbers</li>
|
||||
<li>Show the prime numbers in a range</li>
|
||||
<li>Show the number of primes in a range</li>
|
||||
<li>Show the <code>n<sup>th</sup></code> prime number</li>
|
||||
</ul>
|
||||
|
||||
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 <code>n<sup>th</sup></code> prime). According to the parameters the function should return an array.
|
||||
|
||||
# --hints--
|
||||
|
||||
`primeGenerator` should be a function.
|
||||
|
||||
```js
|
||||
assert(typeof primeGenerator === 'function');
|
||||
```
|
||||
|
||||
`primeGenerator(20, true)` should return `[2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71]`.
|
||||
|
||||
```js
|
||||
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([100, 150], true)` should return `[101, 103, 107, 109, 113, 127, 131, 137, 139, 149]`.
|
||||
|
||||
```js
|
||||
assert.deepEqual(primeGenerator([100, 150], true), [
|
||||
101,
|
||||
103,
|
||||
107,
|
||||
109,
|
||||
113,
|
||||
127,
|
||||
131,
|
||||
137,
|
||||
139,
|
||||
149
|
||||
]);
|
||||
```
|
||||
|
||||
`primeGenerator([7700, 8000], false)` should return `30`.
|
||||
|
||||
```js
|
||||
assert.equal(primeGenerator([7700, 8000], false), 30);
|
||||
```
|
||||
|
||||
`primeGenerator(10000, false)` should return `104729`.
|
||||
|
||||
```js
|
||||
assert.equal(primeGenerator(10000, false), 104729);
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```js
|
||||
function primeGenerator(num, showPrimes) {
|
||||
|
||||
}
|
||||
```
|
||||
|
||||
# --solutions--
|
||||
|
||||
```js
|
||||
function primeGenerator(num, showPrimes) {
|
||||
let i,
|
||||
arr = [];
|
||||
|
||||
function isPrime(num) {
|
||||
// try primes <= 16
|
||||
if (num <= 16) { return (
|
||||
num == 2 || num == 3 || num == 5 || num == 7 || num == 11 || num == 13
|
||||
); }
|
||||
// cull multiples of 2, 3, 5 or 7
|
||||
if (num % 2 == 0 || num % 3 == 0 || num % 5 == 0 || num % 7 == 0)
|
||||
{ return false; }
|
||||
// cull square numbers ending in 1, 3, 7 or 9
|
||||
for (let i = 10; i * i <= num; i += 10) {
|
||||
if (num % (i + 1) == 0) return false;
|
||||
if (num % (i + 3) == 0) return false;
|
||||
if (num % (i + 7) == 0) return false;
|
||||
if (num % (i + 9) == 0) return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
if (typeof num === 'number') {
|
||||
for (i = 0; arr.length < num; i++) if (isPrime(i)) arr.push(i);
|
||||
// first x primes
|
||||
if (showPrimes) return arr;
|
||||
// xth prime
|
||||
return arr.pop();
|
||||
}
|
||||
|
||||
if (Array.isArray(num)) {
|
||||
for (i = num[0]; i <= num[1]; i++) if (isPrime(i)) arr.push(i);
|
||||
// primes between x .. y
|
||||
if (showPrimes) return arr;
|
||||
// number of primes between x .. y
|
||||
return arr.length;
|
||||
}
|
||||
}
|
||||
```
|
@ -0,0 +1,80 @@
|
||||
---
|
||||
id: 597b2b2a2702b44414742771
|
||||
title: Factorial
|
||||
challengeType: 5
|
||||
forumTopicId: 302263
|
||||
dashedName: factorial
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
Write a function to return the factorial of a number.
|
||||
|
||||
Factorial of a number is given by:
|
||||
|
||||
<pre><big>n! = n * (n-1) * (n-2) * ..... * 1</big>
|
||||
</pre>
|
||||
|
||||
For example:
|
||||
|
||||
<ul>
|
||||
<li><code>3! = 3 * 2 * 1 = 6</code></li>
|
||||
<li><code>4! = 4 * 3 * 2 * 1 = 24</code></li>
|
||||
</ul>
|
||||
|
||||
**Note:** `0! = 1`
|
||||
|
||||
# --hints--
|
||||
|
||||
`factorial` should be a function.
|
||||
|
||||
```js
|
||||
assert(typeof factorial === 'function');
|
||||
```
|
||||
|
||||
`factorial(2)` should return a number.
|
||||
|
||||
```js
|
||||
assert(typeof factorial(2) === 'number');
|
||||
```
|
||||
|
||||
`factorial(3)` should return 6.
|
||||
|
||||
```js
|
||||
assert.equal(factorial(3), 6);
|
||||
```
|
||||
|
||||
`factorial(5)` should return 120.
|
||||
|
||||
```js
|
||||
assert.equal(factorial(5), 120);
|
||||
```
|
||||
|
||||
`factorial(10)` should return 3,628,800.
|
||||
|
||||
```js
|
||||
assert.equal(factorial(10), 3628800);
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```js
|
||||
function factorial(n) {
|
||||
|
||||
}
|
||||
```
|
||||
|
||||
# --solutions--
|
||||
|
||||
```js
|
||||
function factorial(n) {
|
||||
let sum = 1;
|
||||
while (n > 1) {
|
||||
sum *= n;
|
||||
n--;
|
||||
}
|
||||
return sum;
|
||||
}
|
||||
```
|
@ -0,0 +1,148 @@
|
||||
---
|
||||
id: 598eea87e5cf4b116c3ff81a
|
||||
title: Factors of a Mersenne number
|
||||
challengeType: 5
|
||||
forumTopicId: 302264
|
||||
dashedName: factors-of-a-mersenne-number
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
A Mersenne number is a number in the form of <code>2<sup>P</sup>-1</code>.
|
||||
|
||||
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](https://rosettacode.org/wiki/Lucas-Lehmer test "Lucas-Lehmer test").
|
||||
|
||||
There are very efficient algorithms for determining if a number divides <code>2<sup>P</sup>-1</code> (or equivalently, if <code>2<sup>P</sup> mod (the number) = 1</code>).
|
||||
|
||||
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 <code>2<sup>23</sup> mod 47</code>.
|
||||
|
||||
Convert the exponent 23 to binary, you get 10111. Starting with <code><tt>square</tt> = 1</code>, 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 <code><tt>square</tt> modulo 47</code>.
|
||||
|
||||
Use the result of the modulo from the last step as the initial value of `square` in the next step:
|
||||
|
||||
<pre>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
|
||||
</pre>
|
||||
|
||||
Since <code>2<sup>23</sup> mod 47 = 1</code>, 47 is a factor of <code>2<sup>P</sup>-1</code>.
|
||||
|
||||
(To see this, subtract 1 from both sides: <code>2<sup>23</sup>-1 = 0 mod 47</code>.)
|
||||
|
||||
Since we've shown that 47 is a factor, <code>2<sup>23</sup>-1</code> is not prime.
|
||||
|
||||
Further properties of Mersenne numbers allow us to refine the process even more.
|
||||
|
||||
Any factor `q` of <code>2<sup>P</sup>-1</code> 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](https://rosettacode.org/wiki/Primality by Trial Division "Primality by Trial Division").
|
||||
|
||||
As in other trial division algorithms, the algorithm stops when `2kP+1 > sqrt(N)`.These primarily tests only work on Mersenne numbers where `P` is prime. For example, <code>M<sub>4</sub>=15</code> yields no factors using these techniques, but factors into 3 and 5, neither of which fit `2kP+1`.
|
||||
|
||||
# --instructions--
|
||||
|
||||
Using the above method find a factor of <code>2<sup>929</sup>-1</code> (aka M929)
|
||||
|
||||
# --hints--
|
||||
|
||||
`check_mersenne` should be a function.
|
||||
|
||||
```js
|
||||
assert(typeof check_mersenne === 'function');
|
||||
```
|
||||
|
||||
`check_mersenne(3)` should return a string.
|
||||
|
||||
```js
|
||||
assert(typeof check_mersenne(3) == 'string');
|
||||
```
|
||||
|
||||
`check_mersenne(3)` should return "M3 = 2^3-1 is prime".
|
||||
|
||||
```js
|
||||
assert.equal(check_mersenne(3), 'M3 = 2^3-1 is prime');
|
||||
```
|
||||
|
||||
`check_mersenne(23)` should return "M23 = 2^23-1 is composite with factor 47".
|
||||
|
||||
```js
|
||||
assert.equal(check_mersenne(23), 'M23 = 2^23-1 is composite with factor 47');
|
||||
```
|
||||
|
||||
`check_mersenne(929)` should return "M929 = 2^929-1 is composite with factor 13007
|
||||
|
||||
```js
|
||||
assert.equal(
|
||||
check_mersenne(929),
|
||||
'M929 = 2^929-1 is composite with factor 13007'
|
||||
);
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```js
|
||||
function check_mersenne(p) {
|
||||
|
||||
}
|
||||
```
|
||||
|
||||
# --solutions--
|
||||
|
||||
```js
|
||||
function check_mersenne(p){
|
||||
function isPrime(value){
|
||||
for (let i=2; i < value; i++){
|
||||
if (value % i == 0){
|
||||
return false;
|
||||
}
|
||||
if (value % i != 0){
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function trial_factor(base, exp, mod){
|
||||
let square, bits;
|
||||
square = 1;
|
||||
bits = exp.toString(2).split('');
|
||||
for (let i=0,ln=bits.length; i<ln; i++){
|
||||
square = Math.pow(square, 2) * (bits[i] == 1 ? base : 1) % mod;
|
||||
}
|
||||
return (square == 1);
|
||||
}
|
||||
|
||||
function mersenne_factor(p){
|
||||
let limit, k, q;
|
||||
limit = Math.sqrt(Math.pow(2,p) - 1);
|
||||
k = 1;
|
||||
while ((2*k*p - 1) < limit){
|
||||
q = 2*k*p + 1;
|
||||
if (isPrime(q) && (q % 8 == 1 || q % 8 == 7) && trial_factor(2,p,q)){
|
||||
return q; // q is a factor of 2**p-1
|
||||
}
|
||||
k++;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
let f, result;
|
||||
result="M"+p+" = 2^"+p+"-1 is ";
|
||||
f = mersenne_factor(p);
|
||||
result+=f == null ? "prime" : "composite with factor "+f;
|
||||
return result;
|
||||
}
|
||||
```
|
@ -0,0 +1,74 @@
|
||||
---
|
||||
id: 597f1e7fbc206f0e9ba95dc4
|
||||
title: Factors of an integer
|
||||
challengeType: 5
|
||||
forumTopicId: 302265
|
||||
dashedName: factors-of-an-integer
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
Write a function that returns the factors of a positive integer as an array.
|
||||
|
||||
These factors are the positive integers by which the number being factored can be divided to yield a positive integer result.
|
||||
|
||||
# --hints--
|
||||
|
||||
`factors` should be a function.
|
||||
|
||||
```js
|
||||
assert(typeof factors === 'function');
|
||||
```
|
||||
|
||||
`factors(45)` should return `[1,3,5,9,15,45]`.
|
||||
|
||||
```js
|
||||
assert.deepEqual(factors(45), ans[0]);
|
||||
```
|
||||
|
||||
`factors(53)` should return `[1,53]`.
|
||||
|
||||
```js
|
||||
assert.deepEqual(factors(53), ans[1]);
|
||||
```
|
||||
|
||||
`factors(64)` should return `[1,2,4,8,16,32,64]`.
|
||||
|
||||
```js
|
||||
assert.deepEqual(factors(64), ans[2]);
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --after-user-code--
|
||||
|
||||
```js
|
||||
const ans=[[1,3,5,9,15,45],[1,53],[1,2,4,8,16,32,64]];
|
||||
```
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```js
|
||||
function factors(num) {
|
||||
|
||||
}
|
||||
```
|
||||
|
||||
# --solutions--
|
||||
|
||||
```js
|
||||
function factors(num)
|
||||
{
|
||||
let n_factors = [], i, sqr=Math.floor(Math.sqrt(num));
|
||||
|
||||
for (i = 1; i <=sqr ; i += 1)
|
||||
if (num % i === 0)
|
||||
{
|
||||
n_factors.push(i);
|
||||
if (num / i !== i)
|
||||
n_factors.push(num / i);
|
||||
}
|
||||
n_factors.sort(function(a, b){return a - b;});
|
||||
return n_factors;
|
||||
}
|
||||
```
|
@ -0,0 +1,109 @@
|
||||
---
|
||||
id: 59c3ec9f15068017c96eb8a3
|
||||
title: Farey sequence
|
||||
challengeType: 5
|
||||
forumTopicId: 302266
|
||||
dashedName: farey-sequence
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
The [Farey sequence](https://en.wikipedia.org/wiki/Farey sequence "wp: Farey sequence") <code>F<sub>n</sub></code> 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:
|
||||
|
||||
<ul>
|
||||
<li>starts with the value 0, denoted by the fraction $ \frac{0}{1} $</li>
|
||||
<li>ends with the value 1, denoted by the fraction $ \frac{1}{1}$.</li>
|
||||
</ul>
|
||||
|
||||
The Farey sequences of orders `1` to `5` are:
|
||||
|
||||
<ul>
|
||||
<li style='list-style: none;'>${\bf\it{F}}_1 = \frac{0}{1}, \frac{1}{1}$</li>
|
||||
<li style='list-style: none;'>${\bf\it{F}}_2 = \frac{0}{1}, \frac{1}{2}, \frac{1}{1}$</li>
|
||||
<li style='list-style: none;'>${\bf\it{F}}_3 = \frac{0}{1}, \frac{1}{3}, \frac{1}{2}, \frac{2}{3}, \frac{1}{1}$</li>
|
||||
<li style='list-style: none;'>${\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}$</li>
|
||||
<li style='list-style: none;'>${\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}$</li>
|
||||
</ul>
|
||||
|
||||
# --instructions--
|
||||
|
||||
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.
|
||||
|
||||
# --hints--
|
||||
|
||||
`farey` should be a function.
|
||||
|
||||
```js
|
||||
assert(typeof farey === 'function');
|
||||
```
|
||||
|
||||
`farey(3)` should return an array
|
||||
|
||||
```js
|
||||
assert(Array.isArray(farey(3)));
|
||||
```
|
||||
|
||||
`farey(3)` should return `["1/3","1/2","2/3"]`
|
||||
|
||||
```js
|
||||
assert.deepEqual(farey(3), ['1/3', '1/2', '2/3']);
|
||||
```
|
||||
|
||||
`farey(4)` should return `["1/4","1/3","1/2","2/4","2/3","3/4"]`
|
||||
|
||||
```js
|
||||
assert.deepEqual(farey(4), ['1/4', '1/3', '1/2', '2/4', '2/3', '3/4']);
|
||||
```
|
||||
|
||||
`farey(5)` should return `["1/5","1/4","1/3","2/5","1/2","2/4","3/5","2/3","3/4","4/5"]`
|
||||
|
||||
```js
|
||||
assert.deepEqual(farey(5), [
|
||||
'1/5',
|
||||
'1/4',
|
||||
'1/3',
|
||||
'2/5',
|
||||
'1/2',
|
||||
'2/4',
|
||||
'3/5',
|
||||
'2/3',
|
||||
'3/4',
|
||||
'4/5'
|
||||
]);
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```js
|
||||
function farey(n) {
|
||||
|
||||
}
|
||||
```
|
||||
|
||||
# --solutions--
|
||||
|
||||
```js
|
||||
function farey(n){
|
||||
let farSeq=[];
|
||||
for(let den = 1; den <= n; den++){
|
||||
for(let num = 1; num < den; num++){
|
||||
farSeq.push({
|
||||
str:num+"/"+den,
|
||||
val:num/den});
|
||||
}
|
||||
}
|
||||
farSeq.sort(function(a,b){
|
||||
return a.val-b.val;
|
||||
});
|
||||
farSeq=farSeq.map(function(a){
|
||||
return a.str;
|
||||
});
|
||||
return farSeq;
|
||||
}
|
||||
```
|
@ -0,0 +1,133 @@
|
||||
---
|
||||
id: 598eef80ba501f1268170e1e
|
||||
title: Fibonacci n-step number sequences
|
||||
challengeType: 5
|
||||
forumTopicId: 302267
|
||||
dashedName: fibonacci-n-step-number-sequences
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
These number series are an expansion of the ordinary [Fibonacci sequence](https://rosettacode.org/wiki/Fibonacci sequence "Fibonacci sequence") where:
|
||||
|
||||
<ol>
|
||||
<li>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$</li>
|
||||
<li>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$</li>
|
||||
<li>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$...</li>
|
||||
<li>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)}}$</li>
|
||||
</ol>
|
||||
|
||||
For small values of $n$, [Greek numeric prefixes](https://en.wikipedia.org/wiki/Number prefix#Greek_series "wp: Number prefix#Greek_series") are sometimes used to individually name each series.
|
||||
|
||||
Fibonacci $n$-step sequences:
|
||||
|
||||
| $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](https://en.wikipedia.org/wiki/Lucas number "wp: Lucas number") sums the two preceding values like the fibonacci series for $n=2$ but uses $\[2, 1]$ as its initial values.
|
||||
|
||||
# --instructions--
|
||||
|
||||
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.
|
||||
|
||||
# --hints--
|
||||
|
||||
`fib_luc` should be a function.
|
||||
|
||||
```js
|
||||
assert(typeof fib_luc === 'function');
|
||||
```
|
||||
|
||||
`fib_luc(2,10,"f")` should return `[1,1,2,3,5,8,13,21,34,55]`.
|
||||
|
||||
```js
|
||||
assert.deepEqual(fib_luc(2, 10, 'f'), ans[0]);
|
||||
```
|
||||
|
||||
`fib_luc(3,15,"f")` should return `[1,1,2,4,7,13,24,44,81,149,274,504,927,1705,3136]`.
|
||||
|
||||
```js
|
||||
assert.deepEqual(fib_luc(3, 15, 'f'), ans[1]);
|
||||
```
|
||||
|
||||
`fib_luc(4,15,"f")` should return `[1,1,2,4,8,15,29,56,108,208,401,773,1490,2872,5536]`.
|
||||
|
||||
```js
|
||||
assert.deepEqual(fib_luc(4, 15, 'f'), ans[2]);
|
||||
```
|
||||
|
||||
`fib_luc(2,10,"l")` should return `[ 2, 1, 3, 4, 7, 11, 18, 29, 47, 76]`.
|
||||
|
||||
```js
|
||||
assert.deepEqual(fib_luc(2, 10, 'l'), ans[3]);
|
||||
```
|
||||
|
||||
`fib_luc(3,15,"l")` should return `[ 2, 1, 3, 6, 10, 19, 35, 64, 118, 217, 399, 734, 1350, 2483, 4567 ]`.
|
||||
|
||||
```js
|
||||
assert.deepEqual(fib_luc(3, 15, 'l'), ans[4]);
|
||||
```
|
||||
|
||||
`fib_luc(4,15,"l")` should return `[ 2, 1, 3, 6, 12, 22, 43, 83, 160, 308, 594, 1145, 2207, 4254, 8200 ]`.
|
||||
|
||||
```js
|
||||
assert.deepEqual(fib_luc(4, 15, 'l'), ans[5]);
|
||||
```
|
||||
|
||||
`fib_luc(5,15,"l")` should return `[ 2, 1, 3, 6, 12, 24, 46, 91, 179, 352, 692, 1360, 2674, 5257, 10335 ]`.
|
||||
|
||||
```js
|
||||
assert.deepEqual(fib_luc(5, 15, 'l'), ans[6]);
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --after-user-code--
|
||||
|
||||
```js
|
||||
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 ]];
|
||||
```
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```js
|
||||
function fib_luc(n, len, w) {
|
||||
|
||||
}
|
||||
```
|
||||
|
||||
# --solutions--
|
||||
|
||||
```js
|
||||
function fib_luc(n, len, w) {
|
||||
function nacci(a, n, len) {
|
||||
while (a.length < len) {
|
||||
let sum = 0;
|
||||
for (let i = Math.max(0, a.length - n); i < a.length; i++)
|
||||
sum += a[i];
|
||||
a.push(sum);
|
||||
}
|
||||
return a;
|
||||
}
|
||||
if(w=="f"){
|
||||
return nacci(nacci([1,1], n, n), n, len);
|
||||
}else{
|
||||
return nacci(nacci([2,1], n, n), n, len);
|
||||
}
|
||||
}
|
||||
```
|
@ -0,0 +1,75 @@
|
||||
---
|
||||
id: 597f24c1dda4e70f53c79c81
|
||||
title: Fibonacci sequence
|
||||
challengeType: 5
|
||||
forumTopicId: 302268
|
||||
dashedName: fibonacci-sequence
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
Write a function to generate the <code>n<sup>th</sup></code> Fibonacci number.
|
||||
|
||||
The <code>n<sup>th</sup></code> Fibonacci number is given by:
|
||||
|
||||
<code>F<sub>n</sub> = F<sub>n-1</sub> + F<sub>n-2</sub></code>
|
||||
|
||||
The first two terms of the series are 0 and 1.
|
||||
|
||||
Hence, the series is: 0, 1, 1, 2, 3, 5, 8, 13...
|
||||
|
||||
# --hints--
|
||||
|
||||
`fibonacci` should be a function.
|
||||
|
||||
```js
|
||||
assert(typeof fibonacci === 'function');
|
||||
```
|
||||
|
||||
`fibonacci(2)` should return a number.
|
||||
|
||||
```js
|
||||
assert(typeof fibonacci(2) == 'number');
|
||||
```
|
||||
|
||||
`fibonacci(3)` should return 2.
|
||||
|
||||
```js
|
||||
assert.equal(fibonacci(3), 2);
|
||||
```
|
||||
|
||||
`fibonacci(5)` should return 5.
|
||||
|
||||
```js
|
||||
assert.equal(fibonacci(5), 5);
|
||||
```
|
||||
|
||||
`fibonacci(10)` should return 55.
|
||||
|
||||
```js
|
||||
assert.equal(fibonacci(10), 55);
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```js
|
||||
function fibonacci(n) {
|
||||
|
||||
}
|
||||
```
|
||||
|
||||
# --solutions--
|
||||
|
||||
```js
|
||||
function fibonacci(n) {
|
||||
let a = 0, b = 1, t;
|
||||
while (--n >= 0) {
|
||||
t = a;
|
||||
a = b;
|
||||
b += t;
|
||||
}
|
||||
return a;
|
||||
}
|
||||
```
|
@ -0,0 +1,121 @@
|
||||
---
|
||||
id: 5992e222d397f00d21122931
|
||||
title: Fibonacci word
|
||||
challengeType: 5
|
||||
forumTopicId: 302269
|
||||
dashedName: fibonacci-word
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
The Fibonacci Word may be created in a manner analogous to the Fibonacci Sequence [as described here](https://hal.archives-ouvertes.fr/docs/00/36/79/72/PDF/The_Fibonacci_word_fractal.pdf):
|
||||
|
||||
<pre>Define F_Word<sub>1</sub> as <strong>1</strong>
|
||||
Define F_Word<sub>2</sub> as <strong>0</strong>
|
||||
Form F_Word<sub>3</sub> as F_Word<sub>2</sub> concatenated with F_Word<sub>1</sub> i.e.: <strong>01</strong>
|
||||
Form F_Word<sub>n</sub> as F_Word<sub>n-1</sub> concatenated with F_word<sub>n-2</sub>
|
||||
</pre>
|
||||
|
||||
# --instructions--
|
||||
|
||||
Write a function to return the Fibonacci Words up to `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' }`.
|
||||
|
||||
# --hints--
|
||||
|
||||
`fibWord` should be a function.
|
||||
|
||||
```js
|
||||
assert(typeof fibWord === 'function');
|
||||
```
|
||||
|
||||
`fibWord(5)` should return an array.
|
||||
|
||||
```js
|
||||
assert(Array.isArray(fibWord(5)));
|
||||
```
|
||||
|
||||
`fibWord(5)` should return `[{ 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" }]`.
|
||||
|
||||
```js
|
||||
assert.deepEqual(fibWord(5), ans);
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --after-user-code--
|
||||
|
||||
```js
|
||||
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' }];
|
||||
```
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```js
|
||||
function fibWord(n) {
|
||||
|
||||
}
|
||||
```
|
||||
|
||||
# --solutions--
|
||||
|
||||
```js
|
||||
function fibWord(n) {
|
||||
function entropy(s) {
|
||||
//create an object containing each individual char
|
||||
//and the amount of iterations per char
|
||||
function prob(s) {
|
||||
var h = Object.create(null);
|
||||
s.split('').forEach(function(c) {
|
||||
h[c] && h[c]++ || (h[c] = 1);
|
||||
});
|
||||
return h;
|
||||
}
|
||||
|
||||
s = s.toString(); //just in case
|
||||
var e = 0, l = s.length, h = prob(s);
|
||||
|
||||
for (var i in h ) {
|
||||
var p = h[i]/l;
|
||||
e -= p * Math.log(p) / Math.log(2);
|
||||
}
|
||||
return e;
|
||||
}
|
||||
var wOne = "1", wTwo = "0", wNth = [wOne, wTwo], w = "", o = [];
|
||||
|
||||
for (var i = 0; i < n; i++) {
|
||||
if (i === 0 || i === 1) {
|
||||
w = wNth[i];
|
||||
} else {
|
||||
w = wNth[i - 1] + wNth[i - 2];
|
||||
wNth.push(w);
|
||||
}
|
||||
var l = w.length;
|
||||
var e = entropy(w);
|
||||
|
||||
if (l <= 21) {
|
||||
o.push({
|
||||
N: i + 1,
|
||||
Length: l,
|
||||
Entropy: e,
|
||||
Word: w
|
||||
});
|
||||
} else {
|
||||
o.push({
|
||||
N: i + 1,
|
||||
Length: l,
|
||||
Entropy: e,
|
||||
Word: "..."
|
||||
});
|
||||
}
|
||||
}
|
||||
return o;
|
||||
}
|
||||
```
|
@ -0,0 +1,92 @@
|
||||
---
|
||||
id: 5e9ddb06ec35240f39657419
|
||||
title: FizzBuzz
|
||||
challengeType: 5
|
||||
forumTopicId: 385370
|
||||
dashedName: fizzbuzz
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
Write a program that generates an array of integers from 1 to 100 (inclusive). But:
|
||||
|
||||
<ul>
|
||||
<li>for multiples of 3, add <code>"Fizz"</code> to the array instead of the number</li>
|
||||
<li>for multiples of 5, add <code>"Buzz"</code> to the array instead of the number</li>
|
||||
<li>for multiples of 3 and 5, add <code>"FizzBuzz"</code> to the array instead of the number</li>
|
||||
</ul>
|
||||
|
||||
# --instructions--
|
||||
|
||||
Your program should return an array containing the results based on the rules above.
|
||||
|
||||
# --hints--
|
||||
|
||||
`fizzBuzz` should be a function.
|
||||
|
||||
```js
|
||||
assert(typeof fizzBuzz == 'function');
|
||||
```
|
||||
|
||||
`fizzBuzz()` should return an Array.
|
||||
|
||||
```js
|
||||
assert(Array.isArray(fizzBuzz()) == true);
|
||||
```
|
||||
|
||||
Numbers divisible by only 3 should return `"Fizz"`.
|
||||
|
||||
```js
|
||||
assert.equal(fizzBuzz()[2], 'Fizz');
|
||||
```
|
||||
|
||||
Numbers divisible by only 5 should return `"Buzz"`.
|
||||
|
||||
```js
|
||||
assert.equal(fizzBuzz()[99], 'Buzz');
|
||||
```
|
||||
|
||||
Numbers divisible by both 3 and 5 should return `"FizzBuzz"`.
|
||||
|
||||
```js
|
||||
assert.equal(fizzBuzz()[89], 'FizzBuzz');
|
||||
```
|
||||
|
||||
Numbers not divisible by either 3 or 5 should return the number itself.
|
||||
|
||||
```js
|
||||
assert.equal(fizzBuzz()[12], 13);
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```js
|
||||
function fizzBuzz() {
|
||||
|
||||
}
|
||||
```
|
||||
|
||||
# --solutions--
|
||||
|
||||
```js
|
||||
function fizzBuzz() {
|
||||
let res=[];
|
||||
for (let i =1; i < 101; i++) {
|
||||
if (i % 3 === 0 && i % 5 === 0) {
|
||||
res.push("FizzBuzz");
|
||||
}
|
||||
else if (i % 3 === 0) {
|
||||
res.push("Fizz");
|
||||
}
|
||||
else if (i % 5 === 0) {
|
||||
res.push("Buzz");
|
||||
}
|
||||
else {
|
||||
res.push(i);
|
||||
}
|
||||
}
|
||||
return res;
|
||||
}
|
||||
```
|
@ -0,0 +1,139 @@
|
||||
---
|
||||
id: 5a7dad05be01840e1778a0d1
|
||||
title: Fractran
|
||||
challengeType: 5
|
||||
forumTopicId: 302270
|
||||
dashedName: fractran
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
[FRACTRAN](https://en.wikipedia.org/wiki/FRACTRAN "wp: FRACTRAN") is a Turing-complete esoteric programming language invented by the mathematician [John Horton Conway](https://en.wikipedia.org/wiki/John Horton Conway "wp: John Horton Conway").
|
||||
|
||||
A FRACTRAN program is an ordered list of positive fractions $P = (f_1, f_2, \\ldots, f_m)$, together with an initial positive integer input $n$.
|
||||
|
||||
The program is run by updating the integer $n$ as follows:
|
||||
|
||||
<ul>
|
||||
<li>for the first fraction, $f_i$, in the list for which $nf_i$ is an integer, replace $n$ with $nf_i$ ;</li>
|
||||
<li>repeat this rule until no fraction in the list produces an integer when multiplied by $n$, then halt.</li>
|
||||
</ul>
|
||||
|
||||
Conway gave a program for primes in FRACTRAN:
|
||||
|
||||
$\\dfrac{17}{91}$, $\\dfrac{78}{85}$, $\\dfrac{19}{51}$, $\\dfrac{23}{38}$, $\\dfrac{29}{33}$, $\\dfrac{77}{29}$, $\\dfrac{95}{23}$, $\\dfrac{77}{19}$, $\\dfrac{1}{17}$, $\\dfrac{11}{13}$, $\\dfrac{13}{11}$, $\\dfrac{15}{14}$, $\\dfrac{15}{2}$, $\\dfrac{55}{1}$
|
||||
|
||||
Starting with $n=2$, this FRACTRAN program will change $n$ to $15=2\\times (\\frac{15}{2})$, then $825=15\\times (\\frac{55}{1})$, generating the following sequence of integers:
|
||||
|
||||
$2$, $15$, $825$, $725$, $1925$, $2275$, $425$, $390$, $330$, $290$, $770$, $\\ldots$
|
||||
|
||||
After 2, this sequence contains the following powers of 2:
|
||||
|
||||
$2^2=4$, $2^3=8$, $2^5=32$, $2^7=128$, $2^{11}=2048$, $2^{13}=8192$, $2^{17}=131072$, $2^{19}=524288$, $\\ldots$
|
||||
|
||||
which are the prime powers of 2.
|
||||
|
||||
# --instructions--
|
||||
|
||||
Write a function that takes a fractran program as a string parameter and returns the first 10 numbers of the program as an array. If the result does not have 10 numbers then return the numbers as is.
|
||||
|
||||
# --hints--
|
||||
|
||||
`fractran` should be a function.
|
||||
|
||||
```js
|
||||
assert(typeof fractran == 'function');
|
||||
```
|
||||
|
||||
`fractran("3/2, 1/3")` should return an array.
|
||||
|
||||
```js
|
||||
assert(Array.isArray(fractran('3/2, 1/3')));
|
||||
```
|
||||
|
||||
`fractran("3/2, 1/3")` should return `[ 2, 3, 1 ]`.
|
||||
|
||||
```js
|
||||
assert.deepEqual(fractran('3/2, 1/3'), [2, 3, 1]);
|
||||
```
|
||||
|
||||
`fractran("3/2, 5/3, 1/5")` should return `[ 2, 3, 5, 1 ]`.
|
||||
|
||||
```js
|
||||
assert.deepEqual(fractran('3/2, 5/3, 1/5'), [2, 3, 5, 1]);
|
||||
```
|
||||
|
||||
`fractran("3/2, 6/3")` should return `[ 2, 3, 6, 9, 18, 27, 54, 81, 162, 243 ]`.
|
||||
|
||||
```js
|
||||
assert.deepEqual(fractran('3/2, 6/3'), [2, 3, 6, 9, 18, 27, 54, 81, 162, 243]);
|
||||
```
|
||||
|
||||
`fractran("2/7, 7/2")` should return `[ 2, 7, 2, 7, 2, 7, 2, 7, 2, 7 ]`.
|
||||
|
||||
```js
|
||||
assert.deepEqual(fractran('2/7, 7/2'), [2, 7, 2, 7, 2, 7, 2, 7, 2, 7]);
|
||||
```
|
||||
|
||||
`fractran("17/91, 78/85, 19/51, 23/38, 29/33, 77/29, 95/23, 77/19, 1/17, 11/13, 13/11, 15/14, 15/2, 55/1")` should return `[ 2, 15, 825, 725, 1925, 2275, 425, 390, 330, 290 ]`.
|
||||
|
||||
```js
|
||||
assert.deepEqual(
|
||||
fractran(
|
||||
'17/91, 78/85, 19/51, 23/38, 29/33, 77/29, 95/23, 77/19, 1/17, 11/13, 13/11, 15/14, 15/2, 55/1'
|
||||
),
|
||||
[2, 15, 825, 725, 1925, 2275, 425, 390, 330, 290]
|
||||
);
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```js
|
||||
function fractran(progStr) {
|
||||
|
||||
}
|
||||
```
|
||||
|
||||
# --solutions--
|
||||
|
||||
```js
|
||||
function fractran(progStr){
|
||||
var num = new Array();
|
||||
var den = new Array();
|
||||
var val ;
|
||||
var out="";
|
||||
function compile(prog){
|
||||
var regex = /\s*(\d*)\s*\/\s*(\d*)\s*(.*)/m;
|
||||
while(regex.test(prog)){
|
||||
num.push(regex.exec(prog)[1]);
|
||||
den.push(regex.exec(prog)[2]);
|
||||
prog = regex.exec(prog)[3];
|
||||
}
|
||||
}
|
||||
|
||||
function step(val){
|
||||
var i=0;
|
||||
while(i<den.length && val%den[i] != 0) i++;
|
||||
return num[i]*val/den[i];
|
||||
}
|
||||
|
||||
var seq=[]
|
||||
|
||||
function exec(val){
|
||||
var i = 0;
|
||||
while(val && i<limit){
|
||||
seq.push(val)
|
||||
val = step(val);
|
||||
i ++;
|
||||
}
|
||||
}
|
||||
|
||||
// Main
|
||||
compile(progStr);
|
||||
var limit = 10;
|
||||
exec(2);
|
||||
return seq;
|
||||
}
|
||||
```
|
@ -0,0 +1,104 @@
|
||||
---
|
||||
id: 5a23c84252665b21eecc7e76
|
||||
title: Gamma function
|
||||
challengeType: 5
|
||||
forumTopicId: 302271
|
||||
dashedName: gamma-function
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
Implement one algorithm (or more) to compute the [Gamma](https://en.wikipedia.org/wiki/Gamma function) ($\\Gamma$) function (in the real field only).
|
||||
|
||||
The Gamma function can be defined as:
|
||||
|
||||
<div style='padding-left: 4em;'><big><big>$\Gamma(x) = \displaystyle\int_0^\infty t^{x-1}e^{-t} dt$</big></big></div>
|
||||
|
||||
# --hints--
|
||||
|
||||
`gamma` should be a function.
|
||||
|
||||
```js
|
||||
assert(typeof gamma == 'function');
|
||||
```
|
||||
|
||||
`gamma(.1)` should return a number.
|
||||
|
||||
```js
|
||||
assert(typeof gamma(0.1) == 'number');
|
||||
```
|
||||
|
||||
`gamma(.1)` should return `9.513507698668736`.
|
||||
|
||||
```js
|
||||
assert.equal(round(gamma(0.1)), round(9.513507698668736));
|
||||
```
|
||||
|
||||
`gamma(.2)` should return `4.590843711998803`.
|
||||
|
||||
```js
|
||||
assert.equal(round(gamma(0.2)), round(4.590843711998803));
|
||||
```
|
||||
|
||||
`gamma(.3)` should return `2.9915689876875904`.
|
||||
|
||||
```js
|
||||
assert.equal(round(gamma(0.3)), round(2.9915689876875904));
|
||||
```
|
||||
|
||||
`gamma(.4)` should return `2.218159543757687`.
|
||||
|
||||
```js
|
||||
assert.equal(round(gamma(0.4)), round(2.218159543757687));
|
||||
```
|
||||
|
||||
`gamma(.5)` should return `1.7724538509055159`.
|
||||
|
||||
```js
|
||||
assert.equal(round(gamma(0.5)), round(1.7724538509055159));
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --after-user-code--
|
||||
|
||||
```js
|
||||
function round(x) {
|
||||
return Number(x).toPrecision(13);
|
||||
}
|
||||
```
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```js
|
||||
function gamma(x) {
|
||||
|
||||
}
|
||||
```
|
||||
|
||||
# --solutions--
|
||||
|
||||
```js
|
||||
function gamma(x) {
|
||||
var p = [0.99999999999980993, 676.5203681218851, -1259.1392167224028,
|
||||
771.32342877765313, -176.61502916214059, 12.507343278686905,
|
||||
-0.13857109526572012, 9.9843695780195716e-6, 1.5056327351493116e-7
|
||||
];
|
||||
|
||||
var g = 7;
|
||||
if (x < 0.5) {
|
||||
return Math.PI / (Math.sin(Math.PI * x) * gamma(1 - x));
|
||||
}
|
||||
|
||||
x -= 1;
|
||||
var a = p[0];
|
||||
var t = x + g + 0.5;
|
||||
for (var i = 1; i < p.length; i++) {
|
||||
a += p[i] / (x + i);
|
||||
}
|
||||
|
||||
var result=Math.sqrt(2 * Math.PI) * Math.pow(t, x + 0.5) * Math.exp(-t) * a;
|
||||
|
||||
return result;
|
||||
}
|
||||
```
|
@ -0,0 +1,230 @@
|
||||
---
|
||||
id: 5a23c84252665b21eecc7e77
|
||||
title: Gaussian elimination
|
||||
challengeType: 5
|
||||
forumTopicId: 302272
|
||||
dashedName: gaussian-elimination
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
Write a function to solve \\(Ax = b\\) using Gaussian elimination then backwards substitution.
|
||||
|
||||
\\(A\\) being an \\(n \\times n\\) matrix. Also, \\(x\\) and \\(b\\) are \\(n\\) by 1 vectors.
|
||||
|
||||
To improve accuracy, please use partial pivoting and scaling.
|
||||
|
||||
# --hints--
|
||||
|
||||
`gaussianElimination` should be a function.
|
||||
|
||||
```js
|
||||
assert(typeof gaussianElimination == 'function');
|
||||
```
|
||||
|
||||
`gaussianElimination([[1,1],[1,-1]], [5,1])` should return an array.
|
||||
|
||||
```js
|
||||
assert(
|
||||
Array.isArray(
|
||||
gaussianElimination(
|
||||
[
|
||||
[1, 1],
|
||||
[1, -1]
|
||||
],
|
||||
[5, 1]
|
||||
)
|
||||
)
|
||||
);
|
||||
```
|
||||
|
||||
`gaussianElimination([[1,1],[1,-1]], [5,1])` should return `[ 3, 2 ]`.
|
||||
|
||||
```js
|
||||
assert.deepEqual(
|
||||
gaussianElimination(
|
||||
[
|
||||
[1, 1],
|
||||
[1, -1]
|
||||
],
|
||||
[5, 1]
|
||||
),
|
||||
[3, 2]
|
||||
);
|
||||
```
|
||||
|
||||
`gaussianElimination([[2,3],[2,1]] , [8,4])` should return `[ 1, 2 ]`.
|
||||
|
||||
```js
|
||||
assert.deepEqual(
|
||||
gaussianElimination(
|
||||
[
|
||||
[2, 3],
|
||||
[2, 1]
|
||||
],
|
||||
[8, 4]
|
||||
),
|
||||
[1, 2]
|
||||
);
|
||||
```
|
||||
|
||||
`gaussianElimination([[1,3],[5,-2]], [14,19])` should return `[ 5, 3 ]`.
|
||||
|
||||
```js
|
||||
assert.deepEqual(
|
||||
gaussianElimination(
|
||||
[
|
||||
[1, 3],
|
||||
[5, -2]
|
||||
],
|
||||
[14, 19]
|
||||
),
|
||||
[5, 3]
|
||||
);
|
||||
```
|
||||
|
||||
`gaussianElimination([[1,1],[5,-1]] , [10,14])` should return `[ 4, 6 ]`.
|
||||
|
||||
```js
|
||||
assert.deepEqual(
|
||||
gaussianElimination(
|
||||
[
|
||||
[1, 1],
|
||||
[5, -1]
|
||||
],
|
||||
[10, 14]
|
||||
),
|
||||
[4, 6]
|
||||
);
|
||||
```
|
||||
|
||||
`gaussianElimination([[1,2,3],[4,5,6],[7,8,8]] , [6,15,23])` should return `[ 1, 1, 1 ]`.
|
||||
|
||||
```js
|
||||
assert.deepEqual(
|
||||
gaussianElimination(
|
||||
[
|
||||
[1, 2, 3],
|
||||
[4, 5, 6],
|
||||
[7, 8, 8]
|
||||
],
|
||||
[6, 15, 23]
|
||||
),
|
||||
[1, 1, 1]
|
||||
);
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```js
|
||||
function gaussianElimination(A,b) {
|
||||
|
||||
}
|
||||
```
|
||||
|
||||
# --solutions--
|
||||
|
||||
```js
|
||||
function gaussianElimination(A, b) {
|
||||
// Lower Upper Decomposition
|
||||
function ludcmp(A) {
|
||||
// A is a matrix that we want to decompose into Lower and Upper matrices.
|
||||
var d = true
|
||||
var n = A.length
|
||||
var idx = new Array(n) // Output vector with row permutations from partial pivoting
|
||||
var vv = new Array(n) // Scaling information
|
||||
|
||||
for (var i=0; i<n; i++) {
|
||||
var max = 0
|
||||
for (var j=0; j<n; j++) {
|
||||
var temp = Math.abs(A[i][j])
|
||||
if (temp > max) max = temp
|
||||
}
|
||||
if (max == 0) return // Singular Matrix!
|
||||
vv[i] = 1 / max // Scaling
|
||||
}
|
||||
|
||||
var Acpy = new Array(n)
|
||||
for (var i=0; i<n; i++) {
|
||||
var Ai = A[i]
|
||||
let Acpyi = new Array(Ai.length)
|
||||
for (j=0; j<Ai.length; j+=1) Acpyi[j] = Ai[j]
|
||||
Acpy[i] = Acpyi
|
||||
}
|
||||
A = Acpy
|
||||
|
||||
var tiny = 1e-20 // in case pivot element is zero
|
||||
for (var i=0; ; i++) {
|
||||
for (var j=0; j<i; j++) {
|
||||
var sum = A[j][i]
|
||||
for (var k=0; k<j; k++) sum -= A[j][k] * A[k][i];
|
||||
A[j][i] = sum
|
||||
}
|
||||
var jmax = 0
|
||||
var max = 0;
|
||||
for (var j=i; j<n; j++) {
|
||||
var sum = A[j][i]
|
||||
for (var k=0; k<i; k++) sum -= A[j][k] * A[k][i];
|
||||
A[j][i] = sum
|
||||
var temp = vv[j] * Math.abs(sum)
|
||||
if (temp >= max) {
|
||||
max = temp
|
||||
jmax = j
|
||||
}
|
||||
}
|
||||
if (i <= jmax) {
|
||||
for (var j=0; j<n; j++) {
|
||||
var temp = A[jmax][j]
|
||||
A[jmax][j] = A[i][j]
|
||||
A[i][j] = temp
|
||||
}
|
||||
d = !d;
|
||||
vv[jmax] = vv[i]
|
||||
}
|
||||
idx[i] = jmax;
|
||||
if (i == n-1) break;
|
||||
var temp = A[i][i]
|
||||
if (temp == 0) A[i][i] = temp = tiny
|
||||
temp = 1 / temp
|
||||
for (var j=i+1; j<n; j++) A[j][i] *= temp
|
||||
}
|
||||
return {A:A, idx:idx, d:d}
|
||||
}
|
||||
|
||||
// Lower Upper Back Substitution
|
||||
function lubksb(lu, b) {
|
||||
// solves the set of n linear equations A*x = b.
|
||||
// lu is the object containing A, idx and d as determined by the routine ludcmp.
|
||||
var A = lu.A
|
||||
var idx = lu.idx
|
||||
var n = idx.length
|
||||
|
||||
var bcpy = new Array(n)
|
||||
for (var i=0; i<b.length; i+=1) bcpy[i] = b[i]
|
||||
b = bcpy
|
||||
|
||||
for (var ii=-1, i=0; i<n; i++) {
|
||||
var ix = idx[i]
|
||||
var sum = b[ix]
|
||||
b[ix] = b[i]
|
||||
if (ii > -1)
|
||||
for (var j=ii; j<i; j++) sum -= A[i][j] * b[j]
|
||||
else if (sum)
|
||||
ii = i
|
||||
b[i] = sum
|
||||
}
|
||||
for (var i=n-1; i>=0; i--) {
|
||||
var sum = b[i]
|
||||
for (var j=i+1; j<n; j++) sum -= A[i][j] * b[j]
|
||||
b[i] = sum / A[i][i]
|
||||
}
|
||||
return b // solution vector x
|
||||
}
|
||||
|
||||
var lu = ludcmp(A)
|
||||
if (lu === undefined) return // Singular Matrix!
|
||||
return lubksb(lu, b)
|
||||
}
|
||||
```
|
@ -0,0 +1,175 @@
|
||||
---
|
||||
id: 5a23c84252665b21eecc7e78
|
||||
title: General FizzBuzz
|
||||
challengeType: 5
|
||||
forumTopicId: 302273
|
||||
dashedName: general-fizzbuzz
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
Write a generalized version of [FizzBuzz](https://rosettacode.org/wiki/FizzBuzz) that works for any list of factors, along with their words.
|
||||
|
||||
This is basically a "fizzbuzz" implementation where the rules of the game are supplied to the user. Create a function to implement this. The function should take two parameters.
|
||||
|
||||
The first will be an array with the FizzBuzz rules. For example: `[ [3, "Fizz"] , [5, "Buzz"] ]`.
|
||||
|
||||
This indicates that `Fizz` should be printed if the number is a multiple of 3 and `Buzz` if it is a multiple of 5. If it is a multiple of both then the strings should be concatenated in the order specified in the array. In this case, `FizzBuzz` if the number is a multiple of 3 and 5.
|
||||
|
||||
The second parameter is the number for which the function should return a string as stated above.
|
||||
|
||||
# --hints--
|
||||
|
||||
`genFizzBuzz` should be a function.
|
||||
|
||||
```js
|
||||
assert(typeof genFizzBuzz == 'function');
|
||||
```
|
||||
|
||||
`genFizzBuzz([[3, "Fizz"],[5, "Buzz"]], 6)` should return a string.
|
||||
|
||||
```js
|
||||
assert(
|
||||
typeof genFizzBuzz(
|
||||
[
|
||||
[3, 'Fizz'],
|
||||
[5, 'Buzz']
|
||||
],
|
||||
6
|
||||
) == 'string'
|
||||
);
|
||||
```
|
||||
|
||||
`genFizzBuzz([[3, "Fizz"],[5, "Buzz"]], 6)` should return `"Fizz"`.
|
||||
|
||||
```js
|
||||
assert.equal(
|
||||
genFizzBuzz(
|
||||
[
|
||||
[3, 'Fizz'],
|
||||
[5, 'Buzz']
|
||||
],
|
||||
6
|
||||
),
|
||||
'Fizz'
|
||||
);
|
||||
```
|
||||
|
||||
`genFizzBuzz([[3, "Fizz"],[5, "Buzz"]], 10)` should return `"Buzz"`.
|
||||
|
||||
```js
|
||||
assert.equal(
|
||||
genFizzBuzz(
|
||||
[
|
||||
[3, 'Fizz'],
|
||||
[5, 'Buzz']
|
||||
],
|
||||
10
|
||||
),
|
||||
'Buzz'
|
||||
);
|
||||
```
|
||||
|
||||
`genFizzBuzz([[3, "Buzz"],[5, "Fizz"]], 12)` should return `"Buzz"`.
|
||||
|
||||
```js
|
||||
assert.equal(
|
||||
genFizzBuzz(
|
||||
[
|
||||
[3, 'Buzz'],
|
||||
[5, 'Fizz']
|
||||
],
|
||||
12
|
||||
),
|
||||
'Buzz'
|
||||
);
|
||||
```
|
||||
|
||||
`genFizzBuzz([[3, "Buzz"],[5, "Fizz"]], 13)` should return `"13"`.
|
||||
|
||||
```js
|
||||
assert.equal(
|
||||
genFizzBuzz(
|
||||
[
|
||||
[3, 'Buzz'],
|
||||
[5, 'Fizz']
|
||||
],
|
||||
13
|
||||
),
|
||||
'13'
|
||||
);
|
||||
```
|
||||
|
||||
`genFizzBuzz([[3, "Buzz"],[5, "Fizz"]], 15)` should return `"BuzzFizz"`.
|
||||
|
||||
```js
|
||||
assert.equal(
|
||||
genFizzBuzz(
|
||||
[
|
||||
[3, 'Buzz'],
|
||||
[5, 'Fizz']
|
||||
],
|
||||
15
|
||||
),
|
||||
'BuzzFizz'
|
||||
);
|
||||
```
|
||||
|
||||
`genFizzBuzz([[3, "Fizz"],[5, "Buzz"]], 15)` should return `"FizzBuzz"`.
|
||||
|
||||
```js
|
||||
assert.equal(
|
||||
genFizzBuzz(
|
||||
[
|
||||
[3, 'Fizz'],
|
||||
[5, 'Buzz']
|
||||
],
|
||||
15
|
||||
),
|
||||
'FizzBuzz'
|
||||
);
|
||||
```
|
||||
|
||||
`genFizzBuzz([[3, "Fizz"],[5, "Buzz"],[7, "Baxx"]], 105)` should return `"FizzBuzzBaxx"`.
|
||||
|
||||
```js
|
||||
assert.equal(
|
||||
genFizzBuzz(
|
||||
[
|
||||
[3, 'Fizz'],
|
||||
[5, 'Buzz'],
|
||||
[7, 'Baxx']
|
||||
],
|
||||
105
|
||||
),
|
||||
'FizzBuzzBaxx'
|
||||
);
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```js
|
||||
function genFizzBuzz(rules, num) {
|
||||
|
||||
}
|
||||
```
|
||||
|
||||
# --solutions--
|
||||
|
||||
```js
|
||||
function genFizzBuzz(rules, num) {
|
||||
let res='';
|
||||
rules.forEach(function (e) {
|
||||
if(num % e[0] == 0)
|
||||
res+=e[1];
|
||||
})
|
||||
|
||||
if(res==''){
|
||||
res=num.toString();
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
```
|
@ -0,0 +1,99 @@
|
||||
---
|
||||
id: 5a23c84252665b21eecc7e7a
|
||||
title: Generate lower case ASCII alphabet
|
||||
challengeType: 5
|
||||
forumTopicId: 302274
|
||||
dashedName: generate-lower-case-ascii-alphabet
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
Write a function to generate an array of lower case ASCII characters for a given range. For example, given the range `['a', 'd']`, the function should return `['a', 'b', 'c', 'd']`.
|
||||
|
||||
# --hints--
|
||||
|
||||
`lascii` should be a function.
|
||||
|
||||
```js
|
||||
assert(typeof lascii == 'function');
|
||||
```
|
||||
|
||||
`lascii("a","d")` should return an array.
|
||||
|
||||
```js
|
||||
assert(Array.isArray(lascii('a', 'd')));
|
||||
```
|
||||
|
||||
`lascii('a','d')` should return `[ 'a', 'b', 'c', 'd' ]`.
|
||||
|
||||
```js
|
||||
assert.deepEqual(lascii('a', 'd'), results[0]);
|
||||
```
|
||||
|
||||
`lascii('c','i')` should return `[ 'c', 'd', 'e', 'f', 'g', 'h', 'i' ]`.
|
||||
|
||||
```js
|
||||
assert.deepEqual(lascii('c', 'i'), results[1]);
|
||||
```
|
||||
|
||||
`lascii('m','q')` should return `[ 'm', 'n', 'o', 'p', 'q' ]`.
|
||||
|
||||
```js
|
||||
assert.deepEqual(lascii('m', 'q'), results[2]);
|
||||
```
|
||||
|
||||
`lascii('k','n')` should return `[ 'k', 'l', 'm', 'n' ]`.
|
||||
|
||||
```js
|
||||
assert.deepEqual(lascii('k', 'n'), results[3]);
|
||||
```
|
||||
|
||||
`lascii('t','z')` should return `[ 't', 'u', 'v', 'w', 'x', 'y', 'z' ]`.
|
||||
|
||||
```js
|
||||
assert.deepEqual(lascii('t', 'z'), results[4]);
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --after-user-code--
|
||||
|
||||
```js
|
||||
let results=[
|
||||
[ 'a', 'b', 'c', 'd' ],
|
||||
[ 'c', 'd', 'e', 'f', 'g', 'h', 'i' ],
|
||||
[ 'm', 'n', 'o', 'p', 'q' ],
|
||||
[ 'k', 'l', 'm', 'n' ],
|
||||
[ 't', 'u', 'v', 'w', 'x', 'y', 'z' ]
|
||||
]
|
||||
```
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```js
|
||||
function lascii(cFrom, cTo) {
|
||||
|
||||
}
|
||||
```
|
||||
|
||||
# --solutions--
|
||||
|
||||
```js
|
||||
function lascii(cFrom, cTo) {
|
||||
|
||||
function cRange(cFrom, cTo) {
|
||||
var iStart = cFrom.charCodeAt(0);
|
||||
|
||||
return Array.apply(
|
||||
null, Array(cTo.charCodeAt(0) - iStart + 1)
|
||||
).map(function (_, i) {
|
||||
|
||||
return String.fromCharCode(iStart + i);
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
return cRange(cFrom, cTo);
|
||||
|
||||
}
|
||||
```
|
@ -0,0 +1,117 @@
|
||||
---
|
||||
id: 5a23c84252665b21eecc7e7b
|
||||
title: Generator/Exponential
|
||||
challengeType: 5
|
||||
forumTopicId: 302275
|
||||
dashedName: generatorexponential
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
A generator is an executable entity (like a function or procedure) that contains code that yields a sequence of values, one at a time, so that each time you call the generator, the next value in the sequence is provided.
|
||||
|
||||
Generators are often built on top of coroutines or objects so that the internal state of the object is handled "naturally".
|
||||
|
||||
Generators are often used in situations where a sequence is potentially infinite, and where it is possible to construct the next value of the sequence with only minimal state.
|
||||
|
||||
# --instructions--
|
||||
|
||||
Write a function that uses generators to generate squares and cubes. Create a new generator that filters all cubes from the generator of squares.
|
||||
|
||||
The function should return the \\( n^{th} \\) value of the filtered generator.
|
||||
|
||||
For example for \\(n=7\\), the function should return 81 as the sequence would be 4, 9, 16, 25, 36, 49, 81. Here 64 is filtered out, as it is a cube.
|
||||
|
||||
# --hints--
|
||||
|
||||
`exponentialGenerator` should be a function.
|
||||
|
||||
```js
|
||||
assert(typeof exponentialGenerator == 'function');
|
||||
```
|
||||
|
||||
`exponentialGenerator()` should return a number.
|
||||
|
||||
```js
|
||||
assert(typeof exponentialGenerator(10) == 'number');
|
||||
```
|
||||
|
||||
`exponentialGenerator(10)` should return `144`.
|
||||
|
||||
```js
|
||||
assert.equal(exponentialGenerator(10), 144);
|
||||
```
|
||||
|
||||
`exponentialGenerator(12)` should return `196`.
|
||||
|
||||
```js
|
||||
assert.equal(exponentialGenerator(12), 196);
|
||||
```
|
||||
|
||||
`exponentialGenerator(14)` should return `256`.
|
||||
|
||||
```js
|
||||
assert.equal(exponentialGenerator(14), 256);
|
||||
```
|
||||
|
||||
`exponentialGenerator(20)` should return `484`.
|
||||
|
||||
```js
|
||||
assert.equal(exponentialGenerator(20), 484);
|
||||
```
|
||||
|
||||
`exponentialGenerator(25)` should return `784`.
|
||||
|
||||
```js
|
||||
assert.equal(exponentialGenerator(25), 784);
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```js
|
||||
function exponentialGenerator(n) {
|
||||
|
||||
}
|
||||
```
|
||||
|
||||
# --solutions--
|
||||
|
||||
```js
|
||||
function exponentialGenerator(n){
|
||||
function* PowersGenerator(m) {
|
||||
var n=0;
|
||||
while(1) {
|
||||
yield Math.pow(n, m);
|
||||
n += 1;
|
||||
}
|
||||
}
|
||||
|
||||
function* FilteredGenerator(g, f){
|
||||
var value = g.next().value;
|
||||
var filter = f.next().value;
|
||||
while(1) {
|
||||
if( value < filter ) {
|
||||
yield value;
|
||||
value = g.next().value;
|
||||
} else if ( value > filter ) {
|
||||
filter = f.next().value;
|
||||
} else {
|
||||
value = g.next().value;
|
||||
filter = f.next().value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var squares = PowersGenerator(2);
|
||||
var cubes = PowersGenerator(3);
|
||||
|
||||
var filtered = FilteredGenerator(squares, cubes);
|
||||
|
||||
var curr=0;
|
||||
for(var i=0;i<n;i++) curr=filtered.next();
|
||||
|
||||
return curr.value;
|
||||
}
|
||||
```
|
@ -0,0 +1,122 @@
|
||||
---
|
||||
id: 5a23c84252665b21eecc7e80
|
||||
title: Gray code
|
||||
challengeType: 5
|
||||
forumTopicId: 302276
|
||||
dashedName: gray-code
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
[Gray code](https://en.wikipedia.org/wiki/Gray code) is a form of binary encoding where transitions between consecutive numbers differ by only one bit.
|
||||
|
||||
This is a useful encoding for reducing hardware data hazards with values that change rapidly and/or connect to slower hardware as inputs.
|
||||
|
||||
It is also useful for generating inputs for [Karnaugh maps](https://en.wikipedia.org/wiki/Karnaugh map) in order from left to right or top to bottom.
|
||||
|
||||
# --instructions--
|
||||
|
||||
Create a function to encode a number to and decode a number from Gray code. The function should will have 2 parameters.
|
||||
|
||||
The first would be a boolean. The function should encode for true and decode for false. The second parameter would be the number to be encoded/decoded.
|
||||
|
||||
Display the normal binary representations, Gray code representations, and decoded Gray code values for all 5-bit binary numbers (0-31 inclusive, leading 0's not necessary).
|
||||
|
||||
There are many possible Gray codes. The following encodes what is called "binary reflected Gray code."
|
||||
|
||||
Encoding (MSB is bit 0, b is binary, g is Gray code):
|
||||
|
||||
<pre>if b[i-1] = 1
|
||||
g[i] = not b[i]
|
||||
else
|
||||
g[i] = b[i]
|
||||
</pre>
|
||||
|
||||
Or:
|
||||
|
||||
<pre>g = b xor (b logically right shifted 1 time)
|
||||
</pre>
|
||||
|
||||
Decoding (MSB is bit 0, b is binary, g is Gray code):
|
||||
|
||||
<pre>b[0] = g[0]<br>
|
||||
for other bits:
|
||||
b[i] = g[i] xor b[i-1]
|
||||
</pre>
|
||||
|
||||
# --hints--
|
||||
|
||||
`gray` should be a function.
|
||||
|
||||
```js
|
||||
assert(typeof gray == 'function');
|
||||
```
|
||||
|
||||
`gray(true,177)` should return a number.
|
||||
|
||||
```js
|
||||
assert(typeof gray(true, 177) == 'number');
|
||||
```
|
||||
|
||||
`gray(true,177)` should return `233`.
|
||||
|
||||
```js
|
||||
assert.equal(gray(true, 177), 233);
|
||||
```
|
||||
|
||||
`gray(true,425)` should return `381`.
|
||||
|
||||
```js
|
||||
assert.equal(gray(true, 425), 381);
|
||||
```
|
||||
|
||||
`gray(true,870)` should return `725`.
|
||||
|
||||
```js
|
||||
assert.equal(gray(true, 870), 725);
|
||||
```
|
||||
|
||||
`gray(false,233)` should return `177`.
|
||||
|
||||
```js
|
||||
assert.equal(gray(false, 233), 177);
|
||||
```
|
||||
|
||||
`gray(false,381)` should return `425`.
|
||||
|
||||
```js
|
||||
assert.equal(gray(false, 381), 425);
|
||||
```
|
||||
|
||||
`gray(false,725)` should return `870`.
|
||||
|
||||
```js
|
||||
assert.equal(gray(false, 725), 870);
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```js
|
||||
function gray(enc, number) {
|
||||
|
||||
}
|
||||
```
|
||||
|
||||
# --solutions--
|
||||
|
||||
```js
|
||||
function gray(enc, number){
|
||||
if(enc){
|
||||
return number ^ (number >> 1);
|
||||
}else{
|
||||
let n = number;
|
||||
|
||||
while (number >>= 1) {
|
||||
n ^= number;
|
||||
}
|
||||
return n;
|
||||
}
|
||||
}
|
||||
```
|
@ -0,0 +1,79 @@
|
||||
---
|
||||
id: 5a23c84252665b21eecc7e82
|
||||
title: Greatest common divisor
|
||||
challengeType: 5
|
||||
forumTopicId: 302277
|
||||
dashedName: greatest-common-divisor
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
Write a function that returns the greatest common divisor of two integers.
|
||||
|
||||
# --hints--
|
||||
|
||||
`gcd` should be a function.
|
||||
|
||||
```js
|
||||
assert(typeof gcd == 'function');
|
||||
```
|
||||
|
||||
`gcd(24,36)` should return a number.
|
||||
|
||||
```js
|
||||
assert(typeof gcd(24, 36) == 'number');
|
||||
```
|
||||
|
||||
`gcd(24,36)` should return `12`.
|
||||
|
||||
```js
|
||||
assert.equal(gcd(24, 36), 12);
|
||||
```
|
||||
|
||||
`gcd(30,48)` should return `6`.
|
||||
|
||||
```js
|
||||
assert.equal(gcd(30, 48), 6);
|
||||
```
|
||||
|
||||
`gcd(10,15)` should return `5`.
|
||||
|
||||
```js
|
||||
assert.equal(gcd(10, 15), 5);
|
||||
```
|
||||
|
||||
`gcd(100,25)` should return `25`.
|
||||
|
||||
```js
|
||||
assert.equal(gcd(100, 25), 25);
|
||||
```
|
||||
|
||||
`gcd(13,250)` should return `1`.
|
||||
|
||||
```js
|
||||
assert.equal(gcd(13, 250), 1);
|
||||
```
|
||||
|
||||
`gcd(1300,250)` should return `50`.
|
||||
|
||||
```js
|
||||
assert.equal(gcd(1300, 250), 50);
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```js
|
||||
function gcd(a, b) {
|
||||
|
||||
}
|
||||
```
|
||||
|
||||
# --solutions--
|
||||
|
||||
```js
|
||||
function gcd(a, b) {
|
||||
return b==0 ? Math.abs(a):gcd(b, a % b);
|
||||
}
|
||||
```
|
@ -0,0 +1,113 @@
|
||||
---
|
||||
id: 5a23c84252665b21eecc7e84
|
||||
title: Greatest subsequential sum
|
||||
challengeType: 5
|
||||
forumTopicId: 302278
|
||||
dashedName: greatest-subsequential-sum
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
Given a sequence of integers, find a continuous subsequence which maximizes the sum of its elements, that is, the elements of no other single subsequence add up to a value larger than this one.
|
||||
|
||||
An empty subsequence is considered to have the sum of \\( 0 \\); thus if all elements are negative, the result must be the empty sequence.
|
||||
|
||||
# --hints--
|
||||
|
||||
`maximumSubsequence` should be a function.
|
||||
|
||||
```js
|
||||
assert(typeof maximumSubsequence == 'function');
|
||||
```
|
||||
|
||||
`maximumSubsequence([ 1, 2, -1, 3, 10, -10 ])` should return an array.
|
||||
|
||||
```js
|
||||
assert(Array.isArray(maximumSubsequence([1, 2, -1, 3, 10, -10])));
|
||||
```
|
||||
|
||||
`maximumSubsequence([ 1, 2, -1, 3, 10, -10 ])` should return `[ 1, 2, -1, 3, 10 ]`.
|
||||
|
||||
```js
|
||||
assert.deepEqual(maximumSubsequence([1, 2, -1, 3, 10, -10]), [1, 2, -1, 3, 10]);
|
||||
```
|
||||
|
||||
`maximumSubsequence([ 0, 8, 10, -2, -4, -1, -5, -3 ])` should return `[ 0, 8, 10 ]`.
|
||||
|
||||
```js
|
||||
assert.deepEqual(maximumSubsequence([0, 8, 10, -2, -4, -1, -5, -3]), [
|
||||
0,
|
||||
8,
|
||||
10
|
||||
]);
|
||||
```
|
||||
|
||||
`maximumSubsequence([ 9, 9, -10, 1 ])` should return `[ 9, 9 ]`.
|
||||
|
||||
```js
|
||||
assert.deepEqual(maximumSubsequence([9, 9, -10, 1]), [9, 9]);
|
||||
```
|
||||
|
||||
`maximumSubsequence([ 7, 1, -5, -3, -8, 1 ])` should return `[ 7, 1 ]`.
|
||||
|
||||
```js
|
||||
assert.deepEqual(maximumSubsequence([7, 1, -5, -3, -8, 1]), [7, 1]);
|
||||
```
|
||||
|
||||
`maximumSubsequence([ -3, 6, -1, 4, -4, -6 ])` should return `[ 6, -1, 4 ]`.
|
||||
|
||||
```js
|
||||
assert.deepEqual(maximumSubsequence([-3, 6, -1, 4, -4, -6]), [6, -1, 4]);
|
||||
```
|
||||
|
||||
`maximumSubsequence([ -1, -2, 3, 5, 6, -2, -1, 4, -4, 2, -1 ])` should return `[ 3, 5, 6, -2, -1, 4 ]`.
|
||||
|
||||
```js
|
||||
assert.deepEqual(maximumSubsequence([-1, -2, 3, 5, 6, -2, -1, 4, -4, 2, -1]), [
|
||||
3,
|
||||
5,
|
||||
6,
|
||||
-2,
|
||||
-1,
|
||||
4
|
||||
]);
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```js
|
||||
function maximumSubsequence(population) {
|
||||
|
||||
}
|
||||
```
|
||||
|
||||
# --solutions--
|
||||
|
||||
```js
|
||||
function maximumSubsequence(population) {
|
||||
function sumValues(arr) {
|
||||
var result = 0;
|
||||
for (var i = 0, len = arr.length; i < len; i++) {
|
||||
result += arr[i];
|
||||
}
|
||||
return result;
|
||||
}
|
||||
var greatest;
|
||||
var maxValue = 0;
|
||||
|
||||
for (var i = 0, len = population.length; i < len; i++) {
|
||||
for (var j = i; j <= len; j++) {
|
||||
var subsequence = population.slice(i, j);
|
||||
var value = sumValues(subsequence);
|
||||
if (value > maxValue) {
|
||||
maxValue = value;
|
||||
greatest = subsequence;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
return greatest;
|
||||
}
|
||||
```
|
@ -0,0 +1,104 @@
|
||||
---
|
||||
id: 595608ff8bcd7a50bd490181
|
||||
title: Hailstone sequence
|
||||
challengeType: 5
|
||||
forumTopicId: 302279
|
||||
dashedName: hailstone-sequence
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
The Hailstone sequence of numbers can be generated from a starting positive integer, `n` by:
|
||||
|
||||
<ul>
|
||||
<li>If <code>n</code> is <code>1</code> then the sequence ends</li>
|
||||
<li>If <code>n</code> is <code>even</code> then the next <code>n</code> of the sequence <code>= n/2</code></li>
|
||||
<li>If <code>n</code> is <code>odd</code> then the next <code>n</code> of the sequence <code>= (3 * n) + 1</code></li>
|
||||
</ul>
|
||||
|
||||
The (unproven) [Collatz conjecture](https://en.wikipedia.org/wiki/Collatz conjecture "wp: 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.
|
||||
|
||||
# --instructions--
|
||||
|
||||
<ol>
|
||||
<li>Create a routine to generate the hailstone sequence for a number</li>
|
||||
<li>Use the routine to show that the hailstone sequence for the number 27 has 112 elements starting with <code>27, 82, 41, 124</code> and ending with <code>8, 4, 2, 1</code></li>
|
||||
<li>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!)</li>
|
||||
</ol>
|
||||
|
||||
**See also:**
|
||||
|
||||
<ul>
|
||||
<li><a href='https://xkcd.com/710' target='_blank'>xkcd</a> (humourous).</li>
|
||||
</ul>
|
||||
|
||||
# --hints--
|
||||
|
||||
`hailstoneSequence` should be a function.
|
||||
|
||||
```js
|
||||
assert(typeof hailstoneSequence === 'function');
|
||||
```
|
||||
|
||||
`hailstoneSequence()` should return `[[27,82,41,124,8,4,2,1], [351, 77031]]`
|
||||
|
||||
```js
|
||||
assert.deepEqual(hailstoneSequence(), res);
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --after-user-code--
|
||||
|
||||
```js
|
||||
const res = [[27, 82, 41, 124, 8, 4, 2, 1], [351, 77031]];
|
||||
```
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```js
|
||||
function hailstoneSequence() {
|
||||
const res = [];
|
||||
|
||||
|
||||
return res;
|
||||
}
|
||||
```
|
||||
|
||||
# --solutions--
|
||||
|
||||
```js
|
||||
function hailstoneSequence () {
|
||||
const res = [];
|
||||
|
||||
function hailstone(n) {
|
||||
const seq = [n];
|
||||
while (n > 1) {
|
||||
n = n % 2 ? 3 * n + 1 : n / 2;
|
||||
seq.push(n);
|
||||
}
|
||||
return seq;
|
||||
}
|
||||
|
||||
const h = hailstone(27);
|
||||
const hLen = h.length;
|
||||
res.push([...h.slice(0, 4), ...h.slice(hLen - 4, hLen)]);
|
||||
|
||||
let n = 0;
|
||||
let max = 0;
|
||||
for (let i = 100000; --i;) {
|
||||
const seq = hailstone(i);
|
||||
const sLen = seq.length;
|
||||
|
||||
if (sLen > max) {
|
||||
n = i;
|
||||
max = sLen;
|
||||
}
|
||||
}
|
||||
res.push([max, n]);
|
||||
|
||||
return res;
|
||||
}
|
||||
```
|
@ -0,0 +1,129 @@
|
||||
---
|
||||
id: 594810f028c0303b75339ad1
|
||||
title: Happy numbers
|
||||
challengeType: 5
|
||||
forumTopicId: 302280
|
||||
dashedName: happy-numbers
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
A [happy number](https://en.wikipedia.org/wiki/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.
|
||||
|
||||
# --instructions--
|
||||
|
||||
Implement a function that returns true if the number is happy, or false if not.
|
||||
|
||||
# --hints--
|
||||
|
||||
`happy` should be a function.
|
||||
|
||||
```js
|
||||
assert(typeof happy === 'function');
|
||||
```
|
||||
|
||||
`happy(1)` should return a boolean.
|
||||
|
||||
```js
|
||||
assert(typeof happy(1) === 'boolean');
|
||||
```
|
||||
|
||||
`happy(1)` should return true.
|
||||
|
||||
```js
|
||||
assert(happy(1));
|
||||
```
|
||||
|
||||
`happy(2)` should return false.
|
||||
|
||||
```js
|
||||
assert(!happy(2));
|
||||
```
|
||||
|
||||
`happy(7)` should return true.
|
||||
|
||||
```js
|
||||
assert(happy(7));
|
||||
```
|
||||
|
||||
`happy(10)` should return true.
|
||||
|
||||
```js
|
||||
assert(happy(10));
|
||||
```
|
||||
|
||||
`happy(13)` should return true.
|
||||
|
||||
```js
|
||||
assert(happy(13));
|
||||
```
|
||||
|
||||
`happy(19)` should return true.
|
||||
|
||||
```js
|
||||
assert(happy(19));
|
||||
```
|
||||
|
||||
`happy(23)` should return true.
|
||||
|
||||
```js
|
||||
assert(happy(23));
|
||||
```
|
||||
|
||||
`happy(28)` should return true.
|
||||
|
||||
```js
|
||||
assert(happy(28));
|
||||
```
|
||||
|
||||
`happy(31)` should return true.
|
||||
|
||||
```js
|
||||
assert(happy(31));
|
||||
```
|
||||
|
||||
`happy(32)` should return true:.
|
||||
|
||||
```js
|
||||
assert(happy(32));
|
||||
```
|
||||
|
||||
`happy(33)` should return false.
|
||||
|
||||
```js
|
||||
assert(!happy(33));
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```js
|
||||
function happy(number) {
|
||||
|
||||
}
|
||||
```
|
||||
|
||||
# --solutions--
|
||||
|
||||
```js
|
||||
function happy (number) {
|
||||
let m;
|
||||
let digit;
|
||||
const cycle = [];
|
||||
|
||||
while (number !== 1 && cycle[number] !== true) {
|
||||
cycle[number] = true;
|
||||
m = 0;
|
||||
while (number > 0) {
|
||||
digit = number % 10;
|
||||
m += Math.pow(digit, 2);
|
||||
number = (number - digit) / 10;
|
||||
}
|
||||
number = m;
|
||||
}
|
||||
return (number === 1);
|
||||
}
|
||||
```
|
@ -0,0 +1,98 @@
|
||||
---
|
||||
id: 595668ca4cfe1af2fb9818d4
|
||||
title: Harshad or Niven series
|
||||
challengeType: 5
|
||||
forumTopicId: 302281
|
||||
dashedName: 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](https://rosettacode.org/wiki/Harshad_or_Niven_series "Harshad or Niven series") as `42` is divisible by `(4 + 2)` without remainder.
|
||||
|
||||
Assume that the series is defined as the numbers in increasing order.
|
||||
|
||||
# --instructions--
|
||||
|
||||
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.
|
||||
|
||||
# --hints--
|
||||
|
||||
`isHarshadOrNiven` should be a function.
|
||||
|
||||
```js
|
||||
assert(typeof isHarshadOrNiven === 'function');
|
||||
```
|
||||
|
||||
`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}`
|
||||
|
||||
```js
|
||||
assert.deepEqual(isHarshadOrNiven(), res);
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --after-user-code--
|
||||
|
||||
```js
|
||||
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
|
||||
};
|
||||
```
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```js
|
||||
function isHarshadOrNiven() {
|
||||
const res = {
|
||||
firstTwenty: [],
|
||||
firstOver1000: undefined
|
||||
};
|
||||
// Only change code below this line
|
||||
|
||||
return res;
|
||||
}
|
||||
```
|
||||
|
||||
# --solutions--
|
||||
|
||||
```js
|
||||
function isHarshadOrNiven() {
|
||||
const res = {
|
||||
firstTwenty: [],
|
||||
firstOver1000: undefined
|
||||
};
|
||||
|
||||
function isHarshad(n) {
|
||||
let s = 0;
|
||||
const nStr = n.toString();
|
||||
for (let i = 0; i < nStr.length; ++i) {
|
||||
s += parseInt(nStr.charAt(i), 10);
|
||||
}
|
||||
return n % s === 0;
|
||||
}
|
||||
|
||||
let count = 0;
|
||||
const harshads = [];
|
||||
|
||||
for (let n = 1; count < 20; ++n) {
|
||||
if (isHarshad(n)) {
|
||||
count++;
|
||||
harshads.push(n);
|
||||
}
|
||||
}
|
||||
|
||||
res.firstTwenty = harshads;
|
||||
|
||||
let h = 1000;
|
||||
while (!isHarshad(++h));
|
||||
res.firstOver1000 = h;
|
||||
|
||||
return res;
|
||||
}
|
||||
```
|
@ -0,0 +1,105 @@
|
||||
---
|
||||
id: 595671d4d2cdc305f0d5b36f
|
||||
title: Hash from two arrays
|
||||
challengeType: 5
|
||||
forumTopicId: 302283
|
||||
dashedName: hash-from-two-arrays
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
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:**
|
||||
|
||||
<ul>
|
||||
<li><a href='https://rosettacode.org/wiki/Associative arrays/Creation' title='Associative arrays/Creation' target='_blank'>Associative arrays/Creation</a></li>
|
||||
</ul>
|
||||
|
||||
# --hints--
|
||||
|
||||
`arrToObj` should be a function.
|
||||
|
||||
```js
|
||||
assert(typeof arrToObj === 'function');
|
||||
```
|
||||
|
||||
`arrToObj([1, 2, 3, 4, 5], ["a", "b", "c", "d", "e"])` should return `{ 1: "a", 2: "b", 3: "c", 4: "d", 5: "e" }`
|
||||
|
||||
```js
|
||||
assert.deepEqual(arrToObj(...testCases[0]), res[0]);
|
||||
```
|
||||
|
||||
`arrToObj([1, 2, 3, 4, 5], ["a", "b", "c", "d"])` should return `{ 1: "a", 2: "b", 3: "c", 4: "d", 5: undefined }`
|
||||
|
||||
```js
|
||||
assert.deepEqual(arrToObj(...testCases[1]), res[1]);
|
||||
```
|
||||
|
||||
`arrToObj([1, 2, 3], ["a", "b", "c", "d", "e"])` should return `{ 1: "a", 2: "b", 3: "c" }`
|
||||
|
||||
```js
|
||||
assert.deepEqual(arrToObj(...testCases[2]), res[2]);
|
||||
```
|
||||
|
||||
`arrToObj(["a", "b", "c", "d", "e"], [1, 2, 3, 4, 5])` should return `{ "a": 1, "b": 2, "c": 3 , "d": 4, "e": 5 }`
|
||||
|
||||
```js
|
||||
assert.deepEqual(arrToObj(...testCases[3]), res[3]);
|
||||
```
|
||||
|
||||
`arrToObj(["a", "b", "c", "d", "e"], [1, 2, 3, 4])` should return `{ "a": 1, "b": 2, "c": 3 , "d": 4, "e": undefined }`
|
||||
|
||||
```js
|
||||
assert.deepEqual(arrToObj(...testCases[4]), res[4]);
|
||||
```
|
||||
|
||||
`arrToObj(["a", "b", "c"], [1, 2, 3, 4, 5])` should return `{ "a": 1, "b": 2, "c": 3 }`
|
||||
|
||||
```js
|
||||
assert.deepEqual(arrToObj(...testCases[5]), res[5]);
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --after-user-code--
|
||||
|
||||
```js
|
||||
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 }
|
||||
];
|
||||
```
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```js
|
||||
function arrToObj (keys, vals) {
|
||||
|
||||
return true;
|
||||
}
|
||||
```
|
||||
|
||||
# --solutions--
|
||||
|
||||
```js
|
||||
function arrToObj (keys, vals) {
|
||||
return keys.reduce((map, key, index) => {
|
||||
map[key] = vals[index];
|
||||
return map;
|
||||
}, {});
|
||||
}
|
||||
```
|
@ -0,0 +1,237 @@
|
||||
---
|
||||
id: 5956795bc9e2c415eb244de1
|
||||
title: Hash join
|
||||
challengeType: 5
|
||||
forumTopicId: 302284
|
||||
dashedName: hash-join
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
An [inner join](https://en.wikipedia.org/wiki/Join_(SQL)#Inner_join "wp: Join\_(SQL)#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](https://en.wikipedia.org/wiki/Nested loop join "wp: Nested loop join") algorithm, but a more scalable alternative is the [hash join](https://en.wikipedia.org/wiki/hash join "wp: hash join") algorithm.
|
||||
|
||||
The "hash join" algorithm consists of two steps:
|
||||
|
||||
<ol>
|
||||
<li><strong>Hash phase:</strong> Create a <a href='https://en.wikipedia.org/wiki/Multimap' title='wp: Multimap' target='_blank'>multimap</a> from one of the two tables, mapping from each join column value to all the rows that contain it.</li>
|
||||
<ul>
|
||||
<li>The multimap must support hash-based lookup which scales better than a simple linear search, because that's the whole point of this algorithm.</li>
|
||||
<li>Ideally we should create the multimap for the smaller table, thus minimizing its creation time and memory size.</li>
|
||||
</ul>
|
||||
<li><strong>Join phase:</strong> Scan the other table, and find matching rows by looking in the multimap created before.</li>
|
||||
</ol>
|
||||
|
||||
In pseudo-code, the algorithm could be expressed as follows:
|
||||
|
||||
<pre><strong>let</strong> <i>A</i> = the first input table (or ideally, the larger one)
|
||||
<strong>let</strong> <i>B</i> = the second input table (or ideally, the smaller one)
|
||||
<strong>let</strong> <i>j<sub>A</sub></i> = the join column ID of table <i>A</i>
|
||||
<strong>let</strong> <i>j<sub>B</sub></i> = the join column ID of table <i>B</i>
|
||||
<strong>let</strong> <i>M<sub>B</sub></i> = a multimap for mapping from single values to multiple rows of table <i>B</i> (starts out empty)
|
||||
<strong>let</strong> <i>C</i> = the output table (starts out empty)
|
||||
<strong>for each</strong> row <i>b</i> in table <i>B</i>:
|
||||
<strong>place</strong> <i>b</i> in multimap <i>M<sub>B</sub></i> under key <i>b(j<sub>B</sub>)</i>
|
||||
<strong>for each</strong> row <i>a</i> in table <i>A</i>:
|
||||
<strong>for each</strong> row <i>b</i> in multimap <i>M<sub>B</sub></i> under key <i>a(j<sub>A</sub>)</i>:
|
||||
<strong>let</strong> <i>c</i> = the concatenation of row <i>a</i> and row <i>b</i>
|
||||
<strong>place</strong> row <i>c</i> in table <i>C</i>
|
||||
</pre>
|
||||
|
||||
# --instructions--
|
||||
|
||||
Implement the "hash join" algorithm as a function and demonstrate that it passes the test-case listed below. The function should accept two arrays of objects and return an array of combined objects.
|
||||
|
||||
**Input**
|
||||
|
||||
<table>
|
||||
<tr>
|
||||
<td style="padding: 4px; margin: 5px;">
|
||||
<table style="border:none; border-collapse:collapse;">
|
||||
<tr>
|
||||
<td style="border:none"><i>A =</i></td>
|
||||
<td style="border:none">
|
||||
<table>
|
||||
<tr>
|
||||
<th style="padding: 4px; margin: 5px;">Age</th>
|
||||
<th style="padding: 4px; margin: 5px;">Name</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td style="padding: 4px; margin: 5px;">27</td>
|
||||
<td style="padding: 4px; margin: 5px;">Jonah</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td style="padding: 4px; margin: 5px;">18</td>
|
||||
<td style="padding: 4px; margin: 5px;">Alan</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td style="padding: 4px; margin: 5px;">28</td>
|
||||
<td style="padding: 4px; margin: 5px;">Glory</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td style="padding: 4px; margin: 5px;">18</td>
|
||||
<td style="padding: 4px; margin: 5px;">Popeye</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td style="padding: 4px; margin: 5px;">28</td>
|
||||
<td style="padding: 4px; margin: 5px;">Alan</td>
|
||||
</tr>
|
||||
</table>
|
||||
</td>
|
||||
<td style="border:none; padding-left:1.5em;" rowspan="2"></td>
|
||||
<td style="border:none"><i>B =</i></td>
|
||||
<td style="border:none">
|
||||
<table>
|
||||
<tr>
|
||||
<th style="padding: 4px; margin: 5px;">Character</th>
|
||||
<th style="padding: 4px; margin: 5px;">Nemesis</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td style="padding: 4px; margin: 5px;">Jonah</td>
|
||||
<td style="padding: 4px; margin: 5px;">Whales</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td style="padding: 4px; margin: 5px;">Jonah</td>
|
||||
<td style="padding: 4px; margin: 5px;">Spiders</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td style="padding: 4px; margin: 5px;">Alan</td>
|
||||
<td style="padding: 4px; margin: 5px;">Ghosts</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td style="padding: 4px; margin: 5px;">Alan</td>
|
||||
<td style="padding: 4px; margin: 5px;">Zombies</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td style="padding: 4px; margin: 5px;">Glory</td>
|
||||
<td style="padding: 4px; margin: 5px;">Buffy</td>
|
||||
</tr>
|
||||
</table>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td style="border:none">
|
||||
<i>j<sub>A</sub> =</i>
|
||||
</td>
|
||||
<td style="border:none">
|
||||
<i><code>Name</code> (i.e. column 1)</i>
|
||||
</td>
|
||||
<td style="border:none">
|
||||
<i>j<sub>B</sub> =</i>
|
||||
</td>
|
||||
<td style="border:none">
|
||||
<i><code>Character</code> (i.e. column 0)</i>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
**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.
|
||||
|
||||
# --hints--
|
||||
|
||||
`hashJoin` should be a function.
|
||||
|
||||
```js
|
||||
assert(typeof hashJoin === 'function');
|
||||
```
|
||||
|
||||
`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"}]`
|
||||
|
||||
```js
|
||||
assert.deepEqual(hashJoin(hash1, hash2), res);
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --after-user-code--
|
||||
|
||||
```js
|
||||
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 }];
|
||||
```
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```js
|
||||
function hashJoin(hash1, hash2) {
|
||||
|
||||
return [];
|
||||
}
|
||||
```
|
||||
|
||||
# --solutions--
|
||||
|
||||
```js
|
||||
function hashJoin(hash1, hash2) {
|
||||
const hJoin = (tblA, tblB, strJoin) => {
|
||||
const [jA, jB] = strJoin.split('=');
|
||||
const M = tblB.reduce((a, x) => {
|
||||
const id = x[jB];
|
||||
return (
|
||||
a[id] ? a[id].push(x) : (a[id] = [x]),
|
||||
a
|
||||
);
|
||||
}, {});
|
||||
|
||||
return tblA.reduce((a, x) => {
|
||||
const match = M[x[jA]];
|
||||
return match ? (
|
||||
a.concat(match.map(row => dictConcat(x, row)))
|
||||
) : a;
|
||||
}, []);
|
||||
};
|
||||
|
||||
const dictConcat = (dctA, dctB) => {
|
||||
const ok = Object.keys;
|
||||
return ok(dctB).reduce(
|
||||
(a, k) => (a[`B_${k}`] = dctB[k]) && a,
|
||||
ok(dctA).reduce(
|
||||
(a, k) => (a[`A_${k}`] = dctA[k]) && a, {}
|
||||
)
|
||||
);
|
||||
};
|
||||
|
||||
return hJoin(hash1, hash2, 'name=character');
|
||||
}
|
||||
```
|
@ -0,0 +1,155 @@
|
||||
---
|
||||
id: 595b98f8b5a2245e243aa831
|
||||
title: Heronian triangles
|
||||
challengeType: 5
|
||||
forumTopicId: 302285
|
||||
dashedName: heronian-triangles
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
[Hero's formula](https://en.wikipedia.org/wiki/Heron's formula "wp: Heron'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.`
|
||||
|
||||
# --instructions--
|
||||
|
||||
Implement a function based on Hero's formula that returns the first <code>n<sub>th</sub></code> ordered triangles in an array of arrays.
|
||||
|
||||
# --hints--
|
||||
|
||||
`heronianTriangle` should be a function.
|
||||
|
||||
```js
|
||||
assert(typeof heronianTriangle === 'function');
|
||||
```
|
||||
|
||||
`heronianTriangle(10)` 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]]`
|
||||
|
||||
```js
|
||||
assert.deepEqual(heronianTriangle(testCases[0]), res[0]);
|
||||
```
|
||||
|
||||
`heronianTriangle(15)` 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]],`
|
||||
|
||||
```js
|
||||
assert.deepEqual(heronianTriangle(testCases[1]), res[1]);
|
||||
```
|
||||
|
||||
`heronianTriangle(20)` 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]],`
|
||||
|
||||
```js
|
||||
assert.deepEqual(heronianTriangle(testCases[2]), res[2]);
|
||||
```
|
||||
|
||||
`heronianTriangle(25)` 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]]`
|
||||
|
||||
```js
|
||||
assert.deepEqual(heronianTriangle(testCases[3]), res[3]);
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --after-user-code--
|
||||
|
||||
```js
|
||||
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]]
|
||||
];
|
||||
```
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```js
|
||||
function heronianTriangle(n) {
|
||||
|
||||
|
||||
return [];
|
||||
}
|
||||
```
|
||||
|
||||
# --solutions--
|
||||
|
||||
```js
|
||||
function heronianTriangle(n) {
|
||||
const list = [];
|
||||
const result = [];
|
||||
|
||||
let j = 0;
|
||||
for (let c = 1; c <= 200; c++) {
|
||||
for (let b = 1; b <= c; b++) {
|
||||
for (let a = 1; a <= b; a++) {
|
||||
if (gcd(gcd(a, b), c) === 1 && isHeron(heronArea(a, b, c))) {
|
||||
list[j++] = new Array(a, b, c, heronArea(a, b, c));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
sort(list);
|
||||
|
||||
for (let i = 0; i < n; i++) {
|
||||
result[i] = [list[i][0], list[i][1], list[i][2]];
|
||||
}
|
||||
|
||||
return result;
|
||||
|
||||
function heronArea(a, b, c) {
|
||||
const s = (a + b + c) / 2;
|
||||
return Math.sqrt(s * (s - a) * (s - b) * (s - c));
|
||||
}
|
||||
|
||||
function isHeron(h) { return h % 1 === 0 && h > 0; }
|
||||
|
||||
function gcd(a, b) {
|
||||
let leftover = 1;
|
||||
let dividend = a > b ? a : b;
|
||||
let divisor = a > b ? b : a;
|
||||
while (leftover !== 0) {
|
||||
leftover = dividend % divisor;
|
||||
if (leftover > 0) {
|
||||
dividend = divisor;
|
||||
divisor = leftover;
|
||||
}
|
||||
}
|
||||
return divisor;
|
||||
}
|
||||
|
||||
function sort(arg) {
|
||||
let swapped = true;
|
||||
let temp = [];
|
||||
while (swapped) {
|
||||
swapped = false;
|
||||
for (let i = 1; i < arg.length; i++) {
|
||||
if (arg[i][4] < arg[i - 1][4] || arg[i][4] === arg[i - 1][4] && arg[i][3] < arg[i - 1][3]) {
|
||||
temp = arg[i];
|
||||
arg[i] = arg[i - 1];
|
||||
arg[i - 1] = temp;
|
||||
swapped = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
@ -0,0 +1,166 @@
|
||||
---
|
||||
id: 59622f89e4e137560018a40e
|
||||
title: Hofstadter Figure-Figure sequences
|
||||
challengeType: 5
|
||||
forumTopicId: 302286
|
||||
dashedName: 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:
|
||||
|
||||
<pre>1, 3, 7, 12, 18, ...</pre>
|
||||
|
||||
Sequence $S$ starts:
|
||||
|
||||
<pre>2, 4, 5, 6, 8, ...</pre>
|
||||
|
||||
# --instructions--
|
||||
|
||||
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.
|
||||
|
||||
**References**
|
||||
|
||||
<ul>
|
||||
<li>
|
||||
Sloane's <a href='https://oeis.org/A005228' target='_blank'>A005228</a> and <a href='https://oeis.org/A030124' target='_blank'>A030124</a>.
|
||||
</li>
|
||||
<li>
|
||||
Wikipedia: <a href='https://en.wikipedia.org/wiki/Hofstadter_sequence#Hofstadter_Figure-Figure_sequences' title='wp: Hofstadter_sequence#Hofstadter_Figure-Figure_sequences' target='_blank'>Hofstadter Figure-Figure sequences</a>.
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
# --hints--
|
||||
|
||||
`ffr` should be a function.
|
||||
|
||||
```js
|
||||
assert(typeof ffr === 'function');
|
||||
```
|
||||
|
||||
`ffs` should be a function.
|
||||
|
||||
```js
|
||||
assert(typeof ffs === 'function');
|
||||
```
|
||||
|
||||
`ffr` should return integer.
|
||||
|
||||
```js
|
||||
assert(Number.isInteger(ffr(1)));
|
||||
```
|
||||
|
||||
`ffs` should return integer.
|
||||
|
||||
```js
|
||||
assert(Number.isInteger(ffs(1)));
|
||||
```
|
||||
|
||||
`ffr(10)` should return `69`
|
||||
|
||||
```js
|
||||
assert.equal(ffr(ffrParamRes[0][0]), ffrParamRes[0][1]);
|
||||
```
|
||||
|
||||
`ffr(50)` should return `1509`
|
||||
|
||||
```js
|
||||
assert.equal(ffr(ffrParamRes[1][0]), ffrParamRes[1][1]);
|
||||
```
|
||||
|
||||
`ffr(100)` should return `5764`
|
||||
|
||||
```js
|
||||
assert.equal(ffr(ffrParamRes[2][0]), ffrParamRes[2][1]);
|
||||
```
|
||||
|
||||
`ffr(1000)` should return `526334`
|
||||
|
||||
```js
|
||||
assert.equal(ffr(ffrParamRes[3][0]), ffrParamRes[3][1]);
|
||||
```
|
||||
|
||||
`ffs(10)` should return `14`
|
||||
|
||||
```js
|
||||
assert.equal(ffs(ffsParamRes[0][0]), ffsParamRes[0][1]);
|
||||
```
|
||||
|
||||
`ffs(50)` should return `59`
|
||||
|
||||
```js
|
||||
assert.equal(ffs(ffsParamRes[1][0]), ffsParamRes[1][1]);
|
||||
```
|
||||
|
||||
`ffs(100)` should return `112`
|
||||
|
||||
```js
|
||||
assert.equal(ffs(ffsParamRes[2][0]), ffsParamRes[2][1]);
|
||||
```
|
||||
|
||||
`ffs(1000)` should return `1041`
|
||||
|
||||
```js
|
||||
assert.equal(ffs(ffsParamRes[3][0]), ffsParamRes[3][1]);
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --after-user-code--
|
||||
|
||||
```js
|
||||
const ffrParamRes = [[10, 69], [50, 1509], [100, 5764], [1000, 526334]];
|
||||
const ffsParamRes = [[10, 14], [50, 59], [100, 112], [1000, 1041]];
|
||||
```
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```js
|
||||
function ffr(n) {
|
||||
return n;
|
||||
}
|
||||
|
||||
function ffs(n) {
|
||||
return n;
|
||||
}
|
||||
```
|
||||
|
||||
# --solutions--
|
||||
|
||||
```js
|
||||
const R = [null, 1];
|
||||
const S = [null, 2];
|
||||
|
||||
function extendSequences (n) {
|
||||
let current = Math.max(R[R.length - 1], S[S.length - 1]);
|
||||
let i;
|
||||
while (R.length <= n || S.length <= n) {
|
||||
i = Math.min(R.length, S.length) - 1;
|
||||
current += 1;
|
||||
if (current === R[i] + S[i]) {
|
||||
R.push(current);
|
||||
} else {
|
||||
S.push(current);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function ffr (n) {
|
||||
extendSequences(n);
|
||||
return R[n];
|
||||
}
|
||||
|
||||
function ffs (n) {
|
||||
extendSequences(n);
|
||||
return S[n];
|
||||
}
|
||||
```
|
@ -0,0 +1,92 @@
|
||||
---
|
||||
id: 59637c4d89f6786115efd814
|
||||
title: Hofstadter Q sequence
|
||||
challengeType: 5
|
||||
forumTopicId: 302287
|
||||
dashedName: hofstadter-q-sequence
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
The [Hofstadter Q sequence](https://en.wikipedia.org/wiki/Hofstadter_sequence#Hofstadter_Q_sequence "wp: Hofstadter_sequence#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](https://rosettacode.org/wiki/Fibonacci sequence "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.
|
||||
|
||||
# --instructions--
|
||||
|
||||
Implement the Hofstadter Q Sequence equation as a function. The function should accept number, `n`, and return an integer.
|
||||
|
||||
# --hints--
|
||||
|
||||
`hofstadterQ` should be a function.
|
||||
|
||||
```js
|
||||
assert(typeof hofstadterQ === 'function');
|
||||
```
|
||||
|
||||
`hofstadterQ()` should return `integer`
|
||||
|
||||
```js
|
||||
assert(Number.isInteger(hofstadterQ(1000)));
|
||||
```
|
||||
|
||||
`hofstadterQ(1000)` should return `502`
|
||||
|
||||
```js
|
||||
assert.equal(hofstadterQ(testCase[0]), res[0]);
|
||||
```
|
||||
|
||||
`hofstadterQ(1500)` should return `755`
|
||||
|
||||
```js
|
||||
assert.equal(hofstadterQ(testCase[1]), res[1]);
|
||||
```
|
||||
|
||||
`hofstadterQ(2000)` should return `1005`
|
||||
|
||||
```js
|
||||
assert.equal(hofstadterQ(testCase[2]), res[2]);
|
||||
```
|
||||
|
||||
`hofstadterQ(2500)` should return `1261`
|
||||
|
||||
```js
|
||||
assert.equal(hofstadterQ(testCase[3]), res[3]);
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --after-user-code--
|
||||
|
||||
```js
|
||||
const testCase = [1000, 1500, 2000, 2500];
|
||||
const res = [502, 755, 1005, 1261];
|
||||
```
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```js
|
||||
function hofstadterQ(n) {
|
||||
|
||||
return n;
|
||||
}
|
||||
```
|
||||
|
||||
# --solutions--
|
||||
|
||||
```js
|
||||
function hofstadterQ (n) {
|
||||
const memo = [1, 1, 1];
|
||||
const Q = function (i) {
|
||||
let result = memo[i];
|
||||
if (typeof result !== 'number') {
|
||||
result = Q(i - Q(i - 1)) + Q(i - Q(i - 2));
|
||||
memo[i] = result;
|
||||
}
|
||||
return result;
|
||||
};
|
||||
return Q(n);
|
||||
}
|
||||
```
|
@ -0,0 +1,101 @@
|
||||
---
|
||||
id: 5a23c84252665b21eecc7eb0
|
||||
title: I before E except after C
|
||||
challengeType: 5
|
||||
forumTopicId: 302288
|
||||
dashedName: i-before-e-except-after-c
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
The phrase ["I before E, except after C"](https://en.wikipedia.org/wiki/I before E except after C) is a widely known mnemonic which is supposed to help when spelling English words.
|
||||
|
||||
Using the words provided, check if the two sub-clauses of the phrase are plausible individually:
|
||||
|
||||
<ol>
|
||||
<li>
|
||||
<i>"I before E when not preceded by C".</i>
|
||||
</li>
|
||||
<li>
|
||||
<i>"E before I when preceded by C".</i>
|
||||
</li>
|
||||
</ol>
|
||||
|
||||
If both sub-phrases are plausible then the original phrase can be said to be plausible.
|
||||
|
||||
# --instructions--
|
||||
|
||||
Write a function that accepts a word and check if the word follows this rule. The function should return true if the word follows the rule and false if it does not.
|
||||
|
||||
# --hints--
|
||||
|
||||
`IBeforeExceptC` should be a function.
|
||||
|
||||
```js
|
||||
assert(typeof IBeforeExceptC == 'function');
|
||||
```
|
||||
|
||||
`IBeforeExceptC("receive")` should return a boolean.
|
||||
|
||||
```js
|
||||
assert(typeof IBeforeExceptC('receive') == 'boolean');
|
||||
```
|
||||
|
||||
`IBeforeExceptC("receive")` should return `true`.
|
||||
|
||||
```js
|
||||
assert.equal(IBeforeExceptC('receive'), true);
|
||||
```
|
||||
|
||||
`IBeforeExceptC("science")` should return `false`.
|
||||
|
||||
```js
|
||||
assert.equal(IBeforeExceptC('science'), false);
|
||||
```
|
||||
|
||||
`IBeforeExceptC("imperceivable")` should return `true`.
|
||||
|
||||
```js
|
||||
assert.equal(IBeforeExceptC('imperceivable'), true);
|
||||
```
|
||||
|
||||
`IBeforeExceptC("inconceivable")` should return `true`.
|
||||
|
||||
```js
|
||||
assert.equal(IBeforeExceptC('inconceivable'), true);
|
||||
```
|
||||
|
||||
`IBeforeExceptC("insufficient")` should return `false`.
|
||||
|
||||
```js
|
||||
assert.equal(IBeforeExceptC('insufficient'), false);
|
||||
```
|
||||
|
||||
`IBeforeExceptC("omniscient")` should return `false`.
|
||||
|
||||
```js
|
||||
assert.equal(IBeforeExceptC('omniscient'), false);
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```js
|
||||
function IBeforeExceptC(word) {
|
||||
|
||||
}
|
||||
```
|
||||
|
||||
# --solutions--
|
||||
|
||||
```js
|
||||
function IBeforeExceptC(word)
|
||||
{
|
||||
if(word.indexOf("c")==-1 && word.indexOf("ie")!=-1)
|
||||
return true;
|
||||
else if(word.indexOf("cei")!=-1)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
```
|
@ -0,0 +1,104 @@
|
||||
---
|
||||
id: 5a23c84252665b21eecc7eaf
|
||||
title: IBAN
|
||||
challengeType: 5
|
||||
forumTopicId: 302289
|
||||
dashedName: iban
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
The [International Bank Account Number (IBAN)](https://en.wikipedia.org/wiki/International_Bank_Account_Number) is an internationally agreed means of identifying bank accounts across national borders with a reduced risk of propagating [transcription errors](https://en.wikipedia.org/wiki/Transcription_error).
|
||||
|
||||
The IBAN consists of up to 34 alphanumeric characters:
|
||||
|
||||
<ul>
|
||||
<li>first the two-letter ISO 3166-1 alpha-2 country code</li>
|
||||
<li>then two check digits, and</li>
|
||||
<li>finally a country-specific Basic Bank Account Number (BBAN).</li>
|
||||
</ul>
|
||||
|
||||
The check digits enable a sanity check of the bank account number to confirm its integrity even before submitting a transaction.
|
||||
|
||||
# --instructions--
|
||||
|
||||
Write a function that takes IBAN string as parameter. If it is valid return true. Otherwise, return false.
|
||||
|
||||
# --hints--
|
||||
|
||||
`isValid` should be a function.
|
||||
|
||||
```js
|
||||
assert(typeof isValid == 'function');
|
||||
```
|
||||
|
||||
`isValid("GB82 WEST 1234 5698 7654 32")` should return a boolean.
|
||||
|
||||
```js
|
||||
assert(typeof isValid('GB82 WEST 1234 5698 7654 32') == 'boolean');
|
||||
```
|
||||
|
||||
`isValid("GB82 WEST 1234 5698 7654 32")` should return `true`.
|
||||
|
||||
```js
|
||||
assert.equal(isValid('GB82 WEST 1234 5698 7654 32'), true);
|
||||
```
|
||||
|
||||
`isValid("GB82 WEST 1.34 5698 7654 32")` should return `false`.
|
||||
|
||||
```js
|
||||
assert.equal(isValid('GB82 WEST 1.34 5698 7654 32'), false);
|
||||
```
|
||||
|
||||
`isValid("GB82 WEST 1234 5698 7654 325")` should return `false`.
|
||||
|
||||
```js
|
||||
assert.equal(isValid('GB82 WEST 1234 5698 7654 325'), false);
|
||||
```
|
||||
|
||||
`isValid("GB82 TEST 1234 5698 7654 32")` should return `false`.
|
||||
|
||||
```js
|
||||
assert.equal(isValid('GB82 TEST 1234 5698 7654 32'), false);
|
||||
```
|
||||
|
||||
`isValid("SA03 8000 0000 6080 1016 7519")` should return `true`.
|
||||
|
||||
```js
|
||||
assert.equal(isValid('SA03 8000 0000 6080 1016 7519'), true);
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```js
|
||||
function isValid(iban) {
|
||||
|
||||
}
|
||||
```
|
||||
|
||||
# --solutions--
|
||||
|
||||
```js
|
||||
function isValid(iban) {
|
||||
var ibanLen = {
|
||||
NO:15, BE:16, DK:18, FI:18, FO:18, GL:18, NL:18, MK:19,
|
||||
SI:19, AT:20, BA:20, EE:20, KZ:20, LT:20, LU:20, CR:21,
|
||||
CH:21, HR:21, LI:21, LV:21, BG:22, BH:22, DE:22, GB:22,
|
||||
GE:22, IE:22, ME:22, RS:22, AE:23, GI:23, IL:23, AD:24,
|
||||
CZ:24, ES:24, MD:24, PK:24, RO:24, SA:24, SE:24, SK:24,
|
||||
VG:24, TN:24, PT:25, IS:26, TR:26, FR:27, GR:27, IT:27,
|
||||
MC:27, MR:27, SM:27, AL:28, AZ:28, CY:28, DO:28, GT:28,
|
||||
HU:28, LB:28, PL:28, BR:29, PS:29, KW:30, MU:30, MT:31
|
||||
}
|
||||
iban = __helpers.removeWhiteSpace(iban)
|
||||
if (!iban.match(/^[\dA-Z]+$/)) return false
|
||||
var len = iban.length
|
||||
if (len != ibanLen[iban.substr(0,2)]) return false
|
||||
iban = iban.substr(4) + iban.substr(0,4)
|
||||
for (var s='', i=0; i<len; i+=1) s+=parseInt(iban.charAt(i),36)
|
||||
for (var m=s.substr(0,15)%97, s=s.substr(15); s; s=s.substr(13)) m=(m+s.substr(0,13))%97
|
||||
return m == 1
|
||||
}
|
||||
```
|
@ -0,0 +1,88 @@
|
||||
---
|
||||
id: 5a23c84252665b21eecc7eb1
|
||||
title: Identity matrix
|
||||
challengeType: 5
|
||||
forumTopicId: 302290
|
||||
dashedName: identity-matrix
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
An *identity matrix* is a square matrix of size \\( n \\times n \\), where the diagonal elements are all `1`s (ones), and all the other elements are all `0`s (zeroes).
|
||||
|
||||
<ul>
|
||||
<li style='list-style: none;'>\(\displaystyle I_{n}=\begin{bmatrix} 1 & 0 & 0 \cr 0 & 1 & 0 \cr 0 & 0 & 1 \cr \end{bmatrix}\)</li>
|
||||
</ul>
|
||||
|
||||
# --instructions--
|
||||
|
||||
Write a function that takes a number `n` as a parameter and returns the identity matrix of order \\( n \\times n \\).
|
||||
|
||||
# --hints--
|
||||
|
||||
`idMatrix` should be a function.
|
||||
|
||||
```js
|
||||
assert(typeof idMatrix == 'function');
|
||||
```
|
||||
|
||||
`idMatrix(1)` should return an array.
|
||||
|
||||
```js
|
||||
assert(Array.isArray(idMatrix(1)));
|
||||
```
|
||||
|
||||
`idMatrix(1)` should return `[ [ 1 ] ]`.
|
||||
|
||||
```js
|
||||
assert.deepEqual(idMatrix(1), results[0]);
|
||||
```
|
||||
|
||||
`idMatrix(2)` should return `[ [ 1, 0 ], [ 0, 1 ] ]`.
|
||||
|
||||
```js
|
||||
assert.deepEqual(idMatrix(2), results[1]);
|
||||
```
|
||||
|
||||
`idMatrix(3)` should return `[ [ 1, 0, 0 ], [ 0, 1, 0 ], [ 0, 0, 1 ] ]`.
|
||||
|
||||
```js
|
||||
assert.deepEqual(idMatrix(3), results[2]);
|
||||
```
|
||||
|
||||
`idMatrix(4)` should return `[ [ 1, 0, 0, 0 ], [ 0, 1, 0, 0 ], [ 0, 0, 1, 0 ], [ 0, 0, 0, 1 ] ]`.
|
||||
|
||||
```js
|
||||
assert.deepEqual(idMatrix(4), results[3]);
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --after-user-code--
|
||||
|
||||
```js
|
||||
let results=[[ [ 1 ] ],
|
||||
[ [ 1, 0 ], [ 0, 1 ] ],
|
||||
[ [ 1, 0, 0 ], [ 0, 1, 0 ], [ 0, 0, 1 ] ],
|
||||
[ [ 1, 0, 0, 0 ], [ 0, 1, 0, 0 ], [ 0, 0, 1, 0 ], [ 0, 0, 0, 1 ] ]]
|
||||
```
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```js
|
||||
function idMatrix(n) {
|
||||
|
||||
}
|
||||
```
|
||||
|
||||
# --solutions--
|
||||
|
||||
```js
|
||||
function idMatrix(n) {
|
||||
return Array.apply(null, new Array(n)).map(function (x, i, xs) {
|
||||
return xs.map(function (_, k) {
|
||||
return i === k ? 1 : 0;
|
||||
})
|
||||
});
|
||||
}
|
||||
```
|
@ -0,0 +1,96 @@
|
||||
---
|
||||
id: 5a23c84252665b21eecc7ec1
|
||||
title: Iterated digits squaring
|
||||
challengeType: 5
|
||||
forumTopicId: 302291
|
||||
dashedName: iterated-digits-squaring
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
If you add the square of the digits of a Natural number (an integer bigger than zero), you always end with either 1 or 89:
|
||||
|
||||
<pre>15 -> 26 -> 40 -> 16 -> 37 -> 58 -> 89
|
||||
7 -> 49 -> 97 -> 130 -> 10 -> 1
|
||||
</pre>
|
||||
|
||||
# --instructions--
|
||||
|
||||
Write a function that takes a number as a parameter and returns 1 or 89 after performing the mentioned process.
|
||||
|
||||
# --hints--
|
||||
|
||||
`iteratedSquare` should be a function.
|
||||
|
||||
```js
|
||||
assert(typeof iteratedSquare == 'function');
|
||||
```
|
||||
|
||||
`iteratedSquare(4)` should return a number.
|
||||
|
||||
```js
|
||||
assert(typeof iteratedSquare(4) == 'number');
|
||||
```
|
||||
|
||||
`iteratedSquare(4)` should return `89`.
|
||||
|
||||
```js
|
||||
assert.equal(iteratedSquare(4), 89);
|
||||
```
|
||||
|
||||
`iteratedSquare(7)` should return `1`.
|
||||
|
||||
```js
|
||||
assert.equal(iteratedSquare(7), 1);
|
||||
```
|
||||
|
||||
`iteratedSquare(15)` should return `89`.
|
||||
|
||||
```js
|
||||
assert.equal(iteratedSquare(15), 89);
|
||||
```
|
||||
|
||||
`iteratedSquare(20)` should return `89`.
|
||||
|
||||
```js
|
||||
assert.equal(iteratedSquare(20), 89);
|
||||
```
|
||||
|
||||
`iteratedSquare(70)` should return `1`.
|
||||
|
||||
```js
|
||||
assert.equal(iteratedSquare(70), 1);
|
||||
```
|
||||
|
||||
`iteratedSquare(100)` should return `1`.
|
||||
|
||||
```js
|
||||
assert.equal(iteratedSquare(100), 1);
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```js
|
||||
function iteratedSquare(n) {
|
||||
|
||||
}
|
||||
```
|
||||
|
||||
# --solutions--
|
||||
|
||||
```js
|
||||
function iteratedSquare(n) {
|
||||
var total;
|
||||
while (n != 89 && n != 1) {
|
||||
total = 0;
|
||||
while (n > 0) {
|
||||
total += Math.pow(n % 10, 2);
|
||||
n = Math.floor(n/10);
|
||||
}
|
||||
n = total;
|
||||
}
|
||||
return n;
|
||||
}
|
||||
```
|
@ -0,0 +1,146 @@
|
||||
---
|
||||
id: 5a23c84252665b21eecc7ec2
|
||||
title: Jaro distance
|
||||
challengeType: 5
|
||||
forumTopicId: 302292
|
||||
dashedName: jaro-distance
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
The Jaro distance is a measure of similarity between two strings. The higher the Jaro distance for two strings is, the more similar the strings are. The score is normalized such that `0` equates to no similarity and `1` is an exact match.
|
||||
|
||||
**Definition**
|
||||
|
||||
The Jaro distance \\( d_j \\) of two given strings \\(s_1\\) and \\(s_2\\) is
|
||||
|
||||
\\begin{align}d_j = \\begin{cases}0& & \\text{if }m=0 \\\\\\\\{\\frac {1}{3}}\\left({\\frac {m}{|s\_{1}|}}+{\\frac {m}{|s\_{2}|}}+{\\frac {m-t}{m}}\\right)& & \\text{otherwise}\\end{cases}\\end{align}
|
||||
|
||||
Where:
|
||||
|
||||
<ul>
|
||||
<li>\(m\) is the number of <i>matching characters</i>;</li>
|
||||
<li> \(t\) is half the number of <i>transpositions</i>.</li>
|
||||
</ul>
|
||||
|
||||
Two characters from \\(s_1\\) and \\(s_2\\) respectively, are considered *matching* only if they are the same and not farther than \\(\\left\\lfloor\\frac{\\max(|s_1|,|s_2|)}{2}\\right\\rfloor-1\\).
|
||||
|
||||
Each character of \\(s_1\\) is compared with all its matching characters in \\(s_2\\) . The number of matching (but different sequence order) characters divided by 2 defines the number of *transpositions*.
|
||||
|
||||
**Example**
|
||||
|
||||
Given the strings \\(s_1\\) *DWAYNE* and \\(s_2\\) *DUANE* we find:
|
||||
|
||||
<ul>
|
||||
<li>\(m = 4\)</li>
|
||||
<li>\(|s_1| = 6\)</li>
|
||||
<li>\(|s_2| = 5\)</li>
|
||||
<li>\(t = 0\)</li>
|
||||
</ul>
|
||||
|
||||
We find a Jaro score of: \\(d_j = \\frac{1}{3}\\left(\\frac{4}{6} + \\frac{4}{5} + \\frac{4-0}{4}\\right) = 0.822\\).
|
||||
|
||||
# --instructions--
|
||||
|
||||
Write a function a that takes two strings as parameters and returns the associated Jaro distance.
|
||||
|
||||
# --hints--
|
||||
|
||||
`jaro` should be a function.
|
||||
|
||||
```js
|
||||
assert(typeof jaro == 'function');
|
||||
```
|
||||
|
||||
`jaro("MARTHA", "MARHTA")` should return a number.
|
||||
|
||||
```js
|
||||
assert(typeof jaro('MARTHA', 'MARHTA') == 'number');
|
||||
```
|
||||
|
||||
`jaro("MARTHA", "MARHTA")` should return `0.9444444444444445`.
|
||||
|
||||
```js
|
||||
assert.equal(jaro('MARTHA', 'MARHTA'), 0.9444444444444445);
|
||||
```
|
||||
|
||||
`jaro("DIXON", "DICKSONX")` should return `0.7666666666666666`.
|
||||
|
||||
```js
|
||||
assert.equal(jaro('DIXON', 'DICKSONX'), 0.7666666666666666);
|
||||
```
|
||||
|
||||
`jaro("JELLYFISH", "SMELLYFISH")` should return `0.8962962962962964`.
|
||||
|
||||
```js
|
||||
assert.equal(jaro('JELLYFISH', 'SMELLYFISH'), 0.8962962962962964);
|
||||
```
|
||||
|
||||
`jaro("HELLOS", "CHELLO")` should return `0.888888888888889`.
|
||||
|
||||
```js
|
||||
assert.equal(jaro('HELLOS', 'CHELLO'), 0.888888888888889);
|
||||
```
|
||||
|
||||
`jaro("ABCD", "BCDA")` should return `0.8333333333333334`.
|
||||
|
||||
```js
|
||||
assert.equal(jaro('ABCD', 'BCDA'), 0.8333333333333334);
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```js
|
||||
function jaro(s, t) {
|
||||
|
||||
}
|
||||
```
|
||||
|
||||
# --solutions--
|
||||
|
||||
```js
|
||||
function jaro(s, t) {
|
||||
var s_len = s.length;
|
||||
var t_len = t.length;
|
||||
|
||||
if (s_len == 0 && t_len == 0) return 1;
|
||||
|
||||
var match_distance = Math.max(s_len, t_len) / 2 - 1;
|
||||
|
||||
var s_matches = new Array(s_len);
|
||||
var t_matches = new Array(t_len);
|
||||
|
||||
var matches = 0;
|
||||
var transpositions = 0;
|
||||
|
||||
for (var i = 0; i < s_len; i++) {
|
||||
var start = Math.max(0, i - match_distance);
|
||||
var end = Math.min(i + match_distance + 1, t_len);
|
||||
|
||||
for (var j = start; j < end; j++) {
|
||||
if (t_matches[j]) continue;
|
||||
if (s.charAt(i) != t.charAt(j)) continue;
|
||||
s_matches[i] = true;
|
||||
t_matches[j] = true;
|
||||
matches++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (matches == 0) return 0;
|
||||
|
||||
var k = 0;
|
||||
for (var i = 0; i < s_len; i++) {
|
||||
if (!s_matches[i]) continue;
|
||||
while (!t_matches[k]) k++;
|
||||
if (s.charAt(i) != t.charAt(k)) transpositions++;
|
||||
k++;
|
||||
}
|
||||
|
||||
return ((matches / s_len) +
|
||||
(matches / t_len) +
|
||||
((matches - transpositions / 2.0) / matches)) / 3.0;
|
||||
}
|
||||
```
|
@ -0,0 +1,90 @@
|
||||
---
|
||||
id: 5a23c84252665b21eecc7ec4
|
||||
title: JortSort
|
||||
challengeType: 5
|
||||
forumTopicId: 302293
|
||||
dashedName: jortsort
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
jortSort is a sorting toolset that makes the user do the work and guarantees efficiency because you don't have to sort ever again. It was originally presented by Jenn "Moneydollars" Schiffer at the prestigious [JSConf](https://www.youtube.com/watch?v=pj4U_W0OFoE).
|
||||
|
||||
jortSort should be a function that takes a single array of comparable objects as its argument. It then sorts the array in ascending order and compares the sorted array to the originally provided array. If the arrays match (i.e. the original array was already sorted), the function returns true. If the arrays do not match (i.e. the original array was not sorted), the function returns false.
|
||||
|
||||
# --hints--
|
||||
|
||||
`jortsort` should be a function.
|
||||
|
||||
```js
|
||||
assert(typeof jortsort == 'function');
|
||||
```
|
||||
|
||||
`jortsort([1,2,3,4,5])` should return a boolean.
|
||||
|
||||
```js
|
||||
assert(typeof jortsort([1, 2, 3, 4, 5]) == 'boolean');
|
||||
```
|
||||
|
||||
`jortsort([1,2,3,4,5])` should return `true`.
|
||||
|
||||
```js
|
||||
assert.equal(jortsort([1, 2, 3, 4, 5]), true);
|
||||
```
|
||||
|
||||
`jortsort([1,2,13,4,5])` should return `false`.
|
||||
|
||||
```js
|
||||
assert.equal(jortsort([1, 2, 13, 4, 5]), false);
|
||||
```
|
||||
|
||||
`jortsort([12,4,51,2,4])` should return `false`.
|
||||
|
||||
```js
|
||||
assert.equal(jortsort([12, 4, 51, 2, 4]), false);
|
||||
```
|
||||
|
||||
`jortsort([1,2])` should return `true`.
|
||||
|
||||
```js
|
||||
assert.equal(jortsort([1, 2]), true);
|
||||
```
|
||||
|
||||
`jortsort([5,4,3,2,1])` should return `false`.
|
||||
|
||||
```js
|
||||
assert.equal(jortsort([5, 4, 3, 2, 1]), false);
|
||||
```
|
||||
|
||||
`jortsort([1,1,1,1,1])` should return `true`.
|
||||
|
||||
```js
|
||||
assert.equal(jortsort([1, 1, 1, 1, 1]), true);
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```js
|
||||
function jortsort(array) {
|
||||
|
||||
}
|
||||
```
|
||||
|
||||
# --solutions--
|
||||
|
||||
```js
|
||||
function jortsort(array) {
|
||||
// sort the array
|
||||
var originalArray = array.slice(0);
|
||||
array.sort( function(a,b){return a - b} );
|
||||
|
||||
// compare to see if it was originally sorted
|
||||
for (var i = 0; i < originalArray.length; ++i) {
|
||||
if (originalArray[i] !== array[i]) return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
};
|
||||
```
|
@ -0,0 +1,121 @@
|
||||
---
|
||||
id: 5a23c84252665b21eecc7ec5
|
||||
title: Josephus problem
|
||||
challengeType: 5
|
||||
forumTopicId: 302294
|
||||
dashedName: josephus-problem
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
[Josephus problem](https://en.wikipedia.org/wiki/Josephus problem) is a math puzzle with a grim description: $n$ prisoners are standing on a circle, sequentially numbered from $0$ to $n-1$.
|
||||
|
||||
An executioner walks along the circle, starting from prisoner $0$, removing every $k$-th prisoner and killing him.
|
||||
|
||||
As the process goes on, the circle becomes smaller and smaller, until only one prisoner remains, who is then freed.
|
||||
|
||||
For example, if there are $n=5$ prisoners and $k=2$, the order the prisoners are killed in (let's call it the "killing sequence") will be 1, 3, 0, and 4, and the survivor will be #2.
|
||||
|
||||
Given any $n, k > 0$, find out which prisoner will be the final survivor.
|
||||
|
||||
In one such incident, there were 41 prisoners and every 3<sup>rd</sup> prisoner was being killed ($k=3$).
|
||||
|
||||
Among them was a clever chap name Josephus who worked out the problem, stood at the surviving position, and lived on to tell the tale.
|
||||
|
||||
Which number was he?
|
||||
|
||||
# --instructions--
|
||||
|
||||
Write a function that takes the initial number of prisoners and 'k' as parameter and returns the number of the prisoner that survives.
|
||||
|
||||
# --hints--
|
||||
|
||||
`josephus` should be a function.
|
||||
|
||||
```js
|
||||
assert(typeof josephus == 'function');
|
||||
```
|
||||
|
||||
`josephus(30,3)` should return a number.
|
||||
|
||||
```js
|
||||
assert(typeof josephus(30, 3) == 'number');
|
||||
```
|
||||
|
||||
`josephus(30,3)` should return `29`.
|
||||
|
||||
```js
|
||||
assert.equal(josephus(30, 3), 29);
|
||||
```
|
||||
|
||||
`josephus(30,5)` should return `3`.
|
||||
|
||||
```js
|
||||
assert.equal(josephus(30, 5), 3);
|
||||
```
|
||||
|
||||
`josephus(20,2)` should return `9`.
|
||||
|
||||
```js
|
||||
assert.equal(josephus(20, 2), 9);
|
||||
```
|
||||
|
||||
`josephus(17,6)` should return `2`.
|
||||
|
||||
```js
|
||||
assert.equal(josephus(17, 6), 2);
|
||||
```
|
||||
|
||||
`josephus(29,4)` should return `2`.
|
||||
|
||||
```js
|
||||
assert.equal(josephus(29, 4), 2);
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```js
|
||||
function josephus(init, kill) {
|
||||
|
||||
}
|
||||
```
|
||||
|
||||
# --solutions--
|
||||
|
||||
```js
|
||||
function josephus(init, kill) {
|
||||
var Josephus = {
|
||||
init: function(n) {
|
||||
this.head = {};
|
||||
var current = this.head;
|
||||
for (var i = 0; i < n - 1; i++) {
|
||||
current.label = i + 1;
|
||||
current.next = {
|
||||
prev: current
|
||||
};
|
||||
current = current.next;
|
||||
}
|
||||
current.label = n;
|
||||
current.next = this.head;
|
||||
this.head.prev = current;
|
||||
return this;
|
||||
},
|
||||
kill: function(spacing) {
|
||||
var current = this.head;
|
||||
while (current.next !== current) {
|
||||
for (var i = 0; i < spacing - 1; i++) {
|
||||
current = current.next;
|
||||
}
|
||||
current.prev.next = current.next;
|
||||
current.next.prev = current.prev;
|
||||
current = current.next;
|
||||
}
|
||||
return current.label;
|
||||
}
|
||||
}
|
||||
|
||||
return Josephus.init(init).kill(kill)
|
||||
}
|
||||
```
|
@ -0,0 +1,469 @@
|
||||
---
|
||||
id: 5a23c84252665b21eecc7ecb
|
||||
title: K-d tree
|
||||
challengeType: 5
|
||||
forumTopicId: 302295
|
||||
dashedName: k-d-tree
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
A k-d tree (short for *k*-dimensional tree) is a space-partitioning data structure for organizing points in a k-dimensional space. k-d trees are a useful data structure for several applications, such as searches involving a multidimensional search key (e.g. range searches and nearest neighbor searches). k-d trees are a special case of binary space partitioning trees. k-d trees are not suitable, however, for efficiently finding the nearest neighbor in high dimensional spaces. As a general rule, if the dimensionality is *k*, the number of points in the data, *N*, should be *N* ≫ 2<sup><i>k</i></sup>. Otherwise, when k-d trees are used with high-dimensional data, most of the points in the tree will be evaluated and the efficiency is no better than exhaustive search, and other methods such as approximate nearest-neighbor are used instead.
|
||||
|
||||
# --instructions--
|
||||
|
||||
Write a function to perform a nearest neighbour search using k-d tree. The function takes two parameters: an array of k-dimensional points, and a single k-dimensional point whose nearest neighbour should be returned by the function. A k-dimensional point will be given as an array of k elements.
|
||||
|
||||
# --hints--
|
||||
|
||||
`kdNN` should be a function.
|
||||
|
||||
```js
|
||||
assert(typeof kdNN == 'function');
|
||||
```
|
||||
|
||||
`kdNN([[[2, 3], [5, 4], [9, 6], [4, 7], [8, 1], [7, 2]], [9, 2])` should return an array.
|
||||
|
||||
```js
|
||||
assert(
|
||||
Array.isArray(
|
||||
kdNN(
|
||||
[
|
||||
[2, 3],
|
||||
[5, 4],
|
||||
[9, 6],
|
||||
[4, 7],
|
||||
[8, 1],
|
||||
[7, 2]
|
||||
],
|
||||
[9, 2]
|
||||
)
|
||||
)
|
||||
);
|
||||
```
|
||||
|
||||
`kdNN([[[2, 3], [5, 4], [9, 6], [4, 7], [8, 1], [7, 2]], [9, 2])` should return `[ 8, 1 ]`.
|
||||
|
||||
```js
|
||||
assert.deepEqual(
|
||||
kdNN(
|
||||
[
|
||||
[2, 3],
|
||||
[5, 4],
|
||||
[9, 6],
|
||||
[4, 7],
|
||||
[8, 1],
|
||||
[7, 2]
|
||||
],
|
||||
[9, 2]
|
||||
),
|
||||
[8, 1]
|
||||
);
|
||||
```
|
||||
|
||||
`kdNN([[[2, 3], [5, 4], [9, 6], [4, 7], [8, 1], [7, 2]], [7, 1])` should return `[ 8, 1 ]`.
|
||||
|
||||
```js
|
||||
assert.deepEqual(
|
||||
kdNN(
|
||||
[
|
||||
[2, 3],
|
||||
[5, 4],
|
||||
[9, 6],
|
||||
[4, 7],
|
||||
[8, 1],
|
||||
[7, 2]
|
||||
],
|
||||
[7, 1]
|
||||
),
|
||||
[8, 1]
|
||||
);
|
||||
```
|
||||
|
||||
`kdNN([[[2, 3], [5, 4], [9, 6], [4, 7], [8, 1], [7, 2]], [3, 2])` should return `[ 2, 3 ]`.
|
||||
|
||||
```js
|
||||
assert.deepEqual(
|
||||
kdNN(
|
||||
[
|
||||
[2, 3],
|
||||
[5, 4],
|
||||
[9, 6],
|
||||
[4, 7],
|
||||
[8, 1],
|
||||
[7, 2]
|
||||
],
|
||||
[3, 2]
|
||||
),
|
||||
[2, 3]
|
||||
);
|
||||
```
|
||||
|
||||
`kdNN([[2, 3, 1], [9, 4, 5], [4, 6, 7], [1, 2, 5], [7, 8, 9], [3, 6, 1]], [1, 2, 3])` should return `[ 1, 2, 5 ]`.
|
||||
|
||||
```js
|
||||
assert.deepEqual(
|
||||
kdNN(
|
||||
[
|
||||
[2, 3, 1],
|
||||
[9, 4, 5],
|
||||
[4, 6, 7],
|
||||
[1, 2, 5],
|
||||
[7, 8, 9],
|
||||
[3, 6, 1]
|
||||
],
|
||||
[1, 2, 3]
|
||||
),
|
||||
[1, 2, 5]
|
||||
);
|
||||
```
|
||||
|
||||
`kdNN([[2, 3, 1], [9, 4, 5], [4, 6, 7], [1, 2, 5], [7, 8, 9], [3, 6, 1]], [4, 5, 6])` should return `[ 4, 6, 7 ]`.
|
||||
|
||||
```js
|
||||
assert.deepEqual(
|
||||
kdNN(
|
||||
[
|
||||
[2, 3, 1],
|
||||
[9, 4, 5],
|
||||
[4, 6, 7],
|
||||
[1, 2, 5],
|
||||
[7, 8, 9],
|
||||
[3, 6, 1]
|
||||
],
|
||||
[4, 5, 6]
|
||||
),
|
||||
[4, 6, 7]
|
||||
);
|
||||
```
|
||||
|
||||
`kdNN([[2, 3, 1], [9, 4, 5], [4, 6, 7], [1, 2, 5], [7, 8, 9], [3, 6, 1]], [8, 8, 8])` should return `[ 7, 8, 9 ]`.
|
||||
|
||||
```js
|
||||
assert.deepEqual(
|
||||
kdNN(
|
||||
[
|
||||
[2, 3, 1],
|
||||
[9, 4, 5],
|
||||
[4, 6, 7],
|
||||
[1, 2, 5],
|
||||
[7, 8, 9],
|
||||
[3, 6, 1]
|
||||
],
|
||||
[8, 8, 8]
|
||||
),
|
||||
[7, 8, 9]
|
||||
);
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```js
|
||||
function kdNN(fpoints, fpoint) {
|
||||
|
||||
}
|
||||
```
|
||||
|
||||
# --solutions--
|
||||
|
||||
```js
|
||||
function kdNN(fpoints, fpoint) {
|
||||
function Node(obj, dimension, parent) {
|
||||
this.obj = obj;
|
||||
this.left = null;
|
||||
this.right = null;
|
||||
this.parent = parent;
|
||||
this.dimension = dimension;
|
||||
}
|
||||
|
||||
function kdTree(points, metric, dimensions) {
|
||||
var self = this;
|
||||
|
||||
function buildTree(points, depth, parent) {
|
||||
var dim = depth % dimensions.length,
|
||||
median,
|
||||
node;
|
||||
|
||||
if (points.length === 0) {
|
||||
return null;
|
||||
}
|
||||
if (points.length === 1) {
|
||||
return new Node(points[0], dim, parent);
|
||||
}
|
||||
|
||||
points.sort(function(a, b) {
|
||||
return a[dimensions[dim]] - b[dimensions[dim]];
|
||||
});
|
||||
|
||||
median = Math.floor(points.length / 2);
|
||||
node = new Node(points[median], dim, parent);
|
||||
node.left = buildTree(points.slice(0, median), depth + 1, node);
|
||||
node.right = buildTree(points.slice(median + 1), depth + 1, node);
|
||||
|
||||
return node;
|
||||
}
|
||||
|
||||
this.root = buildTree(points, 0, null);
|
||||
|
||||
this.insert = function(point) {
|
||||
function innerSearch(node, parent) {
|
||||
if (node === null) {
|
||||
return parent;
|
||||
}
|
||||
|
||||
var dimension = dimensions[node.dimension];
|
||||
if (point[dimension] < node.obj[dimension]) {
|
||||
return innerSearch(node.left, node);
|
||||
} else {
|
||||
return innerSearch(node.right, node);
|
||||
}
|
||||
}
|
||||
|
||||
var insertPosition = innerSearch(this.root, null),
|
||||
newNode,
|
||||
dimension;
|
||||
|
||||
if (insertPosition === null) {
|
||||
this.root = new Node(point, 0, null);
|
||||
return;
|
||||
}
|
||||
|
||||
newNode = new Node(
|
||||
point,
|
||||
(insertPosition.dimension + 1) % dimensions.length,
|
||||
insertPosition
|
||||
);
|
||||
dimension = dimensions[insertPosition.dimension];
|
||||
|
||||
if (point[dimension] < insertPosition.obj[dimension]) {
|
||||
insertPosition.left = newNode;
|
||||
} else {
|
||||
insertPosition.right = newNode;
|
||||
}
|
||||
};
|
||||
|
||||
this.nearest = function(point, maxNodes, maxDistance) {
|
||||
var i, result, bestNodes;
|
||||
|
||||
bestNodes = new BinaryHeap(function(e) {
|
||||
return -e[1];
|
||||
});
|
||||
|
||||
function nearestSearch(node) {
|
||||
var bestChild,
|
||||
dimension = dimensions[node.dimension],
|
||||
ownDistance = metric(point, node.obj),
|
||||
linearPoint = {},
|
||||
linearDistance,
|
||||
otherChild,
|
||||
i;
|
||||
|
||||
function saveNode(node, distance) {
|
||||
bestNodes.push([node, distance]);
|
||||
if (bestNodes.size() > maxNodes) {
|
||||
bestNodes.pop();
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < dimensions.length; i += 1) {
|
||||
if (i === node.dimension) {
|
||||
linearPoint[dimensions[i]] = point[dimensions[i]];
|
||||
} else {
|
||||
linearPoint[dimensions[i]] = node.obj[dimensions[i]];
|
||||
}
|
||||
}
|
||||
|
||||
linearDistance = metric(linearPoint, node.obj);
|
||||
|
||||
if (node.right === null && node.left === null) {
|
||||
if (
|
||||
bestNodes.size() < maxNodes ||
|
||||
ownDistance < bestNodes.peek()[1]
|
||||
) {
|
||||
saveNode(node, ownDistance);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (node.right === null) {
|
||||
bestChild = node.left;
|
||||
} else if (node.left === null) {
|
||||
bestChild = node.right;
|
||||
} else {
|
||||
if (point[dimension] < node.obj[dimension]) {
|
||||
bestChild = node.left;
|
||||
} else {
|
||||
bestChild = node.right;
|
||||
}
|
||||
}
|
||||
|
||||
nearestSearch(bestChild);
|
||||
|
||||
if (bestNodes.size() < maxNodes || ownDistance < bestNodes.peek()[1]) {
|
||||
saveNode(node, ownDistance);
|
||||
}
|
||||
|
||||
if (
|
||||
bestNodes.size() < maxNodes ||
|
||||
Math.abs(linearDistance) < bestNodes.peek()[1]
|
||||
) {
|
||||
if (bestChild === node.left) {
|
||||
otherChild = node.right;
|
||||
} else {
|
||||
otherChild = node.left;
|
||||
}
|
||||
if (otherChild !== null) {
|
||||
nearestSearch(otherChild);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (maxDistance) {
|
||||
for (i = 0; i < maxNodes; i += 1) {
|
||||
bestNodes.push([null, maxDistance]);
|
||||
}
|
||||
}
|
||||
|
||||
if (self.root) nearestSearch(self.root);
|
||||
|
||||
result = [];
|
||||
|
||||
for (i = 0; i < Math.min(maxNodes, bestNodes.content.length); i += 1) {
|
||||
if (bestNodes.content[i][0]) {
|
||||
result.push([bestNodes.content[i][0].obj, bestNodes.content[i][1]]);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
};
|
||||
}
|
||||
|
||||
function BinaryHeap(scoreFunction) {
|
||||
this.content = [];
|
||||
this.scoreFunction = scoreFunction;
|
||||
}
|
||||
|
||||
BinaryHeap.prototype = {
|
||||
push: function(element) {
|
||||
// Add the new element to the end of the array.
|
||||
this.content.push(element);
|
||||
// Allow it to bubble up.
|
||||
this.bubbleUp(this.content.length - 1);
|
||||
},
|
||||
|
||||
pop: function() {
|
||||
// Store the first element so we can return it later.
|
||||
var result = this.content[0];
|
||||
// Get the element at the end of the array.
|
||||
var end = this.content.pop();
|
||||
// If there are any elements left, put the end element at the
|
||||
// start, and let it sink down.
|
||||
if (this.content.length > 0) {
|
||||
this.content[0] = end;
|
||||
this.sinkDown(0);
|
||||
}
|
||||
return result;
|
||||
},
|
||||
|
||||
peek: function() {
|
||||
return this.content[0];
|
||||
},
|
||||
|
||||
size: function() {
|
||||
return this.content.length;
|
||||
},
|
||||
|
||||
bubbleUp: function(n) {
|
||||
// Fetch the element that has to be moved.
|
||||
var element = this.content[n];
|
||||
// When at 0, an element can not go up any further.
|
||||
while (n > 0) {
|
||||
// Compute the parent element's index, and fetch it.
|
||||
var parentN = Math.floor((n + 1) / 2) - 1,
|
||||
parent = this.content[parentN];
|
||||
// Swap the elements if the parent is greater.
|
||||
if (this.scoreFunction(element) < this.scoreFunction(parent)) {
|
||||
this.content[parentN] = element;
|
||||
this.content[n] = parent;
|
||||
// Update 'n' to continue at the new position.
|
||||
n = parentN;
|
||||
}
|
||||
// Found a parent that is less, no need to move it further.
|
||||
else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
sinkDown: function(n) {
|
||||
// Look up the target element and its score.
|
||||
var length = this.content.length,
|
||||
element = this.content[n],
|
||||
elemScore = this.scoreFunction(element);
|
||||
|
||||
while (true) {
|
||||
// Compute the indices of the child elements.
|
||||
var child2N = (n + 1) * 2,
|
||||
child1N = child2N - 1;
|
||||
// This is used to store the new position of the element,
|
||||
// if any.
|
||||
var swap = null;
|
||||
// If the first child exists (is inside the array)...
|
||||
if (child1N < length) {
|
||||
// Look it up and compute its score.
|
||||
var child1 = this.content[child1N],
|
||||
child1Score = this.scoreFunction(child1);
|
||||
// If the score is less than our element's, we need to swap.
|
||||
if (child1Score < elemScore) swap = child1N;
|
||||
}
|
||||
// Do the same checks for the other child.
|
||||
if (child2N < length) {
|
||||
var child2 = this.content[child2N],
|
||||
child2Score = this.scoreFunction(child2);
|
||||
if (child2Score < (swap == null ? elemScore : child1Score)) {
|
||||
swap = child2N;
|
||||
}
|
||||
}
|
||||
|
||||
// If the element needs to be moved, swap it, and continue.
|
||||
if (swap != null) {
|
||||
this.content[n] = this.content[swap];
|
||||
this.content[swap] = element;
|
||||
n = swap;
|
||||
}
|
||||
// Otherwise, we are done.
|
||||
else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
var dims = [];
|
||||
|
||||
for (var i = 0; i < fpoint.length; i++) dims.push(i);
|
||||
|
||||
var tree = new kdTree(
|
||||
fpoints,
|
||||
function(e1, e2) {
|
||||
var d = 0;
|
||||
var e3 = e1;
|
||||
if (!Array.isArray(e1)) {
|
||||
e3 = [];
|
||||
for (var key in e1) e3.push(e1[key]);
|
||||
|
||||
e1 = e3;
|
||||
}
|
||||
e1.forEach(function(e, i) {
|
||||
var sqd = e1[i] - e2[i];
|
||||
d += sqd * sqd;
|
||||
});
|
||||
return d;
|
||||
},
|
||||
dims
|
||||
);
|
||||
|
||||
return tree.nearest(fpoint, 1, 1000)[0][0];
|
||||
}
|
||||
```
|
@ -0,0 +1,110 @@
|
||||
---
|
||||
id: 5a23c84252665b21eecc7eca
|
||||
title: Kaprekar numbers
|
||||
challengeType: 5
|
||||
forumTopicId: 302296
|
||||
dashedName: kaprekar-numbers
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
A positive integer is a [Kaprekar number](https://en.wikipedia.org/wiki/Kaprekar number) if:
|
||||
|
||||
<ul>
|
||||
<li>It is 1, or,</li>
|
||||
<li>The decimal representation of its square may be split once into two parts consisting of positive integers which sum to the original number. </li>
|
||||
</ul>
|
||||
|
||||
Note that a split resulting in a part consisting purely of 0s is not valid, as 0 is not considered positive.Example
|
||||
|
||||
Kaprekar numbers:
|
||||
|
||||
<ul>
|
||||
<li><code>2223</code> is a Kaprekar number, as <code>2223 * 2223 = 4941729</code>, <code>4941729</code> may be split to <code>494</code> and <code>1729</code>, and <code>494 + 1729 = 2223</code></li>
|
||||
<li>The series of Kaprekar numbers is known as <a href='https://oeis.org/A006886' target='_blank'>A006886</a>, and begins as <code>1, 9, 45, 55, ...</code></li>
|
||||
</ul>
|
||||
|
||||
# --instructions--
|
||||
|
||||
Write a function that takes a number $n$, a base $bs$, and returns true if the number is a Kaprekar number for the given base. Otherwise, the function returns false.
|
||||
|
||||
# --hints--
|
||||
|
||||
`isKaprekar` should be a function.
|
||||
|
||||
```js
|
||||
assert(typeof isKaprekar == 'function');
|
||||
```
|
||||
|
||||
`isKaprekar(1, 10)` should return a boolean.
|
||||
|
||||
```js
|
||||
assert(typeof isKaprekar(1, 10) == 'boolean');
|
||||
```
|
||||
|
||||
`isKaprekar(1, 10)` should return `true`.
|
||||
|
||||
```js
|
||||
assert.equal(isKaprekar(1, 10), true);
|
||||
```
|
||||
|
||||
`isKaprekar(9, 10)` should return `true`.
|
||||
|
||||
```js
|
||||
assert.equal(isKaprekar(9, 10), true);
|
||||
```
|
||||
|
||||
`isKaprekar(2223, 10)` should return `true`.
|
||||
|
||||
```js
|
||||
assert.equal(isKaprekar(2223, 10), true);
|
||||
```
|
||||
|
||||
`isKaprekar(22823, 10)` should return `false`.
|
||||
|
||||
```js
|
||||
assert.equal(isKaprekar(22823, 10), false);
|
||||
```
|
||||
|
||||
`isKaprekar(9, 17)` should return `false`.
|
||||
|
||||
```js
|
||||
assert.equal(isKaprekar(9, 17), false);
|
||||
```
|
||||
|
||||
`isKaprekar(225, 17)` should return `true`.
|
||||
|
||||
```js
|
||||
assert.equal(isKaprekar(225, 17), true);
|
||||
```
|
||||
|
||||
`isKaprekar(999, 17)` should return `false`.
|
||||
|
||||
```js
|
||||
assert.equal(isKaprekar(999, 17), false);
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```js
|
||||
function isKaprekar(n, bs) {
|
||||
|
||||
}
|
||||
```
|
||||
|
||||
# --solutions--
|
||||
|
||||
```js
|
||||
function isKaprekar(n, bs) {
|
||||
if (n < 1) return false;
|
||||
if (n == 1) return true;
|
||||
for (var a = n * n, b = 0, s = 1; a; s *= bs) {
|
||||
b += (a % bs) * s;
|
||||
a = Math.floor(a / bs);
|
||||
if (b && a + b == n) return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
```
|
@ -0,0 +1,255 @@
|
||||
---
|
||||
id: 5a23c84252665b21eecc7ed1
|
||||
title: Knapsack problem/0-1
|
||||
challengeType: 5
|
||||
forumTopicId: 323649
|
||||
dashedName: knapsack-problem0-1
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
The 0-1 knapsack problem is defined as follows:
|
||||
|
||||
You are given an array of objects representing items to be put in a knapsack. The objects have 3 attributes: name, weight, and value. The items need to be selected so that the total weight does not exceed the maximum weight and the value is maximized.
|
||||
|
||||
# --instructions--
|
||||
|
||||
Write a function to solve the knapsack problem. The function is given the array of objects and the maximum weight as parameters. It should return the maximum total value possible.
|
||||
|
||||
# --hints--
|
||||
|
||||
`knapsack([{ name:'map', weight:9, value:150 }, { name:'compass', weight:13, value:35 }, { name:'water', weight:153, value:200 }, { name:'sandwich', weight:50, value:160 }, { name:'glucose', weight:15, value:60 }, { name:'tin', weight:68, value:45 }, { name:'banana', weight:27, value:60 }, { name:'apple', weight:39, value:40 }], 100)` should return `405`.
|
||||
|
||||
```js
|
||||
assert.equal(
|
||||
knapsack(
|
||||
[
|
||||
{ name: 'map', weight: 9, value: 150 },
|
||||
{ name: 'compass', weight: 13, value: 35 },
|
||||
{ name: 'water', weight: 153, value: 200 },
|
||||
{ name: 'sandwich', weight: 50, value: 160 },
|
||||
{ name: 'glucose', weight: 15, value: 60 },
|
||||
{ name: 'tin', weight: 68, value: 45 },
|
||||
{ name: 'banana', weight: 27, value: 60 },
|
||||
{ name: 'apple', weight: 39, value: 40 }
|
||||
],
|
||||
100
|
||||
),
|
||||
405
|
||||
);
|
||||
```
|
||||
|
||||
`knapsack([{ name:'map', weight:9, value:150 }, { name:'compass', weight:13, value:35 }, { name:'water', weight:153, value:200 }, { name:'sandwich', weight:50, value:160 }, { name:'glucose', weight:15, value:60 }, { name:'tin', weight:68, value:45 }, { name:'banana', weight:27, value:60 }, { name:'apple', weight:39, value:40 }], 200)` should return `510`.
|
||||
|
||||
```js
|
||||
assert.equal(
|
||||
knapsack(
|
||||
[
|
||||
{ name: 'map', weight: 9, value: 150 },
|
||||
{ name: 'compass', weight: 13, value: 35 },
|
||||
{ name: 'water', weight: 153, value: 200 },
|
||||
{ name: 'sandwich', weight: 50, value: 160 },
|
||||
{ name: 'glucose', weight: 15, value: 60 },
|
||||
{ name: 'tin', weight: 68, value: 45 },
|
||||
{ name: 'banana', weight: 27, value: 60 },
|
||||
{ name: 'apple', weight: 39, value: 40 }
|
||||
],
|
||||
200
|
||||
),
|
||||
510
|
||||
);
|
||||
```
|
||||
|
||||
`knapsack([{ name:'cheese', weight:23, value:30 }, { name:'beer', weight:52, value:10 }, { name:'suntan cream', weight:11, value:70 }, { name:'camera', weight:32, value:30 }, { name:'T-shirt', weight:24, value:15 }, { name:'trousers', weight:48, value:10 }, { name:'umbrella', weight:73, value:40 }], 100)` should return `145`.
|
||||
|
||||
```js
|
||||
assert.equal(
|
||||
knapsack(
|
||||
[
|
||||
{ name: 'cheese', weight: 23, value: 30 },
|
||||
{ name: 'beer', weight: 52, value: 10 },
|
||||
{ name: 'suntan cream', weight: 11, value: 70 },
|
||||
{ name: 'camera', weight: 32, value: 30 },
|
||||
{ name: 'T-shirt', weight: 24, value: 15 },
|
||||
{ name: 'trousers', weight: 48, value: 10 },
|
||||
{ name: 'umbrella', weight: 73, value: 40 }
|
||||
],
|
||||
100
|
||||
),
|
||||
145
|
||||
);
|
||||
```
|
||||
|
||||
`knapsack([{ name:'cheese', weight:23, value:30 }, { name:'beer', weight:52, value:10 }, { name:'suntan cream', weight:11, value:70 }, { name:'camera', weight:32, value:30 }, { name:'T-shirt', weight:24, value:15 }, { name:'trousers', weight:48, value:10 }, { name:'umbrella', weight:73, value:40 }], 200)` should return `185`.
|
||||
|
||||
```js
|
||||
assert.equal(
|
||||
knapsack(
|
||||
[
|
||||
{ name: 'cheese', weight: 23, value: 30 },
|
||||
{ name: 'beer', weight: 52, value: 10 },
|
||||
{ name: 'suntan cream', weight: 11, value: 70 },
|
||||
{ name: 'camera', weight: 32, value: 30 },
|
||||
{ name: 'T-shirt', weight: 24, value: 15 },
|
||||
{ name: 'trousers', weight: 48, value: 10 },
|
||||
{ name: 'umbrella', weight: 73, value: 40 }
|
||||
],
|
||||
200
|
||||
),
|
||||
185
|
||||
);
|
||||
```
|
||||
|
||||
`knapsack([{ name:'waterproof trousers', weight:42, value:70 }, { name:'waterproof overclothes', weight:43, value:75 }, { name:'note-case', weight:22, value:80 }, { name:'sunglasses', weight:7, value:20 }, { name:'towel', weight:18, value:12 }, { name:'socks', weight:4, value:50 }, { name:'book', weight:30, value:10 }], 100)` should return `237`.
|
||||
|
||||
```js
|
||||
assert.equal(
|
||||
knapsack(
|
||||
[
|
||||
{ name: 'waterproof trousers', weight: 42, value: 70 },
|
||||
{ name: 'waterproof overclothes', weight: 43, value: 75 },
|
||||
{ name: 'note-case', weight: 22, value: 80 },
|
||||
{ name: 'sunglasses', weight: 7, value: 20 },
|
||||
{ name: 'towel', weight: 18, value: 12 },
|
||||
{ name: 'socks', weight: 4, value: 50 },
|
||||
{ name: 'book', weight: 30, value: 10 }
|
||||
],
|
||||
100
|
||||
),
|
||||
237
|
||||
);
|
||||
```
|
||||
|
||||
`knapsack([{ name:'waterproof trousers', weight:42, value:70 }, { name:'waterproof overclothes', weight:43, value:75 }, { name:'note-case', weight:22, value:80 }, { name:'sunglasses', weight:7, value:20 }, { name:'towel', weight:18, value:12 }, { name:'socks', weight:4, value:50 }, { name:'book', weight:30, value:10 }], 200)` should return `317`.'
|
||||
|
||||
```js
|
||||
assert.equal(
|
||||
knapsack(
|
||||
[
|
||||
{ name: 'waterproof trousers', weight: 42, value: 70 },
|
||||
{ name: 'waterproof overclothes', weight: 43, value: 75 },
|
||||
{ name: 'note-case', weight: 22, value: 80 },
|
||||
{ name: 'sunglasses', weight: 7, value: 20 },
|
||||
{ name: 'towel', weight: 18, value: 12 },
|
||||
{ name: 'socks', weight: 4, value: 50 },
|
||||
{ name: 'book', weight: 30, value: 10 }
|
||||
],
|
||||
200
|
||||
),
|
||||
317
|
||||
);
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```js
|
||||
function knapsack(items, maxweight) {
|
||||
|
||||
}
|
||||
```
|
||||
|
||||
# --solutions--
|
||||
|
||||
```js
|
||||
function knapsack(items, maxweight) {
|
||||
var _ = {
|
||||
max: function(e) {
|
||||
var mx = e[0];
|
||||
e.forEach(function(f) {
|
||||
if (mx < f) mx = f;
|
||||
});
|
||||
return mx;
|
||||
},
|
||||
map: function(array, func) {
|
||||
return array.map(func);
|
||||
},
|
||||
isUndefined: function(a) {
|
||||
if (a) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
},
|
||||
range: function(start, end, step) {
|
||||
var a = [];
|
||||
var f = (f = (i, end) => i < end);
|
||||
if (start > end) f = (i, end) => i > end;
|
||||
|
||||
for (var i = start; f(i, end); i += step) a.push(i);
|
||||
return a;
|
||||
}
|
||||
};
|
||||
|
||||
var valuefn = e => e.value;
|
||||
var weightfn = e => e.weight;
|
||||
var _epsilon = 0.01;
|
||||
var _p = _.max(_.map(items, valuefn));
|
||||
var _k = (_epsilon * _p) / items.length;
|
||||
|
||||
var _memo = (function() {
|
||||
var _mem = {};
|
||||
var _key = function(i, w) {
|
||||
return i + '::' + w;
|
||||
};
|
||||
return {
|
||||
get: function(i, w) {
|
||||
return _mem[_key(i, w)];
|
||||
},
|
||||
put: function(i, w, r) {
|
||||
_mem[_key(i, w)] = r;
|
||||
return r;
|
||||
}
|
||||
};
|
||||
})();
|
||||
|
||||
var _m = function(i, w) {
|
||||
i = Math.round(i);
|
||||
w = Math.round(w);
|
||||
|
||||
if (i < 0 || w === 0) {
|
||||
// empty base case
|
||||
return { items: [], totalWeight: 0, totalValue: 0 };
|
||||
}
|
||||
|
||||
var mm = _memo.get(i, w);
|
||||
if (!_.isUndefined(mm)) {
|
||||
return mm;
|
||||
}
|
||||
|
||||
var item = items[i];
|
||||
if (weightfn(item) > w) {
|
||||
//item does not fit, try the next item
|
||||
return _memo.put(i, w, _m(i - 1, w));
|
||||
}
|
||||
// this item could fit.
|
||||
// are we better off excluding it?
|
||||
var excluded = _m(i - 1, w);
|
||||
// or including it?
|
||||
var included = _m(i - 1, w - weightfn(item));
|
||||
if (
|
||||
included.totalValue + Math.floor(valuefn(item) / _k) >
|
||||
excluded.totalValue
|
||||
) {
|
||||
// better off including it
|
||||
// make a copy of the list
|
||||
var i1 = included.items.slice();
|
||||
i1.push(item);
|
||||
return _memo.put(i, w, {
|
||||
items: i1,
|
||||
totalWeight: included.totalWeight + weightfn(item),
|
||||
totalValue: included.totalValue + Math.floor(valuefn(item) / _k)
|
||||
});
|
||||
}
|
||||
//better off excluding it
|
||||
return _memo.put(i, w, excluded);
|
||||
};
|
||||
var scaled = _m(items.length - 1, maxweight);
|
||||
|
||||
var val = 0;
|
||||
scaled.items.forEach(function(e) {
|
||||
val += e.value;
|
||||
});
|
||||
return val;
|
||||
}
|
||||
```
|
@ -0,0 +1,212 @@
|
||||
---
|
||||
id: 5a23c84252665b21eecc7ed2
|
||||
title: Knapsack problem/Bounded
|
||||
challengeType: 5
|
||||
forumTopicId: 323652
|
||||
dashedName: knapsack-problembounded
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
The bounded knapsack problem is defined as follows:
|
||||
|
||||
You are given an array of objects representing items to be put in a knapsack. The objects have 4 attributes: name, pieces (the number of the particular item), weight, and value. The items need to be selected so that the total weight does not exceed the maximum weight and the value is maximized. Keep in mind that each item can appear between 0 and `pieces` times.
|
||||
|
||||
# --instructions--
|
||||
|
||||
Write a function to solve the knapsack problem. The function is given the array of objects and the maximum weight as parameters. It should return the maximum total value possible.
|
||||
|
||||
# --hints--
|
||||
|
||||
`findBestPack([{ name:'map', weight:9, value:150, pieces:1 }, { name:'compass', weight:13, value:35, pieces:1 }, { name:'water', weight:153, value:200, pieces:2 }, { name:'sandwich', weight:50, value:60, pieces:2 }, { name:'glucose', weight:15, value:60, pieces:2 }, { name:'tin', weight:68, value:45, pieces:3 }, { name:'banana', weight:27, value:60, pieces:3 }, { name:'apple', weight:39, value:40, pieces:3 }, { name:'cheese', weight:23, value:30, pieces:1 }, { name:'beer', weight:52, value:10, pieces:3 }, { name:'suntan, cream', weight:11, value:70, pieces:1 }, { name:'camera', weight:32, value:30, pieces:1 }, { name:'T-shirt', weight:24, value:15, pieces:2 }], 300)` should return `755`.
|
||||
|
||||
```js
|
||||
assert.equal(
|
||||
findBestPack(
|
||||
[
|
||||
{ name: 'map', weight: 9, value: 150, pieces: 1 },
|
||||
{ name: 'compass', weight: 13, value: 35, pieces: 1 },
|
||||
{ name: 'water', weight: 153, value: 200, pieces: 2 },
|
||||
{ name: 'sandwich', weight: 50, value: 60, pieces: 2 },
|
||||
{ name: 'glucose', weight: 15, value: 60, pieces: 2 },
|
||||
{ name: 'tin', weight: 68, value: 45, pieces: 3 },
|
||||
{ name: 'banana', weight: 27, value: 60, pieces: 3 },
|
||||
{ name: 'apple', weight: 39, value: 40, pieces: 3 },
|
||||
{ name: 'cheese', weight: 23, value: 30, pieces: 1 },
|
||||
{ name: 'beer', weight: 52, value: 10, pieces: 3 },
|
||||
{ name: 'suntan, cream', weight: 11, value: 70, pieces: 1 },
|
||||
{ name: 'camera', weight: 32, value: 30, pieces: 1 },
|
||||
{ name: 'T-shirt', weight: 24, value: 15, pieces: 2 }
|
||||
],
|
||||
300
|
||||
),
|
||||
755
|
||||
);
|
||||
```
|
||||
|
||||
`findBestPack([{ name:'map', weight:9, value:150, pieces:1 }, { name:'compass', weight:13, value:35, pieces:1 }, { name:'water', weight:153, value:200, pieces:2 }, { name:'sandwich', weight:50, value:60, pieces:2 }, { name:'glucose', weight:15, value:60, pieces:2 }, { name:'tin', weight:68, value:45, pieces:3 }, { name:'banana', weight:27, value:60, pieces:3 }, { name:'apple', weight:39, value:40, pieces:3 }, { name:'cheese', weight:23, value:30, pieces:1 }, { name:'beer', weight:52, value:10, pieces:3 }, { name:'suntan, cream', weight:11, value:70, pieces:1 }, { name:'camera', weight:32, value:30, pieces:1 }, { name:'T-shirt', weight:24, value:15, pieces:2 }], 400)` should return `875`.
|
||||
|
||||
```js
|
||||
assert.equal(
|
||||
findBestPack(
|
||||
[
|
||||
{ name: 'map', weight: 9, value: 150, pieces: 1 },
|
||||
{ name: 'compass', weight: 13, value: 35, pieces: 1 },
|
||||
{ name: 'water', weight: 153, value: 200, pieces: 2 },
|
||||
{ name: 'sandwich', weight: 50, value: 60, pieces: 2 },
|
||||
{ name: 'glucose', weight: 15, value: 60, pieces: 2 },
|
||||
{ name: 'tin', weight: 68, value: 45, pieces: 3 },
|
||||
{ name: 'banana', weight: 27, value: 60, pieces: 3 },
|
||||
{ name: 'apple', weight: 39, value: 40, pieces: 3 },
|
||||
{ name: 'cheese', weight: 23, value: 30, pieces: 1 },
|
||||
{ name: 'beer', weight: 52, value: 10, pieces: 3 },
|
||||
{ name: 'suntan, cream', weight: 11, value: 70, pieces: 1 },
|
||||
{ name: 'camera', weight: 32, value: 30, pieces: 1 },
|
||||
{ name: 'T-shirt', weight: 24, value: 15, pieces: 2 }
|
||||
],
|
||||
400
|
||||
),
|
||||
875
|
||||
);
|
||||
```
|
||||
|
||||
`findBestPack([{ name:'map', weight:9, value:150, pieces:1 }, { name:'compass', weight:13, value:35, pieces:1 }, { name:'water', weight:153, value:200, pieces:2 }, { name:'sandwich', weight:50, value:60, pieces:2 }, { name:'glucose', weight:15, value:60, pieces:2 }, { name:'tin', weight:68, value:45, pieces:3 }, { name:'banana', weight:27, value:60, pieces:3 }, { name:'apple', weight:39, value:40, pieces:3 }, { name:'cheese', weight:23, value:30, pieces:1 }, { name:'beer', weight:52, value:10, pieces:3 }, { name:'suntan, cream', weight:11, value:70, pieces:1 }, { name:'camera', weight:32, value:30, pieces:1 }, { name:'T-shirt', weight:24, value:15, pieces:2 }], 500)` should return `1015`.
|
||||
|
||||
```js
|
||||
assert.equal(
|
||||
findBestPack(
|
||||
[
|
||||
{ name: 'map', weight: 9, value: 150, pieces: 1 },
|
||||
{ name: 'compass', weight: 13, value: 35, pieces: 1 },
|
||||
{ name: 'water', weight: 153, value: 200, pieces: 2 },
|
||||
{ name: 'sandwich', weight: 50, value: 60, pieces: 2 },
|
||||
{ name: 'glucose', weight: 15, value: 60, pieces: 2 },
|
||||
{ name: 'tin', weight: 68, value: 45, pieces: 3 },
|
||||
{ name: 'banana', weight: 27, value: 60, pieces: 3 },
|
||||
{ name: 'apple', weight: 39, value: 40, pieces: 3 },
|
||||
{ name: 'cheese', weight: 23, value: 30, pieces: 1 },
|
||||
{ name: 'beer', weight: 52, value: 10, pieces: 3 },
|
||||
{ name: 'suntan, cream', weight: 11, value: 70, pieces: 1 },
|
||||
{ name: 'camera', weight: 32, value: 30, pieces: 1 },
|
||||
{ name: 'T-shirt', weight: 24, value: 15, pieces: 2 }
|
||||
],
|
||||
500
|
||||
),
|
||||
1015
|
||||
);
|
||||
```
|
||||
|
||||
`findBestPack([{ name:'map', weight:9, value:150, pieces:1 }, { name:'compass', weight:13, value:35, pieces:1 }, { name:'water', weight:153, value:200, pieces:2 }, { name:'sandwich', weight:50, value:60, pieces:2 }, { name:'glucose', weight:15, value:60, pieces:2 }, { name:'tin', weight:68, value:45, pieces:3 }, { name:'banana', weight:27, value:60, pieces:3 }, { name:'apple', weight:39, value:40, pieces:3 }, { name:'cheese', weight:23, value:30, pieces:1 }, { name:'beer', weight:52, value:10, pieces:3 }, { name:'suntan, cream', weight:11, value:70, pieces:1 }, { name:'camera', weight:32, value:30, pieces:1 }, { name:'T-shirt', weight:24, value:15, pieces:2 }], 600)` should return `1120`.
|
||||
|
||||
```js
|
||||
assert.equal(
|
||||
findBestPack(
|
||||
[
|
||||
{ name: 'map', weight: 9, value: 150, pieces: 1 },
|
||||
{ name: 'compass', weight: 13, value: 35, pieces: 1 },
|
||||
{ name: 'water', weight: 153, value: 200, pieces: 2 },
|
||||
{ name: 'sandwich', weight: 50, value: 60, pieces: 2 },
|
||||
{ name: 'glucose', weight: 15, value: 60, pieces: 2 },
|
||||
{ name: 'tin', weight: 68, value: 45, pieces: 3 },
|
||||
{ name: 'banana', weight: 27, value: 60, pieces: 3 },
|
||||
{ name: 'apple', weight: 39, value: 40, pieces: 3 },
|
||||
{ name: 'cheese', weight: 23, value: 30, pieces: 1 },
|
||||
{ name: 'beer', weight: 52, value: 10, pieces: 3 },
|
||||
{ name: 'suntan, cream', weight: 11, value: 70, pieces: 1 },
|
||||
{ name: 'camera', weight: 32, value: 30, pieces: 1 },
|
||||
{ name: 'T-shirt', weight: 24, value: 15, pieces: 2 }
|
||||
],
|
||||
600
|
||||
),
|
||||
1120
|
||||
);
|
||||
```
|
||||
|
||||
`findBestPack([{ name:'map', weight:9, value:150, pieces:1 }, { name:'compass', weight:13, value:35, pieces:1 }, { name:'water', weight:153, value:200, pieces:2 }, { name:'sandwich', weight:50, value:60, pieces:2 }, { name:'glucose', weight:15, value:60, pieces:2 }, { name:'tin', weight:68, value:45, pieces:3 }, { name:'banana', weight:27, value:60, pieces:3 }, { name:'apple', weight:39, value:40, pieces:3 }, { name:'cheese', weight:23, value:30, pieces:1 }, { name:'beer', weight:52, value:10, pieces:3 }, { name:'suntan, cream', weight:11, value:70, pieces:1 }, { name:'camera', weight:32, value:30, pieces:1 }, { name:'T-shirt', weight:24, value:15, pieces:2 }], 700)` should return `1225`.
|
||||
|
||||
```js
|
||||
assert.equal(
|
||||
findBestPack(
|
||||
[
|
||||
{ name: 'map', weight: 9, value: 150, pieces: 1 },
|
||||
{ name: 'compass', weight: 13, value: 35, pieces: 1 },
|
||||
{ name: 'water', weight: 153, value: 200, pieces: 2 },
|
||||
{ name: 'sandwich', weight: 50, value: 60, pieces: 2 },
|
||||
{ name: 'glucose', weight: 15, value: 60, pieces: 2 },
|
||||
{ name: 'tin', weight: 68, value: 45, pieces: 3 },
|
||||
{ name: 'banana', weight: 27, value: 60, pieces: 3 },
|
||||
{ name: 'apple', weight: 39, value: 40, pieces: 3 },
|
||||
{ name: 'cheese', weight: 23, value: 30, pieces: 1 },
|
||||
{ name: 'beer', weight: 52, value: 10, pieces: 3 },
|
||||
{ name: 'suntan, cream', weight: 11, value: 70, pieces: 1 },
|
||||
{ name: 'camera', weight: 32, value: 30, pieces: 1 },
|
||||
{ name: 'T-shirt', weight: 24, value: 15, pieces: 2 }
|
||||
],
|
||||
700
|
||||
),
|
||||
1225
|
||||
);
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```js
|
||||
function findBestPack(data, maxweight) {
|
||||
|
||||
}
|
||||
```
|
||||
|
||||
# --solutions--
|
||||
|
||||
```js
|
||||
function findBestPack(data, maxweight) {
|
||||
var m = [[0]]; // maximum pack value found so far
|
||||
var b = [[0]]; // best combination found so far
|
||||
var opts = [0]; // item index for 0 of item 0
|
||||
var P = [1]; // item encoding for 0 of item 0
|
||||
var choose = 0;
|
||||
for (var j = 0; j < data.length; j++) {
|
||||
opts[j + 1] = opts[j] + data[j].pieces; // item index for 0 of item j+1
|
||||
P[j + 1] = P[j] * (1 + data[j].pieces); // item encoding for 0 of item j+1
|
||||
}
|
||||
for (var j = 0; j < opts[data.length]; j++) {
|
||||
m[0][j + 1] = b[0][j + 1] = 0; // best values and combos for empty pack: nothing
|
||||
}
|
||||
for (var w = 1; w <= maxweight; w++) {
|
||||
m[w] = [0];
|
||||
b[w] = [0];
|
||||
for (var j = 0; j < data.length; j++) {
|
||||
var N = data[j].pieces; // how many of these can we have?
|
||||
var base = opts[j]; // what is the item index for 0 of these?
|
||||
for (var n = 1; n <= N; n++) {
|
||||
var W = n * data[j].weight; // how much do these items weigh?
|
||||
var s = w >= W ? 1 : 0; // can we carry this many?
|
||||
var v = s * n * data[j].value; // how much are they worth?
|
||||
var I = base + n; // what is the item number for this many?
|
||||
var wN = w - s * W; // how much other stuff can we be carrying?
|
||||
var C = n * P[j] + b[wN][base]; // encoded combination
|
||||
m[w][I] = Math.max(m[w][I - 1], v + m[wN][base]); // best value
|
||||
choose = b[w][I] = m[w][I] > m[w][I - 1] ? C : b[w][I - 1];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var best = [];
|
||||
for (var j = data.length - 1; j >= 0; j--) {
|
||||
best[j] = Math.floor(choose / P[j]);
|
||||
choose -= best[j] * P[j];
|
||||
}
|
||||
|
||||
var wgt = 0;
|
||||
var val = 0;
|
||||
for (var i = 0; i < best.length; i++) {
|
||||
if (0 == best[i]) continue;
|
||||
wgt += best[i] * data[i].weight;
|
||||
val += best[i] * data[i].value;
|
||||
}
|
||||
|
||||
return val;
|
||||
}
|
||||
```
|
@ -0,0 +1,169 @@
|
||||
---
|
||||
id: 5a23c84252665b21eecc7ed3
|
||||
title: Knapsack problem/Continuous
|
||||
challengeType: 5
|
||||
forumTopicId: 323654
|
||||
dashedName: knapsack-problemcontinuous
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
A thief burgles a butcher's shop, where he can select from some items.
|
||||
|
||||
The thief knows the weights and prices of each items. Because he has a knapsack with a limit on the maximum weight that it can carry, he wants to select the items such that he would have his profit maximized. He may cut the items; the item has a reduced price after cutting that is proportional to the original price by the ratio of masses. That means: half of an item has half the price of the original.
|
||||
|
||||
# --instructions--
|
||||
|
||||
Write a function that takes an array of objects representing the items available in the shop. Each object has 3 attributes: name, weight, and value. The function also takes the maximum weight as a parameter. The function should return the maximum value possible, and the total weight of the selected items should not exceed the maximum weight.
|
||||
|
||||
# --hints--
|
||||
|
||||
`knapContinuous([{ "weight":3.8, "value":36, name:"beef" }, { "weight":5.4, "value":43, name:"pork" }, { "weight":3.6, "value":90, name:"ham" }, { "weight":2.4, "value":45, name:"greaves" }, { "weight":4.0, "value":30, name:"flitch" }, { "weight":2.5, "value":56, name:"brawn" }, { "weight":3.7, "value":67, name:"welt" }, { "weight":3.0, "value":95, name:"salami" }, { "weight":5.9, "value":98, name:"sausage" }], 10)` should return `257.875`.
|
||||
|
||||
```js
|
||||
assert.equal(
|
||||
knapContinuous(
|
||||
[
|
||||
{ weight: 3.8, value: 36, name: 'beef' },
|
||||
{ weight: 5.4, value: 43, name: 'pork' },
|
||||
{ weight: 3.6, value: 90, name: 'ham' },
|
||||
{ weight: 2.4, value: 45, name: 'greaves' },
|
||||
{ weight: 4.0, value: 30, name: 'flitch' },
|
||||
{ weight: 2.5, value: 56, name: 'brawn' },
|
||||
{ weight: 3.7, value: 67, name: 'welt' },
|
||||
{ weight: 3.0, value: 95, name: 'salami' },
|
||||
{ weight: 5.9, value: 98, name: 'sausage' }
|
||||
],
|
||||
10
|
||||
),
|
||||
257.875
|
||||
);
|
||||
```
|
||||
|
||||
`knapContinuous([{ "weight":3.8, "value":36, name:"beef" }, { "weight":5.4, "value":43, name:"pork" }, { "weight":3.6, "value":90, name:"ham" }, { "weight":2.4, "value":45, name:"greaves" }, { "weight":4.0, "value":30, name:"flitch" }, { "weight":2.5, "value":56, name:"brawn" }, { "weight":3.7, "value":67, name:"welt" }, { "weight":3.0, "value":95, name:"salami" }, { "weight":5.9, "value":98, name:"sausage" }], 12)` should return `295.05405405405406`.
|
||||
|
||||
```js
|
||||
assert.equal(
|
||||
knapContinuous(
|
||||
[
|
||||
{ weight: 3.8, value: 36, name: 'beef' },
|
||||
{ weight: 5.4, value: 43, name: 'pork' },
|
||||
{ weight: 3.6, value: 90, name: 'ham' },
|
||||
{ weight: 2.4, value: 45, name: 'greaves' },
|
||||
{ weight: 4.0, value: 30, name: 'flitch' },
|
||||
{ weight: 2.5, value: 56, name: 'brawn' },
|
||||
{ weight: 3.7, value: 67, name: 'welt' },
|
||||
{ weight: 3.0, value: 95, name: 'salami' },
|
||||
{ weight: 5.9, value: 98, name: 'sausage' }
|
||||
],
|
||||
12
|
||||
),
|
||||
295.05405405405406
|
||||
);
|
||||
```
|
||||
|
||||
`knapContinuous([{ "weight":3.8, "value":36, name:"beef" }, { "weight":5.4, "value":43, name:"pork" }, { "weight":3.6, "value":90, name:"ham" }, { "weight":2.4, "value":45, name:"greaves" }, { "weight":4.0, "value":30, name:"flitch" }, { "weight":2.5, "value":56, name:"brawn" }, { "weight":3.7, "value":67, name:"welt" }, { "weight":3.0, "value":95, name:"salami" }, { "weight":5.9, "value":98, name:"sausage" }], 15)` should return `349.3783783783784`.
|
||||
|
||||
```js
|
||||
assert.equal(
|
||||
knapContinuous(
|
||||
[
|
||||
{ weight: 3.8, value: 36, name: 'beef' },
|
||||
{ weight: 5.4, value: 43, name: 'pork' },
|
||||
{ weight: 3.6, value: 90, name: 'ham' },
|
||||
{ weight: 2.4, value: 45, name: 'greaves' },
|
||||
{ weight: 4.0, value: 30, name: 'flitch' },
|
||||
{ weight: 2.5, value: 56, name: 'brawn' },
|
||||
{ weight: 3.7, value: 67, name: 'welt' },
|
||||
{ weight: 3.0, value: 95, name: 'salami' },
|
||||
{ weight: 5.9, value: 98, name: 'sausage' }
|
||||
],
|
||||
15
|
||||
),
|
||||
349.3783783783784
|
||||
);
|
||||
```
|
||||
|
||||
`knapContinuous([{ "weight":3.8, "value":36, name:"beef" }, { "weight":5.4, "value":43, name:"pork" }, { "weight":3.6, "value":90, name:"ham" }, { "weight":2.4, "value":45, name:"greaves" }, { "weight":4.0, "value":30, name:"flitch" }, { "weight":2.5, "value":56, name:"brawn" }, { "weight":3.7, "value":67, name:"welt" }, { "weight":3.0, "value":95, name:"salami" }, { "weight":5.9, "value":98, name:"sausage" }], 22)` should return `459.5263157894737`.
|
||||
|
||||
```js
|
||||
assert.equal(
|
||||
knapContinuous(
|
||||
[
|
||||
{ weight: 3.8, value: 36, name: 'beef' },
|
||||
{ weight: 5.4, value: 43, name: 'pork' },
|
||||
{ weight: 3.6, value: 90, name: 'ham' },
|
||||
{ weight: 2.4, value: 45, name: 'greaves' },
|
||||
{ weight: 4.0, value: 30, name: 'flitch' },
|
||||
{ weight: 2.5, value: 56, name: 'brawn' },
|
||||
{ weight: 3.7, value: 67, name: 'welt' },
|
||||
{ weight: 3.0, value: 95, name: 'salami' },
|
||||
{ weight: 5.9, value: 98, name: 'sausage' }
|
||||
],
|
||||
22
|
||||
),
|
||||
459.5263157894737
|
||||
);
|
||||
```
|
||||
|
||||
`knapContinuous([{ "weight":3.8, "value":36, name:"beef" }, { "weight":5.4, "value":43, name:"pork" }, { "weight":3.6, "value":90, name:"ham" }, { "weight":2.4, "value":45, name:"greaves" }, { "weight":4.0, "value":30, name:"flitch" }, { "weight":2.5, "value":56, name:"brawn" }, { "weight":3.7, "value":67, name:"welt" }, { "weight":3.0, "value":95, name:"salami" }, { "weight":5.9, "value":98, name:"sausage" }], 24)` should return `478.4736842105263`.
|
||||
|
||||
```js
|
||||
assert.equal(
|
||||
knapContinuous(
|
||||
[
|
||||
{ weight: 3.8, value: 36, name: 'beef' },
|
||||
{ weight: 5.4, value: 43, name: 'pork' },
|
||||
{ weight: 3.6, value: 90, name: 'ham' },
|
||||
{ weight: 2.4, value: 45, name: 'greaves' },
|
||||
{ weight: 4.0, value: 30, name: 'flitch' },
|
||||
{ weight: 2.5, value: 56, name: 'brawn' },
|
||||
{ weight: 3.7, value: 67, name: 'welt' },
|
||||
{ weight: 3.0, value: 95, name: 'salami' },
|
||||
{ weight: 5.9, value: 98, name: 'sausage' }
|
||||
],
|
||||
24
|
||||
),
|
||||
478.4736842105263
|
||||
);
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```js
|
||||
function knapContinuous(items, maxweight) {
|
||||
|
||||
}
|
||||
```
|
||||
|
||||
# --solutions--
|
||||
|
||||
```js
|
||||
function knapContinuous(items, maxweight) {
|
||||
function item_cmp(a, b) {
|
||||
const ua = a.unitVal,
|
||||
ub = b.unitVal;
|
||||
return ua < ub ? 1 : ua > ub ? -1 : 0;
|
||||
}
|
||||
items = items.map(({ value, weight }) => ({
|
||||
unitVal: value / weight,
|
||||
weight
|
||||
}));
|
||||
items.sort(item_cmp);
|
||||
|
||||
let val = 0;
|
||||
let wt = 0;
|
||||
for (let { unitVal, weight } of items) {
|
||||
var portion = Math.min(maxweight - wt, weight);
|
||||
wt += portion;
|
||||
var addVal = portion * unitVal;
|
||||
val += addVal;
|
||||
if (wt >= maxweight) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
return val;
|
||||
}
|
||||
```
|
@ -0,0 +1,155 @@
|
||||
---
|
||||
id: 5a23c84252665b21eecc7ed4
|
||||
title: Knapsack problem/Unbounded
|
||||
challengeType: 5
|
||||
forumTopicId: 323655
|
||||
dashedName: knapsack-problemunbounded
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
A traveler gets diverted and has to make an unscheduled stop in what turns out to be Shangri-La. Opting to leave, he is allowed to take as much as he likes of the items available there, so long as it will fit in his knapsack, and he can carry it.
|
||||
|
||||
He knows that he can carry no more than a particular value of maximum weight in total; and that the capacity of his knapsack has a limited volume.
|
||||
|
||||
Looking just above the bar codes on the items he finds their weights and volumes. He digs out his recent copy of a financial paper and gets the value of each item.
|
||||
|
||||
He can only take whole units of any item, but there is much more of any item than he could ever carry.
|
||||
|
||||
# --instructions--
|
||||
|
||||
Write a function that takes an array of objects, maximum weight, and maximum volume as parameters. Each object has 4 attributes: name, value, weight, and volume. The function should return the maximum value of items the traveller can take with him.
|
||||
|
||||
# --hints--
|
||||
|
||||
`knapsackUnbounded([{ name:"panacea", value:3000, weight:0.3, volume:0.025 }, { name:"ichor", value:1800, weight:0.2, volume:0.015 }, { name:"gold", value:2500, weight:2, volume:0.002 }], 25, 0.25)` should return `54500`.
|
||||
|
||||
```js
|
||||
assert.equal(
|
||||
knapsackUnbounded(
|
||||
[
|
||||
{ name: 'panacea', value: 3000, weight: 0.3, volume: 0.025 },
|
||||
{ name: 'ichor', value: 1800, weight: 0.2, volume: 0.015 },
|
||||
{ name: 'gold', value: 2500, weight: 2, volume: 0.002 }
|
||||
],
|
||||
25,
|
||||
0.25
|
||||
),
|
||||
54500
|
||||
);
|
||||
```
|
||||
|
||||
`knapsackUnbounded([{ name:"panacea", value:3000, weight:0.3, volume:0.025 }, { name:"ichor", value:1800, weight:0.2, volume:0.015 }, { name:"gold", value:2500, weight:2, volume:0.002 }], 55, 0.25)` should return `88400`.
|
||||
|
||||
```js
|
||||
assert.equal(
|
||||
knapsackUnbounded(
|
||||
[
|
||||
{ name: 'panacea', value: 3000, weight: 0.3, volume: 0.025 },
|
||||
{ name: 'ichor', value: 1800, weight: 0.2, volume: 0.015 },
|
||||
{ name: 'gold', value: 2500, weight: 2, volume: 0.002 }
|
||||
],
|
||||
55,
|
||||
0.25
|
||||
),
|
||||
88400
|
||||
);
|
||||
```
|
||||
|
||||
`knapsackUnbounded([{ name:"panacea", value:3000, weight:0.3, volume:0.025 }, { name:"ichor", value:1800, weight:0.2, volume:0.015 }, { name:"gold", value:2500, weight:2, volume:0.002 }], 25, 0.15)` should return `42500`.
|
||||
|
||||
```js
|
||||
assert.equal(
|
||||
knapsackUnbounded(
|
||||
[
|
||||
{ name: 'panacea', value: 3000, weight: 0.3, volume: 0.025 },
|
||||
{ name: 'ichor', value: 1800, weight: 0.2, volume: 0.015 },
|
||||
{ name: 'gold', value: 2500, weight: 2, volume: 0.002 }
|
||||
],
|
||||
25,
|
||||
0.15
|
||||
),
|
||||
42500
|
||||
);
|
||||
```
|
||||
|
||||
`knapsackUnbounded([{ name:"panacea", value:3000, weight:0.3, volume:0.025 }, { name:"ichor", value:1800, weight:0.2, volume:0.015 }, { name:"gold", value:2500, weight:2, volume:0.002 }], 35, 0.35)` should return `75300`.
|
||||
|
||||
```js
|
||||
assert.equal(
|
||||
knapsackUnbounded(
|
||||
[
|
||||
{ name: 'panacea', value: 3000, weight: 0.3, volume: 0.025 },
|
||||
{ name: 'ichor', value: 1800, weight: 0.2, volume: 0.015 },
|
||||
{ name: 'gold', value: 2500, weight: 2, volume: 0.002 }
|
||||
],
|
||||
35,
|
||||
0.35
|
||||
),
|
||||
75300
|
||||
);
|
||||
```
|
||||
|
||||
`knapsackUnbounded([{ name:"panacea", value:3000, weight:0.3, volume:0.025 }, { name:"ichor", value:1800, weight:0.2, volume:0.015 }, { name:"gold", value:2500, weight:2, volume:0.002 }], 15, 0.25)` should return `43200`.
|
||||
|
||||
```js
|
||||
assert.equal(
|
||||
knapsackUnbounded(
|
||||
[
|
||||
{ name: 'panacea', value: 3000, weight: 0.3, volume: 0.025 },
|
||||
{ name: 'ichor', value: 1800, weight: 0.2, volume: 0.015 },
|
||||
{ name: 'gold', value: 2500, weight: 2, volume: 0.002 }
|
||||
],
|
||||
15,
|
||||
0.25
|
||||
),
|
||||
43200
|
||||
);
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```js
|
||||
function knapsackUnbounded(items, maxweight, maxvolume) {
|
||||
|
||||
}
|
||||
```
|
||||
|
||||
# --solutions--
|
||||
|
||||
```js
|
||||
function knapsackUnbounded(items, maxweight, maxvolume) {
|
||||
var n = items.length;
|
||||
var best_value = 0;
|
||||
var count = new Array(n);
|
||||
var best = new Array(n);
|
||||
function recurseKnapsack(i, value, weight, volume) {
|
||||
var j, m1, m2, m;
|
||||
if (i == n) {
|
||||
if (value > best_value) {
|
||||
best_value = value;
|
||||
for (j = 0; j < n; j++) {
|
||||
best[j] = count[j];
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
m1 = Math.floor(weight / items[i].weight);
|
||||
m2 = Math.floor(volume / items[i].volume);
|
||||
m = m1 < m2 ? m1 : m2;
|
||||
for (count[i] = m; count[i] >= 0; count[i]--) {
|
||||
recurseKnapsack(
|
||||
i + 1,
|
||||
value + count[i] * items[i].value,
|
||||
weight - count[i] * items[i].weight,
|
||||
volume - count[i] * items[i].volume
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
recurseKnapsack(0, 0, maxweight, maxvolume);
|
||||
return best_value;
|
||||
}
|
||||
```
|
@ -0,0 +1,154 @@
|
||||
---
|
||||
id: 5a23c84252665b21eecc7ed5
|
||||
title: Knight's tour
|
||||
challengeType: 5
|
||||
forumTopicId: 302297
|
||||
dashedName: knights-tour
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
[Knight's Tour](https://en.wikipedia.org/wiki/Knight%27s_tour)Problem: You have an empty `w` \* `h` chessboard, but for a single knight on some square. The knight must perform a sequence of legal moves that result in the knight visiting every square on the chessboard exactly once. Note that it is *not* a requirement that the tour be "closed"; that is, the knight need not end within a single move of its start position.
|
||||
|
||||
# --instructions--
|
||||
|
||||
Write a function that takes `w` and `h` as parameters and returns the number of initial positions from where it is possible to achieve the task stated above.
|
||||
|
||||
# --hints--
|
||||
|
||||
`knightTour` should be a function.
|
||||
|
||||
```js
|
||||
assert(typeof knightTour == 'function');
|
||||
```
|
||||
|
||||
`knightTour(6, 6)` should return a number.
|
||||
|
||||
```js
|
||||
assert(typeof knightTour(6, 6) == 'number');
|
||||
```
|
||||
|
||||
`knightTour(6, 6)` should return `35`.
|
||||
|
||||
```js
|
||||
assert.equal(knightTour(6, 6), 35);
|
||||
```
|
||||
|
||||
`knightTour(5, 6)` should return `20`.
|
||||
|
||||
```js
|
||||
assert.equal(knightTour(5, 6), 20);
|
||||
```
|
||||
|
||||
`knightTour(4, 6)` should return `10`.
|
||||
|
||||
```js
|
||||
assert.equal(knightTour(4, 6), 10);
|
||||
```
|
||||
|
||||
`knightTour(7, 3)` should return `4`.
|
||||
|
||||
```js
|
||||
assert.equal(knightTour(7, 3), 4);
|
||||
```
|
||||
|
||||
`knightTour(8, 6)` should return `47`.
|
||||
|
||||
```js
|
||||
assert.equal(knightTour(8, 6), 47);
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```js
|
||||
function knightTour(w, h) {
|
||||
|
||||
}
|
||||
```
|
||||
|
||||
# --solutions--
|
||||
|
||||
```js
|
||||
function knightTour(w, h) {
|
||||
var b,
|
||||
cnt = 0;
|
||||
|
||||
var dx = [-2, -2, -1, 1, 2, 2, 1, -1];
|
||||
var dy = [-1, 1, 2, 2, 1, -1, -2, -2];
|
||||
|
||||
function init_board() {
|
||||
var i, j, k, x, y;
|
||||
// * b is board; a is board with 2 rows padded at each side
|
||||
|
||||
for (i = 0; i < h; i++) {
|
||||
for (j = 0; j < w; j++) {
|
||||
b[i][j] = 255;
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < h; i++) {
|
||||
for (j = 0; j < w; j++) {
|
||||
for (k = 0; k < 8; k++) {
|
||||
(x = j + dx[k]), (y = i + dy[k]);
|
||||
if (b[i][j] == 255) b[i][j] = 0;
|
||||
if (x >= 0 && x < w && y >= 0 && y < h) b[i][j]++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function walk_board(x, y) {
|
||||
var i, nx, ny, least;
|
||||
var steps = 0;
|
||||
// printf(E"H"E"J"E"%d;%dH"E"32m[]"E"m", y + 1, 1 + 2 * x);
|
||||
|
||||
while (1) {
|
||||
// * occupy cell
|
||||
b[y][x] = 255;
|
||||
|
||||
// * reduce all neighbors' neighbor count
|
||||
for (i = 0; i < 8; i++)
|
||||
if (y + dy[i] >= 0 && x + dx[i] >= 0 && y + dy[i] < h && x + dx[i] < w)
|
||||
b[y + dy[i]][x + dx[i]]--;
|
||||
|
||||
// find neighbor with lowest neighbor count
|
||||
least = 255;
|
||||
for (i = 0; i < 8; i++) {
|
||||
if (y + dy[i] >= 0 && x + dx[i] >= 0 && y + dy[i] < h && x + dx[i] < w)
|
||||
if (b[y + dy[i]][x + dx[i]] < least) {
|
||||
nx = x + dx[i];
|
||||
ny = y + dy[i];
|
||||
least = b[ny][nx];
|
||||
}
|
||||
}
|
||||
|
||||
if (least > 7) {
|
||||
return steps == w * h - 1;
|
||||
}
|
||||
|
||||
steps++;
|
||||
(x = nx), (y = ny);
|
||||
}
|
||||
}
|
||||
|
||||
function solve(x, y) {
|
||||
b = new Array(h);
|
||||
for (var i = 0; i < h; i++) b[i] = new Array(w);
|
||||
|
||||
init_board();
|
||||
if (walk_board(x, y)) {
|
||||
cnt++;
|
||||
}
|
||||
}
|
||||
|
||||
for (var i = 0; i < h; i++) {
|
||||
for (var j = 0; j < w; j++) {
|
||||
solve(j, i);
|
||||
}
|
||||
}
|
||||
|
||||
return cnt;
|
||||
}
|
||||
```
|
@ -0,0 +1,85 @@
|
||||
---
|
||||
id: 5a23c84252665b21eecc7edb
|
||||
title: Largest int from concatenated ints
|
||||
challengeType: 5
|
||||
forumTopicId: 302298
|
||||
dashedName: largest-int-from-concatenated-ints
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
Given a set of positive integers, write a function to order the integers in such a way that the concatenation of the numbers forms the largest possible integer and return this integer.
|
||||
|
||||
# --hints--
|
||||
|
||||
`maxCombine` should be a function.
|
||||
|
||||
```js
|
||||
assert(typeof maxCombine == 'function');
|
||||
```
|
||||
|
||||
`maxCombine([1, 3, 3, 4, 55])` should return a number.
|
||||
|
||||
```js
|
||||
assert(typeof maxCombine([1, 3, 3, 4, 55]) == 'number');
|
||||
```
|
||||
|
||||
`maxCombine([1, 3, 3, 4, 55])` should return `554331`.
|
||||
|
||||
```js
|
||||
assert.equal(maxCombine([1, 3, 3, 4, 55]), 554331);
|
||||
```
|
||||
|
||||
`maxCombine([71, 45, 23, 4, 5])` should return `71545423`.
|
||||
|
||||
```js
|
||||
assert.equal(maxCombine([71, 45, 23, 4, 5]), 71545423);
|
||||
```
|
||||
|
||||
`maxCombine([14, 43, 53, 114, 55])` should return `55534314114`.
|
||||
|
||||
```js
|
||||
assert.equal(maxCombine([14, 43, 53, 114, 55]), 55534314114);
|
||||
```
|
||||
|
||||
`maxCombine([1, 34, 3, 98, 9, 76, 45, 4])` should return `998764543431`.
|
||||
|
||||
```js
|
||||
assert.equal(maxCombine([1, 34, 3, 98, 9, 76, 45, 4]), 998764543431);
|
||||
```
|
||||
|
||||
`maxCombine([54, 546, 548, 60])` should return `6054854654`.
|
||||
|
||||
```js
|
||||
assert.equal(maxCombine([54, 546, 548, 60]), 6054854654);
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```js
|
||||
function maxCombine(xs) {
|
||||
|
||||
}
|
||||
```
|
||||
|
||||
# --solutions--
|
||||
|
||||
```js
|
||||
function maxCombine(xs) {
|
||||
return parseInt(
|
||||
xs
|
||||
.sort(function(x, y) {
|
||||
var a = x.toString(),
|
||||
b = y.toString(),
|
||||
ab = parseInt(a + b),
|
||||
ba = parseInt(b + a);
|
||||
|
||||
return ab > ba ? -1 : ab < ba ? 1 : 0;
|
||||
})
|
||||
.join(''),
|
||||
10
|
||||
);
|
||||
}
|
||||
```
|
@ -0,0 +1,99 @@
|
||||
---
|
||||
id: 5a23c84252665b21eecc7edc
|
||||
title: Last Friday of each month
|
||||
challengeType: 5
|
||||
forumTopicId: 302299
|
||||
dashedName: last-friday-of-each-month
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
Write a function that returns the date of the last Friday of a given month for a given year.
|
||||
|
||||
# --hints--
|
||||
|
||||
`lastFriday` should be a function.
|
||||
|
||||
```js
|
||||
assert(typeof lastFriday == 'function');
|
||||
```
|
||||
|
||||
`lastFriday(2018, 1)` should return a number.
|
||||
|
||||
```js
|
||||
assert(typeof lastFriday(2018, 1) == 'number');
|
||||
```
|
||||
|
||||
`lastFriday(2018, 1)` should return `26`.
|
||||
|
||||
```js
|
||||
assert.equal(lastFriday(2018, 1), 26);
|
||||
```
|
||||
|
||||
`lastFriday(2017, 2)` should return `24`.
|
||||
|
||||
```js
|
||||
assert.equal(lastFriday(2017, 2), 24);
|
||||
```
|
||||
|
||||
`lastFriday(2012, 3)` should return `30`.
|
||||
|
||||
```js
|
||||
assert.equal(lastFriday(2012, 3), 30);
|
||||
```
|
||||
|
||||
`lastFriday(1900, 4)` should return `27`.
|
||||
|
||||
```js
|
||||
assert.equal(lastFriday(1900, 4), 27);
|
||||
```
|
||||
|
||||
`lastFriday(2000, 5)` should return `26`.
|
||||
|
||||
```js
|
||||
assert.equal(lastFriday(2000, 5), 26);
|
||||
```
|
||||
|
||||
`lastFriday(2006, 6)` should return `30`.
|
||||
|
||||
```js
|
||||
assert.equal(lastFriday(2006, 6), 30);
|
||||
```
|
||||
|
||||
`lastFriday(2010, 7)` should return `30`.
|
||||
|
||||
```js
|
||||
assert.equal(lastFriday(2010, 7), 30);
|
||||
```
|
||||
|
||||
`lastFriday(2005, 8)` should return `26`.
|
||||
|
||||
```js
|
||||
assert.equal(lastFriday(2005, 8), 26);
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```js
|
||||
function lastFriday(year, month) {
|
||||
|
||||
}
|
||||
```
|
||||
|
||||
# --solutions--
|
||||
|
||||
```js
|
||||
function lastFriday(year, month) {
|
||||
var i, last_day;
|
||||
i = 0;
|
||||
while (true) {
|
||||
last_day = new Date(year, month, i);
|
||||
if (last_day.getDay() === 5) {
|
||||
return last_day.getDate();
|
||||
}
|
||||
i -= 1;
|
||||
}
|
||||
}
|
||||
```
|
@ -0,0 +1,211 @@
|
||||
---
|
||||
id: 5e4ce2b6ac708cc68c1df25e
|
||||
title: Last letter-first letter
|
||||
challengeType: 5
|
||||
forumTopicId: 385256
|
||||
dashedName: last-letter-first-letter
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
A certain children's game involves starting with a word in a particular category. Each participant in turn says a word, but that word must begin with the final letter of the previous word. Once a word has been given, it cannot be repeated. If an opponent cannot give a word in the category, they fall out of the game.
|
||||
|
||||
For example, with "animals" as the category,
|
||||
|
||||
<pre>Child 1: dog
|
||||
Child 2: goldfish
|
||||
Child 1: hippopotamus
|
||||
Child 2: snake
|
||||
...
|
||||
</pre>
|
||||
|
||||
# --instructions--
|
||||
|
||||
Write a function that takes an input array of words. The function should return an array of words where the first letter of each word is the same as the last letter of the previous word. Only use the words in the input array, and once a word is used it cannot be repeated. The words in the return array should be selected and sequenced so that that its length is maximized.
|
||||
|
||||
# --hints--
|
||||
|
||||
`findLongestChain` should be a function.
|
||||
|
||||
```js
|
||||
assert(typeof findLongestChain == 'function');
|
||||
```
|
||||
|
||||
`findLongestChain(["certain", "each", "game", "involves", "starting", "with", "word"])` should return an array.
|
||||
|
||||
```js
|
||||
assert(
|
||||
Array.isArray(
|
||||
findLongestChain([
|
||||
'certain',
|
||||
'each',
|
||||
'game',
|
||||
'involves',
|
||||
'starting',
|
||||
'with',
|
||||
'word'
|
||||
])
|
||||
)
|
||||
);
|
||||
```
|
||||
|
||||
`findLongestChain(["certain", "each", "game", "involves", "starting", "with", "word"])` should return `["involves", "starting", "game", "each"]`.
|
||||
|
||||
```js
|
||||
assert.deepEqual(
|
||||
findLongestChain([
|
||||
'certain',
|
||||
'each',
|
||||
'game',
|
||||
'involves',
|
||||
'starting',
|
||||
'with',
|
||||
'word'
|
||||
]),
|
||||
['involves', 'starting', 'game', 'each']
|
||||
);
|
||||
```
|
||||
|
||||
`findLongestChain(["audino", "bagon", "kangaskhan", "banette", "bidoof", "braviary", "exeggcute", "yamask"])` should return `["braviary", "yamask", "kangaskhan"]`
|
||||
|
||||
```js
|
||||
assert.deepEqual(
|
||||
findLongestChain([
|
||||
'audino',
|
||||
'bagon',
|
||||
'kangaskhan',
|
||||
'banette',
|
||||
'bidoof',
|
||||
'braviary',
|
||||
'exeggcute',
|
||||
'yamask'
|
||||
]),
|
||||
['braviary', 'yamask', 'kangaskhan']
|
||||
);
|
||||
```
|
||||
|
||||
`findLongestChain(["harp", "poliwrath", "poochyena", "porygon2", "porygonz", "archana"])` should return `["poliwrath", "harp", "poochyena", "archana"]`.
|
||||
|
||||
```js
|
||||
assert.deepEqual(
|
||||
findLongestChain([
|
||||
'harp',
|
||||
'poliwrath',
|
||||
'poochyena',
|
||||
'porygon2',
|
||||
'porygonz',
|
||||
'archana'
|
||||
]),
|
||||
['poliwrath', 'harp', 'poochyena', 'archana']
|
||||
);
|
||||
```
|
||||
|
||||
`findLongestChain(["scolipede", "elephant", "zeaking", "sealeo", "silcoon", "tigers"])` should return `["scolipede", "elephant", "tigers", "sealeo"]`.
|
||||
|
||||
```js
|
||||
assert.deepEqual(
|
||||
findLongestChain([
|
||||
'scolipede',
|
||||
'elephant',
|
||||
'zeaking',
|
||||
'sealeo',
|
||||
'silcoon',
|
||||
'tigers'
|
||||
]),
|
||||
['scolipede', 'elephant', 'tigers', 'sealeo']
|
||||
);
|
||||
```
|
||||
|
||||
`findLongestChain(["loudred", "lumineon", "lunatone", "machamp", "magnezone", "nosepass", "petilil", "pidgeotto", "pikachu"])` should return `["machamp", "petilil", "lumineon", "nosepass"]`.
|
||||
|
||||
```js
|
||||
assert.deepEqual(
|
||||
findLongestChain([
|
||||
'loudred',
|
||||
'lumineon',
|
||||
'lunatone',
|
||||
'machamp',
|
||||
'magnezone',
|
||||
'nosepass',
|
||||
'petilil',
|
||||
'pidgeotto',
|
||||
'pikachu'
|
||||
]),
|
||||
['machamp', 'petilil', 'lumineon', 'nosepass']
|
||||
);
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```js
|
||||
function findLongestChain(items) {
|
||||
|
||||
}
|
||||
```
|
||||
|
||||
# --solutions--
|
||||
|
||||
```js
|
||||
function findLongestChain(items) {
|
||||
function Ref(index, first_char, last_char) {
|
||||
this.index = index;
|
||||
this.first_char = first_char;
|
||||
this.last_char = last_char;
|
||||
}
|
||||
|
||||
var items_len = items.length
|
||||
var refs_len = items_len;
|
||||
var refs = []
|
||||
|
||||
// enough space for all items
|
||||
var longest_path_refs_len = 0;
|
||||
var longest_path_refs = new Array(items_len);
|
||||
|
||||
function search(curr_len) {
|
||||
if (curr_len > longest_path_refs_len) {
|
||||
longest_path_refs_len = curr_len;
|
||||
|
||||
for (var i = 0; i < curr_len; i++) {
|
||||
longest_path_refs[i] = refs[i];
|
||||
}
|
||||
}
|
||||
|
||||
// recursive search
|
||||
var last_char = refs[curr_len - 1].last_char;
|
||||
for (var i = curr_len; i < refs_len; i++)
|
||||
if (refs[i].first_char == last_char) {
|
||||
var aux = refs[curr_len];
|
||||
refs[curr_len] = refs[i];
|
||||
refs[i] = aux;
|
||||
search(curr_len + 1);
|
||||
refs[i] = refs[curr_len];
|
||||
refs[curr_len] = aux;
|
||||
}
|
||||
}
|
||||
|
||||
for (var i = 0; i < items_len; i++) {
|
||||
var itemsi_len = items[i].length;
|
||||
refs.push(new Ref(i, items[i][0], items[i][itemsi_len - 1]));
|
||||
}
|
||||
|
||||
// try each item as possible start
|
||||
for (var i = 0; i < items_len; i++) {
|
||||
var aux = refs[0];
|
||||
refs[0] = refs[i];
|
||||
refs[i] = aux;
|
||||
search(1);
|
||||
refs[i] = refs[0];
|
||||
refs[0] = aux;
|
||||
}
|
||||
|
||||
var longest_path_len = longest_path_refs_len;
|
||||
var longest_path = new Array(longest_path_len);
|
||||
|
||||
for (var i = 0; i < longest_path_len; i++)
|
||||
longest_path[i] = items[longest_path_refs[i].index];
|
||||
|
||||
return longest_path;
|
||||
}
|
||||
```
|
@ -0,0 +1,79 @@
|
||||
---
|
||||
id: 5a23c84252665b21eecc7ede
|
||||
title: Leap year
|
||||
challengeType: 5
|
||||
forumTopicId: 302300
|
||||
dashedName: leap-year
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
Determine whether a given year is a leap year in the Gregorian calendar.
|
||||
|
||||
# --hints--
|
||||
|
||||
`isLeapYear` should be a function.
|
||||
|
||||
```js
|
||||
assert(typeof isLeapYear == 'function');
|
||||
```
|
||||
|
||||
`isLeapYear()` should return a boolean.
|
||||
|
||||
```js
|
||||
assert(typeof isLeapYear(2018) == 'boolean');
|
||||
```
|
||||
|
||||
`isLeapYear(2018)` should return `false`.
|
||||
|
||||
```js
|
||||
assert.equal(isLeapYear(2018), false);
|
||||
```
|
||||
|
||||
`isLeapYear(2016)` should return `true`.
|
||||
|
||||
```js
|
||||
assert.equal(isLeapYear(2016), true);
|
||||
```
|
||||
|
||||
`isLeapYear(2000)` should return `true`.
|
||||
|
||||
```js
|
||||
assert.equal(isLeapYear(2000), true);
|
||||
```
|
||||
|
||||
`isLeapYear(1900)` should return `false`.
|
||||
|
||||
```js
|
||||
assert.equal(isLeapYear(1900), false);
|
||||
```
|
||||
|
||||
`isLeapYear(1996)` should return `true`.
|
||||
|
||||
```js
|
||||
assert.equal(isLeapYear(1996), true);
|
||||
```
|
||||
|
||||
`isLeapYear(1800)` should return `false`.
|
||||
|
||||
```js
|
||||
assert.equal(isLeapYear(1800), false);
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```js
|
||||
function isLeapYear(year) {
|
||||
|
||||
}
|
||||
```
|
||||
|
||||
# --solutions--
|
||||
|
||||
```js
|
||||
function isLeapYear(year) {
|
||||
return year % 100 === 0 ? year % 400 === 0 : year % 4 === 0;
|
||||
}
|
||||
```
|
@ -0,0 +1,87 @@
|
||||
---
|
||||
id: 5a23c84252665b21eecc7edf
|
||||
title: Least common multiple
|
||||
challengeType: 5
|
||||
forumTopicId: 302301
|
||||
dashedName: least-common-multiple
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
The least common multiple of 12 and 18 is 36, because 12 is a factor (12 × 3 = 36), and 18 is a factor (18 × 2 = 36), and there is no positive integer less than 36 that has both factors. As a special case, if either *m* or *n* is zero, then the least common multiple is zero. One way to calculate the least common multiple is to iterate all the multiples of *m*, until you find one that is also a multiple of *n*. If you already have *gcd* for [greatest common divisor](https://rosettacode.org/wiki/greatest common divisor), then this formula calculates *lcm*. ( \\operatorname{lcm}(m, n) = \\frac{|m \\times n|}{\\operatorname{gcd}(m, n)} )
|
||||
|
||||
# --instructions--
|
||||
|
||||
Compute the least common multiple of an array of integers. Given *m* and *n*, the least common multiple is the smallest positive integer that has both *m* and *n* as factors.
|
||||
|
||||
# --hints--
|
||||
|
||||
`LCM` should be a function.
|
||||
|
||||
```js
|
||||
assert(typeof LCM == 'function');
|
||||
```
|
||||
|
||||
`LCM([2, 4, 8])` should return a number.
|
||||
|
||||
```js
|
||||
assert(typeof LCM([2, 4, 8]) == 'number');
|
||||
```
|
||||
|
||||
`LCM([2, 4, 8])` should return `8`.
|
||||
|
||||
```js
|
||||
assert.equal(LCM([2, 4, 8]), 8);
|
||||
```
|
||||
|
||||
`LCM([4, 8, 12])` should return `24`.
|
||||
|
||||
```js
|
||||
assert.equal(LCM([4, 8, 12]), 24);
|
||||
```
|
||||
|
||||
`LCM([3, 4, 5, 12, 40])` should return `120`.
|
||||
|
||||
```js
|
||||
assert.equal(LCM([3, 4, 5, 12, 40]), 120);
|
||||
```
|
||||
|
||||
`LCM([11, 33, 90])` should return `990`.
|
||||
|
||||
```js
|
||||
assert.equal(LCM([11, 33, 90]), 990);
|
||||
```
|
||||
|
||||
`LCM([-50, 25, -45, -18, 90, 447])` should return `67050`.
|
||||
|
||||
```js
|
||||
assert.equal(LCM([-50, 25, -45, -18, 90, 447]), 67050);
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```js
|
||||
function LCM(A) {
|
||||
|
||||
}
|
||||
```
|
||||
|
||||
# --solutions--
|
||||
|
||||
```js
|
||||
function LCM(A) {
|
||||
var n = A.length,
|
||||
a = Math.abs(A[0]);
|
||||
for (var i = 1; i < n; i++) {
|
||||
var b = Math.abs(A[i]),
|
||||
c = a;
|
||||
while (a && b) {
|
||||
a > b ? (a %= b) : (b %= a);
|
||||
}
|
||||
a = Math.abs(c * A[i]) / (a + b);
|
||||
}
|
||||
return a;
|
||||
}
|
||||
```
|
@ -0,0 +1,115 @@
|
||||
---
|
||||
id: 5a23c84252665b21eecc7ee0
|
||||
title: Left factorials
|
||||
challengeType: 5
|
||||
forumTopicId: 302302
|
||||
dashedName: left-factorials
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
**Left factorials**, $ !n $, may refer to either *subfactorials* or to *factorial sums*. The same notation can be confusingly seen used for the two different definitions. Sometimes, *subfactorials* (also known as *derangements*) may use any of the notations:
|
||||
|
||||
<ul>
|
||||
<li>$!n`$</li>
|
||||
<li>$!n$</li>
|
||||
<li>$n¡$</li>
|
||||
</ul>
|
||||
|
||||
(It may not be visually obvious, but the last example uses an upside-down exclamation mark.) This task will be using this formula for **left factorial**:
|
||||
|
||||
$ !n = \\sum\_{k=0}^{n-1} k! $
|
||||
|
||||
where $!0 = 0$
|
||||
|
||||
# --instructions--
|
||||
|
||||
Write a function to calculate the left factorial of a given number.
|
||||
|
||||
# --hints--
|
||||
|
||||
`leftFactorial` should be a function.
|
||||
|
||||
```js
|
||||
assert(typeof leftFactorial == 'function');
|
||||
```
|
||||
|
||||
`leftFactorial(0)` should return a number.
|
||||
|
||||
```js
|
||||
assert(typeof leftFactorial(0) == 'number');
|
||||
```
|
||||
|
||||
`leftFactorial(0)` should return `0`.
|
||||
|
||||
```js
|
||||
assert.equal(leftFactorial(0), 0);
|
||||
```
|
||||
|
||||
`leftFactorial(1)` should return `1`.
|
||||
|
||||
```js
|
||||
assert.equal(leftFactorial(1), 1);
|
||||
```
|
||||
|
||||
`leftFactorial(2)` should return `2`.
|
||||
|
||||
```js
|
||||
assert.equal(leftFactorial(2), 2);
|
||||
```
|
||||
|
||||
`leftFactorial(3)` should return `4`.
|
||||
|
||||
```js
|
||||
assert.equal(leftFactorial(3), 4);
|
||||
```
|
||||
|
||||
`leftFactorial(10)` should return `409114`.
|
||||
|
||||
```js
|
||||
assert.equal(leftFactorial(10), 409114);
|
||||
```
|
||||
|
||||
`leftFactorial(17)` should return `22324392524314`.
|
||||
|
||||
```js
|
||||
assert.equal(leftFactorial(17), 22324392524314);
|
||||
```
|
||||
|
||||
`leftFactorial(19)` should return `6780385526348314`.
|
||||
|
||||
```js
|
||||
assert.equal(leftFactorial(19), 6780385526348314);
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```js
|
||||
function leftFactorial(n) {
|
||||
|
||||
}
|
||||
```
|
||||
|
||||
# --solutions--
|
||||
|
||||
```js
|
||||
function leftFactorial(n) {
|
||||
if (n == 0) return 0;
|
||||
if (n == 1) return 1;
|
||||
|
||||
// Note: for n>=20, the result may not be correct.
|
||||
// This is because JavaScript uses 53 bit integers and
|
||||
// for n>=20 result becomes too large.
|
||||
|
||||
let res = 2,
|
||||
fact = 2;
|
||||
for (var i = 2; i < n; i++) {
|
||||
res += fact;
|
||||
fact *= i + 1;
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
```
|
@ -0,0 +1,209 @@
|
||||
---
|
||||
id: 5e4ce2bbac708cc68c1df25f
|
||||
title: Letter frequency
|
||||
challengeType: 5
|
||||
forumTopicId: 385263
|
||||
dashedName: letter-frequency
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
Given a string, calculate the frequency of each character.
|
||||
|
||||
All characters should be counted. This includes lower and upper case letters, digits, whitespace, special characters, or any other distinct characters.
|
||||
|
||||
# --instructions--
|
||||
|
||||
Write a function to count the occurrences of each character in a given string.
|
||||
|
||||
The function should return a 2D array with each of the elements in the following form: `['char', freq]`. The character should be a string with a length of 1, and frequency is a number denoting the count.
|
||||
|
||||
For example, given the string "ab", your function should return `[['a', 1], ['b', 1]]`.
|
||||
|
||||
# --hints--
|
||||
|
||||
`letterFrequency` should be a function.
|
||||
|
||||
```js
|
||||
assert(typeof letterFrequency == 'function');
|
||||
```
|
||||
|
||||
`letterFrequency("Not all that Mrs. Bennet, however")` should return an array.
|
||||
|
||||
```js
|
||||
assert(Array.isArray(letterFrequency('Not all that Mrs. Bennet, however')));
|
||||
```
|
||||
|
||||
`letterFrequency("Not all that Mrs. Bennet, however")` should return `[[" ", 5], [", ", 1], [".", 1], ["B", 1], ["M", 1], ["N", 1], ["a", 2], ["e", 4], ["h", 2], ["l", 2], ["n", 2], ["o", 2], ["r", 2], ["s", 1], ["t", 4], ["v", 1], ["w", 1]]`.
|
||||
|
||||
```js
|
||||
assert.deepEqual(letterFrequency('Not all that Mrs. Bennet, however'), [
|
||||
[' ', 5],
|
||||
[',', 1],
|
||||
['.', 1],
|
||||
['B', 1],
|
||||
['M', 1],
|
||||
['N', 1],
|
||||
['a', 2],
|
||||
['e', 4],
|
||||
['h', 2],
|
||||
['l', 2],
|
||||
['n', 2],
|
||||
['o', 2],
|
||||
['r', 2],
|
||||
['s', 1],
|
||||
['t', 4],
|
||||
['v', 1],
|
||||
['w', 1]
|
||||
]);
|
||||
```
|
||||
|
||||
`letterFrequency("daughters, could ask on the ")` should return `[[' ',5],[',',1],['a',2],['c',1],['d',2],['e',2],['g',1],['h',2],['k',1],['l',1],['n',1],['o',2],['r',1],['s',2],['t',2],['u',2]]`.
|
||||
|
||||
```js
|
||||
assert.deepEqual(letterFrequency('daughters, could ask on the '), [
|
||||
[' ', 5],
|
||||
[',', 1],
|
||||
['a', 2],
|
||||
['c', 1],
|
||||
['d', 2],
|
||||
['e', 2],
|
||||
['g', 1],
|
||||
['h', 2],
|
||||
['k', 1],
|
||||
['l', 1],
|
||||
['n', 1],
|
||||
['o', 2],
|
||||
['r', 1],
|
||||
['s', 2],
|
||||
['t', 2],
|
||||
['u', 2]
|
||||
]);
|
||||
```
|
||||
|
||||
`letterFrequency("husband any satisfactory description")` should return `[[" ", 3], ["a", 4], ["b", 1], ["c", 2], ["d", 2], ["e", 1], ["f", 1], ["h", 1], ["i", 3], ["n", 3], ["o", 2], ["p", 1], ["r", 2], ["s", 4], ["t", 3], ["u", 1], ["y", 2]]`.
|
||||
|
||||
```js
|
||||
assert.deepEqual(letterFrequency('husband any satisfactory description'), [
|
||||
[' ', 3],
|
||||
['a', 4],
|
||||
['b', 1],
|
||||
['c', 2],
|
||||
['d', 2],
|
||||
['e', 1],
|
||||
['f', 1],
|
||||
['h', 1],
|
||||
['i', 3],
|
||||
['n', 3],
|
||||
['o', 2],
|
||||
['p', 1],
|
||||
['r', 2],
|
||||
['s', 4],
|
||||
['t', 3],
|
||||
['u', 1],
|
||||
['y', 2]
|
||||
]);
|
||||
```
|
||||
|
||||
`letterFrequency("in various ways--with barefaced")` should return `[[" ", 3], ["-", 2], ["a", 4], ["b", 1], ["c", 1], ["d", 1], ["e", 2], ["f", 1], ["h", 1], ["i", 3], ["n", 1], ["o", 1], ["r", 2], ["s", 2], ["t", 1], ["u", 1], ["v", 1], ["w", 2], ["y", 1]]`.
|
||||
|
||||
```js
|
||||
assert.deepEqual(letterFrequency('in various ways--with barefaced'), [
|
||||
[' ', 3],
|
||||
['-', 2],
|
||||
['a', 4],
|
||||
['b', 1],
|
||||
['c', 1],
|
||||
['d', 1],
|
||||
['e', 2],
|
||||
['f', 1],
|
||||
['h', 1],
|
||||
['i', 3],
|
||||
['n', 1],
|
||||
['o', 1],
|
||||
['r', 2],
|
||||
['s', 2],
|
||||
['t', 1],
|
||||
['u', 1],
|
||||
['v', 1],
|
||||
['w', 2],
|
||||
['y', 1]
|
||||
]);
|
||||
```
|
||||
|
||||
`letterFrequency("distant surmises; but he eluded")` should return `[[" ", 4], ["; ", 1], ["a", 1], ["b", 1], ["d", 3], ["e", 4], ["h", 1], ["i", 2], ["l", 1], ["m", 1], ["n", 1], ["r", 1], ["s", 4], ["t", 3], ["u", 3]]`.
|
||||
|
||||
```js
|
||||
assert.deepEqual(letterFrequency('distant surmises; but he eluded'), [
|
||||
[' ', 4],
|
||||
[';', 1],
|
||||
['a', 1],
|
||||
['b', 1],
|
||||
['d', 3],
|
||||
['e', 4],
|
||||
['h', 1],
|
||||
['i', 2],
|
||||
['l', 1],
|
||||
['m', 1],
|
||||
['n', 1],
|
||||
['r', 1],
|
||||
['s', 4],
|
||||
['t', 3],
|
||||
['u', 3]
|
||||
]);
|
||||
```
|
||||
|
||||
`letterFrequency("last obliged to accept the second-hand,")` should return `[[" ", 5], [", ", 1], ["-", 1], ["a", 3], ["b", 1], ["c", 3], ["d", 3], ["e", 4], ["g", 1], ["h", 2], ["i", 1], ["l", 2], ["n", 2], ["o", 3], ["p", 1], ["s", 2], ["t", 4]]`.
|
||||
|
||||
```js
|
||||
assert.deepEqual(letterFrequency('last obliged to accept the second-hand,'), [
|
||||
[' ', 5],
|
||||
[',', 1],
|
||||
['-', 1],
|
||||
['a', 3],
|
||||
['b', 1],
|
||||
['c', 3],
|
||||
['d', 3],
|
||||
['e', 4],
|
||||
['g', 1],
|
||||
['h', 2],
|
||||
['i', 1],
|
||||
['l', 2],
|
||||
['n', 2],
|
||||
['o', 3],
|
||||
['p', 1],
|
||||
['s', 2],
|
||||
['t', 4]
|
||||
]);
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```js
|
||||
function letterFrequency(txt) {
|
||||
|
||||
}
|
||||
```
|
||||
|
||||
# --solutions--
|
||||
|
||||
```js
|
||||
function letterFrequency(txt) {
|
||||
var cs = txt.split(''),
|
||||
i = cs.length,
|
||||
dct = {},
|
||||
c = '',
|
||||
keys;
|
||||
|
||||
while (i--) {
|
||||
c = cs[i];
|
||||
dct[c] = (dct[c] || 0) + 1;
|
||||
}
|
||||
|
||||
keys = Object.keys(dct);
|
||||
keys.sort();
|
||||
return keys.map(function (c) { return [c, dct[c]]; });
|
||||
}
|
||||
```
|
@ -0,0 +1,105 @@
|
||||
---
|
||||
id: 5e4ce2eaac708cc68c1df260
|
||||
title: Levenshtein distance
|
||||
challengeType: 5
|
||||
forumTopicId: 385264
|
||||
dashedName: levenshtein-distance
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
In information theory and computer science, the **Levenshtein distance** is a [metric](https://en.wikipedia.org/wiki/string metric) for measuring the amount of difference between two sequences (i.e. an [edit distance](https://en.wikipedia.org/wiki/edit distance)). The Levenshtein distance between two strings is defined as the minimum number of edits needed to transform one string into the other, with the allowable edit operations being insertion, deletion, or substitution of a single character.
|
||||
|
||||
Example:
|
||||
|
||||
The Levenshtein distance between "**kitten**" and "**sitting**" is 3, since the following three edits change one into the other, and there isn't a way to do it with fewer than three edits:
|
||||
|
||||
<ul>
|
||||
<li><strong>k</strong>itten <strong>s</strong>itten (substitution of 'k' with 's')</li>
|
||||
<li>sitt<strong>e</strong>n sitt<strong>i</strong>n (substitution of 'e' with 'i')</li>
|
||||
<li>sittin sittin<strong>g</strong> (insert 'g' at the end).</li>
|
||||
</ul>
|
||||
|
||||
*The Levenshtein distance between "**rosettacode**", "**raisethysword**" is **8**.*
|
||||
|
||||
*The distance between two strings is same as that when both strings are reversed.*
|
||||
|
||||
# --instructions--
|
||||
|
||||
Write a function that returns the Levenshtein distance between two strings given as parameters.
|
||||
|
||||
# --hints--
|
||||
|
||||
`levenshtein` should be a function.
|
||||
|
||||
```js
|
||||
assert(typeof levenshtein == 'function');
|
||||
```
|
||||
|
||||
`levenshtein("mist", "dist")` should return a number.
|
||||
|
||||
```js
|
||||
assert(typeof levenshtein('mist', 'dist') == 'number');
|
||||
```
|
||||
|
||||
`levenshtein("mist", "dist")` should return `1`.
|
||||
|
||||
```js
|
||||
assert.equal(levenshtein('mist', 'dist'), 1);
|
||||
```
|
||||
|
||||
`levenshtein("tier", "tor")` should return `2`.
|
||||
|
||||
```js
|
||||
assert.equal(levenshtein('tier', 'tor'), 2);
|
||||
```
|
||||
|
||||
`levenshtein("kitten", "sitting")` should return `3`.
|
||||
|
||||
```js
|
||||
assert.equal(levenshtein('kitten', 'sitting'), 3);
|
||||
```
|
||||
|
||||
`levenshtein("stop", "tops")` should return `2`.
|
||||
|
||||
```js
|
||||
assert.equal(levenshtein('stop', 'tops'), 2);
|
||||
```
|
||||
|
||||
`levenshtein("rosettacode", "raisethysword")` should return `8`.
|
||||
|
||||
```js
|
||||
assert.equal(levenshtein('rosettacode', 'raisethysword'), 8);
|
||||
```
|
||||
|
||||
`levenshtein("mississippi", "swiss miss")` should return `8`.
|
||||
|
||||
```js
|
||||
assert.equal(levenshtein('mississippi', 'swiss miss'), 8);
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```js
|
||||
function levenshtein(a, b) {
|
||||
|
||||
}
|
||||
```
|
||||
|
||||
# --solutions--
|
||||
|
||||
```js
|
||||
function levenshtein(a, b) {
|
||||
var t = [], u, i, j, m = a.length, n = b.length;
|
||||
if (!m) { return n; }
|
||||
if (!n) { return m; }
|
||||
for (j = 0; j <= n; j++) { t[j] = j; }
|
||||
for (i = 1; i <= m; i++) {
|
||||
for (u = [i], j = 1; j <= n; j++) {
|
||||
u[j] = a[i - 1] === b[j - 1] ? t[j - 1] : Math.min(t[j - 1], t[j], u[j - 1]) + 1;
|
||||
} t = u;
|
||||
} return u[n];
|
||||
}
|
||||
```
|
@ -0,0 +1,97 @@
|
||||
---
|
||||
id: 5e4ce2f5ac708cc68c1df261
|
||||
title: Linear congruential generator
|
||||
challengeType: 5
|
||||
forumTopicId: 385266
|
||||
dashedName: linear-congruential-generator
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
The [linear congruential generator](https://en.wikipedia.org/wiki/linear congruential generator) is a very simple example of a [random number generator](http://rosettacode.org/wiki/random number generator). All linear congruential generators use this formula:
|
||||
|
||||
$$r_{n + 1} = (a \times r_n + c) \bmod m$$
|
||||
|
||||
Where:
|
||||
|
||||
<ul>
|
||||
<li>$ r_0 $ is a seed.</li>
|
||||
<li>$r_1$, $r_2$, $r_3$, ..., are the random numbers.</li>
|
||||
<li>$a$, $c$, $m$ are constants.</li>
|
||||
</ul>
|
||||
|
||||
If one chooses the values of $a$, $c$ and $m$ with care, then the generator produces a uniform distribution of integers from $0$ to $m - 1$.
|
||||
|
||||
LCG numbers have poor quality. $r_n$ and $r\_{n + 1}$ are not independent, as true random numbers would be. Anyone who knows $r_n$ can predict $r\_{n + 1}$, therefore LCG is not cryptographically secure. The LCG is still good enough for simple tasks like [Miller-Rabin primality test](http://rosettacode.org/wiki/Miller-Rabin primality test), or [FreeCell deals](http://rosettacode.org/wiki/deal cards for FreeCell). Among the benefits of the LCG, one can easily reproduce a sequence of numbers, from the same $r_0$. One can also reproduce such sequence with a different programming language, because the formula is so simple.
|
||||
|
||||
# --instructions--
|
||||
|
||||
Write a function that takes $r_0,a,c,m,n$ as parameters and returns $r_n$.
|
||||
|
||||
# --hints--
|
||||
|
||||
`linearCongGenerator` should be a function.
|
||||
|
||||
```js
|
||||
assert(typeof linearCongGenerator == 'function');
|
||||
```
|
||||
|
||||
`linearCongGenerator(324, 1145, 177, 2148, 3)` should return a number.
|
||||
|
||||
```js
|
||||
assert(typeof linearCongGenerator(324, 1145, 177, 2148, 3) == 'number');
|
||||
```
|
||||
|
||||
`linearCongGenerator(324, 1145, 177, 2148, 3)` should return `855`.
|
||||
|
||||
```js
|
||||
assert.equal(linearCongGenerator(324, 1145, 177, 2148, 3), 855);
|
||||
```
|
||||
|
||||
`linearCongGenerator(234, 11245, 145, 83648, 4)` should return `1110`.
|
||||
|
||||
```js
|
||||
assert.equal(linearCongGenerator(234, 11245, 145, 83648, 4), 1110);
|
||||
```
|
||||
|
||||
`linearCongGenerator(85, 11, 1234, 214748, 5)` should return `62217`.
|
||||
|
||||
```js
|
||||
assert.equal(linearCongGenerator(85, 11, 1234, 214748, 5), 62217);
|
||||
```
|
||||
|
||||
`linearCongGenerator(0, 1103515245, 12345, 2147483648, 1)` should return `12345`.
|
||||
|
||||
```js
|
||||
assert.equal(linearCongGenerator(0, 1103515245, 12345, 2147483648, 1), 12345);
|
||||
```
|
||||
|
||||
`linearCongGenerator(0, 1103515245, 12345, 2147483648, 2)` should return `1406932606`.
|
||||
|
||||
```js
|
||||
assert.equal(
|
||||
linearCongGenerator(0, 1103515245, 12345, 2147483648, 2),
|
||||
1406932606
|
||||
);
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```js
|
||||
function linearCongGenerator(r0, a, c, m, n) {
|
||||
|
||||
}
|
||||
```
|
||||
|
||||
# --solutions--
|
||||
|
||||
```js
|
||||
function linearCongGenerator(r0, a, c, m, n) {
|
||||
for (let i = 0; i < n; i++) {
|
||||
r0 = (a * r0 + c) % m;
|
||||
}
|
||||
return r0;
|
||||
}
|
||||
```
|
@ -0,0 +1,111 @@
|
||||
---
|
||||
id: 5e4ce2a1ac708cc68c1df25d
|
||||
title: Long multiplication
|
||||
challengeType: 5
|
||||
forumTopicId: 385269
|
||||
dashedName: long-multiplication
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
Explicitly implement [long multiplication](https://en.wikipedia.org/wiki/long multiplication).
|
||||
|
||||
This is one possible approach to arbitrary-precision integer algebra.
|
||||
|
||||
# --instructions--
|
||||
|
||||
Write a function that takes two strings of large numbers as parameters. Your function should return the product of these two large numbers as a string.
|
||||
|
||||
**Note:** In JavaScript, arithmetic operations are inaccurate with large numbers, so you will have to implement precise multiplication yourself.
|
||||
|
||||
# --hints--
|
||||
|
||||
`mult` should be a function.
|
||||
|
||||
```js
|
||||
assert(typeof mult == 'function');
|
||||
```
|
||||
|
||||
`mult("18446744073709551616", "18446744073709551616")` should return a string.
|
||||
|
||||
```js
|
||||
assert(typeof mult('18446744073709551616', '18446744073709551616') == 'string');
|
||||
```
|
||||
|
||||
`mult("18446744073709551616", "18446744073709551616")` should return `"340282366920938463463374607431768211456"`.
|
||||
|
||||
```js
|
||||
assert.equal(
|
||||
mult('18446744073709551616', '18446744073709551616'),
|
||||
'340282366920938463463374607431768211456'
|
||||
);
|
||||
```
|
||||
|
||||
`mult("31844674073709551616", "1844674407309551616")` should return `"58743055272886011737990786529368211456"`.
|
||||
|
||||
```js
|
||||
assert.equal(
|
||||
mult('31844674073709551616', '1844674407309551616'),
|
||||
'58743055272886011737990786529368211456'
|
||||
);
|
||||
```
|
||||
|
||||
`mult("1846744073709551616", "44844644073709551616")` should return `"82816580680737279241781007431768211456"`.
|
||||
|
||||
```js
|
||||
assert.equal(
|
||||
mult('1846744073709551616', '44844644073709551616'),
|
||||
'82816580680737279241781007431768211456'
|
||||
);
|
||||
```
|
||||
|
||||
`mult("1844674407370951616", "1844674407709551616")` should return `"3402823669833978308014392742590611456"`.
|
||||
|
||||
```js
|
||||
assert.equal(
|
||||
mult('1844674407370951616', '1844674407709551616'),
|
||||
'3402823669833978308014392742590611456'
|
||||
);
|
||||
```
|
||||
|
||||
`mult("2844674407370951616", "1844674407370955616")` should return `"5247498076580334548376218009219475456"`.
|
||||
|
||||
```js
|
||||
assert.equal(
|
||||
mult('2844674407370951616', '1844674407370955616'),
|
||||
'5247498076580334548376218009219475456'
|
||||
);
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```js
|
||||
function mult(strNum1, strNum2) {
|
||||
|
||||
}
|
||||
```
|
||||
|
||||
# --solutions--
|
||||
|
||||
```js
|
||||
function mult(strNum1, strNum2) {
|
||||
var a1 = strNum1.split("").reverse();
|
||||
var a2 = strNum2.toString().split("").reverse();
|
||||
var aResult = new Array;
|
||||
|
||||
for ( var iterNum1 = 0; iterNum1 < a1.length; iterNum1++ ) {
|
||||
for ( var iterNum2 = 0; iterNum2 < a2.length; iterNum2++ ) {
|
||||
var idxIter = iterNum1 + iterNum2; // Get the current array position.
|
||||
aResult[idxIter] = a1[iterNum1] * a2[iterNum2] + ( idxIter >= aResult.length ? 0 : aResult[idxIter] );
|
||||
|
||||
if ( aResult[idxIter] > 9 ) { // Carrying
|
||||
aResult[idxIter + 1] = Math.floor( aResult[idxIter] / 10 ) + ( idxIter + 1 >= aResult.length ? 0 : aResult[idxIter + 1] );
|
||||
aResult[idxIter] %= 10;
|
||||
}
|
||||
}
|
||||
}
|
||||
return aResult.reverse().join("");
|
||||
}
|
||||
```
|
@ -0,0 +1,102 @@
|
||||
---
|
||||
id: 5e6dd1278e6ca105cde40ea9
|
||||
title: Longest common subsequence
|
||||
challengeType: 5
|
||||
forumTopicId: 385271
|
||||
dashedName: longest-common-subsequence
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
The **longest common subsequence** (or [**LCS**](http://en.wikipedia.org/wiki/Longest_common_subsequence_problem)) of groups A and B is the longest group of elements from A and B that are common between the two groups and in the same order in each group. For example, the sequences "1234" and "1224533324" have an LCS of "1234":
|
||||
|
||||
***1234***
|
||||
|
||||
***12***245***3***332***4***
|
||||
|
||||
For a string example, consider the sequences "thisisatest" and "testing123testing". An LCS would be "tsitest":
|
||||
|
||||
***t***hi***si***sa***test***
|
||||
|
||||
***t***e***s***t***i***ng123***test***ing.
|
||||
|
||||
Your code only needs to deal with strings.
|
||||
|
||||
For more information on this problem please see [Wikipedia](https://en.wikipedia.org/wiki/Longest_common_subsequence_problem).
|
||||
|
||||
# --instructions--
|
||||
|
||||
Write a case-sensitive function that returns the LCS of two strings. You don't need to show multiple LCS's.
|
||||
|
||||
# --hints--
|
||||
|
||||
`lcs` should be a function.
|
||||
|
||||
```js
|
||||
assert(typeof lcs == 'function');
|
||||
```
|
||||
|
||||
`lcs("thisisatest", "testing123testing")` should return a string.
|
||||
|
||||
```js
|
||||
assert(typeof lcs('thisisatest', 'testing123testing') == 'string');
|
||||
```
|
||||
|
||||
`lcs("thisisatest", "testing123testing")` should return `"tsitest"`.
|
||||
|
||||
```js
|
||||
assert.equal(lcs('thisisatest', 'testing123testing'), 'tsitest');
|
||||
```
|
||||
|
||||
`lcs("ABCDGH", "AEDFHR")` should return `"ADH"`.
|
||||
|
||||
```js
|
||||
assert.equal(lcs('ABCDGH', 'AEDFHR'), 'ADH');
|
||||
```
|
||||
|
||||
`lcs("AGGTAB", "GXTXAYB")` should return `"GTAB"`.
|
||||
|
||||
```js
|
||||
assert.equal(lcs('AGGTAB', 'GXTXAYB'), 'GTAB');
|
||||
```
|
||||
|
||||
`lcs("BDACDB", "BDCB")` should return `"BDCB"`.
|
||||
|
||||
```js
|
||||
assert.equal(lcs('BDACDB', 'BDCB'), 'BDCB');
|
||||
```
|
||||
|
||||
`lcs("ABAZDC", "BACBAD")` should return `"ABAD"`.
|
||||
|
||||
```js
|
||||
assert.equal(lcs('ABAZDC', 'BACBAD'), 'ABAD');
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```js
|
||||
function lcs(a, b) {
|
||||
|
||||
}
|
||||
```
|
||||
|
||||
# --solutions--
|
||||
|
||||
```js
|
||||
function lcs(a, b) {
|
||||
var aSub = a.substr(0, a.length - 1);
|
||||
var bSub = b.substr(0, b.length - 1);
|
||||
|
||||
if (a.length === 0 || b.length === 0) {
|
||||
return '';
|
||||
} else if (a.charAt(a.length - 1) === b.charAt(b.length - 1)) {
|
||||
return lcs(aSub, bSub) + a.charAt(a.length - 1);
|
||||
} else {
|
||||
var x = lcs(a, bSub);
|
||||
var y = lcs(aSub, b);
|
||||
return (x.length > y.length) ? x : y;
|
||||
}
|
||||
}
|
||||
```
|
@ -0,0 +1,120 @@
|
||||
---
|
||||
id: 5e6dd139859c290b6ab80292
|
||||
title: Longest increasing subsequence
|
||||
challengeType: 5
|
||||
forumTopicId: 385272
|
||||
dashedName: longest-increasing-subsequence
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
The longest increasing subsequence problem is to find a subsequence of a given sequence in which the subsequence's elements are in sorted order, lowest to highest, and in which the subsequence is as long as possible. An example:
|
||||
|
||||
For the following array:
|
||||
|
||||
$\\{3, 10, 2, 1, 20\\}$
|
||||
|
||||
Longest increasing sequence is:
|
||||
|
||||
$\\{3, 10, 20\\}$
|
||||
|
||||
For more information on this problem please see [Wikipedia](https://en.wikipedia.org/wiki/Longest increasing subsequence).
|
||||
|
||||
# --instructions--
|
||||
|
||||
Write a function that takes an array of numbers as a parameter and returns the longest increasing subsequence.
|
||||
|
||||
It is guaranteed that every array will have a longest increasing subsequence.
|
||||
|
||||
# --hints--
|
||||
|
||||
`findSequence` should be a function.
|
||||
|
||||
```js
|
||||
assert(typeof findSequence == 'function');
|
||||
```
|
||||
|
||||
`findSequence([3, 10, 2, 1, 20])` should return a array.
|
||||
|
||||
```js
|
||||
assert(Array.isArray(findSequence([3, 10, 2, 1, 20])));
|
||||
```
|
||||
|
||||
`findSequence([3, 10, 2, 1, 20])` should return `[3, 10, 20]`.
|
||||
|
||||
```js
|
||||
assert.deepEqual(findSequence([3, 10, 2, 1, 20]), [3, 10, 20]);
|
||||
```
|
||||
|
||||
`findSequence([2, 7, 3, 5, 8])` should return `[2, 3, 5, 8]`.
|
||||
|
||||
```js
|
||||
assert.deepEqual(findSequence([2, 7, 3, 5, 8]), [2, 3, 5, 8]);
|
||||
```
|
||||
|
||||
`findSequence([2, 6, 4, 5, 1])` should return `[2, 4, 5]`.
|
||||
|
||||
```js
|
||||
assert.deepEqual(findSequence([2, 6, 4, 5, 1]), [2, 4, 5]);
|
||||
```
|
||||
|
||||
`findSequence([10, 22, 9, 33, 21, 50, 60, 80])` should return `[10, 22, 33, 50, 60, 80]`.
|
||||
|
||||
```js
|
||||
assert.deepEqual(findSequence([10, 22, 9, 33, 21, 50, 60, 80]), [
|
||||
10,
|
||||
22,
|
||||
33,
|
||||
50,
|
||||
60,
|
||||
80
|
||||
]);
|
||||
```
|
||||
|
||||
`findSequence([0, 12, 2, 10, 6, 14, 1, 9, 5, 13, 3, 11, 7, 15])` should return `[0, 2, 6, 9, 11, 15`.
|
||||
|
||||
```js
|
||||
assert.deepEqual(
|
||||
findSequence([0, 12, 2, 10, 6, 14, 1, 9, 5, 13, 3, 11, 7, 15]),
|
||||
[0, 2, 6, 9, 11, 15]
|
||||
);
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```js
|
||||
function findSequence(input) {
|
||||
|
||||
}
|
||||
```
|
||||
|
||||
# --solutions--
|
||||
|
||||
```js
|
||||
function findSequence(input) {
|
||||
var len = input.length;
|
||||
var result = []
|
||||
for (var i = 0; i < len; i++) result.push(1)
|
||||
|
||||
for (var i = 0; i < len; i++)
|
||||
for (var j = i - 1; j >= 0; j--)
|
||||
if (input[i] > input[j] && result[j] >= result[i])
|
||||
result[i] = result[j] + 1;
|
||||
|
||||
var maxValue = Math.max.apply(null, result);
|
||||
var maxIndex = result.indexOf(Math.max.apply(Math, result));
|
||||
var output = [];
|
||||
output.push(input[maxIndex]);
|
||||
for (var i = maxIndex; i >= 0; i--) {
|
||||
if (maxValue == 0) break;
|
||||
if (input[maxIndex] > input[i] && result[i] == maxValue - 1) {
|
||||
output.push(input[i]);
|
||||
maxValue--;
|
||||
}
|
||||
}
|
||||
output.reverse();
|
||||
return output;
|
||||
}
|
||||
```
|
@ -0,0 +1,101 @@
|
||||
---
|
||||
id: 5e6dd14192286d95fc43046e
|
||||
title: Longest string challenge
|
||||
challengeType: 5
|
||||
forumTopicId: 385275
|
||||
dashedName: longest-string-challenge
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
In this challenge, you have to find the strings that are the longest among the given strings.
|
||||
|
||||
# --instructions--
|
||||
|
||||
Write a function that takes an array of strings and returns the strings that have a length equal to the longest length.
|
||||
|
||||
# --hints--
|
||||
|
||||
`longestString` should be a function.
|
||||
|
||||
```js
|
||||
assert(typeof longestString == 'function');
|
||||
```
|
||||
|
||||
`longestString(["a", "bb", "ccc", "ee", "f", "ggg"])` should return a array.
|
||||
|
||||
```js
|
||||
assert(Array.isArray(longestString(['a', 'bb', 'ccc', 'ee', 'f', 'ggg'])));
|
||||
```
|
||||
|
||||
`longestString(["a", "bb", "ccc", "ee", "f", "ggg"])` should return `["ccc", "ggg"]'`.
|
||||
|
||||
```js
|
||||
assert.deepEqual(longestString(['a', 'bb', 'ccc', 'ee', 'f', 'ggg']), [
|
||||
'ccc',
|
||||
'ggg'
|
||||
]);
|
||||
```
|
||||
|
||||
`longestString(["afedg", "bb", "sdccc", "efdee", "f", "geegg"])` should return `["afedg", "sdccc", "efdee", "geegg"]`.
|
||||
|
||||
```js
|
||||
assert.deepEqual(
|
||||
longestString(['afedg', 'bb', 'sdccc', 'efdee', 'f', 'geegg']),
|
||||
['afedg', 'sdccc', 'efdee', 'geegg']
|
||||
);
|
||||
```
|
||||
|
||||
`longestString(["a", "bhghgb", "ccc", "efde", "fssdrr", "ggg"])` should return `["bhghgb", "fssdrr"]`.
|
||||
|
||||
```js
|
||||
assert.deepEqual(
|
||||
longestString(['a', 'bhghgb', 'ccc', 'efde', 'fssdrr', 'ggg']),
|
||||
['bhghgb', 'fssdrr']
|
||||
);
|
||||
```
|
||||
|
||||
`longestString(["ahgfhg", "bdsfsb", "ccc", "ee", "f", "ggdsfg"])` should return `["ahgfhg", "bdsfsb", "ggdsfg"]`.
|
||||
|
||||
```js
|
||||
assert.deepEqual(
|
||||
longestString(['ahgfhg', 'bdsfsb', 'ccc', 'ee', 'f', 'ggdsfg']),
|
||||
['ahgfhg', 'bdsfsb', 'ggdsfg']
|
||||
);
|
||||
```
|
||||
|
||||
`longestString(["a", "bbdsf", "ccc", "edfe", "gzzzgg"])` should return `["gzzzgg"]`.
|
||||
|
||||
```js
|
||||
assert.deepEqual(longestString(['a', 'bbdsf', 'ccc', 'edfe', 'gzzzgg']), [
|
||||
'gzzzgg'
|
||||
]);
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```js
|
||||
function longestString(strings) {
|
||||
|
||||
}
|
||||
```
|
||||
|
||||
# --solutions--
|
||||
|
||||
```js
|
||||
function longestString(strings) {
|
||||
var mx = 0;
|
||||
var result = []
|
||||
strings.forEach(function (e) {
|
||||
if (e.length > mx) {
|
||||
mx = e.length
|
||||
result = [e]
|
||||
} else if (e.length == mx)
|
||||
result.push(e)
|
||||
})
|
||||
|
||||
return result
|
||||
}
|
||||
```
|
@ -0,0 +1,92 @@
|
||||
---
|
||||
id: 5e6dd14797f5ce267c2f19d0
|
||||
title: Look-and-say sequence
|
||||
challengeType: 5
|
||||
forumTopicId: 385277
|
||||
dashedName: look-and-say-sequence
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
The [Look and say sequence](https://en.wikipedia.org/wiki/Look and say sequence) is a recursively defined sequence of numbers.
|
||||
|
||||
Sequence Definition
|
||||
|
||||
<ul><li>Take a decimal number</li>
|
||||
<li><span>Look</span> at the number, visually grouping consecutive runs of the same digit.</li>
|
||||
<li><span>Say</span> the number, from left to right, group by group; as how many of that digit there are - followed by the digit grouped.</li></ul><span> This becomes the next number of the sequence.</span>
|
||||
|
||||
An example:
|
||||
|
||||
<ul><li>Starting with the number 1, you have <span>one</span> 1 which produces 11</li>
|
||||
<li>Starting with 11, you have <span>two</span> 1's. I.E.: 21</li>
|
||||
<li>Starting with 21, you have <span>one</span> 2, then <span>one</span> 1. I.E.: (12)(11) which becomes 1211</li>
|
||||
<li>Starting with 1211, you have <span>one</span> 1, <span>one</span> 2, then <span>two</span> 1's. I.E.: (11)(12)(21) which becomes 111221</li></ul>
|
||||
|
||||
# --instructions--
|
||||
|
||||
Write a function that accepts a string as a parameter, processes it, and returns the resultant string.
|
||||
|
||||
# --hints--
|
||||
|
||||
`lookAndSay` should be a function.
|
||||
|
||||
```js
|
||||
assert(typeof lookAndSay == 'function');
|
||||
```
|
||||
|
||||
`lookAndSay("1")` should return a string.
|
||||
|
||||
```js
|
||||
assert(typeof lookAndSay('1') == 'string');
|
||||
```
|
||||
|
||||
`lookAndSay("1")` should return `"11"`.
|
||||
|
||||
```js
|
||||
assert.equal(lookAndSay('1'), '11');
|
||||
```
|
||||
|
||||
`lookAndSay("11")` should return `"21"`.
|
||||
|
||||
```js
|
||||
assert.equal(lookAndSay('11'), '21');
|
||||
```
|
||||
|
||||
`lookAndSay("21")` should return `"1211"`.
|
||||
|
||||
```js
|
||||
assert.equal(lookAndSay('21'), '1211');
|
||||
```
|
||||
|
||||
`lookAndSay("1211")` should return `"111221"`.
|
||||
|
||||
```js
|
||||
assert.equal(lookAndSay('1211'), '111221');
|
||||
```
|
||||
|
||||
`lookAndSay("3542")` should return `"13151412"`.
|
||||
|
||||
```js
|
||||
assert.equal(lookAndSay('3542'), '13151412');
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```js
|
||||
function lookAndSay(str) {
|
||||
|
||||
}
|
||||
```
|
||||
|
||||
# --solutions--
|
||||
|
||||
```js
|
||||
function lookAndSay(str) {
|
||||
return str.replace(/(.)\1*/g, function(seq, p1) {
|
||||
return seq.length.toString() + p1;
|
||||
});
|
||||
}
|
||||
```
|
@ -0,0 +1,135 @@
|
||||
---
|
||||
id: 5e6dd15004c88cf00d2a78b3
|
||||
title: Loop over multiple arrays simultaneously
|
||||
challengeType: 5
|
||||
forumTopicId: 385279
|
||||
dashedName: loop-over-multiple-arrays-simultaneously
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
Loop over multiple arrays and create a new array whose $i^{th}$ element is the concatenation of $i^{th}$ element of each of the given.
|
||||
|
||||
For this example, if you are given this array of arrays:
|
||||
|
||||
`[ ["a", "b", "c"], ["A", "B", "C"], [1, 2, 3] ]`
|
||||
|
||||
the output should be:
|
||||
|
||||
`["aA1","bB2","cC3"]`
|
||||
|
||||
# --instructions--
|
||||
|
||||
Write a function that takes an array of arrays as a parameter and returns an array of strings satisfying the given description.
|
||||
|
||||
# --hints--
|
||||
|
||||
`loopSimult` should be a function.
|
||||
|
||||
```js
|
||||
assert(typeof loopSimult == 'function');
|
||||
```
|
||||
|
||||
`loopSimult([["a", "b", "c"], ["A", "B", "C"], [1, 2, 3]])` should return a array.
|
||||
|
||||
```js
|
||||
assert(
|
||||
Array.isArray(
|
||||
loopSimult([
|
||||
['a', 'b', 'c'],
|
||||
['A', 'B', 'C'],
|
||||
[1, 2, 3]
|
||||
])
|
||||
)
|
||||
);
|
||||
```
|
||||
|
||||
`loopSimult([["a", "b", "c"], ["A", "B", "C"], [1, 2, 3]])` should return `["aA1", "bB2", "cC3"]`.
|
||||
|
||||
```js
|
||||
assert.deepEqual(
|
||||
loopSimult([
|
||||
['a', 'b', 'c'],
|
||||
['A', 'B', 'C'],
|
||||
[1, 2, 3]
|
||||
]),
|
||||
['aA1', 'bB2', 'cC3']
|
||||
);
|
||||
```
|
||||
|
||||
`loopSimult([["c", "b", "c"], ["4", "5", "C"], [7, 7, 3]])` should return `["c47", "b57", "cC3"]`.
|
||||
|
||||
```js
|
||||
assert.deepEqual(
|
||||
loopSimult([
|
||||
['c', 'b', 'c'],
|
||||
['4', '5', 'C'],
|
||||
[7, 7, 3]
|
||||
]),
|
||||
['c47', 'b57', 'cC3']
|
||||
);
|
||||
```
|
||||
|
||||
`loopSimult([["a", "b", "c", "d"], ["A", "B", "C", "d"], [1, 2, 3, 4]])` should return `["aA1", "bB2", "cC3", "dd4"]`.
|
||||
|
||||
```js
|
||||
assert.deepEqual(
|
||||
loopSimult([
|
||||
['a', 'b', 'c', 'd'],
|
||||
['A', 'B', 'C', 'd'],
|
||||
[1, 2, 3, 4]
|
||||
]),
|
||||
['aA1', 'bB2', 'cC3', 'dd4']
|
||||
);
|
||||
```
|
||||
|
||||
`loopSimult([["a", "b"], ["A", "B"], [1, 2]])` should return `["aA1", "bB2"]`.
|
||||
|
||||
```js
|
||||
assert.deepEqual(
|
||||
loopSimult([
|
||||
['a', 'b'],
|
||||
['A', 'B'],
|
||||
[1, 2]
|
||||
]),
|
||||
['aA1', 'bB2']
|
||||
);
|
||||
```
|
||||
|
||||
`loopSimult([["b", "c"], ["B", "C"], [2, 3]])` should return `["bB2", "cC3"]`.
|
||||
|
||||
```js
|
||||
assert.deepEqual(
|
||||
loopSimult([
|
||||
['b', 'c'],
|
||||
['B', 'C'],
|
||||
[2, 3]
|
||||
]),
|
||||
['bB2', 'cC3']
|
||||
);
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```js
|
||||
function loopSimult(A) {
|
||||
|
||||
}
|
||||
```
|
||||
|
||||
# --solutions--
|
||||
|
||||
```js
|
||||
function loopSimult(A) {
|
||||
var res = [], output;
|
||||
for (var i = 0; i < A[0].length; i += 1) {
|
||||
output = "";
|
||||
for (var j = 0; j < A.length; j++)
|
||||
output += A[j][i];
|
||||
res.push(output);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
```
|
@ -0,0 +1,318 @@
|
||||
---
|
||||
id: 5e6decd8ec8d7db960950d1c
|
||||
title: LU decomposition
|
||||
challengeType: 5
|
||||
forumTopicId: 385280
|
||||
dashedName: lu-decomposition
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
Every square matrix $A$ can be decomposed into a product of a lower triangular matrix $L$ and a upper triangular matrix $U$, as described in [LU decomposition](https://en.wikipedia.org/wiki/LU decomposition).
|
||||
|
||||
$A = LU$
|
||||
|
||||
It is a modified form of Gaussian elimination.
|
||||
|
||||
While the [Cholesky decomposition](http://rosettacode.org/wiki/Cholesky decomposition) only works for symmetric, positive definite matrices, the more general LU decomposition works for any square matrix.
|
||||
|
||||
There are several algorithms for calculating $L$ and $U$.
|
||||
|
||||
To derive *Crout's algorithm* for a 3x3 example, we have to solve the following system:
|
||||
|
||||
\\begin{align}A = \\begin{pmatrix} a\_{11} & a\_{12} & a\_{13}\\\\ a\_{21} & a\_{22} & a\_{23}\\\\ a\_{31} & a\_{32} & a\_{33}\\\\ \\end{pmatrix}= \\begin{pmatrix} l\_{11} & 0 & 0 \\\\ l\_{21} & l\_{22} & 0 \\\\ l\_{31} & l\_{32} & l\_{33}\\\\ \\end{pmatrix} \\begin{pmatrix} u\_{11} & u\_{12} & u\_{13} \\\\ 0 & u\_{22} & u\_{23} \\\\ 0 & 0 & u\_{33} \\end{pmatrix} = LU\\end{align}
|
||||
|
||||
We now would have to solve 9 equations with 12 unknowns. To make the system uniquely solvable, usually the diagonal elements of $L$ are set to 1
|
||||
|
||||
$l\_{11}=1$
|
||||
|
||||
$l\_{22}=1$
|
||||
|
||||
$l\_{33}=1$
|
||||
|
||||
so we get a solvable system of 9 unknowns and 9 equations.
|
||||
|
||||
\\begin{align}A = \\begin{pmatrix} a\_{11} & a\_{12} & a\_{13}\\\\ a\_{21} & a\_{22} & a\_{23}\\\\ a\_{31} & a\_{32} & a\_{33}\\\\ \\end{pmatrix} = \\begin{pmatrix} 1 & 0 & 0 \\\\ l\_{21} & 1 & 0 \\\\ l\_{31} & l\_{32} & 1\\\\ \\end{pmatrix} \\begin{pmatrix} u\_{11} & u\_{12} & u\_{13} \\\\ 0 & u\_{22} & u\_{23} \\\\ 0 & 0 & u\_{33} \\end{pmatrix} = \\begin{pmatrix} u\_{11} & u\_{12} & u\_{13} \\\\ u\_{11}l\_{21} & u\_{12}l\_{21}+u\_{22} & u\_{13}l\_{21}+u\_{23} \\\\ u\_{11}l\_{31} & u\_{12}l\_{31}+u\_{22}l\_{32} & u\_{13}l\_{31} + u\_{23}l\_{32}+u\_{33} \\end{pmatrix} = LU\\end{align}
|
||||
|
||||
Solving for the other $l$ and $u$, we get the following equations:
|
||||
|
||||
$u\_{11}=a\_{11}$
|
||||
|
||||
$u\_{12}=a\_{12}$
|
||||
|
||||
$u\_{13}=a\_{13}$
|
||||
|
||||
$u\_{22}=a\_{22} - u\_{12}l\_{21}$
|
||||
|
||||
$u\_{23}=a\_{23} - u\_{13}l\_{21}$
|
||||
|
||||
$u\_{33}=a\_{33} - (u\_{13}l\_{31} + u\_{23}l\_{32})$
|
||||
|
||||
and for $l$:
|
||||
|
||||
$l\_{21}=\\frac{1}{u\_{11}} a\_{21}$
|
||||
|
||||
$l\_{31}=\\frac{1}{u\_{11}} a\_{31}$
|
||||
|
||||
$l\_{32}=\\frac{1}{u\_{22}} (a\_{32} - u\_{12}l\_{31})$
|
||||
|
||||
We see that there is a calculation pattern, which can be expressed as the following formulas, first for $U$
|
||||
|
||||
$u\_{ij} = a\_{ij} - \\sum\_{k=1}^{i-1} u\_{kj}l\_{ik}$
|
||||
|
||||
and then for $L$
|
||||
|
||||
$l\_{ij} = \\frac{1}{u\_{jj}} (a\_{ij} - \\sum\_{k=1}^{j-1} u\_{kj}l\_{ik})$
|
||||
|
||||
We see in the second formula that to get the $l\_{ij}$ below the diagonal, we have to divide by the diagonal element (pivot) $u\_{jj}$, so we get problems when $u\_{jj}$ is either 0 or very small, which leads to numerical instability.
|
||||
|
||||
The solution to this problem is *pivoting* $A$, which means rearranging the rows of $A$, prior to the $LU$ decomposition, in a way that the largest element of each column gets onto the diagonal of $A$. Rearranging the rows means to multiply $A$ by a permutation matrix $P$:
|
||||
|
||||
$PA \\Rightarrow A'$
|
||||
|
||||
Example:
|
||||
|
||||
\\begin{align} \\begin{pmatrix} 0 & 1 \\\\ 1 & 0 \\end{pmatrix} \\begin{pmatrix} 1 & 4 \\\\ 2 & 3 \\end{pmatrix} \\Rightarrow \\begin{pmatrix} 2 & 3 \\\\ 1 & 4 \\end{pmatrix} \\end{align}
|
||||
|
||||
The decomposition algorithm is then applied on the rearranged matrix so that
|
||||
|
||||
$PA = LU$
|
||||
|
||||
# --instructions--
|
||||
|
||||
The task is to implement a routine which will take a square nxn matrix $A$ and return a lower triangular matrix $L$, a upper triangular matrix $U$ and a permutation matrix $P$, so that the above equation is fullfilled. The returned value should be in the form `[L, U, P]`.
|
||||
|
||||
# --hints--
|
||||
|
||||
`luDecomposition` should be a function.
|
||||
|
||||
```js
|
||||
assert(typeof luDecomposition == 'function');
|
||||
```
|
||||
|
||||
`luDecomposition([[1, 3, 5], [2, 4, 7], [1, 1, 0]])` should return a array.
|
||||
|
||||
```js
|
||||
assert(
|
||||
Array.isArray(
|
||||
luDecomposition([
|
||||
[1, 3, 5],
|
||||
[2, 4, 7],
|
||||
[1, 1, 0]
|
||||
])
|
||||
)
|
||||
);
|
||||
```
|
||||
|
||||
`luDecomposition([[1, 3, 5], [2, 4, 7], [1, 1, 0]])` should return `[[[1, 0, 0], [0.5, 1, 0], [0.5, -1, 1]], [[2, 4, 7], [0, 1, 1.5], [0, 0, -2]], [[0, 1, 0], [1, 0, 0], [0, 0, 1]]]`.
|
||||
|
||||
```js
|
||||
assert.deepEqual(
|
||||
luDecomposition([
|
||||
[1, 3, 5],
|
||||
[2, 4, 7],
|
||||
[1, 1, 0]
|
||||
]),
|
||||
[
|
||||
[
|
||||
[1, 0, 0],
|
||||
[0.5, 1, 0],
|
||||
[0.5, -1, 1]
|
||||
],
|
||||
[
|
||||
[2, 4, 7],
|
||||
[0, 1, 1.5],
|
||||
[0, 0, -2]
|
||||
],
|
||||
[
|
||||
[0, 1, 0],
|
||||
[1, 0, 0],
|
||||
[0, 0, 1]
|
||||
]
|
||||
]
|
||||
);
|
||||
```
|
||||
|
||||
`luDecomposition([[11, 9, 24, 2], [1, 5, 2, 6], [3, 17, 18, 1], [2, 5, 7, 1]])` should return `[[[1, 0, 0, 0], [0.2727272727272727, 1, 0, 0], [0.09090909090909091, 0.2875, 1, 0], [0.18181818181818182, 0.23124999999999996, 0.0035971223021580693, 1]], [[11, 9, 24, 2], [0, 14.545454545454547, 11.454545454545455, 0.4545454545454546], [0, 0, -3.4749999999999996, 5.6875], [0, 0, 0, 0.510791366906476]], [[1, 0, 0, 0], [0, 0, 1, 0], [0, 1, 0, 0], [0, 0, 0, 1]]]`.
|
||||
|
||||
```js
|
||||
assert.deepEqual(
|
||||
luDecomposition([
|
||||
[11, 9, 24, 2],
|
||||
[1, 5, 2, 6],
|
||||
[3, 17, 18, 1],
|
||||
[2, 5, 7, 1]
|
||||
]),
|
||||
[
|
||||
[
|
||||
[1, 0, 0, 0],
|
||||
[0.2727272727272727, 1, 0, 0],
|
||||
[0.09090909090909091, 0.2875, 1, 0],
|
||||
[0.18181818181818182, 0.23124999999999996, 0.0035971223021580693, 1]
|
||||
],
|
||||
[
|
||||
[11, 9, 24, 2],
|
||||
[0, 14.545454545454547, 11.454545454545455, 0.4545454545454546],
|
||||
[0, 0, -3.4749999999999996, 5.6875],
|
||||
[0, 0, 0, 0.510791366906476]
|
||||
],
|
||||
[
|
||||
[1, 0, 0, 0],
|
||||
[0, 0, 1, 0],
|
||||
[0, 1, 0, 0],
|
||||
[0, 0, 0, 1]
|
||||
]
|
||||
]
|
||||
);
|
||||
```
|
||||
|
||||
`luDecomposition([[1, 1, 1], [4, 3, -1], [3, 5, 3]])` should return `[[[1, 0, 0], [0.75, 1, 0], [0.25, 0.09090909090909091, 1]], [[4, 3, -1], [0, 2.75, 3.75], [0, 0, 0.9090909090909091]], [[0, 1, 0], [0, 0, 1], [1, 0, 0]]]`.
|
||||
|
||||
```js
|
||||
assert.deepEqual(
|
||||
luDecomposition([
|
||||
[1, 1, 1],
|
||||
[4, 3, -1],
|
||||
[3, 5, 3]
|
||||
]),
|
||||
[
|
||||
[
|
||||
[1, 0, 0],
|
||||
[0.75, 1, 0],
|
||||
[0.25, 0.09090909090909091, 1]
|
||||
],
|
||||
[
|
||||
[4, 3, -1],
|
||||
[0, 2.75, 3.75],
|
||||
[0, 0, 0.9090909090909091]
|
||||
],
|
||||
[
|
||||
[0, 1, 0],
|
||||
[0, 0, 1],
|
||||
[1, 0, 0]
|
||||
]
|
||||
]
|
||||
);
|
||||
```
|
||||
|
||||
`luDecomposition([[1, -2, 3], [2, -5, 12], [0, 2, -10]])` should return `[[[1, 0, 0], [0, 1, 0], [0.5, 0.25, 1]], [[2, -5, 12], [0, 2, -10], [0, 0, -0.5]], [[0, 1, 0], [0, 0, 1], [1, 0, 0]]]`.
|
||||
|
||||
```js
|
||||
assert.deepEqual(
|
||||
luDecomposition([
|
||||
[1, -2, 3],
|
||||
[2, -5, 12],
|
||||
[0, 2, -10]
|
||||
]),
|
||||
[
|
||||
[
|
||||
[1, 0, 0],
|
||||
[0, 1, 0],
|
||||
[0.5, 0.25, 1]
|
||||
],
|
||||
[
|
||||
[2, -5, 12],
|
||||
[0, 2, -10],
|
||||
[0, 0, -0.5]
|
||||
],
|
||||
[
|
||||
[0, 1, 0],
|
||||
[0, 0, 1],
|
||||
[1, 0, 0]
|
||||
]
|
||||
]
|
||||
);
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```js
|
||||
function luDecomposition(A) {
|
||||
|
||||
}
|
||||
```
|
||||
|
||||
# --solutions--
|
||||
|
||||
```js
|
||||
function luDecomposition(A) {
|
||||
|
||||
function dotProduct(a, b) {
|
||||
var sum = 0;
|
||||
for (var i = 0; i < a.length; i++)
|
||||
sum += a[i] * b[i]
|
||||
return sum;
|
||||
}
|
||||
|
||||
function matrixMul(A, B) {
|
||||
var result = new Array(A.length);
|
||||
for (var i = 0; i < A.length; i++)
|
||||
result[i] = new Array(B[0].length)
|
||||
var aux = new Array(B.length);
|
||||
|
||||
for (var j = 0; j < B[0].length; j++) {
|
||||
|
||||
for (var k = 0; k < B.length; k++)
|
||||
aux[k] = B[k][j];
|
||||
|
||||
for (var i = 0; i < A.length; i++)
|
||||
result[i][j] = dotProduct(A[i], aux);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
function pivotize(m) {
|
||||
var n = m.length;
|
||||
var id = new Array(n);
|
||||
for (var i = 0; i < n; i++) {
|
||||
id[i] = new Array(n);
|
||||
id[i].fill(0)
|
||||
id[i][i] = 1;
|
||||
}
|
||||
|
||||
for (var i = 0; i < n; i++) {
|
||||
var maxm = m[i][i];
|
||||
var row = i;
|
||||
for (var j = i; j < n; j++)
|
||||
if (m[j][i] > maxm) {
|
||||
maxm = m[j][i];
|
||||
row = j;
|
||||
}
|
||||
|
||||
if (i != row) {
|
||||
var tmp = id[i];
|
||||
id[i] = id[row];
|
||||
id[row] = tmp;
|
||||
}
|
||||
}
|
||||
return id;
|
||||
}
|
||||
|
||||
var n = A.length;
|
||||
var L = new Array(n);
|
||||
for (var i = 0; i < n; i++) { L[i] = new Array(n); L[i].fill(0) }
|
||||
var U = new Array(n);
|
||||
for (var i = 0; i < n; i++) { U[i] = new Array(n); U[i].fill(0) }
|
||||
var P = pivotize(A);
|
||||
var A2 = matrixMul(P, A);
|
||||
|
||||
for (var j = 0; j < n; j++) {
|
||||
L[j][j] = 1;
|
||||
for (var i = 0; i < j + 1; i++) {
|
||||
var s1 = 0;
|
||||
for (var k = 0; k < i; k++)
|
||||
s1 += U[k][j] * L[i][k];
|
||||
U[i][j] = A2[i][j] - s1;
|
||||
}
|
||||
for (var i = j; i < n; i++) {
|
||||
var s2 = 0;
|
||||
for (var k = 0; k < j; k++)
|
||||
s2 += U[k][j] * L[i][k];
|
||||
L[i][j] = (A2[i][j] - s2) / U[j][j];
|
||||
}
|
||||
}
|
||||
return [L, U, P];
|
||||
}
|
||||
```
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user