diff --git a/curriculum/challenges/english/10-coding-interview-prep/project-euler/problem-461-almost-pi.md b/curriculum/challenges/english/10-coding-interview-prep/project-euler/problem-461-almost-pi.md index 50a12c051c..10a83e63f8 100644 --- a/curriculum/challenges/english/10-coding-interview-prep/project-euler/problem-461-almost-pi.md +++ b/curriculum/challenges/english/10-coding-interview-prep/project-euler/problem-461-almost-pi.md @@ -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)` = a2 + b2 + c2 + d2 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)` = 62 + 752 + 892 + 2262 = 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; +} ```