Індексація розширених чисел Фібоначчі


21

Напевно, ви чули про числа Фібоначчі. Ви знаєте, що ціла послідовність, яка починається з 1, 1, і тоді кожне нове число є сумою останніх двох?

1 1 2 3 5 8 13...

І так далі. Виклики щодо цифр Фібоначчі тут досить популярні . Але хто каже, що числа Фібоначчі повинні починатися 1, 1? Чому вони не могли почати 0, 1? Добре, давайте переосмислимо їх, щоб почати з 0:

0 1 1 2 3 5 8 13...

Але ... На цьому ми теж не повинні зупинятися! Якщо ми можемо додати останні два числа, щоб отримати наступне, ми також могли б відняти перше число від другого числа, щоб додати нове число. Отже, це може початися з 1, 0:

1 0 1 1 2 3 5 8 13...

Ми навіть можемо закінчитись негативами:

-1 1 0 1 1 2 3 5 8 13...

І ця серія також триває назавжди. Я думаю, що цікаво, як це закінчується своєрідним дзеркальним відображенням регулярних чисел Фібоначчі, як і з будь-яким іншим числом, негативним:

13 -8 5 -3 2 -1 1 0 1 1 2 3 5 8 13...

Назвемо цей ряд "Розширеним числом Фібоначчі", або EFN . Оскільки насправді немає очевидного від’ємного числа для початку цього ряду, ми скажемо, що 0 з’являється на 0 , звичайні числа Фібоначчі поширюються на позитивні показники, а від’ємні (напівнегативні?) Числа Фібоначчі поширюються до негативних показників, як-от так:

Indices: ...-7  -6 -5  -4 -3  -2 -1  0  1  2  3  4  5  6  7 ...
Values:  ...13  -8  5  -3  2  -1  1  0  1  1  2  3  5  8  13...

Це призводить до сьогоднішнього виклику:

Враховуючи ціле число N , повертайте кожен індекс, при якому N з'являється в серії EFN .

Кілька випадкових спостережень за цим завданням:

  • 1 з'являється кілька разів в EFN , ніж будь-яке інше число: [-1, 1, 2]. Жодне число не з’явиться у більш ніж 3 місцях.

  • Кожне число Фібоначчі> 1 з’явиться або один раз (3, 8, 21 і т.д.) або двічі (2, 5, 13 і т.д.)

Пояснення правил:

  • Якщо abs(N)це не число Фібоначчі, воно ніколи не з’явиться в серії EFN , тому ви повинні вивести нічого / порожню колекцію, якщо це можливо, або якщо це неможливо на вашій мові, ви можете вивести деяке постійне нечислове значення.
  • Якщо N відображається у кількох місцях EFN , ваш вихід не потребує сортування. Хоча кожен індекс повинен з’являтися рівно один раз.
  • Хоча більшість викликів дозволяють вам вибрати, чи хочете ви використовувати індексацію на основі 1 або 0, для цього виклику необхідно використовувати описане індексування (де 0 відображається у 0).
  • Ви можете приймати введення-виведення через будь-який стандартний формат.

Випробування

-13: []
-12: []
-11: []
-10: []
-9: []
-8: [-6]
-7: []
-6: []
-5: []
-4: []
-3: [-4]
-2: []
-1: [-2]
0: 0
1: [-1, 1, 2]
2: [-3, 3]
3: [4]
4: []
5: [-5, 5]
6: []
7: []
8: [6]
9: []
10: []
11: []
12: []
13: [-7, 7]

І кілька великих тестових випадків:

89: [-11, 11]
1836311903: [46]
10000: []
-39088169: [-38]

Як завжди, найкоротша відповідь у байтах виграє!


Пов’язаний , хоч і не дублікат, оскільки він не потребує обробки негативів чи чисел, що не входять у Фібоначчі.
DJMcMayhem

12
До речі, є ще одна вагома причина того, що числа Фібоначчі завжди слід індексувати так, що $ F_0 = 0 $, навіть коли використовується лише додатне число Фібоначчі. Ось така індексація дозволяє це прекрасне властивість: якщо $ k $ ділить $ n $, то $ F_k $ ділить $ F_n $.
Грег Мартін

Відповіді:


9

Haskell , 78 байт

4 байти збережено завдяки німі

