Прыжки вверх по последовательности


19

Рассмотрим следующую последовательность:

0 1 3 2 5 4 8 6 7 12 9 10 11 17 13 14 15 16 23 ...

Выглядит довольно шаблонно, верно? Вот как это работает. Начиная с 0, прыгайте вверх nцелые числа, nначиная с 1. Это следующий номер в последовательности. Затем добавьте все числа, «пропущенные», и которые еще не были показаны в порядке возрастания. Затем увеличивайте nи переходите от последнего добавленного числа. Повторите этот шаблон.

Так, например, когда мы достигаем 11, мы находимся n=5. Мы увеличиваем, nчтобы быть n=6, подпрыгнуть 17, затем добавить, 13 14 15 16так как они еще не были замечены. Наш следующий переход - n=7следующий элемент в последовательности 23.

Соревнование

Задавая входные данные x, xвыводим термы этой последовательности, первые xтермы последовательности или строим бесконечный список терминов последовательности. Вы можете выбрать 0- или 1-индексацию.

Ввод / вывод и правила

  • Вход и выход могут быть заданы любым удобным способом .
  • Можно предположить, что ввод и вывод соответствуют типу номера вашего языка.
  • Либо полная программа или функция приемлемы. Если функция, вы можете вернуть вывод, а не распечатать его.
  • Стандартные лазейки запрещены.
  • Это поэтому применяются все обычные правила игры в гольф, и выигрывает самый короткий код (в байтах).

Это очевидно не (еще?) На OEIS
JayCe

@JayCe Я не удивлен - это довольно произвольная последовательность.
AdmBorkBork

Ответы:


24

JavaScript (ES7), 41 байт

Возвращает n-й член последовательности с 0 индексами.

n=>(d=(n--*8-23)**.5)%1?n:'121'[n]^n-~d/2

Попробуйте онлайн!

Как?

Основной случай: n>3

Первые четыре члена последовательности являются специальными, поэтому давайте отложим их пока.

Для последовательность выглядит так:n>3

 n  | [4] 5 [6] 7 8 [ 9] 10 11 12 [13] 14 15 16 17 [18] 19 20 21 22 23 [24] 25 26 27 ...
----+------------------------------------------------------------------------------------
a(n)| [5] 4 [8] 6 7 [12]  9 10 11 [17] 13 14 15 16 [23] 18 19 20 21 22 [30] 24 25 26 ...
----+------------------------------------------------------------------------------------
 k  |  2  -  3  - -   4   -  -  -   5   -  -  -  -   6   -  -  -  -  -   7   -  -  - ...

Мы можем заметить, что на самом деле есть две чередующиеся подпоследовательности:

  • Большинство значений принадлежат подпоследовательности для которой мы просто имеем:A

    A(n)=n1
  • Некоторые другие значения принадлежат подпоследовательности (выделено скобками на диаграмме выше), индексы которой следуют арифметической последовательности 3, 3, 4, 6, 9, 13, 18, 24 ... и для которой мы имеем:B

    B(n,k)=n+k1

    где является индексом в основной последовательности , и к является индексом в суб-последовательности B .nkB

Индексы в основной последовательности определяются как:B

nk=k2k+62

Учитывая , мы знаем, что соответствующий член в главной последовательности принадлежит B, если n является целочисленным решением квадратного уравнения:nBn

x2x+62n=0

чей дискриминант является:

Δ=14(62n)=8n23

и чье положительное решение:

x=1+Δ2

Мы ожидаем быть целым числом. Отсюда и тест:Δ

(d = (n-- * 8 - 23) ** .5) % 1

Особые случаи: 0n3

При дискриминант отрицателен, а получение его квадратного корня приводит к NaN . Для n = 3 дискриминант равен 1 . Таким образом, эти первые четыре члены последовательности считаются принадлежащими к подпоследовательности B .n<3n=31B

Если бы мы просто применили нашу стандартную формулу n - ~ d / 2 , мы получили бы:

12,12,32,3

вместо того:

0,1,3,2

Вот почему мы XOR эти результаты с соответственно.0,1,2 and 1


10

Шелуха , 12 байт

Θṁṙ_1C+ḣ2tNN

Попробуйте онлайн!

Выходы в виде бесконечного списка. Вот версия , которая печатает первый N .

объяснение

Θṁṙ_1C + ḣ2tNN - Полная программа. Не требует ввода, выводит на STDOUT.
         tN - построить бесконечный список натуральных чисел, начиная с 2.
      + ḣ2 - и добавить [1, 2] к нему. Выходы [1,2,2,3,4,5,6,7,8,9,10,11, ...].
     CN - Разрежьте бесконечный список натуральных чисел на куски
               размеры. Выходы [[1], [2,3], [4,5], [6,7,8], [9,10,11,12], ...].
 Map - Нанесите на карту и сгладьте результаты после этого.
  ṙ_1 - поверните каждый вправо на 1 единицу.
               Доходность [1,3,2,5,4,8,6,7,12,9,10,11, ...]
