chore(i18n,learn): processed translations (#44851)

This commit is contained in:
camperbot
2022-01-21 01:00:18 +05:30
committed by GitHub
parent f866718a3d
commit 5c868af2b8
1696 changed files with 159426 additions and 69 deletions

View File

@ -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;
}
```

View File

@ -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);
}
});
}
}
}
}
```

View File

@ -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];
}
```

View File

@ -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;
}
```

View File

@ -0,0 +1,95 @@
---
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.
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 `num` (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(5000)` should return an array.
```js
assert(Array.isArray(getDPA(5000)));
```
`getDPA(5000)` return array should have a length of `3`.
```js
assert(getDPA(5000).length === 3);
```
`getDPA(5000)` should return `[3758, 3, 1239]`.
```js
assert.deepEqual(getDPA(5000), [3758, 3, 1239]);
```
`getDPA(10000)` should return `[7508, 4, 2488]`.
```js
assert.deepEqual(getDPA(10000), [7508, 4, 2488]);
```
`getDPA(20000)` should return `[15043, 4, 4953]`.
```js
assert.deepEqual(getDPA(20000), [15043, 4, 4953]);
```
# --seed--
## --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;
}
```

View File

@ -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;
};
}
```

View File

@ -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));
}
```

View File

@ -0,0 +1,189 @@
---
id: 594810f028c0303b75339ad0
title: Align columns
challengeType: 5
forumTopicId: 302224
dashedName: align-columns
---
# --description--
Given an array 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:
```js
const testText = [
'Given$a$text$file$of$many$lines',
'where$fields$within$a$line$',
'are$delineated$by$a$single$"dollar"$character',
'write$a$program',
'that$aligns$each$column$of$fields',
'by$ensuring$that$words$in$each$',
'column$are$separated$by$at$least$one$space.',
'Further,$allow$for$each$word$in$a$column$to$be$either$left$',
'justified,$right$justified',
'or$center$justified$within$its$column.'
];
```
**Note that:**
- The example input texts lines may, or may not, have trailing dollar characters.
- All columns should share the same alignment.
- Consecutive space characters produced adjacent to the end of lines are insignificant for the purposes of the task.
- Output text will be viewed in a mono-spaced font on a plain text editor or basic terminal. Lines in it should be joined using new line character (`\n`).
- The minimum space between columns should be computed from the text and not hard-coded.
- It is not a requirement to add separating characters between or around columns.
For example, one of the lines from the `testText`, after jusitifing to the right, left and center respectivelly:
```js
' column are separated by at least one space.\n'
'column are separated by at least one space.\n'
' column are separated by at least one space.\n'
```
# --hints--
`formatText` should be a function.
```js
assert(typeof formatText === 'function');
```
`formatText(testText, 'right')` should produce text with columns justified to the right.
```js
assert.strictEqual(formatText(_testText, 'right'), rightAligned);
```
`formatText(testText, 'left')` should produce text with columns justified to the left.
```js
assert.strictEqual(formatText(_testText, 'left'), leftAligned);
```
`formatText(testText, 'center')` should produce text with columns justified to the center.
```js
assert.strictEqual(formatText(_testText, 'center'), centerAligned);
```
# --seed--
## --after-user-code--
```js
const _testText = [
'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
function formatText(input, justification) {
}
const testText = [
'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.'
];
```
# --solutions--
```js
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;
}
```

View File

@ -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));
}
```

View File

@ -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;
}
```

View File

@ -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'}`
};
}
```

View File

@ -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);
}
```

View File

@ -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;
}
```

View File

@ -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;
}
```

View File

@ -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;
}
```

View File

@ -0,0 +1,414 @@
---
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.
The straightforward solution is a $O(n^2)$ 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 &#x3C; 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)| &#x3C; 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, which is $O(n\log 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 &#x3C; dR <strong>then</strong>
(dmin, pairMin) ← (dL, pairL)
<strong>endif</strong>
yS ← { p ∈ yP : |xm - p<sub>x</sub>| &#x3C; 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> &#x3C; dmin
<strong>if</strong> |yS(k) - yS(i)| &#x3C; 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 `Point` objects with `x` and `y` members set to numbers. Return an object containing the key:value pairs for `distance` and `pair` (the pair of two closest points).
For example `getClosestPair` with input array `points`:
```js
const points = [
new Point(1, 2),
new Point(3, 3),
new Point(2, 2)
];
```
Would return:
```js
{
distance: 1,
pair: [
{
x: 1,
y: 2
},
{
x: 2,
y: 2
}
]
}
```
**Note:** Sort the `pair` array by their `x` values in incrementing order.
# --hints--
`getClosestPair` should be a function.
```js
assert(typeof getClosestPair === 'function');
```
`getClosestPair(points1).distance` should be `0.0894096443343775`.
```js
assert.equal(getClosestPair(points1).distance, answer1.distance);
```
`getClosestPair(points1).pair` should be `[ { x: 7.46489, y: 4.6268 }, { x: 7.46911, y: 4.71611 } ]`.
```js
assert.deepEqual(
JSON.parse(JSON.stringify(getClosestPair(points1))).pair,
answer1.pair
);
```
`getClosestPair(points2).distance` should be `65.06919393998976`.
```js
assert.equal(getClosestPair(points2).distance, answer2.distance);
```
`getClosestPair(points2).pair` should be `[ { x: 37134, y: 1963 }, { x: 37181, y: 2008 } ]`.
```js
assert.deepEqual(
JSON.parse(JSON.stringify(getClosestPair(points2))).pair,
answer2.pair
);
```
`getClosestPair(points3).distance` should be `6754.625082119658`.
```js
assert.equal(getClosestPair(points3).distance, answer3.distance);
```
`getClosestPair(points3).pair` should be `[ { x: 46817, y: 64975 }, { x: 48953, y: 58567 } ]`.
```js
assert.deepEqual(
JSON.parse(JSON.stringify(getClosestPair(points3))).pair,
answer3.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 answer1 = {
distance: 0.0894096443343775,
pair: [
{
x: 7.46489,
y: 4.6268
},
{
x: 7.46911,
y: 4.71611
}
]
};
const points2 = [
new Point(37100, 13118),
new Point(37134, 1963),
new Point(37181, 2008),
new Point(37276, 21611),
new Point(37307, 9320)
];
const answer2 = {
distance: 65.06919393998976,
pair: [
{
x: 37134,
y: 1963
},
{
x: 37181,
y: 2008
}
]
};
const points3 = [
new Point(16910, 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, 39744),
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)
];
const answer3 = {
distance: 6754.625082119658,
pair: [
{
x: 46817,
y: 64975
},
{
x: 48953,
y: 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.sort((pointA, pointB) => pointA.x - pointB.x)
};
};
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);
}
```

View File

@ -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));
}
```

View File

@ -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] || '') +
"}";
}
```

View File

@ -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;
}
```

View File

@ -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> |
| 86400 | <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);
}
```

View File

@ -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;
}
```

View File

@ -0,0 +1,93 @@
---
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 given input, `cents`, that represents an amount of US pennies using these common coins.
# --hints--
`countCoins` should be a function.
```js
assert(typeof countCoins === 'function');
```
`countCoins(15)` should return `6`.
```js
assert.equal(countCoins(15), 6);
```
`countCoins(85)` shouls return `163`.
```js
assert.equal(countCoins(85), 163);
```
`countCoins(100)` should return `242`.
```js
assert.equal(countCoins(100), 242);
```
# --seed--
## --seed-contents--
```js
function countCoins(cents) {
return true;
}
```
# --solutions--
```js
function countCoins(cents) {
const operands = [1, 5, 10, 25];
const targetsLength = cents + 1;
const operandsLength = operands.length;
const 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];
}
```

View File

@ -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());
}
```

View File

@ -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;
}
```

View File

@ -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;
}
```

View File

@ -0,0 +1,203 @@
---
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>
.diagram-g { fill: none; stroke: #ccc }
.diagram-s, .diagram-s2 { fill: #bff; stroke: black; fill-opacity: .4 }
.diagram-s2 { fill: #fbf }
.diagram-d { stroke:black; fill:none}
</style>
<defs>
<g id="diagram-m">
<g id="diagram-h4">
<g id="diagram-h2">
<path id="diagram-h" d="m0 10h 640" class="diagram-g"/>
<use xlink:href="#diagram-h" transform="translate(0, 20)"/>
</g>
<use xlink:href="#diagram-h2" transform="translate(0, 40)"/>
</g>
<use xlink:href="#diagram-h4" transform="translate(0, 80)"/>
<g id="diagram-v8">
<g id="diagram-v4">
<g id="diagram-v2">
<path id="diagram-v" d="m10 0v160 m 20 0 v-160" class="diagram-g"/>
<use xlink:href="#diagram-v" transform="translate(40, 0)"/>
</g>
<use xlink:href="#diagram-v2" transform="translate(80, 0)"/>
</g>
<use xlink:href="#diagram-v4" transform="translate(160, 0)"/>
</g>
<use xlink:href="#diagram-v8" transform="translate(320, 0)"/>
</g>
<path id="diagram-b" d="m0 0h80v60h-80z" class="diagram-s"/>
</defs>
<g transform="translate(.5, .5)">
<use xlink:href="#diagram-m"/>
<g transform="translate(10, 10)">
<path d="m0 0v40h40v-40z" class="diagram-s2"/>
<path d="m20 0v40" class="diagram-d"/>
<path d="m60 0v40h40v-40z" class="diagram-s2"/>
<path d="m60 20h40" class="diagram-d"/>
<g transform="translate(120, 0)">
<use xlink:href="#diagram-b"/>
<path d="m0 20h40v20h40" class="diagram-d"/>
</g>
<g transform="translate(220, 0)">
<use xlink:href="#diagram-b"/>
<path d="m0 40h40v-20h40" class="diagram-d"/>
</g>
<g transform="translate(320, 0)">
<use xlink:href="#diagram-b"/>
<path d="m20 0v40h20v-20h20v40" class="diagram-d"/>
</g>
<g transform="translate(420, 0)">
<use xlink:href="#diagram-b"/>
<path d="m60 0v40h-20v-20h-20v40" class="diagram-d"/>
</g>
<g transform="translate(20, 80)">
<use xlink:href="#diagram-b"/>
<path d="m40 0v60" class="diagram-d"/>
</g>
<g transform="translate(120, 80)">
<use xlink:href="#diagram-b"/>
<path d="m60 0v20h-20v20h-20v20" class="diagram-d"/>
</g>
<g transform="translate(220, 80)">
<use xlink:href="#diagram-b"/>
<path d="m20 0v20h20v20h20v20" class="diagram-d"/>
</g>
<g transform="translate(320, 80)">
<use xlink:href="#diagram-b"/>
<path d="m0 20h20v20h20v-20h20v20h20" class="diagram-d"/>
</g>
<g transform="translate(420, 80)">
<use xlink:href="#diagram-b"/>
<path d="m0 40h20v-20h20v20h20v-20h20" class="diagram-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;
}
```

View File

@ -0,0 +1,90 @@
---
id: 59669d08d75b60482359409f
title: Date format
challengeType: 5
forumTopicId: 302243
dashedName: date-format
---
# --description--
Return an array with two date strings of the current date with the following specifications:
- The first string's date order should be the year number, month number, and day number separated by dashes (`-`).
- The first string's year should be four digits in length.
- The first string's month and day should not contain any leading zeros.
- The second string's weekday and month names should not be abbreviated.
- The second string's day should not contain any leading zeros.
Example outputs:
```js
['2007-11-23', 'Friday, November 23, 2007']
['2021-3-2', 'Tuesday, March 2, 2021']
```
# --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];
}
```

View File

@ -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`;
}
```

View File

@ -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;
}
```

View File

@ -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;
}
```

View File

@ -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));
}
```

View File

@ -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(); };
```

View File

@ -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;
}
```

View File

@ -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 + '!' : '')
;
}
```

View File

@ -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;
}
```

View File

@ -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;
}
```

View File

@ -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],false)` 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;
}
}
```

View File

@ -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;
}
```

View File

@ -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;
}
```

View File

@ -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];
}
```

View File

@ -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 [this article](https://www.freecodecamp.org/news/eulers-method-explained-with-examples/ "news: Euler's Method Explained with Examples").
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;
}
```

View File

@ -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;
}
```

View File

@ -0,0 +1,246 @@
---
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&#x3A;//en.wikipedia.org/wiki/Turing_machine"), implementing a three-state [busy beaver](http://en.wikipedia.org/wiki/Busy_beaver "link: http&#x3A;//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;
}
```

View File

@ -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>&lt;</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,"&amp;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;
}
```

View File

@ -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;
}
}
```

View File

@ -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;
}
```

View File

@ -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>p</sup>-1</code>.
# --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 the string `M3 = 2^3-1 is prime`.
```js
assert.equal(check_mersenne(3), 'M3 = 2^3-1 is prime');
```
`check_mersenne(23)` should return the string `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 the string `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;
}
```

View File

@ -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;
}
```

View File

@ -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;
}
```

View File

@ -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);
}
}
```

View File

@ -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;
}
```

View File

@ -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;
}
```

View File

