Reconstruire une séquence arithmétique


23

Étant donné une séquence arithmétique finie d'entiers positifs avec certains termes retirés du milieu, reconstruisez la séquence entière.

La tâche

Considérons une séquence arithmétique: une liste d'entiers positifs dans laquelle la différence entre deux éléments successifs est la même.

2 5 8 11 14 17

Supposons maintenant qu'un ou plusieurs entiers soient supprimés de la séquence, sous réserve des contraintes suivantes:

  • Les entiers supprimés seront des termes consécutifs de la séquence.
  • Le premier et le dernier entier de la séquence ne seront pas supprimés.
  • Au moins trois entiers resteront dans la séquence.

Pour la séquence ci-dessus, les suppressions possibles incluent:

2 5 8 14 17  (removed 11)
2 5 17       (removed 8 11 14)
2 14 17      (removed 5 8 11)

Votre tâche: étant donné l'une de ces séquences partielles, reconstruisez la séquence complète d'origine.

Détails

Vous pouvez supposer que l'entrée est valide (a une solution) et qu'il manque au moins un terme. Tous les nombres de la séquence seront des entiers positifs (> 0). La séquence peut avoir une différence positive ou négative entre les termes (c'est-à-dire qu'elle peut augmenter ou diminuer). Ce ne sera pas une séquence constante (par exemple5 5 5 ).

Votre solution peut être un programme complet ou une fonction . N'importe laquelle des méthodes d'entrée et de sortie par défaut sont acceptables.

Vos entrées et sorties peuvent être une chaîne (avec tout délimiteur raisonnable), une liste de chaînes ou une liste de nombres. Vous pouvez représenter les nombres dans la base qui convient à votre langue.

Veuillez mentionner toute méthode / format d'E / S inhabituel dans votre soumission, afin que d'autres puissent tester votre code plus facilement.

Cas de test

In: 2 5 8 14 17
Out: 2 5 8 11 14 17
In: 2 5 17
Out: 2 5 8 11 14 17
In: 2 14 17
Out: 2 5 8 11 14 17
In: 21 9 6 3
Out: 21 18 15 12 9 6 3
In: 10 9 5
Out: 10 9 8 7 6 5
In: 1 10 91 100
Out: 1 10 19 28 37 46 55 64 73 82 91 100

C'est ; la réponse la plus courte dans chaque langue l'emporte.



Aurait été intéressant d'avoir l'entrée sous la forme2 5 ... 17
schnaader

Réponses:


9

Haskell , 63 octets

f(a:b:c)|s<-[a,b..last c],all(`elem`s)c=s
f a=r$f$r a
r=reverse

Essayez-le en ligne!

Fonctionne essentiellement en essayant de construire le résultat de l'avant et, si cela échoue, de l'arrière. Cela utilise le fait que les premier et dernier membres de l'entrée seront toujours corrects, le fait que les membres supprimés doivent être consécutifs et le fait qu'il y aura toujours au moins trois éléments dans l'entrée. Tout ce que je dois faire, c'est supposer que les avant-derniers ou avant-derniers membres sont exacts et vérifier si cela fonctionne. Heureusement, Haskell a une très belle syntaxe pour créer des séries arithmétiques.

EDIT: merci à @xnor pour avoir signalé un bug et fourni une solution!


5
Bien que ce soit joli, il semble que cela ne fonctionne pas toujours: [1,3,4,5]donne [1,3,5].
xnor

1
Et je pense que all(`elem`s)cdevrait le réparer avec le même nombre d'octets.
xnor

6

05AB1E , 9 8 octets

Ÿs¥¿Äô€н

Essayez-le en ligne!

Explication

  • Construisez la plage [premier, ..., dernier] avec une différence de +/- 1
  • Calculer les deltas de l'entrée
  • Obtenez la valeur absolue du pgcd des deltas
  • Divisez la gamme complète en morceaux de cette taille
  • Obtenez le premier élément de chaque morceau

1 octet enregistré en utilisant gcd of deltasau lieu de min delta, inspiré par user202729


5

Brachylog v2, 9 octets

⊆.s₂ᵇ-ᵐ=∧

Essayez-le en ligne!

Ceci est une soumission de fonction. L'interpréteur Brachylog peut être fait pour évaluer une fonction comme s'il s'agissait d'un programme complet en la donnant Zcomme argument de ligne de commande; dans ce cas, l'entrée est spécifiée dans le format, par exemple, [1, 2, 4]et la sortie est retournée dans un format similaire, par exemple Z = [1, 2, 3, 4]. (Bien sûr, pour une soumission de fonction, l'entrée et la sortie ne sont pas du tout dans n'importe quel format; ce sont juste des listes.)

