Послідовність сум цілих чисел, які не є в послідовності


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 перший елемент , n = 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

Пітон, 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, і ей престо, ви повинні формулювати вище.



9

Математика, 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] ( Wolfram link ):

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:- зауважте, що він переходить на використання індексації на основі 0.
Глен О

@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).

Використовуючи той самий метод, що і відповідь Юнга Хвана Міна (сума діапазону мінус сума попередніх доданків).

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

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

Простий forцикл продовжує тривати, поки кількість послідовностей не дорівнює або не дорівнює цілому вхідному числу, тоді я повертаю цей $nелемент.


@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

Хаскелл , 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}...*)[$_]}

Спробуй це

Розширено:

{ # 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, яке (трохи) читабельніше:

Чистий баш, 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;}

Безголівки:

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.