chore: manual translations (#42811)

This commit is contained in:
Nicholas Carrigan (he/him)
2021-07-09 21:23:54 -07:00
committed by GitHub
parent a3395269a0
commit c4fd49e5b7
806 changed files with 8935 additions and 4378 deletions

View File

@ -20,6 +20,8 @@ Let's create the basic functionality of a hash table. We've created a naive hash
Be sure to write your code to account for collisions!
**Note:** The `remove` method tests won't pass until the `add` and `lookup` methods are correctly implemented.
# --hints--
The HashTable data structure should exist.
@ -50,20 +52,6 @@ assert(
);
```
The HashTable should have a remove method.
```js
assert(
(function () {
var test = false;
if (typeof HashTable !== 'undefined') {
test = new HashTable();
}
return typeof test.remove === 'function';
})()
);
```
The HashTable should have a lookup method.
```js
@ -78,6 +66,20 @@ assert(
);
```
The HashTable should have a remove method.
```js
assert(
(function () {
var test = false;
if (typeof HashTable !== 'undefined') {
test = new HashTable();
}
return typeof test.remove === 'function';
})()
);
```
The add method should add key value pairs and the lookup method should return the values associated with a given key.
```js
@ -103,14 +105,40 @@ assert(
if (typeof HashTable !== 'undefined') {
test = new HashTable();
}
test.add = addMethodSolution;
test.add('key', 'value');
test.remove('key');
return !test.collection.hasOwnProperty(hashValue);
})()
);
```
The remove method should only remove the correct key value pair.
```js
assert(
(function () {
var test = false;
var hashValue = hash('key');
if (typeof HashTable !== 'undefined') {
test = new HashTable();
}
test.add('key', 'value');
test.add('yek', 'value');
test.add('altKey', 'value');
test.remove('yek');
if (test.lookup('yek') || !test.lookup('key') || !test.lookup('altKey')) {
return false;
}
test.remove('key');
return !test.collection.hasOwnProperty(hashValue) && test.lookup('altKey');
})()
);
```
Items should be added using the hash function.
```js
@ -165,14 +193,6 @@ var hash = string => {
}
return hash;
};
var addMethodSolution = function(key, val) {
var theHash = hash(key);
if (!this.collection.hasOwnProperty(theHash)) {
this.collection[theHash] = {};
}
this.collection[theHash][key] = val;
}
```
## --seed-contents--

View File

@ -12,11 +12,15 @@ In this challenge you will be creating a Priority Queue. A Priority Queue is a s
For instance, lets imagine we have a priority queue with three items:
`[['kitten', 2], ['dog', 2], ['rabbit', 2]]`
```js
[['kitten', 2], ['dog', 2], ['rabbit', 2]]
```
Here the second value (an integer) represents item priority. If we enqueue `['human', 1]` with a priority of `1` (assuming lower priorities are given precedence) it would then be the first item to be dequeued. The collection would look like this:
`[['human', 1], ['kitten', 2], ['dog', 2], ['rabbit', 2]]`.
```js
[['human', 1], ['kitten', 2], ['dog', 2], ['rabbit', 2]]
```
Weve started writing a `PriorityQueue` in the code editor. You will need to add an `enqueue` method for adding items with a priority, a `dequeue` method for removing and returning items, a `size` method to return the number of items in the queue, a `front` method to return the element at the front of the queue, and finally an `isEmpty` method that will return `true` if the queue is empty or `false` if it is not.

View File

@ -77,8 +77,9 @@ The `peek` method should return the top element of the stack
assert(
(function () {
var test = new Stack();
test.push('CS61');
test.push('CS50');
return test.peek() === 'CS50';
return test.peek() === 'CS50' && test.peek() === 'CS50';
})()
);
```
@ -89,8 +90,9 @@ The `pop` method should remove and return the top element of the stack
assert(
(function () {
var test = new Stack();
test.push('CS61');
test.push('CS50');
return test.pop() === 'CS50';
return test.pop() === 'CS50' && test.pop() === 'CS61';
})()
);
```
@ -112,6 +114,7 @@ The `clear` method should remove all element from the stack
assert(
(function () {
var test = new Stack();
test.push('CS61');
test.push('CS50');
test.clear();
return test.isEmpty();

View File

@ -31,7 +31,9 @@ assert(myMap.get('freeCodeCamp') === 'Awesome!');
# --seed--
## --seed-contents--
```js
```
# --solutions--

View File

@ -12,15 +12,21 @@ Now that you have worked through ES5, you are going to perform something similar
To create a new empty set:
`var set = new Set();`
```js
var set = new Set();
```
You can create a set with a value:
`var set = new Set(1);`
```js
var set = new Set(1);
```
You can create a set with an array:
`var set = new Set([1, 2, 3]);`
```js
var set = new Set([1, 2, 3]);
```
Once you have created a set, you can add the values you wish using the `add` method:

View File

@ -14,13 +14,17 @@ While binary heaps may be implemented as tree structures with nodes that contain
For instance, consider this array representation of a binary min heap:
`[ 6, 22, 30, 37, 63, 48, 42, 76 ]`
```js
[ 6, 22, 30, 37, 63, 48, 42, 76 ]
```
The root node is the first element, `6`. Its children are `22` and `30`. If we look at the relationship between the array indices of these values, for index `i` the children are `2 * i + 1` and `2 * i + 2`. Similarly, the element at index `0` is the parent of these two children at indices `1` and `2`. More generally, we can find the parent of a node at any index with the following: `Math.floor((i - 1) / 2)`. These patterns will hold true as the binary tree grows to any size. Finally, we can make a slight adjustment to make this arithmetic even easier by skipping the first element in the array. Doing this creates the following relationship for any element at a given index `i`:
Example array representation:
`[ null, 6, 22, 30, 37, 63, 48, 42, 76 ]`
```js
[ null, 6, 22, 30, 37, 63, 48, 42, 76 ]
```
An element's left child: `i * 2`

View File

@ -12,7 +12,9 @@ Let's practice removing items from an ES6 Set using the `delete` method.
First, create an ES6 Set:
`var set = new Set([1,2,3]);`
```js
var set = new Set([1,2,3]);
```
Now remove an item from your Set with the `delete` method.
@ -46,8 +48,11 @@ assert(
```js
function checkSet(){
var set = null;
return set;
// Only change code below this line
var set = null;
// Only change code above this line
return set;
}
```

View File

@ -10,7 +10,9 @@ dashedName: typed-arrays
Arrays are JavaScript objects that can hold a lot of different elements.
`var complexArr = [1, 5, "2", "Word", {"name": "James"}];`
```js
var complexArr = [1, 5, "2", "Word", {"name": "James"}];
```
Basically what happens in the background is that your browser will automatically give the right amount of memory space for that array. It will also change as needed if you add or remove data.

View File

@ -12,15 +12,21 @@ Let's look at the .has and .size methods available on the ES6 Set object.
First, create an ES6 Set
`var set = new Set([1,2,3]);`
```js
var set = new Set([1,2,3]);
```
The .has method will check if the value is contained within the set.
`var hasTwo = set.has(2);`
```js
var hasTwo = set.has(2);
```
The .size method will return an integer representing the size of the Set
`var howBig = set.size;`
```js
var howBig = set.size;
```
# --instructions--

View File

@ -8,24 +8,50 @@ dashedName: problem-100-arranged-probability
# --description--
If a box contains twenty-one coloured discs, composed of fifteen blue discs and six red discs, and two discs were taken at random, it can be seen that the probability of taking two blue discs, P(BB) = (15/21)×(14/20) = 1/2.
If a box contains twenty-one colored discs, composed of fifteen blue discs and six red discs, and two discs were taken at random, it can be seen that the probability of taking two blue discs.
The next such arrangement, for which there is exactly 50% chance of taking two blue discs at random, is a box containing eighty-five blue discs and thirty-five red discs.
$${P(BB)} = \frac{15}{21}×\frac{14}{20} = \frac{1}{2}$$
By finding the first arrangement to contain over 10<sup>12</sup> = 1,000,000,000,000 discs in total, determine the number of blue discs that the box would contain.
The next such arrangement, for which there is exactly a 50% chance of taking two blue discs at random, is a box containing eighty-five blue discs and thirty-five red discs.
By finding the first arrangement to contain over `limit` discs in total, determine the number of blue discs that the box would contain.
# --hints--
`arrangedProbability()` should return a number.
`arrangedProbability(20)` should return a number.
```js
assert(typeof arrangedProbability() === 'number');
assert(typeof arrangedProbability(10) === 'number');
```
`arrangedProbability()` should return 756872327473.
`arrangedProbability(20)` should return `15`.
```js
assert.strictEqual(arrangedProbability(), 756872327473);
assert.strictEqual(arrangedProbability(20), 15);
```
`arrangedProbability(100)` should return `85`.
```js
assert.strictEqual(arrangedProbability(100), 85);
```
`arrangedProbability(100000)` should return `97513`.
```js
assert.strictEqual(arrangedProbability(100000), 97513);
```
`arrangedProbability(1000000000)` should return `3822685023`.
```js
assert.strictEqual(arrangedProbability(1000000000), 3822685023);
```
`arrangedProbability(1000000000000)` should return `756872327473`.
```js
assert.strictEqual(arrangedProbability(1000000000000), 756872327473);
```
# --seed--
@ -33,16 +59,29 @@ assert.strictEqual(arrangedProbability(), 756872327473);
## --seed-contents--
```js
function arrangedProbability() {
function arrangedProbability(limit) {
return true;
}
arrangedProbability();
arrangedProbability(20);
```
# --solutions--
```js
// solution required
function arrangedProbability(limit) {
// Based on https://www.mathblog.dk/project-euler-100-blue-discs-two-blue/
let blue = 15;
let discs = 21;
while (discs < limit) {
const nextBlue = 3 * blue + 2 * discs - 2;
const nextDiscs = 4 * blue + 3 * discs - 3;
blue = nextBlue;
discs = nextDiscs;
}
return blue;
}
```

View File

@ -10,26 +10,30 @@ dashedName: problem-101-optimum-polynomial
If we are presented with the first k terms of a sequence it is impossible to say with certainty the value of the next term, as there are infinitely many polynomial functions that can model the sequence.
As an example, let us consider the sequence of cube numbers. This is defined by the generating function, un = n3: 1, 8, 27, 64, 125, 216, ...
As an example, let us consider the sequence of cube numbers. This is defined by the generating function, $u_n = n^3: 1, 8, 27, 64, 125, 216, \ldots$
Suppose we were only given the first two terms of this sequence. Working on the principle that "simple is best" we should assume a linear relationship and predict the next term to be 15 (common difference 7). Even if we were presented with the first three terms, by the same principle of simplicity, a quadratic relationship should be assumed.
We shall define OP(k, n) to be the nth term of the optimum polynomial generating function for the first k terms of a sequence. It should be clear that OP(k, n) will accurately generate the terms of the sequence for n ≤ k, and potentially the first incorrect term (FIT) will be OP(k, k+1); in which case we shall call it a bad OP (BOP).
We shall define $OP(k, n)$ to be the $n^{th}$ term of the optimum polynomial generating function for the first k terms of a sequence. It should be clear that $OP(k, n)$ will accurately generate the terms of the sequence for $n ≤ k$, and potentially the first incorrect term (FIT) will be $OP(k, k+1)$; in which case we shall call it a bad OP (BOP).
As a basis, if we were only given the first term of sequence, it would be most sensible to assume constancy; that is, for n ≥ 2, OP(1, n) = u1.
As a basis, if we were only given the first term of sequence, it would be most sensible to assume constancy; that is, for $n ≥ 2, OP(1, n) = u_1$.
Hence we obtain the following OPs for the cubic sequence:
OP(1, n) = 1 1, 1, 1, 1, ... OP(2, n) = 7n6 1, 8, 15, ... OP(3, n) = 6n211n+6 1, 8, 27, 58, ... OP(4, n) = n3 1, 8, 27, 64, 125, ...
$$\begin{array}{ll} OP(1, n) = 1 & 1, {\color{red}1}, 1, 1, \ldots \\\\ OP(2, n) = 7n6 & 1, 8, {\color{red}{15}}, \ldots \\\\ OP(3, n) = 6n^211n+6 & 1, 8, 27, {\color{red}{58}}, \ldots \\\\ OP(4, n) = n^3 & 1, 8, 27, 64, 125, \ldots \end{array}$$
Clearly no BOPs exist for k ≥ 4. By considering the sum of FITs generated by the BOPs (indicated in red above), we obtain 1 + 15 + 58 = 74. Consider the following tenth degree polynomial generating function: un = 1 n + n2 n3 + n4 n5 + n6 n7 + n8 n9 + n10 Find the sum of FITs for the BOPs.
Clearly no BOPs exist for k ≥ 4. By considering the sum of FITs generated by the BOPs (indicated in $\color{red}{red}$ above), we obtain 1 + 15 + 58 = 74. Consider the following tenth degree polynomial generating function:
$$u_n = 1 n + n^2 n^3 + n^4 n^5 + n^6 n^7 + n^8 n^9 + n^{10}$$
Find the sum of FITs for the BOPs.
# --hints--
`euler101()` should return 37076114526.
`optimumPolynomial()` should return `37076114526`.
```js
assert.strictEqual(euler101(), 37076114526);
assert.strictEqual(optimumPolynomial(), 37076114526);
```
# --seed--
@ -37,12 +41,12 @@ assert.strictEqual(euler101(), 37076114526);
## --seed-contents--
```js
function euler101() {
function optimumPolynomial() {
return true;
}
euler101();
optimumPolynomial();
```
# --solutions--

View File

@ -8,30 +8,29 @@ dashedName: problem-103-special-subset-sums-optimum
# --description--
Let S(A) represent the sum of elements in set A of size n. We shall call it a special sum set if for any two non-empty disjoint subsets, B and C, the following properties are true:
Let $S(A)$ represent the sum of elements in set A of size n. We shall call it a special sum set if for any two non-empty disjoint subsets, B and C, the following properties are true:
S(B) ≠ S(C); that is, sums of subsets cannot be equal.
1. $S(B) ≠ S(C)$; that is, sums of subsets cannot be equal.
2. If B contains more elements than C then $S(B) > S(C)$.
If B contains more elements than C then S(B) > S(C).
If $S(A)$ is minimised for a given n, we shall call it an optimum special sum set. The first five optimum special sum sets are given below.
If S(A) is minimised for a given n, we shall call it an optimum special sum set. The first five optimum special sum sets are given below.
$$\begin{align} & n = 1: \\{1\\} \\\\ & n = 2: \\{1, 2\\} \\\\ & n = 3: \\{2, 3, 4\\} \\\\ & n = 4: \\{3, 5, 6, 7\\} \\\\ & n = 5: \\{6, 9, 11, 12, 13\\} \\\\ \end{align}$$
n = 1: {1}n = 2: {1, 2}n = 3: {2, 3, 4}n = 4: {3, 5, 6, 7}n = 5: {6, 9, 11, 12, 13}
It seems that for a given optimum set, $A = \\{a_1, a_2, \ldots, a_n\\}$, the next optimum set is of the form $B = \\{b, a_1 + b, a_2 + b, \ldots, a_n + b\\}$, where b is the "middle" element on the previous row.
It seems that for a given optimum set, A = {a1, a2, ... , an}, the next optimum set is of the form B = {b, a1+b, a2+b, ... ,an+b}, where b is the "middle" element on the previous row.
By applying this "rule" we would expect the optimum set for $n = 6$ to be $A = \\{11, 17, 20, 22, 23, 24\\}$, with $S(A) = 117$. However, this is not the optimum set, as we have merely applied an algorithm to provide a near optimum set. The optimum set for $n = 6$ is $A = \\{11, 18, 19, 20, 22, 25\\}$, with $S(A) = 115$ and corresponding set string: `111819202225`.
By applying this "rule" we would expect the optimum set for n = 6 to be A = {11, 17, 20, 22, 23, 24}, with S(A) = 117. However, this is not the optimum set, as we have merely applied an algorithm to provide a near optimum set. The optimum set for n = 6 is A = {11, 18, 19, 20, 22, 25}, with S(A) = 115 and corresponding set string: 111819202225.
Given that A is an optimum special sum set for $n = 7$, find its set string.
Given that A is an optimum special sum set for n = 7, find its set string.
NOTE: This problem is related to Problem 105 and Problem 106.
**Note:** This problem is related to Problem 105 and Problem 106.
# --hints--
`euler103()` should return 20313839404245.
`optimumSpecialSumSet()` should return the string `20313839404245`.
```js
assert.strictEqual(euler103(), 20313839404245);
assert.strictEqual(optimumSpecialSumSet(), '20313839404245');
```
# --seed--
@ -39,12 +38,12 @@ assert.strictEqual(euler103(), 20313839404245);
## --seed-contents--
```js
function euler103() {
function optimumSpecialSumSet() {
return true;
}
euler103();
optimumSpecialSumSet();
```
# --solutions--

View File

@ -10,18 +10,18 @@ dashedName: problem-104-pandigital-fibonacci-ends
The Fibonacci sequence is defined by the recurrence relation:
Fn = Fn1 + Fn2, where F1 = 1 and F2 = 1.
$F_n = F_{n 1} + F_{n 2}$, where $F_1 = 1$ and $F_2 = 1$
It turns out that F541, which contains 113 digits, is the first Fibonacci number for which the last nine digits are 1-9 pandigital (contain all the digits 1 to 9, but not necessarily in order). And F2749, which contains 575 digits, is the first Fibonacci number for which the first nine digits are 1-9 pandigital.
It turns out that $F_{541}$, which contains 113 digits, is the first Fibonacci number for which the last nine digits are 1 - 9 pandigital (contain all the digits 1 to 9, but not necessarily in order). And $F_{2749}$, which contains 575 digits, is the first Fibonacci number for which the first nine digits are 1 - 9 pandigital.
Given that Fk is the first Fibonacci number for which the first nine digits AND the last nine digits are 1-9 pandigital, find k.
Given that $F_k$ is the first Fibonacci number for which the first nine digits AND the last nine digits are 1 - 9 pandigital, find `k`.
# --hints--
`euler104()` should return 329468.
`pandigitalFibonacciEnds()` should return `329468`.
```js
assert.strictEqual(euler104(), 329468);
assert.strictEqual(pandigitalFibonacciEnds(), 329468);
```
# --seed--
@ -29,12 +29,12 @@ assert.strictEqual(euler104(), 329468);
## --seed-contents--
```js
function euler104() {
function pandigitalFibonacciEnds() {
return true;
}
euler104();
pandigitalFibonacciEnds();
```
# --solutions--

View File

@ -8,37 +8,48 @@ dashedName: problem-105-special-subset-sums-testing
# --description--
Let S(A) represent the sum of elements in set A of size n. We shall call it a special sum set if for any two non-empty disjoint subsets, B and C, the following properties are true:
Let $S(A)$ represent the sum of elements in set A of size n. We shall call it a special sum set if for any two non-empty disjoint subsets, B and C, the following properties are true:
S(B) ≠ S(C); that is, sums of subsets cannot be equal.
1. $S(B) ≠ S(C)$; that is, sums of subsets cannot be equal.
2. If B contains more elements than C then $S(B) > S(C)$.
If B contains more elements than C then S(B) > S(C).
For example, {81, 88, 75, 42, 87, 84, 86, 65} is not a special sum set because 65 + 87 + 88 = 75 + 81 + 84, whereas {157, 150, 164, 119, 79, 159, 161, 139, 158} satisfies both rules for all possible subset pair combinations and $S(A) = 1286$.
For example, {81, 88, 75, 42, 87, 84, 86, 65} is not a special sum set because 65 + 87 + 88 = 75 + 81 + 84, whereas {157, 150, 164, 119, 79, 159, 161, 139, 158} satisfies both rules for all possible subset pair combinations and S(A) = 1286.
Using `sets`, an array with one-hundred sets, containing seven to twelve elements (the two examples given above are the first two sets), identify all the special sum sets, $A_1, A_2, \ldots, A_k$, and find the value of $(A_1) + S(A_2) + \cdots + S(A_k)$.
Using sets.txt (right click and "Save Link/Target As..."), a 4K text file with one-hundred sets containing seven to twelve elements (the two examples given above are the first two sets in the file), identify all the special sum sets, A1, A2, ..., Ak, and find the value of S(A1) + S(A2) + ... + S(Ak).
NOTE: This problem is related to Problem 103 and Problem 106.
**Note:** This problem is related to Problem 103 and Problem 106.
# --hints--
`euler105()` should return 73702.
`testingSpecialSubsetSums(testSets)` should return `73702`.
```js
assert.strictEqual(euler105(), 73702);
assert.strictEqual(testingSpecialSubsetSums(_testSets), 73702);
```
# --seed--
## --after-user-code--
```js
const _testSets = [
[81,88,75,42,87,84,86,65],[157,150,164,119,79,159,161,139,158],[673,465,569,603,629,592,584,300,601,599,600],[90,85,83,84,65,87,76,46],[165,168,169,190,162,85,176,167,127],[224,275,278,249,277,279,289,295,139],[354,370,362,384,359,324,360,180,350,270],[599,595,557,298,448,596,577,667,597,588,602],[175,199,137,88,187,173,168,171,174],[93,187,196,144,185,178,186,202,182],[157,155,81,158,119,176,152,167,159],[184,165,159,166,163,167,174,124,83],[1211,1212,1287,605,1208,1189,1060,1216,1243,1200,908,1210],[339,299,153,305,282,304,313,306,302,228],[94,104,63,112,80,84,93,96],[41,88,82,85,61,74,83,81],[90,67,84,83,82,97,86,41],[299,303,151,301,291,302,307,377,333,280],[55,40,48,44,25,42,41],[1038,1188,1255,1184,594,890,1173,1151,1186,1203,1187,1195],[76,132,133,144,135,99,128,154],[77,46,108,81,85,84,93,83],[624,596,391,605,529,610,607,568,604,603,453],[83,167,166,189,163,174,160,165,133],[308,281,389,292,346,303,302,304,300,173],[593,1151,1187,1184,890,1040,1173,1186,1195,1255,1188,1203],[68,46,64,33,60,58,65],[65,43,88,87,86,99,93,90],[83,78,107,48,84,87,96,85],[1188,1173,1256,1038,1187,1151,890,1186,1184,1203,594,1195],[302,324,280,296,294,160,367,298,264,299],[521,760,682,687,646,664,342,698,692,686,672],[56,95,86,97,96,89,108,120],[344,356,262,343,340,382,337,175,361,330],[47,44,42,27,41,40,37],[139,155,161,158,118,166,154,156,78],[118,157,164,158,161,79,139,150,159],[299,292,371,150,300,301,281,303,306,262],[85,77,86,84,44,88,91,67],[88,85,84,44,65,91,76,86],[138,141,127,96,136,154,135,76],[292,308,302,346,300,324,304,305,238,166],[354,342,341,257,348,343,345,321,170,301],[84,178,168,167,131,170,193,166,162],[686,701,706,673,694,687,652,343,683,606,518],[295,293,301,367,296,279,297,263,323,159],[1038,1184,593,890,1188,1173,1187,1186,1195,1150,1203,1255],[343,364,388,402,191,383,382,385,288,374],[1187,1036,1183,591,1184,1175,888,1197,1182,1219,1115,1167],[151,291,307,303,345,238,299,323,301,302],[140,151,143,138,99,69,131,137],[29,44,42,59,41,36,40],[348,329,343,344,338,315,169,359,375,271],[48,39,34,37,50,40,41],[593,445,595,558,662,602,591,297,610,580,594],[686,651,681,342,541,687,691,707,604,675,699],[180,99,189,166,194,188,144,187,199],[321,349,335,343,377,176,265,356,344,332],[1151,1255,1195,1173,1184,1186,1188,1187,1203,593,1038,891],[90,88,100,83,62,113,80,89],[308,303,238,300,151,304,324,293,346,302],[59,38,50,41,42,35,40],[352,366,174,355,344,265,343,310,338,331],[91,89,93,90,117,85,60,106],[146,186,166,175,202,92,184,183,189],[82,67,96,44,80,79,88,76],[54,50,58,66,31,61,64],[343,266,344,172,308,336,364,350,359,333],[88,49,87,82,90,98,86,115],[20,47,49,51,54,48,40],[159,79,177,158,157,152,155,167,118],[1219,1183,1182,1115,1035,1186,591,1197,1167,887,1184,1175],[611,518,693,343,704,667,686,682,677,687,725],[607,599,634,305,677,604,603,580,452,605,591],[682,686,635,675,692,730,687,342,517,658,695],[662,296,573,598,592,584,553,593,595,443,591],[180,185,186,199,187,210,93,177,149],[197,136,179,185,156,182,180,178,99],[271,298,218,279,285,282,280,238,140],[1187,1151,890,593,1194,1188,1184,1173,1038,1186,1255,1203],[169,161,177,192,130,165,84,167,168],[50,42,43,41,66,39,36],[590,669,604,579,448,599,560,299,601,597,598],[174,191,206,179,184,142,177,180,90],[298,299,297,306,164,285,374,269,329,295],[181,172,162,138,170,195,86,169,168],[1184,1197,591,1182,1186,889,1167,1219,1183,1033,1115,1175],[644,695,691,679,667,687,340,681,770,686,517],[606,524,592,576,628,593,591,584,296,444,595],[94,127,154,138,135,74,136,141],[179,168,172,178,177,89,198,186,137],[302,299,291,300,298,149,260,305,280,370],[678,517,670,686,682,768,687,648,342,692,702],[302,290,304,376,333,303,306,298,279,153],[95,102,109,54,96,75,85,97],[150,154,146,78,152,151,162,173,119],[150,143,157,152,184,112,154,151,132],[36,41,54,40,25,44,42],[37,48,34,59,39,41,40],[681,603,638,611,584,303,454,607,606,605,596]
];
```
## --seed-contents--
```js
function euler105() {
function testingSpecialSubsetSums(sets) {
return true;
}
euler105();
const testSets = [
[81,88,75,42,87,84,86,65],[157,150,164,119,79,159,161,139,158],[673,465,569,603,629,592,584,300,601,599,600],[90,85,83,84,65,87,76,46],[165,168,169,190,162,85,176,167,127],[224,275,278,249,277,279,289,295,139],[354,370,362,384,359,324,360,180,350,270],[599,595,557,298,448,596,577,667,597,588,602],[175,199,137,88,187,173,168,171,174],[93,187,196,144,185,178,186,202,182],[157,155,81,158,119,176,152,167,159],[184,165,159,166,163,167,174,124,83],[1211,1212,1287,605,1208,1189,1060,1216,1243,1200,908,1210],[339,299,153,305,282,304,313,306,302,228],[94,104,63,112,80,84,93,96],[41,88,82,85,61,74,83,81],[90,67,84,83,82,97,86,41],[299,303,151,301,291,302,307,377,333,280],[55,40,48,44,25,42,41],[1038,1188,1255,1184,594,890,1173,1151,1186,1203,1187,1195],[76,132,133,144,135,99,128,154],[77,46,108,81,85,84,93,83],[624,596,391,605,529,610,607,568,604,603,453],[83,167,166,189,163,174,160,165,133],[308,281,389,292,346,303,302,304,300,173],[593,1151,1187,1184,890,1040,1173,1186,1195,1255,1188,1203],[68,46,64,33,60,58,65],[65,43,88,87,86,99,93,90],[83,78,107,48,84,87,96,85],[1188,1173,1256,1038,1187,1151,890,1186,1184,1203,594,1195],[302,324,280,296,294,160,367,298,264,299],[521,760,682,687,646,664,342,698,692,686,672],[56,95,86,97,96,89,108,120],[344,356,262,343,340,382,337,175,361,330],[47,44,42,27,41,40,37],[139,155,161,158,118,166,154,156,78],[118,157,164,158,161,79,139,150,159],[299,292,371,150,300,301,281,303,306,262],[85,77,86,84,44,88,91,67],[88,85,84,44,65,91,76,86],[138,141,127,96,136,154,135,76],[292,308,302,346,300,324,304,305,238,166],[354,342,341,257,348,343,345,321,170,301],[84,178,168,167,131,170,193,166,162],[686,701,706,673,694,687,652,343,683,606,518],[295,293,301,367,296,279,297,263,323,159],[1038,1184,593,890,1188,1173,1187,1186,1195,1150,1203,1255],[343,364,388,402,191,383,382,385,288,374],[1187,1036,1183,591,1184,1175,888,1197,1182,1219,1115,1167],[151,291,307,303,345,238,299,323,301,302],[140,151,143,138,99,69,131,137],[29,44,42,59,41,36,40],[348,329,343,344,338,315,169,359,375,271],[48,39,34,37,50,40,41],[593,445,595,558,662,602,591,297,610,580,594],[686,651,681,342,541,687,691,707,604,675,699],[180,99,189,166,194,188,144,187,199],[321,349,335,343,377,176,265,356,344,332],[1151,1255,1195,1173,1184,1186,1188,1187,1203,593,1038,891],[90,88,100,83,62,113,80,89],[308,303,238,300,151,304,324,293,346,302],[59,38,50,41,42,35,40],[352,366,174,355,344,265,343,310,338,331],[91,89,93,90,117,85,60,106],[146,186,166,175,202,92,184,183,189],[82,67,96,44,80,79,88,76],[54,50,58,66,31,61,64],[343,266,344,172,308,336,364,350,359,333],[88,49,87,82,90,98,86,115],[20,47,49,51,54,48,40],[159,79,177,158,157,152,155,167,118],[1219,1183,1182,1115,1035,1186,591,1197,1167,887,1184,1175],[611,518,693,343,704,667,686,682,677,687,725],[607,599,634,305,677,604,603,580,452,605,591],[682,686,635,675,692,730,687,342,517,658,695],[662,296,573,598,592,584,553,593,595,443,591],[180,185,186,199,187,210,93,177,149],[197,136,179,185,156,182,180,178,99],[271,298,218,279,285,282,280,238,140],[1187,1151,890,593,1194,1188,1184,1173,1038,1186,1255,1203],[169,161,177,192,130,165,84,167,168],[50,42,43,41,66,39,36],[590,669,604,579,448,599,560,299,601,597,598],[174,191,206,179,184,142,177,180,90],[298,299,297,306,164,285,374,269,329,295],[181,172,162,138,170,195,86,169,168],[1184,1197,591,1182,1186,889,1167,1219,1183,1033,1115,1175],[644,695,691,679,667,687,340,681,770,686,517],[606,524,592,576,628,593,591,584,296,444,595],[94,127,154,138,135,74,136,141],[179,168,172,178,177,89,198,186,137],[302,299,291,300,298,149,260,305,280,370],[678,517,670,686,682,768,687,648,342,692,702],[302,290,304,376,333,303,306,298,279,153],[95,102,109,54,96,75,85,97],[150,154,146,78,152,151,162,173,119],[150,143,157,152,184,112,154,151,132],[36,41,54,40,25,44,42],[37,48,34,59,39,41,40],[681,603,638,611,584,303,454,607,606,605,596]
];
testingSpecialSubsetSums(testSets);
```
# --solutions--

View File

@ -8,11 +8,10 @@ dashedName: problem-106-special-subset-sums-meta-testing
# --description--
Let S(A) represent the sum of elements in set A of size n. We shall call it a special sum set if for any two non-empty disjoint subsets, B and C, the following properties are true:
Let $S(A)$ represent the sum of elements in set A of size n. We shall call it a special sum set if for any two non-empty disjoint subsets, B and C, the following properties are true:
S(B) ≠ S(C); that is, sums of subsets cannot be equal.
If B contains more elements than C then S(B) > S(C).
1. $S(B) ≠ S(C)$; that is, sums of subsets cannot be equal.
2. If B contains more elements than C then $S(B) > S(C)$.
For this problem we shall assume that a given set contains n strictly increasing elements and it already satisfies the second rule.
@ -20,14 +19,14 @@ Surprisingly, out of the 25 possible subset pairs that can be obtained from a se
For n = 12, how many of the 261625 subset pairs that can be obtained need to be tested for equality?
NOTE: This problem is related to Problem 103 and Problem 105.
**Note:** This problem is related to Problem 103 and Problem 105.
# --hints--
`euler106()` should return 21384.
`subsetSumsMetaTesting()` should return `21384`.
```js
assert.strictEqual(euler106(), 21384);
assert.strictEqual(subsetSumsMetaTesting(), 21384);
```
# --seed--
@ -35,12 +34,12 @@ assert.strictEqual(euler106(), 21384);
## --seed-contents--
```js
function euler106() {
function subsetSumsMetaTesting() {
return true;
}
euler106();
subsetSumsMetaTesting();
```
# --solutions--

View File

@ -10,19 +10,17 @@ dashedName: problem-108-diophantine-reciprocals-i
In the following equation x, y, and n are positive integers.
1/`x` + 1/`y` = 1/`n`
$$\frac{1}{x} + \frac{1}{y} = \frac{1}{n}$$
For `n` = 4 there are exactly three distinct solutions:
1/5 + 1/20 = 1/4
1/6 + 1/12 = 1/4
1/8 + 1/8 = 1/4
$$\begin{align} & \frac{1}{5} + \frac{1}{20} = \frac{1}{4}\\\\ \\\\ & \frac{1}{6} + \frac{1}{12} = \frac{1}{4}\\\\ \\\\ & \frac{1}{8} + \frac{1}{8} = \frac{1}{4} \end{align}$$
What is the least value of `n` for which the number of distinct solutions exceeds one-thousand?
# --hints--
`diophantineOne()` should return 180180.
`diophantineOne()` should return `180180`.
```js
assert.strictEqual(diophantineOne(), 180180);

View File

@ -10,28 +10,26 @@ dashedName: problem-109-darts
In the game of darts a player throws three darts at a target board which is split into twenty equal sized sections numbered one to twenty.
The score of a dart is determined by the number of the region that the dart lands in. A dart landing outside the red/green outer ring scores zero. The black and cream regions inside this ring represent single scores. However, the red/green outer ring and middle ring score double and treble scores respectively. At the centre of the board are two concentric circles called the bull region, or bulls-eye. The outer bull is worth 25 points and the inner bull is a double, worth 50 points. There are many variations of rules but in the most popular game the players will begin with a score 301 or 501 and the first player to reduce their running total to zero is a winner. However, it is normal to play a "doubles out" system, which means that the player must land a double (including the double bulls-eye at the centre of the board) on their final dart to win; any other dart that would reduce their running total to one or lower means the score for that set of three darts is "bust". When a player is able to finish on their current score it is called a "checkout" and the highest checkout is 170: T20 T20 D25 (two treble 20s and double bull). There are exactly eleven distinct ways to checkout on a score of 6:
<img class="img-responsive center-block" alt="Darts board" src="https://cdn.freecodecamp.org/curriculum/project-euler/darts.png" style="background-color: white; padding: 10px;" />
D3
The score of a dart is determined by the number of the region that the dart lands in. A dart landing outside the red/green outer ring scores zero. The black and cream regions inside this ring represent single scores. However, the red/green outer ring and middle ring score double and treble scores respectively.
D1 D2
At the center of the board are two concentric circles called the bull region, or bulls-eye. The outer bull is worth 25 points and the inner bull is a double, worth 50 points.
S2 D2
There are many variations of rules but in the most popular game the players will begin with a score of 301 or 501 and the first player to reduce their running total to zero is a winner. However, it is normal to play a "doubles out" system, which means that the player must land a double (including the double bulls-eye at the center of the board) on their final dart to win; any other dart that would reduce their running total to one or lower means the score for that set of three darts is "bust".
D2 D1
When a player is able to finish on their current score it is called a "checkout" and the highest checkout is 170: T20 T20 D25 (two treble 20s and double bull). There are exactly eleven distinct ways to checkout on a score of 6:
S4 D1
$$\begin{array} \text{D3} & & \\\\ D1 & D2 & \\\\ S2 & D2 & \\\\ D2 & D1 & \\\\ S4 & D1 & \\\\ S1 & S1 & D2 \\\\ S1 & T1 & D1 \\\\ S1 & S3 & D1 \\\\ D1 & D1 & D1 \\\\ D1 & S2 & D1 \\\\ S2 & S2 & D1 \end{array}$$
S1 S1 D2 S1 T1 D1 S1 S3 D1 D1 D1 D1 D1 S2 D1 S2 S2 D1
Note that D1 D2 is considered different to D2 D1 as they finish on different doubles. However, the combination S1 T1 D1 is considered the same as T1 S1 D1. In addition we shall not include misses in considering combinations; for example, D3 is the same as 0 D3 and 0 0 D3. Incredibly there are 42336 distinct ways of checking out in total. How many distinct ways can a player checkout with a score less than 100?
Note that D1 D2 is considered different from D2 D1 as they finish on different doubles. However, the combination S1 T1 D1 is considered the same as T1 S1 D1. In addition, we shall not include misses in considering combinations; for example, D3 is the same as 0 D3 and 0 0 D3. Incredibly there are 42336 distinct ways of checking out in total. How many distinct ways can a player checkout with a score less than 100?
# --hints--
`euler109()` should return 38182.
`darts()` should return `38182`.
```js
assert.strictEqual(euler109(), 38182);
assert.strictEqual(darts(), 38182);
```
# --seed--
@ -39,12 +37,12 @@ assert.strictEqual(euler109(), 38182);
## --seed-contents--
```js
function euler109() {
function darts() {
return true;
}
euler109();
darts();
```
# --solutions--

View File

@ -10,15 +10,17 @@ dashedName: problem-110-diophantine-reciprocals-ii
In the following equation x, y, and n are positive integers.
1/`x` + 1/`y` = 1/`n`
$$\frac{1}{x} + \frac{1}{y} = \frac{1}{n}$$
It can be verified that when `n` = 1260 there are 113 distinct solutions and this is the least value of `n` for which the total number of distinct solutions exceeds one hundred.
What is the least value of `n` for which the number of distinct solutions exceeds four million?
**Note:** This problem is a much more difficult version of Problem 108 and as it is well beyond the limitations of a brute force approach it requires a clever implementation.
# --hints--
`diophantineTwo()` should return 9350130049860600.
`diophantineTwo()` should return `9350130049860600`.
```js
assert.strictEqual(diophantineTwo(), 9350130049860600);

View File

@ -10,24 +10,35 @@ dashedName: problem-111-primes-with-runs
Considering 4-digit primes containing repeated digits it is clear that they cannot all be the same: 1111 is divisible by 11, 2222 is divisible by 22, and so on. But there are nine 4-digit primes containing three ones:
1117, 1151, 1171, 1181, 1511, 1811, 2111, 4111, 8111
$$1117, 1151, 1171, 1181, 1511, 1811, 2111, 4111, 8111$$
We shall say that M(n, d) represents the maximum number of repeated digits for an n-digit prime where d is the repeated digit, N(n, d) represents the number of such primes, and S(n, d) represents the sum of these primes.
We shall say that $M(n, d)$ represents the maximum number of repeated digits for an n-digit prime where d is the repeated digit, $N(n, d)$ represents the number of such primes, and $S(n, d)$ represents the sum of these primes.
So M(4, 1) = 3 is the maximum number of repeated digits for a 4-digit prime where one is the repeated digit, there are N(4, 1) = 9 such primes, and the sum of these primes is S(4, 1) = 22275. It turns out that for d = 0, it is only possible to have M(4, 0) = 2 repeated digits, but there are N(4, 0) = 13 such cases.
So $M(4, 1) = 3$ is the maximum number of repeated digits for a 4-digit prime where one is the repeated digit, there are $N(4, 1) = 9$ such primes, and the sum of these primes is $S(4, 1) = 22275$. It turns out that for d = 0, it is only possible to have $M(4, 0) = 2$ repeated digits, but there are $N(4, 0) = 13$ such cases.
In the same way we obtain the following results for 4-digit primes.
Digit, d M(4, d) N(4, d) S(4, d) 0 2 13 67061 1 3 9 22275 2 3 1 2221 3 3 12 46214 4 3 2 8888 5 3 1 5557 6 3 1 6661 7 3 9 57863 8 3 1 8887 9 3 7 48073
| Digit, d | $M(4, d)$ | $N(4, d)$ | $S(4, d)$ |
| -------- | --------- | --------- | --------- |
| 0 | 2 | 13 | 67061 |
| 1 | 3 | 9 | 22275 |
| 2 | 3 | 1 | 2221 |
| 3 | 3 | 12 | 46214 |
| 4 | 3 | 2 | 8888 |
| 5 | 3 | 1 | 5557 |
| 6 | 3 | 1 | 6661 |
| 7 | 3 | 9 | 57863 |
| 8 | 3 | 1 | 8887 |
| 9 | 3 | 7 | 48073 |
For d = 0 to 9, the sum of all S(4, d) is 273700. Find the sum of all S(10, d).
For d = 0 to 9, the sum of all $S(4, d)$ is 273700. Find the sum of all $S(10, d)$.
# --hints--
`euler111()` should return 612407567715.
`primesWithRuns()` should return `612407567715`.
```js
assert.strictEqual(euler111(), 612407567715);
assert.strictEqual(primesWithRuns(), 612407567715);
```
# --seed--
@ -35,12 +46,12 @@ assert.strictEqual(euler111(), 612407567715);
## --seed-contents--
```js
function euler111() {
function primesWithRuns() {
return true;
}
euler111();
primesWithRuns();
```
# --solutions--

View File

@ -22,10 +22,10 @@ Find the least number for which the proportion of bouncy numbers is exactly 99%.
# --hints--
`euler112()` should return 1587000.
`bouncyNumbers()` should return `1587000`.
```js
assert.strictEqual(euler112(), 1587000);
assert.strictEqual(bouncyNumbers(), 1587000);
```
# --seed--
@ -33,12 +33,12 @@ assert.strictEqual(euler112(), 1587000);
## --seed-contents--
```js
function euler112() {
function bouncyNumbers() {
return true;
}
euler112();
bouncyNumbers();
```
# --solutions--

View File

@ -14,16 +14,16 @@ Similarly if no digit is exceeded by the digit to its right it is called a decre
We shall call a positive integer that is neither increasing nor decreasing a "bouncy" number; for example, 155349.
As n increases, the proportion of bouncy numbers below n increases such that there are only 12951 numbers below one-million that are not bouncy and only 277032 non-bouncy numbers below 1010.
As n increases, the proportion of bouncy numbers below n increases such that there are only 12951 numbers below one-million that are not bouncy and only 277032 non-bouncy numbers below ${10}^{10}$.
How many numbers below a googol (10100) are not bouncy?
How many numbers below a googol (${10}^{100}$) are not bouncy?
# --hints--
`euler113()` should return 51161058134250.
`nonBouncyNumbers()` should return `51161058134250`.
```js
assert.strictEqual(euler113(), 51161058134250);
assert.strictEqual(nonBouncyNumbers(), 51161058134250);
```
# --seed--
@ -31,12 +31,12 @@ assert.strictEqual(euler113(), 51161058134250);
## --seed-contents--
```js
function euler113() {
function nonBouncyNumbers() {
return true;
}
euler113();
nonBouncyNumbers();
```
# --solutions--

View File

@ -10,14 +10,18 @@ dashedName: problem-114-counting-block-combinations-i
A row measuring seven units in length has red blocks with a minimum length of three units placed on it, such that any two red blocks (which are allowed to be different lengths) are separated by at least one black square. There are exactly seventeen ways of doing this.
How many ways can a row measuring fifty units in length be filled? NOTE: Although the example above does not lend itself to the possibility, in general it is permitted to mix block sizes. For example, on a row measuring eight units in length you could use red (3), black (1), and red (4).
<img class="img-responsive center-block" alt="Possible ways of placing block with a minimum length of three units, on a row with length of seven units" src="https://cdn.freecodecamp.org/curriculum/project-euler/counting-block-combinations-i.png" style="background-color: white; padding: 10px;" />
How many ways can a row measuring fifty units in length be filled?
**Note:** Although the example above does not lend itself to the possibility, in general it is permitted to mix block sizes. For example, on a row measuring eight units in length you could use red (3), black (1), and red (4).
# --hints--
`euler114()` should return 16475640049.
`countingBlockOne()` should return `16475640049`.
```js
assert.strictEqual(euler114(), 16475640049);
assert.strictEqual(countingBlockOne(), 16475640049);
```
# --seed--
@ -25,12 +29,12 @@ assert.strictEqual(euler114(), 16475640049);
## --seed-contents--
```js
function euler114() {
function countingBlockOne() {
return true;
}
euler114();
countingBlockOne();
```
# --solutions--

View File

@ -8,26 +8,26 @@ dashedName: problem-115-counting-block-combinations-ii
# --description--
NOTE: This is a more difficult version of Problem 114.
A row measuring `n` units in length has red blocks with a minimum length of `m` units placed on it, such that any two red blocks (which are allowed to be different lengths) are separated by at least one black square.
A row measuring n units in length has red blocks with a minimum length of m units placed on it, such that any two red blocks (which are allowed to be different lengths) are separated by at least one black square.
Let the fill-count function, $F(m, n)$, represent the number of ways that a row can be filled.
Let the fill-count function, F(m, n), represent the number of ways that a row can be filled.
For example, F(3, 29) = 673135 and F(3, 30) = 1089155.
For example, $F(3, 29) = 673135$ and $F(3, 30) = 1089155$.
That is, for m = 3, it can be seen that n = 30 is the smallest value for which the fill-count function first exceeds one million.
In the same way, for m = 10, it can be verified that F(10, 56) = 880711 and F(10, 57) = 1148904, so n = 57 is the least value for which the fill-count function first exceeds one million.
In the same way, for m = 10, it can be verified that $F(10, 56) = 880711$ and $F(10, 57) = 1148904$, so n = 57 is the least value for which the fill-count function first exceeds one million.
For m = 50, find the least value of n for which the fill-count function first exceeds one million.
For m = 50, find the least value of `n` for which the fill-count function first exceeds one million.
**Note:** This is a more difficult version of Problem 114.
# --hints--
`euler115()` should return 168.
`countingBlockTwo()` should return `168`.
```js
assert.strictEqual(euler115(), 168);
assert.strictEqual(countingBlockTwo(), 168);
```
# --seed--
@ -35,12 +35,12 @@ assert.strictEqual(euler115(), 168);
## --seed-contents--
```js
function euler115() {
function countingBlockTwo() {
return true;
}
euler115();
countingBlockTwo();
```
# --solutions--

View File

@ -12,18 +12,26 @@ A row of five black square tiles is to have a number of its tiles replaced with
If red tiles are chosen there are exactly seven ways this can be done.
<img class="img-responsive center-block" alt="Possible ways to placing red oblong on a row with length of five units" src="https://cdn.freecodecamp.org/curriculum/project-euler/red-green-or-blue-tiles-1.png" style="background-color: white; padding: 10px;" />
If green tiles are chosen there are three ways.
<img class="img-responsive center-block" alt="Possible ways of placing green oblong on a row with length of five units" src="https://cdn.freecodecamp.org/curriculum/project-euler/red-green-or-blue-tiles-2.png" style="background-color: white; padding: 10px;" />
And if blue tiles are chosen there are two ways.
Assuming that colours cannot be mixed there are 7 + 3 + 2 = 12 ways of replacing the black tiles in a row measuring five units in length. How many different ways can the black tiles in a row measuring fifty units in length be replaced if colours cannot be mixed and at least one coloured tile must be used? NOTE: This is related to Problem 117.
<img class="img-responsive center-block" alt="Possible ways of placing blue oblong on a row with length of five units" src="https://cdn.freecodecamp.org/curriculum/project-euler/red-green-or-blue-tiles-3.png" style="background-color: white; padding: 10px;" />
Assuming that colors cannot be mixed there are 7 + 3 + 2 = 12 ways of replacing the black tiles in a row measuring five units in length. How many different ways can the black tiles in a row measuring fifty units in length be replaced if colors cannot be mixed and at least one colored tile must be used?
**Note:** This is related to Problem 117.
# --hints--
`euler116()` should return 20492570929.
`redGreenBlueOne()` should return `20492570929`.
```js
assert.strictEqual(euler116(), 20492570929);
assert.strictEqual(redGreenBlueOne(), 20492570929);
```
# --seed--
@ -31,12 +39,12 @@ assert.strictEqual(euler116(), 20492570929);
## --seed-contents--
```js
function euler116() {
function redGreenBlueOne() {
return true;
}
euler116();
redGreenBlueOne();
```
# --solutions--

View File

@ -10,14 +10,18 @@ dashedName: problem-117-red-green-and-blue-tiles
Using a combination of black square tiles and oblong tiles chosen from: red tiles measuring two units, green tiles measuring three units, and blue tiles measuring four units, it is possible to tile a row measuring five units in length in exactly fifteen different ways.
How many ways can a row measuring fifty units in length be tiled? NOTE: This is related to Problem 116.
<img class="img-responsive center-block" alt="Possible ways of placing red, green and blue oblongs on a row with length of five units" src="https://cdn.freecodecamp.org/curriculum/project-euler/red-green-and-blue-tiles.png" style="background-color: white; padding: 10px;" />
How many ways can a row measuring fifty units in length be tiled?
**Note**: This is related to Problem 116.
# --hints--
`euler117()` should return 100808458960497.
`redGreenBlueTilesTwo()` should return `100808458960497`.
```js
assert.strictEqual(euler117(), 100808458960497);
assert.strictEqual(redGreenBlueTilesTwo(), 100808458960497);
```
# --seed--
@ -25,12 +29,12 @@ assert.strictEqual(euler117(), 100808458960497);
## --seed-contents--
```js
function euler117() {
function redGreenBlueTilesTwo() {
return true;
}
euler117();
redGreenBlueTilesTwo();
```
# --solutions--

View File

@ -8,16 +8,16 @@ dashedName: problem-118-pandigital-prime-sets
# --description--
Using all of the digits 1 through 9 and concatenating them freely to form decimal integers, different sets can be formed. Interestingly with the set {2,5,47,89,631}, all of the elements belonging to it are prime.
Using all of the digits 1 through 9 and concatenating them freely to form decimal integers, different sets can be formed. Interestingly with the set $\\{2, 5, 47, 89, 631\\}$, all of the elements belonging to it are prime.
How many distinct sets containing each of the digits one through nine exactly once contain only prime elements?
# --hints--
`euler118()` should return 44680.
`pandigitalPrimeSets()` should return `44680`.
```js
assert.strictEqual(euler118(), 44680);
assert.strictEqual(pandigitalPrimeSets(), 44680);
```
# --seed--
@ -25,12 +25,12 @@ assert.strictEqual(euler118(), 44680);
## --seed-contents--
```js
function euler118() {
function pandigitalPrimeSets() {
return true;
}
euler118();
pandigitalPrimeSets();
```
# --solutions--

View File

@ -8,20 +8,20 @@ dashedName: problem-119-digit-power-sum
# --description--
The number 512 is interesting because it is equal to the sum of its digits raised to some power: 5 + 1 + 2 = 8, and 83 = 512. Another example of a number with this property is 614656 = 284.
The number 512 is interesting because it is equal to the sum of its digits raised to some power: $5 + 1 + 2 = 8$, and $8^3 = 512$. Another example of a number with this property is $614656 = 28^4$.
We shall define an to be the nth term of this sequence and insist that a number must contain at least two digits to have a sum.
We shall define an to be the $n-th$ term of this sequence and insist that a number must contain at least two digits to have a sum.
You are given that a2 = 512 and a10 = 614656.
You are given that $a_2 = 512$ and $a_{10} = 614656$.
Find a30.
Find $a_{30}$.
# --hints--
`euler119()` should return 248155780267521.
`digitPowerSum()` should return `248155780267521`.
```js
assert.strictEqual(euler119(), 248155780267521);
assert.strictEqual(digitPowerSum(), 248155780267521);
```
# --seed--
@ -29,12 +29,12 @@ assert.strictEqual(euler119(), 248155780267521);
## --seed-contents--
```js
function euler119() {
function digitPowerSum() {
return true;
}
euler119();
digitPowerSum();
```
# --solutions--

View File

@ -8,18 +8,18 @@ dashedName: problem-120-square-remainders
# --description--
Let r be the remainder when (a1)n + (a+1)n is divided by a2.
Let `r` be the remainder when ${(a 1)}^n + {(a + 1)}^n$ is divided by $a^2$.
For example, if a = 7 and n = 3, then r = 42: 63 + 83 = 728 ≡ 42 mod 49. And as n varies, so too will r, but for a = 7 it turns out that rmax = 42.
For example, if $a = 7$ and $n = 3$, then $r = 42: 6^3 + 8^3 = 728 ≡ 42 \\ \text{mod}\\ 49$. And as `n` varies, so too will `r`, but for $a = 7$ it turns out that $r_{max} = 42$.
For 3 ≤ a ≤ 1000, find ∑ rmax.
For $3 ≤ a ≤ 1000$, find $\sum{r}_{max}$.
# --hints--
`euler120()` should return 333082500.
`squareRemainders()` should return `333082500`.
```js
assert.strictEqual(euler120(), 333082500);
assert.strictEqual(squareRemainders(), 333082500);
```
# --seed--
@ -27,12 +27,12 @@ assert.strictEqual(euler120(), 333082500);
## --seed-contents--
```js
function euler120() {
function squareRemainders() {
return true;
}
euler120();
squareRemainders();
```
# --solutions--

View File

@ -10,16 +10,48 @@ dashedName: problem-182-rsa-encryption
The RSA encryption is based on the following procedure:
Generate two distinct primes p and q.Compute n=pq and φ=(p-1)(q-1).
Generate two distinct primes `p` and `q`. Compute `n=p*q` and `φ=(p-1)(q-1)`. Find an integer `e`, `1 < e < φ`, such that `gcd(e,φ) = 1`
Find an integer e, 1&lt;e&lt;φ, such='' that='' gcd(e,φ)='1.' a='' message='' in='' this='' system='' is='' number='' the='' interval='' \[0,n-1].='' text='' to='' be='' encrypted='' then='' somehow='' converted='' messages='' (numbers='' \[0,n-1]).='' encrypt='' text,='' for='' each='' message,='' m,='' c='me' mod='' n='' calculated.='' decrypt='' following='' procedure='' needed:='' calculate='' d='' ed='1' φ,='' c,='' m='cd' n.='' there='' exist='' values='' of='' e='' and='' me='' call='' which='' unconcealed='' messages.='' an='' issue='' when='' choosing='' should='' not='' too='' many='' instance,='' let='' p='19' q='37.' φ='18\*36=648.' if='' we='' choose='' then,='' although='' gcd(181,648)='1' it='' turns='' out='' all='' possible='' messagesm='' (0≤m≤n-1)='' are='' calculating='' any='' valid='' choice='' some='' it's='' important='' at='' minimum.='' find='' sum='' e,='' 1&lt;e&lt;φ(1009,3643)='' so='' value='' &lt;='' section=''>&lt;/e&lt;φ,>
A message in this system is a number in the interval `[0,n-1]`. A text to be encrypted is then somehow converted to messages (numbers in the interval `[0,n-1]`). To encrypt the text, for each message, `m`, c=m<sup>e</sup> mod n is calculated.
To decrypt the text, the following procedure is needed: calculate `d` such that `ed=1 mod φ`, then for each encrypted message, `c`, calculate m=c<sup>d</sup> mod n.
There exist values of `e` and `m` such that m<sup>e</sup> mod n = m. We call messages `m` for which m<sup>e</sup> mod n=m unconcealed messages.
An issue when choosing `e` is that there should not be too many unconcealed messages. For instance, let `p=19` and `q=37`. Then `n=19*37=703` and `φ=18*36=648`. If we choose `e=181`, then, although `gcd(181,648)=1` it turns out that all possible messages m `(0≤m≤n-1)` are unconcealed when calculating m<sup>e</sup> mod n. For any valid choice of `e` there exist some unconcealed messages. It's important that the number of unconcealed messages is at a minimum.
For any given `p` and `q`, find the sum of all values of `e`, `1 < e < φ(p,q)` and `gcd(e,φ)=1`, so that the number of unconcealed messages for this value of `e` is at a minimum.
# --hints--
`euler182()` should return 399788195976.
`RSAEncryption` should be a function.
```js
assert.strictEqual(euler182(), 399788195976);
assert(typeof RSAEncryption === 'function')
```
`RSAEncryption` should return a number.
```js
assert.strictEqual(typeof RSAEncryption(19, 37), 'number');
```
`RSAEncryption(19, 37)` should return `17766`.
```js
assert.strictEqual(RSAEncryption(19, 37), 17766);
```
`RSAEncryption(283, 409)` should return `466196580`.
```js
assert.strictEqual(RSAEncryption(283, 409), 466196580);
```
`RSAEncryption(1009, 3643)` should return `399788195976`.
```js
assert.strictEqual(RSAEncryption(19, 37), 17766);
```
# --seed--
@ -27,16 +59,44 @@ assert.strictEqual(euler182(), 399788195976);
## --seed-contents--
```js
function euler182() {
function RSAEncryption(p, q) {
return true;
}
euler182();
RSAEncryption(19, 37);
```
# --solutions--
```js
// solution required
function gcd(a, b) {
if (b)
return gcd(b, a % b);
else
return a;
}
function RSAEncryption(p, q) {
let phi = (p - 1) * (q - 1);
let best = Number.MAX_SAFE_INTEGER;
let sum = 0;
for (let e = 0; e < phi; ++e) {
if (!(gcd(e, phi) == 1))
continue;
let msg = (gcd(p - 1, e - 1) + 1) * (gcd(q - 1, e - 1) + 1);
if (best == msg) {
sum += e;
} else if (best > msg) {
best = msg;
sum = e;
}
}
return sum;
}
```

View File

@ -12,22 +12,46 @@ We shall say that an `n`-digit number is pandigital if it makes use of all the d
The product 7254 is unusual, as the identity, 39 × 186 = 7254, containing multiplicand, multiplier, and product is 1 through 9 pandigital.
Find the sum of all products whose multiplicand/multiplier/product identity can be written as a 1 through 9 pandigital.
Find the sum of all products whose multiplicand/multiplier/product identity can be written as a 1 through `n` pandigital.
**Hint:** Some products can be obtained in more than one way so be sure to only include it once in your sum.
# --hints--
`pandigitalProducts()` should return a number.
`pandigitalProducts(4)` should return a number.
```js
assert(typeof pandigitalProducts() === 'number');
assert(typeof pandigitalProducts(4) === 'number');
```
`pandigitalProducts()` should return 45228.
`pandigitalProducts(4)` should return `12`.
```js
assert.strictEqual(pandigitalProducts(), 45228);
assert.strictEqual(pandigitalProducts(4), 12);
```
`pandigitalProducts(6)` should return `162`.
```js
assert.strictEqual(pandigitalProducts(6), 162);
```
`pandigitalProducts(7)` should return `0`.
```js
assert.strictEqual(pandigitalProducts(7), 0);
```
`pandigitalProducts(8)` should return `13458`.
```js
assert.strictEqual(pandigitalProducts(8), 13458);
```
`pandigitalProducts(9)` should return `45228`.
```js
assert.strictEqual(pandigitalProducts(9), 45228);
```
# --seed--
@ -35,22 +59,21 @@ assert.strictEqual(pandigitalProducts(), 45228);
## --seed-contents--
```js
function pandigitalProducts() {
function pandigitalProducts(n) {
return true;
}
pandigitalProducts();
pandigitalProducts(4);
```
# --solutions--
```js
function pandigitalProducts() {
function is1to9Pandigital(...numbers) {
const digitStr = concatenateNums(...numbers);
// check if length is 9
if (digitStr.length !== 9) {
function pandigitalProducts(n) {
function is1toNPandigital(n, digitStr) {
// check if length is n
if (digitStr.length !== n) {
return false;
}
// check if pandigital
@ -70,15 +93,24 @@ function pandigitalProducts() {
}
const pandigitalNums = [];
const limit = 10 ** Math.floor(n / 2) - 1;
let sum = 0;
for (let mult1 = 2; mult1 < 9876; mult1++) {
let mult2 = 123;
while (concatenateNums(mult1, mult2, mult1 * mult2).length < 10) {
if (is1to9Pandigital(mult1, mult2, mult1 * mult2) && !pandigitalNums.includes(mult1 * mult2)) {
pandigitalNums.push(mult1 * mult2);
sum += mult1 * mult2;
for (let mult1 = 2; mult1 < limit; mult1++) {
for (let mult2 = 2; mult2 < limit; mult2++) {
const product = mult1 * mult2;
const concatenated = concatenateNums(mult1, mult2, product);
if (concatenated.length > n) {
break;
} else if (concatenated.length < n) {
continue;
}
if (
is1toNPandigital(n, concatenated) &&
!pandigitalNums.includes(product)
) {
pandigitalNums.push(product);
sum += product;
}
mult2++;
}
}
return sum;

View File

@ -16,7 +16,7 @@ The ant is always oriented in one of the cardinal directions (left, right, up or
\- if it is on a white square, it flips the color of the square to black, rotates 90 degrees clockwise and moves forward one square.
Starting with a grid that is entirely white, how many squares are black after 1018 moves of the ant?
Starting with a grid that is entirely white, how many squares are black after 10<sup>18</sup> moves of the ant?
# --hints--

View File

@ -10,30 +10,32 @@ dashedName: problem-38-pandigital-multiples
Take the number 192 and multiply it by each of 1, 2, and 3:
<div style='margin-left: 4em;'>
192 × 1 = 192<br>
192 × 2 = 384<br>
192 × 3 = 576<br>
</div>
$$\begin{align} 192 × 1 = 192\\\\ 192 × 2 = 384\\\\ 192 × 3 = 576\\\\ \end{align}$$
By concatenating each product we get the 1 to 9 pandigital, 192384576. We will call 192384576 the concatenated product of 192 and (1, 2, 3).
The same can be achieved by starting with 9 and multiplying by 1, 2, 3, 4, and 5, giving the pandigital, 918273645, which is the concatenated product of 9 and (1, 2, 3, 4, 5).
What is the largest 1 to 9 pandigital 9-digit number that can be formed as the concatenated product of an integer with (1, 2, ... , `n`) where `n` > 1?
What is the largest 1 to `k` pandigital `k`-digit number that can be formed as the concatenated product of an integer with (1, 2, ..., `n`) where `n` > 1?
# --hints--
`pandigitalMultiples()` should return a number.
`pandigitalMultiples(8)` should return a number.
```js
assert(typeof pandigitalMultiples() === 'number');
assert(typeof pandigitalMultiples(8) === 'number');
```
`pandigitalMultiples()` should return 932718654.
`pandigitalMultiples(8)` should return `78156234`.
```js
assert.strictEqual(pandigitalMultiples(), 932718654);
assert.strictEqual(pandigitalMultiples(8), 78156234);
```
`pandigitalMultiples(9)` should return `932718654`.
```js
assert.strictEqual(pandigitalMultiples(9), 932718654);
```
# --seed--
@ -41,38 +43,37 @@ assert.strictEqual(pandigitalMultiples(), 932718654);
## --seed-contents--
```js
function pandigitalMultiples() {
function pandigitalMultiples(k) {
return true;
}
pandigitalMultiples();
pandigitalMultiples(8);
```
# --solutions--
```js
function pandigitalMultiples() {
function get9DigitConcatenatedProduct(num) {
// returns false if concatenated product is not 9 digits
function pandigitalMultiples(k) {
function getKDigitConcatenatedProduct(num, k) {
// returns false if concatenated product is not k digits
let concatenatedProduct = num.toString();
for (let i = 2; concatenatedProduct.length < 9; i++) {
for (let i = 2; concatenatedProduct.length < k; i++) {
concatenatedProduct += num * i;
}
return concatenatedProduct.length === 9 ? concatenatedProduct : false;
return concatenatedProduct.length === k ? concatenatedProduct : false;
}
function is1to9Pandigital(num) {
function is1toKPandigital(num, k) {
const numStr = num.toString();
// check if length is not 9
if (numStr.length !== 9) {
// check if length is not k
if (numStr.length !== k) {
return false;
}
// check if pandigital
for (let i = 9; i > 0; i--) {
for (let i = k; i > 0; i--) {
if (numStr.indexOf(i.toString()) === -1) {
return false;
}
@ -81,11 +82,13 @@ function pandigitalMultiples() {
}
let largestNum = 0;
for (let i = 9999; i >= 9000; i--) {
const concatenatedProduct = get9DigitConcatenatedProduct(i);
if (is1to9Pandigital(concatenatedProduct) && concatenatedProduct > largestNum) {
largestNum = parseInt(concatenatedProduct);
break;
for (let i = 10 ** Math.floor(k / 2) + 1; i >= 1; i--) {
const concatenatedProduct = getKDigitConcatenatedProduct(i, k);
if (is1toKPandigital(concatenatedProduct, k)) {
const number = parseInt(concatenatedProduct, 10);
if (number > largestNum) {
largestNum = number;
}
}
}
return largestNum;

View File

@ -10,49 +10,50 @@ dashedName: problem-43-sub-string-divisibility
The number, 1406357289, is a 0 to 9 pandigital number because it is made up of each of the digits 0 to 9 in some order, but it also has a rather interesting sub-string divisibility property.
Let d<sub>1</sub> be the 1<sup>st</sup> digit, d<sub>2</sub> be the 2<sup>nd</sup> digit, and so on. In this way, we note the following:
Let $d_1$ be the $1^{st}$ digit, $d_2$ be the $2^{nd}$ digit, and so on. In this way, we note the following:
<ul>
<li>d<sub>2</sub>d<sub>3</sub>d<sub>4</sub> = 406 is divisible by 2</li>
<li>d<sub>3</sub>d<sub>4</sub>d<sub>5</sub> = 063 is divisible by 3</li>
<li>d<sub>4</sub>d<sub>5</sub>d<sub>6</sub> = 635 is divisible by 5</li>
<li>d<sub>5</sub>d<sub>6</sub>d<sub>7</sub> = 357 is divisible by 7</li>
<li>d<sub>6</sub>d<sub>7</sub>d<sub>8</sub> = 572 is divisible by 11</li>
<li>d<sub>7</sub>d<sub>8</sub>d<sub>9</sub> = 728 is divisible by 13</li>
<li>d<sub>8</sub>d<sub>9</sub>d<sub>10</sub> = 289 is divisible by 17</li>
</ul>
- ${d_2}{d_3}{d_4} = 406$ is divisible by 2
- ${d_3}{d_4}{d_5} = 063$ is divisible by 3
- ${d_4}{d_5}{d_6} = 635$ is divisible by 5
- ${d_5}{d_6}{d_7} = 357$ is divisible by 7
- ${d_6}{d_7}{d_8} = 572$ is divisible by 11
- ${d_7}{d_8}{d_9} = 728$ is divisible by 13
- ${d_8}{d_9}{d_{10}} = 289$ is divisible by 17
Find the numbers of all 0 to 9 pandigital numbers with this property.
Find the sum of all 0 to `n` pandigital numbers with sub-strings fulfilling `n - 2` of these divisibility properties.
**Note:** Pandigital numbers starting with `0` are to be considered in the result.
# --hints--
`substringDivisibility()` should return an array.
`substringDivisibility(5)` should return a number.
```js
assert(Array.isArray(substringDivisibility()));
assert(typeof substringDivisibility(5) === 'number');
```
`substringDivisibility()` should return [ 1430952867, 1460357289, 1406357289, 4130952867, 4160357289, 4106357289 ].
`substringDivisibility(5)` should return `12444480`.
```js
assert.sameMembers(substringDivisibility(), [
1430952867,
1460357289,
1406357289,
4130952867,
4160357289,
4106357289
]);
assert.strictEqual(substringDivisibility(5), 12444480)
```
You should not copy and return the array.
`substringDivisibility(7)` should return `1099210170`.
```js
assert(
!code.match(
/(1430952867)|(1460357289)|(1406357289)|(4130952867)|(4160357289)|(4106357289)/
)
);
assert.strictEqual(substringDivisibility(7), 1099210170)
```
`substringDivisibility(8)` should return `1113342912`.
```js
assert.strictEqual(substringDivisibility(8), 1113342912)
```
`substringDivisibility(9)` should return `16695334890`.
```js
assert.strictEqual(substringDivisibility(9), 16695334890)
```
# --seed--
@ -60,16 +61,66 @@ assert(
## --seed-contents--
```js
function substringDivisibility() {
function substringDivisibility(n) {
return [];
return true;
}
substringDivisibility();
substringDivisibility(5);
```
# --solutions--
```js
// solution required
function substringDivisibility(n) {
function isSubDivisable(digits) {
const factors = [2, 3, 5, 7, 11, 13, 17];
for (let i = 1; i < digits.length - 2; i++) {
const subNumber = digits[i] * 100 + digits[i + 1] * 10 + digits[i + 2];
if (subNumber % factors[i - 1] !== 0) {
return false;
}
}
return true;
}
function heapsPermutations(k, digits, conditionCheck, results) {
if (k === 1) {
if (conditionCheck(digits)) {
const number = parseInt(digits.join(''), 10);
results.push(number);
}
return;
}
heapsPermutations(k - 1, digits, conditionCheck, results);
for (let i = 0; i < k - 1; i++) {
if (k % 2 === 0) {
[digits[i], digits[k - 1]] = [digits[k - 1], digits[i]];
} else {
[digits[0], digits[k - 1]] = [digits[k - 1], digits[0]];
}
heapsPermutations(k - 1, digits, conditionCheck, results);
}
return;
}
const allowedDigits = [...new Array(n + 1).keys()];
const divisablePandigitals = [];
heapsPermutations(
allowedDigits.length,
allowedDigits,
isSubDivisable,
divisablePandigitals
);
let sum = 0;
for (let i = 0; i < divisablePandigitals.length; i++) {
sum += divisablePandigitals[i];
}
return sum;
}
```

View File

@ -8,26 +8,46 @@ dashedName: problem-461-almost-pi
# --description--
Let fn(k) = ek/n - 1, for all non-negative integers k.
Let `f(k, n)` = $e^\frac{k}{n} - 1$, for all non-negative integers `k`.
Remarkably, f200(6) + f200(75) + f200(89) + f200(226) = 3.141592644529… ≈ π.
Remarkably, `f(6, 200) + f(75, 200) + f(89, 200) + f(226, 200)` = 3.1415926… ≈ π.
In fact, it is the best approximation of π of the form fn(a) + fn(b) + fn(c) + fn(d) for n = 200.
In fact, it is the best approximation of π of the form `f(a, 200) + f(b, 200) + f(c, 200) + f(d, 200)`.
Let g(n) = a2 + b2 + c2 + d 2 for a, b, c, d that minimize the error: | fn(a) + fn(b) + fn(c) + fn(d) - π|
Let `almostPi(n)` = a<sup>2</sup> + b<sup>2</sup> + c<sup>2</sup> + d<sup>2</sup> for a, b, c, d that minimize the error: $\lvert f(a,n) + f(b,n) + f(c,n) + f(d,n) - \Pi\rvert$
(where |x| denotes the absolute value of x).
You are given g(200) = 62 + 752 + 892 + 2262 = 64658.
Find g(10000).
You are given `almostPi(200)` = 6<sup>2</sup> + 75<sup>2</sup> + 89<sup>2</sup> + 226<sup>2</sup> = 64658.
# --hints--
`euler461()` should return 159820276.
`almostPi` should be a function.
```js
assert.strictEqual(euler461(), 159820276);
assert(typeof almostPi === 'function')
```
`almostPi` should return a number.
```js
assert.strictEqual(typeof almostPi(10), 'number');
```
`almostPi(29)` should return `1208`.
```js
assert.strictEqual(almostPi(29), 1208);
```
`almostPi(50)` should return `4152`.
```js
assert.strictEqual(almostPi(50), 4152);
```
`almostPi(200)` should return `64658`.
```js
assert.strictEqual(almostPi(200), 64658);
```
# --seed--
@ -35,16 +55,99 @@ assert.strictEqual(euler461(), 159820276);
## --seed-contents--
```js
function euler461() {
function almostPi(n) {
return true;
}
euler461();
```
# --solutions--
```js
// solution required
function almostPi(n) {
// Find all possible values where f(k, n) <= PI
const f = [];
let max = 0;
while (1) {
let current = Math.exp(max / n) - 1;
if (current > Math.PI) break;
f.push(current);
++max;
}
// Get all pairs where f[i] + f[j] <= PI
const pairs = [];
for (let i = 0; i < max; ++i) {
for (let j = 0; j < max; ++j) {
if (f[i] + f[j] > Math.PI) break;
pairs.push(f[i] + f[j]);
}
}
// Sort all values
pairs.sort((a, b) => a - b);
// Optimal Value for (a + b)
let left = 0;
// Optimal Value for (c + d)
let right = 0;
// minimum error with Math.abs(a + b - Math.PI)
let minError = Math.PI;
// Binary Search for the best match
for (let i = 0; i < pairs.length; ++i) {
let current = pairs[i];
let need = Math.PI - current;
if (need < current) break;
let match;
for (let i = 1; i < pairs.length; ++i) {
if (pairs[i] > need) {
match = i;
break;
}
}
let error = Math.abs(need - pairs[match]);
if (error < minError)
{
minError = error;
left = i;
right = match;
}
--match;
error = Math.abs(need - pairs[match]);
if (error < minError) {
minError = error;
left = i;
right = match;
}
}
let a, b, c, d;
OuterLoop1:
for (a = 0; a < max; ++a) {
for (b = a; b < max; ++b) {
if (pairs[left] == f[a] + f[b]) {
break OuterLoop1;
}
}
}
OuterLoop2:
for (c = 0; c < max; ++c) {
for (d = c; d < max; ++d) {
if (pairs[right] == f[c] + f[d]) {
break OuterLoop2;
}
}
}
return a*a + b*b + c*c + d*d;
}
```

View File

@ -12,20 +12,32 @@ By replacing the 1st digit of the 2-digit number \*3, it turns out that six of t
By replacing the 3rd and 4th digits of 56\*\*3 with the same digit, this 5-digit number is the first example having seven primes among the ten generated numbers, yielding the family: 56003, 56113, 56333, 56443, 56663, 56773, and 56993. Consequently 56003, being the first member of this family, is the smallest prime with this property.
Find the smallest prime which, by replacing part of the number (not necessarily adjacent digits) with the same digit, is part of an eight prime value family.
Find the smallest prime which, by replacing part of the number (not necessarily adjacent digits) with the same digit, is part of an `n` prime value family.
# --hints--
`primeDigitReplacements()` should return a number.
`primeDigitReplacements(6)` should return a number.
```js
assert(typeof primeDigitReplacements() === 'number');
assert(typeof primeDigitReplacements(6) === 'number');
```
`primeDigitReplacements()` should return 121313.
`primeDigitReplacements(6)` should return `13`.
```js
assert.strictEqual(primeDigitReplacements(), 121313);
assert.strictEqual(primeDigitReplacements(6), 13);
```
`primeDigitReplacements(7)` should return `56003`.
```js
assert.strictEqual(primeDigitReplacements(7), 56003);
```
`primeDigitReplacements(8)` should return `121313`.
```js
assert.strictEqual(primeDigitReplacements(8), 121313);
```
# --seed--
@ -33,16 +45,81 @@ assert.strictEqual(primeDigitReplacements(), 121313);
## --seed-contents--
```js
function primeDigitReplacements() {
function primeDigitReplacements(n) {
return true;
}
primeDigitReplacements();
primeDigitReplacements(6);
```
# --solutions--
```js
// solution required
function primeDigitReplacements(n) {
function isNFamily(number, primesMap, n) {
const prime = number.toString();
const lastDigit = prime[prime.length - 1];
return (
doesReplacingMakeFamily(prime, '0', primesMap, n) ||
(lastDigit !== '1' &&
doesReplacingMakeFamily(prime, '1', primesMap, n)) ||
doesReplacingMakeFamily(prime, '2', primesMap, n)
);
}
function doesReplacingMakeFamily(prime, digitToReplace, primesMap, family) {
let count = 0;
const replaceWith = '0123456789';
for (let i = 0; i < replaceWith.length; i++) {
const nextNumber = parseInt(
prime.replace(new RegExp(digitToReplace, 'g'), replaceWith[i]),
10
);
if (isPartOfFamily(nextNumber, prime, primesMap)) {
count++;
}
}
return count === family;
}
function isPartOfFamily(number, prime, primesMap) {
return (
isPrime(number, primesMap) && number.toString().length === prime.length
);
}
function getSievePrimes(max) {
const primesMap = new Array(max).fill(true);
primesMap[0] = false;
primesMap[1] = false;
for (let i = 2; i < max; i++) {
if (primesMap[i]) {
let j = i * i;
for (j; j < max; j += i) {
primesMap[j] = false;
}
}
}
return primesMap;
}
function isPrime(num, primesMap) {
return primesMap[num];
}
const primesMap = getSievePrimes(1000000);
for (let number = 1; number < 300000; number++) {
if (primesMap[number]) {
if (isNFamily(number, primesMap, n)) {
return number;
}
}
}
return -1;
}
```

View File

@ -10,20 +10,26 @@ dashedName: problem-52-permuted-multiples
It can be seen that the number, 125874, and its double, 251748, contain exactly the same digits, but in a different order.
Find the smallest positive integer, `x`, such that `2x`, `3x`, `4x`, `5x`, and `6x`, contain the same digits.
Find the smallest positive integer, such that multiplied by integers $\\{2, 3, \ldots, n\\}$, contain the same digits.
# --hints--
`permutedMultiples()` should return a number.
`permutedMultiples(2)` should return a number.
```js
assert(typeof permutedMultiples() === 'number');
assert(typeof permutedMultiples(2) === 'number');
```
`permutedMultiples()` should return 142857.
`permutedMultiples(2)` should return `125874`.
```js
assert.strictEqual(permutedMultiples(), 142857);
assert.strictEqual(permutedMultiples(2), 125874);
```
`permutedMultiples(6)` should return `142857`.
```js
assert.strictEqual(permutedMultiples(6), 142857);
```
# --seed--
@ -31,18 +37,18 @@ assert.strictEqual(permutedMultiples(), 142857);
## --seed-contents--
```js
function permutedMultiples() {
function permutedMultiples(n) {
return true;
}
permutedMultiples();
permutedMultiples(2);
```
# --solutions--
```js
function permutedMultiples() {
function permutedMultiples(n) {
const isPermutation = (a, b) =>
a.length !== b.length
? false
@ -55,9 +61,9 @@ function permutedMultiples() {
while (!found) {
start *= 10;
for (let i = start; i < start * 10 / 6; i++) {
for (let i = start; i < start * 10 / n; i++) {
found = true;
for (let j = 2; j <= 6; j++) {
for (let j = 2; j <= n; j++) {
if (!isPermutation(i + '', j * i + '')) {
found = false;
break;

View File

@ -8,22 +8,46 @@ dashedName: problem-56-powerful-digit-sum
# --description--
A googol (10<sup>100</sup>) is a massive number: one followed by one-hundred zeros; 100<sup>100</sup> is almost unimaginably large: one followed by two-hundred zeros. Despite their size, the sum of the digits in each number is only 1.
A googol ($10^{100}$) is a massive number: one followed by one-hundred zeros; $100^{100}$ is almost unimaginably large: one followed by two-hundred zeros. Despite their size, the sum of the digits in each number is only 1.
Considering natural numbers of the form, `ab`, where `a`, `b` &lt; 100, what is the maximum digital sum?
Considering natural numbers of the form, $a^b$, where `a`, `b` &lt; `n`, what is the maximum digital sum?
# --hints--
`powerfulDigitSum()` should return a number.
`powerfulDigitSum(3)` should return a number.
```js
assert(typeof powerfulDigitSum() === 'number');
assert(typeof powerfulDigitSum(3) === 'number');
```
`powerfulDigitSum()` should return 972.
`powerfulDigitSum(3)` should return `4`.
```js
assert.strictEqual(powerfulDigitSum(), 972);
assert.strictEqual(powerfulDigitSum(3), 4);
```
`powerfulDigitSum(10)` should return `45`.
```js
assert.strictEqual(powerfulDigitSum(10), 45);
```
`powerfulDigitSum(50)` should return `406`.
```js
assert.strictEqual(powerfulDigitSum(50), 406);
```
`powerfulDigitSum(75)` should return `684`.
```js
assert.strictEqual(powerfulDigitSum(75), 684);
```
`powerfulDigitSum(100)` should return `972`.
```js
assert.strictEqual(powerfulDigitSum(100), 972);
```
# --seed--
@ -31,16 +55,47 @@ assert.strictEqual(powerfulDigitSum(), 972);
## --seed-contents--
```js
function powerfulDigitSum() {
function powerfulDigitSum(n) {
return true;
}
powerfulDigitSum();
powerfulDigitSum(3);
```
# --solutions--
```js
// solution required
function powerfulDigitSum(n) {
function sumDigitsOfPower(numA, numB) {
let digitsSum = 0;
let number = power(numA, numB);
while (number > 0n) {
const digit = number % 10n;
digitsSum += parseInt(digit, 10);
number = number / 10n;
}
return digitsSum;
}
function power(numA, numB) {
let sum = 1n;
for (let b = 0; b < numB; b++) {
sum = sum * BigInt(numA);
}
return sum;
}
const limit = n - 1;
let maxDigitsSum = 0;
for (let a = limit; a > 0; a--) {
for (let b = limit; b > 0; b--) {
const curDigitSum = sumDigitsOfPower(a, b);
if (curDigitSum > maxDigitsSum) {
maxDigitsSum = curDigitSum;
}
}
}
return maxDigitsSum;
}
```

View File

@ -24,20 +24,32 @@ $1 + \\frac 1 {2 + \\frac 1 {2+\\frac 1 {2+\\frac 1 2}}} = \\frac {41}{29} = 1.4
The next three expansions are $\\frac {99}{70}$, $\\frac {239}{169}$, and $\\frac {577}{408}$, but the eighth expansion, $\\frac {1393}{985}$, is the first example where the number of digits in the numerator exceeds the number of digits in the denominator.
In the first one-thousand expansions, how many fractions contain a numerator with more digits than denominator?
In the first `n` expansions, how many fractions contain a numerator with more digits than denominator?
# --hints--
`squareRootConvergents()` should return a number.
`squareRootConvergents(10)` should return a number.
```js
assert(typeof squareRootConvergents() === 'number');
assert(typeof squareRootConvergents(10) === 'number');
```
`squareRootConvergents()` should return 153.
`squareRootConvergents(10)` should return 1.
```js
assert.strictEqual(squareRootConvergents(), 153);
assert.strictEqual(squareRootConvergents(10), 1);
```
`squareRootConvergents(100)` should return 15.
```js
assert.strictEqual(squareRootConvergents(100), 15);
```
`squareRootConvergents(1000)` should return 153.
```js
assert.strictEqual(squareRootConvergents(1000), 153);
```
# --seed--
@ -45,16 +57,42 @@ assert.strictEqual(squareRootConvergents(), 153);
## --seed-contents--
```js
function squareRootConvergents() {
function squareRootConvergents(n) {
return true;
}
squareRootConvergents();
squareRootConvergents(1000);
```
# --solutions--
```js
// solution required
function squareRootConvergents(n) {
function countDigits(number) {
let counter = 0;
while (number > 0) {
counter++;
number = number / 10n;
}
return counter;
}
// Use BigInt as integer won't handle all cases
let numerator = 3n;
let denominator = 2n;
let moreDigitsInNumerator = 0;
for (let i = 2; i <= n; i++) {
[numerator, denominator] = [
numerator + 2n * denominator,
denominator + numerator
];
if (countDigits(numerator) > countDigits(denominator)) {
moreDigitsInNumerator++;
}
}
return moreDigitsInNumerator;
}
```

View File

@ -22,20 +22,32 @@ Starting with 1 and spiralling anticlockwise in the following way, a square spir
It is interesting to note that the odd squares lie along the bottom right diagonal, but what is more interesting is that 8 out of the 13 numbers lying along both diagonals are prime; that is, a ratio of 8/13 ≈ 62%.
If one complete new layer is wrapped around the spiral above, a square spiral with side length 9 will be formed. If this process is continued, what is the side length of the square spiral for which the ratio of primes along both diagonals first falls below 10%?
If one complete new layer is wrapped around the spiral above, a square spiral with side length 9 will be formed. If this process is continued, what is the side length of the square spiral for which the percent of primes along both diagonals first falls below `percent`?
# --hints--
`spiralPrimes()` should return a number.
`spiralPrimes(50)` should return a number.
```js
assert(typeof spiralPrimes() === 'number');
assert(typeof spiralPrimes(50) === 'number');
```
`spiralPrimes()` should return 26241.
`spiralPrimes(50)` should return `11`.
```js
assert.strictEqual(spiralPrimes(), 26241);
assert.strictEqual(spiralPrimes(50), 11);
```
`spiralPrimes(15)` should return `981`.
```js
assert.strictEqual(spiralPrimes(15), 981);
```
`spiralPrimes(10)` should return `26241`.
```js
assert.strictEqual(spiralPrimes(10), 26241);
```
# --seed--
@ -43,16 +55,51 @@ assert.strictEqual(spiralPrimes(), 26241);
## --seed-contents--
```js
function spiralPrimes() {
function spiralPrimes(percent) {
return true;
}
spiralPrimes();
spiralPrimes(50);
```
# --solutions--
```js
// solution required
function spiralPrimes(percent) {
function isPrime(n) {
if (n <= 3) {
return n > 1;
} else if (n % 2 === 0 || n % 3 === 0) {
return false;
}
for (let i = 5; i * i <= n; i += 6) {
if (n % i === 0 || n % (i + 2) === 0) {
return false;
}
}
return true;
}
let totalCount = 1;
let primesCount = 0;
let curNumber = 1;
let curSideLength = 1;
let ratio = 1;
const wantedRatio = percent / 100;
while (ratio >= wantedRatio) {
curSideLength += 2;
for (let i = 0; i < 4; i++) {
curNumber += curSideLength - 1;
totalCount++;
if (i !== 3 && isPrime(curNumber)) {
primesCount++;
}
}
ratio = primesCount / totalCount;
}
return curSideLength;
}
```

View File

@ -10,37 +10,53 @@ dashedName: problem-61-cyclical-figurate-numbers
Triangle, square, pentagonal, hexagonal, heptagonal, and octagonal numbers are all figurate (polygonal) numbers and are generated by the following formulae:
| Type of Number | Formula | Sequence |
| -------------- | --------------------------------------------------------------------- | --------------------- |
| Triangle | P<sub>3</sub>,<var><sub>n</sub></var>=<var>n</var>(<var>n</var>+1)/2 | 1, 3, 6, 10, 15, ... |
| Square | P<sub>4</sub>,<var><sub>n</sub></var>=<var>n</var><sup>2</sup> | 1, 4, 9, 16, 25, ... |
| Pentagonal | P<sub>5</sub>,<var><sub>n</sub></var>=<var>n</var>(3<var>n</var>1)/2 | 1, 5, 12, 22, 35, ... |
| Hexagonal | P<sub>6</sub>,<var><sub>n</sub></var>=<var>n</var>(2<var>n</var>1) | 1, 6, 15, 28, 45, ... |
| Heptagonal | P<sub>7</sub>,<var><sub>n</sub></var>=<var>n</var>(5<var>n</var>3)/2 | 1, 7, 18, 34, 55, ... |
| Octagonal | P<sub>8</sub>,<var><sub>n</sub></var>=<var>n</var>(3<var>n</var>2) | 1, 8, 21, 40, 65, ... |
| Type of Number | Formula | Sequence |
| -------------- | ----------------------------- | --------------------- |
| Triangle | $P_3(n) = \frac{n(n+1)}{2}$ | 1, 3, 6, 10, 15, ... |
| Square | $P_4(n) = n^2$ | 1, 4, 9, 16, 25, ... |
| Pentagonal | $P_5(n) = \frac{n(3n1)}2$ | 1, 5, 12, 22, 35, ... |
| Hexagonal | $P_6(n) = n(2n1)$ | 1, 6, 15, 28, 45, ... |
| Heptagonal | $P_7(n) = \frac{n(5n3)}{2}$ | 1, 7, 18, 34, 55, ... |
| Octagonal | $P_8(n) = n(3n2)$ | 1, 8, 21, 40, 65, ... |
The ordered set of three 4-digit numbers: 8128, 2882, 8281, has three interesting properties.
<ol>
<li>The set is cyclic, in that the last two digits of each number is the first two digits of the next number (including the last number with the first).</li>
<li>Each polygonal type: triangle (P<sub>3,127</sub> = 8128), square (P<sub>4,91</sub> = 8281), and pentagonal (P<sub>5,44</sub> = 2882), is represented by a different number in the set.</li>
<li>This is the only set of 4-digit numbers with this property.</li>
</ol>
1. The set is cyclic, in that the last two digits of each number is the first two digits of the next number (including the last number with the first).
2. Each polygonal type: triangle ($P_3(127) = 8128$), square ($P_4(91) = 8281$), and pentagonal ($P_5(44) = 2882$), is represented by a different number in the set.
3. This is the only set of 4-digit numbers with this property.
Find the sum of the only ordered set of six cyclic 4-digit numbers for which each polygonal type: triangle, square, pentagonal, hexagonal, heptagonal, and octagonal, is represented by a different number in the set.
Find the sum of all numbers in ordered sets of `n` cyclic 4-digit numbers for which each of the $P_3$ to $P_{n + 2}$ polygonal types, is represented by a different number in the set.
# --hints--
`cyclicalFigurateNums()` should return a number.
`cyclicalFigurateNums(3)` should return a number.
```js
assert(typeof cyclicalFigurateNums() === 'number');
assert(typeof cyclicalFigurateNums(3) === 'number');
```
`cyclicalFigurateNums()` should return 28684.
`cyclicalFigurateNums(3)` should return `19291`.
```js
assert.strictEqual(cyclicalFigurateNums(), 28684);
assert.strictEqual(cyclicalFigurateNums(3), 19291);
```
`cyclicalFigurateNums(4)` should return `28684`.
```js
assert.strictEqual(cyclicalFigurateNums(4), 28684);
```
`cyclicalFigurateNums(5)` should return `76255`.
```js
assert.strictEqual(cyclicalFigurateNums(5), 76255);
```
`cyclicalFigurateNums(6)` should return `28684`.
```js
assert.strictEqual(cyclicalFigurateNums(6), 28684);
```
# --seed--
@ -48,16 +64,189 @@ assert.strictEqual(cyclicalFigurateNums(), 28684);
## --seed-contents--
```js
function cyclicalFigurateNums() {
function cyclicalFigurateNums(n) {
return true;
}
cyclicalFigurateNums();
cyclicalFigurateNums(3);
```
# --solutions--
```js
// solution required
function cyclicalFigurateNums(n) {
function getChains(chain, n, numberTypes, numsExcludingLastNeededType) {
if (chain.length === n) {
return [chain];
}
const nextNumbers = getNextNumbersInChain(
chain[chain.length - 1],
numsExcludingLastNeededType
);
const chains = [];
for (let j = 0; j < nextNumbers.length; j++) {
const nextNumber = nextNumbers[j];
if (chain.indexOf(nextNumber) === -1) {
const nextChain = [...chain, nextNumber];
chains.push(
...getChains(nextChain, n, numberTypes, numsExcludingLastNeededType)
);
}
}
return chains;
}
function getNextNumbersInChain(num, numsExcludingLastNeededType) {
const results = [];
const beginning = num % 100;
numsExcludingLastNeededType.forEach(number => {
if (Math.floor(number / 100) === beginning) {
results.push(number);
}
});
return results;
}
function fillNumberTypes(n, numberTypes, numsExcludingLastNeededType) {
const [, lastTypeCheck, lastTypeArr] = numberTypes[n - 1];
for (let i = 1000; i <= 9999; i++) {
for (let j = 0; j < n - 1; j++) {
const [, typeCheck, typeArr] = numberTypes[j];
if (typeCheck(i)) {
typeArr.push(i);
numsExcludingLastNeededType.add(i);
}
}
if (lastTypeCheck(i)) {
lastTypeArr.push(i);
}
}
}
function isCyclicalChain(chain, n, numberTypes) {
const numberTypesInChain = getNumberTypesInChain(chain, numberTypes);
if (!isChainAllowed(numberTypesInChain, n)) {
return false;
}
const isChainCyclic =
Math.floor(chain[0] / 100) === chain[chain.length - 1] % 100;
return isChainCyclic;
}
function getNumberTypesInChain(chain, numberTypes) {
const numbersInChain = {};
for (let i = 0; i < numberTypes.length; i++) {
const numberTypeName = numberTypes[i][0];
numbersInChain[numberTypeName] = [];
}
for (let i = 0; i < chain.length; i++) {
for (let j = 0; j < n; j++) {
const [typeName, , typeNumbers] = numberTypes[j];
const typeNumbersInChain = numbersInChain[typeName];
if (typeNumbers.indexOf(chain[i]) !== -1) {
typeNumbersInChain.push(chain[i]);
}
}
}
return numbersInChain;
}
function isChainAllowed(numberTypesInChain, n) {
for (let i = 0; i < n; i++) {
const typeName = numberTypes[i][0];
const isNumberWithTypeInChain = numberTypesInChain[typeName].length > 0;
if (!isNumberWithTypeInChain) {
return false;
}
for (let j = i + 1; j < n; j++) {
const otherTypeName = numberTypes[j][0];
if (
isNumberRepeatedAsOnlyNumberInTwoTypes(
numberTypesInChain[typeName],
numberTypesInChain[otherTypeName]
)
) {
return false;
}
}
}
return true;
}
function isNumberRepeatedAsOnlyNumberInTwoTypes(
typeNumbers,
otherTypeNumbers
) {
return (
typeNumbers.length === 1 &&
otherTypeNumbers.length === 1 &&
typeNumbers[0] === otherTypeNumbers[0]
);
}
function isTriangle(num) {
return ((8 * num + 1) ** 0.5 - 1) % 2 === 0;
}
function isSquare(num) {
return num ** 0.5 === parseInt(num ** 0.5, 10);
}
function isPentagonal(num) {
return ((24 * num + 1) ** 0.5 + 1) % 6 === 0;
}
function isHexagonal(num) {
return ((8 * num + 1) ** 0.5 + 1) % 4 === 0;
}
function isHeptagonal(num) {
return ((40 * num + 9) ** 0.5 + 3) % 10 === 0;
}
function isOctagonal(num) {
return ((3 * num + 1) ** 0.5 + 1) % 3 === 0;
}
const numberTypes = [
['triangle', isTriangle, []],
['square', isSquare, []],
['pentagonal', isPentagonal, []],
['hexagonal', isHexagonal, []],
['heptagonal', isHeptagonal, []],
['octagonal', isOctagonal, []]
];
const numsExcludingLastNeededType = new Set();
fillNumberTypes(n, numberTypes, numsExcludingLastNeededType);
const nNumberChains = [];
const [, , lastType] = numberTypes[n - 1];
for (let i = 0; i < lastType.length; i++) {
const startOfChain = lastType[i];
nNumberChains.push(
...getChains([startOfChain], n, numberTypes, numsExcludingLastNeededType)
);
}
const cyclicalChains = nNumberChains.filter(chain =>
isCyclicalChain(chain, n, numberTypes)
);
let sum = 0;
for (let i = 0; i < cyclicalChains.length; i++) {
for (let j = 0; j < cyclicalChains[0].length; j++) {
sum += cyclicalChains[i][j];
}
}
return sum;
}
```

View File

@ -8,22 +8,40 @@ dashedName: problem-62-cubic-permutations
# --description--
The cube, 41063625 (345<sup>3</sup>), can be permuted to produce two other cubes: 56623104 (384<sup>3</sup>) and 66430125 (405<sup>3</sup>). In fact, 41063625 is the smallest cube which has exactly three permutations of its digits which are also cube.
The cube, 41063625 ($345^3$), can be permuted to produce two other cubes: 56623104 ($384^3$) and 66430125 ($405^3$). In fact, 41063625 is the smallest cube which has exactly three permutations of its digits which are also cube.
Find the smallest cube for which exactly five permutations of its digits are cube.
Find the smallest cube for which exactly `n` permutations of its digits are cube.
# --hints--
`cubicPermutations()` should return a number.
`cubicPermutations(2)` should return a number.
```js
assert(typeof cubicPermutations() === 'number');
assert(typeof cubicPermutations(2) === 'number');
```
`cubicPermutations()` should return 127035954683.
`cubicPermutations(2)` should return `125`.
```js
assert.strictEqual(cubicPermutations(), 127035954683);
assert.strictEqual(cubicPermutations(2), 125);
```
`cubicPermutations(3)` should return `41063625`.
```js
assert.strictEqual(cubicPermutations(3), 41063625);
```
`cubicPermutations(4)` should return `1006012008`.
```js
assert.strictEqual(cubicPermutations(4), 1006012008);
```
`cubicPermutations(5)` should return `127035954683`.
```js
assert.strictEqual(cubicPermutations(5), 127035954683);
```
# --seed--
@ -31,16 +49,49 @@ assert.strictEqual(cubicPermutations(), 127035954683);
## --seed-contents--
```js
function cubicPermutations() {
function cubicPermutations(n) {
return true;
}
cubicPermutations();
cubicPermutations(2);
```
# --solutions--
```js
// solution required
function cubicPermutations(n) {
function getDigits(num) {
const digits = [];
while (num > 0) {
digits.push(num % 10);
num = Math.floor(num / 10);
}
return digits;
}
function getCube(num) {
return num ** 3;
}
const digitsToCubeCounts = {};
let curNum = 1;
let digits;
while (!digitsToCubeCounts[digits] || digitsToCubeCounts[digits].count < n) {
const cube = getCube(curNum);
digits = getDigits(cube).sort().join();
if (!digitsToCubeCounts[digits]) {
digitsToCubeCounts[digits] = {
count: 1,
smallestCube: cube
};
} else {
digitsToCubeCounts[digits].count += 1;
}
curNum++;
}
return digitsToCubeCounts[digits].smallestCube;
}
```

View File

@ -10,20 +10,74 @@ dashedName: problem-63-powerful-digit-counts
The 5-digit number, 16807 = 7<sup>5</sup>, is also a fifth power. Similarly, the 9-digit number, 134217728 = 8<sup>9</sup>, is a ninth power.
How many `n`-digit positive integers exist which are also an `n`th power?
Complete the function so that it returns how many positive integers are of length `n` and an `n`th power.
# --hints--
`powerfulDigitCounts()` should return a number.
`powerfulDigitCounts(1)` should return a number.
```js
assert(typeof powerfulDigitCounts() === 'number');
assert(typeof powerfulDigitCounts(1) === 'number');
```
`powerfulDigitCounts()` should return 49.
`powerfulDigitCounts(1)` should return `9`.
```js
assert.strictEqual(powerfulDigitCounts(), 49);
assert.strictEqual(powerfulDigitCounts(1), 9);
```
`powerfulDigitCounts(2)` should return `6`.
```js
assert.strictEqual(powerfulDigitCounts(2), 6);
```
`powerfulDigitCounts(3)` should return `5`.
```js
assert.strictEqual(powerfulDigitCounts(3), 5);
```
`powerfulDigitCounts(4)` should return `4`.
```js
assert.strictEqual(powerfulDigitCounts(4), 4);
```
`powerfulDigitCounts(5)` should return `3`.
```js
assert.strictEqual(powerfulDigitCounts(5), 3);
```
`powerfulDigitCounts(6)` should return `3`.
```js
assert.strictEqual(powerfulDigitCounts(6), 3);
```
`powerfulDigitCounts(7)` should return `2`.
```js
assert.strictEqual(powerfulDigitCounts(7), 2);
```
`powerfulDigitCounts(8)` should return `2`.
```js
assert.strictEqual(powerfulDigitCounts(8), 2);
```
`powerfulDigitCounts(10)` should return `2`.
```js
assert.strictEqual(powerfulDigitCounts(10), 2);
```
`powerfulDigitCounts(21)` should return `1`.
```js
assert.strictEqual(powerfulDigitCounts(21), 1);
```
# --seed--
@ -31,16 +85,38 @@ assert.strictEqual(powerfulDigitCounts(), 49);
## --seed-contents--
```js
function powerfulDigitCounts() {
function powerfulDigitCounts(n) {
return true;
}
powerfulDigitCounts();
powerfulDigitCounts(1);
```
# --solutions--
```js
// solution required
function powerfulDigitCounts(n) {
function countDigits(num) {
let counter = 0;
while (num > 0) {
num = Math.floor(num / 10);
counter++;
}
return counter;
}
let numbersCount = 0;
let curNum = 1;
while (curNum < 10) {
let power = n;
if (power === countDigits(curNum ** power)) {
numbersCount++;
}
curNum++;
}
return numbersCount;
}
```

View File

@ -64,20 +64,38 @@ $\\quad \\quad \\sqrt{13}=\[3;(1,1,1,1,6)]$, period = 5
Exactly four continued fractions, for $N \\le 13$, have an odd period.
How many continued fractions for $N \\le 10\\,000$ have an odd period?
How many continued fractions for $N \\le n$ have an odd period?
# --hints--
`oddPeriodSqrts()` should return a number.
`oddPeriodSqrts(13)` should return a number.
```js
assert(typeof oddPeriodSqrts() === 'number');
assert(typeof oddPeriodSqrts(13) === 'number');
```
`oddPeriodSqrts()` should return 1322.
`oddPeriodSqrts(500)` should return `83`.
```js
assert.strictEqual(oddPeriodSqrts(), 1322);
assert.strictEqual(oddPeriodSqrts(500), 83);
```
`oddPeriodSqrts(1000)` should return `152`.
```js
assert.strictEqual(oddPeriodSqrts(1000), 152);
```
`oddPeriodSqrts(5000)` should return `690`.
```js
assert.strictEqual(oddPeriodSqrts(5000), 690);
```
`oddPeriodSqrts(10000)` should return `1322`.
```js
assert.strictEqual(oddPeriodSqrts(10000), 1322);
```
# --seed--
@ -85,16 +103,46 @@ assert.strictEqual(oddPeriodSqrts(), 1322);
## --seed-contents--
```js
function oddPeriodSqrts() {
function oddPeriodSqrts(n) {
return true;
}
oddPeriodSqrts();
oddPeriodSqrts(13);
```
# --solutions--
```js
// solution required
function oddPeriodSqrts(n) {
// Based on https://www.mathblog.dk/project-euler-continued-fractions-odd-period/
function getPeriod(num) {
let period = 0;
let m = 0;
let d = 1;
let a = Math.floor(Math.sqrt(num));
const a0 = a;
while (2 * a0 !== a) {
m = d * a - m;
d = Math.floor((num - m ** 2) / d);
a = Math.floor((Math.sqrt(num) + m) / d);
period++;
}
return period;
}
function isPerfectSquare(num) {
return Number.isInteger(Math.sqrt(num));
}
let counter = 0;
for (let i = 2; i <= n; i++) {
if (!isPerfectSquare(i)) {
if (getPeriod(i) % 2 !== 0) {
counter++;
}
}
}
return counter;
}
```

View File

@ -26,20 +26,44 @@ $2, 3, \\dfrac{8}{3}, \\dfrac{11}{4}, \\dfrac{19}{7}, \\dfrac{87}{32}, \\dfrac{1
The sum of digits in the numerator of the 10<sup>th</sup> convergent is $1 + 4 + 5 + 7 = 17$.
Find the sum of digits in the numerator of the 100<sup>th</sup> convergent of the continued fraction for `e`.
Find the sum of digits in the numerator of the `n`<sup>th</sup> convergent of the continued fraction for `e`.
# --hints--
`convergentsOfE()` should return a number.
`convergentsOfE(10)` should return a number.
```js
assert(typeof convergentsOfE() === 'number');
assert(typeof convergentsOfE(10) === 'number');
```
`convergentsOfE()` should return 272.
`convergentsOfE(10)` should return `17`.
```js
assert.strictEqual(convergentsOfE(), 272);
assert.strictEqual(convergentsOfE(10), 17);
```
`convergentsOfE(30)` should return `53`.
```js
assert.strictEqual(convergentsOfE(30), 53);
```
`convergentsOfE(50)` should return `91`.
```js
assert.strictEqual(convergentsOfE(50), 91);
```
`convergentsOfE(70)` should return `169`.
```js
assert.strictEqual(convergentsOfE(70), 169);
```
`convergentsOfE(100)` should return `272`.
```js
assert.strictEqual(convergentsOfE(100), 272);
```
# --seed--
@ -47,16 +71,47 @@ assert.strictEqual(convergentsOfE(), 272);
## --seed-contents--
```js
function convergentsOfE() {
function convergentsOfE(n) {
return true;
}
convergentsOfE();
convergentsOfE(10);
```
# --solutions--
```js
// solution required
function convergentsOfE(n) {
function sumDigits(num) {
let sum = 0n;
while (num > 0) {
sum += num % 10n;
num = num / 10n;
}
return parseInt(sum);
}
// BigInt is needed for high convergents
let convergents = [
[2n, 1n],
[3n, 1n]
];
const multipliers = [1n, 1n, 2n];
for (let i = 2; i < n; i++) {
const [secondLastConvergent, lastConvergent] = convergents;
const [secondLastNumerator, secondLastDenominator] = secondLastConvergent;
const [lastNumerator, lastDenominator] = lastConvergent;
const curMultiplier = multipliers[i % 3];
const numerator = secondLastNumerator + curMultiplier * lastNumerator;
const denominator = secondLastDenominator + curMultiplier * lastDenominator;
convergents = [lastConvergent, [numerator, denominator]]
if (i % 3 === 2) {
multipliers[2] += 2n;
}
}
return sumDigits(convergents[1][0]);
}
```

View File

@ -28,20 +28,44 @@ By finding minimal solutions in x for D = {2, 3, 5, 6, 7}, we obtain the followi
Hence, by considering minimal solutions in `x` for D ≤ 7, the largest `x` is obtained when D=5.
Find the value of D ≤ 1000 in minimal solutions of `x` for which the largest value of `x` is obtained.
Find the value of D ≤ `n` in minimal solutions of `x` for which the largest value of `x` is obtained.
# --hints--
`diophantineEquation()` should return a number.
`diophantineEquation(7)` should return a number.
```js
assert(typeof diophantineEquation() === 'number');
assert(typeof diophantineEquation(7) === 'number');
```
`diophantineEquation()` should return 661.
`diophantineEquation(7)` should return `5`.
```
assert.strictEqual(diophantineEquation(7), 5);
```
`diophantineEquation(100)` should return `61`.
```
assert.strictEqual(diophantineEquation(100), 61);
```
`diophantineEquation(409)` should return `409`.
```
assert.strictEqual(diophantineEquation(409), 409);
```
`diophantineEquation(500)` should return `421`.
```
assert.strictEqual(diophantineEquation(500), 421);
```
`diophantineEquation(1000)` should return `661`.
```js
assert.strictEqual(diophantineEquation(), 661);
assert.strictEqual(diophantineEquation(1000), 661);
```
# --seed--
@ -49,16 +73,57 @@ assert.strictEqual(diophantineEquation(), 661);
## --seed-contents--
```js
function diophantineEquation() {
function diophantineEquation(n) {
return true;
}
diophantineEquation();
diophantineEquation(7);
```
# --solutions--
```js
// solution required
function diophantineEquation(n) {
// Based on https://www.mathblog.dk/project-euler-66-diophantine-equation/
function isSolution(D, numerator, denominator) {
return numerator * numerator - BigInt(D) * denominator * denominator === 1n;
}
let result = 0;
let biggestX = 0;
for (let D = 2; D <= n; D++) {
let boundary = Math.floor(Math.sqrt(D));
if (boundary ** 2 === D) {
continue;
}
let m = 0n;
let d = 1n;
let a = BigInt(boundary);
let [numerator, prevNumerator] = [a, 1n];
let [denominator, prevDenominator] = [1n, 0n];
while (!isSolution(D, numerator, denominator)) {
m = d * a - m;
d = (BigInt(D) - m * m) / d;
a = (BigInt(boundary) + m) / d;
[numerator, prevNumerator] = [a * numerator + prevNumerator, numerator];
[denominator, prevDenominator] = [
a * denominator + prevDenominator,
denominator
];
}
if (numerator > biggestX) {
biggestX = numerator;
result = D;
}
}
return result;
}
```

View File

@ -8,40 +8,58 @@ dashedName: problem-69-totient-maximum
# --description--
Euler's Totient function, φ(`n`) \[sometimes called the phi function], is used to determine the number of numbers less than `n` which are relatively prime to `n`. For example, as 1, 2, 4, 5, 7, and 8, are all less than nine and relatively prime to nine, φ(9)=6.
Euler's Totient function, ${\phi}(n)$ (sometimes called the phi function), is used to determine the number of numbers less than `n` which are relatively prime to `n`. For example, as 1, 2, 4, 5, 7, and 8, are all less than nine and relatively prime to nine, ${\phi}(9) = 6$.
<div style='margin-left: 4em;'>
| !!crwdBlockTags_15_sgaTkcolBdwrc!! | Relatively Prime | φ(!!crwdBlockTags_16_sgaTkcolBdwrc!!) |!!crwdBlockTags_17_sgaTkcolBdwrc!!/φ(!!crwdBlockTags_18_sgaTkcolBdwrc!!) |
| ------------ | ---------------- | --------------- | ---------------------------- |
| 2 | 1 | 1 | 2 |
| 3 | 1,2 | 2 | 1.5 |
| 4 | 1,3 | 2 | 2 |
| 5 | 1,2,3,4 | 4 | 1.25 |
| 6 | 1,5 | 2 | 3 |
| 7 | 1,2,3,4,5,6 | 6 | 1.1666... |
| 8 | 1,3,5,7 | 4 | 2 |
| 9 | 1,2,4,5,7,8 | 6 | 1.5 |
| 10 | 1,3,7,9 | 4 | 2.5 |
| $n$ | $\text{Relatively Prime}$ | $\displaystyle{\phi}(n)$ | $\displaystyle\frac{n}{{\phi}(n)}$ |
| --- | ------------------------- | ------------------------ | ---------------------------------- |
| 2 | 1 | 1 | 2 |
| 3 | 1,2 | 2 | 1.5 |
| 4 | 1,3 | 2 | 2 |
| 5 | 1,2,3,4 | 4 | 1.25 |
| 6 | 1,5 | 2 | 3 |
| 7 | 1,2,3,4,5,6 | 6 | 1.1666... |
| 8 | 1,3,5,7 | 4 | 2 |
| 9 | 1,2,4,5,7,8 | 6 | 1.5 |
| 10 | 1,3,7,9 | 4 | 2.5 |
</div>
It can be seen that `n`=6 produces a maximum `n`/φ(`n`) for `n` ≤ 10.
It can be seen that `n` = 6 produces a maximum $\displaystyle\frac{n}{{\phi}(n)}$ for `n` ≤ 10.
Find the value of `n`1,000,000 for which n/φ(`n`) is a maximum.
Find the value of `n``limit` for which $\displaystyle\frac{n}{{\phi(n)}}$ is a maximum.
# --hints--
`totientMaximum()` should return a number.
`totientMaximum(10)` should return a number.
```js
assert(typeof totientMaximum() === 'number');
assert(typeof totientMaximum(10) === 'number');
```
`totientMaximum()` should return 510510.
`totientMaximum(10)` should return `6`.
```js
assert.strictEqual(totientMaximum(), 510510);
assert.strictEqual(totientMaximum(10), 6);
```
`totientMaximum(10000)` should return `2310`.
```js
assert.strictEqual(totientMaximum(10000), 2310);
```
`totientMaximum(500000)` should return `30030`.
```js
assert.strictEqual(totientMaximum(500000), 30030);
```
`totientMaximum(1000000)` should return `510510`.
```js
assert.strictEqual(totientMaximum(1000000), 510510);
```
# --seed--
@ -49,16 +67,44 @@ assert.strictEqual(totientMaximum(), 510510);
## --seed-contents--
```js
function totientMaximum() {
function totientMaximum(limit) {
return true;
}
totientMaximum();
totientMaximum(10);
```
# --solutions--
```js
// solution required
function totientMaximum(limit) {
function getSievePrimes(max) {
const primesMap = new Array(max).fill(true);
primesMap[0] = false;
primesMap[1] = false;
const primes = [];
for (let i = 2; i < max; i = i + 2) {
if (primesMap[i]) {
primes.push(i);
for (let j = i * i; j < max; j = j + i) {
primesMap[j] = false;
}
}
if (i === 2) {
i = 1;
}
}
return primes;
}
const MAX_PRIME = 50;
const primes = getSievePrimes(MAX_PRIME);
let result = 1;
for (let i = 0; result * primes[i] < limit; i++) {
result *= primes[i];
}
return result;
}
```

View File

@ -8,24 +8,42 @@ dashedName: problem-70-totient-permutation
# --description--
Euler's Totient function, φ(`n`) \[sometimes called the phi function], is used to determine the number of positive numbers less than or equal to `n` which are relatively prime to `n`. For example, as 1, 2, 4, 5, 7, and 8, are all less than nine and relatively prime to nine, φ(9)=6. The number 1 is considered to be relatively prime to every positive number, so φ(1)=1.
Euler's Totient function, ${\phi}(n)$ (sometimes called the phi function), is used to determine the number of positive numbers less than or equal to `n` which are relatively prime to `n`. For example, as 1, 2, 4, 5, 7, and 8, are all less than nine and relatively prime to nine, ${\phi}(9) = 6$. The number 1 is considered to be relatively prime to every positive number, so ${\phi}(1) = 1$.
Interestingly, φ(87109)=79180, and it can be seen that 87109 is a permutation of 79180.
Interestingly, ${\phi}(87109) = 79180$, and it can be seen that 87109 is a permutation of 79180.
Find the value of `n`, 1 &lt; `n` &lt; 10<sup>7</sup>, for which φ(`n`) is a permutation of `n` and the ratio `n`/φ(`n`) produces a minimum.
Find the value of `n`, 1 &lt; `n` &lt; `limit`, for which ${\phi}(n)$ is a permutation of `n` and the ratio $\displaystyle\frac{n}{{\phi}(n)}$ produces a minimum.
# --hints--
`totientPermutation()` should return a number.
`totientPermutation(10000)` should return a number.
```js
assert(typeof totientPermutation() === 'number');
assert(typeof totientPermutation(10000) === 'number');
```
`totientPermutation()` should return 8319823.
`totientPermutation(10000)` should return `4435`.
```js
assert.strictEqual(totientPermutation(), 8319823);
assert.strictEqual(totientPermutation(10000), 4435);
```
`totientPermutation(100000)` should return `75841`.
```js
assert.strictEqual(totientPermutation(100000), 75841);
```
`totientPermutation(500000)` should return `474883`.
```js
assert.strictEqual(totientPermutation(500000), 474883);
```
`totientPermutation(10000000)` should return `8319823`.
```js
assert.strictEqual(totientPermutation(10000000), 8319823);
```
# --seed--
@ -33,16 +51,68 @@ assert.strictEqual(totientPermutation(), 8319823);
## --seed-contents--
```js
function totientPermutation() {
function totientPermutation(limit) {
return true;
}
totientPermutation();
totientPermutation(10000);
```
# --solutions--
```js
// solution required
function totientPermutation(limit) {
function getSievePrimes(max) {
const primes = [];
const primesMap = new Array(max).fill(true);
primesMap[0] = false;
primesMap[1] = false;
for (let i = 2; i < max; i += 2) {
if (primesMap[i]) {
primes.push(i);
for (let j = i * i; j < max; j += i) {
primesMap[j] = false;
}
}
if (i === 2) {
i = 1;
}
}
return primes;
}
function sortDigits(number) {
return number.toString().split('').sort().join('');
}
function isPermutation(numberA, numberB) {
return sortDigits(numberA) === sortDigits(numberB);
}
const MAX_PRIME = 4000;
const primes = getSievePrimes(MAX_PRIME);
let nValue = 1;
let minRatio = Infinity;
for (let i = 1; i < primes.length; i++) {
for (let j = i + 1; j < primes.length; j++) {
const num = primes[i] * primes[j];
if (num > limit) {
break;
}
const phi = (primes[i] - 1) * (primes[j] - 1);
const ratio = num / phi;
if (minRatio > ratio && isPermutation(num, phi)) {
nValue = num;
minRatio = ratio;
}
}
}
return nValue;
}
```

View File

@ -8,28 +8,52 @@ dashedName: problem-71-ordered-fractions
# --description--
Consider the fraction, `n`/`d`, where `n` and `d` are positive integers. If `n`&lt;`d` and HCF(`n`,`d`)=1, it is called a reduced proper fraction.
Consider the fraction, $\frac{n}{d}$, where `n` and `d` are positive integers. If `n` &lt; `d` and highest common factor, ${{HCF}(n, d)} = 1$, it is called a reduced proper fraction.
If we list the set of reduced proper fractions for `d` ≤ 8 in ascending order of size, we get:
<div style='text-align: center;'>1/8, 1/7, 1/6, 1/5, 1/4, 2/7, 1/3, 3/8, <strong>2/5</strong>, 3/7, 1/2, 4/7, 3/5, 5/8, 2/3, 5/7, 3/4, 4/5, 5/6, 6/7, 7/8</div>
$$\frac{1}{8}, \frac{1}{7}, \frac{1}{6}, \frac{1}{5}, \frac{1}{4}, \frac{2}{7}, \frac{1}{3}, \frac{3}{8}, \frac{\textbf2}{\textbf5}, \frac{3}{7}, \frac{1}{2}, \frac{4}{7}, \frac{3}{5}, \frac{5}{8}, \frac{2}{3}, \frac{5}{7}, \frac{3}{4}, \frac{4}{5}, \frac{5}{6}, \frac{6}{7}, \frac{7}{8}$$
It can be seen that 2/5 is the fraction immediately to the left of 3/7.
It can be seen that $\frac{2}{5}$ is the fraction immediately to the left of $\frac{3}{7}$.
By listing the set of reduced proper fractions for `d`1,000,000 in ascending order of size, find the numerator of the fraction immediately to the left of 3/7.
By listing the set of reduced proper fractions for `d``limit` in ascending order of size, find the numerator of the fraction immediately to the left of $\frac{3}{7}$.
# --hints--
`orderedFractions()` should return a number.
`orderedFractions(8)` should return a number.
```js
assert(typeof orderedFractions() === 'number');
assert(typeof orderedFractions(8) === 'number');
```
`orderedFractions()` should return 428570.
`orderedFractions(8)` should return `2`.
```js
assert.strictEqual(orderedFractions(), 428570);
assert.strictEqual(orderedFractions(8), 2);
```
`orderedFractions(10)` should return `2`.
```js
assert.strictEqual(orderedFractions(10), 2);
```
`orderedFractions(9994)` should return `4283`.
```js
assert.strictEqual(orderedFractions(9994), 4283);
```
`orderedFractions(500000)` should return `214283`.
```js
assert.strictEqual(orderedFractions(500000), 214283);
```
`orderedFractions(1000000)` should return `428570`.
```js
assert.strictEqual(orderedFractions(1000000), 428570);
```
# --seed--
@ -37,16 +61,35 @@ assert.strictEqual(orderedFractions(), 428570);
## --seed-contents--
```js
function orderedFractions() {
function orderedFractions(limit) {
return true;
}
orderedFractions();
orderedFractions(8);
```
# --solutions--
```js
// solution required
function orderedFractions(limit) {
const fractions = [];
const fractionValues = {};
const highBoundary = 3 / 7;
let lowBoundary = 2 / 7;
for (let denominator = limit; denominator > 2; denominator--) {
let numerator = Math.floor((3 * denominator - 1) / 7);
let value = numerator / denominator;
if (value > highBoundary || value < lowBoundary) {
continue;
}
fractionValues[value] = [numerator, denominator];
fractions.push(value);
lowBoundary = value;
}
fractions.sort();
return fractionValues[fractions[fractions.length - 1]][0];
}
```

View File

@ -8,28 +8,46 @@ dashedName: problem-72-counting-fractions
# --description--
Consider the fraction, `n`/`d`, where n and d are positive integers. If `n`&lt;`d` and HCF(`n`,`d`)=1, it is called a reduced proper fraction.
Consider the fraction, $\frac{n}{d}$, where `n` and `d` are positive integers. If `n` &lt; `d` and highest common factor, ${HCF}(n, d) = 1$, it is called a reduced proper fraction.
If we list the set of reduced proper fractions for `d` ≤ 8 in ascending order of size, we get:
<div style='text-align: center;'>1/8, 1/7, 1/6, 1/5, 1/4, 2/7, 1/3, 3/8, 2/5, 3/7, 1/2, 4/7, 3/5, 5/8, 2/3, 5/7, 3/4, 4/5, 5/6, 6/7, 7/8</div>
$$\frac{1}{8}, \frac{1}{7}, \frac{1}{6}, \frac{1}{5}, \frac{1}{4}, \frac{2}{7}, \frac{1}{3}, \frac{3}{8}, \frac{2}{5}, \frac{3}{7}, \frac{1}{2}, \frac{4}{7}, \frac{3}{5}, \frac{5}{8}, \frac{2}{3}, \frac{5}{7}, \frac{3}{4}, \frac{4}{5}, \frac{5}{6}, \frac{6}{7}, \frac{7}{8}$$
It can be seen that there are 21 elements in this set.
It can be seen that there are `21` elements in this set.
How many elements would be contained in the set of reduced proper fractions for `d`1,000,000?
How many elements would be contained in the set of reduced proper fractions for `d``limit`?
# --hints--
`countingFractions()` should return a number.
`countingFractions(8)` should return a number.
```js
assert(typeof countingFractions() === 'number');
assert(typeof countingFractions(8) === 'number');
```
`countingFractions()` should return 303963552391.
`countingFractions(8)` should return `21`.
```js
assert.strictEqual(countingFractions(), 303963552391);
assert.strictEqual(countingFractions(8), 21);
```
`countingFractions(20000)` should return `121590395`.
```js
assert.strictEqual(countingFractions(20000), 121590395);
```
`countingFractions(500000)` should return `75991039675`.
```js
assert.strictEqual(countingFractions(500000), 75991039675);
```
`countingFractions(1000000)` should return `303963552391`.
```js
assert.strictEqual(countingFractions(1000000), 303963552391);
```
# --seed--
@ -37,16 +55,36 @@ assert.strictEqual(countingFractions(), 303963552391);
## --seed-contents--
```js
function countingFractions() {
function countingFractions(limit) {
return true;
}
countingFractions();
countingFractions(8);
```
# --solutions--
```js
// solution required
function countingFractions(limit) {
const phi = {};
let count = 0;
for (let i = 2; i <= limit; i++) {
if (!phi[i]) {
phi[i] = i;
}
if (phi[i] === i) {
for (let j = i; j <= limit; j += i) {
if (!phi[j]) {
phi[j] = j;
}
phi[j] = (phi[j] / i) * (i - 1);
}
}
count += phi[i];
}
return count;
}
```

View File

@ -8,28 +8,46 @@ dashedName: problem-73-counting-fractions-in-a-range
# --description--
Consider the fraction, `n`/`d`, where n and d are positive integers. If `n`&lt;`d` and HCF(`n`,`d`)=1, it is called a reduced proper fraction.
Consider the fraction, $\frac{n}{d}$, where `n` and `d` are positive integers. If `n` &lt; `d` and highest common factor, ${HCF}(n, d) = 1$, it is called a reduced proper fraction.
If we list the set of reduced proper fractions for `d` ≤ 8 in ascending order of size, we get:
<div style='text-align: center;'>1/8, 1/7, 1/6, 1/5, 1/4, 2/7, 1/3, <strong>3/8</strong>, <strong>2/5</strong>, <strong>3/7</strong>, 1/2, 4/7, 3/5, 5/8, 2/3, 5/7, 3/4, 4/5, 5/6, 6/7, 7/8</div>
$$\frac{1}{8}, \frac{1}{7}, \frac{1}{6}, \frac{1}{5}, \frac{1}{4}, \frac{2}{7}, \frac{1}{3}, \mathbf{\frac{3}{8}, \frac{2}{5}, \frac{3}{7}}, \frac{1}{2}, \frac{4}{7}, \frac{3}{5}, \frac{5}{8}, \frac{2}{3}, \frac{5}{7}, \frac{3}{4}, \frac{4}{5}, \frac{5}{6}, \frac{6}{7}, \frac{7}{8}$$
It can be seen that there are 3 fractions between 1/3 and 1/2.
It can be seen that there are `3` fractions between $\frac{1}{3}$ and $\frac{1}{2}$.
How many fractions lie between 1/3 and 1/2 in the sorted set of reduced proper fractions for `d`12,000?
How many fractions lie between $\frac{1}{3}$ and $\frac{1}{2}$ in the sorted set of reduced proper fractions for `d``limit`?
# --hints--
`countingFractionsInARange()` should return a number.
`countingFractionsInARange(8)` should return a number.
```js
assert(typeof countingFractionsInARange() === 'number');
assert(typeof countingFractionsInARange(8) === 'number');
```
`countingFractionsInARange()` should return 7295372.
`countingFractionsInARange(8)` should return `3`.
```js
assert.strictEqual(countingFractionsInARange(), 7295372);
assert.strictEqual(countingFractionsInARange(8), 3);
```
`countingFractionsInARange(1000)` should return `50695`.
```js
assert.strictEqual(countingFractionsInARange(1000), 50695);
```
`countingFractionsInARange(6000)` should return `1823861`.
```js
assert.strictEqual(countingFractionsInARange(6000), 1823861);
```
`countingFractionsInARange(12000)` should return `7295372`.
```js
assert.strictEqual(countingFractionsInARange(12000), 7295372);
```
# --seed--
@ -37,16 +55,29 @@ assert.strictEqual(countingFractionsInARange(), 7295372);
## --seed-contents--
```js
function countingFractionsInARange() {
function countingFractionsInARange(limit) {
return true;
}
countingFractionsInARange();
countingFractionsInARange(8);
```
# --solutions--
```js
// solution required
function countingFractionsInARange(limit) {
let result = 0;
const stack = [[3, 2]];
while (stack.length > 0) {
const [startDenominator, endDenominator] = stack.pop();
const curDenominator = startDenominator + endDenominator;
if (curDenominator <= limit) {
result++;
stack.push([startDenominator, curDenominator]);
stack.push([curDenominator, endDenominator]);
}
}
return result;
}
```

View File

@ -10,39 +10,50 @@ dashedName: problem-74-digit-factorial-chains
The number 145 is well known for the property that the sum of the factorial of its digits is equal to 145:
<div style='margin-left: 4em;'>1! + 4! + 5! = 1 + 24 + 120 = 145</div>
$$1! + 4! + 5! = 1 + 24 + 120 = 145$$
Perhaps less well known is 169, in that it produces the longest chain of numbers that link back to 169; it turns out that there are only three such loops that exist:
<div style='margin-left: 4em;'>
169 → 363601 → 1454 → 169<br>
871 → 45361 → 871<br>
872 → 45362 → 872<br>
</div>
$$\begin{align} &169 → 363601 → 1454 → 169\\\\ &871 → 45361 → 871\\\\ &872 → 45362 → 872\\\\ \end{align}$$
It is not difficult to prove that EVERY starting number will eventually get stuck in a loop. For example,
<div style='margin-left: 4em;'>
69 → 363600 → 1454 → 169 → 363601 (→ 1454)<br>
78 → 45360 → 871 → 45361 (→ 871)<br>
540 → 145 (→ 145)<br>
</div>
$$\begin{align} &69 → 363600 → 1454 → 169 → 363601\\ (→ 1454)\\\\ &78 → 45360 → 871 → 45361\\ (→ 871)\\\\ &540 → 145\\ (→ 145)\\\\ \end{align}$$
Starting with 69 produces a chain of five non-repeating terms, but the longest non-repeating chain with a starting number below one million is sixty terms.
How many chains, with a starting number below one million, contain exactly sixty non-repeating terms?
How many chains, with a starting number below `n`, contain exactly sixty non-repeating terms?
# --hints--
`digitFactorialChains()` should return a number.
`digitFactorialChains(2000)` should return a number.
```js
assert(typeof digitFactorialChains() === 'number');
assert(typeof digitFactorialChains(2000) === 'number');
```
`digitFactorialChains()` should return 402.
`digitFactorialChains(2000)` should return `6`.
```js
assert.strictEqual(digitFactorialChains(), 402);
assert.strictEqual(digitFactorialChains(2000), 6);
```
`digitFactorialChains(100000)` should return `42`.
```js
assert.strictEqual(digitFactorialChains(100000), 42);
```
`digitFactorialChains(500000)` should return `282`.
```js
assert.strictEqual(digitFactorialChains(500000), 282);
```
`digitFactorialChains(1000000)` should return `402`.
```js
assert.strictEqual(digitFactorialChains(1000000), 402);
```
# --seed--
@ -50,16 +61,63 @@ assert.strictEqual(digitFactorialChains(), 402);
## --seed-contents--
```js
function digitFactorialChains() {
function digitFactorialChains(n) {
return true;
}
digitFactorialChains();
digitFactorialChains(2000);
```
# --solutions--
```js
// solution required
function digitFactorialChains(n) {
function sumDigitsFactorials(number) {
let sum = 0;
while (number > 0) {
sum += factorials[number % 10];
number = Math.floor(number / 10);
}
return sum;
}
const factorials = [1];
for (let i = 1; i < 10; i++) {
factorials.push(factorials[factorials.length - 1] * i);
}
const sequences = {
169: 3,
871: 2,
872: 2,
1454: 3,
45362: 2,
45461: 2,
3693601: 3
};
let result = 0;
for (let i = 2; i < n; i++) {
let curNum = i;
let chainLength = 0;
const curSequence = [];
while (curSequence.indexOf(curNum) === -1) {
curSequence.push(curNum);
curNum = sumDigitsFactorials(curNum);
chainLength++;
if (sequences.hasOwnProperty(curNum) > 0) {
chainLength += sequences[curNum];
break;
}
}
if (chainLength === 60) {
result++;
}
for (let j = 1; j < curSequence.length; j++) {
sequences[curSequence[j]] = chainLength - j;
}
}
return result;
}
```

View File

@ -16,29 +16,47 @@ It turns out that 12 cm is the smallest length of wire that can be bent to form
<strong>30 cm:</strong> (5,12,13)<br>
<strong>36 cm:</strong> (9,12,15)<br>
<strong>40 cm:</strong> (8,15,17)<br>
<strong>48 cm:</strong> (12,16,20)<br>
<strong>48 cm:</strong> (12,16,20)<br><br>
</div>
In contrast, some lengths of wire, like 20 cm, cannot be bent to form an integer sided right angle triangle, and other lengths allow more than one solution to be found; for example, using 120 cm it is possible to form exactly three different integer sided right angle triangles.
<div style='margin-left: 4em;'>
<strong>120 cm:</strong> (30,40,50), (20,48,52), (24,45,51)
<strong>120 cm:</strong> (30,40,50), (20,48,52), (24,45,51)<br><br>
</div>
Given that L is the length of the wire, for how many values of L ≤ 1,500,000 can exactly one integer sided right angle triangle be formed?
Given that L is the length of the wire, for how many values of L ≤ `n` can exactly one, integer sided right angle, triangle be formed?
# --hints--
`singularIntRightTriangles()` should return a number.
`singularIntRightTriangles(48)` should return a number.
```js
assert(typeof singularIntRightTriangles() === 'number');
assert(typeof singularIntRightTriangles(48) === 'number');
```
`singularIntRightTriangles()` should return 161667.
`singularIntRightTriangles(48)` should return `6`.
```js
assert.strictEqual(singularIntRightTriangles(), 161667);
assert.strictEqual(singularIntRightTriangles(48), 6);
```
`singularIntRightTriangles(700000)` should return `75783`.
```js
assert.strictEqual(singularIntRightTriangles(700000), 75783);
```
`singularIntRightTriangles(1000000)` should return `107876`.
```js
assert.strictEqual(singularIntRightTriangles(1000000), 107876);
```
`singularIntRightTriangles(1500000)` should return `161667`.
```js
assert.strictEqual(singularIntRightTriangles(1500000), 161667);
```
# --seed--
@ -46,16 +64,54 @@ assert.strictEqual(singularIntRightTriangles(), 161667);
## --seed-contents--
```js
function singularIntRightTriangles() {
function singularIntRightTriangles(n) {
return true;
}
singularIntRightTriangles();
singularIntRightTriangles(48);
```
# --solutions--
```js
// solution required
function singularIntRightTriangles(limit) {
function euclidFormula(m, n) {
return [m ** 2 - n ** 2, 2 * m * n, m ** 2 + n ** 2];
}
function gcd(numberA, numberB) {
if (numberB === 0) {
return numberA;
}
return gcd(numberB, numberA % numberB);
}
function notBothOdd(numberA, numberB) {
return (numberA + numberB) % 2 === 1;
}
function areCoprime(numberA, numberB) {
return gcd(numberA, numberB) === 1;
}
const trianglesWithPerimeter = new Array(limit + 1).fill(0);
const mLimit = Math.sqrt(limit / 2);
for (let m = 2; m < mLimit; m++) {
for (let n = 1; n < m; n++) {
if (notBothOdd(m, n) && areCoprime(m, n)) {
const [sideA, sideB, sideC] = euclidFormula(m, n);
const perimeter = sideA + sideB + sideC;
let curPerimeter = perimeter;
while (curPerimeter <= limit) {
trianglesWithPerimeter[curPerimeter]++;
curPerimeter += perimeter;
}
}
}
}
return trianglesWithPerimeter.filter(trianglesCount => trianglesCount === 1)
.length;
}
```

View File

@ -16,23 +16,41 @@ It is possible to write five as a sum in exactly six different ways:
3 + 1 + 1<br>
2 + 2 + 1<br>
2 + 1 + 1 + 1<br>
1 + 1 + 1 + 1 + 1<br>
1 + 1 + 1 + 1 + 1<br><br>
</div>
How many different ways can one hundred be written as a sum of at least two positive integers?
How many different ways can `n` be written as a sum of at least two positive integers?
# --hints--
`countingSummations()` should return a number.
`countingSummations(5)` should return a number.
```js
assert(typeof countingSummations() === 'number');
assert(typeof countingSummations(5) === 'number');
```
`countingSummations()` should return 190569291.
`countingSummations(5)` should return `6`.
```js
assert.strictEqual(countingSummations(), 190569291);
assert.strictEqual(countingSummations(5), 6);
```
`countingSummations(20)` should return `626`.
```js
assert.strictEqual(countingSummations(20), 626);
```
`countingSummations(50)` should return `204225`.
```js
assert.strictEqual(countingSummations(50), 204225);
```
`countingSummations(100)` should return `190569291`.
```js
assert.strictEqual(countingSummations(100), 190569291);
```
# --seed--
@ -40,16 +58,26 @@ assert.strictEqual(countingSummations(), 190569291);
## --seed-contents--
```js
function countingSummations() {
function countingSummations(n) {
return true;
}
countingSummations();
countingSummations(5);
```
# --solutions--
```js
// solution required
function countingSummations(n) {
const combinations = new Array(n + 1).fill(0);
combinations[0] = 1;
for (let i = 1; i < n; i++) {
for (let j = i; j < n + 1; j++) {
combinations[j] += combinations[j - i];
}
}
return combinations[n];
}
```

View File

@ -15,23 +15,41 @@ It is possible to write ten as the sum of primes in exactly five different ways:
5 + 5<br>
5 + 3 + 2<br>
3 + 3 + 2 + 2<br>
2 + 2 + 2 + 2 + 2<br>
2 + 2 + 2 + 2 + 2<br><br>
</div>
What is the first value which can be written as the sum of primes in over five thousand different ways?
What is the first value which can be written as the sum of primes in over `n` ways?
# --hints--
`primeSummations()` should return a number.
`primeSummations(5)` should return a number.
```js
assert(typeof primeSummations() === 'number');
assert(typeof primeSummations(5) === 'number');
```
`primeSummations()` should return 71.
`primeSummations(5)` should return `11`.
```js
assert.strictEqual(primeSummations(), 71);
assert.strictEqual(primeSummations(5), 11);
```
`primeSummations(100)` should return `31`.
```js
assert.strictEqual(primeSummations(100), 31);
```
`primeSummations(1000)` should return `53`.
```js
assert.strictEqual(primeSummations(1000), 53);
```
`primeSummations(5000)` should return `71`.
```js
assert.strictEqual(primeSummations(5000), 71);
```
# --seed--
@ -39,16 +57,54 @@ assert.strictEqual(primeSummations(), 71);
## --seed-contents--
```js
function primeSummations() {
function primeSummations(n) {
return true;
}
primeSummations();
primeSummations(5);
```
# --solutions--
```js
// solution required
function primeSummations(n) {
function getSievePrimes(max) {
const primesMap = new Array(max).fill(true);
primesMap[0] = false;
primesMap[1] = false;
const primes = [];
for (let i = 2; i < max; i += 2) {
if (primesMap[i]) {
primes.push(i);
for (let j = i * i; j < max; j += i) {
primesMap[j] = false;
}
}
if (i === 2) {
i = 1;
}
}
return primes;
}
const MAX_NUMBER = 100;
const primes = getSievePrimes(MAX_NUMBER);
for (let curNumber = 2; curNumber < MAX_NUMBER; curNumber++) {
const combinations = new Array(curNumber + 1).fill(0);
combinations[0] = 1;
for (let i = 0; i < primes.length; i++) {
for (let j = primes[i]; j <= curNumber; j++) {
combinations[j] += combinations[j - primes[i]];
}
}
if (combinations[curNumber] > n) {
return curNumber;
}
}
return false;
}
```

View File

@ -8,7 +8,7 @@ dashedName: problem-78-coin-partitions
# --description--
Let p(n) represent the number of different ways in which n coins can be separated into piles. For example, five coins can be separated into piles in exactly seven different ways, so p(5)=7.
Let ${p}(n)$ represent the number of different ways in which `n` coins can be separated into piles. For example, five coins can be separated into piles in exactly seven different ways, so ${p}(5) = 7$.
<div style='text-align: center;'>
@ -22,22 +22,40 @@ Let p(n) represent the number of different ways in which n coins can be separate
| OO   O   O   O |
| O   O   O   O   O |
</div>
</div><br>
Find the least value of `n` for which p(`n`) is divisible by one million.
Find the least value of `n` for which ${p}(n)$ is divisible by `divisor`.
# --hints--
`coinPartitions()` should return a number.
`coinPartitions(7)` should return a number.
```js
assert(typeof coinPartitions() === 'number');
assert(typeof coinPartitions(7) === 'number');
```
`coinPartitions()` should return 55374.
`coinPartitions(7)` should return `5`.
```js
assert.strictEqual(coinPartitions(), 55374);
assert.strictEqual(coinPartitions(7), 5);
```
`coinPartitions(10000)` should return `599`.
```js
assert.strictEqual(coinPartitions(10000), 599);
```
`coinPartitions(100000)` should return `11224`.
```js
assert.strictEqual(coinPartitions(100000), 11224);
```
`coinPartitions(1000000)` should return `55374`.
```js
assert.strictEqual(coinPartitions(1000000), 55374);
```
# --seed--
@ -45,16 +63,41 @@ assert.strictEqual(coinPartitions(), 55374);
## --seed-contents--
```js
function coinPartitions() {
function coinPartitions(divisor) {
return true;
}
coinPartitions();
coinPartitions(7);
```
# --solutions--
```js
// solution required
function coinPartitions(divisor) {
const partitions = [1];
let n = 0;
while (partitions[n] !== 0) {
n++;
partitions.push(0);
let i = 0;
let pentagonal = 1;
while (pentagonal <= n) {
const sign = i % 4 > 1 ? -1 : 1;
partitions[n] += sign * partitions[n - pentagonal];
partitions[n] = partitions[n] % divisor;
i++;
let k = Math.floor(i / 2) + 1;
if (i % 2 !== 0) {
k *= -1;
}
pentagonal = Math.floor((k * (3 * k - 1)) / 2);
}
}
return n;
}
```

View File

@ -8,28 +8,54 @@ dashedName: problem-79-passcode-derivation
# --description--
A common security method used for online banking is to ask the user for three random characters from a passcode. For example, if the passcode was 531278, they may ask for the 2nd, 3rd, and 5th characters; the expected reply would be: 317.
A common security method used for online banking is to ask the user for three random characters from a passcode. For example, if the passcode was `531278`, they may ask for the 2nd, 3rd, and 5th characters; the expected reply would be: `317`.
The array, `keylog`, contains fifty successful login attempts.
The arrays, `keylog1`, `keylog2`, and `keylog3`, contains fifty successful login attempts.
Given that the three characters are always asked for in order, analyze the array so as to determine the shortest possible secret passcode of unknown length.
# --hints--
`passcodeDerivation(keylog)` should return a number.
`passcodeDerivation(keylog1)` should return a number.
```js
assert(typeof passcodeDerivation(keylog) === 'number');
assert(typeof passcodeDerivation(_keylog1) === 'number');
```
`passcodeDerivation(keylog)` should return 73162890.
`passcodeDerivation(keylog1)` should return `531278`.
```js
assert.strictEqual(passcodeDerivation(keylog), 73162890);
assert.strictEqual(passcodeDerivation(_keylog1), 531278);
```
`passcodeDerivation(keylog2)` should return `1230567`.
```js
assert.strictEqual(passcodeDerivation(_keylog2), 1230567);
```
`passcodeDerivation(keylog3)` should return `73162890`.
```js
assert.strictEqual(passcodeDerivation(_keylog3), 73162890);
```
# --seed--
## --after-user-code--
```js
const _keylog1 = [
127,327,178,528,537,538,532,328,127,178,537,127,317,328,512,278,328,327,178,327,578,317,527,178,128,328,517,312,531,128,128,317,527,312,328,532,512,518,317,127,537,528,537,527,327,278,532,128, 318,517
];
const _keylog2 = [
305,367,256,123,357,120,125,307,236,256,356,267,357,256,356,136,257,107,126,567,567,105,120,237,367,120,367,135,207,167,367,367,307,125,120,130,367,230,106,356,126,106,130,123,307,127,306,167,136,126
];
const _keylog3 = [
319,680,180,690,129,620,762,689,762,318,368,710,720,710,629,168,160,689,716,731,736,729,316,729,729,710,769,290,719,680,318,389,162,289,162,718,729,319,790,680,890,362,319,760,316,729,380,319,728,716,
];
```
## --seed-contents--
```js
@ -40,15 +66,50 @@ function passcodeDerivation(arr) {
// Only change code above this line
const keylog = [
const keylog1 = [
319,680,180,690,129,620,762,689,762,318,368,710,720,710,629,168,160,689,716,731,736,729,316,729,729,710,769,290,719,680,318,389,162,289,162,718,729,319,790,680,890,362,319,760,316,729,380,319,728,716,
];
passcodeDerivation(keylog);
passcodeDerivation(keylog1);
```
# --solutions--
```js
// solution required
function passcodeDerivation(arr) {
const numbersInPasscode = [];
const relativePositions = new Array(10)
.fill()
.map(() => new Array(10).fill(0));
for (let i = 0; i < arr.length; i++) {
const curAttempt = arr[i]
.toString()
.split('')
.map(key => parseInt(key, 10));
for (let j = 0; j < curAttempt.length; j++) {
if (numbersInPasscode.indexOf(curAttempt[j]) === -1) {
numbersInPasscode.push(curAttempt[j]);
}
for (let k = j + 1; k < curAttempt.length; k++) {
relativePositions[curAttempt[j]][curAttempt[k]] += 1;
}
}
}
const ranks = {};
for (let i = 0; i < numbersInPasscode.length; i++) {
const curNumber = numbersInPasscode[i];
ranks[curNumber] = relativePositions[curNumber].filter(
count => count > 0
).length;
}
const passcode = numbersInPasscode
.sort((i, j) => ranks[i] - ranks[j])
.reverse()
.join('');
return parseInt(passcode, 10);
}
```

View File

@ -10,22 +10,34 @@ dashedName: problem-80-square-root-digital-expansion
It is well known that if the square root of a natural number is not an integer, then it is irrational. The decimal expansion of such square roots is infinite without any repeating pattern at all.
The square root of two is 1.41421356237309504880..., and the digital sum of the first one hundred decimal digits is 475.
The square root of two is `1.41421356237309504880...`, and the digital sum of the first one hundred decimal digits is `475`.
For the first one hundred natural numbers, find the total of the digital sums of the first one hundred decimal digits for all the irrational square roots.
For the first `n` natural numbers, find the total of the digital sums of the first one hundred decimal digits for all the irrational square roots.
# --hints--
`sqrtDigitalExpansion()` should return a number.
`sqrtDigitalExpansion(2)` should return a number.
```js
assert(typeof sqrtDigitalExpansion() === 'number');
assert(typeof sqrtDigitalExpansion(2) === 'number');
```
`sqrtDigitalExpansion()` should return 40886.
`sqrtDigitalExpansion(2)` should return `475`.
```js
assert.strictEqual(sqrtDigitalExpansion(), 40886);
assert.strictEqual(sqrtDigitalExpansion(2), 475);
```
`sqrtDigitalExpansion(50)` should return `19543`.
```js
assert.strictEqual(sqrtDigitalExpansion(50), 19543);
```
`sqrtDigitalExpansion(100)` should return `40886`.
```js
assert.strictEqual(sqrtDigitalExpansion(100), 40886);
```
# --seed--
@ -33,16 +45,65 @@ assert.strictEqual(sqrtDigitalExpansion(), 40886);
## --seed-contents--
```js
function sqrtDigitalExpansion() {
function sqrtDigitalExpansion(n) {
return true;
}
sqrtDigitalExpansion();
sqrtDigitalExpansion(2);
```
# --solutions--
```js
// solution required
function sqrtDigitalExpansion(n) {
function sumDigits(number) {
let sum = 0;
while (number > 0n) {
let digit = number % 10n;
sum += parseInt(digit, 10);
number = number / 10n;
}
return sum;
}
function power(numberA, numberB) {
let result = 1n;
for (let b = 0; b < numberB; b++) {
result = result * BigInt(numberA);
}
return result;
}
// Based on http://www.afjarvis.staff.shef.ac.uk/maths/jarvisspec02.pdf
function expandSquareRoot(number, numDigits) {
let a = 5n * BigInt(number);
let b = 5n;
const boundaryWithNeededDigits = power(10, numDigits + 1);
while (b < boundaryWithNeededDigits) {
if (a >= b) {
a = a - b;
b = b + 10n;
} else {
a = a * 100n;
b = (b / 10n) * 100n + 5n;
}
}
return b / 100n;
}
let result = 0;
let nextPerfectRoot = 1;
const requiredDigits = 100;
for (let i = 1; i <= n; i++) {
if (nextPerfectRoot ** 2 === i) {
nextPerfectRoot++;
continue;
}
result += sumDigits(expandSquareRoot(i, requiredDigits));
}
return result;
}
```

View File

@ -8,46 +8,45 @@ dashedName: problem-81-path-sum-two-ways
# --description--
In the 5 by 5 matrix below, the minimal path sum from the top left to the bottom right, by **only moving to the right and down**, is indicated in bold red and is equal to 2427.
In the 5 by 5 matrix below, the minimal path sum from the top left to the bottom right, by **only moving to the right and down**, is indicated in bold red and is equal to `2427`.
<div style='text-align: center;'>
$\begin{pmatrix}
\color{red}{131} & 673 & 234 & 103 & 18\\\\
\color{red}{201} & \color{red}{96} & \color{red}{342} & 965 & 150\\\\
630 & 803 & \color{red}{746} & \color{red}{422} & 111\\\\
537 & 699 & 497 & \color{red}{121} & 956\\\\
805 & 732 & 524 & \color{red}{37} & \color{red}{331}
\end{pmatrix}$
</div>
$$\begin{pmatrix} \color{red}{131} & 673 & 234 & 103 & 18\\\\ \color{red}{201} & \color{red}{96} & \color{red}{342} & 965 & 150\\\\ 630 & 803 & \color{red}{746} & \color{red}{422} & 111\\\\ 537 & 699 & 497 & \color{red}{121} & 956\\\\ 805 & 732 & 524 & \color{red}{37} & \color{red}{331} \end{pmatrix}$$
Find the minimal path sum from the top left to the bottom right by only moving right and down in `matrix`, a 2D array containing an 80 by 80 matrix.
Find the minimal path sum from the top left to the bottom right by only moving right and down in `matrix`, a 2D array representing a matrix. The maximum matrix size used in the tests will be 80 by 80.
# --hints--
`pathSumTwoWays(testMatrix)` should return a number.
`pathSumTwoWays(testMatrix1)` should return a number.
```js
assert(typeof pathSumTwoWays(testMatrix) === 'number');
assert(typeof pathSumTwoWays(_testMatrix1) === 'number');
```
`pathSumTwoWays(testMatrix)` should return 2427.
`pathSumTwoWays(testMatrix1)` should return `2427`.
```js
assert.strictEqual(pathSumTwoWays(testMatrix), 2427);
assert.strictEqual(pathSumTwoWays(_testMatrix1), 2427);
```
`pathSumTwoWays(matrix)` should return 427337.
`pathSumTwoWays(testMatrix2)` should return `427337`.
```js
assert.strictEqual(pathSumTwoWays(matrix), 427337);
assert.strictEqual(pathSumTwoWays(_testMatrix2), 427337);
```
# --seed--
## --before-user-code--
## --after-user-code--
```js
const matrix = [
const _testMatrix1 = [
[131, 673, 234, 103, 18],
[201, 96, 342, 965, 150],
[630, 803, 746, 422, 111],
[537, 699, 497, 121, 956],
[805, 732, 524, 37, 331]
];
const _testMatrix2 = [
[4445,2697,5115,718,2209,2212,654,4348,3079,6821,7668,3276,8874,4190,3785,2752,9473,7817,9137,496,7338,3434,7152,4355,4552,7917,7827,2460,2350,691,3514,5880,3145,7633,7199,3783,5066,7487,3285,1084,8985,760,872,8609,8051,1134,9536,5750,9716,9371,7619,5617,275,9721,2997,2698,1887,8825,6372,3014,2113,7122,7050,6775,5948,2758,1219,3539,348,7989,2735,9862,1263,8089,6401,9462,3168,2758,3748,5870],
[1096,20,1318,7586,5167,2642,1443,5741,7621,7030,5526,4244,2348,4641,9827,2448,6918,5883,3737,300,7116,6531,567,5997,3971,6623,820,6148,3287,1874,7981,8424,7672,7575,6797,6717,1078,5008,4051,8795,5820,346,1851,6463,2117,6058,3407,8211,117,4822,1317,4377,4434,5925,8341,4800,1175,4173,690,8978,7470,1295,3799,8724,3509,9849,618,3320,7068,9633,2384,7175,544,6583,1908,9983,481,4187,9353,9377],
[9607,7385,521,6084,1364,8983,7623,1585,6935,8551,2574,8267,4781,3834,2764,2084,2669,4656,9343,7709,2203,9328,8004,6192,5856,3555,2260,5118,6504,1839,9227,1259,9451,1388,7909,5733,6968,8519,9973,1663,5315,7571,3035,4325,4283,2304,6438,3815,9213,9806,9536,196,5542,6907,2475,1159,5820,9075,9470,2179,9248,1828,4592,9167,3713,4640,47,3637,309,7344,6955,346,378,9044,8635,7466,5036,9515,6385,9230],
@ -134,14 +133,14 @@ const matrix = [
## --seed-contents--
```js
function pathSumTwoWays(arr) {
function pathSumTwoWays(matrix) {
return true;
}
// Only change code above this line
const testMatrix = [
const testMatrix1 = [
[131, 673, 234, 103, 18],
[201, 96, 342, 965, 150],
[630, 803, 746, 422, 111],
@ -149,11 +148,36 @@ const testMatrix = [
[805, 732, 524, 37, 331]
];
pathSumTwoWays(testMatrix);
pathSumTwoWays(testMatrix1);
```
# --solutions--
```js
// solution required
function pathSumTwoWays(matrix) {
function makeMinimalMove(row, column) {
if (resultMatrix[row][column + 1] < resultMatrix[row + 1][column]) {
return resultMatrix[row][column + 1];
}
return resultMatrix[row + 1][column];
}
const size = matrix.length;
const resultMatrix = [];
for (let i = 0; i < size; i++) {
resultMatrix.push([...matrix[i]])
}
for (let i = size - 2; i >= 0; i--) {
resultMatrix[size - 1][i] += resultMatrix[size - 1][i + 1];
resultMatrix[i][size - 1] += resultMatrix[i + 1][size - 1];
}
for (let row = size - 2; row >= 0; row--) {
for (let column = size - 2; column >= 0; column--) {
resultMatrix[row][column] += makeMinimalMove(row, column);
}
}
return resultMatrix[0][0];
}
```

View File

@ -10,46 +10,45 @@ dashedName: problem-82-path-sum-three-ways
**Note:** This problem is a more challenging version of Problem 81.
The minimal path sum in the 5 by 5 matrix below, by starting in any cell in the left column and finishing in any cell in the right column, and only moving up, down, and right, is indicated in red and bold; the sum is equal to 994.
The minimal path sum in the 5 by 5 matrix below, by starting in any cell in the left column and finishing in any cell in the right column, and only moving up, down, and right, is indicated in red and bold; the sum is equal to `994`.
<div style='text-align: center;'>
$\begin{pmatrix}
131 & 673 & \color{red}{234} & \color{red}{103} & \color{red}{18}\\\\
\color{red}{201} & \color{red}{96} & \color{red}{342} & 965 & 150\\\\
630 & 803 & 746 & 422 & 111\\\\
537 & 699 & 497 & 121 & 956\\\\
805 & 732 & 524 & 37 & 331
\end{pmatrix}$
</div>
$$\begin{pmatrix} 131 & 673 & \color{red}{234} & \color{red}{103} & \color{red}{18}\\\\ \color{red}{201} & \color{red}{96} & \color{red}{342} & 965 & 150\\\\ 630 & 803 & 746 & 422 & 111\\\\ 537 & 699 & 497 & 121 & 956\\\\ 805 & 732 & 524 & 37 & 331 \end{pmatrix}$$
Find the minimal path sum from the left column to the right column in `matrix`, a 2D array containing an 80 by 80 matrix.
Find the minimal path sum from the left column to the right column in `matrix`, a 2D array representing a matrix. The maximum matrix size used in tests will be 80 by 80.
# --hints--
`pathSumThreeWays(testMatrix)` should return a number.
`pathSumThreeWays(testMatrix1)` should return a number.
```js
assert(typeof pathSumThreeWays(testMatrix) === 'number');
assert(typeof pathSumThreeWays(_testMatrix1) === 'number');
```
`pathSumThreeWays(testMatrix)` should return 994.
`pathSumThreeWays(testMatrix1)` should return `994`.
```js
assert.strictEqual(pathSumThreeWays(testMatrix), 994);
assert.strictEqual(pathSumThreeWays(_testMatrix1), 994);
```
`pathSumThreeWays(matrix)` should return 260324.
`pathSumThreeWays(testMatrix2)` should return `260324`.
```js
assert.strictEqual(pathSumThreeWays(matrix), 260324);
assert.strictEqual(pathSumThreeWays(_testMatrix2), 260324);
```
# --seed--
## --before-user-code--
## --after-user-code--
```js
const matrix = [
const _testMatrix1 = [
[131, 673, 234, 103, 18],
[201, 96, 342, 965, 150],
[630, 803, 746, 422, 111],
[537, 699, 497, 121, 956],
[805, 732, 524, 37, 331]
];
const _testMatrix2 = [
[4445,2697,5115,718,2209,2212,654,4348,3079,6821,7668,3276,8874,4190,3785,2752,9473,7817,9137,496,7338,3434,7152,4355,4552,7917,7827,2460,2350,691,3514,5880,3145,7633,7199,3783,5066,7487,3285,1084,8985,760,872,8609,8051,1134,9536,5750,9716,9371,7619,5617,275,9721,2997,2698,1887,8825,6372,3014,2113,7122,7050,6775,5948,2758,1219,3539,348,7989,2735,9862,1263,8089,6401,9462,3168,2758,3748,5870],
[1096,20,1318,7586,5167,2642,1443,5741,7621,7030,5526,4244,2348,4641,9827,2448,6918,5883,3737,300,7116,6531,567,5997,3971,6623,820,6148,3287,1874,7981,8424,7672,7575,6797,6717,1078,5008,4051,8795,5820,346,1851,6463,2117,6058,3407,8211,117,4822,1317,4377,4434,5925,8341,4800,1175,4173,690,8978,7470,1295,3799,8724,3509,9849,618,3320,7068,9633,2384,7175,544,6583,1908,9983,481,4187,9353,9377],
[9607,7385,521,6084,1364,8983,7623,1585,6935,8551,2574,8267,4781,3834,2764,2084,2669,4656,9343,7709,2203,9328,8004,6192,5856,3555,2260,5118,6504,1839,9227,1259,9451,1388,7909,5733,6968,8519,9973,1663,5315,7571,3035,4325,4283,2304,6438,3815,9213,9806,9536,196,5542,6907,2475,1159,5820,9075,9470,2179,9248,1828,4592,9167,3713,4640,47,3637,309,7344,6955,346,378,9044,8635,7466,5036,9515,6385,9230],
@ -136,14 +135,14 @@ const matrix = [
## --seed-contents--
```js
function pathSumThreeWays(arr) {
function pathSumThreeWays(matrix) {
return true;
}
// Only change code above this line
const testMatrix = [
const testMatrix1 = [
[131, 673, 234, 103, 18],
[201, 96, 342, 965, 150],
[630, 803, 746, 422, 111],
@ -151,11 +150,44 @@ const testMatrix = [
[805, 732, 524, 37, 331]
];
pathSumThreeWays(testMatrix);
pathSumThreeWays(testMatrix1);
```
# --solutions--
```js
// solution required
function pathSumThreeWays(matrix) {
function makeMinimumMoveFromUpOrRight(row, column) {
const curValue = matrix[row][column];
if (values[row - 1] > values[row]) {
return values[row] + curValue;
}
return values[row - 1] + curValue;
}
function isGoingFromDownBetter(row, column) {
return values[row] > values[row + 1] + matrix[row][column];
}
const size = matrix.length;
const values = [];
for (let row = 0; row < size; row++) {
values.push(matrix[row][size - 1]);
}
for (let column = size - 2; column >= 0; column--) {
values[0] += matrix[0][column];
for (let row = 1; row < size; row++) {
values[row] = makeMinimumMoveFromUpOrRight(row, column);
}
for (let row = size - 2; row >= 0; row--) {
if (isGoingFromDownBetter(row, column)) {
values[row] = values[row + 1] + matrix[row][column];
}
}
}
return Math.min(...values);
}
```

View File

@ -10,46 +10,45 @@ dashedName: problem-83-path-sum-four-ways
**Note:** This problem is a significantly more challenging version of Problem 81.
In the 5 by 5 matrix below, the minimal path sum from the top left to the bottom right, by moving left, right, up, and down, is indicated in bold red and is equal to 2297.
In the 5 by 5 matrix below, the minimal path sum from the top left to the bottom right, by moving left, right, up, and down, is indicated in bold red and is equal to `2297`.
<div style='text-align: center;'>
$\begin{pmatrix}
\color{red}{131} & 673 & \color{red}{234} & \color{red}{103} & \color{red}{18}\\\\
\color{red}{201} & \color{red}{96} & \color{red}{342} & 965 & \color{red}{150}\\\\
630 & 803 & 746 & \color{red}{422} & \color{red}{111}\\\\
537 & 699 & 497 & \color{red}{121} & 956\\\\
805 & 732 & 524 & \color{red}{37} & \color{red}{331}
\end{pmatrix}$
</div>
$$\begin{pmatrix} \color{red}{131} & 673 & \color{red}{234} & \color{red}{103} & \color{red}{18}\\\\ \color{red}{201} & \color{red}{96} & \color{red}{342} & 965 & \color{red}{150}\\\\ 630 & 803 & 746 & \color{red}{422} & \color{red}{111}\\\\ 537 & 699 & 497 & \color{red}{121} & 956\\\\ 805 & 732 & 524 & \color{red}{37} & \color{red}{331} \end{pmatrix}$$
Find the minimal path sum from the top left to the bottom right by moving left, right, up, and down in `matrix`, a 2D array defined in the background, containing an 80 by 80 matrix.
Find the minimal path sum from the top left to the bottom right by moving left, right, up, and down in `matrix`, a 2D array representing a matrix. The maximum matrix size used in tests will be 80 by 80.
# --hints--
`pathSumFourWays(testMatrix)` should return a number.
`pathSumFourWays(testMatrix1)` should return a number.
```js
assert(typeof pathSumFourWays(testMatrix) === 'number');
assert(typeof pathSumFourWays(_testMatrix1) === 'number');
```
`pathSumFourWays(testMatrix)` should return 2297.
`pathSumFourWays(testMatrix1)` should return `2297`.
```js
assert.strictEqual(pathSumFourWays(testMatrix), 2297);
assert.strictEqual(pathSumFourWays(_testMatrix1), 2297);
```
`pathSumFourWays(matrix)` should return 425185.
`pathSumFourWays(testMatrix2)` should return `425185`.
```js
assert.strictEqual(pathSumFourWays(matrix), 425185);
assert.strictEqual(pathSumFourWays(_testMatrix2), 425185);
```
# --seed--
## --before-user-code--
## --after-user-code--
```js
const matrix = [
const _testMatrix1 = [
[131, 673, 234, 103, 18],
[201, 96, 342, 965, 150],
[630, 803, 746, 422, 111],
[537, 699, 497, 121, 956],
[805, 732, 524, 37, 331]
];
const _testMatrix2 = [
[4445,2697,5115,718,2209,2212,654,4348,3079,6821,7668,3276,8874,4190,3785,2752,9473,7817,9137,496,7338,3434,7152,4355,4552,7917,7827,2460,2350,691,3514,5880,3145,7633,7199,3783,5066,7487,3285,1084,8985,760,872,8609,8051,1134,9536,5750,9716,9371,7619,5617,275,9721,2997,2698,1887,8825,6372,3014,2113,7122,7050,6775,5948,2758,1219,3539,348,7989,2735,9862,1263,8089,6401,9462,3168,2758,3748,5870],
[1096,20,1318,7586,5167,2642,1443,5741,7621,7030,5526,4244,2348,4641,9827,2448,6918,5883,3737,300,7116,6531,567,5997,3971,6623,820,6148,3287,1874,7981,8424,7672,7575,6797,6717,1078,5008,4051,8795,5820,346,1851,6463,2117,6058,3407,8211,117,4822,1317,4377,4434,5925,8341,4800,1175,4173,690,8978,7470,1295,3799,8724,3509,9849,618,3320,7068,9633,2384,7175,544,6583,1908,9983,481,4187,9353,9377],
[9607,7385,521,6084,1364,8983,7623,1585,6935,8551,2574,8267,4781,3834,2764,2084,2669,4656,9343,7709,2203,9328,8004,6192,5856,3555,2260,5118,6504,1839,9227,1259,9451,1388,7909,5733,6968,8519,9973,1663,5315,7571,3035,4325,4283,2304,6438,3815,9213,9806,9536,196,5542,6907,2475,1159,5820,9075,9470,2179,9248,1828,4592,9167,3713,4640,47,3637,309,7344,6955,346,378,9044,8635,7466,5036,9515,6385,9230],
@ -136,14 +135,14 @@ const matrix = [
## --seed-contents--
```js
function pathSumFourWays(arr) {
function pathSumFourWays(matrix) {
return true;
}
// Only change code above this line
const testMatrix = [
const testMatrix1 = [
[131, 673, 234, 103, 18],
[201, 96, 342, 965, 150],
[630, 803, 746, 422, 111],
@ -151,11 +150,64 @@ const testMatrix = [
[805, 732, 524, 37, 331]
];
pathSumFourWays(testMatrix);
pathSumFourWays(testMatrix1);
```
# --solutions--
```js
// solution required
function pathSumFourWays(matrix) {
const MOVES = [
[-1, 0],
[1, 0],
[0, -1],
[0, 1]
];
function getAllowedMoves(row, col) {
const moves = [];
for (let i = 0; i < MOVES.length; i++) {
const [rowChange, colChange] = MOVES[i];
const nextRow = row + rowChange;
const nextCol = col + colChange;
if (isMoveAllowed(nextRow, nextCol)) {
moves.push([nextRow, nextCol]);
}
}
return moves;
}
function isMoveAllowed(nextRow, nextCol) {
if (nextRow < 0 || nextRow >= size || nextCol < 0 || nextCol >= size) {
return false;
}
return true;
}
const size = matrix.length;
const resultMatrix = new Array(size)
.fill()
.map(() => new Array(size).fill(Infinity));
const [startRow, startCol] = new Array(2).fill(size - 1);
const queue = [[startRow, startCol]];
resultMatrix[startRow][startCol] = matrix[startRow][startCol];
while (queue.length > 0) {
const [curRow, curCol] = queue.shift();
const allowedMoves = getAllowedMoves(curRow, curCol);
for (let i = 0; i < allowedMoves.length; i++) {
const [nextRow, nextCol] = allowedMoves[i];
const bestPath = resultMatrix[nextRow][nextCol];
const newPath = resultMatrix[curRow][curCol] + matrix[nextRow][nextCol];
if (newPath < bestPath) {
resultMatrix[nextRow][nextCol] = newPath;
queue.push(allowedMoves[i]);
}
}
}
return resultMatrix[0][0];
}
```

View File

@ -86,7 +86,7 @@ In the game, *Monopoly*, the standard board is set up in the following way:
</tr>
</tbody>
</table>
</div>
</div><br>
A player starts on the GO square and adds the scores on two 6-sided dice to determine the number of squares they advance in a clockwise direction. Without any further rules we would expect to visit each square with equal probability: 2.5%. However, landing on G2J (Go To Jail), CC (community chest), and CH (chance) changes this distribution.
@ -120,22 +120,40 @@ The heart of this problem concerns the likelihood of visiting a particular squar
By starting at GO and numbering the squares sequentially from 00 to 39 we can concatenate these two-digit numbers to produce strings that correspond with sets of squares.
Statistically it can be shown that the three most popular squares, in order, are JAIL (6.24%) = Square 10, E3 (3.18%) = Square 24, and GO (3.09%) = Square 00. So these three most popular squares can be listed with the six-digit modal string: 102400.
Statistically it can be shown that the three most popular squares, in order, are JAIL (6.24%) = Square 10, E3 (3.18%) = Square 24, and GO (3.09%) = Square 00. So these three most popular squares can be listed with the six-digit modal string `102400`.
If, instead of using two 6-sided dice, two 4-sided dice are used, find the six-digit modal string.
If, instead of using two 6-sided dice, two `n`-sided dice are used, find the six-digit modal string.
# --hints--
`monopolyOdds()` should return a number.
`monopolyOdds(8)` should return a string.
```js
assert(typeof monopolyOdds() === 'number');
assert(typeof monopolyOdds(8) === 'string');
```
`monopolyOdds()` should return 101524.
`monopolyOdds(8)` should return string `102400`.
```js
assert.strictEqual(monopolyOdds(), 101524);
assert.strictEqual(monopolyOdds(8), '102400');
```
`monopolyOdds(10)` should return string `100024`.
```js
assert.strictEqual(monopolyOdds(10), '100024');
```
`monopolyOdds(20)` should return string `100005`.
```js
assert.strictEqual(monopolyOdds(20), '100005');
```
`monopolyOdds(4)` should return string `101524`.
```js
assert.strictEqual(monopolyOdds(4), '101524');
```
# --seed--
@ -143,16 +161,108 @@ assert.strictEqual(monopolyOdds(), 101524);
## --seed-contents--
```js
function monopolyOdds() {
function monopolyOdds(n) {
return true;
}
monopolyOdds();
monopolyOdds(8);
```
# --solutions--
```js
// solution required
function monopolyOdds(n) {
function chanceCard(position, chanceCardPosition) {
chanceCardPosition = (chanceCardPosition + 1) % 16;
if (chanceCardPosition < 6) {
position = chanceCardsMoves[chanceCardPosition];
} else if (chanceCardPosition === 6 || chanceCardPosition === 7) {
position = nextMovesFromR[position];
} else if (chanceCardPosition === 8) {
position = nextMovesFromU[position];
} else if (chanceCardPosition === 9) {
position -= 3;
}
return [position, chanceCardPosition];
}
function chestCard(position, chestPosition) {
chestPosition = (chestPosition + 1) % 16;
if (chestPosition < 2) {
position = chestCardsMoves[chestPosition];
}
return [position, chestPosition];
}
function isChest(position) {
return position === 2 || position === 17 || position === 33;
}
function isChance(position) {
return position === 7 || position === 22 || position === 36;
}
function isJail(position) {
return position === 30;
}
function roll(dice) {
return Math.floor(Math.random() * dice) + 1;
}
function getTopThree(board) {
return sortByVisits(board)
.slice(0, 3)
.map(elem => elem[0].toString().padStart(2, '0'))
.join('');
}
function sortByVisits(board) {
return board
.map((element, index) => [index, element])
.sort((a, b) => a[1] - b[1])
.reverse();
}
const rounds = 2000000;
const chestCardsMoves = [0, 10];
const chanceCardsMoves = [0, 10, 11, 24, 39, 5];
const nextMovesFromR = { 7: 15, 22: 25, 36: 5 };
const nextMovesFromU = { 7: 12, 36: 12, 22: 28 };
const board = new Array(40).fill(0);
let doubleCount = 0;
let curPosition = 0;
let curChestCard = 0;
let curChanceCard = 0;
for (let i = 0; i < rounds; i++) {
const dice1 = roll(n);
const dice2 = roll(n);
if (dice1 === dice2) {
doubleCount++;
} else {
doubleCount = 0;
}
if (doubleCount > 2) {
curPosition = 10;
doubleCount = 0;
} else {
curPosition = (curPosition + dice1 + dice2) % 40;
if (isChance(curPosition)) {
[curPosition, curChanceCard] = chanceCard(curPosition, curChanceCard);
} else if (isChest(curPosition)) {
[curPosition, curChestCard] = chestCard(curPosition, curChestCard);
} else if (isJail(curPosition)) {
curPosition = 10;
}
}
board[curPosition]++;
}
return getTopThree(board);
}
```

View File

@ -12,20 +12,44 @@ By counting carefully it can be seen that a rectangular grid measuring 3 by 2 co
<img class="img-responsive center-block" alt="a diagram of the different rectangles found within a 3 by 2 rectangular grid" src="https://cdn-media-1.freecodecamp.org/project-euler/counting-rectangles.png" style="background-color: white; padding: 10px;" />
Although there exists no rectangular grid that contains exactly two million rectangles, find the area of the grid with the nearest solution.
Although there may not exists a rectangular grid that contains exactly `n` rectangles, find the area of the grid with the nearest solution.
# --hints--
`countingRectangles()` should return a number.
`countingRectangles(18)` should return a number.
```js
assert(typeof countingRectangles() === 'number');
assert(typeof countingRectangles(18) === 'number');
```
`countingRectangles()` should return 2772.
`countingRectangles(18)` should return `6`.
```js
assert.strictEqual(countingRectangles(), 2772);
assert.strictEqual(countingRectangles(18), 6);
```
`countingRectangles(250)` should return `22`.
```js
assert.strictEqual(countingRectangles(250), 22);
```
`countingRectangles(50000)` should return `364`.
```js
assert.strictEqual(countingRectangles(50000), 364);
```
`countingRectangles(1000000)` should return `1632`.
```js
assert.strictEqual(countingRectangles(1000000), 1632);
```
`countingRectangles(2000000)` should return `2772`.
```js
assert.strictEqual(countingRectangles(2000000), 2772);
```
# --seed--
@ -33,16 +57,53 @@ assert.strictEqual(countingRectangles(), 2772);
## --seed-contents--
```js
function countingRectangles() {
function countingRectangles(n) {
return true;
}
countingRectangles();
countingRectangles(18);
```
# --solutions--
```js
// solution required
function countingRectangles(n) {
function numberOfRectangles(h, w) {
return (h * (h + 1) * w * (w + 1)) / 4;
}
function rectangleArea(h, w) {
return h * w;
}
let rectanglesCount = 1;
let maxSide = 1;
while (rectanglesCount < n) {
maxSide++;
rectanglesCount = numberOfRectangles(maxSide, 1);
}
let bestDiff = Math.abs(rectanglesCount - n);
let bestSize = [maxSide, 1];
let curHeight = maxSide - 1;
let curWidth = 1;
for (curWidth; curWidth < curHeight; curWidth++) {
for (curHeight; curHeight > curWidth; curHeight--) {
rectanglesCount = numberOfRectangles(curHeight, curWidth);
const curDiff = Math.abs(rectanglesCount - n);
if (curDiff < bestDiff) {
bestDiff = curDiff;
bestSize = [curHeight, curWidth];
}
if (rectanglesCount < n) {
break;
}
}
}
return rectangleArea(...bestSize);
}
```

View File

@ -14,22 +14,40 @@ A spider, S, sits in one corner of a cuboid room, measuring 6 by 5 by 3, and a f
However, there are up to three "shortest" path candidates for any given cuboid and the shortest route doesn't always have integer length.
It can be shown that there are exactly 2060 distinct cuboids, ignoring rotations, with integer dimensions, up to a maximum size of M by M by M, for which the shortest route has integer length when M = 100. This is the least value of M for which the number of solutions first exceeds two thousand; the number of solutions when M = 99 is 1975.
It can be shown that there are exactly `2060` distinct cuboids, ignoring rotations, with integer dimensions, up to a maximum size of M by M by M, for which the shortest route has integer length when M = 100. This is the least value of M for which the number of solutions first exceeds two thousand; the number of solutions when M = 99 is `1975`.
Find the least value of M such that the number of solutions first exceeds one million.
Find the least value of M such that the number of solutions first exceeds `n`.
# --hints--
`cuboidRoute()` should return a number.
`cuboidRoute(2000)` should return a number.
```js
assert(typeof cuboidRoute() === 'number');
assert(typeof cuboidRoute(2000) === 'number');
```
`cuboidRoute()` should return 1818.
`cuboidRoute(2000)` should return `100`.
```js
assert.strictEqual(cuboidRoute(), 1818);
assert.strictEqual(cuboidRoute(2000), 100);
```
`cuboidRoute(25000)` should return `320`.
```js
assert.strictEqual(cuboidRoute(25000), 320);
```
`cuboidRoute(500000)` should return `1309`.
```js
assert.strictEqual(cuboidRoute(500000), 1309);
```
`cuboidRoute(1000000)` should return `1818`.
```js
assert.strictEqual(cuboidRoute(1000000), 1818);
```
# --seed--
@ -37,16 +55,40 @@ assert.strictEqual(cuboidRoute(), 1818);
## --seed-contents--
```js
function cuboidRoute() {
function cuboidRoute(n) {
return true;
}
cuboidRoute();
cuboidRoute(2000);
```
# --solutions--
```js
// solution required
function cuboidRoute(n) {
// Based on https://www.mathblog.dk/project-euler-86-shortest-path-cuboid/
function getLength(a, b) {
return Math.sqrt(a ** 2 + b ** 2);
}
let M = 2;
let counter = 0;
while (counter < n) {
M++;
for (let baseHeightWidth = 3; baseHeightWidth <= 2 * M; baseHeightWidth++) {
const pathLength = getLength(M, baseHeightWidth);
if (Number.isInteger(pathLength)) {
if (baseHeightWidth <= M) {
counter += Math.floor(baseHeightWidth / 2);
} else {
counter += 1 + M - Math.floor((baseHeightWidth + 1) / 2);
}
}
}
}
return M;
}
```

View File

@ -8,29 +8,53 @@ dashedName: problem-87-prime-power-triples
# --description--
The smallest number expressible as the sum of a prime square, prime cube, and prime fourth power is 28. In fact, there are exactly four numbers below fifty that can be expressed in such a way:
The smallest number expressible as the sum of a prime square, prime cube, and prime fourth power is `28`. In fact, there are exactly four numbers below fifty that can be expressed in such a way:
<div style='margin-left: 4em;'>
28 = 2<sup>2</sup> + 2<sup>3</sup> + 2<sup>4</sup><br>
33 = 3<sup>2</sup> + 2<sup>3</sup> + 2<sup>4</sup><br>
49 = 5<sup>2</sup> + 2<sup>3</sup> + 2<sup>4</sup><br>
47 = 2<sup>2</sup> + 3<sup>3</sup> + 2<sup>4</sup>
</div>
</div><br>
How many numbers below fifty million can be expressed as the sum of a prime square, prime cube, and prime fourth power?
How many numbers below `n` can be expressed as the sum of a prime square, prime cube, and prime fourth power?
# --hints--
`primePowerTriples()` should return a number.
`primePowerTriples(50)` should return a number.
```js
assert(typeof primePowerTriples() === 'number');
assert(typeof primePowerTriples(50) === 'number');
```
`primePowerTriples()` should return 1097343.
`primePowerTriples(50)` should return `4`.
```js
assert.strictEqual(primePowerTriples(), 1097343);
assert.strictEqual(primePowerTriples(50), 4);
```
`primePowerTriples(10035)` should return `684`.
```js
assert.strictEqual(primePowerTriples(10035), 684);
```
`primePowerTriples(500000)` should return `18899`.
```js
assert.strictEqual(primePowerTriples(500000), 18899);
```
`primePowerTriples(5000000)` should return `138932`.
```js
assert.strictEqual(primePowerTriples(5000000), 138932);
```
`primePowerTriples(50000000)` should return `1097343`.
```js
assert.strictEqual(primePowerTriples(50000000), 1097343);
```
# --seed--
@ -38,16 +62,70 @@ assert.strictEqual(primePowerTriples(), 1097343);
## --seed-contents--
```js
function primePowerTriples() {
function primePowerTriples(n) {
return true;
}
primePowerTriples();
primePowerTriples(50);
```
# --solutions--
```js
// solution required
function primePowerTriples(n) {
function getSievePrimes(max) {
const primes = [];
const primesMap = new Array(max).fill(true);
primesMap[0] = false;
primesMap[1] = false;
for (let i = 2; i <= max; i += 2) {
if (primesMap[i]) {
primes.push(i);
for (let j = i * i; j <= max; j = j + i) {
primesMap[j] = false;
}
}
if (i === 2) {
i = 1;
}
}
return primes;
}
function getPowersSummed(numbers, powers, limit, curSum) {
if (curSum >= limit) {
return [];
} else if (powers.length === 0) {
return [curSum];
}
const powersSummed = [];
const curPower = powers[0];
const powersLeft = powers.slice(1);
for (let i = 0; i < numbers.length; i++) {
const curNumber = numbers[i];
const nextSum = curSum + curNumber ** curPower;
if (nextSum >= limit) {
return powersSummed;
}
const result = getPowersSummed(
numbers,
powersLeft,
limit,
curSum + curNumber ** curPower
);
powersSummed.push(...result);
}
return powersSummed;
}
const maximumBaseNumber = Math.floor(Math.sqrt(n - 2 ** 3 - 2 ** 4)) + 1;
const primes = getSievePrimes(maximumBaseNumber);
const uniqueSums = new Set(getPowersSummed(primes, [2, 3, 4], n, 0));
return uniqueSums.size;
}
```

View File

@ -8,7 +8,7 @@ dashedName: problem-88-product-sum-numbers
# --description--
A natural number, N, that can be written as the sum and product of a given set of at least two natural numbers, {`a`<sub>1</sub>, `a`<sub>2</sub>, ... , `a`<sub>k</sub>} is called a product-sum number: N = `a`<sub>1</sub> + `a`<sub>2</sub> + ... + `a`<sub>k</sub> = `a`<sub>1</sub> × `a`<sub>2</sub> × ... × `a`<sub>k</sub>.
A natural number, `N`, that can be written as the sum and product of a given set of at least two natural numbers, $\\{a_1, a_2, \ldots , a_k\\}$ is called a product-sum number: $N = a_1 + a_2 + \cdots + a_k = a_1 × a_2 × \cdots × a_k$.
For example, 6 = 1 + 2 + 3 = 1 × 2 × 3.
@ -20,26 +20,50 @@ For a given set of size, `k`, we shall call the smallest N with this property a
<var>k</var>=4: 8 = 1 × 1 × 2 × 4 = 1 + 1 + 2 + 4<br>
<var>k</var>=5: 8 = 1 × 1 × 2 × 2 × 2 = 1 + 1 + 2 + 2 + 2<br>
<var>k</var>=6: 12 = 1 × 1 × 1 × 1 × 2 × 6 = 1 + 1 + 1 + 1 + 2 + 6
</div>
</div><br>
Hence for 2`k`6, the sum of all the minimal product-sum numbers is 4+6+8+12 = 30; note that 8 is only counted once in the sum.
Hence for 2`k`6, the sum of all the minimal product-sum numbers is 4 + 6 + 8 + 12 = 30; note that `8` is only counted once in the sum.
In fact, as the complete set of minimal product-sum numbers for 2`k`12 is {4, 6, 8, 12, 15, 16}, the sum is 61.
In fact, as the complete set of minimal product-sum numbers for 2`k`12 is $\\{4, 6, 8, 12, 15, 16\\}$, the sum is `61`.
What is the sum of all the minimal product-sum numbers for 2`k`≤12000?
What is the sum of all the minimal product-sum numbers for 2`k``limit`?
# --hints--
`productSumNumbers()` should return a number.
`productSumNumbers(6)` should return a number.
```js
assert(typeof productSumNumbers() === 'number');
assert(typeof productSumNumbers(6) === 'number');
```
`productSumNumbers()` should return 7587457.
`productSumNumbers(6)` should return `30`.
```js
assert.strictEqual(productSumNumbers(), 7587457);
assert.strictEqual(productSumNumbers(6), 30);
```
`productSumNumbers(12)` should return `61`.
```js
assert.strictEqual(productSumNumbers(12), 61);
```
`productSumNumbers(300)` should return `12686`.
```js
assert.strictEqual(productSumNumbers(300), 12686);
```
`productSumNumbers(6000)` should return `2125990`.
```js
assert.strictEqual(productSumNumbers(6000), 2125990);
```
`productSumNumbers(12000)` should return `7587457`.
```js
assert.strictEqual(productSumNumbers(12000), 7587457);
```
# --seed--
@ -47,16 +71,40 @@ assert.strictEqual(productSumNumbers(), 7587457);
## --seed-contents--
```js
function productSumNumbers() {
function productSumNumbers(limit) {
return true;
}
productSumNumbers();
productSumNumbers(6);
```
# --solutions--
```js
// solution required
function productSumNumbers(limit) {
function getProductSums(curProduct, curSum, factorsCount, start) {
const k = curProduct - curSum + factorsCount;
if (k <= limit) {
if (curProduct < minimalProductSums[k]) {
minimalProductSums[k] = curProduct;
}
for (let i = start; i < Math.floor((limit / curProduct) * 2) + 1; i++) {
getProductSums(curProduct * i, curSum + i, factorsCount + 1, i);
}
}
}
const minimalProductSums = new Array(limit + 1).fill(2 * limit);
getProductSums(1, 1, 1, 2);
const uniqueProductSums = [...new Set(minimalProductSums.slice(2))];
let sum = 0;
for (let i = 0; i < uniqueProductSums.length; i++) {
sum += uniqueProductSums[i];
}
return sum;
}
```

View File

@ -8,28 +8,46 @@ dashedName: problem-91-right-triangles-with-integer-coordinates
# --description--
The points P (`x`<sub>1</sub>, `y`<sub>1</sub>) and Q (`x`<sub>2</sub>, `y`<sub>2</sub>) are plotted at integer co-ordinates and are joined to the origin, O(0,0), to form ΔOPQ.
The points ${P}(x_1, y_1)$ and ${Q}(x_2, y_2)$ are plotted at integer co-ordinates and are joined to the origin, ${O}(0, 0)$, to form ${\Delta}OPQ$.
<img class="img-responsive center-block" alt="a graph plotting points P (x_1, y_1) and Q(x_2, y_2) at integer coordinates that are joined to the origin O (0, 0)" src="https://cdn-media-1.freecodecamp.org/project-euler/right-triangles-integer-coordinates-1.png" style="background-color: white; padding: 10px;" />
There are exactly fourteen triangles containing a right angle that can be formed when each co-ordinate lies between 0 and 2 inclusive; that is, 0 ≤ `x`<sub>1</sub>, `y`<sub>1</sub>, `x`<sub>2</sub>, `y`<sub>2</sub> ≤ 2.
There are exactly fourteen triangles containing a right angle that can be formed when each co-ordinate lies between 0 and 2 inclusive; that is, $0 ≤ x_1, y_1, x_2, y_2 ≤ 2$.
<img class="img-responsive center-block" alt="a diagram showing the 14 triangles containing a right angle that can be formed when each coordinate is between 0 and 2" src="https://cdn-media-1.freecodecamp.org/project-euler/right-triangles-integer-coordinates-2.png" style="background-color: white; padding: 10px;" />
Given that 0 ≤ `x`<sub>1</sub>, `y`<sub>1</sub>, `x`<sub>2</sub>, `y`<sub>2</sub> ≤ 50, how many right triangles can be formed?
Given that $0 ≤ x_1, y_1, x_2, y_2 ≤ limit$, how many right triangles can be formed?
# --hints--
`rightTrianglesIntCoords()` should return a number.
`rightTrianglesIntCoords(2)` should return a number.
```js
assert(typeof rightTrianglesIntCoords() === 'number');
assert(typeof rightTrianglesIntCoords(2) === 'number');
```
`rightTrianglesIntCoords()` should return 14234.
`rightTrianglesIntCoords(2)` should return `14`.
```js
assert.strictEqual(rightTrianglesIntCoords(), 14234);
assert.strictEqual(rightTrianglesIntCoords(2), 14);
```
`rightTrianglesIntCoords(10)` should return `448`.
```js
assert.strictEqual(rightTrianglesIntCoords(10), 448);
```
`rightTrianglesIntCoords(25)` should return `3207`.
```js
assert.strictEqual(rightTrianglesIntCoords(25), 3207);
```
`rightTrianglesIntCoords(50)` should return `14234`.
```js
assert.strictEqual(rightTrianglesIntCoords(50), 14234);
```
# --seed--
@ -37,16 +55,65 @@ assert.strictEqual(rightTrianglesIntCoords(), 14234);
## --seed-contents--
```js
function rightTrianglesIntCoords() {
function rightTrianglesIntCoords(limit) {
return true;
}
rightTrianglesIntCoords();
rightTrianglesIntCoords(2);
```
# --solutions--
```js
// solution required
function rightTrianglesIntCoords(limit) {
function isRightTriangle(points) {
for (let i = 0; i < points.length; i++) {
const pointA = points[i];
const pointB = points[(i + 1) % 3];
const pointC = points[(i + 2) % 3];
const vectorAB = [pointB[0] - pointA[0], pointB[1] - pointA[1]];
const vectorAC = [pointC[0] - pointA[0], pointC[1] - pointA[1]];
if (isRightAngleBetween(vectorAB, vectorAC)) {
return true;
}
}
return false;
}
function isRightAngleBetween(vector1, vector2) {
return vector1[0] * vector2[0] + vector1[1] * vector2[1] === 0;
}
function getSetKey(points) {
return (
'0.0,' +
points
.sort((a, b) => a[0] - b[0])
.map(point => point.join('.'))
.join(',')
);
}
const pointO = [0, 0];
const rightTriangles = new Set();
for (let x1 = 1; x1 <= limit; x1++) {
for (let y1 = 0; y1 <= limit; y1++) {
const pointP = [x1, y1];
for (let x2 = 0; x2 <= limit; x2++) {
for (let y2 = 1; y2 <= limit; y2++) {
const pointQ = [x2, y2];
if (pointP[0] === pointQ[0] && pointP[1] === pointQ[1]) {
continue;
}
if (isRightTriangle([pointO, pointP, pointQ])) {
rightTriangles.add(getSetKey([pointP, pointQ]));
}
}
}
}
}
return rightTriangles.size;
}
```

View File

@ -12,27 +12,42 @@ A number chain is created by continuously adding the square of the digits in a n
For example,
<div style='margin-left: 4em;'>
44 → 32 → 13 → 10 → <strong>1</strong><strong>1</strong><br>
85 → <strong>89</strong> → 145 → 42 → 20 → 4 → 16 → 37 → 58 → <strong>89</strong>
</div>
$$\begin{align} & 44 → 32 → 13 → 10 → \boldsymbol{1} → \boldsymbol{1}\\\\ & 85 → \boldsymbol{89} → 145 → 42 → 20 → 4 → 16 → 37 → 58 → \boldsymbol{89}\\\\ \end{align}$$
Therefore any chain that arrives at 1 or 89 will become stuck in an endless loop. What is most amazing is that EVERY starting number will eventually arrive at 1 or 89.
How many starting numbers below ten million will arrive at 89?
How many starting numbers below `limit` will arrive at 89?
# --hints--
`squareDigitChains()` should return a number.
`squareDigitChains(100)` should return a number.
```js
assert(typeof squareDigitChains() === 'number');
assert(typeof squareDigitChains(100) === 'number');
```
`squareDigitChains()` should return 8581146.
`squareDigitChains(100)` should return `80`.
```js
assert.strictEqual(squareDigitChains(), 8581146);
assert.strictEqual(squareDigitChains(100), 80);
```
`squareDigitChains(1000)` should return `857`.
```js
assert.strictEqual(squareDigitChains(1000), 857);
```
`squareDigitChains(100000)` should return `85623`.
```js
assert.strictEqual(squareDigitChains(100000), 85623);
```
`squareDigitChains(10000000)` should return `8581146`.
```js
assert.strictEqual(squareDigitChains(10000000), 8581146);
```
# --seed--
@ -40,16 +55,98 @@ assert.strictEqual(squareDigitChains(), 8581146);
## --seed-contents--
```js
function squareDigitChains() {
function squareDigitChains(limit) {
return true;
}
squareDigitChains();
squareDigitChains(100);
```
# --solutions--
```js
// solution required
function squareDigitChains(limit) {
// Based on https://www.xarg.org/puzzle/project-euler/problem-92/
function getCombinations(neededDigits, curDigits) {
if (neededDigits === curDigits.length) {
return [curDigits];
}
const combinations = [];
const lastDigit = curDigits.length !== 0 ? curDigits[0] : 9;
for (let i = 0; i <= lastDigit; i++) {
const results = getCombinations(neededDigits, [i].concat(curDigits));
combinations.push(...results);
}
return combinations;
}
function getPossibleSums(limit) {
const digitsCount = getDigits(limit).length - 1;
const possibleSquaredSums = [false];
for (let i = 1; i <= 81 * digitsCount; i++) {
let curVal = i;
while (curVal !== 1 && curVal !== 89) {
curVal = addSquaredDigits(curVal);
}
possibleSquaredSums[i] = curVal === 89;
}
return possibleSquaredSums;
}
function addSquaredDigits(num) {
const digits = getDigits(num);
let result = 0;
for (let i = 0; i < digits.length; i++) {
result += digits[i] ** 2;
}
return result;
}
function getDigits(number) {
const digits = [];
while (number > 0) {
digits.push(number % 10);
number = Math.floor(number / 10);
}
return digits;
}
function getFactorials(number) {
const factorials = [1];
for (let i = 1; i < number; i++) {
factorials[i] = factorials[i - 1] * i;
}
return factorials;
}
const neededDigits = getDigits(limit).length - 1;
const combinations = getCombinations(neededDigits, []);
const possibleSquaredDigitsSums = getPossibleSums(limit);
const factorials = getFactorials(neededDigits + 1);
let endingWith89 = 0;
for (let i = 0; i < combinations.length; i++) {
let counts = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
let digits = combinations[i];
let curSum = 0;
for (let j = 0; j < digits.length; j++) {
const curDigit = digits[j];
curSum += curDigit ** 2;
counts[curDigit]++;
}
if (possibleSquaredDigitsSums[curSum]) {
let denominator = 1;
for (let j = 0; j < counts.length; j++) {
denominator = denominator * factorials[counts[j]];
}
endingWith89 += Math.floor(
factorials[factorials.length - 1] / denominator
);
}
}
return endingWith89;
}
```

View File

@ -8,24 +8,42 @@ dashedName: problem-94-almost-equilateral-triangles
# --description--
It is easily proved that no equilateral triangle exists with integral length sides and integral area. However, the <dfn>almost equilateral triangle</dfn> 5-5-6 has an area of 12 square units.
It is easily proved that no equilateral triangle exists with integral length sides and integral area. However, the almost equilateral triangle 5-5-6 has an area of 12 square units.
We shall define an <dfn>almost equilateral triangle</dfn> to be a triangle for which two sides are equal and the third differs by no more than one unit.
Find the sum of the perimeters of all <dfn>almost equilateral triangle</dfn> with integral side lengths and area and whose perimeters do not exceed one billion (1,000,000,000).
Find the sum of the perimeters of all almost equilateral triangles with integral side lengths and area and whose perimeters do not exceed `limit`.
# --hints--
`almostEquilateralTriangles()` should return a number.
`almostEquilateralTriangles(50)` should return a number.
```js
assert(typeof almostEquilateralTriangles() === 'number');
assert(typeof almostEquilateralTriangles(50) === 'number');
```
`almostEquilateralTriangles()` should return 518408346.
`almostEquilateralTriangles(50)` should return `66`.
```js
assert.strictEqual(almostEquilateralTriangles(), 518408346);
assert.strictEqual(almostEquilateralTriangles(50), 66);
```
`almostEquilateralTriangles(10000)` should return `3688`.
```js
assert.strictEqual(almostEquilateralTriangles(10000), 3688);
```
`almostEquilateralTriangles(10000000)` should return `9973078`.
```js
assert.strictEqual(almostEquilateralTriangles(10000000), 9973078);
```
`almostEquilateralTriangles(1000000000)` should return `518408346`.
```js
assert.strictEqual(almostEquilateralTriangles(1000000000), 518408346);
```
# --seed--
@ -33,16 +51,34 @@ assert.strictEqual(almostEquilateralTriangles(), 518408346);
## --seed-contents--
```js
function almostEquilateralTriangles() {
function almostEquilateralTriangles(limit) {
return true;
}
almostEquilateralTriangles();
almostEquilateralTriangles(50);
```
# --solutions--
```js
// solution required
function almostEquilateralTriangles(limit) {
// Based on https://blog.dreamshire.com/project-euler-94-solution/
let perimetersSum = 0;
let sidesAB = 1;
let sideC = 1;
let perimeter = 0;
let perimeterOffset = 1;
while (perimeter <= limit) {
[sidesAB, sideC] = [4 * sidesAB - sideC + 2 * perimeterOffset, sidesAB];
perimeterOffset = -perimeterOffset;
perimetersSum += perimeter;
perimeter = 3 * sidesAB - perimeterOffset;
}
return perimetersSum;
}
```

View File

@ -14,26 +14,42 @@ Interestingly the sum of the proper divisors of 220 is 284 and the sum of the pr
Perhaps less well known are longer chains. For example, starting with 12496, we form a chain of five numbers:
<div style="text-align: center;">
12496 → 14288 → 15472 → 14536 → 14264 (→ 12496 → ...)
</div>
$$ 12496 → 14288 → 15472 → 14536 → 14264 \\,(→ 12496 → \cdots) $$
Since this chain returns to its starting point, it is called an amicable chain.
Find the smallest member of the longest amicable chain with no element exceeding one million.
Find the smallest member of the longest amicable chain with no element exceeding `limit`.
# --hints--
`amicableChains()` should return a number.
`amicableChains(300)` should return a number.
```js
assert(typeof amicableChains() === 'number');
assert(typeof amicableChains(300) === 'number');
```
`amicableChains()` should return 14316.
`amicableChains(300)` should return `220`.
```js
assert.strictEqual(amicableChains(), 14316);
assert.strictEqual(amicableChains(300), 220);
```
`amicableChains(15000)` should return `220`.
```js
assert.strictEqual(amicableChains(15000), 220);
```
`amicableChains(100000)` should return `12496`.
```js
assert.strictEqual(amicableChains(100000), 12496);
```
`amicableChains(1000000)` should return `14316`.
```js
assert.strictEqual(amicableChains(1000000), 14316);
```
# --seed--
@ -41,16 +57,68 @@ assert.strictEqual(amicableChains(), 14316);
## --seed-contents--
```js
function amicableChains() {
function amicableChains(limit) {
return true;
}
amicableChains();
amicableChains(300);
```
# --solutions--
```js
// solution required
function amicableChains(limit) {
function getSmallestMember(chain) {
let smallest = chain[0];
for (let i = 1; i < chain.length; i++) {
if (smallest > chain[i]) {
smallest = chain[i];
}
}
return smallest;
}
function getFactorsSums(limit) {
const factorsSums = new Array(limit + 1).fill(1);
for (let i = 2; i <= limit / 2; i++) {
for (let j = 2 * i; j <= limit; j += i) {
factorsSums[j] += i;
}
}
return factorsSums;
}
const factorsSums = getFactorsSums(limit);
const checkedNumbers = new Set();
let longestChain = 0;
let smallestMember = 0;
for (let i = 0; i <= limit; i++) {
const curChain = [];
let curNumber = i;
while (!checkedNumbers.has(curNumber) && factorsSums[curNumber] <= limit) {
curNumber = factorsSums[curNumber];
const chainStart = curChain.indexOf(curNumber);
if (chainStart === -1) {
curChain.push(curNumber);
continue;
}
const chainLength = curChain.length - chainStart;
if (chainLength > longestChain) {
longestChain = chainLength;
smallestMember = getSmallestMember(curChain.slice(chainStart));
}
break;
}
for (let j = 0; j < curChain.length; j++) {
checkedNumbers.add(curChain[j]);
}
}
return smallestMember;
}
```

View File

@ -102,49 +102,42 @@ Su Doku (Japanese meaning *number place*) is the name given to a popular puzzle
A well constructed Su Doku puzzle has a unique solution and can be solved by logic, although it may be necessary to employ "guess and test" methods in order to eliminate options (there is much contested opinion over this). The complexity of the search determines the difficulty of the puzzle; the example above is considered easy because it can be solved by straight forward direct deduction.
The `puzzlesArr` array contains fifty different Su Doku puzzle strings ranging in difficulty, but all with unique solutions (the first puzzle in the array is the example in the challenge description).
The `puzzlesArr` array contains different Su Doku puzzle strings ranging in difficulty, but all with unique solutions.
By solving all fifty puzzles find the sum of the 3-digit numbers found in the top left corner of each solution grid; for example, 483 is the 3-digit number found in the top left corner of the solution grid above.
By solving all puzzles in `puzzlesArr`, find the sum of the 3-digit numbers found in the top left corner of each solution grid; for example, 483 is the 3-digit number found in the top left corner of the solution grid above.
# --hints--
`suDoku(testPuzzles)` should return a number.
`suDoku(testPuzzles1)` should return a number.
```js
assert(typeof suDoku(testPuzzles) === 'number');
assert(typeof suDoku(_testPuzzles1) === 'number');
```
`suDoku(testPuzzles)` should return 1190.
`suDoku(testPuzzles1)` should return `1190`.
```js
assert.strictEqual(suDoku(testPuzzles), 1190);
assert.strictEqual(suDoku(_testPuzzles1), 1190);
```
`suDoku(puzzlesArr)` should return 24702.
`suDoku(testPuzzles2)` should return `24702`.
```js
assert.strictEqual(suDoku(puzzlesArr), 24702);
assert.strictEqual(suDoku(_testPuzzles2), 24702);
```
# --seed--
## --seed-contents--
## --after-user-code--
```js
function suDoku(arr) {
return true;
}
// Only change code above this line
const testPuzzles = [
const _testPuzzles1 = [
'003020600900305001001806400008102900700000008006708200002609500800203009005010300',
'200080300060070084030500209000105408000000000402706000301007040720040060004010003',
'000000907000420180000705026100904000050000040000507009920108000034059000507000000'
];
const puzzlesArr = [
const _testPuzzles2 = [
'003020600900305001001806400008102900700000008006708200002609500800203009005010300',
'200080300060070084030500209000105408000000000402706000301007040720040060004010003',
'000000907000420180000705026100904000050000040000507009920108000034059000507000000',
@ -196,12 +189,108 @@ const puzzlesArr = [
'000003017015009008060000000100007000009000200000500004000000020500600340340200000',
'300200000000107000706030500070009080900020004010800050009040301000702000000008006'
];
```
suDoku(testPuzzles);
## --seed-contents--
```js
function suDoku(puzzlesArr) {
return true;
}
// Only change code above this line
const testPuzzles1 = [
'003020600900305001001806400008102900700000008006708200002609500800203009005010300',
'200080300060070084030500209000105408000000000402706000301007040720040060004010003',
'000000907000420180000705026100904000050000040000507009920108000034059000507000000'
];
suDoku(testPuzzles1);
```
# --solutions--
```js
// solution required
function suDoku(puzzlesArr) {
function solve(puzzle) {
for (let row = 0; row < 9; row++) {
for (let col = 0; col < 9; col++) {
if (puzzle[row][col] > 0) {
continue;
}
const allowedNumbers = getAllowedNumbers(puzzle, row, col);
for (let number = 1; number <= 9; number++) {
if (allowedNumbers[number]) {
puzzle[row][col] = number;
if (solve(puzzle)) {
return true;
}
}
}
puzzle[row][col] = 0;
return false;
}
}
return true;
}
function getAllowedNumbers(puzzle, row, col) {
const allowed = new Array(10).fill(true);
allowed[0] = false;
for (let i = 0; i < 9; i++) {
const numberInSameRow = puzzle[row][i];
if (numberInSameRow > 0) {
allowed[numberInSameRow] = false;
}
const numberInSameCol = puzzle[i][col];
if (numberInSameCol > 0) {
allowed[numberInSameCol] = false;
}
}
const rowOfSubGrid = Math.floor(row / 3) * 3;
const colOfSubGrid = Math.floor(col / 3) * 3;
for (let rowInSubGrid = 0; rowInSubGrid < 3; rowInSubGrid++) {
for (let colInSubGrid = 0; colInSubGrid < 3; colInSubGrid++) {
const numberInSameSubGrid =
puzzle[rowOfSubGrid + rowInSubGrid][colOfSubGrid + colInSubGrid];
if (numberInSameSubGrid > 0) {
allowed[numberInSameSubGrid] = false;
}
}
}
return allowed;
}
function parsePuzzle(string) {
const puzzle = [];
for (let row = 0; row < 9; row++) {
puzzle.push(
string
.slice(row * 9, 9 + row * 9)
.split('')
.map(x => parseInt(x, 10))
);
}
return puzzle;
}
let sum = 0;
for (let i = 0; i < puzzlesArr.length; i++) {
const puzzle = parsePuzzle(puzzlesArr[i]);
if (solve(puzzle)) {
sum += 100 * puzzle[0][0] + 10 * puzzle[0][1] + puzzle[0][2];
}
}
return sum;
}
```

View File

@ -8,24 +8,42 @@ dashedName: problem-97-large-non-mersenne-prime
# --description--
The first known prime found to exceed one million digits was discovered in 1999, and is a Mersenne prime of the form 2<sup>6972593</sup>1; it contains exactly 2,098,960 digits. Subsequently other Mersenne primes, of the form 2<sup><var>p</var></sup>1, have been found which contain more digits.
The first known prime found to exceed one million digits was discovered in 1999, and is a Mersenne prime of the form $2^{6972593} 1$; it contains exactly 2,098,960 digits. Subsequently other Mersenne primes, of the form $2^p 1$, have been found which contain more digits.
However, in 2004 there was found a massive non-Mersenne prime which contains 2,357,207 digits: 28433×2<sup>7830457</sup>+1.
However, in 2004 there was found a massive non-Mersenne prime which contains 2,357,207 digits: $28433 × 2^{7830457} + 1$.
Find the last ten digits of this prime number.
Find the last ten digits of that non-Mersenne prime in the form $multiplier × 2^{power} + 1$.
# --hints--
`lrgNonMersennePrime()` should return a number.
`largeNonMersennePrime(19, 6833086)` should return a string.
```js
assert(typeof lrgNonMersennePrime() === 'number');
assert(typeof largeNonMersennePrime(19, 6833086) === 'string');
```
`lrgNonMersennePrime()` should return 8739992577.
`largeNonMersennePrime(19, 6833086)` should return the string `3637590017`.
```js
assert.strictEqual(lrgNonMersennePrime(), 8739992577);
assert.strictEqual(largeNonMersennePrime(19, 6833086), '3637590017');
```
`largeNonMersennePrime(27, 7046834)` should return the string `0130771969`.
```js
assert.strictEqual(largeNonMersennePrime(27, 7046834), '0130771969');
```
`largeNonMersennePrime(6679881, 6679881)` should return the string `4455386113`.
```js
assert.strictEqual(largeNonMersennePrime(6679881, 6679881), '4455386113');
```
`largeNonMersennePrime(28433, 7830457)` should return the string `8739992577`.
```js
assert.strictEqual(largeNonMersennePrime(28433, 7830457), '8739992577');
```
# --seed--
@ -33,16 +51,38 @@ assert.strictEqual(lrgNonMersennePrime(), 8739992577);
## --seed-contents--
```js
function lrgNonMersennePrime() {
function largeNonMersennePrime(multiplier, power) {
return true;
}
lrgNonMersennePrime();
largeNonMersennePrime(19, 6833086);
```
# --solutions--
```js
// solution required
function largeNonMersennePrime(multiplier, power) {
function modStepsResults(number, other, mod, startValue, step) {
let result = startValue;
for (let i = 0; i < other; i++) {
result = step(number, result) % mod;
}
return result;
}
const numOfDigits = 10;
const mod = 10 ** numOfDigits;
const digitsAfterPower = modStepsResults(2, power, mod, 1, (a, b) => a * b);
const digitsAfterMultiply = modStepsResults(
digitsAfterPower,
multiplier,
mod,
0,
(a, b) => a + b
);
const lastDigits = (digitsAfterMultiply + 1) % mod;
return lastDigits.toString().padStart(10, '0');
}
```

View File

@ -8,7 +8,7 @@ dashedName: abundant-deficient-and-perfect-number-classifications
# --description--
These define three classifications of positive integers based on their [proper divisors](https://rosettacode.org/wiki/Proper divisors "Proper divisors").
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.
@ -22,7 +22,7 @@ If `P(n) > n` then `n` is classed as `abundant`
# --instructions--
Implement a function that calculates how many of the integers from `1` to `20,000` (inclusive) are in each of the three classes. Output the result as an array in the following format `[deficient, perfect, abundant]`.
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--
@ -32,32 +32,38 @@ Implement a function that calculates how many of the integers from `1` to `20,00
assert(typeof getDPA === 'function');
```
`getDPA` should return an array.
`getDPA(5000)` should return an array.
```js
assert(Array.isArray(getDPA(100)));
assert(Array.isArray(getDPA(5000)));
```
`getDPA` return value should have a length of 3.
`getDPA(5000)` return array should have a length of `3`.
```js
assert(getDPA(100).length === 3);
assert(getDPA(5000).length === 3);
```
`getDPA(20000)` should equal [15043, 4, 4953]
`getDPA(5000)` should return `[3758, 3, 1239]`.
```js
assert.deepEqual(getDPA(20000), solution);
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--
## --after-user-code--
```js
const solution = [15043, 4, 4953];
```
## --seed-contents--
```js

View File

@ -8,35 +8,43 @@ dashedName: align-columns
# --description--
Given a text file of many lines, where fields within a line are delineated by a single `$` character, write a program that aligns each column of fields by ensuring that words in each column are separated by at least one space. Further, allow for each word in a column to be either left justified, right justified, or center justified within its column.
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:
<pre>
Given$a$text$file$of$many$lines
where$fields$within$a$line$
are$delineated$by$a$single$'dollar'$character
write$a$program
that$aligns$each$column$of$fields
by$ensuring$that$words$in$each$
column$are$separated$by$at$least$one$space.
Further,$allow$for$each$word$in$a$column$to$be$either$left$
justified,$right$justified
or$center$justified$within$its$column.
</pre>
```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:**
<ul>
<li>The example input texts lines may, or may not, have trailing dollar characters.</li>
<li>All columns should share the same alignment.</li>
<li>Consecutive space characters produced adjacent to the end of lines are insignificant for the purposes of the task.</li>
<li>Output text will be viewed in a mono-spaced font on a plain text editor or basic terminal.</li>
<li>The minimum space between columns should be computed from the text and not hard-coded.</li>
<li>It is not a requirement to add separating characters between or around columns.</li>
</ul>
- 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--
@ -46,22 +54,22 @@ or$center$justified$within$its$column.
assert(typeof formatText === 'function');
```
`formatText` with the above input and "right" justification should produce the following:
`formatText(testText, 'right')` should produce text with columns justified to the right.
```js
assert.strictEqual(formatText(testInput, 'right'), rightAligned);
assert.strictEqual(formatText(_testText, 'right'), rightAligned);
```
`formatText` with the above input and "left" justification should produce the following:
`formatText(testText, 'left')` should produce text with columns justified to the left.
```js
assert.strictEqual(formatText(testInput, 'left'), leftAligned);
assert.strictEqual(formatText(_testText, 'left'), leftAligned);
```
`formatText` with the above input and "center" justification should produce the following:
`formatText(testText, 'center')` should produce text with columns justified to the center.
```js
assert.strictEqual(formatText(testInput, 'center'), centerAligned);
assert.strictEqual(formatText(_testText, 'center'), centerAligned);
```
# --seed--
@ -69,10 +77,10 @@ assert.strictEqual(formatText(testInput, 'center'), centerAligned);
## --after-user-code--
```js
const testInput = [
const _testText = [
'Given$a$text$file$of$many$lines',
'where$fields$within$a$line$',
'are$delineated$by$a$single$\"dollar\"$character',
'are$delineated$by$a$single$"dollar"$character',
'write$a$program',
'that$aligns$each$column$of$fields$',
'by$ensuring$that$words$in$each$',
@ -119,7 +127,11 @@ const centerAligned = ' Given a text file of many
## --seed-contents--
```js
const testArr = [
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',
@ -131,28 +143,11 @@ const testArr = [
'justified,$right$justified',
'or$center$justified$within$its$column.'
];
function formatText(input, justification) {
}
```
# --solutions--
```js
const testArr = [
'Given$a$text$file$of$many$lines',
'where$fields$within$a$line$',
'are$delineated$by$a$single$"dollar"$character',
'write$a$program',
'that$aligns$each$column$of$fields$',
'by$ensuring$that$words$in$each$',
'column$are$separated$by$at$least$one$space.',
'Further,$allow$for$each$word$in$a$column$to$be$either$left$',
'justified,$right$justified',
'or$center$justified$within$its$column.'
];
String.prototype.repeat = function (n) { return new Array(1 + parseInt(n)).join(this); };
function formatText(input, justification) {

View File

@ -8,9 +8,9 @@ dashedName: closest-pair-problem
# --description--
Provide a function to find the closest two points among a set of given points in two dimensions, i.e. to solve the [Closest pair of points problem](https://en.wikipedia.org/wiki/Closest pair of points problem "wp: Closest pair of points problem") in the *planar* case.
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<sup>2</sup>) algorithm (which we can call *brute-force algorithm*); the pseudo-code (using indexes) could be simply:
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>
@ -30,7 +30,7 @@ The straightforward solution is a O(n<sup>2</sup>) algorithm (which we can call
<strong>endif</strong>
</pre>
A better algorithm is based on the recursive divide and conquer approach, as explained also at [Wikipedia's Closest pair of points problem](https://en.wikipedia.org/wiki/Closest pair of points problem#Planar_case "wp: Closest pair of points problem#Planar_case"), which is `O(nlog(n))` a pseudo-code could be:
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
@ -65,16 +65,38 @@ A better algorithm is based on the recursive divide and conquer approach, as exp
<strong>endif</strong>
</pre>
For the input, expect the argument to be an array of objects (points) with `x` and `y` members set to numbers. For the output, return an object containing the key:value pairs for `distance` and `pair` (the pair of two closest points).
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).
**References and further readings:**
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.
<ul>
<li><a href='https://en.wikipedia.org/wiki/Closest pair of points problem' title='wp: Closest pair of points problem' target='_blank'>Closest pair of points problem</a></li>
<li><a href='https://www.cs.mcgill.ca/~cs251/ClosestPair/ClosestPairDQ.html' target='_blank'>Closest Pair (McGill)</a></li>
<li><a href='https://www.cs.ucsb.edu/~suri/cs235/ClosestPair.pdf' target='_blank'>Closest Pair (UCSB)</a></li>
<li><a href='https://classes.cec.wustl.edu/~cse241/handouts/closestpair.pdf' target='_blank'>Closest pair (WUStL)</a></li>
</ul>
# --hints--
@ -84,13 +106,13 @@ For the input, expect the argument to be an array of objects (points) with `x` a
assert(typeof getClosestPair === 'function');
```
Distance should be the following.
`getClosestPair(points1).distance` should be `0.0894096443343775`.
```js
assert.equal(getClosestPair(points1).distance, answer1.distance);
```
Points should be the following.
`getClosestPair(points1).pair` should be `[ { x: 7.46489, y: 4.6268 }, { x: 7.46911, y: 4.71611 } ]`.
```js
assert.deepEqual(
@ -99,13 +121,13 @@ assert.deepEqual(
);
```
Distance should be the following.
`getClosestPair(points2).distance` should be `65.06919393998976`.
```js
assert.equal(getClosestPair(points2).distance, answer2.distance);
```
Points should be the following.
`getClosestPair(points2).pair` should be `[ { x: 37134, y: 1963 }, { x: 37181, y: 2008 } ]`.
```js
assert.deepEqual(
@ -114,6 +136,21 @@ assert.deepEqual(
);
```
`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--
@ -132,14 +169,6 @@ const points1 = [
new Point(1.45428, 0.087596)
];
const points2 = [
new Point(37100, 13118),
new Point(37134, 1963),
new Point(37181, 2008),
new Point(37276, 21611),
new Point(37307, 9320)
];
const answer1 = {
distance: 0.0894096443343775,
pair: [
@ -154,6 +183,14 @@ const answer1 = {
]
};
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: [
@ -168,8 +205,8 @@ const answer2 = {
]
};
const benchmarkPoints = [
new Point(16909, 54699),
const points3 = [
new Point(16910, 54699),
new Point(14773, 61107),
new Point(95547, 45344),
new Point(95951, 17573),
@ -196,7 +233,7 @@ const benchmarkPoints = [
new Point(70721, 66707),
new Point(31863, 9837),
new Point(49358, 30795),
new Point(13041, 39745),
new Point(13041, 39744),
new Point(59635, 26523),
new Point(25859, 1292),
new Point(1551, 53890),
@ -220,6 +257,20 @@ const benchmarkPoints = [
new Point(51090, 52158),
new Point(48953, 58567)
];
const answer3 = {
distance: 6754.625082119658,
pair: [
{
x: 46817,
y: 64975
},
{
x: 48953,
y: 58567
}
]
}
```
## --seed-contents--
@ -347,7 +398,7 @@ const closestPair = function _closestPair(Px, Py) {
return {
distance: minDelta,
pair: closestPair
pair: closestPair.sort((pointA, pointB) => pointA.x - pointB.x)
};
};

View File

@ -22,7 +22,7 @@ Demonstrate that it passes the following three test-cases:
| Input number | Output number |
| ------------ | ------------------------- |
| 7259 | <code>2 hr, 59 sec</code> |
| 728640059 | <code>1 d</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>

View File

@ -30,7 +30,7 @@ There are four types of common coins in [US](https://en.wikipedia.org/wiki/Unite
# --instructions--
Implement a function to determine how many ways there are to make change for a dollar using these common coins (1 dollar = 100 cents)
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--
@ -40,10 +40,22 @@ Implement a function to determine how many ways there are to make change for a d
assert(typeof countCoins === 'function');
```
`countCoins()` should return 242.
`countCoins(15)` should return `6`.
```js
assert.equal(countCoins(), 242);
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--
@ -51,7 +63,7 @@ assert.equal(countCoins(), 242);
## --seed-contents--
```js
function countCoins() {
function countCoins(cents) {
return true;
}
@ -60,12 +72,11 @@ function countCoins() {
# --solutions--
```js
function countCoins() {
let t = 100;
function countCoins(cents) {
const operands = [1, 5, 10, 25];
const targetsLength = t + 1;
const targetsLength = cents + 1;
const operandsLength = operands.length;
t = [1];
const t = [1];
for (let a = 0; a < operandsLength; a++) {
for (let b = 1; b < targetsLength; b++) {

View File

@ -13,51 +13,82 @@ A given rectangle is made from *m* × *n* squares. If *m* and *n* are not both o
<div style="width: 100%; text-align: center;">
<svg xmlns="https://www.w3.org/2000/svg" xmlns:xlink="https://www.w3.org/1999/xlink" width="520" height="170" aria-hidden="true" alt="Diagram showing the possible paths for 2 by 2 and 4 by 3 rectangles">
<style>
.g { fill: none; stroke: #ccc }
.s, .s2 { fill: #bff; stroke: black; fill-opacity: .4 }
.s2 { fill: #fbf }
.d { stroke:black; fill:none}
.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="m">
<g id="h4"><g id="h2">
<path id="h" d="m0 10h 640" class="g"/>
<use xlink:href="#h" transform="translate(0,20)"/></g>
<use xlink:href="#h2" transform="translate(0, 40)"/></g>
<use xlink:href="#h4" transform="translate(0,80)"/>
<g id="v8"><g id="v4"><g id="v2">
<path id="v" d="m10 0v160 m 20 0 v-160" class="g"/>
<use xlink:href="#v" transform="translate(40,0)"/></g>
<use xlink:href="#v2" transform="translate(80,0)"/></g>
<use xlink:href="#v4" transform="translate(160,0)"/></g>
<use xlink:href="#v8" transform="translate(320,0)"/></g>
<path id="b" d="m0 0h80v60h-80z" class="s"/>
<defs>
<g 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="#m"/>
<g transform="translate(10,10)">
<path d="m0 0v40h40v-40z" class="s2"/><path d="m20 0v40" class="d"/>
<path d="m60 0v40h40v-40z" class="s2"/><path d="m60 20h40" class="d"/>
<g transform="translate(120, 0)">
<use xlink:href="#b"/><path d="m0 20h40v20h40" class="d"/></g>
<g transform="translate(220, 0)">
<use xlink:href="#b"/><path d="m0 40h40v-20h40" class="d"/></g>
<g transform="translate(320, 0)">
<use xlink:href="#b"/><path d="m20 0v40h20v-20h20v40" class="d"/></g>
<g transform="translate(420, 0)">
<use xlink:href="#b"/><path d="m60 0v40h-20v-20h-20v40" class="d"/></g>
<g transform="translate(20, 80)">
<use xlink:href="#b"/><path d="m40 0v60" class="d"/></g>
<g transform="translate(120, 80)">
<use xlink:href="#b"/><path d="m60 0v20h-20v20h-20v20" class="d"/></g>
<g transform="translate(220, 80)">
<use xlink:href="#b"/><path d="m20 0v20h20v20h20v20" class="d"/></g>
<g transform="translate(320, 80)">
<use xlink:href="#b"/><path d="m0 20h20v20h20v-20h20v20h20" class="d"/></g>
<g transform="translate(420, 80)">
<use xlink:href="#b"/><path d="m0 40h20v-20h20v20h20v-20h20" class="d"/></g>
</g></g>
</svg>
</div>
<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--

View File

@ -8,14 +8,20 @@ dashedName: date-format
# --description--
Return an array with the current date in the formats:
Return an array with two date strings of the current date with the following specifications:
<ul>
<li>2007-11-23</li>
<li>Friday, November 23, 2007</li>
</ul>
- 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 output: `['2007-11-23', 'Friday, November 23, 2007']`
Example outputs:
```js
['2007-11-23', 'Friday, November 23, 2007']
['2021-3-2', 'Tuesday, March 2, 2021']
```
# --hints--

View File

@ -82,7 +82,7 @@ assert.deepEqual(emirps([7700, 8000], true), [
]);
```
`emirps([7700,8000],true)` should return `11`
`emirps([7700,8000],false)` should return `11`
```js
assert.deepEqual(emirps([7700, 8000], false), 11);

View File

@ -40,13 +40,7 @@ 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.`
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:**
@ -61,13 +55,7 @@ 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.`
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:**
@ -86,13 +74,7 @@ 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.`
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:**
@ -128,13 +110,7 @@ _1 -> 1
_+_ ->
</pre>
Sample text of:
`_1111*11111_`
should generate the output:
`11111111111111111111`
Sample text of `_1111*11111_` should generate the output `11111111111111111111`
**Ruleset 5:**
@ -164,13 +140,7 @@ B1 -> 1B
1C1 -> H11
</pre>
This ruleset should turn
`000000A000000`
into
`00011H1111000`
This ruleset should turn `000000A000000` into `00011H1111000`
# --hints--

View File

@ -54,7 +54,7 @@ As in other trial division algorithms, the algorithm stops when `2kP+1 > sqrt(N)
# --instructions--
Using the above method find a factor of <code>2<sup>929</sup>-1</code> (aka M929)
Using the above method find a factor of <code>2<sup>p</sup>-1</code>.
# --hints--
@ -70,19 +70,19 @@ assert(typeof check_mersenne === 'function');
assert(typeof check_mersenne(3) == 'string');
```
`check_mersenne(3)` should return "M3 = 2^3-1 is prime".
`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 "M23 = 2^23-1 is composite with factor 47".
`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 "M929 = 2^929-1 is composite with factor 13007
`check_mersenne(929)` should return the string `M929 = 2^929-1 is composite with factor 13007`.
```js
assert.equal(

View File

@ -10,29 +10,18 @@ dashedName: hailstone-sequence
The Hailstone sequence of numbers can be generated from a starting positive integer, `n` by:
<ul>
<li>If <code>n</code> is <code>1</code> then the sequence ends</li>
<li>If <code>n</code> is <code>even</code> then the next <code>n</code> of the sequence <code>= n/2</code></li>
<li>If <code>n</code> is <code>odd</code> then the next <code>n</code> of the sequence <code>= (3 * n) + 1</code></li>
</ul>
- If `n` is `1` then the sequence ends
- If `n` is `even` then the next `n` of the sequence `= n/2`
- If `n` is `odd` then the next `n` of the sequence `= (3 * n) + 1`
The (unproven) [Collatz conjecture](https://en.wikipedia.org/wiki/Collatz conjecture "wp: Collatz conjecture") is that the hailstone sequence for any starting number always terminates.
The (unproven) Collatz conjecture is that the hailstone sequence for any starting number always terminates.
The hailstone sequence is also known as hailstone numbers (because the values are usually subject to multiple descents and ascents like hailstones in a cloud), or as the Collatz sequence.
# --instructions--
<ol>
<li>Create a routine to generate the hailstone sequence for a number</li>
<li>Use the routine to show that the hailstone sequence for the number 27 has 112 elements starting with <code>27, 82, 41, 124</code> and ending with <code>8, 4, 2, 1</code></li>
<li>Show the number less than 100,000 which has the longest hailstone sequence together with that sequence's length. (But don't show the actual sequence!)</li>
</ol>
**See also:**
<ul>
<li><a href='https://xkcd.com/710' target='_blank'>xkcd</a> (humourous).</li>
</ul>
1. Create a routine to generate the hailstone sequence for a number
2. Your function should return an array with the number less than `limit` which has the longest hailstone sequence and that sequence's length. (But don't show the actual sequence!)
# --hints--
@ -42,24 +31,36 @@ The hailstone sequence is also known as hailstone numbers (because the values ar
assert(typeof hailstoneSequence === 'function');
```
`hailstoneSequence()` should return `[[27,82,41,124,8,4,2,1], [351, 77031]]`
`hailstoneSequence(30)` should return an array.
```js
assert.deepEqual(hailstoneSequence(), res);
assert(Array.isArray(hailstoneSequence(30)));
```
`hailstoneSequence(30)` should return `[27, 112]`.
```js
assert.deepEqual(hailstoneSequence(30), [27, 112]);
```
`hailstoneSequence(50000)` should return `[35655, 324]`.
```js
assert.deepEqual(hailstoneSequence(50000), [35655, 324]);
```
`hailstoneSequence(100000)` should return `[77031, 351]`.
```js
assert.deepEqual(hailstoneSequence(100000), [77031, 351]);
```
# --seed--
## --after-user-code--
```js
const res = [[27, 82, 41, 124, 8, 4, 2, 1], [351, 77031]];
```
## --seed-contents--
```js
function hailstoneSequence() {
function hailstoneSequence(limit) {
const res = [];
@ -70,9 +71,7 @@ function hailstoneSequence() {
# --solutions--
```js
function hailstoneSequence () {
const res = [];
function hailstoneSequence (limit) {
function hailstone(n) {
const seq = [n];
while (n > 1) {
@ -82,13 +81,9 @@ function hailstoneSequence () {
return seq;
}
const h = hailstone(27);
const hLen = h.length;
res.push([...h.slice(0, 4), ...h.slice(hLen - 4, hLen)]);
let n = 0;
let max = 0;
for (let i = 100000; --i;) {
for (let i = limit; --i;) {
const seq = hailstone(i);
const sLen = seq.length;
@ -97,8 +92,7 @@ function hailstoneSequence () {
max = sLen;
}
}
res.push([max, n]);
return res;
return [n, max];
}
```

View File

@ -30,67 +30,67 @@ assert(typeof happy === 'function');
assert(typeof happy(1) === 'boolean');
```
`happy(1)` should return true.
`happy(1)` should return `true`.
```js
assert(happy(1));
```
`happy(2)` should return false.
`happy(2)` should return `false`.
```js
assert(!happy(2));
```
`happy(7)` should return true.
`happy(7)` should return `true`.
```js
assert(happy(7));
```
`happy(10)` should return true.
`happy(10)` should return `true`.
```js
assert(happy(10));
```
`happy(13)` should return true.
`happy(13)` should return `true`.
```js
assert(happy(13));
```
`happy(19)` should return true.
`happy(19)` should return `true`.
```js
assert(happy(19));
```
`happy(23)` should return true.
`happy(23)` should return `true`.
```js
assert(happy(23));
```
`happy(28)` should return true.
`happy(28)` should return `true`.
```js
assert(happy(28));
```
`happy(31)` should return true.
`happy(31)` should return `true`.
```js
assert(happy(31));
```
`happy(32)` should return true:.
`happy(32)` should return `true`.
```js
assert(happy(32));
```
`happy(33)` should return false.
`happy(33)` should return `false`.
```js
assert(!happy(33));

View File

@ -10,7 +10,7 @@ dashedName: harshad-or-niven-series
The Harshad or Niven numbers are positive integers ≥ 1 that are divisible by the sum of their digits.
For example, `42` is a [Harshad number](https://rosettacode.org/wiki/Harshad_or_Niven_series "Harshad or Niven series") as `42` is divisible by `(4 + 2)` without remainder.
For example, `42` is a Harshad number as `42` is divisible by `(4 + 2)` without remainder.
Assume that the series is defined as the numbers in increasing order.
@ -18,7 +18,7 @@ Assume that the series is defined as the numbers in increasing order.
Implement a function to generate successive members of the Harshad sequence.
Use it to list the first twenty members of the sequence and list the first Harshad number greater than 1000.
Use it to return an array with ten members of the sequence, starting with first Harshad number greater than `n`.
# --hints--
@ -28,32 +28,31 @@ Use it to list the first twenty members of the sequence and list the first Harsh
assert(typeof isHarshadOrNiven === 'function');
```
`isHarshadOrNiven()` should return `{"firstTwenty": [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 12, 18, 20, 21, 24, 27, 30, 36, 40, 42],"firstOver1000": 1002}`
`isHarshadOrNiven(10)` should return `[12, 18, 20, 21, 24, 27, 30, 36, 40, 42]`
```js
assert.deepEqual(isHarshadOrNiven(), res);
assert.deepEqual(isHarshadOrNiven(10), [12, 18, 20, 21, 24, 27, 30, 36, 40, 42]);
```
`isHarshadOrNiven(400)` should return `[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)` should return `[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--
## --after-user-code--
```js
const res = {
firstTwenty: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 12, 18, 20, 21, 24, 27, 30, 36, 40, 42],
firstOver1000: 1002
};
```
## --seed-contents--
```js
function isHarshadOrNiven() {
const res = {
firstTwenty: [],
firstOver1000: undefined
};
// Only change code below this line
function isHarshadOrNiven(n) {
const res = [];
return res;
}
@ -62,37 +61,27 @@ function isHarshadOrNiven() {
# --solutions--
```js
function isHarshadOrNiven() {
const res = {
firstTwenty: [],
firstOver1000: undefined
};
function isHarshad(n) {
function isHarshadOrNiven(n) {
function isHarshad(num) {
let s = 0;
const nStr = n.toString();
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;
const harshads = [];
for (let n = 1; count < 20; ++n) {
while (count < 10) {
n++;
if (isHarshad(n)) {
count++;
harshads.push(n);
res.push(n);
}
}
res.firstTwenty = harshads;
let h = 1000;
while (!isHarshad(++h));
res.firstOver1000 = h;
return res;
}
```

View File

@ -42,34 +42,34 @@ assert(typeof josephus == 'function');
assert(typeof josephus(30, 3) == 'number');
```
`josephus(30,3)` should return `29`.
`josephus(30,3)` should return `28`.
```js
assert.equal(josephus(30, 3), 29);
assert.equal(josephus(30, 3), 28);
```
`josephus(30,5)` should return `3`.
`josephus(30,5)` should return `2`.
```js
assert.equal(josephus(30, 5), 3);
assert.equal(josephus(30, 5), 2);
```
`josephus(20,2)` should return `9`.
`josephus(20,2)` should return `8`.
```js
assert.equal(josephus(20, 2), 9);
assert.equal(josephus(20, 2), 8);
```
`josephus(17,6)` should return `2`.
`josephus(17,6)` should return `1`.
```js
assert.equal(josephus(17, 6), 2);
assert.equal(josephus(17, 6), 1);
```
`josephus(29,4)` should return `2`.
`josephus(29,4)` should return `1`.
```js
assert.equal(josephus(29, 4), 2);
assert.equal(josephus(29, 4), 1);
```
# --seed--
@ -86,36 +86,13 @@ function josephus(init, kill) {
```js
function josephus(init, kill) {
var Josephus = {
init: function(n) {
this.head = {};
var current = this.head;
for (var i = 0; i < n - 1; i++) {
current.label = i + 1;
current.next = {
prev: current
};
current = current.next;
}
current.label = n;
current.next = this.head;
this.head.prev = current;
return this;
},
kill: function(spacing) {
var current = this.head;
while (current.next !== current) {
for (var i = 0; i < spacing - 1; i++) {
current = current.next;
}
current.prev.next = current.next;
current.next.prev = current.prev;
current = current.next;
}
return current.label;
}
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 Josephus.init(init).kill(kill)
return arr[0];
}
```

View File

@ -73,7 +73,7 @@ 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)` should return `75300`.
`knapsackUnbounded([{ name:"panacea", value:3000, weight:0.3, volume:0.025 }, { name:"ichor", value:1800, weight:0.2, volume:0.015 }, { name:"gold", value:2500, weight:2, volume:0.002 }], 35, 0.35)` should return `75900`.
```js
assert.equal(
@ -86,7 +86,7 @@ assert.equal(
35,
0.35
),
75300
75900
);
```
@ -120,36 +120,66 @@ function knapsackUnbounded(items, maxweight, maxvolume) {
# --solutions--
```js
function knapsackUnbounded(items, maxweight, maxvolume) {
var n = items.length;
var best_value = 0;
var count = new Array(n);
var best = new Array(n);
function recurseKnapsack(i, value, weight, volume) {
var j, m1, m2, m;
if (i == n) {
if (value > best_value) {
best_value = value;
for (j = 0; j < n; j++) {
best[j] = count[j];
}
}
return;
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;
}
m1 = Math.floor(weight / items[i].weight);
m2 = Math.floor(volume / items[i].volume);
m = m1 < m2 ? m1 : m2;
for (count[i] = m; count[i] >= 0; count[i]--) {
recurseKnapsack(
i + 1,
value + count[i] * items[i].value,
weight - count[i] * items[i].weight,
volume - count[i] * items[i].volume
);
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);
}
}
recurseKnapsack(0, 0, maxweight, maxvolume);
return best_value;
return bestValue;
}
```

View File

@ -8,7 +8,7 @@ dashedName: knights-tour
# --description--
[Knight's Tour](https://en.wikipedia.org/wiki/Knight%27s_tour)Problem: You have an empty `w` \* `h` chessboard, but for a single knight on some square. The knight must perform a sequence of legal moves that result in the knight visiting every square on the chessboard exactly once. Note that it is *not* a requirement that the tour be "closed"; that is, the knight need not end within a single move of its start position.
[Knight's Tour](https://en.wikipedia.org/wiki/Knight%27s_tour) Problem: You have an empty `w` \* `h` chessboard, but for a single knight on some square. The knight must perform a sequence of legal moves that result in the knight visiting every square on the chessboard exactly once. Note that it is *not* a requirement that the tour be "closed"; that is, the knight need not end within a single move of its start position.
# --instructions--
@ -28,34 +28,34 @@ assert(typeof knightTour == 'function');
assert(typeof knightTour(6, 6) == 'number');
```
`knightTour(6, 6)` should return `35`.
`knightTour(6, 6)` should return `36`.
```js
assert.equal(knightTour(6, 6), 35);
assert.equal(knightTour(6, 6), 36);
```
`knightTour(5, 6)` should return `20`.
`knightTour(5, 6)` should return `30`.
```js
assert.equal(knightTour(5, 6), 20);
assert.equal(knightTour(5, 6), 30);
```
`knightTour(4, 6)` should return `10`.
`knightTour(4, 6)` should return `12`.
```js
assert.equal(knightTour(4, 6), 10);
assert.equal(knightTour(4, 6), 12);
```
`knightTour(7, 3)` should return `4`.
`knightTour(7, 3)` should return `10`.
```js
assert.equal(knightTour(7, 3), 4);
assert.equal(knightTour(7, 3), 10);
```
`knightTour(8, 6)` should return `47`.
`knightTour(8, 6)` should return `48`.
```js
assert.equal(knightTour(8, 6), 47);
assert.equal(knightTour(8, 6), 48);
```
# --seed--
@ -72,83 +72,154 @@ function knightTour(w, h) {
```js
function knightTour(w, h) {
var b,
cnt = 0;
var dx = [-2, -2, -1, 1, 2, 2, 1, -1];
var dy = [-1, 1, 2, 2, 1, -1, -2, -2];
function init_board() {
var i, j, k, x, y;
// * b is board; a is board with 2 rows padded at each side
for (i = 0; i < h; i++) {
for (j = 0; j < w; j++) {
b[i][j] = 255;
}
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];
}
for (i = 0; i < h; i++) {
for (j = 0; j < w; j++) {
for (k = 0; k < 8; k++) {
(x = j + dx[k]), (y = i + dy[k]);
if (b[i][j] == 255) b[i][j] = 0;
if (x >= 0 && x < w && y >= 0 && y < h) b[i][j]++;
}
function 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 walk_board(x, y) {
var i, nx, ny, least;
var steps = 0;
// printf(E"H"E"J"E"%d;%dH"E"32m[]"E"m", y + 1, 1 + 2 * x);
while (1) {
// * occupy cell
b[y][x] = 255;
// * reduce all neighbors' neighbor count
for (i = 0; i < 8; i++)
if (y + dy[i] >= 0 && x + dx[i] >= 0 && y + dy[i] < h && x + dx[i] < w)
b[y + dy[i]][x + dx[i]]--;
// find neighbor with lowest neighbor count
least = 255;
for (i = 0; i < 8; i++) {
if (y + dy[i] >= 0 && x + dx[i] >= 0 && y + dy[i] < h && x + dx[i] < w)
if (b[y + dy[i]][x + dx[i]] < least) {
nx = x + dx[i];
ny = y + dy[i];
least = b[ny][nx];
}
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]--;
}
}
}
if (least > 7) {
return steps == w * h - 1;
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]);
}
steps++;
(x = nx), (y = ny);
}
if (bestMoves.length > 0) {
return bestMoves;
}
return zeroMove;
}
function solve(x, y) {
b = new Array(h);
for (var i = 0; i < h; i++) b[i] = new Array(w);
init_board();
if (walk_board(x, y)) {
cnt++;
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;
}
for (var i = 0; i < h; i++) {
for (var j = 0; j < w; j++) {
solve(j, i);
}
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);
}
return cnt;
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

@ -34,7 +34,7 @@ assert(typeof letterFrequency == 'function');
assert(Array.isArray(letterFrequency('Not all that Mrs. Bennet, however')));
```
`letterFrequency("Not all that Mrs. Bennet, however")` should return `[[" ", 5], [", ", 1], [".", 1], ["B", 1], ["M", 1], ["N", 1], ["a", 2], ["e", 4], ["h", 2], ["l", 2], ["n", 2], ["o", 2], ["r", 2], ["s", 1], ["t", 4], ["v", 1], ["w", 1]]`.
`letterFrequency("Not all that Mrs. Bennet, however")` should return `[[" ", 5], [",", 1], [".", 1], ["B", 1], ["M", 1], ["N", 1], ["a", 2], ["e", 4], ["h", 2], ["l", 2], ["n", 2], ["o", 2], ["r", 2], ["s", 1], ["t", 4], ["v", 1], ["w", 1]]`.
```js
assert.deepEqual(letterFrequency('Not all that Mrs. Bennet, however'), [
@ -58,7 +58,7 @@ assert.deepEqual(letterFrequency('Not all that Mrs. Bennet, however'), [
]);
```
`letterFrequency("daughters, could ask on the ")` should return `[[' ',5],[',',1],['a',2],['c',1],['d',2],['e',2],['g',1],['h',2],['k',1],['l',1],['n',1],['o',2],['r',1],['s',2],['t',2],['u',2]]`.
`letterFrequency("daughters, could ask on the ")` should return `[[" ", 5],[",", 1],["a", 2],["c", 1],["d", 2],["e", 2],["g", 1],["h", 2],["k", 1],["l", 1],["n", 1],["o", 2],["r", 1],["s", 2],["t", 2],["u", 2]]`.
```js
assert.deepEqual(letterFrequency('daughters, could ask on the '), [
@ -131,7 +131,7 @@ assert.deepEqual(letterFrequency('in various ways--with barefaced'), [
]);
```
`letterFrequency("distant surmises; but he eluded")` should return `[[" ", 4], ["; ", 1], ["a", 1], ["b", 1], ["d", 3], ["e", 4], ["h", 1], ["i", 2], ["l", 1], ["m", 1], ["n", 1], ["r", 1], ["s", 4], ["t", 3], ["u", 3]]`.
`letterFrequency("distant surmises; but he eluded")` should return `[[" ", 4], [";", 1], ["a", 1], ["b", 1], ["d", 3], ["e", 4], ["h", 1], ["i", 2], ["l", 1], ["m", 1], ["n", 1], ["r", 1], ["s", 4], ["t", 3], ["u", 3]]`.
```js
assert.deepEqual(letterFrequency('distant surmises; but he eluded'), [
@ -153,7 +153,7 @@ assert.deepEqual(letterFrequency('distant surmises; but he eluded'), [
]);
```
`letterFrequency("last obliged to accept the second-hand,")` should return `[[" ", 5], [", ", 1], ["-", 1], ["a", 3], ["b", 1], ["c", 3], ["d", 3], ["e", 4], ["g", 1], ["h", 2], ["i", 1], ["l", 2], ["n", 2], ["o", 3], ["p", 1], ["s", 2], ["t", 4]]`.
`letterFrequency("last obliged to accept the second-hand,")` should return `[[" ", 5], [",", 1], ["-", 1], ["a", 3], ["b", 1], ["c", 3], ["d", 3], ["e", 4], ["g", 1], ["h", 2], ["i", 1], ["l", 2], ["n", 2], ["o", 3], ["p", 1], ["s", 2], ["t", 4]]`.
```js
assert.deepEqual(letterFrequency('last obliged to accept the second-hand,'), [

View File

@ -12,11 +12,15 @@ Loop over multiple arrays and create a new array whose $i^{th}$ element is the c
For this example, if you are given this array of arrays:
`[ ["a", "b", "c"], ["A", "B", "C"], [1, 2, 3] ]`
```js
[ ["a", "b", "c"], ["A", "B", "C"], [1, 2, 3] ]
```
the output should be:
`["aA1","bB2","cC3"]`
```js
["aA1","bB2","cC3"]
```
# --instructions--

View File

@ -22,9 +22,9 @@ Newlines and other whitespace may be ignored unless contained within a quoted st
Handling escaped quotes inside a string is optional; thus "`(foo"bar)`" may be treated as a string "`foo"bar`", or as an error.
For this, the reader need not recognize "<code>\\</code>" for escaping, but should, in addition, recognize numbers if the language has appropriate data types.
For this, the reader need not recognize `\` for escaping, but should, in addition, recognize numbers if the language has appropriate data types.
Note that with the exception of "`()"`" ("<code>\\</code>" if escaping is supported) and whitespace there are no special characters. Anything else is allowed without quotes.
Note that with the exception of `()"` (`\` if escaping is supported) and whitespace, there are no special characters. Anything else is allowed without quotes.
The reader should be able to read the following input
@ -48,7 +48,7 @@ assert(typeof parseSexpr === 'function');
assert.deepEqual(parseSexpr(simpleSExpr), simpleSolution);
```
`parseSexpr('(data1 data2 data3)')` should return an array with 3 elements.
`parseSexpr('((data "quoted data" 123 4.5) (data (!@# (4.5) "(more" "data)")))')` should return `[['data', '"quoted data"', 123, 4.5], ['data', ['!@#', [4.5], '"(more"', '"data)"']]]`.
```js
assert.deepEqual(parseSexpr(basicSExpr), basicSolution);

View File

@ -8,11 +8,11 @@ dashedName: sha-256
# --description--
**[SHA-256](https://en.wikipedia.org/wiki/SHA-256)** is the recommended stronger alternative to [SHA-1](https://rosettacode.org/wiki/SHA-1).
The `SHA-2` family is a stronger alternative to `SHA-1`. The main difference between them is the length of the hash. Meaning `SHA-1` provides a shorter code with fewer possibilities for unique combinations. `SHA-2` or `SHA-256` creates a longer and thus more complex hash with more possibilities.
# --instructions--
Write a function that takes a string as a parameter and returns its SHA-256 digest.
Research implemenation details and write a function that takes a string as the parameter and returns a hash using `SHA-256`
# --hints--

View File

@ -14,7 +14,9 @@ Make your function work with the following list of values and set of indices:
<code>values: [7, <b>6</b>, 5, 4, 3, 2, <b>1</b>, <b>0</b>]</code>
`indices(0-based): {6, 1, 7}`
```js
indices(0-based): {6, 1, 7}
```
Where the correct result would be:

View File

@ -11,13 +11,13 @@ dashedName: split-a-character-string-based-on-change-of-character
Split a (character) string into comma (plus a blank) delimited strings based on a change of character (left to right). Blanks should be treated as any other character (except they are problematic to display clearly). The same applies to commas. For instance, the string:
<pre>
"gHHH5YY++///\"
"gHHH5YY++///\\"
</pre>
should be split as:
<pre>
["g", "HHH", "5", "YY", "++", "///", "\" ];
["g", "HHH", "5", "YY", "++", "///", "\\" ];
</pre>
# --hints--
@ -80,7 +80,7 @@ assert.deepEqual(split('sssmmmaaammmaaat'), [
]);
```
`split("gHHH5YY++///\")` should return `["g", "HHH", "5", "YY", "++", "///", "\\"]`.
`split("gHHH5YY++///\\")` should return `["g", "HHH", "5", "YY", "++", "///", "\\"]`.
```js
assert.deepEqual(split('gHHH5YY++///\\'), [

View File

@ -8,7 +8,7 @@ dashedName: sudoku
# --description--
Write a function to solve a partially filled-in normal 9x9 [Sudoku](https://en.wikipedia.org/wiki/Sudoku) grid and return the result. The blank fields are represented by 0s. [Algorithmics of Sudoku](https://en.wikipedia.org/wiki/Algorithmics_of_sudoku) may help implement this.
Write a function to solve a partially filled-in normal 9x9 [Sudoku](https://en.wikipedia.org/wiki/Sudoku) grid and return the result. The blank fields are represented by `-1`. [Algorithmics of Sudoku](https://en.wikipedia.org/wiki/Algorithmics_of_sudoku) may help implement this.
# --hints--

Some files were not shown because too many files have changed in this diff Show More