Cela résout en fait un problème plus difficile que celui demandé par l'OP: il élabore la séquence arithmétique la plus courte d'entiers contenant les valeurs spécifiées dans l'ordre spécifié, que les suppressions soient consécutives ou non. Parce qu'il utilise la force brute, il peut être très lent si de nombreuses valeurs sont supprimées.

Explication

Le programme comprend trois parties principales.

trouve une superséquence de l'entrée (c'est-à-dire une séquence qui a l'entrée comme sous-séquence). Lorsqu'il existe plusieurs sorties possibles d'un programme Brachylog, la sortie choisie est la première sortie dans l'ordre de départage, et l'ordre de départage est déterminé par la première commande du programme qui a une opinion à ce sujet; dans ce cas, spécifie un ordre qui privilégie les sorties courtes aux sorties longues. Ainsi, la sortie que nous obtiendrons sera la plus courte superséquence de l'entrée qui obéit aux restrictions dans le reste du programme.

.Est utilisé pour sortir la valeur qu'il considère comme entrée (c'est-à-dire la super-séquence dans ce cas), mais aussi pour affirmer qu'une condition spécifique est maintenue. En d'autres termes, nous produisons la plus courte séquence qui obéit à une condition spécifique (et ignorons les résultats intermédiaires utilisés pour voir si elle obéit à la condition).

Enfin, nous avons s₂ᵇ-ᵐ =, c'est-à-dire "tous les deltas de la séquence sont égaux", la condition que nous appliquons à la sortie. (La valeur de retour de ceci est une liste de deltas, plutôt que la super-séquence elle-même, c'est pourquoi nous avons besoin du .pour nous assurer que la bonne chose est sortie.)

Brachylog est freiné ici par le fait de ne pas avoir de commandes internes capables de gérer le calcul des deltas, d'appliquer une opération aux paires se chevauchant d'une liste, ou similaire. Au lieu de cela, nous devons dire ce que nous voulons dire explicitement: s₂ᵇtrouve toutes les ( ) sous-chaînes ( s) de longueur 2 ( ) (l'utilisation de est requise pour conserver un lien entre les inconnues dans les sous-chaînes et dans la super-séquence; le plus couramment utilisé romprait cela lien). Effectue ensuite -ᵐune soustraction sur chacune de ces paires pour produire un delta. C'est ennuyeux d'avoir à écrire cinq octets s₂ᵇ-ᵐpour quelque chose que la plupart des langages de golf modernes ont intégré, mais c'est ainsi que le codegolf se passe parfois, je suppose.


4

Python 2, 104 97 89 83 71 67 60 octets

Merci à Chas Brown d' avoir économisé 4 octets.
Merci à ovs pour avoir économisé 7 octets.

Saisissez la liste par arguments.

lambda a,b,*c:range(a,c[-1],min(b-a,c[0]-b,key=abs))+[c[-1]]

Essayez-le en ligne!

Explication:

Les éléments supprimés étant consécutifs, il suffit de vérifier les différences entre deux paires d'éléments consécutifs.


Vous pouvez économiser 3 octets en remplaçant b if b%c else cpar [c,b][b%c>0].
Chas Brown

@ChasBrown Merci, bien que j'aie rapidement trouvé une meilleure approche.
Colera Su

1
Sympa avec le key=abs! Il semble qu'à peu près, les gens omettent souvent la f=partie à moins qu'une fonction récursive soit utilisée; afin que vous puissiez économiser 2 octets de cette façon.
Chas Brown

1
Remplacez également a[-1]-a[-2]par a[2]-a[1]- la logique est la même et vous obtenez 2 autres octets.
Chas Brown


4

Pyth , 11 octets

%hS.+SQ}hQe

Essayez-le ici!

Merci à Steven H. pour avoir sauvé un octet!

Pyth , 12 octets

%.aiF.+Q}hQe

Essayez-le ici!

Comment ça marche

% .aiF. + Q} hQe ~ Programme complet.

     . + Q ~ Obtenez les deltas.
   iF ~ Réduire de GCD.
 .a ~ Valeur absolue.
% ~ Modulaire. Obtenez chaque nième élément de ...
        } ~ La plage numérique incluse entre ...
         hQ ~ Le premier élément, et ...
           e ~ Le dernier élément.

Tri préliminaire Qafin que vous puissiez trier et prendre le premier élément au lieu de abs(GCD(Q))comme %hS.+SQ}hQepour 11 octets. Suite de tests
Steven H.

3

Gelée , 8 octets

ṂrṀmIg/$

Essayez-le en ligne!