@ -0,0 +1,92 @@
---
id: 5e9ddb06ec35240f39657419
title: FizzBuzz 問題
challengeType: 5
forumTopicId: 385370
dashedName: fizzbuzz
---
# --description--
1 から 100 までの整数の配列を生成するプログラムを記述します。 ただし、
<ul>
<li>3の倍数の場合は、数値ではなく、<code>"Fizz"</code> を配列に 追加します</li>
<li>5の倍数の場合は、数値ではなく、<code>"Buzz"</code> を配列に 追加します</li>
<li>3と5の倍数の場合は、数値ではなく、<code>"FizzBuzz"</code> を配列に 追加します</li>
</ul>
# --instructions--
上記のルールに基づく結果を含む配列を返すプログラムを記述してください。
# --hints--
`fizzBuzz` は関数とします。
```js
assert(typeof fizzBuzz == 'function');
```
`fizzBuzz()` は配列を返す必要があります。
```js
assert(Array.isArray(fizzBuzz()) == true);
```
3 でのみ割り切れる数値は、 `"Fizz"` を返す必要があります。
```js
assert.equal(fizzBuzz()[2], 'Fizz');
```
5 でのみ割り切れる数値は、 `"Buzz"` を返す必要があります。
```js
assert.equal(fizzBuzz()[99], 'Buzz');
```
3と5 の両方で割り切れる数値は、 `"FizzBuzz"` を返す必要があります。
```js
assert.equal(fizzBuzz()[89], 'FizzBuzz');
```
3 または 5のいずれでも割り切れない数値は、その数値自体を返す必要があります。
```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;
}
```

View File

@ -0,0 +1,139 @@
---
id: 5a7dad05be01840e1778a0d1
title: FRACTRAN
challengeType: 5
forumTopicId: 302270
dashedName: fractran
---
# --description--
[FRACTRAN](https://en.wikipedia.org/wiki/FRACTRAN "wp: FRACTRAN") は、数学者 [ジョン・ホートン・コンウェイ](https://en.wikipedia.org/wiki/John Horton Conway "wp: John Horton Conway") 氏によって発明されたチューリング完全で難解なプログラミング言語です。
FRACTRAN プログラムは、最初の正の整数入力 $n$ を含む、正の分数$P = (f_1, f_2, \\ldots, f_m)$の順序付きリストです。
このプログラムは、整数 $n$ を以下のように更新することで実行されます。
<ul>
<li>$nf_i$ が整数であるリストの最初の分数の $f_i$では、 $n$ を $nf_i$ に置き換えます。</li>
<li>$n$を掛けた場合にリスト内の分数が整数を生成しなくなるまで、このルールをくり返した後、停止します。</li>
</ul>
コンウェイ氏は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}$
$n=2$から開始して、このFRACTRANプログラムは $n$を $15=2\\times (\\frac{15}{2})$, に、その後、$825=15\\times (\\frac{55}{1})$に変更し、 以下の整数数列を生成します。
$2$, $15$, $825$, $725$, $1925$, $2275$, $425$, $390$, $330$, $290$, $770$, $\\ldots$
2 の後には、この数列には以下の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$
これは2の素数の累乗です。
# --instructions--
FRACTRANプログラムを文字列パラメータとして取り、プログラムが生成する最初の10個の数値を配列として返す関数を記述してください。 結果が 10 個の数値を持たない場合は、数値をそのまま返します。
# --hints--
`fractran` は関数とします。
```js
assert(typeof fractran == 'function');
```
`fractran("3/2, 1/3")` は配列を返す必要があります。
```js
assert(Array.isArray(fractran('3/2, 1/3')));
```
`fractran("3/2, 1/3")` は、`[ 2, 3, 1 ]`を返す必要があります。
```js
assert.deepEqual(fractran('3/2, 1/3'), [2, 3, 1]);
```
`fractran("3/2, 5/3, 1/5")` は、 `[ 2, 3, 5, 1 ]`を返す必要があります。
```js
assert.deepEqual(fractran('3/2, 5/3, 1/5'), [2, 3, 5, 1]);
```
`fractran("3/2, 6/3")` は、`[ 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")` は、 `[ 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")` は、 `[ 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;
}
```

View File

