Une séquence de sommes d'entiers qui ne sont pas dans la séquence


28

Contexte

Considérons une séquence définie comme suit:

  • Le premier élément est 0;
  • Le deuxième élément est 4;
  • A partir du troisième élément, sa valeur peut être calculée par:
    • Prendre l'ensemble des entiers de 0 à l'élément précédent de la séquence (inclusif ou exclusif, peu importe);
    • Supprimer tous les entiers qui sont déjà apparus plus tôt dans la séquence de l'ensemble;
    • Additionner les éléments restants de l'ensemble; c'est la valeur que vous voulez.

Fait intéressant, cette séquence ne semble pas encore être sur OEIS .

La tâche

Écrivez un programme ou une fonction qui prend un entier n en entrée et génère le n ème élément de la séquence.

Cas de test

Les premiers éléments de la séquence sont:

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

Clarifications

  • Votre programme devrait en théorie être capable de gérer arbitrairement n s'il est exécuté sur une variante de votre langue qui a des nombres entiers sans limites et un accès à une quantité illimitée de mémoire. (Il est peu probable que les langues sans bignum puissent aller bien au-delà de 468930, mais ce n'est pas une excuse pour coder en dur les réponses.)
  • Vous pouvez choisir une indexation basée sur 0 ou 1 pour la séquence (par exemple, c'est à vous de décider si n = 1 renvoie le premier élément, n = 2 le deuxième élément, etc.) ou si n = 0 renvoie le premier élément , n = 1 le deuxième élément, etc.).
  • Il n'y a aucune exigence sur l'algorithme que vous utilisez, ni sur son efficacité; vous pouvez implémenter directement la définition de la séquence (même si elle est vraiment inefficace), et vous pouvez également implémenter un algorithme différent qui conduit aux mêmes résultats.

Condition de victoire

Il s'agit de , donc le programme correct le plus court, mesuré en octets, gagne.


1
Pourquoi ne pas autoriser une sortie infinie au lieu de prendre une entrée?
John Dvorak

2
@JanDvorak: Parce que cela oblige tous les programmes à utiliser des algorithmes qui génèrent chaque terme; cette méthode de rédaction de la question laisse aux répondants le choix de le faire ou d'utiliser une formule fermée (en supposant qu'il y en ait une). Cela donne donc plus de choix de stratégies pour résoudre la question.

1
Je suppose que la séquence n'est pas là parce que 0,4 est un décalage étrange
boboquack

1
@boboquack Avec (0,3), (0,2), (1,4) ou des variations similaires, la séquence serait constante après quelques termes.
Dennis

La balise [math] a-t-elle un sens à cela?
mbomb007

Réponses:


10

Gelée , 13 12 9 octets

rSạo4¥ð@¡

Utilise l'indexation basée sur 0.

Essayez-le en ligne!

Comment ça marche

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 octets

Merci à @Dennis d'avoir rasé 6 octets!

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

Ce n'est pas le code le plus golfique de tous les temps, mais il utilise une formule que j'ai faite:

entrez la description de l'image ici

Où se trouve xsur le côté droit f(n - 1), et yest f(n - 2).

Explication:

La somme des entiers continus de aà b(inclus) peut être décrite par cette formule:

amount * average

amount(quantité de nombres) est décrit comme suit:

((a - b) - 1)

Et average(la moyenne de tous les nombres) est décrite comme suit:

(a + b) / 2

Donc, la formule complète est maintenant:

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

La façon dont nous mettons en œuvre cette formule dans la formule finale consiste à substituer aà f(n - 1), bpour f(n - 2), qui calcule essentiellement la somme de tous les nouveaux termes, et ajouter une autre f(n - 1)(qui est maintenant a) sur, qui est la somme de tous les termes précédents.

En combinant cela ensemble, nous obtenons:

  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

Remplacez apar xet bpar y, et hé hop, vous devez faire la formule ci-dessus.



9

Mathematica, 49 48 octets

±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

Utilise l'encodage CP-1252. Définit la fonction PlusMinus (±). 1 indexé.

Explication

±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

Oasis , 11 octets

Code:

+>bc-*2/640


Explication:

Pour visualiser la relation de f n , prenons l'exemple f 5 . Pour calculer f 5 , regardons la somme suivante:

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

La partie en gras est identique à f 4 . La partie 7 + 8 + 9 + 10 est la plage [f n-2 + 1, f n-1 - 1] . Cela fait la formule f n-1 + Σ [f n-2 + 1 ... f n-1 - 1] ( lien Wolfram ):

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

Qui peut être réécrit en:

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

Quelle est la formule que nous utiliserons dans le code:


Explication du code

La 640partie nous donne les cas de base:

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