Pend - добавить 0. Выход [0,1,3,2,5,4,8,6,7,12,9,10,11, ...]

7

Haskell , 43 байта

0:1:3:2:5!3
a!n=a:[a-n+2..a-1]++(a+n)!(n+1)

Попробуйте онлайн!

Определяет бесконечный список:

  0:1:3:2:(5!3)
 0:1:3:2:5:4:(8!4)
 0:1:3:2:5:4:8:6:7:(12!5)
 0:1:3:2:5:4:8:6:7:12:9:10:11:(17!6)
 0:1:3:2:5:4:8:6:7:12:9:10:11:17:13:14:15:16:(23!7) 

4

Желе , 15 байт

+‘ɼṪRṙ-œ|@
0Ç¡ḣ

Это полная программа, которая, учитывая n , печатает первые n элементов последовательности.

Попробуйте онлайн!

Как это устроено

0Ç¡ḣ        Main link. Argument: n

0           Set the return value to 0.
 Ç¡         Call the helper link n times, first with argument 0, then n-1 times
            with the previous return value as argument.
   ḣ        Head; extract the first n items of the last return value.


+‘ɼṪRṙ-œ|@  Helper link. Argument: A (array)

 ‘ɼ         Increment the value in the register (initially 0) and yield it.
+           Add that value to all items in the sequence.
   Ṫ        Tail; extract the last item.
    R       Range; map k to [1, .., k].
     ṙ-     Rotate -1 units to the left, yielding [k, 1, ..., k-1].
       œ|@  Perform multiset union of A and the previous return value.

3

C (gcc), 73 67 64 байта

t,d;f(x){for(t=4,d=2;d<x;t+=d++)x-t||(d+=x+=d);t=x<4?x^x/2:x-1;}

Попробуйте онлайн!

Определяет функцию, fкоторая принимает 0-индексированный nи производит nth-е число в последовательности.

Мы можем проанализировать последовательность следующим образом:

f(n)  = n   where n = 0, 1

f(2)  = 3   // 2 and 3 are swapped
f(3)  = 2

f(4)  = 5   // (+2,+3)
f(6)  = 8   // (+3,+4)
f(9)  = 12  // (+4,+5)
f(13) = 17  // (...)
...

f(n)  = n-1 // for all cases not yet covered

Сначала мы обращаемся к средней части:

for(t=4,d=2;d<x;t+=d++)x-t||(d+=x+=d);

Обратите внимание, что аргументы слева (4, 6, 9, 13, ...) следуют шаблону: сначала добавьте два, затем добавьте три, затем добавьте четыре и так далее. Мы начинаем с t=4и добавляем d(который начинается с 2) каждую итерацию цикла, увеличиваясь dв процессе.

Тело цикла является более интересным. Помните, что мы хотим отобразить от 4 до 5, от 6 до 8, от 9 до 12 и т. Д .; это просто добавление, d-1если xесть t. Однако эта логика предшествует последнему случаю, f(n) = n - 1поэтому мы знаем, что мы собираемся вычесть 1 в конце. Поэтому мы можем просто добавить dif x == t( x-t||(x+=d)). Тем не менее, мы также должны выйти из цикла сразу же после этого - поэтому мы добавим , что к dполучить абсурдный вид d+=x+=d, который всегда сделает d<xсостояние терпеть неудачу.

Это охватывает все, кроме первых четырех значений. Глядя на них в двоичном виде, мы получаем:

00 -> 00
01 -> 01
10 -> 11
11 -> 10

Итак, мы хотим перевернуть последний бит, если 2 <= x < 4. Это достигается с x^x/2. x/2дает второй младший значащий бит, так что XOR с этим исходным номером переворачивает последний бит, если число равно 2 или 3.


3

Желе ,  13  10 байт

-3 Благодаря Деннису (используйте 0-индексирование, чтобы сохранить 2 от настройки накопленной суммы и окончательного уменьшения)

Ḷ»2Äi+_>2$

Монадическая ссылка, принимающая целое, 0 -индексированное n , которое возвращает целое число a (n)

Попробуйте онлайн! Или посмотрите тестовый набор


Ницца! Я имел ḶÄ+3i+’, но понятия не имел, как обращаться с крайними случаями.
Деннис

У меня также есть Ḷ»ạ¥3для Ḋ3,2;- чувство, что должно быть terser для этого бита.
Джонатан Аллан

