Последовательность сумм целых чисел, которых нет в последовательности


28

Задний план

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

  • Первый элемент 0;
  • Второй элемент 4;
  • Начиная с третьего элемента, его значение можно рассчитать по формуле:
    • Взятие набора целых чисел от 0 до предыдущего элемента последовательности (включительно или исключительно, это не имеет значения);
    • Удаление любых целых чисел, которые уже появились ранее в последовательности из набора;
    • Складывая оставшиеся элементы набора; это значение, которое вы хотите.

Интересно, что эта последовательность еще не появилась в OEIS .

Задание

Напишите программу или функцию, которая принимает целое число n в качестве входных данных и выводит n- й элемент последовательности.

Контрольные примеры

Первые несколько элементов последовательности:

  • 0
  • 4
  • 6 (1 + 2 + 3)
  • 11 (1 + 2 + 3 + 5)
  • 45 (1 + 2 + 3 + 5 + 7 + 8 + 9 + 10)
  • 969 (1 + 2 + 3 + 5 + 7… 10 + 12… 44)
  • 468930 (1 + 2 + 3 + 5 + 7… 10 + 12… 44 + 46… 968)

Разъяснения

  • Ваша программа теоретически должна быть способна обрабатывать произвольное число n, если она запускается на варианте вашего языка, который имеет неограниченно большие целые числа и имеет доступ к неограниченному объему памяти. (Маловероятно, что языки без бинумов смогут выйти за рамки 468930, но это не повод жестко закодировать ответы.)
  • Вы можете выбрать индексирование на основе 0 или 1 для последовательности (например, вам решать, вернет ли n = 1 первый элемент, n = 2 второй элемент и т. Д., Или n = 0 вернет первый элемент , п = 1 , второй элемент, и так далее).
  • Нет требований ни к используемому алгоритму, ни к его эффективности; вы можете напрямую реализовать определение последовательности (даже если она действительно неэффективна), и вы можете также реализовать другой алгоритм, который приводит к тем же результатам.

Состояние победы

Это , поэтому выигрывает самая короткая правильная программа, измеряемая в байтах.


1
Почему бы не разрешить бесконечный вывод вместо ввода?
Джон Дворак

2
@JanDvorak: Потому что это заставляет все программы использовать алгоритмы, которые генерируют каждый термин; этот метод написания вопроса оставляет на усмотрение ответчиков, хотят ли они это сделать, или же они хотят использовать формулу закрытой формы (при условии, что она есть). Так что это дает больше выбора стратегий при решении вопроса.

1
Я бы предположил, что последовательности там нет, потому что 0,4 - странное смещение
boboquack

1
@boboquack При (0,3), (0,2), (1,4) или аналогичных вариациях последовательность будет постоянной через несколько членов.
Деннис

Имеет ли смысл тег [math] для этого?
mbomb007

Ответы:


10

Желе , 13 12 9 байт

rSạo4¥ð@¡

Использует индексирование на основе 0.

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

Как это работает

rSạo4¥ð@¡  Main link. No arguments. Implicit argument: 0

      ð    Collect everything to the left into a chain and start a new, dyadic one.
           The arity of the first chain is unknown at this point, as it isn't
           prefixed by ø, µ, or ð.
       @   Swap the arguments of the first chain. Swapping  arguments is only
           implemented for dyadic links, so this makes the chain dyadic.
        ¡  Read an integer n from STDIN and execute the chain n times. Taking the
           argument swap into account, the chain is executed first with 0 as left
           and right argument, then with the previous right argument as left
           argument and the previous return value as right argument.
           The return value of the last call is the return value of the quicklink
           and becomes the implicit output.

           Let's call the left argument x and the right argument y.
r            Range; yield [x, ..., y].
 S           Compute the sum of all integers in the range.
     ¥       Convert the two atoms to the left into a dyadic chain, and call that
             chain with arguments x and y.
   o4          Take the logical OR of x and 4, replacing a 0 with 4 and leaving
               positive integers untouched.
  ạ          Take the absolute difference of the sum to the left and the result of
             the logical OR to the right.

10

Python, 66 60 байт

Спасибо @Dennis за то, что сбрил 6 байтов!

f=lambda n:n>2and(f(n-1)-~f(n-2))*(f(n-1)-f(n-2))/2or(5-n)*n

Это не самый лучший кусок кода за всю историю, но он использует формулу, которую я сделал:

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

