Una sequenza di somme di numeri interi che non sono nella sequenza


28

sfondo

Considera una sequenza definita come segue:

  • Il primo elemento è 0;
  • Il secondo elemento è 4;
  • Dal terzo elemento in poi, il suo valore può essere calcolato da:
    • Prendendo l'insieme di numeri interi da 0 fino all'elemento precedente della sequenza (inclusivo o esclusivo, non importa);
    • Rimozione di numeri interi che sono già apparsi in precedenza nella sequenza dal set;
    • Sommando gli elementi rimanenti dell'insieme; questo è il valore che desideri.

È interessante notare che questa sequenza non sembra essere ancora su OEIS .

L'obiettivo

Scrivere un programma o funzione che prende un numero intero n in ingresso, ed emette il n -esimo elemento della sequenza.

Casi test

I primi elementi della sequenza sono:

  • 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)

chiarimenti

  • In teoria il tuo programma dovrebbe essere in grado di gestire n arbitrari se eseguito su una variante del tuo linguaggio che ha numeri interi senza limiti e accesso a una quantità illimitata di memoria. (È improbabile che le lingue senza bignum siano in grado di andare molto oltre 468930, ma non è una scusa per decodificare le risposte.)
  • Puoi scegliere l'indicizzazione basata su 0 o 1 per la sequenza (ad es. Dipende da te se n = 1 restituisce il primo elemento, n = 2 il secondo elemento e così via; oppure se n = 0 restituisce il primo elemento , n = 1 il secondo elemento e così via).
  • Non ci sono requisiti per l'algoritmo che usi, né per la sua efficienza; puoi implementare direttamente la definizione della sequenza (anche se è davvero inefficiente) e puoi anche implementare un algoritmo diverso che porta agli stessi risultati.

Condizione di vittoria

Questo è , quindi vince il programma corretto più breve, misurato in byte.


1
Perché non consentire un output infinito invece di accettare input?
John Dvorak,

2
@JanDvorak: Perché questo obbliga tutti i programmi a usare algoritmi che generano ogni termine; questo metodo di scrittura della domanda lascia ai rispondenti se vogliono farlo o se vogliono usare una formula a forma chiusa (supponendo che ce ne sia una). Quindi offre una scelta più ampia di strategie per risolvere la domanda.

1
Suppongo che la sequenza non sia presente perché 0,4 è uno strano offset
boboquack il

1
@boboquack Con (0,3), (0,2), (1,4) o variazioni simili, la sequenza sarebbe costante dopo alcuni termini.
Dennis,

Il tag [math] ha senso per questo?
mbomb007,

Risposte:


10

Gelatina , 13 12 9 byte

rSạo4¥ð@¡

Utilizza l'indicizzazione basata su 0.

Provalo online!

Come funziona

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 byte

Grazie a @Dennis per la rasatura di 6 byte!

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

Non è il codice più golfistico di sempre, ma utilizza una formula che ho creato:

inserisci qui la descrizione dell'immagine

Dove si trova xil lato destro f(n - 1)ed yè f(n - 2).

Spiegazione:

La somma di numeri interi continui da aa b(compreso) può essere descritta con questa formula:

amount * average

Dove amount(quantità di numeri) è descritta in questo modo:

((a - b) - 1)

E average(la media di tutti i numeri) è descritta in questo modo:

(a + b) / 2

Quindi la formula completa è ora:

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

Il modo di implementare questa formula nella formula finale è di sostituire aper f(n - 1), bper f(n - 2), che calcola sostanzialmente la somma di tutti i nuovi termini, e aggiungere un altro f(n - 1)(che è ora a) su, che è la somma di tutti i termini precedenti.

Combinando insieme, otteniamo:

  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

Sostituisci acon xe bcon y, e hey presto, devi formula sopra.



9

Mathematica, 49 48 byte

±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

Utilizza la codifica CP-1252. Definisce la funzione PlusMinus (±). 1-indicizzati.

Spiegazione

±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

Oasi , 11 byte

Codice:

+>bc-*2/640


Spiegazione:

Per visualizzare la relazione di f n , prendiamo l'esempio f 5 . Per calcolare f 5 , diamo un'occhiata alla seguente somma:

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

La parte in grassetto è la stessa di f 4 . La parte 7 + 8 + 9 + 10 è l'intervallo [f n-2 + 1, f n-1 - 1] . Questo rende la formula f n-1 + Σ [f n-2 + 1 ... f n-1 - 1] ( link Wolfram ):

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

Che può essere riscritto in:

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

Qual è la formula che useremo nel codice:


Spiegazione del codice

Il 640 parte ci fornisce i casi base:

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