Ḷ»2Äi+_>2$сохраняет 3 байта с индексированием на основе 0.
Деннис

О, классный гольф! Я застрял в 1-индексной земле.
Джонатан Аллан


2

MATL , 22 байта

1y:"t0)@+h5M:yX-h]qw:)

Выводит первые nчлены последовательности.

Попробуйте онлайн!

объяснение

1         % Push 1
y         % Implicit input: n. Duplicate from below
":        % For each k in [1 2 ... n]
  t0)     %   Duplicate sequence so far. Get last entry, say m
  @+      %   Add k: gives m+k
  h       %   Concatenate horizontally
  5M      %   Push m+k again
  :       %   Range [1 2 ... m+k]
  y       %   Duplicate from below
  X-      %   Set difference
  h       %   Concatenate horizontally
]         % End
q         % Subtract 1, element-wise
w         % Swap. Brings original copy of n to the top
:)        % Keep the first n entries. Implicit display

Мне нравится смайлик в конце, теперь я хочу, чтобы все мои программы MATL заканчивались улыбкой. :)
sundar - Восстановить Монику

@sundar Да, я счастлив, что в MATL это довольно распространенная идиома :-D
Луис Мендо,



1

QBasic, 58 байт

DO
b=r+j
?b
r=b
FOR x=a+1TO b-1
?x
r=x
NEXT
a=b
j=j+1
LOOP

Выходы на неопределенный срок. Вы можете добавить SLEEP 1внутри цикла или сделать его LOOP WHILE b<100или что-то в этом роде, чтобы увидеть результаты.

Это в основном просто реализует спецификацию. Заметьте, что числа, к которым мы возвращаемся, всегда будут числами между последним числом перехода и числом перехода до этого. Поэтому мы сохраняем эти границы как aи bи используем FORцикл для печати всех чисел между ними.



1

R 70 байт

function(e){for(i in 1:e)F=c(setdiff((F+i):1-1,F),F[1]+i,F);rev(F)[e]}

Попробуйте онлайн!

  • 1-индексированных
  • -4 байта используя F константы благодаря предложению @JAD
  • -5 байт переворачивают список благодаря предложению @Giuseppe
  • -2 байта, удаляющих ненужные скобки для цикла благодаря предложению @JAD
  • -2 байта setdiffвместоx[x %in% y]

Предыдущая версия (79 байт)



@JAD: я всегда забывал использовать F / T ... Я ничего не могу поделать, я слишком склонен избегать «небезопасного кода»: D
digEmAll

1
Построение списка в обратном порядке сохраняет 5 bytesи вызывает кучу предупреждений!
Джузеппе

Это даже небезопасно, если F/Tне переопределено при определении функции. Это не (IIRC) изменяет глобальное значение дляF/T
JAD


1

Python 2 , 123 байта

def f(z):[s.extend([s[-1]+n]+[x for x in range(s[-1]+1,s[-1]+n)if not x in s]) for n in range(1,z)if len(s)<z];return s    

Попробуйте онлайн!

При заданном вводе x выведите первые x членов последовательности,

Я изучаю Python, и эти проблемы делают вещи более интересными.

Изменить: побрить пробел


Добро пожаловать в PPCG! Вы можете избавиться от некоторых более пробелов в for n in range(1,z) if len(s) < z]; return s: for n in range(1,z)if len(s)<z];return s.
Лайкони

0

Желе , 16 байт

RÄṬŻk²Ḋ$ṙ€-Ø.;Fḣ

Попробуйте онлайн!

Один байт длиннее, чем существующий ответ Jelly, но это может быть немного в гольфе. RÄṬŻk²Ḋ$может быть короче.

18 байт

RÄṬŻk²Ḋ$‘ṙ€1FŻŻỤ’ḣ

Дольше, но разные.



0

Perl 6 , 52 байта

(0,{((^max @_)∖@_).min.?key//(1+@_[*-1]+$++)}...*)

Попробуйте онлайн!

Это выражение генератора с использованием ...оператора. Он ищет пробелы в предыдущей последовательности @_через ((^max @_)∖@_).min.?key:

      @_  # prior sequence values         [0,1,3]
  max @_  # largest prior sequence value       3
 ^        # the Range 0..max @_            0,1,2
(       )∖@_  # set subtract prior seq     -0,1  -> (2=>True)
            .min  # smallest unseen value  2=>True
                .?key  # set yields pairs  2

?Необходимо для начального значения , которое не имеет .key. Если пропуски не найдены, то это добавляет n (здесь в $переменной) к последнему значению в списке, плюс один для отключения на 0 ошибок.


Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.