Где xна правой стороне есть f(n - 1), и yесть f(n - 2).

Объяснение:

Сумма непрерывных целых чисел от aдо b(включительно) может быть описана этой формулой:

amount * average

Где amount(количество чисел) описывается так:

((a - b) - 1)

И average(среднее из всех чисел) описывается так:

(a + b) / 2

Итак, полная формула теперь:

  ((a - b) - 1)(a + b) / 2
= (a - b - 1)(a + b) / 2

Образом мы реализуем эту формулу в окончательную формулу заменить aна f(n - 1), bна f(n - 2), который в основном вычисляет сумму всех новых терминов, и добавить еще один f(n - 1)(который в настоящее время a) на, что сумма всех предыдущих членов.

Объединяя это вместе, мы получаем:

  a + ((a - b - 1)(a + b) / 2)
= a + ((a^2 + ab - ab - b^2 - a - b) / 2)
= a + ((a^2 - b^2 - a - b) / 2)
= (a^2 - b^2 - a - b + 2a) / 2
= (a^2 - b^2 + a - b) / 2
= ((a + b)(a - b) + (a - b)) / 2
= (a + b + 1)(a - b) / 2

Замените aна xи bс y, и эй Presto, вы должны формула выше.



9

Mathematica, 49 48 байтов

±2=4;±1=0;±n_:=Tr@Range@±(n-1)-Tr@Array[±#&,n-1]
(* or *)
±2=4;±1=0;±n_:=-Tr@Array[(k=±#)&,n-1]+Tr@Range@k

Использует кодировку CP-1252. Определяет функцию PlusMinus (±). 1-индексироваться.

объяснение

±2=4;±1=0;±n_:=Tr@Range@±(n-1)-Tr@Array[±#&,n-1]

±2=4;±1=0;                                        (* Define ±1 and ±2 *)
          ±n_:=                                   (* ±n equals ... *)
               Tr@Range@±(n-1)                    (* Sum of (1, 2, ..., ±(n-1)) ... *)
                              -Tr@Array[±#&,n-1]  (* Minus the sum of previous terms *)

8

Оазис , 11 байт

Код:

+>bc-*2/640


Объяснение:

Чтобы визуализировать отношение f n , давайте возьмем пример f 5 . Чтобы вычислить f 5 , давайте посмотрим на следующую сумму:

1 + 2 + 3 + 5 + 7 + 8 + 9 + 10

Жирная часть точно такая же, как f 4 . Часть 7 + 8 + 9 + 10 - это диапазон [f n-2 + 1, f n-1 - 1] . Это дает формулу f n-1 + Σ [f n-2 + 1 ... f n-1 - 1] ( ссылка Вольфрама ):

f n = 0,5 × (f n-1 2 - f n-2 2 + f n-1 - f n-2 )

Который может быть переписан на:

f n = 0,5 × ((f n-1 - f n-2 ) (f n-1 + f n-2 ) + (f n-1 - f n-2 ))

f n = 0,5 × ((f n-1 - f n-2 ) (f n-1 + f n-2 + 1))

Какую формулу мы будем использовать в коде:


Объяснение кода

640Часть дает нам базовые случаи:

a(0) = 0
a(1) = 4
a(2) = 6

Код, который будет выполнен (который определяет (n) ):

+>bc-*2/

+          # Add a(n + 1) and a(n + 2) implicitly
 >         # Add one to get a(n + 1) + a(n + 2) + 1
  b        # Push a(n + 1)
   c       # Push a(n + 2)
    -      # Subtract from each other
     *     # Multiply with the previous result
      2/   # Halve the result

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


3
Объяснение? Это сделало меня более любопытным, чем многие другие ответы.

@ ais523 Я добавил объяснение.
Аднан

5

Юлия, 39 33 32 байта

!n=n<3?5n-n^2:sum(!(n-2)+1:!~-n)

0 на основе.

Благодаря @Dennis сэкономлено 6 байт.

Благодаря @GlenO, сохранил байт.

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

Предыдущий ответ 1- на основе:

!n=n<4?2(n>1)n:sum(!(n-2)+1:!~-n)

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

Предыдущий негольфированный ответ на основе 1:

f(n)=n<4?n<2?0:n*2:sum(f(n-2)+1:f(n-1))

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


1
Чтобы сохранить дополнительный байт, используйте n<3?5n-n^2:вместо n<4?2(n>1)n:- обратите внимание, что он переключается на индексирование с нуля.
Глен О,

@GlenO Спасибо, 1 байт сохранен!
rahnema1

4

JavaScript (ES6), 47 байт

f=(n,b=4,a=6)=>n?--n?f(n,a,(a+b+1)*(a-b)/2):b:0

Использует рекуррентное соотношение, которое f(n) = sum(range(f(n-2) + 1, f(n-1) + 1))при n> 2.


4

PowerShell , 84 89 88 87 байт

$OFS='+'
for($a=0,4;$a.Count-le($n="$args")){$a+=("$(1..$a[-1])"|iex)-("$a"|iex)}$a[$n]

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

объяснение

Индексирование на основе 0. Работает только через n = 6(на моей Windows-машине происходит сбой при переполнении стека n = 7)

Используя тот же метод, что и ответ JungHwan Min (сумма диапазона минус сумма предыдущих терминов).

Суммирование диапазона / массива в PowerShell занимает много времени, поэтому я использую хитрость, заключающуюся в соединении массива с помощью +создания длинного выражения (например 1+2+3+4...etc) и последующей его отправки через iex( Invoke-Expression).

Поскольку мне нужно сделать это дважды, вместо использования -joinя устанавливаю специальную переменную $OFS, которая обозначает разделитель выходного поля. Когда вы структурируете массив, это символ, используемый для объединения элементов; по умолчанию это пробел. Таким образом , установив его +(один раз), я могу заменить что - то подобное $a-join'+'|iexс "$a"|iex.

Простой forцикл продолжается до тех пор, пока счетчик последовательности не станет меньше или равен входному целому числу, тогда я верну $nth-й элемент.


@AdmBorkBork очень приятно! Я действительно думаю, что это заслуживает внятного ответа; метод достаточно отличается, чтобы я не чувствовал себя так, как если бы я использовал его.
Бриантист

1
@AdmBorkBork хорошо, +1, и я узнал одну вещь из этого: нет ;необходимости после forцикла. Никогда не осознавал этого раньше.
Бриантист

3

MATL , 17 16 байт

OKi:"tP:yX-sv]G)

1на основе индексации используется. Код очень неэффективен. Ибо n = 6он уже превышает лимит памяти онлайн-компилятора.

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

Как это работает

O       % Push 0
K       % Push 4
i       % Input n
:"      % Do the following n times
  t     %   Push a copy of the top array (or number)
  P:    %   Range from 1 to the last element of array
  y     %   Push a copy of the second-top number/array
  X-    %   Set difference
  s     %   Sum
  v     %   Concatenate everything into a column vector
]       % End
G)      % Get n-th entry of the array. Implicity display

Для 20 байт следующая версия позволяет избежать ограничения памяти. Но все же есть ограничение doubleтипа данных ( тип может гарантировать только то, что целые числа точно представлены до 2^53), поэтому результаты действительны n = 8только до .

OKi:"t0)tQ*2/ys-v]G)

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


2

Haskell , 42 байта

f 0=0
f 1=4
f 2=6
f n=sum[1+f(n-2)..f$n-1]

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

Это непосредственно реализует рецидивы что n>2, f(n)равно f(n-1)плюс сумму открытого интервала от f(n-2)к f(n-1)которой вновь равна сумме полусегмент от f(n-2)до f(n-1)включительно.

f(0) = 0
f(1) = 4
f(2) = 6 = 1+2+3
f(3) = 11 = 1+2+3+5 = 6 + 5 = 6 + sum]4,6[ = f(2)+ sum]f(1),f(2)[ = sum]f(1),f(2)]
...
f(n) = sum]f(n-2),f(n-1)] = sum[f(n-2)+1,f(n-1)]

