110 lines
		
	
	
		
			2.6 KiB
		
	
	
	
		
			Markdown
		
	
	
	
	
	
			
		
		
	
	
			110 lines
		
	
	
		
			2.6 KiB
		
	
	
	
		
			Markdown
		
	
	
	
	
	
| ---
 | |
| id: 5900f3bc1000cf542c50fecf
 | |
| title: '問題 80: 平方根の小数展開'
 | |
| challengeType: 5
 | |
| forumTopicId: 302194
 | |
| dashedName: problem-80-square-root-digital-expansion
 | |
| ---
 | |
| 
 | |
| # --description--
 | |
| 
 | |
| よく知られているとおり、自然数の平方根は、整数でない場合は無理数です。 このような平方根の小数展開は無限であり、繰り返されるパターンが全くありません。
 | |
| 
 | |
| 2 の平方根は `1.41421356237309504880...` で、小数第 1 位から第 100 位までの各位の和は `475` です。
 | |
| 
 | |
| 最初の `n` 個の自然数について、その平方根が無理数であれば小数第 1 位から第 100 位までの各位の和を求めるとします。その和を、該当するすべての無理数で合計するといくつになりますか。
 | |
| 
 | |
| # --hints--
 | |
| 
 | |
| `sqrtDigitalExpansion(2)` は数値を返す必要があります。
 | |
| 
 | |
| ```js
 | |
| assert(typeof sqrtDigitalExpansion(2) === 'number');
 | |
| ```
 | |
| 
 | |
| `sqrtDigitalExpansion(2)` は `475` を返す必要があります。
 | |
| 
 | |
| ```js
 | |
| assert.strictEqual(sqrtDigitalExpansion(2), 475);
 | |
| ```
 | |
| 
 | |
| `sqrtDigitalExpansion(50)` は `19543` を返す必要があります。
 | |
| 
 | |
| ```js
 | |
| assert.strictEqual(sqrtDigitalExpansion(50), 19543);
 | |
| ```
 | |
| 
 | |
| `sqrtDigitalExpansion(100)` は `40886` を返す必要があります。
 | |
| 
 | |
| ```js
 | |
| assert.strictEqual(sqrtDigitalExpansion(100), 40886);
 | |
| ```
 | |
| 
 | |
| # --seed--
 | |
| 
 | |
| ## --seed-contents--
 | |
| 
 | |
| ```js
 | |
| function sqrtDigitalExpansion(n) {
 | |
| 
 | |
|   return true;
 | |
| }
 | |
| 
 | |
| sqrtDigitalExpansion(2);
 | |
| ```
 | |
| 
 | |
| # --solutions--
 | |
| 
 | |
| ```js
 | |
| 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;
 | |
| }
 | |
| ```
 |