Послідовність Кімберлінга


18

Вступ

Звичайно, у нас багато проблем із , тож ось ще одна.

Послідовність Кімберлінга ( A007063 ) має такий вигляд :

1, 3, 5, 4, 10, 7, 15, 8, 20, 9, 18, 24, 31, 14, 28, 22, ...

Це відбувається шляхом переміщення нормальної ітерації:

[1] 2  3  4  5  6  7  8

Перший член послідовності - 1. Після цього ми переставляємо послідовність, поки не будуть використані всі терміни зліва. Перемішування має малюнок right - left - right - left - .... Оскільки немає лівих термінів зліва 1, перетасування не відбувається. Ми отримуємо наступне:

 2 [3] 4  5  6  7  8  9

На i- й ітерації ми відкидаємо i- й елемент і ставимо це в нашій послідовності. Це 2-а ітерація, тому ми відкидаємо другий пункт. Послідовність стає: 1, 3. Для нашої наступної ітерації ми перетасуємо поточну ітерацію за вищевказаним зразком. Ми беремо перший невикористаний предмет праворуч від i- го предмета. Це буває 4. Ми додамо це до нашої нової ітерації:

 4

Тепер ми візьмемо перший невикористаний елемент ліворуч від i- го елемента. Це 2. Ми додамо це до нашої нової ітерації:

 4  2

Оскільки зліва від i- го елемента не залишилося елементів, ми просто додамо решту послідовності до нової ітерації:

 4  2 [5] 6  7  8  9  10  11  ...

Це наша третя ітерація, тому ми відкинемо цю 3-й елемент, який є 5. Це третій пункт у нашій послідовності:

 1, 3, 5

Щоб отримати наступну ітерацію, просто повторіть процес. Я зробив gif, якщо це не ясно:

введіть тут опис зображення

Gif у мене зайняв більше часу, ніж написання фактичної публікації

Завдання

  • Враховуючи невід'ємне ціле число n , виведіть перше n доданків послідовності
  • Ви можете надати функцію або програму
  • Це , тому подання з найменшою кількістю байтів виграє!

Тестові приклади:

Input: 4
Output: 1, 3, 5, 4

Input: 8
Output: 1, 3, 5, 4, 10, 7, 15, 8

Input: 15
Output: 1, 3, 5, 4, 10, 7, 15, 8, 20, 9, 18, 24, 31, 14, 28

Примітка: Коси у висновку не потрібні. Наприклад, ви можете використовувати нові рядки або виводити список тощо.


Я працюю над методом, що використовує обертання стека
Cyoce

@Cyoce Удачі :)
Аднан

схоже, мені це потрібно
Cyoce

Відповіді:


3

Піт, 22 байти

JS*3QVQ@JN=J.i>JhN_<JN

Спробуйте в Інтернеті: Демонстрація

Просто виконує техніку перетасування, описану в ОП.

Пояснення:

JS*3QVQ@JN=J.i>JhN_<JN
JS*3Q                    assign the list [1, 2, ..., 3*input-1] to J
     VQ                  for N in range(Q):
       @JN                  print J[N]
            .i              interleave 
              >JhN             J[N+1:] with
                  _<JN         reverse J[:N]
          =J                assign the resulting list to J

6

Джулія, 78 71 байт