2

Haskell, 31 байт

m#s=m:s#sum[m+1..s]
((0:4#6)!!)

Пример использования: ((0:4#6)!!) 6-> 468930. Попробуйте онлайн! ,

Простая рекурсия, которая отслеживает максимальный элемент mдо следующего значения s.


Всякий раз, когда я сталкиваюсь с новым испытанием, кто-то всегда отвечает лучше, чем любой другой, которого я когда-либо мог сделать XD
theonlygusti

Я всегда прибегаю к каким-то математическим вызовам, думаю: «Эй, наконец-то я могу попробовать haskell!» CMD-F 'Haskell' - о, подождите, нет, этот ответ ... подождите, что?
Сдаётся


2

Perl 6 ,  52 49 44  35 байт

{(|(0,4 X 0),{[+](^.[0])-.[1],.[0]+.[1]}...*)[$_;0]}

Попытайся

{(0,(4,0),{[+](^.[0])-.[1],.[0]+.[1]}...*)[$_;0]}

Попытайся

{(0,(4,0),{[+](^.[0])-.[1],.sum}...*)[$_;0]}

Попытайся

{(0,4,6,{[+] $^a^..$^b}...*)[$_]}

Попытайся

Expanded:

{ # bare block lambda with implicit parameter 「$_」

  (
    # generate a sequence

    0, 4, 6,      # seed the sequence

    {             # lambda with placeholder parameters 「$a」 「$b」
      [+]         # reduce with 「&infix:<+>」
          $^a     # n-2
          ^..     # Range that excludes the first value
          $^b     # n-1
    }
    ...           # keep generating values until
    *             # never stop

  )[ $_ ]         # get the value that was asked for (0 based index)
}

2

PowerShell , 77 73 байта

param($n)$a=0,4;1..$n|%{$a+=(0..$a[-1]|?{$_-notin$a})-join'+'|iex};$a[$n]

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

Реализует алгоритм, как определено, и 0-проиндексирован. Ввод 6слишком много для TIO для обработки.

Устанавливает $aбыть массивом [0,4]. Циклы от 1до ввода $n. В цикле мы берем диапазон чисел от 0наибольшего числа, которое у нас есть $a[-1], и используем Where-Objectпредложение, |?{...}чтобы извлечь только те числа, которых еще нет. Этот массив чисел -joinредактируется вместе с +s, а затем подается на iex(сокращение от Invoke-Expressionи аналогично eval). Это значение затем присоединяется к массиву в конце $a. Наконец, мы выходим из нашего цикла и берем число $nth в нашем массиве. Это число остается в конвейере, а вывод неявным.



1

Пакетная, 108 байтов

@if %1==0 echo 0&exit/b
@set/ab=4,a=6
@for /l %%i in (2,1,%1)do @set/ac=(a+b+1)*(a-b)/2,b=a,a=c
@echo %b%

Порт моего JavaScript ответа.


1

постоянный ток , 47 байтов

?d1-scd/4*dd[d1+*2/r-dsn+dlnlc1-dsc0<x]sxlc0<xp

Работает с целыми числами, как вы хотите, вплоть до объема памяти компьютера.

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

Индексирование на основе 0, ввод в stdin, вывод в stdout. (Также есть вывод на stderr, который следует игнорировать.)

Образцы прогонов:

$ for ((j=0;j<12;j++)){ echo -n "$j ";dc -f sumseq.dc <<<"$j";echo;} 2>/dev/null
0 0

1 4

2 6

3 11

4 45

5 969

6 468930

7 109947436950

8 6044219445882138462810

9 18266294354989892462984673364511343859409730

10 166828754731567805766174036610844675771635260155825966927845486666328\
837158267993261860

11 139159167026428037700805570917048711514125048327321592278500415852500\
422178720517080334552793040951056255170819719745908378102737875659900\
61575545777065220385544711322919415

В нем используется тот же алгоритм, что и в следующем решении в bash, которое (немного) более читабельно:

Чистый bash, 60 байтов

for((n=s=$1?4:0,k=1;k<$1;k++,s+=(n=n++*n/2-s))){ :;}
echo $n

Но программа bash работает только для входов до 7, поскольку она выходит за пределы целочисленного переполнения.



0

C # - 74 байта

int A(int f){int e=4,i=1,s=0;for(;i++<f;)e=e*-~e/2-(s+=e);return f>0?e:0;}

Ungolfed:

int A(int f)
{
    int e = 4, 
        i = 1, 
        s = 0; // e is the last element, s is the sum of all previous elements
    for (; i++ < f; ) // calculate for indexes 1 through max (don't need the index, just a correct number of loop cycles)
        e = e * -~e / 2 - (s += e); // -~e => (e + 1), higher precedence to remove parentheses
    return f > 0 ? e : 0; //handle input 0 as a special case, which is 0
}

Вероятно, есть способ преобразовать это в лямбду, чтобы сэкономить еще больше, или что-то еще, используя функцию .Aggregate. Хотя в настоящее время у меня нет импорта, так что, может быть, это выровняется?


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