@ -0,0 +1,104 @@
---
id: 5a23c84252665b21eecc7e76
title: ガンマ関数
challengeType: 5
forumTopicId: 302271
dashedName: gamma-function
---
# --description--
1 つのアルゴリズム (またはそれ以上) を実装して、 [ガンマ](https://en.wikipedia.org/wiki/Gamma function) ($\\Gamma$) 関数を計算します(実体においてのみ)。
ガンマ関数は次のように定義できます。
<div style='padding-left: 4em;'><big><big>$\Gamma(x) = \displaystyle\int_0^\infty t^{x-1}e^{-t} dt$</big></big></div>
# --hints--
`gamma` は関数とします。
```js
assert(typeof gamma == 'function');
```
`gamma(.1)` は数値を返す必要があります。
```js
assert(typeof gamma(0.1) == 'number');
```
`gamma(.1)` は、`9.513507698668736`を返す必要があります。
```js
assert.equal(round(gamma(0.1)), round(9.513507698668736));
```
`gamma(.2)` は、`4.590843711998803`を返す必要があります。
```js
assert.equal(round(gamma(0.2)), round(4.590843711998803));
```
`gamma(.3)` は、`2.9915689876875904`を返す必要があります。
```js
assert.equal(round(gamma(0.3)), round(2.9915689876875904));
```
`gamma(.4)` は、`2.218159543757687`を返す必要があります。
```js
assert.equal(round(gamma(0.4)), round(2.218159543757687));
```
`gamma(.5)` は、 `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;
}
```

View File

@ -0,0 +1,230 @@
---
id: 5a23c84252665b21eecc7e77
title: ガウスの消去法
challengeType: 5
forumTopicId: 302272
dashedName: gaussian-elimination
---
# --description--
ガウスの消去法を用い、後退代入で\\(Ax = b\\) を解く関数を記述します。
\\(A\\) は \\(n \\times n\\) 行列とします。 また、\\(x\\) と \\(b\\) は \\(n\\) に 1ベクトルを掛けます。
精度を向上させるために、部分ピボット選択とスケーリングを使用してください。
# --hints--
`gaussianElimination` は関数とします。
```js
assert(typeof gaussianElimination == 'function');
```
`gaussianElimination([[1,1],[1,-1]], [5,1])`は、配列を返す必要があります。
```js
assert(
Array.isArray(
gaussianElimination(
[
[1, 1],
[1, -1]
],
[5, 1]
)
)
);
```
`gaussianElimination([[1,1],[1,-1]], [5,1])` は、`[ 3, 2 ]`を返す必要があります。
```js
assert.deepEqual(
gaussianElimination(
[
[1, 1],
[1, -1]
],
[5, 1]
),
[3, 2]
);
```
`gaussianElimination([[2,3],[2,1]] , [8,4])` は、`[ 1, 2 ]`を返す必要があります。
```js
assert.deepEqual(
gaussianElimination(
[
[2, 3],
[2, 1]
],
[8, 4]
),
[1, 2]
);
```
`gaussianElimination([[1,3],[5,-2]], [14,19])``[ 5, 3 ]`を返す必要があります。
```js
assert.deepEqual(
gaussianElimination(
[
[1, 3],
[5, -2]
],
[14, 19]
),
[5, 3]
);
```
`gaussianElimination([[1,1],[5,-1]] , [10,14])``[ 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])` は、`[ 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)
}
```

View File

@ -0,0 +1,175 @@
---
id: 5a23c84252665b21eecc7e78
title: 一般的な FizzBuzz プログラム
challengeType: 5
forumTopicId: 302273
dashedName: general-fizzbuzz
---
# --description--
[FizzBuzz](https://rosettacode.org/wiki/FizzBuzz) プログラムの一般化されたバージョンを記述します。このバージョンは、倍数と単語を含むあらゆるリストに適しています。
これは基本的に、このゲームのルールをユーザーに提供する "fizzbuzz" 実装です。 これを実装する関数を作成します。 この関数は 2 つのパラメーターを取得する必要があります。
1つ目は、FizzBuzz ルールの配列です。 例: `[ [3, "Fizz"] , [5, "Buzz"] ]`.
これは、数値が 3 の倍数の場合、 `Fizz` が出力され、5の倍数の場合、 `Buzz` が出力されることを示します。 両方の倍数であれば、文字列は配列で指定された順番で連結される必要があります。 このケースでは、数値が 3 と 5 の倍数の場合、 `FizzBuzz` となります。
2 つ目のパラメーターは、関数が上記のように文字列を返す対象となる数値です。
# --hints--
`genFizzBuzz` は関数とします。
```js
assert(typeof genFizzBuzz == 'function');
```
`genFizzBuzz([[3, "Fizz"],[5, "Buzz"]], 6)` は文字列を返す必要があります。
```js
assert(
typeof genFizzBuzz(
[
[3, 'Fizz'],
[5, 'Buzz']
],
6
) == 'string'
);
```
`genFizzBuzz([[3, "Fizz"],[5, "Buzz"]], 6)``"Fizz"`を返す必要があります。
```js
assert.equal(
genFizzBuzz(
[
[3, 'Fizz'],
[5, 'Buzz']
],
6
),
'Fizz'
);
```
`genFizzBuzz([[3, "Fizz"],[5, "Buzz"]], 10)``"Buzz"`を返す必要があります。
```js
assert.equal(
genFizzBuzz(
[
[3, 'Fizz'],
[5, 'Buzz']
],
10
),
'Buzz'
);
```
`genFizzBuzz([[3, "Buzz"],[5, "Fizz"]], 12)` は、`"Buzz"`を返す必要があります。
```js
assert.equal(
genFizzBuzz(
[
[3, 'Buzz'],
[5, 'Fizz']
],
12
),
'Buzz'
);
```
`genFizzBuzz([[3, "Buzz"],[5, "Fizz"]], 13)``"13"`を返す必要があります。
```js
assert.equal(
genFizzBuzz(
[
[3, 'Buzz'],
[5, 'Fizz']
],
13
),
'13'
);
```
`genFizzBuzz([[3, "Buzz"],[5, "Fizz"]], 15)``"BuzzFizz"`を返す必要があります。
```js
assert.equal(
genFizzBuzz(
[
[3, 'Buzz'],
[5, 'Fizz']
],
15
),
'BuzzFizz'
);
```
`genFizzBuzz([[3, "Fizz"],[5, "Buzz"]], 15)``"FizzBuzz"`を返す必要があります。
```js
assert.equal(
genFizzBuzz(
[
[3, 'Fizz'],
[5, 'Buzz']
],
15
),
'FizzBuzz'
);
```
`genFizzBuzz([[3, "Fizz"],[5, "Buzz"],[7, "Baxx"]], 105)``"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;
}
```

View File

@ -0,0 +1,99 @@
---
id: 5a23c84252665b21eecc7e7a
title: 小文字の ASCII アルファベットを生成する
challengeType: 5
forumTopicId: 302274
dashedName: generate-lower-case-ascii-alphabet
---
# --description--
与えられた範囲の小文字の ASCII 文字の配列を生成する関数を記述します。 例えば、範囲 `['a', 'd']`を指定すると、関数は `['a', 'b', 'c', 'd']` を返します。
# --hints--
`lascii` は関数とします。
```js
assert(typeof lascii == 'function');
```
`lascii("a","d")` は配列を返す必要があります。
```js
assert(Array.isArray(lascii('a', 'd')));
```
`lascii('a','d')``[ 'a', 'b', 'c', 'd' ]`を返す必要があります。
```js
assert.deepEqual(lascii('a', 'd'), results[0]);
```
`lascii('c','i')``[ 'c', 'd', 'e', 'f', 'g', 'h', 'i' ]`を返す必要があります。
```js
assert.deepEqual(lascii('c', 'i'), results[1]);
```
`lascii('m','q')``[ 'm', 'n', 'o', 'p', 'q' ]`を返す必要があります。
```js
assert.deepEqual(lascii('m', 'q'), results[2]);
```
`lascii('k','n')``[ 'k', 'l', 'm', 'n' ]`を返す必要があります。
```js
assert.deepEqual(lascii('k', 'n'), results[3]);
```
`lascii('t','z')``[ '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);
}
```

View File

@ -0,0 +1,117 @@
---
id: 5a23c84252665b21eecc7e7b
title: ジェネレータ/指数関数
challengeType: 5
forumTopicId: 302275
dashedName: generatorexponential
---
# --description--
ジェネレータは、一連の値を1度に1つずつ生成するコードを含む実行可能なエンティティ (関数やプロシージャのような) であり、ジェネレータを呼び出すたびに、数列内の次の値を返します。
ジェネレータは、オブジェクトの内部状態が「自然に」処理されるように、しばしば、コルーチンやオブジェクトに追加して作成されます。
ジェネレータは、数列が無限になる可能性がある場合、 そして最小限の状態さえあれば、数列の次の値を生成することが可能な場合によく使用されます。
# --instructions--
ジェネレータを使って正方形や立方体を生成する関数を記述してください。 正方形のジェネレータからすべての立方体をフィルタリングする新しいジェネレータを作成します。
この関数は、フィルタリングされたジェネレータの \\( n^{th} \\) 値を返します。
例えば、\\(n=7\\) の場合、数列は4,9,16,25,36,49,81となるため、この関数は81を返すことになります。 ここで、64は立方体であるため除外されます。
# --hints--
`exponentialGenerator` は関数とします。
```js
assert(typeof exponentialGenerator == 'function');
```
`exponentialGenerator()` は数値を返す必要があります。
```js
assert(typeof exponentialGenerator(10) == 'number');
```
`exponentialGenerator(10)``144`を返す必要があります。
```js
assert.equal(exponentialGenerator(10), 144);
```
`exponentialGenerator(12)``196`を返す必要があります。
```js
assert.equal(exponentialGenerator(12), 196);
```
`exponentialGenerator(14)``256`を返す必要があります。
```js
assert.equal(exponentialGenerator(14), 256);
```
`exponentialGenerator(20)``484`を返す必要があります。
```js
assert.equal(exponentialGenerator(20), 484);
```
`exponentialGenerator(25)``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;
}
```

View File

@ -0,0 +1,122 @@
---
id: 5a23c84252665b21eecc7e80
title: グレイコード
challengeType: 5
forumTopicId: 302276
dashedName: gray-code
---
# --description--
[グレイコード](https://en.wikipedia.org/wiki/Gray code)はバイナリエンコーディングの一形態で、連続する数値の変化が 1 ビットのみとなっています。
これは、急速に変化する値を持つ場合や入力時に動作の遅いハードウェアに接続する場合に、ハードウェアのデータハザードを減少させるのに役立つエンコーディングです。
また、 [カルノー図](https://en.wikipedia.org/wiki/Karnaugh map) への入力を左から右へ、または上から下へと順に生成するのにも便利です。
# --instructions--
数値をグレイコードにエンコードし、グレイコードから数値にデコードする関数を作成してください。 この関数は 2 つのパラメーターを取得する必要があります。
1つ目はブール値です。 この関数は true の場合にエンコードし、false の場合にデコードします。 2 つ目のパラメータはエンコード/デコードされる数値です。
すべての 5 ビット 2 進数 (0-31 を含む、最初の 0 は省略可) の通常のバイナリ表現、グレイコード表現、およびグレイコードからデコードされた値を表示します。
グレイコードには様々な方法があります。 以下は、「交番二進グレイコード」と呼ばれるエンコードです。
エンコーディング (最上位ビットはビット 0、b はバイナリ、g はグレイコード):
<pre>if b[i-1] = 1
g[i] = not b[i]
else
g[i] = b[i]
</pre>
または:
<pre>g = b xor (b を論理的に 1 回右シフト)
</pre>
デコーディング (最上位ビットはビット 0、b はバイナリ、g はグレイコード):
<pre>b[0] = g[0]<br>
for other bits:
b[i] = g[i] xor b[i-1]
</pre>
# --hints--
`gray` は関数とします。
```js
assert(typeof gray == 'function');
```
`gray(true,177)` は数値を返す必要があります。
```js
assert(typeof gray(true, 177) == 'number');
```
`gray(true,177)``233`を返す必要があります。
```js
assert.equal(gray(true, 177), 233);
```
`gray(true,425)``381`を返す必要があります。
```js
assert.equal(gray(true, 425), 381);
```
`gray(true,870)``725`を返す必要があります。
```js
assert.equal(gray(true, 870), 725);
```
`gray(false,233)``177`を返す必要があります。
```js
assert.equal(gray(false, 233), 177);
```
`gray(false,381)``425`を返す必要があります。
```js
assert.equal(gray(false, 381), 425);
```
`gray(false,725)``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;
}
}
```

View File

@ -0,0 +1,79 @@
---
id: 5a23c84252665b21eecc7e82
title: 最大公約数
challengeType: 5
forumTopicId: 302277
dashedName: greatest-common-divisor
---
# --description--
2つの整数の最大公約数を返す関数を記述します。
# --hints--
`gcd`は関数とします。
```js
assert(typeof gcd == 'function');
```
`gcd(24,36)` は数値を返す必要があります。
```js
assert(typeof gcd(24, 36) == 'number');
```
`gcd(24,36)``12`を返す必要があります。
```js
assert.equal(gcd(24, 36), 12);
```
`gcd(30,48)``6`を返す必要があります。
```js
assert.equal(gcd(30, 48), 6);
```
`gcd(10,15)``5`を返す必要があります。
```js
assert.equal(gcd(10, 15), 5);
```
`gcd(100,25)``25`を返す必要があります。
```js
assert.equal(gcd(100, 25), 25);
```
`gcd(13,250)``1`を返す必要があります。
```js
assert.equal(gcd(13, 250), 1);
```
`gcd(1300,250)``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);
}
```

View File

@ -0,0 +1,113 @@
---
id: 5a23c84252665b21eecc7e84
title: 最大部分配列
challengeType: 5
forumTopicId: 302278
dashedName: greatest-subsequential-sum
---
# --description--
与えられた整数の数列において、その要素の和が最大となる部分配列を求めます。 つまり、他の単一の部分配列の合計値がこの部分配列の合計値より大きくなることはありません。
空の部分配列は、\\( 0 \\); の和を取るとみなされるため、すべての要素が負の場合、結果は空の数列でなければなりません。
# --hints--
`maximumSubsequence` は関数とします。
```js
assert(typeof maximumSubsequence == 'function');
```
`maximumSubsequence([ 1, 2, -1, 3, 10, -10 ])` は配列を返す必要があります。
```js
assert(Array.isArray(maximumSubsequence([1, 2, -1, 3, 10, -10])));
```
`maximumSubsequence([ 1, 2, -1, 3, 10, -10 ])``[ 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 ])``[ 0, 8, 10 ]`を返す必要があります。
```js
assert.deepEqual(maximumSubsequence([0, 8, 10, -2, -4, -1, -5, -3]), [
0,
8,
10
]);
```
`maximumSubsequence([ 9, 9, -10, 1 ])``[ 9, 9 ]`を返す必要があります。
```js
assert.deepEqual(maximumSubsequence([9, 9, -10, 1]), [9, 9]);
```
`maximumSubsequence([ 7, 1, -5, -3, -8, 1 ])``[ 7, 1 ]`を返す必要があります。
```js
assert.deepEqual(maximumSubsequence([7, 1, -5, -3, -8, 1]), [7, 1]);
```
`maximumSubsequence([ -3, 6, -1, 4, -4, -6 ])``[ 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 ])``[ 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;
}
```

View File

@ -0,0 +1,98 @@
---
id: 595608ff8bcd7a50bd490181
title: ヘイルストーンシーケンス (コラッツ数列)
challengeType: 5
forumTopicId: 302279
dashedName: hailstone-sequence
---
# --description--
ヘイルストーンシーケンスの数列は、正の整数 `n` を初期値として生成され、n は以下のいずれかになります:
- `n``1` の場合、この数列は終了します
- `n``even` (偶数) の場合、シーケンスの 次の `n``= n/2`
- `n``odd` (奇数) の場合、シーケンスの次の `n``= (3 * n) + 1`
コラッツの予想 (証明されていない) では、初期値が何であれ、ヘイルストーンシーケンスは常に終了するとされています。
ヘイルストーンシーケンスは、ヘイルストーン数としても知られています (値が通常は雲の中の雹 (ヘイルストーン) のように何度も上下するためです)。 あるいはコラッツ数列とも呼ばれます。
# --instructions--
1. ある数値のヘイルストーンシーケンスを生成するルーチンを作成してください。
2. この関数は、最長のヘイルストーンシーケンスを取る `limit` 未満の数とそのシーケンスの長さを持つ配列を返す必要があります。 (ただし、実際のシーケンスは表示しないでください!)
# --hints--
`hailstoneSequence` は関数とします。
```js
assert(typeof hailstoneSequence === 'function');
```
`hailstoneSequence(30)` は配列を返す必要があります。
```js
assert(Array.isArray(hailstoneSequence(30)));
```
`hailstoneSequence(30)``[27, 112]`を返す必要があります。
```js
assert.deepEqual(hailstoneSequence(30), [27, 112]);
```
`hailstoneSequence(50000)``[35655, 324]`を返す必要があります。
```js
assert.deepEqual(hailstoneSequence(50000), [35655, 324]);
```
`hailstoneSequence(100000)``[77031, 351]`を返す必要があります。
```js
assert.deepEqual(hailstoneSequence(100000), [77031, 351]);
```
# --seed--
## --seed-contents--
```js
function hailstoneSequence(limit) {
const res = [];
return res;
}
```
# --solutions--
```js
function hailstoneSequence (limit) {
function hailstone(n) {
const seq = [n];
while (n > 1) {
n = n % 2 ? 3 * n + 1 : n / 2;
seq.push(n);
}
return seq;
}
let n = 0;
let max = 0;
for (let i = limit; --i;) {
const seq = hailstone(i);
const sLen = seq.length;
if (sLen > max) {
n = i;
max = sLen;
}
}
return [n, max];
}
```

View File

@ -0,0 +1,129 @@
---
id: 594810f028c0303b75339ad1
title: ハッピー数
challengeType: 5
forumTopicId: 302280
dashedName: happy-numbers
---
# --description--
[ハッピー数](https://en.wikipedia.org/wiki/Happy_number) は次のプロセスで定義されます。
任意の正の整数から開始して、その各桁をそれぞれ 2 乗して足した数で置き換え、この数が `1` に等しくなる (1 からは変化しない) か、`1`を含まないサイクルで無限ループするまでこのプロセスを繰り返します。 このプロセスが`1`で終わる場合の数字がハッピー数となり、`1`で終わらない場合はアンハッピー数となります。
# --instructions--
数値がハッピー数なら true を返し、そうでない場合は false を返す関数を作成してください。
# --hints--
`happy` は関数とします。
```js
assert(typeof happy === 'function');
```
`happy(1)` はブール値を返す必要があります。
```js
assert(typeof happy(1) === 'boolean');
```
`happy(1)``true`を返す必要があります。
```js
assert(happy(1));
```
`happy(2)``false`を返す必要があります。
```js
assert(!happy(2));
```
`happy(7)``true`を返す必要があります。
```js
assert(happy(7));
```
`happy(10)``true`を返す必要があります。
```js
assert(happy(10));
```
`happy(13)``true`を返す必要があります。
```js
assert(happy(13));
```
`happy(19)``true`を返す必要があります。
```js
assert(happy(19));
```
`happy(23)``true`を返す必要があります。
```js
assert(happy(23));
```
`happy(28)``true`を返す必要があります。
```js
assert(happy(28));
```
`happy(31)``true`を返す必要があります。
```js
assert(happy(31));
```
`happy(32)``true`を返す必要があります。
```js
assert(happy(32));
```
`happy(33)``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);
}
```

View File

@ -0,0 +1,87 @@
---
id: 595668ca4cfe1af2fb9818d4
title: ハーシャッド数 (ニーベン数)
challengeType: 5
forumTopicId: 302281
dashedName: harshad-or-niven-series
---
# --description--
ハーシャッド数またはニーベン数とは、自身の各桁の和で割り切れる1以上の正の整数です。
例えば、 `42` は、 `42``(4 + 2)` で割り切れるため、ハーシャッド数です。
この級数が昇順の数値として定義されていると仮定します。
# --instructions--
ハーシャッド数列の連続した要素を生成する関数を作成してください。
この関数を使用して、`n`より大きなハーシャッド数で始まる、ハーシャッド数列要素を10個持つ配列を返します。
# --hints--
`isHarshadOrNiven` は関数とします。
```js
assert(typeof isHarshadOrNiven === 'function');
```
`isHarshadOrNiven(10)``[12, 18, 20, 21, 24, 27, 30, 36, 40, 42]`を返す必要があります。
```js
assert.deepEqual(isHarshadOrNiven(10), [12, 18, 20, 21, 24, 27, 30, 36, 40, 42]);
```
`isHarshadOrNiven(400)``[402, 405, 407, 408, 410, 414, 420, 423, 432, 440]`を返す必要があります。
```js
assert.deepEqual(isHarshadOrNiven(400), [402, 405, 407, 408, 410, 414, 420, 423, 432, 440]);
```
`isHarshadOrNiven(1000)``[1002, 1008, 1010, 1011, 1012, 1014, 1015, 1016, 1017, 1020]`を返す必要があります。
```js
assert.deepEqual(isHarshadOrNiven(1000), [1002, 1008, 1010, 1011, 1012, 1014, 1015, 1016, 1017, 1020]);
```
# --seed--
## --seed-contents--
```js
function isHarshadOrNiven(n) {
const res = [];
return res;
}
```
# --solutions--
```js
function isHarshadOrNiven(n) {
function isHarshad(num) {
let s = 0;
const nStr = num.toString();
for (let i = 0; i < nStr.length; ++i) {
s += parseInt(nStr.charAt(i), 10);
}
return n % s === 0;
}
const res = [];
let count = 0;
while (count < 10) {
n++;
if (isHarshad(n)) {
count++;
res.push(n);
}
}
return res;
}
```

View File

@ -0,0 +1,105 @@
---
id: 595671d4d2cdc305f0d5b36f
title: 2つの配列からハッシュを作成する
challengeType: 5
forumTopicId: 302283
dashedName: hash-from-two-arrays
---
# --description--
長さの等しい 2 つの配列を使用して、1 つの配列の要素 (キー) が他方の要素 (値) にリンクしているハッシュオブジェクトを作成します。
**関連タスク:**
<ul>
<li><a href='https://rosettacode.org/wiki/Associative arrays/Creation' title='連想配列/作成' target='_blank'>連想配列/作成</a></li>
</ul>
# --hints--
`arrToObj` は関数とします。
```js
assert(typeof arrToObj === 'function');
```
`arrToObj([1, 2, 3, 4, 5], ["a", "b", "c", "d", "e"])``{ 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"])``{ 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"])``{ 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])``{ "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])``{ "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])``{ "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;
}, {});
}
```

View File

@ -0,0 +1,237 @@
---
id: 5956795bc9e2c415eb244de1
title: ハッシュ結合 (hash join)
challengeType: 5
forumTopicId: 302284
dashedName: hash-join
---
# --description--
[内部結合 (inner join)](https://www.freecodecamp.org/news/sql-join-types-inner-join-vs-outer-join-example/#how-to-use-an-inner-join-in-sql "news: SQL Join Types Inner Join VS Outer Join Example#How to Use an INNER JOIN in SQL") は、一致している列の値に基づいて、2つのデータテーブルを1つのテーブルに結合する操作です。 この操作を実行する最も簡単な方法は、 [nested loop join](https://en.wikipedia.org/wiki/Nested loop join "wp: Nested loop join") アルゴリズムを使用する方法ですが、 よりスケーラブルな代替方法として、[hash join](https://en.wikipedia.org/wiki/hash join "wp: hash join") アルゴリズムを使用する方法が挙げられます。
「hash join」アルゴリズムは次の 2 つのステップで構成されています。
<ol>
<li><strong>Hash phase:</strong> 2つのテーブルのいずれかから <a href='https://en.wikipedia.org/wiki/Multimap' title='wp: Multimap' target='_blank'>multimap</a> を作成し、 各結合列の値をそれを含むすべての行にマッピングします。</li>
<ul>
<li>multimapは単純な線形探索よりもスケーラブルなハッシュベースの探索をサポートする必要があります。それこそが、このアルゴリズムの肝要な点だからです。</li>
<li>理想としては、小さい方のテーブルのmultimapを作成することを推奨します。これにより、作成時間とメモリサイズを最小化できます。</li>
</ul>
<li><strong>join phase:</strong> もう一方のテーブルをスキャンし、作成しておいたmultimapを参照して一致する行を見つけます。</li>
</ol>
擬似コードでは、このアルゴリズムは以下のように表現できます。
<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--
「ハッシュ結合」アルゴリズムを関数として作成し、以下のテストケースで実行してみてください。 この関数は、オブジェクトの2つの配列を受け取り、結合されたオブジェクトの配列を返します。
**入力**
<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> (例:列 1)</i>
</td>
<td style="border:none">
<i>j<sub>B</sub> =</i>
</td>
<td style="border:none">
<i><code>Character</code> (例:列 0)</i>
</td>
</tr>
</table>
</td>
</tr>
</table>
**出力**
| 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 |
出力テーブルの行の順序は重要ではありません。
# --hints--
`hashJoin` は関数とします。
```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" }])` は、`[{"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');
}
```

View File

@ -0,0 +1,155 @@
---
id: 595b98f8b5a2245e243aa831
title: ヘロンの三角形
challengeType: 5
forumTopicId: 302285
dashedName: heronian-triangles
---
# --description--
三角形の面積についての[ヘロンの公式](https://en.wikipedia.org/wiki/Heron's formula "wp: Heron's formula")は、3辺の長さが `a``b``c` である場合、以下のとおりです。
$A = \\sqrt{s(s-a)(s-b)(s-c)},$
`s` は三角形の周囲の半分です。つまり、
$s=\\frac{a+b+c}{2}.$
ヘロンの三角形は、その辺と面積がすべて整数である三角形です。
例として、辺が `3, 4, 5` でその面積が`6` (そして、その周囲が`12`) の三角形が挙げられます。
辺が`6, 8, 10,`のように、`3, 4, 5`の整数の倍数である三角形もすべてヘロンの三角形となることを覚えておいてください。
原始ヘロン三角形を
3辺の最大公約数が `1` (単一) であるヘロン三角形として定義します。
例えば、`6, 8, 10.`の三角形はこれに当てはまりません。
# --instructions--
配列の配列の中にある最初の<code>n<sub>th</sub></code>番目までの三角形を返す、ヘロンの公式に基づく関数を作成してください。
# --hints--
`heronianTriangle` は関数とします。
```js
assert(typeof heronianTriangle === 'function');
```
`heronianTriangle(10)` は、`[[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)` は、`[[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)` は、`[[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)` は 、`[[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;
}
}
}
}
}
```

View File

@ -0,0 +1,166 @@
---
id: 59622f89e4e137560018a40e
title: ホフスタッターフィギュア-フィギュア数列 (Hofstadter Figure-Figure sequences)
challengeType: 5
forumTopicId: 302286
dashedName: hofstadter-figure-figure-sequences
---
# --description--
この正の整数の2つの数列は次のように定義されます。
$R(1)=1\\ ;\\ S(1)=2 \\\\R(n)=R(n-1)+S(n-1), \\quad n>1.$
数列 $S(n)$ は $R(n)$ に存在しない正の整数の数列としてさらに定義されます。
数列 $R$ は次のように始まります:
<pre>1, 3, 7, 12, 18, ...</pre>
数列 $S$ は次のように始まります:
<pre>2, 4, 5, 6, 8, ...</pre>
# --instructions--
`n` を与えられると、それぞれ `R(n)` または`S(n)` を返す、`ffr``ffs` という名前の2つの関数を作成してください。 オフバイワンエラーを避けるために、R(1) = 1であり、 S(1) = 2 であることに注意してください。)
`n` の最大値は仮定しないものとします。
**参照**
<ul>
<li>
Sloaneの<a href='https://oeis.org/A005228' target='_blank'>A005228</a><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` は関数とします。
```js
assert(typeof ffr === 'function');
```
`ffs` は関数とします。
```js
assert(typeof ffs === 'function');
```
`ffr` は整数を返す必要があります。
```js
assert(Number.isInteger(ffr(1)));
```
`ffs` は整数を返す必要があります。
```js
assert(Number.isInteger(ffs(1)));
```
`ffr(10)``69`を返す必要があります。
```js
assert.equal(ffr(ffrParamRes[0][0]), ffrParamRes[0][1]);
```
`ffr(50)``1509`を返す必要があります。
```js
assert.equal(ffr(ffrParamRes[1][0]), ffrParamRes[1][1]);
```
`ffr(100)``5764`を返す必要があります。
```js
assert.equal(ffr(ffrParamRes[2][0]), ffrParamRes[2][1]);
```
`ffr(1000)``526334`を返す必要があります。
```js
assert.equal(ffr(ffrParamRes[3][0]), ffrParamRes[3][1]);
```
`ffs(10)``14`を返す必要があります。
```js
assert.equal(ffs(ffsParamRes[0][0]), ffsParamRes[0][1]);
```
`ffs(50)``59`を返す必要があります。
```js
assert.equal(ffs(ffsParamRes[1][0]), ffsParamRes[1][1]);
```
`ffs(100)``112`を返す必要があります。
```js
assert.equal(ffs(ffsParamRes[2][0]), ffsParamRes[2][1]);
```
`ffs(1000)``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];
}
```

View File

@ -0,0 +1,92 @@
---
id: 59637c4d89f6786115efd814
title: ホフスタッター Q 数列
challengeType: 5
forumTopicId: 302287
dashedName: hofstadter-q-sequence
---
# --description--
[ホフスタッター Q 数列](https://en.wikipedia.org/wiki/Hofstadter_sequence#Hofstadter_Q_sequence "wp: Hofstadter_sequence#Hofstadter_Q_sequence") は次のように定義されます。
$Q(1)=Q(2)=1, \\\\ Q(n)=Q\\big(n-Q(n-1)\\big)+Q\\big(n-Q(n-2)), \\quad n>2.$
これは [フィボナッチ数列](https://rosettacode.org/wiki/Fibonacci sequence "Fibonacci sequence")に似た定義ですが、 フィボナッチ数列の次の項が前の2つの項の合計であるのに対し、 Q数列では、前の2つの項は、次の項を作成するために合計する2つの数字を見つけるためにQ数列内で戻る距離を示しています。
# --instructions--
ホフスタッター Q 数列方程式を関数として作成してください。 この関数は、数値`n`を受け取り、整数を返します。
# --hints--
`hofstadterQ` は関数とします。
```js
assert(typeof hofstadterQ === 'function');
```
`hofstadterQ()``integer`を返す必要があります。
```js
assert(Number.isInteger(hofstadterQ(1000)));
```
`hofstadterQ(1000)``502`を返す必要があります。
```js
assert.equal(hofstadterQ(testCase[0]), res[0]);
```
`hofstadterQ(1500)``755`を返す必要があります。
```js
assert.equal(hofstadterQ(testCase[1]), res[1]);
```
`hofstadterQ(2000)``1005`を返す必要があります。
```js
assert.equal(hofstadterQ(testCase[2]), res[2]);
```
`hofstadterQ(2500)``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);
}
```

View File

@ -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--
["I before E, except after C"](https://en.wikipedia.org/wiki/I before E except after C) は広く知られているニーモニック (覚え歌) で、英単語を綴る場合に役立つものです。
与えられた単語を使用して、フレーズの2つの従属節がそれぞれ妥当かどうかを確認します。
<ol>
<li>
<i>「I before E when not before preceded by C」</i>
</li>
<li>
<i>「E before I when preceded by C」</i>
</li>
</ol>
両方の従属節が妥当である場合は、元のフレーズは妥当であると言うことができます。
# --instructions--
単語を受け取り、その単語がルールに従っているかを確認する関数を記述してください。 この関数は、単語がルールに従っていれば true を、そうでない場合は false を返します。
# --hints--
`IBeforeExceptC` は関数とします。
```js
assert(typeof IBeforeExceptC == 'function');
```
`IBeforeExceptC("receive")` はブール値を返す必要があります。
```js
assert(typeof IBeforeExceptC('receive') == 'boolean');
```
`IBeforeExceptC("receive")``true`を返す必要があります。
```js
assert.equal(IBeforeExceptC('receive'), true);
```
`IBeforeExceptC("science")``false`を返す必要があります。
```js
assert.equal(IBeforeExceptC('science'), false);
```
`IBeforeExceptC("imperceivable")``true`を返す必要があります。
```js
assert.equal(IBeforeExceptC('imperceivable'), true);
```
`IBeforeExceptC("inconceivable")``true`を返す必要があります。
```js
assert.equal(IBeforeExceptC('inconceivable'), true);
```
`IBeforeExceptC("insufficient")``false`を返す必要があります。
```js
assert.equal(IBeforeExceptC('insufficient'), false);
```
`IBeforeExceptC("omniscient")``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;
}
```

View File

@ -0,0 +1,104 @@
---
id: 5a23c84252665b21eecc7eaf
title: IBAN国際銀行口座番号
challengeType: 5
forumTopicId: 302289
dashedName: iban
---
# --description--
[International Bank Account Number (IBAN)](https://en.wikipedia.org/wiki/International_Bank_Account_Number) は、国境を越えて銀行口座を特定する国際的に合意された手段であり、 [transcription errors](https://en.wikipedia.org/wiki/Transcription_error) を起こすリスクを減少させます。
IBANは最大で英数字34文字からなります。
<ul>
<li>最初の2文字は、ISO 3166-1 alpha-2 の国コードです。</li>
<li>続いて 2 桁のチェックデジット、</li>
<li>最後に、国ごとの基本銀行口座番号 (BBAN) となっています。</li>
</ul>
チェックデジットにより、トランザクションの送信前であっても、銀行口座番号のサニティーチェックを行いその整合性を確認することが可能です。
# --instructions--
パラメータとしてIBAN文字列を取る関数を記述してください。 有効なら true を、 そうでなければ false を返します。
# --hints--
`isValid` は関数とします。
```js
assert(typeof isValid == 'function');
```
`isValid("GB82 WEST 1234 5698 7654 32")` はブール値を返す必要があります。
```js
assert(typeof isValid('GB82 WEST 1234 5698 7654 32') == 'boolean');
```
`isValid("GB82 WEST 1234 5698 7654 32")``true`を返す必要があります。
```js
assert.equal(isValid('GB82 WEST 1234 5698 7654 32'), true);
```
`isValid("GB82 WEST 1.34 5698 7654 32")``false`を返す必要があります。
```js
assert.equal(isValid('GB82 WEST 1.34 5698 7654 32'), false);
```
`isValid("GB82 WEST 1234 5698 7654 325")``false`を返す必要があります。
```js
assert.equal(isValid('GB82 WEST 1234 5698 7654 325'), false);
```
`isValid("GB82 TEST 1234 5698 7654 32")``false`を返す必要があります。
```js
assert.equal(isValid('GB82 TEST 1234 5698 7654 32'), false);
```
`isValid("SA03 8000 0000 6080 1016 7519")``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
}
```

View File

@ -0,0 +1,88 @@
---
id: 5a23c84252665b21eecc7eb1
title: 単位行列
challengeType: 5
forumTopicId: 302290
dashedName: identity-matrix
---
# --description--
*単位行列* は、サイズ\\( n \\times n \\) の正方行列であり、ここでは、対角線要素はすべて`1`、その他の要素はすべて`0`となります。
<ul>
<li style='list-style: none;'>\(\displaystyle I_{n}=\begin{bmatrix} 1 &#x26; 0 &#x26; 0 \cr 0 &#x26; 1 &#x26; 0 \cr 0 &#x26; 0 &#x26; 1 \cr \end{bmatrix}\)</li>
</ul>
# --instructions--
数値 `n` をパラメータとして取り、(n \\times n \\) 次の単位行列を返す関数を記述してください。
# --hints--
`idMatrix` は関数とします。
```js
assert(typeof idMatrix == 'function');
```
`idMatrix(1)` は配列を返す必要があります。
```js
assert(Array.isArray(idMatrix(1)));
```
`idMatrix(1)``[ [ 1 ] ]`を返す必要があります。
```js
assert.deepEqual(idMatrix(1), results[0]);
```
`idMatrix(2)``[ [ 1, 0 ], [ 0, 1 ] ]`を返す必要があります。
```js
assert.deepEqual(idMatrix(2), results[1]);
```
`idMatrix(3)``[ [ 1, 0, 0 ], [ 0, 1, 0 ], [ 0, 0, 1 ] ]`を返す必要があります。
```js
assert.deepEqual(idMatrix(3), results[2]);
```
`idMatrix(4)``[ [ 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;
})
});
}
```

View File

@ -0,0 +1,96 @@
---
id: 5a23c84252665b21eecc7ec1
title: 各位の2乗を繰り返す
challengeType: 5
forumTopicId: 302291
dashedName: iterated-digits-squaring
---
# --description--
自然数 (0より大きい整数) の各位を2乗して足すと、やがて、常に1か89になります。
<pre>15 -> 26 -> 40 -> 16 -> 37 -> 58 -> 89
7 -> 49 -> 97 -> 130 -> 10 -> 1
</pre>
# --instructions--
パラメータとして数値を取り、上記プロセスを実行した後に 1 または 89 を返す関数を記述してください。
# --hints--
`iteratedSquare` は関数とします。
```js
assert(typeof iteratedSquare == 'function');
```
`iteratedSquare(4)` は数値を返す必要があります。
```js
assert(typeof iteratedSquare(4) == 'number');
```
`iteratedSquare(4)``89`を返す必要があります。
```js
assert.equal(iteratedSquare(4), 89);
```
`iteratedSquare(7)``1`を返す必要があります。
```js
assert.equal(iteratedSquare(7), 1);
```
`iteratedSquare(15)``89`を返す必要があります。
```js
assert.equal(iteratedSquare(15), 89);
```
`iteratedSquare(20)``89`を返す必要があります。
```js
assert.equal(iteratedSquare(20), 89);
```
`iteratedSquare(70)``1`を返す必要があります。
```js
assert.equal(iteratedSquare(70), 1);
```
`iteratedSquare(100)``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;
}
```

View File

@ -0,0 +1,146 @@
---
id: 5a23c84252665b21eecc7ec2
title: ジャロ距離
challengeType: 5
forumTopicId: 302292
dashedName: jaro-distance
---
# --description--
ジャロ距離は、2つの文字列の類似性を測る尺度です。 2つの文字列のジャロ距離が大きいほど、類似性が高くなります。 スコアは、`0` は類似性がなく、 `1` は完全一致であるように正規化されています。
**定義**
2つの指定された文字列 \\(s_1\\) と \\(s_2\\) のジャロ距離 \\( d_j \\) は以下となります。
\\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}
ここでは、
<ul>
<li>\(m\) は <i>一致する文字数 </i> です。</li>
<li> \(t\) は <i>転置</i> の半数です。</li>
</ul>
\\(s_1\\) および \\(s_2\\) の2つの文字はそれぞれ、同じか、\\(\\left\\lfloor\\frac{\\max(|s_1|,|s_2|)}{2}\\right\\rfloor-1\\) よりも離れていない場合にのみ*一致している*とみなされます。
\\(s_1\\) の各文字は、\\(s_2\\) の一致しているすべての文字と対照されます。 一致する文字の数 (ただし、文字列における順序は異なる) を 2 で割ることで、 *転置*の数が定義されます。
**例**
文字列 \\(s_1\\) *DWAYNE* と \\(s_2\\) *DUANE*の場合、以下となります。
<ul>
<li>\(m = 4\)</li>
<li>\(|s_1| = 6\)</li>
<li>\(|s_2| = 5\)</li>
<li>\(t = 0\)</li>
</ul>
ジャロスコアは次のように求められます: \\(d_j = \\frac{1}{3}\\left(\\frac{4}{6} + \\frac{4}{5} + \\frac{4-0}{4}\\right) = 0. 22\\)
# --instructions--
2つの文字列をパラメータとして取り、関連するジャロ距離を返す関数を記述してください。
# --hints--
`jaro` は関数とします。
```js
assert(typeof jaro == 'function');
```
`jaro("MARTHA", "MARHTA")` は数値を返す必要があります。
```js
assert(typeof jaro('MARTHA', 'MARHTA') == 'number');
```
`jaro("MARTHA", "MARHTA")``0.9444444444444445` を返す必要があります。
```js
assert.equal(jaro('MARTHA', 'MARHTA'), 0.9444444444444445);
```
`jaro("DIXON", "DICKSONX")``0.7666666666666666` を返す必要があります。
```js
assert.equal(jaro('DIXON', 'DICKSONX'), 0.7666666666666666);
```
`jaro("JELLYFISH", "SMELLYFISH")``0.8962962962962964` を返す必要があります。
```js
assert.equal(jaro('JELLYFISH', 'SMELLYFISH'), 0.8962962962962964);
```
`jaro("HELLOS", "CHELLO")``0.888888888888889` を返す必要があります。
```js
assert.equal(jaro('HELLOS', 'CHELLO'), 0.888888888888889);
```
`jaro("ABCD", "BCDA")``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;
}
```

View File

@ -0,0 +1,90 @@
---
id: 5a23c84252665b21eecc7ec4
title: JortSort
challengeType: 5
forumTopicId: 302293
dashedName: jortsort
---
# --description--
jortSortは、ユーザーがソート作業に使用するソート用ツールセットで、ソート作業をやり直さずにすむよう効率性を保証します。 もとは権威ある [JSConf](https://www.youtube.com/watch?v=pj4U_W0OFoE) においてJenn "Moneydollars" Schiffer によって提唱されました。
jortSort は、比較可能なオブジェクトの単一の配列を引数として取る関数とします。 その後、配列を昇順にソートし、ソートされた配列を元の配列と比較します。 配列が一致する (つまり、元の配列がすでにソートされていた) 場合、関数は true を返します。 配列が一致しない (つまり、元の配列がソートされていなかった) 場合、関数は false を返します。
# --hints--
`jortsort` は関数とします。
```js
assert(typeof jortsort == 'function');
```
`jortsort([1,2,3,4,5])` はブール値を返す必要があります。
```js
assert(typeof jortsort([1, 2, 3, 4, 5]) == 'boolean');
```
`jortsort([1,2,3,4,5])``true` を返す必要があります。
```js
assert.equal(jortsort([1, 2, 3, 4, 5]), true);
```
`jortsort([1,2,13,4,5])``false` を返す必要があります。
```js
assert.equal(jortsort([1, 2, 13, 4, 5]), false);
```
`jortsort([12,4,51,2,4])``false` を返す必要があります。
```js
assert.equal(jortsort([12, 4, 51, 2, 4]), false);
```
`jortsort([1,2])``true` を返す必要があります。
```js
assert.equal(jortsort([1, 2]), true);
```
`jortsort([5,4,3,2,1])``false` を返す必要があります。
```js
assert.equal(jortsort([5, 4, 3, 2, 1]), false);
```
`jortsort([1,1,1,1,1])``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;
};
```

View File

@ -0,0 +1,98 @@
---
id: 5a23c84252665b21eecc7ec5
title: ヨセフスの問題
challengeType: 5
forumTopicId: 302294
dashedName: josephus-problem
---
# --description--
[ヨセフスの問題](https://en.wikipedia.org/wiki/Josephus problem) とは、次のような恐ろしい描写付きの数学パズルです。$n$ 人の囚人が円状に立っており、$0$ から順に $n-1$ まで番号が付けられています。
死刑執行人が円の周囲を歩きながら、囚人 $0$ から始め、$k$ 番目ごとに囚人を処刑していきます。
死刑の執行が進むにつれ円はどんどん小さくなっていき、最後の1人は釈放されます。
例えば、 $n=5$ 人の囚人がおり、 $k=2$ の場合、囚人が処刑される順番 (「執行シーケンス」と呼ぶことにしましょう) は 1、3、0、4 となり、釈放されるのは 2 番の囚人になります。
任意の $n, k > 0$ が与えられた場合に、どの囚人が最後に生き残るかを求めてみましょう。
このような例の 1 つに、囚人が41 人で、3<sup>rd</sup> 番目の囚人ごとに処刑された ($k=3$) という出来事があります。
そのうちの 1 人がこの問題を解いたヨセフスという賢い人物で、最終的に生き残り、この物語を語り継ぎました。
ヨセフスは何番目だったでしょうか。
# --instructions--
囚人の最初の数と「k」をパラメータとして取り、生き残った囚人の番号を返す関数を記述してください。
# --hints--
`josephus` は関数とします。
```js
assert(typeof josephus == 'function');
```
`josephus(30,3)` は数値を返す必要があります。
```js
assert(typeof josephus(30, 3) == 'number');
```
`josephus(30,3)``28` を返す必要があります。
```js
assert.equal(josephus(30, 3), 28);
```
`josephus(30,5)``2` を返す必要があります。
```js
assert.equal(josephus(30, 5), 2);
```
`josephus(20,2)``8` を返す必要があります。
```js
assert.equal(josephus(20, 2), 8);
```
`josephus(17,6)``1` を返す必要があります。
```js
assert.equal(josephus(17, 6), 1);
```
`josephus(29,4)``1` を返す必要があります。
```js
assert.equal(josephus(29, 4), 1);
```
# --seed--
## --seed-contents--
```js
function josephus(init, kill) {
}
```
# --solutions--
```js
function josephus(init, kill) {
const arr = Array.from(Array(init).keys());
let curr = -1
while (arr.length > 1) {
curr = (curr + kill) % arr.length;
arr.splice(curr, 1);
curr--;
}
return arr[0];
}
```

View File

@ -0,0 +1,469 @@
---
id: 5a23c84252665b21eecc7ecb
title: K-D ツリー
challengeType: 5
forumTopicId: 302295
dashedName: k-d-tree
---
# --description--
k-d ツリー (*k*-次元ツリーの略称) は、k 次元空間の点を整理するためのスペース分割データ構造です。 k-d ツリーは、多次元探索鍵に関わる探索 (例えば、範囲探索や最近傍探索) など、いくつかの応用にとって有用なデータ構造です。 k-d ツリーはバイナリ空間分割ツリーの特殊ケースです。 ただし、k-d ツリーは高次元空間での効率的な最近傍探索には適していません。 原則として、次元が *k* の場合、データ内の点の数 *N* は、*N* ≫ 2<sup><i>k</i></sup> であるべきです。 そうでなければ、k-d ツリーが高次元データで使用される場合、ツリーの点のほとんどを評価することになり、効率はしらみつぶし探索と大差なく、代わりに近似最近傍探索など他の方法が使用されることになります。
# --instructions--
k-d ツリーを使って最近傍探索を実行する関数を記述してください。 関数は次の 2 つのパラメータをとります。k 次元ポイントの配列と、関数が返す最近傍を求めるための単一の k 次元ポイントです。 k 次元ポイントは、k 要素の配列として与えられます。
# --hints--
`kdNN` は関数とします。
```js
assert(typeof kdNN == 'function');
```
`kdNN([[[2, 3], [5, 4], [9, 6], [4, 7], [8, 1], [7, 2]], [9, 2])` は配列を返す必要があります。
```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])``[ 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])``[ 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])``[ 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])``[ 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])``[ 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])``[ 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];
}
```

View File

@ -0,0 +1,110 @@
---
id: 5a23c84252665b21eecc7eca
title: カプレカ数
challengeType: 5
forumTopicId: 302296
dashedName: kaprekar-numbers
---
# --description--
正の整数は以下の場合、[カプレカ数](https://en.wikipedia.org/wiki/Kaprekar number) となります。
<ul>
<li>1 である、または</li>
<li>その数字の2乗の10進数を正の整数の2つの部分に分け、その合計が元の数値に等しくなる </li>
</ul>
ただし、分割された部分が 0 のみであった場合は、0 は正とはみなされないため、無効となることに注意してください。
カプレカ数の例:
<ul>
<li><code>2223</code> は以下のとおりカプレカ数です。<code>2223 * 2223 = 4941729</code> であり、<code>4941729</code><code>494</code><code>1729</code> に分割でき、かつ <code>494 + 1729 = 2223</code> となります。</li>
<li>カプレカ数の数列は <a href='https://oeis.org/A006886' target='_blank'>A006886</a> として知られており、<code>1, 9, 45, 55, ...</code> で始まります。</li>
</ul>
# --instructions--
数値 $n$、底 $bs$ を取り、数値が与えられた底に対するカプレカ数の場合は true を返す関数を記述してください。 それ以外の場合、関数は false を返します。
# --hints--
`isKaprekar` は関数とします。
```js
assert(typeof isKaprekar == 'function');
```
`isKaprekar(1, 10)` はブール値を返す必要があります。
```js
assert(typeof isKaprekar(1, 10) == 'boolean');
```
`isKaprekar(1, 10)``true` を返す必要があります。
```js
assert.equal(isKaprekar(1, 10), true);
```
`isKaprekar(9, 10)``true` を返す必要があります。
```js
assert.equal(isKaprekar(9, 10), true);
```
`isKaprekar(2223, 10)``true` を返す必要があります。
```js
assert.equal(isKaprekar(2223, 10), true);
```
`isKaprekar(22823, 10)``false` を返す必要があります。
```js
assert.equal(isKaprekar(22823, 10), false);
```
`isKaprekar(9, 17)``false` を返す必要があります。
```js
assert.equal(isKaprekar(9, 17), false);
```
`isKaprekar(225, 17)``true` を返す必要があります。
```js
assert.equal(isKaprekar(225, 17), true);
```
`isKaprekar(999, 17)``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;
}
```

View File

@ -0,0 +1,255 @@
---
id: 5a23c84252665b21eecc7ed1
title: ナップサック問題 /0-1
challengeType: 5
forumTopicId: 323649
dashedName: knapsack-problem0-1
---
# --description--
0-1 ナップサック問題は以下のように定義されます。
ナップサックに入れるアイテムを表すオブジェクトの配列が与えられます。 オブジェクトにはアイテム名、重量、価値の 3 つの属性があります。 総重量が最大重量を超えず、価値が最大化されるようにアイテムを選択する必要があります。
# --instructions--
ナップサック問題を解決するための関数を記述してください。 この関数には、オブジェクトの配列と最大重量がパラメータとして与えられます。 価値の合計が最大となる値を返す必要があります。
# --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)``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)``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)``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)``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)``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)``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;
}
```

