Files

253 lines
7.5 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

---
id: 5900f3a91000cf542c50febc
title: 'Завдання 61: Циклічні фігурні числа'
challengeType: 5
forumTopicId: 302173
dashedName: problem-61-cyclical-figurate-numbers
---
# --description--
Трикутні, квадратні, п'ятикутні, шестикутні, семикутні і восьмикутні числа є фігурними (багатокутними) числами і визначаються за такими формулами:
| Тип числа | Формула | Послідовність |
| ----------- | ----------------------------- | --------------------- |
| Трикутне | $P_3(n) = \frac{n(n+1)}{2}$ | 1, 3, 6, 10, 15, ... |
| Квадратне | $P_4(n) = n^2$ | 1, 4, 9, 16, 25, ... |
| П'ятикутне | $P_5(n) = \frac{n(3n1)}2$ | 1, 5, 12, 22, 35, ... |
| Шестикутне | $P_6(n) = n(2n1)$ | 1, 6, 15, 28, 45, ... |
| Семикутне | $P_7(n) = \frac{n(5n3)}{2}$ | 1, 7, 18, 34, 55, ... |
| Восьмикутне | $P_8(n) = n(3n2)$ | 1, 8, 21, 40, 65, ... |
Впорядкована множина з трьох 4-значних чисел: 8128, 2882, 8281 має три цікаві властивості.
1. Множина циклічна, оскільки дві останні цифри кожного числа є першими двома цифрами наступного числа (включаючи останнє та перше число).
2. Кожен тип багатокутника: трикутний ($P_3(127) = 8128$), квадратний ($P_4(91) = 8281$), і п'ятикутний ($P_5(44) = 2882$), представлений іншим числом в даній множині.
3. Це єдина множина 4-цифрових чисел з цією властивістю.
Знайдіть суму всіх чисел у впорядкованих множинах з `n` циклічних 4-значних чисел, в яких кожен з типів багатокутника від $P_3$ до $P_{n + 2}$ представлений іншим числом цієї множини.
# --hints--
`cyclicalFigurateNums(3)` має повернути число.
```js
assert(typeof cyclicalFigurateNums(3) === 'number');
```
`cyclicalFigurateNums(3)` має повернути `19291`.
```js
assert.strictEqual(cyclicalFigurateNums(3), 19291);
```
`cyclicalFigurateNums(4)` має повернути `28684`.
```js
assert.strictEqual(cyclicalFigurateNums(4), 28684);
```
`cyclicalFigurateNums(5)` має повернути `76255`.
```js
assert.strictEqual(cyclicalFigurateNums(5), 76255);
```
`cyclicalFigurateNums(6)` має повернути `28684`.
```js
assert.strictEqual(cyclicalFigurateNums(6), 28684);
```
# --seed--
## --seed-contents--
```js
function cyclicalFigurateNums(n) {
return true;
}
cyclicalFigurateNums(3);
```
# --solutions--
```js
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;
}
```