a#b=a:b#(a-b)
f 0=[0]
f a=do{(i,x)<-zip[0..a*a+1]$0#1;[-i|x==a]++[i|abs x==a]}

Спробуйте в Інтернеті!

Спочатку ми налаштовуємо (#), (#)приймаємо два параметри aі b, і повертаємо список, починаючи з aі за ним b#(a-b). Це створює нескінченний список, але оскільки Хаскелл лінивий, нам не потрібно турбуватися про його петлі назавжди. Це по суті працює назад, створюючи послідовність Фібоначчі перед певною парою. Наприклад (0#1), буде список усіх чисел Фібоначчі з від’ємним індексом.

Звідси ми робимо f. fбере аргумент a, число, яке ми намагаємося знайти в послідовності. Тут ми використовуємо doпозначення для розуміння списку. Почнемо з взяття перших a*a+1елементів списку 0#11 . Оскільки функція a*a+1зростає швидше, ніж обернена послідовність Фібоначчі, ми можемо бути впевнені, що якщо ми перевіримо в межах цієї межі, ми знайдемо всі результати. Це заважає нам шукати нескінченний список. Тоді для кожного значення xта індексу i, якщо x==aми знайшли aв негативній половині послідовності, тому ми повертаємось -i, і якщо abs x==aми також повернемось i, тому що абсолютне значення від’ємної половини є додатною половиною, тому ми її знайшли там.

Оскільки це робить список [0,0]для цього, 0ми жорстко кодуємо правильний вихід для цього.

1: Ця хитрість взята з чистої відповіді Οurous . Та ж SpeedUp aplies тут , як там, замініть a*a+1з , abs a+1щоб заощадити багато часу.


Заміна uна a#b=a:b#(a-b)плюс 0#1економить байт: Спробуйте це в Інтернеті!
німі

@nimi Це фактично економить 4 байти, у вашому посиланні tio є 3 додаткові пробіли.
Пшеничний майстер

5

Чистота , 132 120 109 байт

import StdEnv
g n|n<2=n=g(n-1)+g(n-2)
?k=[e\\p<-[0..k*k+1],e<-if(isOdd p)([~p,p]%(0,k))[p*sign k]|g p==abs k]

Спробуйте в Інтернеті!

g :: Int -> Int- це функція Фібоначчі.
? :: Int -> [Int]тільки індекси в елементах EFN в межах k^2+1від 0.

Для версії, яка працює за розумну кількість часу, змініть k*k+1на abs k+1.


1
Цей трюк із розуміння списку досить акуратний! Економить мої відповіді 14 байтів.
Пшеничний майстер




1

Сітківка 0,8,2 , 104 102 байти

[1-9].*
$*
(-)?(\b1|(?>\3?)(\2))*(1)$|(0)?.*
$5$1$4$4$#2$*
-1(11)+$

^1(11)+$
-$&,$&
1+
$.&
^2$
-1,1,2

Спробуйте в Інтернеті! Пояснення:

[1-9].*
$*

Перетворити в одинарне, якщо тільки вхід не дорівнює нулю.

(-)?(\b1|(?>\3?)(\2))*(1)$|(0)?.*
$5$1$4$4$#2$*

Обчисліть індекс Фібоначчі абсолютного значення, але якщо число не є числом Фібоначчі, то видаліть його, якщо тільки воно не дорівнювало нулю. Для цього використовується регекс тестування Фібоначчі @ MartinEnder.

-1(11)+$

Видаліть від’ємні числа, абсолютні значення яких непарні числа Фібоначчі.

^1(11)+$
-$&,$&

Додайте від’ємні показники для непарних додатних чисел Фібоначчі.

1+
$.&

Перетворити в десятковий.

^2$
-1,1,2

Додайте додаткові індекси для 1.


1

Насправді 34 байти

;╗3*;±kSix⌠;;AF@;1&@0>*YτD(s**╜=⌡░

Брут-сила економить день

Пояснення:

;╗3*;±kSix⌠;;AF@;1&@0>*YτD(s**╜=⌡░
;╗                                  save a copy of the input (let's call it N) to register 0 (the main way to get additional values into functions)
  3*;±                              -3*N, 3*N
      kSi                           push to list, sort, flatten (sort the two values on the stack so that they are in the right order for x)
         x                          range(min(-3*N, 3*N), max(-3*N, 3*N))
          ⌠;;AF@;1&@0>*YτD(s**╜=⌡░  filter (remove values where function leaves a non-truthy value on top of the stack):
           ;;                         make two copies of parameter (let's call it n)
             AF                       absolute value, Fib(|n|)
               @;                     bring a copy of n to the top of the stack and make another copy
                 1&                   0 if n is divisible by 2 else 1
                   @0>                1 if n is negative else 0 (using another copy of n)
                      *               multiply those two values (acts as logical AND: is n negative and not divisible by 2)
                       YτD            logical negate, double, decrement (maps [0, 1] to [1, -1])
                          (s          sign of n (using the last copy)
                            **        multiply Fib(|n|), sign of n, and result of complicated logic (deciding whether or not to flip the sign of the value for the extended sequence)
                              ╜=      push value from register 0, equality comparison (1 if value equals N else 0)

Спробуйте в Інтернеті!




0

05AB1E , 36 байт

x*ÝʒÅfIÄQ}Ii®šë1KIdiÐ`ÉiD(ì}ëD`Èi(ë¯

Має бути кращий підхід 0.

Спробуйте в Інтернеті або перевірте всі тестові випадки .

Пояснення:

x            # Create a list in the range [0, (implicit) input * input * 2]
   ʒ     }     # Filter this list by:
    Åf         #  Where the Fibonacci value at that index
      IÄQ      #  Is equal to the absolute value of the input
Ii             # If the input is exactly 1:
  ®š           #  Prepend -1 to the list
ë              # Else:
 1K            #  Remove all 1s (only applies to input -1)
 Idi           #  If the input is non-negative:
    Ð`Éi   }   #   If the found index in the list is odd:
        D    #    Prepend its negative index to the list
   ë           #  Else (the input is negative):
    Di       #   If the found index in the list is even:
        (      #    Negate the found index
       ë       #   Else (found index is odd):
        ¯      #    Push an empty array
               # (Output the top of the stack implicitly as result)

Деякі покрокові приклади:

Input:  Filtered indices:  Path it follows (with actions) and result:

-8      [6]                NOT 1 → neg → even index → negate index: [-6]
-5      [5]                NOT 1 → neg → odd index → push empty array: []
-1      [1,2]              NOT 1 → (remove 1) neg → even remaining index: negate index: [-2]
0       [0]                NOT 1 → even index → negate index: [0]    
1       [1,2]              1 → prepend -1: [-1,1,2]
5       [5]                NOT 1 → non-neg → odd index → Prepend neg index: [-5,5]
8       [6]                NOT 1 → non-neg → even index → (nothing): [6]


Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.