View File

@ -0,0 +1,212 @@
---
id: 5a23c84252665b21eecc7ed2
title: ナップサック問題 / 個数制限付き
challengeType: 5
forumTopicId: 323652
dashedName: knapsack-problembounded
---
# --description--
個数制限付きナップサック問題は以下のように定義されます。
ナップサックに入れるアイテムを表すオブジェクトの配列が与えられます。 オブジェクトにはアイテム名、ピース (特定のアイテムの数)、重量、価値の 4 つの属性があります。 総重量が最大重量を超えず、価値が最大化されるようにアイテムを選択する必要があります。 各アイテムは 0 `pieces` 回の範囲で選択できることに注意してください。
# --instructions--
ナップサック問題を解決するための関数を記述してください。 この関数には、オブジェクトの配列と最大重量がパラメータとして与えられます。 価値の合計が最大となる値を返す必要があります。
# --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)``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)``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)``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)``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)``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;
}
```

View File

@ -0,0 +1,169 @@
---
id: 5a23c84252665b21eecc7ed3
title: ナップサック問題 / 連続
challengeType: 5
forumTopicId: 323654
dashedName: knapsack-problemcontinuous
---
# --description--
泥棒が肉屋に押し入り、商品の中から盗むものを選びます。
泥棒はそれぞれの商品の重量と価格を知っています。 泥棒は耐荷重に制限のあるナップサックを持ち込んでおり、耐えられる重量の範囲内で利益を最大化できる商品を選びたいと考えています。 商品は切ることも可能です。切ると、元の価格に応じ、質量比に合わせて価格が減少します。 つまり、商品を半分に切ると、その価格は元の商品の半値になります。
# --instructions--
店に並んでいる商品を表すオブジェクトの配列を取る関数を記述してください。 各オブジェクトには商品名、重量、価格の 3 つの属性があります。 また、この関数はパラメータとして最大重量を取ります。 関数は価格が最大となる値を返す必要があり、選択した商品の総重量は最大重量を超えてはいけません。
# --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)``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)``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)``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)``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)``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;
}
```