Remarques:

  • Ne fonctionne que sur une ancienne version de Jelly. ( cette validation par exemple) (où guse fractions.gcd, dont le résultat est le même que le signe d'entrée, au lieu de math.gcd, qui renvoie toujours une valeur positive).

  • Le lien TIO ci-dessus est le lien TIO Python 3, le code Python se compose du code source Jelly du commit que j'ai mentionné ci-dessus, à l'exception de tout (3 fichiers) regroupés dans le même fichier (pour TIO à exécuter) et dictionary.pya été réduit à seulement quelques lignes. Néanmoins dictionary.py, elle n'est pas liée à cette réponse, car elle n'utilise pas de chaîne compressée. (la “...»construction)

Explication:

Premièrement, comme un segment continu est supprimé et qu'il reste au moins 3 éléments, il reste deux numéros consécutifs dans l'ancienne liste et les deltas seront tous des multiples de l'étape. Par conséquent, la liste gcddes différences ( I, incréments) sera la valeur absolue de l'étape.

Heureusement le gcdest signé (voir note ci-dessus)

Le programme:

ṂrṀ

Une gamme entière croissante de l' inimum à l' aximum.

m

Modulaire, choisissez chaque élément n.

Ig/$

La $chaîne monadique ( ) combine I(incréments, différences) et g/(réduit gcdles éléments de la liste). Si les incréments sont positifs, le gcdsera positif et la liste de retour sera de gauche à droite (croissante), et vice-versa.


Yay! Bat la réponse 05AB1E d'un octet!
user202729

Utiliser gcdau lieu de minnous a fait attacher. Dommage que j'obtienne un gcd avec signe, sinon je serais à 7;)
Emigna

3

MATL , 13 octets

1)0GdYkG0)3$:

Essayez-le en ligne!

Explication:

Consider the example input [2 14 17]:
           # implicit input, STACK: [[2 14 17]]
1)         # push 1, index, STACK: [2]
0G         # push 0, duplicate input, STACK: [2, 0, [2 14 17]]
d          # take differences, STACK: [2, 0, [12, 3]]
Yk         # get value in [12, 3] nearest to 0, STACK: [2, 3]
G0)        # get last element in input, STACK: [2, 3, 17]
3$:        # 3-input :, computes 2:3:17, the range from 2 to 17 by 3
           # STACK: [[2 5 8 11 14 17]], implicit output.


3

JavaScript (ES6), 92 90

Modifier 2 octets enregistrés thx Arnauld

Facile, car il suffit de vérifier les différences entre les deux premiers et les deux derniers. Mais toujours incroyablement long.

s=>(e=(z=s.pop(a=s[0]))-s.pop(d=s[1]-a),[...Array((z-(a-=d=e*e>d*d?d:e))/d)].map(_=>a+=d))

Moins golfé

s=>{
  a =s[0]
  b =s[1]
  z = s.pop()
  y = s.pop()
  d = b-a
  e = z-y
  d = e*e>d*d?d:e  
  n = (z-a)/d+1
  return [...Array(n)].map((_,i) => a + i*d)
}

Tester

var F=
s=>(e=(z=s.pop(a=s[0]))-s.pop(d=s[1]-a),[...Array((z-(a-=d=e*e>d*d?d:e))/d)].map(_=>a+=d))

var test=`In: 2 5 8 14 17 Out: 2 5 8 11 14 17
In: 2 5 17 Out: 2 5 8 11 14 17
In: 2 14 17 Out: 2 5 8 11 14 17
In: 21 9 6 3 Out: 21 18 15 12 9 6 3
In: 10 9 5 Out: 10 9 8 7 6 5
In: 1 10 91 100 Out: 1 10 19 28 37 46 55 64 73 82 91 100`.split`\n`
.map(r=>r.split`Out`.map(x=>x.match(/\d+/g)))

test.forEach(([i,k])=>{
  var o=F(i.slice(0))
  var ok = o+''==k
  console.log(ok?'OK':'KO',i+' => '+o)
})


a-=d=e*e>d*d?d:edevrait fonctionner et enregistrer 2 octets.
Arnauld

@Arnauld ça marche vraiment merci
edc65

2

Wolfram Language (Mathematica) , 50 octets