Il codice che verrà eseguito (che definisce un (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

Provalo online!


3
Spiegazione? Questo mi ha reso più curioso di molte altre risposte.

@ ais523 Ho aggiunto una spiegazione.
Adnan,

5

Julia, 39 33 32 byte

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

0-based.

Grazie a @Dennis, risparmiato 6 byte.

Grazie a @GlenO, ho salvato un byte.

Provalo online!

Risposta precedente 1- basata:

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

Provalo online!

Risposta ungolf precedente in base 1:

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

Provalo online!


1
Per salvare un byte aggiuntivo, utilizzare n<3?5n-n^2:invece di n<4?2(n>1)n:- notare che passa all'utilizzo dell'indicizzazione basata su 0.
Glen O,

@GlenO Grazie, 1 byte salvato!
rahnema1,

4

JavaScript (ES6), 47 byte

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

Utilizza la relazione di ricorrenza che f(n) = sum(range(f(n-2) + 1, f(n-1) + 1))per n> 2.


4

PowerShell , 84 89 88 87 byte

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

Provalo online!

Spiegazione

Indicizzazione basata su 0. Funziona solo attraverso n = 6(sul mio computer Windows si arresta in modo anomalo con un overflow dello stack pern = 7 ).

Utilizzando lo stesso metodo della risposta di JungHwan Min (somma dell'intervallo meno somma dei termini precedenti).

Sommare un intervallo / array in PowerShell è lungo, quindi sto usando un trucco per unire un array +per creare un'espressione lunga (come 1+2+3+4...etc) e quindi inviarlo tramite iex(Invoke-Expression ).

Dato che devo farlo due volte, invece di usare -joinsto impostando la variabile speciale $OFS, che sta per separatore del campo di output. Quando stringi una matrice, questo è il carattere usato per unire gli elementi; per impostazione predefinita è uno spazio. Quindi impostandolo su +(una volta), posso sostituire qualcosa di simile $a-join'+'|iexa "$a"|iex.

Un semplice forciclo continua finché il conteggio delle sequenze non è inferiore o uguale all'intero di input, quindi restituisco l' $nelemento th.


@AdmBorkBork molto bello! Penso davvero che sia degno di una risposta distinta; il metodo è abbastanza diverso da non sembrare il mio se lo avessi usato.
Briantist,

1
@AdmBorkBork nice, +1, e da questo ho imparato una cosa: non è ;necessario dopo il forloop. Non l'avevo mai capito prima.
Briantist,

3

MATL , 17 16 byte

OKi:"tP:yX-sv]G)

1viene utilizzato l'indicizzazione basata su. Il codice è molto inefficiente. Perché n = 6supera già il limite di memoria del compilatore online.

Provalo online!

Come funziona

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

Per 20 byte , la versione seguente evita la limitazione della memoria. Ma c'è ancora la limitazione del tipo di dati (il doubletipo può solo garantire che gli interi siano rappresentati accuratamente fino a 2^53), quindi i risultati sono validi n = 8solo fino a .

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

Provalo anche online !


2

Haskell , 42 byte

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

Provalo online!

Questo realizza direttamente la ricorrenza che per n>2, f(n)uguale f(n-1)più la somma dell'intervallo aperto da f(n-2)a f(n-1)che è ancora pari alla somma dell'intervallo semiaperto da f(n-2)a f(n-1)inclusiva.

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 byte

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

Esempio di utilizzo: ((0:4#6)!!) 6-> 468930. Provalo online! .

Ricorsione semplice, che tiene traccia dell'elemento massimo mfinora e del valore successivo s.


Ogni volta che arrivo a una nuova sfida, qualcuno ha sempre fatto una risposta haskell migliore di qualsiasi altra cosa avrei mai potuto fare XD
theonlygusti,

Arrivo sempre ad una sfida matematica, penso "Ehi finalmente posso provare l'hashell!" CMD-F 'Haskell' - oh aspetta no, questa risposta ... aspetta, cosa? Si arrende su haskell
theonlygusti,

2

JavaScript, 123 119 byte

(a,i=x=y=0)=>{r=[0,4];while(r.length<a){x++;y=0;for(i=0;i<r[x];i++){if(!r.includes(i)){y+=i;}}r.push(y)}return r[a-1];}

Provalo online! Questa soluzione è 1-based, f(1) => 0.


2

Perl 6 ,  52 49 44  35 byte

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

Provalo

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

Provalo

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

Provalo

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

Provalo

Allargato:

{ # 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 byte

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

Provalo online!

Implementa l'algoritmo come definito ed è indicizzato 0. Ingresso di6 è troppo per essere gestita da TIO.

Imposta $aper essere un array [0,4]. Passa da 1un input all'altro $n. Nel ciclo, prendiamo l'intervallo di numeri dal 0numero più grande che abbiamo $a[-1]e usiamo una Where-Objectclausola |?{...}per estrarre solo quei numeri che non sono già presenti. Quell'array di numeri viene -joineditato insieme a +s, e quindi inviato a iex(abbreviazione di Invoke-Expressione simile a eval). Tale valore viene quindi concatenato da array alla fine di $a. Infine, usciamo dal nostro loop e prendiamo il $nnumero th nel nostro array. Quel numero è rimasto sulla pipeline e l'output è implicito.



1

Lotto, 108 byte

@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%

Porta della mia risposta JavaScript.


1

dc , 47 byte

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

Funziona con numeri interi grandi quanto vuoi, fino alla capacità di memoria del computer.

Provalo online!

Indicizzazione basata su 0, input su stdin, output su stdout. (C'è anche l'output su stderr, che deve essere ignorato.)

Esecuzioni campione:

$ 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

Questo utilizza lo stesso algoritmo della seguente soluzione in bash, che è (un po ') più leggibile:

Bash puro, 60 byte

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

Ma il programma bash funziona solo per input fino a 7, poiché supera l'overflow dei numeri interi.



0

C # - 74 byte

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
}

C'è probabilmente un modo per convertirlo in un lambda per risparmiare ancora di più, o qualcosa usando la funzione .Aggregate. Anche se al momento non ho importazioni, quindi forse pareggia?


0

> <> , 43 + 3 = 46 byte

Utilizza la formula presentata nelle risposte di Adnan e Qwerp-Derp .

:2(?^&46v
}v?=&:&l<,2*{-$@:}+1+@:{::
*>n;>4

Si aspetta che l'input sia presente nello stack, quindi +3 byte per il -vflag.

Provalo online!

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.