View File

@ -0,0 +1,185 @@
---
id: 5a23c84252665b21eecc7ed4
title: ナップサック問題 / 個数制限なし
challengeType: 5
forumTopicId: 323655
dashedName: knapsack-problemunbounded
---
# --description--
ある旅人が道から外れ、予定外の場所に立ち寄ることを余儀なくされたところ、そこは理想郷だったのです。 その地を離れるにあたり、そこで入手できるアイテムを好きなだけ、ナップサックに入れて運べる限り持って行くことを許されています。
旅人は、合計で最大重量を超えるものを運ぶことができないことを知っていますし、ナップサックの容量は限られています。
アイテムのバーコードのすぐ上を見ると、重量と容量がわかるようになっています。 旅人は持っていた最近の経済紙を探し出して、それぞれのアイテムの価値を把握しました。
どのアイテムもひとまとまり全体を取る必要がありますが、それぞれ、これまで運ぶことのできた量をはるかに超える数量があります。
# --instructions--
オブジェクトの配列、最大重量、最大容量をパラメータとして取る関数を記述してください。 各オブジェクトには アイテム名、価値、重量、容量の 4 つの属性があります。 この関数は、旅人が持っていくことのできるアイテムの価値の最大値を返さなければなりません。
# --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)``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)``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)``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)``75900` を返す必要があります。
```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
),
75900
);
```
`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` を返す必要があります。
```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) {
function getPickTotals(items, pick) {
let totalValue = 0;
let totalWeight = 0;
let totalVolume = 0;
for (let i = 0; i < items.length; i++) {
totalValue += pick[i] * items[i].value;
totalWeight += pick[i] * items[i].weight;
totalVolume += pick[i] * items[i].volume;
}
return [totalValue, totalWeight, totalVolume];
}
function getMaxes(items, maxWeight, maxVolume) {
const maxes = [];
for (let i = 0; i < items.length; i++) {
const maxUnitsInWeight = Math.floor(maxWeight / items[i].weight);
const maxUnitsInVolume = Math.floor(maxVolume / items[i].volume);
const maxUnitsInLimit = Math.min(maxUnitsInWeight, maxUnitsInVolume);
maxes.push(maxUnitsInLimit);
}
return maxes;
}
function isInLimit(value, limit) {
return value <= limit;
}
function getCombinations(maxValues, curPicks, combinations) {
if (maxValues.length === 0) {
combinations.push(curPicks);
}
const curMax = maxValues[0];
const leftMaxValues = maxValues.slice(1);
for (let i = 0; i <= curMax; i++) {
getCombinations(leftMaxValues, curPicks.concat(i), combinations);
}
return combinations;
}
let bestValue = 0;
let bestPick = [];
const maxes = getMaxes(items, maxWeight, maxVolume);
const combinations = getCombinations(maxes, [], []);
for (let i = 0; i < combinations.length; i++) {
const curPick = combinations[i];
const [curValue, curWeight, curVolume] = getPickTotals(items, curPick);
if (!isInLimit(curWeight, maxWeight) || !isInLimit(curVolume, maxVolume)) {
continue;
}
if (curValue > bestValue) {
bestValue = curValue;
bestPick = [curPick];
} else if (curValue === bestValue) {
bestPick.push(curPick);
}
}
return bestValue;
}
```