n->[(i=j=x;while j<2i-3 j=i-(j%2>0?1-j:j+22;i-=1end;i+j-1)for x=1:n]

Це неназвана функція, яка приймає ціле число і повертає цілий масив. Щоб викликати його, призначте його змінній.

Підхід тут такий же, як описаний у OEIS.

Безголівки:

# This computes the element of the sequence
function K(x)
    i = j = x
    while j < 2i - 3
        j = i - (j % 2 > 0 ? 1 - j : j + 22
        i -= 1
    end
    return i + j - 1
end

# This gives the first n terms of the sequence
n -> [K(i) for i = 1:n]

Збережено 7 байт завдяки Маврису!


3

Математика 130 байт

(n=0;s={};Nest[(n++;AppendTo[s,z=#[[n]]];Flatten[TakeDrop[#,1+2(n-1)]/.{t___,z,r___}:> 
Riffle[{r},Reverse@{t}]])&,Range[3*#],#];s)&

Почнемо зі списку, що складається з діапазону від 1до 3x, де xє бажана кількість термінів послідовності Кімберлінга.

На кожному кроці n, TakeDropрозбиває поточний список на передній список 2n+1термінів (де виконана робота) і задній лист (який пізніше буде об'єднаний з переробленим переднім списком). Передній список узгоджується з наступною схемою, {t___,z,r___}де z - термін Кімберлінга в центрі переднього списку. rє Riffle'd із зворотним боком, tа потім додається задній список. zвидаляється та додається до (AppendTo ) зростаючої послідовності Кімберлінга.

nзбільшується на, 1а поточний список обробляється тією ж функцією черезNest.


Приклад

(n=0;s={};Nest[(n++;AppendTo[s,z=#[[n]]];Flatten[TakeDrop[#,1+2(n-1)]/.{t___,z,r___}:> 
Riffle[{r},Reverse@{t}]])&,Range[3*#],#];s)&[100]

{1, 3, 5, 4, 10, 7, 15, 8, 20, 9, 18, 24, 31, 14, 28, 22, 42, 35, 33, 46, 53, 6, 36, 23, 2 , 55, 62, 59, 76, 65, 54, 11, 34, 48, 70, 79, 99, 95, 44, 97, 58, 84, 25, 13, 122, 83, 26, 115, 82, 91 , 52, 138, 67, 90, 71, 119, 64, 37, 81, 39, 169, 88, 108, 141, 38, 16, 146, 41, 21, 175, 158, 165, 86, 191, 45 , 198, 216, 166, 124, 128, 204, 160, 12, 232, 126, 208, 114, 161, 156, 151, 249, 236, 263, 243, 101, 121, 72, 120, 47, 229 }


2

Python 2, 76 байт

for a in range(input()):
 b=a+1
 while-~b<2*a:b=a-(b^b%-2)/2;a-=1
 print a+b

Пояснення

Це формула OEIS після багатьох перетворень у гольф! Це вийшло чудово . Оригінальний код був

i=b=a+1
while b<2*i-3:b=i-(b+2,1-b)[b%2]/2;i-=1
print i+b-1

Я спершу позбувся i, замінивши його a+1всюди і розширивши вирази:

b=a+1
while b<2*a-1:b=a+1-(b+2,1-b)[b%2]/2;a-=1
print a+b

Потім переписав b<2*a-1, -~b<2*aщоб зберегти байт пробілу, і перемістив +1у виділення, поділ на 2 та заперечення:

while-~b<2*a:b=a-(b,-b-1)[b%2]/2;a-=1

Тоді, -b-1просто ~b, щоб ми могли писати (b,~b)[b%2]. Це еквівалентно з b^0 if b%2 else b^-1допомогою оператора XOR, або в якості альтернативи, b^b%-2.

while-~b<2*a:b=a-(b^b%-2)/2;a-=1

2

Pyth, 29 25 байт

VQ+.W<hHyN-~tN/x%Z_2Z2hNN

Jakube врятував 4 байти, але в мене немає поняття, як читати код.

Ось старе рішення:

VQKhNW<hKyN=K-~tN/x%K_2K2)+KN

Переклад моєї відповіді Python. Я не дуже добре в Pyth, тому, можливо, ще є способи скоротити це.

VQ                              for N in range(input()):
  KhN                             K = N+1
     W<hKyN                       while 1+K < 2*N:
           =K-~tN/x%K_2K2)         K = (N--) - (K%-2 xor K) / 2
                          +KN     print K + N

Ви можете використовувати .Wдля гольфу від 4 байта: VQ+.W<hHyN-~tN/x%Z_2Z2hNN.
Якубе

Це круто - ви могли б приблизно пояснити, як це працює?
Лінн

1
.Wмає вигляд: .W<condition><apply><start-value>. Я використовував початкове значення hN, як і ви KhN. .Wзмінює це значення до тих пір, поки значення <condition>true є. Я використовував таку ж умову, що і ви <hHyN. Умова - лямбда-функція з параметром H, тому поточне значення (у вашому коді K) є H. І я також використовував той же <apply>заяву , як ви, я тільки замінити Kз Z, тому що <apply>твердження лямбда-функції з параметром Z. Ми можемо ігнорувати =K, .Wсправляється з цим. Він замінює старе значення на обчислене. На завершення друк+...N
Якубе

2

APL, 56 44 байти

{⍵<⍺+⍺-3:(⍺-1)∇⍺-4÷⍨3+(1+2×⍵)ׯ1*⍵⋄⍺+⍵-1}⍨¨⍳

Це неназваний монадичний поїзд, який приймає ціле число праворуч і повертає масив. Це приблизно такий самий підхід, як і моя відповідь Юлії .

Найпотаємніша функція - це рекурсивна діадична функція, яка повертає n- й член у послідовності Кімберлінга, заданий n як однакові аргументи зліва та справа.

{⍵<⍺+⍺-3:                                    ⍝ If ⍵ < 2⍺ - 3
         (⍺-1)∇⍺-4÷⍨3+(1+2×⍵)ׯ1*⍵           ⍝ Recurse, incrementing a and setting
                                             ⍝ ⍵ = ⍺ - (3 + (-1)^⍵ * (1 + 2⍵))/4
                                   ⋄⍺+⍵-1}   ⍝ Otherwise return ⍺ + ⍵ - 1

Маючи це в руці, ми можемо отримати окремі умови послідовності. Однак проблема стає в тому, що це діадична функція, тобто вона вимагає аргументів обох сторін. Введіть оператора! Дана функція fта вхід x, f⍨xце те саме, що x f x. Тож у нашому випадку, посилаючись на вищезгадану функцію як f, ми можемо побудувати наступний монадичний потяг:

f⍨¨⍳

Ми застосовуємо fдо кожного цілого числа від 1 до вхідного сигналу, отримуючи масив.

Збережено 12 байт завдяки Деннісу!

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