Le code qui sera exécuté (qui définit 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

Essayez-le en ligne!


3
Explication? Cela m'a rendu plus curieux que la plupart des autres réponses.

@ ais523 J'ai ajouté une explication.
Adnan

5

Julia, 39 33 32 octets

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

Basé sur 0.

Merci à @Dennis, économisé 6 octets.

Merci à @GlenO, a sauvé un octet.

Essayez-le en ligne!

Réponse précédente 1- basée:

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

Essayez-le en ligne!

Réponse précédente non golfée basée sur 1:

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

Essayez-le en ligne!


1
Pour enregistrer un octet supplémentaire, utilisez n<3?5n-n^2:plutôt que n<4?2(n>1)n:- notez qu'il passe à l'utilisation de l'indexation basée sur 0, cependant.
Glen O

@GlenO Merci, 1 octet enregistré!
rahnema1

4

JavaScript (ES6), 47 octets

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

Utilise la relation de récurrence f(n) = sum(range(f(n-2) + 1, f(n-1) + 1))pour n> 2.


4

PowerShell , 84 89 88 87 octets

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

Essayez-le en ligne!

Explication

Indexation basée sur 0. Fonctionne uniquement n = 6(sur ma machine Windows, il se bloque avec un débordement de pile pour n = 7).

En utilisant la même méthode que la réponse de JungHwan Min (somme de la plage moins somme des termes précédents).

La somme d'une plage / d'un tableau dans PowerShell est longue, j'utilise donc une astuce pour joindre un tableau avec +pour créer une expression longue (comme 1+2+3+4...etc), puis l'envoyer via iex( Invoke-Expression).

Étant donné que je dois le faire deux fois, au lieu d'utiliser, -joinje définis la variable spéciale $OFS, qui signifie séparateur de champ de sortie. Lorsque vous chaînez un tableau, c'est le caractère utilisé pour joindre les éléments; c'est un espace par défaut. Donc, en le définissant sur +(une fois), je peux remplacer quelque chose comme $a-join'+'|iexavec "$a"|iex.

Une simple forboucle continue jusqu'à ce que le nombre de séquences soit inférieur ou égal à l'entier d'entrée, puis je retourne le $ne élément.


@AdmBorkBork très sympa! Je pense vraiment que cela mérite une réponse distincte; la méthode est suffisamment différente pour ne pas ressembler à la mienne si je l'utilisais.
briantist

1
@AdmBorkBork nice, +1, et j'ai appris une chose de cela: pas ;besoin après la forboucle. Je n'avais jamais réalisé ça auparavant.
briantist

3

MATL , 17 16 octets

OKi:"tP:yX-sv]G)

1l'indexation basée sur est utilisée. Le code est très inefficace. Car n = 6il dépasse déjà la limite de mémoire du compilateur en ligne.

Essayez-le en ligne!

Comment ça marche

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

Pour 20 octets , la version suivante évite la limitation de mémoire. Mais il y a toujours la limitation du type de données (le doubletype ne peut garantir que les entiers sont représentés avec précision jusqu'à 2^53), donc les résultats ne sont valides que jusqu'à n = 8.

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

Essayez-le aussi en ligne !


2

Haskell , 42 octets

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

Essayez-le en ligne!

Cela implémente directement la récurrence qui, pour n>2, f(n)est égal à f(n-1)plus la somme de l'intervalle ouvert à partir f(n-2)de f(n-1)laquelle est à nouveau égal à la somme de l'intervalle semi-ouvert de f(n-2)à f(n-1)inclusif.

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 octets

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

Exemple d'utilisation: ((0:4#6)!!) 6-> 468930. Essayez-le en ligne! .

Récursivité simple, qui garde mjusqu'à présent l' élément maximum et la valeur suivante s.


Chaque fois que je relève un nouveau défi, quelqu'un a toujours fait une réponse haskell meilleure que toutes celles que je pourrais jamais faire XD
theonlygusti

J'arrive toujours à un défi mathématique, je me dis "Hé, enfin je peux essayer haskell!" CMD-F 'Haskell' - oh attendez non, cette réponse ... attendez, quoi?
Abandonne

2

JavaScript, 123 119 octets

(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];}

Essayez-le en ligne! Cette solution est basée 1, f(1) => 0.


2

Perl 6 ,  52 49 44  35 octets

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

Essayez-le

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

Essayez-le

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

Essayez-le

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

Essayez-le

Étendu:

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

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

Essayez-le en ligne!

Implémente l'algorithme tel que défini et est indexé 0. L'entrée de 6est trop pour TIO à gérer.

Définit $acomme un tableau [0,4]. Boucles de l' 1entrée à l'entrée $n. Dans la boucle, nous prenons la plage de nombres du 0plus grand nombre que nous avons $a[-1], et utilisons une Where-Objectclause |?{...}pour extraire uniquement les nombres qui ne sont pas déjà présents. Ce tableau de nombres est -joinédité avec +s, puis alimenté iex(abréviation de Invoke-Expressionet similaire à eval). Cette valeur est ensuite concaténée en tableau à la fin de $a. Enfin, nous quittons notre boucle et prenons le $nnuméro e dans notre tableau. Ce nombre est laissé sur le pipeline et la sortie est implicite.



1

Lot, 108 octets

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

Port de ma réponse JavaScript.


1

dc , 47 octets

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

Fonctionne avec des entiers aussi grands que vous le souhaitez, jusqu'à la capacité de mémoire de l'ordinateur.

Essayez-le en ligne!

Indexation basée sur 0, entrée sur stdin, sortie sur stdout. (Il y a aussi une sortie sur stderr, qui doit être ignorée.)

Exemples de cycles:

$ 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

Cela utilise le même algorithme que la solution suivante dans bash, qui est (un peu) plus lisible:

Pure bash, 60 octets

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

Mais le programme bash ne fonctionne que pour les entrées jusqu'à 7, car il dépasse le dépassement d'entier.



0

C # - 74 octets

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;}

Non golfé:

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
}

Il existe probablement un moyen de le convertir en lambda pour économiser encore plus, ou quelque chose en utilisant la fonction .Aggregate. Bien qu'actuellement je n'aie pas d'importations, alors peut-être que ça égalise?


En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.