View File

@ -0,0 +1,225 @@
---
id: 5a23c84252665b21eecc7ed5
title: ナイトツアー
challengeType: 5
forumTopicId: 302297
dashedName: knights-tour
---
# --description--
[ナイトツアー](https://en.wikipedia.org/wiki/Knight%27s_tour)の問題: 空の `w` \* `h` のチェスボードがあり、その上の任意のマスに 1 つのナイトの駒が置いてあります。 ナイトは一連のルールに従って動き、チェスボード上のすべてのマスを 1 度だけ訪れなければなりません。 ツアーを「終了する」必要は*ない*ことに注意してください。つまり、ナイトは開始地点の一手以内を終了地点にする必要はありません。
# --instructions--
パラメータとして `w``h` を取る関数を記述し、上記のタスクの達成が可能な開始位置の数値を返してください。
# --hints--
`knightTour` は関数とします。
```js
assert(typeof knightTour == 'function');
```
`knightTour(6, 6)` は数値を返す必要があります.
```js
assert(typeof knightTour(6, 6) == 'number');
```
`knightTour(6, 6)``36` を返す必要があります。
```js
assert.equal(knightTour(6, 6), 36);
```
`knightTour(5, 6)``30` を返す必要があります。
```js
assert.equal(knightTour(5, 6), 30);
```
`knightTour(4, 6)``12` を返す必要があります。
```js
assert.equal(knightTour(4, 6), 12);
```
`knightTour(7, 3)``10` を返す必要があります。
```js
assert.equal(knightTour(7, 3), 10);
```
`knightTour(8, 6)``48` を返す必要があります。
```js
assert.equal(knightTour(8, 6), 48);
```
# --seed--
## --seed-contents--
```js
function knightTour(w, h) {
}
```
# --solutions--
```js
function knightTour(w, h) {
function createBoards(rows, columns) {
const board = [];
const visited = [];
for (let i = 0; i < rows; i++) {
board.push(new Array(columns).fill(-1));
visited.push(new Array(columns).fill(false));
}
return [board, visited];
}
function copyBoard(board) {
const copied = [];
for (let i = 0; i < board.length; i++) {
copied.push([...board[i]]);
}
return copied;
}
function isOnBoard(value, limit) {
return value >= 0 && value < limit;
}
function markVisited(board, visited, row, column) {
visited[row][column] = true;
board[row][column] = -1;
}
function areAllVisited(visited) {
return (
visited.filter(row => row.filter(column => column === false).length !== 0)
.length === 0
);
}
function getMovesFrom(board, row, column) {
const possibleMoves = [];
for (let i = 0; i < moves.length; i++) {
const [rowChange, colChange] = moves[i];
const [rowN, colN] = [row + rowChange, column + colChange];
if (!isOnBoard(rowN, board.length) || !isOnBoard(colN, board[0].length)) {
continue;
}
possibleMoves.push([rowN, colN]);
}
return possibleMoves;
}
function fillAllowedMovesCounts(board) {
for (let row = 0; row < board.length; row++) {
for (let column = 0; column < board[0].length; column++) {
board[row][column] = getMovesFrom(board, row, column).length;
}
}
}
function updateAllowedMovesCounts(board, possibleMoves) {
for (let i = 0; i < possibleMoves.length; i++) {
const [row, column] = possibleMoves[i];
if (board[row][column] > 0) {
board[row][column]--;
}
}
}
function getBestNextMoves(board, allowedMoves) {
let bestMoves = [];
let fewestNextMoves = Infinity;
let zeroMove = [];
for (let i = 0; i < allowedMoves.length; i++) {
const [moveRow, moveCol] = allowedMoves[i];
const numMoves = board[moveRow][moveCol];
if (numMoves === -1) {
continue;
}
if (numMoves === 0) {
zeroMove.push(allowedMoves[i]);
}
if (numMoves < fewestNextMoves) {
bestMoves = [allowedMoves[i]];
fewestNextMoves = numMoves;
} else if (numMoves === fewestNextMoves) {
bestMoves.push(allowedMoves[i]);
}
}
if (bestMoves.length > 0) {
return bestMoves;
}
return zeroMove;
}
function solve(board, visited, lastRow, lastColumn) {
if (areAllVisited(visited)) {
return true;
}
const nextMoves = getMovesFrom(board, lastRow, lastColumn);
updateAllowedMovesCounts(board, nextMoves);
const allowedMoves = nextMoves.filter(
([row, column]) => !visited[row][column]
);
const bestMoves = getBestNextMoves(board, allowedMoves);
const restMoves = allowedMoves.filter(
move => bestMoves.indexOf(move) === -1
);
const possibleMoves = [...bestMoves];
possibleMoves.push(...getBestNextMoves(board, restMoves));
for (let i = 0; i < possibleMoves.length; i++) {
const [moveRow, moveCol] = possibleMoves[i];
const newBoard = copyBoard(board);
const newVisited = copyBoard(visited);
markVisited(newBoard, newVisited, moveRow, moveCol);
if (solve(newBoard, newVisited, moveRow, moveCol)) {
return true;
}
}
return false;
}
function solveStart(board, visited, startRow, startColumn) {
const newBoard = copyBoard(board);
const newVisited = copyBoard(visited);
markVisited(newBoard, newVisited, startRow, startColumn);
return solve(newBoard, newVisited, startRow, startColumn);
}
const moves = [
[-1, -2],
[-2, -1],
[-2, 1],
[-1, 2],
[1, 2],
[2, 1],
[2, -1],
[1, -2]
];
const [baseBoard, baseVisited] = createBoards(h, w);
fillAllowedMovesCounts(baseBoard);
let solvedCount = 0;
for (let row = 0; row < h; row++) {
for (let column = 0; column < w; column++) {
if (solveStart(baseBoard, baseVisited, row, column)) {
solvedCount++;
}
}
}
return solvedCount;
}
```

View File

@ -0,0 +1,85 @@
---
id: 5a23c84252665b21eecc7edb
title: 連結整数の最大整数
challengeType: 5
forumTopicId: 302298
dashedName: largest-int-from-concatenated-ints
---
# --description--
指定された正の整数一式に対して、この数字の連結が最大の整数を形成するように整数を並び替え、この最大整数を返すような関数を記述してください。
# --hints--
`maxCombine` は関数とします。
```js
assert(typeof maxCombine == 'function');
```
`maxCombine([1, 3, 3, 4, 55])` は数値を返す必要があります。
```js
assert(typeof maxCombine([1, 3, 3, 4, 55]) == 'number');
```
`maxCombine([1, 3, 3, 4, 55])``554331` を返す必要があります。
```js
assert.equal(maxCombine([1, 3, 3, 4, 55]), 554331);
```
`maxCombine([71, 45, 23, 4, 5])``71545423` を返す必要があります。
```js
assert.equal(maxCombine([71, 45, 23, 4, 5]), 71545423);
```
`maxCombine([14, 43, 53, 114, 55])``55534314114` を返す必要があります。
```js
assert.equal(maxCombine([14, 43, 53, 114, 55]), 55534314114);
```
`maxCombine([1, 34, 3, 98, 9, 76, 45, 4])``998764543431` を返す必要があります。
```js
assert.equal(maxCombine([1, 34, 3, 98, 9, 76, 45, 4]), 998764543431);
```
`maxCombine([54, 546, 548, 60])``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
);
}
```

View File

@ -0,0 +1,99 @@
---
id: 5a23c84252665b21eecc7edc
title: 毎月の最終金曜日
challengeType: 5
forumTopicId: 302299
dashedName: last-friday-of-each-month
---
# --description--
指定した年の指定した月の最終金曜日の日付を返す関数を記述してください。
# --hints--
`lastFriday` は関数とします。
```js
assert(typeof lastFriday == 'function');
```
`lastFriday(2018, 1)` は数値を返す必要があります。
```js
assert(typeof lastFriday(2018, 1) == 'number');
```
`lastFriday(2018, 1)``26` を返す必要があります。
```js
assert.equal(lastFriday(2018, 1), 26);
```
`lastFriday(2017, 2)``24` を返す必要があります。
```js
assert.equal(lastFriday(2017, 2), 24);
```
`lastFriday(2012, 3)``30` を返す必要があります。
```js
assert.equal(lastFriday(2012, 3), 30);
```
`lastFriday(1900, 4)``27` を返す必要があります。
```js
assert.equal(lastFriday(1900, 4), 27);
```
`lastFriday(2000, 5)``26` を返す必要があります。
```js
assert.equal(lastFriday(2000, 5), 26);
```
`lastFriday(2006, 6)``30` を返す必要があります。
```js
assert.equal(lastFriday(2006, 6), 30);
```
`lastFriday(2010, 7)``30` を返す必要があります。
```js
assert.equal(lastFriday(2010, 7), 30);
```
`lastFriday(2005, 8)``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;
}
}
```

View File

@ -0,0 +1,211 @@
---
id: 5e4ce2b6ac708cc68c1df25e
title: しりとり (Last letter-first letter)
challengeType: 5
forumTopicId: 385256
dashedName: last-letter-first-letter
---
# --description--
子供たちの遊びのひとつで、あるカテゴリに属する単語の連想から始めます。 各参加者は順番に単語を言いますが、その単語は前の単語の最後の文字で始まる必要があります。 一度誰かが言った単語を繰り返して使うことはできません。 そのカテゴリの単語を言えなかった参加者は、ゲームから脱落します。
例えば、カテゴリが「動物」であるとします。
<pre>子供 1: dog
子供 2: goldfish
子供 1: hippopotamus
子供 2: snake
...
</pre>
# --instructions--
単語の入力配列を取る関数を記述してください。 関数は、各単語の最初の文字が前の単語の最後の文字と同じである単語の配列を返す必要があります。 入力配列内の単語のみを使用し、一度使用された単語を繰り返して使うことはできません。 戻り値となる配列の単語は、その長さが最大となるよう選択され、並べられる必要があります。
# --hints--
`findLongestChain` は関数とします。
```js
assert(typeof findLongestChain == 'function');
```
`findLongestChain(["certain", "each", "game", "involves", "starting", "with", "word"])` は配列を返す必要があります。
```js
assert(
Array.isArray(
findLongestChain([
'certain',
'each',
'game',
'involves',
'starting',
'with',
'word'
])
)
);
```
`findLongestChain(["certain", "each", "game", "involves", "starting", "with", "word"])``["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"])``["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"])``["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"])``["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"])``["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;
}
```

View File

@ -0,0 +1,79 @@
---
id: 5a23c84252665b21eecc7ede
title: うるう年
challengeType: 5
forumTopicId: 302300
dashedName: leap-year
---
# --description--
指定された年がグレゴリオ暦のうるう年かどうかを判断します。
# --hints--
`isLeapYear` は関数とします。
```js
assert(typeof isLeapYear == 'function');
```
`isLeapYear()` はブール値を返す必要があります。
```js
assert(typeof isLeapYear(2018) == 'boolean');
```
`isLeapYear(2018)``false` を返す必要があります。
```js
assert.equal(isLeapYear(2018), false);
```
`isLeapYear(2016)``true` を返す必要があります。
```js
assert.equal(isLeapYear(2016), true);
```
`isLeapYear(2000)``true` を返す必要があります。
```js
assert.equal(isLeapYear(2000), true);
```
`isLeapYear(1900)``false` を返す必要があります。
```js
assert.equal(isLeapYear(1900), false);
```
`isLeapYear(1996)``true` を返す必要があります。
```js
assert.equal(isLeapYear(1996), true);
```
`isLeapYear(1800)``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;
}
```

View File

@ -0,0 +1,87 @@
---
id: 5a23c84252665b21eecc7edf
title: 最小公倍数
challengeType: 5
forumTopicId: 302301
dashedName: least-common-multiple
---
# --description--
12 と 18 の最小公倍数は 36 です。なぜなら、12 は倍数 (12×3 = 36) そして 18 は倍数 (18×2=36) を持ち、36 より小さい両方の倍数となる正の整数はないからです。 特殊なケースとして、 *m* または *n* がゼロの場合、最小公倍数はゼロになります。 最小公倍数を計算する 1 つの方法は、*m* のすべての倍数を、*n* の倍数でもあるものが見つかるまで繰り返すことです。 [最大公約数](https://rosettacode.org/wiki/greatest common divisor) の *gcd* がすでにある場合、以下の公式で *lcm* を計算します。 ( \\operatorname{lcm}(m, n) = \\frac{|m \\times n|}{\\operatorname{gcd}(m, n)} )
# --instructions--
整数の配列の最小公倍数を計算してください。 *m**n* が指定されている場合、最小公倍数は、*m* と *n* の両方の倍数を持つ最小の正の整数となります。
# --hints--
`LCM` は関数とします。
```js
assert(typeof LCM == 'function');
```
`LCM([2, 4, 8])` は数値を返す必要があります。
```js
assert(typeof LCM([2, 4, 8]) == 'number');
```
`LCM([2, 4, 8])``8` を返す必要があります。
```js
assert.equal(LCM([2, 4, 8]), 8);
```
`LCM([4, 8, 12])``24` を返す必要があります。
```js
assert.equal(LCM([4, 8, 12]), 24);
```
`LCM([3, 4, 5, 12, 40])``120` を返す必要があります。
```js
assert.equal(LCM([3, 4, 5, 12, 40]), 120);
```
`LCM([11, 33, 90])``990` を返す必要があります。
```js
assert.equal(LCM([11, 33, 90]), 990);
```
`LCM([-50, 25, -45, -18, 90, 447])``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;
}
```

View File

@ -0,0 +1,115 @@
---
id: 5a23c84252665b21eecc7ee0
title: 左階乗
challengeType: 5
forumTopicId: 302302
dashedName: left-factorials
---
# --description--
**左階乗**, $ !n $, は *下位階乗* または *階乗和* のいずれかをいいます。 同じ表記が 2 つの別々の定義に使われているために、混乱を招く可能性があります。 *下位階乗* (*攪乱順列*とも呼ばれる) は、以下の表記を使用することもあります。
<ul>
<li>$!n`$</li>
<li>$!n$</li>
<li>$n¡$</li>
</ul>
(視覚的に分かりづらいかもしれませんが、最後の例は逆感嘆符が使用されています)。 このタスクは、 以下の**左階乗** の公式を使用します。
$ !n = \\sum\_{k=0}^{n-1} k! $
where $!0 = 0$
# --instructions--
与えられた数値の左階乗を計算する関数を記述してください。
# --hints--
`leftFactorial` は関数とします。
```js
assert(typeof leftFactorial == 'function');
```
`leftFactorial(0)` は数値を返す必要があります。
```js
assert(typeof leftFactorial(0) == 'number');
```
`leftFactorial(0)` は `0` を返す必要があります。
```js
assert.equal(leftFactorial(0), 0);
```
`leftFactorial(1)` は `1` を返す必要があります。
```js
assert.equal(leftFactorial(1), 1);
```
`leftFactorial(2)` は `2` を返す必要があります。
```js
assert.equal(leftFactorial(2), 2);
```
`leftFactorial(3)` は `4` を返す必要があります。
```js
assert.equal(leftFactorial(3), 4);
```
`leftFactorial(10)` は `409114` を返す必要があります。
```js
assert.equal(leftFactorial(10), 409114);
```
`leftFactorial(17)` は `22324392524314` を返す必要があります。
```js
assert.equal(leftFactorial(17), 22324392524314);
```
`leftFactorial(19)` は `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;
}
```

View File

@ -0,0 +1,209 @@
---
id: 5e4ce2bbac708cc68c1df25f
title: 文字の出現頻度
challengeType: 5
forumTopicId: 385263
dashedName: letter-frequency
---
# --description--
与えられた文字列で、各文字の出現頻度を計算します。
すべての文字を数える必要があります。 これには、小文字・大文字、数字、空白、特殊文字、その他のあらゆる記号などが含まれます。
# --instructions--
与えられた文字列の各文字の出現数をカウントする関数を記述してください。
この関数は、`['char', freq]` という形式の各要素を含む 2 次元配列を返します。 文字 (char) は長さが 1 の文字列で、頻度 (freq) はカウント数を表す数字です。
例えば、"ab" という文字列を与えられた場合、関数は `[['a', 1], ['b', 1]]` を返します。
# --hints--
`letterFrequency` は関数とします。
```js
assert(typeof letterFrequency == 'function');
```
`letterFrequency("Not all that Mrs. Bennet, however")` は配列を返す必要があります。
```js
assert(Array.isArray(letterFrequency('Not all that Mrs. Bennet, however')));
```
`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]]` を返す必要があります。
```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 ")``[[" ", 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")``[[" ", 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")``[[" ", 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")``[[" ", 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,")``[[" ", 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]]; });
}
```

View File

@ -0,0 +1,105 @@
---
id: 5e4ce2eaac708cc68c1df260
title: レーベンシュタイン距離
challengeType: 5
forumTopicId: 385264
dashedName: levenshtein-distance
---
# --description--
情報理論とコンピュータサイエンスでは、**レーベンシュタイン距離** は 2 つのシーケンスがどの程度異なっているかを測定するための [メトリック](https://en.wikipedia.org/wiki/string metric) です ([編集距離](https://en.wikipedia.org/wiki/edit distance)ともいう)。 2 つの文字列間のレーベンシュタイン距離は、1 つの文字の挿入、削除、置換を行うことで、1 つの文字列をもう 1 つの文字列に変換するために必要な最小編集回数として定義されます。
例:
"**kitten**" と "**sitting**" の間のレーベンシュタイン距離は 3 です。以下の 3 回で一方から他方へと変換され、かつ 3 回より少ない回数の編集でこの変換を行う方法がないからです。
<ul>
<li><strong>k</strong>itten   <strong>s</strong>itten    ('k' を 's' で置換)</li>
<li>sitt<strong>e</strong>n   sitt<strong>i</strong>n    ('e' を 'i' で置換)</li>
<li>sittin   sittin<strong>g</strong>    (最後に 'g' を挿入)</li>
</ul>
*"**rosettacode**" と "**raisethysword**" とのレーベンシュタイン距離は **8** となります。*
*2つの文字列間のレーベンシュタイン距離は、両方の文字列を逆にした場合も同じです。*
# --instructions--
パラメータとして与えられた 2 つの文字列間のレーベンシュタイン距離を返す関数を記述してください。
# --hints--
`levenshtein` は関数とします。
```js
assert(typeof levenshtein == 'function');
```
`levenshtein("mist", "dist")` は数値を返す必要があります。
```js
assert(typeof levenshtein('mist', 'dist') == 'number');
```
`levenshtein("mist", "dist")``1` を返す必要があります。
```js
assert.equal(levenshtein('mist', 'dist'), 1);
```
`levenshtein("tier", "tor")``2` を返す必要があります。
```js
assert.equal(levenshtein('tier', 'tor'), 2);
```
`levenshtein("kitten", "sitting")``3` を返す必要があります。
```js
assert.equal(levenshtein('kitten', 'sitting'), 3);
```
`levenshtein("stop", "tops")``2` を返す必要があります。
```js
assert.equal(levenshtein('stop', 'tops'), 2);
```
`levenshtein("rosettacode", "raisethysword")``8` を返す必要があります。
```js
assert.equal(levenshtein('rosettacode', 'raisethysword'), 8);
```
`levenshtein("mississippi", "swiss miss")``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];
}
```

View File

@ -0,0 +1,97 @@
---
id: 5e4ce2f5ac708cc68c1df261
title: 線形合同法
challengeType: 5
forumTopicId: 385266
dashedName: linear-congruential-generator
---
# --description--
[線形合同法](https://en.wikipedia.org/wiki/linear congruential generator) は、 [乱数発生器](http://rosettacode.org/wiki/random number generator)の非常に単純な例です。 すべての線形合同法は次の式を使用します。
$$r_{n + 1} = (a \times r_n + c) \bmod m$$
ここでは、
<ul>
<li>$ r_0 $ はシードです。</li>
<li>$r_1$, $r_2$, $r_3$, ... は乱数です。</li>
<li>$a$, $c$, $m$ は定数です。</li>
</ul>
$a$、$c$、および $m$ の値を慎重に選択すると、発生器は $0$ から $m -1$ までの整数の一様分布を発生させます。
LCG (線形合同法) の乱数の質は低いです。 $r_n$ と $r\_{n + 1}$ には真の乱数にあるような独立性がありません。 $r_n$ を知っている人は誰でも $r\_{n + 1}$ を予測できるため、LCG は暗号的に安全ではありません。 LCG は [ミラー–ラビン素数判定法](http://rosettacode.org/wiki/Miller-Rabin primality test)や [フリーセルの駆け引き](http://rosettacode.org/wiki/deal cards for FreeCell) のようなシンプルなタスクには十分です。 LCG の利点に、同じ $r_0$ から簡単に数列を再現できることがあります。 式がとても簡単なので、このような数列を異なるプログラミング言語で再現することも可能です。
# --instructions--
$r_0,a,c,m,n$ をパラメータとして取り、 $r_n$ を返す関数を記述してください。
# --hints--
`linearCongGenerator` は関数とします。
```js
assert(typeof linearCongGenerator == 'function');
```
`linearCongGenerator(324, 1145, 177, 2148, 3)` は数値を返す必要があります。
```js
assert(typeof linearCongGenerator(324, 1145, 177, 2148, 3) == 'number');
```
`linearCongGenerator(324, 1145, 177, 2148, 3)``855` を返す必要があります。
```js
assert.equal(linearCongGenerator(324, 1145, 177, 2148, 3), 855);
```
`linearCongGenerator(234, 11245, 145, 83648, 4)``1110` を返す必要があります。
```js
assert.equal(linearCongGenerator(234, 11245, 145, 83648, 4), 1110);
```
`linearCongGenerator(85, 11, 1234, 214748, 5)``62217` を返す必要があります。
```js
assert.equal(linearCongGenerator(85, 11, 1234, 214748, 5), 62217);
```
`linearCongGenerator(0, 1103515245, 12345, 2147483648, 1)``12345` を返す必要があります。
```js
assert.equal(linearCongGenerator(0, 1103515245, 12345, 2147483648, 1), 12345);
```
`linearCongGenerator(0, 1103515245, 12345, 2147483648, 2)``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;
}
```

View File

@ -0,0 +1,111 @@
---
id: 5e4ce2a1ac708cc68c1df25d
title: 桁数の多い数字の掛け算
challengeType: 5
forumTopicId: 385269
dashedName: long-multiplication
---
# --description--
[桁数の多い数字の掛け算](https://en.wikipedia.org/wiki/long multiplication)を明示的に実装します。
これは任意精度の整数代数に対するアプローチの一つです。
# --instructions--
パラメータとして、巨大数の文字列を 2 つ取る関数を記述してください。 関数はこれら 2 つの巨大数の積を文字列として返す必要があります。
**注意:** JavaScript では、巨大数の場合の算術演算は不正確になるため、自身で正確な乗算を実装する必要があります。
# --hints--
`mult` は関数とします。
```js
assert(typeof mult == 'function');
```
`mult("18446744073709551616", "18446744073709551616")` は文字列を返す必要があります。
```js
assert(typeof mult('18446744073709551616', '18446744073709551616') == 'string');
```
`mult("18446744073709551616", "18446744073709551616")``"340282366920938463463374607431768211456"` を返す必要があります。
```js
assert.equal(
mult('18446744073709551616', '18446744073709551616'),
'340282366920938463463374607431768211456'
);
```
`mult("31844674073709551616", "1844674407309551616")``"58743055272886011737990786529368211456"` を返す必要があります。
```js
assert.equal(
mult('31844674073709551616', '1844674407309551616'),
'58743055272886011737990786529368211456'
);
```
`mult("1846744073709551616", "44844644073709551616")``"82816580680737279241781007431768211456"` を返す必要があります。
```js
assert.equal(
mult('1846744073709551616', '44844644073709551616'),
'82816580680737279241781007431768211456'
);
```
`mult("1844674407370951616", "1844674407709551616")``"3402823669833978308014392742590611456"` を返す必要があります。
```js
assert.equal(
mult('1844674407370951616', '1844674407709551616'),
'3402823669833978308014392742590611456'
);
```
`mult("2844674407370951616", "1844674407370955616")``"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("");
}
```

View File

@ -0,0 +1,102 @@
---
id: 5e6dd1278e6ca105cde40ea9
title: 最長共通部分列
challengeType: 5
forumTopicId: 385271
dashedName: longest-common-subsequence
---
# --description--
グループAおよびBの **最長共通部分列** (または [**LCS**](http://en.wikipedia.org/wiki/Longest_common_subsequence_problem)) とは、2つのグループ間で共通していて、各グループで同じ順序であるAおよびBの要素の最長グループです。 たとえば、数列 "1234" と "1224533324" の LCS は "1234" です。
***1234***
***12***245***3***332***4***
文字列の例として、文字列 "thisisatest" と "testing123testing" の場合を考えてみましょう。 LCS は "tsitest" となります。
***t***hi***si***sa***test***
***t***e***s***t***i***ng123***test***ing.
今回のコードでは文字列のみを扱います。
この問題の詳細については、 [Wikipedia](https://en.wikipedia.org/wiki/Longest_common_subsequence_problem) を参照してください。
# --instructions--
2 つの文字列の LCS を返す関数 (大文字と小文字を区別する) を記述してください。 複数の LCS を表示する必要はありません。
# --hints--
`lcs` は関数とします。
```js
assert(typeof lcs == 'function');
```
`lcs("thisisatest", "testing123testing")` は文字列を返す必要があります。
```js
assert(typeof lcs('thisisatest', 'testing123testing') == 'string');
```
`lcs("thisisatest", "testing123testing")``"tsitest"` を返す必要があります。
```js
assert.equal(lcs('thisisatest', 'testing123testing'), 'tsitest');
```
`lcs("ABCDGH", "AEDFHR")``"ADH"` を返す必要があります。
```js
assert.equal(lcs('ABCDGH', 'AEDFHR'), 'ADH');
```
`lcs("AGGTAB", "GXTXAYB")``"GTAB"` を返す必要があります。
```js
assert.equal(lcs('AGGTAB', 'GXTXAYB'), 'GTAB');
```
`lcs("BDACDB", "BDCB")``"BDCB"` を返す必要があります。
```js
assert.equal(lcs('BDACDB', 'BDCB'), 'BDCB');
```
`lcs("ABAZDC", "BACBAD")``"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;
}
}
```

View File

@ -0,0 +1,120 @@
---
id: 5e6dd139859c290b6ab80292
title: 最長増加部分列
challengeType: 5
forumTopicId: 385272
dashedName: longest-increasing-subsequence
---
# --description--
最長増加部分列問題は、与えられた数列で、部分列の要素が最小から最大の順になっているもののうち最長の長さの部分列を求めるものです。 以下に例を示します。
次の配列の場合:
$\\{3, 10, 2, 1, 20\\}$
最長増加部分列は:
$\\{3, 10, 20\\}$
この問題の詳細については、 [Wikipedia](https://en.wikipedia.org/wiki/Longest increasing subsequence) を参照してください。
# --instructions--
数列をパラメータとして取り、最長増加部分列を返す関数を記述してください。
数列はすべて最長増加部分列を持つことが保証されています。
# --hints--
`findSequence` は関数とします。
```js
assert(typeof findSequence == 'function');
```
`findSequence([3, 10, 2, 1, 20])` は配列を返す必要があります。
```js
assert(Array.isArray(findSequence([3, 10, 2, 1, 20])));
```
`findSequence([3, 10, 2, 1, 20])``[3, 10, 20]` を返す必要があります。
```js
assert.deepEqual(findSequence([3, 10, 2, 1, 20]), [3, 10, 20]);
```
`findSequence([2, 7, 3, 5, 8])``[2, 3, 5, 8]` を返す必要があります。
```js
assert.deepEqual(findSequence([2, 7, 3, 5, 8]), [2, 3, 5, 8]);
```
`findSequence([2, 6, 4, 5, 1])``[2, 4, 5]` を返す必要があります。
```js
assert.deepEqual(findSequence([2, 6, 4, 5, 1]), [2, 4, 5]);
```
`findSequence([10, 22, 9, 33, 21, 50, 60, 80])``[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])``[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;
}
```

View File

@ -0,0 +1,101 @@
---
id: 5e6dd14192286d95fc43046e
title: 最長文字列チャレンジ
challengeType: 5
forumTopicId: 385275
dashedName: longest-string-challenge
---
# --description--
このチャレンジでは、与えられた文字列の中で最も長い文字列を見つけます。
# --instructions--
文字列の配列を取り、長さが最長であるすべての文字列を返す関数を記述してください。
# --hints--
`longestString` は関数とします。
```js
assert(typeof longestString == 'function');
```
`longestString(["a", "bb", "ccc", "ee", "f", "ggg"])` は配列を返す必要があります。
```js
assert(Array.isArray(longestString(['a', 'bb', 'ccc', 'ee', 'f', 'ggg'])));
```
`longestString(["a", "bb", "ccc", "ee", "f", "ggg"])``["ccc", "ggg"]` を返す必要があります。
```js
assert.deepEqual(longestString(['a', 'bb', 'ccc', 'ee', 'f', 'ggg']), [
'ccc',
'ggg'
]);
```
`longestString(["afedg", "bb", "sdccc", "efdee", "f", "geegg"])``["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"])``["bhghgb", "fssdrr"]` を返す必要があります。
```js
assert.deepEqual(
longestString(['a', 'bhghgb', 'ccc', 'efde', 'fssdrr', 'ggg']),
['bhghgb', 'fssdrr']
);
```
`longestString(["ahgfhg", "bdsfsb", "ccc", "ee", "f", "ggdsfg"])``["ahgfhg", "bdsfsb", "ggdsfg"]` を返す必要があります。
```js
assert.deepEqual(
longestString(['ahgfhg', 'bdsfsb', 'ccc', 'ee', 'f', 'ggdsfg']),
['ahgfhg', 'bdsfsb', 'ggdsfg']
);
```
`longestString(["a", "bbdsf", "ccc", "edfe", "gzzzgg"])``["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
}
```

View File

@ -0,0 +1,92 @@
---
id: 5e6dd14797f5ce267c2f19d0
title: 読み上げ数列
challengeType: 5
forumTopicId: 385277
dashedName: look-and-say-sequence
---
# --description--
[読み上げ数列](https://en.wikipedia.org/wiki/Look and say sequence) は、再帰的に定義された数列です。
数列の定義
<ul><li>10進数の数値を 1 つ選びます</li>
<li>数字を<span>見て</span>、同じ数字の連続した並びのグループを視覚的に把握します</li>
<li>番号を左から右へグループごとに、数字が何個あるかと、続けてそのグループの数字を<span>読み上げ</span>ます。</li></ul><span> これが数列の次の数値になります。</span>
以下に例を示します。
<ul><li>数値 1 から始めると、<span>1</span> 個の 1 で 11 になります</li>
<li>11 から始めると、<span>2</span> 個の1。 つまり、21になります</li>
<li>21から始めると、 <span>1</span> 個の 2、<span>1</span> 個の 1。 つまり、(12)(11) で 1211 になります</li>
<li>1211から始めると、 <span>1</span> 個の 1、 <span>1</span> 個の 2、そして <span>2</span> 個の 1。 つまり、(11)(12)(21) で 111221 になります</li></ul>
# --instructions--
文字列をパラメータとして取る関数を記述し、それを実行して結果の文字列を返してください。
# --hints--
`lookAndSay` は関数とします。
```js
assert(typeof lookAndSay == 'function');
```
`lookAndSay("1")` は文字列を返す必要があります。
```js
assert(typeof lookAndSay('1') == 'string');
```
`lookAndSay("1")``"11"` を返す必要があります。
```js
assert.equal(lookAndSay('1'), '11');
```
`lookAndSay("11")``"21"` を返す必要があります。
```js
assert.equal(lookAndSay('11'), '21');
```
`lookAndSay("21")``"1211"` を返す必要があります。
```js
assert.equal(lookAndSay('21'), '1211');
```
`lookAndSay("1211")``"111221"` を返す必要があります。
```js
assert.equal(lookAndSay('1211'), '111221');
```
`lookAndSay("3542")``"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;
});
}
```

View File

@ -0,0 +1,139 @@
---
id: 5e6dd15004c88cf00d2a78b3
title: 複数配列に対する同時ループ処理
challengeType: 5
forumTopicId: 385279
dashedName: loop-over-multiple-arrays-simultaneously
---
# --description--
複数の配列にループ処理を行い、 与えられた各要素 $i^{th}$ の連結である$i^{th}$ 要素を持つ新しい配列を作成します。
以下の例では、次の配列の配列が与えられています。
```js
[ ["a", "b", "c"], ["A", "B", "C"], [1, 2, 3] ]
```
出力は次のようになります。
```js
["aA1","bB2","cC3"]
```
# --instructions--
配列の配列をパラメータとして取り、上記の説明を満たす文字列の配列を返す関数を記述してください。
# --hints--
`loopSimult` は関数とします。
```js
assert(typeof loopSimult == 'function');
```
`loopSimult([["a", "b", "c"], ["A", "B", "C"], [1, 2, 3]])` は配列を返す必要があります。
```js
assert(
Array.isArray(
loopSimult([
['a', 'b', 'c'],
['A', 'B', 'C'],
[1, 2, 3]
])
)
);
```
`loopSimult([["a", "b", "c"], ["A", "B", "C"], [1, 2, 3]])``["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]])``["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]])``["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]])``["aA1", "bB2"]` を返す必要があります。
```js
assert.deepEqual(
loopSimult([
['a', 'b'],
['A', 'B'],
[1, 2]
]),
['aA1', 'bB2']
);
```
`loopSimult([["b", "c"], ["B", "C"], [2, 3]])``["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;
}
```

View File

@ -0,0 +1,318 @@
---
id: 5e6decd8ec8d7db960950d1c
title: LU 分解
challengeType: 5
forumTopicId: 385280
dashedName: lu-decomposition
---
# --description--
[LU 分解](https://en.wikipedia.org/wiki/LU decomposition) で説明されているように、すべての正方行列 $A$ は、下三角行列 $L$ と上三角行列 $U$ の積に分解できます。
$A = LU$
これはガウスの消去法の修正版です。
[コレスキー分解](http://rosettacode.org/wiki/Cholesky decomposition) が正定値対称行列に対してのみ機能するのに対し、より一般的な LU 分解は任意の正方行列に対して機能します。
$L$ と $U$ を計算するためのアルゴリズムはいくつかあります。
3x3 の例について *クラウト法* を導き出すには、次の系を解く必要があります。
\\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}
次に、未知数 12 個を持つ 9つの方程式を解かなければなりません。 系を一意に解決できるようにするために、通常 $L$ の対角要素を 1 に設定します。
$l\_{11}=1$
$l\_{22}=1$
$l\_{33}=1$
これで、9 つの未知数と 9 つの方程式を解くことができます。
\\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}
他の $l$ と $u$ を解くと、次の式が得られます。
$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})$
$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})$
以下の式として表現できる計算パターンがあることがわかります。まず $U$ の場合、
$u\_{ij} = a\_{ij} - \\sum\_{k=1}^{i-1} u\_{kj}l\_{ik}$
そして $L$ の場合、
$l\_{ij} = \\frac{1}{u\_{jj}} (a\_{ij} - \\sum\_{k=1}^{j-1} u\_{kj}l\_{ik})$
2 番目の式で、対角線より下の $l\_{ij}$ を取得するには、対角要素 (ピボット) $u\_{jj}$ で除算する必要があるため、$u\_{jj}$ が 0 または非常に小さい時、数値が不安定になり、問題が発生します。
この問題の解決策が、*ピボット選択* $A$ です。これは、$LU$ 分解の前に $A$ の行を再配置することを意味します。これにより、各列の最大要素が $A$の対角要素となります。 行を並べ替えることで、 $A$ に 置換行列 $P$ をかけることになります。
$PA \\Rightarrow A'$
例:
\\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}
次に、再配置された行列に分解アルゴリズムが適用され、以下のようになります。
$PA = LU$
# --instructions--
タスクは、nxn の正方行列 $A$ を取り、下三角行列 $L$、上三角行列 $U$、および置換行列 $P$ を返すルーチンを実装して、上記の式が満たされるようにすることです。 戻り値は、 `[L, U, P]` の形式でなければなりません。
# --hints--
`luDecomposition` は関数とします。
```js
assert(typeof luDecomposition == 'function');
```
`luDecomposition([[1, 3, 5], [2, 4, 7], [1, 1, 0]])` は配列を返す必要があります。
```js
assert(
Array.isArray(
luDecomposition([
[1, 3, 5],
[2, 4, 7],
[1, 1, 0]
])
)
);
```
`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]]]` を返す必要があります。
```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]])``[[[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]])``[[[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]])``[[[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