Files

206 lines
4.8 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: 594810f028c0303b75339ad6
title: Подання Цекендорфа
challengeType: 5
forumTopicId: 302346
dashedName: zeckendorf-number-representation
---
# --description--
Так само як числа можуть бути представлені в позиційній нотації як суми кратних степенів десяти (десяткових) або двох (двійкових); всі додатні цілі числа можна єдиним чином представити у вигляді суми одного або декількох різних чисел Фібоначчі. Нагадаємо, що перші шість різних чисел Фібоначчі дорівнюють: `1, 2, 3, 5, 8, 13`.
Десяткове число 11 можна записати як `0*13 + 1*8 + 0*5 + 1*3 + 0*2 + 0*1` або `010100` у позиційній нотації, де стовпці представляють множення на певний елемент послідовності. Початкові нулі упущено, тому десяткові числа стають `10100`. 10100 не єдиний спосіб утворити 11 з чисел Фібоначчі, однак`0*13 + 1*8 + 0*5 + 0*3 + 1*2 + 1*1` або 010011 також утворює число 11. Для справжнього числа Цекендорфа існує додаткова умова, при якій *не можна використовувати два послідовних числа Фібоначчі*, що призводить до попереднього унікального рішення.
# --instructions--
Напишіть функцію, яка створює і повертає подання Цекендорфа для чисел у вигляді `n`.
# --hints--
`zeckendorf` повинен бути функцією.
```js
assert.equal(typeof zeckendorf, 'function');
```
`zeckendorf(0)` має повернути `0`.
```js
assert.equal(zeckendorf(0), 0);
```
`zeckendorf(1)` має повернути `1`.
```js
assert.equal(zeckendorf(1), 1);
```
`zeckendorf(2)` має повернути `10`.
```js
assert.equal(zeckendorf(2), 10);
```
`zeckendorf(3)` має повернути `100`.
```js
assert.equal(zeckendorf(3), 100);
```
`zeckendorf(4)` має повернути `101`.
```js
assert.equal(zeckendorf(4), 101);
```
`zeckendorf(5)` має повернути `1000`.
```js
assert.equal(zeckendorf(5), 1000);
```
`zeckendorf(6)` має повернути `1001`.
```js
assert.equal(zeckendorf(6), 1001);
```
`zeckendorf(7)` має повернути `1010`.
```js
assert.equal(zeckendorf(7), 1010);
```
`zeckendorf(8)` має повернути `10000`.
```js
assert.equal(zeckendorf(8), 10000);
```
`zeckendorf(9)` має повернути `10001`.
```js
assert.equal(zeckendorf(9), 10001);
```
`zeckendorf(10)` має повернути `10010`.
```js
assert.equal(zeckendorf(10), 10010);
```
`zeckendorf(11)` має повернути `10100`.
```js
assert.equal(zeckendorf(11), 10100);
```
`zeckendorf(12)` має повернути `10101`.
```js
assert.equal(zeckendorf(12), 10101);
```
`zeckendorf(13)` має повернути `100000`.
```js
assert.equal(zeckendorf(13), 100000);
```
`zeckendorf(14)` має повернути `100001`.
```js
assert.equal(zeckendorf(14), 100001);
```
`zeckendorf(15)` має повернути `100010`.
```js
assert.equal(zeckendorf(15), 100010);
```
`zeckendorf(16)` має повернути `100100`.
```js
assert.equal(zeckendorf(16), 100100);
```
`zeckendorf(17)` має повернути `100101`.
```js
assert.equal(zeckendorf(17), 100101);
```
`zeckendorf(18)` має повернути `101000`.
```js
assert.equal(zeckendorf(18), 101000);
```
`zeckendorf(19)` має повернути `101001`.
```js
assert.equal(zeckendorf(19), 101001);
```
`zeckendorf(20)` має повернути `101010`.
```js
assert.equal(zeckendorf(20), 101010);
```
# --seed--
## --seed-contents--
```js
function zeckendorf(n) {
}
```
# --solutions--
```js
// zeckendorf :: Int -> Int
function zeckendorf(n) {
const f = (m, x) => (m < x ? [m, 0] : [m - x, 1]);
return parseInt((n === 0 ? ([0]) :
mapAccumL(f, n, reverse(
tail(fibUntil(n))
))[1]).join(''));
}
// fibUntil :: Int -> [Int]
let fibUntil = n => {
const xs = [];
until(
([a]) => a > n,
([a, b]) => (xs.push(a), [b, a + b]), [1, 1]
);
return xs;
};
let mapAccumL = (f, acc, xs) => (
xs.reduce((a, x) => {
const pair = f(a[0], x);
return [pair[0], a[1].concat(pair[1])];
}, [acc, []])
);
let until = (p, f, x) => {
let v = x;
while (!p(v)) v = f(v);
return v;
};
const tail = xs => (
xs.length ? xs.slice(1) : undefined
);
const reverse = xs => xs.slice(0).reverse();
```