Range[#&@@#,#[[-1]],#&@@Differences@#~SortBy~Abs]&

Essayez-le en ligne!


Est-ce qu'une "liste de nombres" inclut le fait d'avoir les nombres comme arguments individuels? Si c'est le cas, il semble que vous pourriez économiser un bon nombre d'octets.
numbermaniac

@numbermaniac Je ne pense pas, car il n'y a pas de fonction intégrée qui récupère la dernière entrée ...
JungHwan Min

Ahh ... c'est vrai. J'ai oublié ça.
numbermaniac

Vous pouvez utiliser {##}et Last@{##}mais le meilleur que j'ai pu obtenir était de 51 octets.
numbermaniac


1

Haskell , 73 69 octets

f(h:t)=do(#)<-[(-),(+)];[h,h#minimum(abs<$>zipWith(-)t(h:t))..last t]

Essayez-le en ligne!


1
J'ai trouvé une solution de 63 octets mais elle est assez différente de la vôtre. Dois-je faire un article séparé?
user1472751

@ user1472751 Je ne suis pas Laikoni, mais ce site était destiné à la compétition, ainsi qu'à la collaboration. Je le posterais donc.
H.PWiz

@ user1472751 Belle approche! Veuillez continuer et l'afficher comme votre propre réponse.
Laikoni

1

J , 49, 47 46 octets

(0-[:<./2|@-/\]){.@[&]\({.<.{:)+[:i.{:(+*)@-{.

Inspiré par la solution d'Emigna.

Comment ça marche:

 (0-[:<./2|@-/\]){.@[&]\({.<.{:)+[:i.{:(+*)@-{. - fork of 3 verbs

                        ({.<.{:)+[:i.{:(+*)@-{. - generates a list in the entire range of values
                                     {:     -{. - last minus first element  
                                       (+*)@    - adds the signum of the difference
                                 [:i.           - makes a list 
                       ({.<.{:)                 - the smallest of first and last elements                                     
                               +                - adds the offset to the list (translates all elements according to the first one)

 (0-[:<./2|@-/\])                               - finds the step
         2|@-/\]                                - the absolute differences between all consecutive elements
    [:<./                                       - the smallest one
  0-                                            - negate (for splitting)

                 {.@[&]\                        - splits the list from the right verb into left verb's result sublists and takes their first elements

Essayez-le en ligne!


1

Coque , 9 octets

m←C▼Ẋ≠⁰…⁰

Essayez-le en ligne!

Merci beaucoup à H.PWiz d' avoir divisé par deux le nombre d'octets, en soulignant que l'application sur une liste le classifie! ...


@ HP.Wiz X_X Je ne savais pas que Husk listait des plages comme ça ... Etes-vous sûr de ne pas le poster comme votre propre réponse?
M. Xcoder

@ HP.Wiz Merci beaucoup !
M. Xcoder

Peut également F⌋être remplacé par ?
H.PWiz

@ H.PWiz @ _ @ Pourquoi cela fonctionne-t-il même?
M. Xcoder

La plus petite différence (absolue) sera la différence d'origine. La seule raison gcdétait de gérer les deltas négatifs
H.PWiz

1

C # (.NET Core) , 167 + 13 = 180 145 + 13 = 158 octets

a=>{int x=a[1]-a[0],y=a[2]-a[1],d=x*x<y*y?x:y,s=Math.Abs((a[a.Length-1]-a[0])/d),i=0,j=a[0];var r=new int[s+1];for(;i<=s;j+=d)r[i++]=j;return r;}

Essayez-le en ligne!

+13 pour using System;

Étonnamment, ce défi avait plus de nuances que je l'avais initialement prévu.

Remerciements

-22 octets enregistrés grâce à quelques simplifications soignées de @DLosc.

DeGolfed

a=>{
    int x = a[1]-a[0],        // difference between first and second numbers
        y = a[2]-a[1],        // difference between second to last and last numbers
        d = x*x < y*y? x : y, // smallest absolute value difference
        s = Math.Abs((a[a.Length-1] - a[0]) / d), // number of steps in the reconstructed sequence (not the number of elements)
        i = 0,                // step position
        j = a[0];             // next number in reconstructed sequence

    var r = new int[s+1];

    // reconstruct the sequence
    for(; i <= s; j+=d)
        r[i++]=j;

    return r;
}

0

Python 2 , 147 octets

from fractions import*
a=input()
b=[j-i for i,j in zip(a[:-1],a[1:])]
l=min(gcd(i,j)for i in b for j in b)
print list(range(a[0],a[-1]+l/abs(l),l))

Essayez-le en ligne!





0

Japt , 12 octets

ÌõUg Uäa ñ g

Essayez-le


Explication

Générez un tableau d'entiers ( õ) du dernier élément du tableau d'entrée ( Ì) au premier ( Ug). Calculez le pas entre les éléments en obtenant les deux paires d'éléments de l'entrée et en les réduisant par différence absolue ( Uäa) puis en triant ( ñ) ce tableau et en prenant le premier élément ( g).

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.