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


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- й элемент и помещаем его в нашу последовательность. Это вторая итерация, поэтому мы отбрасываем второй пункт. Последовательность становится: 1, 3. Для нашей следующей итерации мы будем перетасовывать текущую итерацию с шаблоном выше. Мы берем первый неиспользованный предмет справа от i- го предмета. Это случается 4. Мы добавим это к нашей новой итерации:

 4

Теперь мы возьмем первый неиспользованный предмет слева от i- го предмета. Это 2. Мы добавим это к нашей новой итерации:

 4  2

Поскольку слева от i- го элемента не осталось элементов, мы просто добавим остальную часть последовательности к новой итерации:

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

Это наша третья итерация, поэтому мы отбросим третий пункт, который есть 5. Это третий пункт в нашей последовательности:

 1, 3, 5

Чтобы получить следующую итерацию, просто повторите процесс. Я сделал подарок, если не ясно:

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

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

Pyth, 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.

Ungolfed:

# 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 байтов благодаря Mauris!


3

Mathematica 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«д с обратной 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

Якубе сохранил 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>оно истинно. Я использовал то же условие, что и вы <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.