Réparer les gammes

30

Étant donné l'entrée d'une liste d'entiers positifs dont certains ont été remplacés par 0, affichez la liste avec les nombres manquants qui ont été 0remplacés par.

Caractéristiques de la liste d'entrée:

  • La liste aura toujours une longueur d'au moins 2.

  • Définissons la liste d'entrée comme aet la "liste d'origine" (c'est-à-dire la liste avant que les nombres aient été remplacés par 0s) comme b. Pour tout n, a[n]c'est soit b[n]ou 0.

  • Pour tout n, b[n]c'est soit b[n-1] + 1ou b[n-1] - 1. C'est-à-dire que les nombres en bchangeront toujours de 1chaque index par rapport au précédent. Le premier élément est bien entendu exempté de cette règle.

  • Pour chaque série de zéros dans a(c'est-à-dire les éléments consécutifs remplacés par 0), avec xreprésentant l'index du début de la série et y représentant la fin, a[x-1]to a[y+1]sera toujours soit uniquement en augmentation soit uniquement en diminution. Par conséquent, il n'y aura qu'une seule façon possible de remplir les zéros.

    • Cela signifie également que ni le premier ni le dernier élément du tableau ne peuvent être des zéros.

En termes plus simples, pour remplir une série de zéros, remplacez-le simplement par une plage allant du nombre précédent au nombre suivant. Par exemple, une entrée de

1 2 0 0 0 6 7

doit sortir

1 2 3 4 5 6 7

Puisqu'il s'agit de , le code le plus court en octets gagnera.

Cas de test:

In                      Out
-----------------------------------------------------
1 0 0 0 5 6 0 4 0 0 1 | 1 2 3 4 5 6 5 4 3 2 1
7 6 0 0 3 0 0 0 7 0 5 | 7 6 5 4 3 4 5 6 7 6 5
1 0 3 0 5 0 3 0 5 0 7 | 1 2 3 4 5 4 3 4 5 6 7
14 0 0 0 0 0 0 0 0 23 | 14 15 16 17 18 19 20 21 22 23
Poignée de porte
la source
Au lieu de, 0notre programme peut-il prendre une autre valeur telle que null?
Downgoat
@Downgoat Non, les chiffres manquants doivent être indiqués comme 0.
Poignée de porte

Réponses:

15

JavaScript (ES6), 72 66 64 54 53 octets

12 octets enregistrés grâce à @Neil!

1 octet enregistré grâce à @IsmaelMiguel

a=>a.map((l,i)=>l?b=l:b+=a.find((q,r)=>r>i&&q)>b||-1)

Très bon pour JavaScript.


Essayez-le en ligne (tous les navigateurs fonctionnent)

Explication

a=>  // Function with arg `a`
  a.map((l,i)=>  // Loop through input
    l?             // If nonzero
      b=l          // Set `b` to current number
    :a.find((q,r)=>r>i&q) // Otherwise look for the next nonzero number
     >b?           // If it's increased since nonzero last number   
       ++b:--b)    // Increasing? increase `b` (the previous nonzero number)
                   // otherwise decrease `b`
Downgoat
la source
1
Je pense que a.find((q,r)=>r>i&&q)>b?++b:--bc'est la même chose queb+=a.find((q,r)=>r>i&&q)>b||-1
Ismael Miguel
@IsmaelMiguel c'est intelligent, merci!
Downgoat
De rien. Je suis content que ça a marché pour vous.
Ismael Miguel
Je pense que vous pouvez remplacer && par juste & (Je viens de remarquer que vous avez un & dans l'explication et deux dans la réponse)
Charlie Wynn
7

MATL , 11 12 octets

fGXzGn:3$Yn

Fonctionne avec la version actuelle (13.0.0) du langage / compilateur.

Essayez-le en ligne!

f        % implicitly input array. Indices of nonzero elements (*)
GXz      % push input and get its nonzero elements (**)
Gn:      % vector [1,2,...,n], where n is input length (***)
3$Yn     % interpolate at positions (***) from data (**) defined at positions (*)
Luis Mendo
la source
7

Haskell, 68 61 58 octets

g(a:b:r)=[a..b-1]++[a,a-1..b+1]++g(b:r)
g x=x
g.filter(>0)

Exemple d'utilisation: g.filter(>0) $ [7,6,0,0,3,0,0,0,7,0,5]-> [7,6,5,4,3,4,5,6,7,6,5].

Comment ça marche: supprimez les zéros de l'entrée, puis appelez g. Soit ale premier bpuis le deuxième élément de la liste restante. Concaténer les listes de ahaut en bas b-1et de abas en haut b+1(l'une d'entre elles sera vide) et un appel récursif avec aabandon.

Modifier: @Zgarb a enregistré 3 octets. Merci!

nimi
la source
6

Mathematica, 59 octets

#//.{a___,x_,0..,y_,b___}:>{a,##&@@Range[x,y,Sign[y-x]],b}&

Cas de test

%[{1,0,3,0,5,0,3,0,5,0,7}]
(* {1,2,3,4,5,4,3,4,5,6,7} *)
njpipeorgan
la source
4

Perl, 47 45 44 39 37 octets

Comprend +1 pour -p

s%\S+%$p+=/\G(0 )+/?$'<=>$p:$&-$p%eg

Attend la liste sur stdin. Exemple: écho 1 0 3 0 1 | perl -p fichier.pl

Ton Hospel
la source
Je vois des copies collées ici .. ;-) Joliment fait btw.
Kenney
3

Gelée, 12 11 octets

ḢWW;ḟ0Ṫr¥\F

Essayez-le en ligne!

Version alternative, 8 octets (non concurrent)

Malheureusement, Jelly's popn'a pas été lancé en version itérable, dans la dernière version antérieure à ce défi. Ce problème a été corrigé et les éléments suivants fonctionnent dans la version actuelle.

ḟ0Ṫr¥\FḊ

Essayez-le en ligne!

Comment ça marche

ḢWW;ḟ0Ṫr¥\F  Main link. Input: A (list)

Ḣ            Pop the first element of A. Let's call it a.
 WW          Yield [[a]].
   ;         Concatenate with the popped A.
             This wraps the first element of A in an array.
    ḟ0       Filter; remove all zeroes.
        ¥    Create a dyadic chain:
      Ṫ        Pop the last element of the left argument.
       r       Call range on the popped element and the right argument.
         \   Reduce the modified A by this chain.
          F  Flatten the resulting list of ranges.

Dans la version alternative, ḢWW;devient inutile. Cependant, étant donné que le premier élément est converti en itérable avant l'éclatement, il n'est pas réellement modifié. La finale supprime le doublon du premier élément.

Dennis
la source
3

Rétine, 39 34 31 octets

3 octets enregistrés grâce à @Martin.

+`1(1*) (?= +((1)\1)?)
$0$1$3$3

Prend l'entrée et donne la sortie en unaire.

Le code remplit de manière itérative tous les espaces vides (0) avec previous_number - 1 + 2 * if_next_nonzero_number_bigger. previous_number - 1est $1etif_next_nonzero_number_bigger est$3 .

Avec les E / S décimales, le code fait 51 octets, comme vous pouvez le voir dans l' interpréteur en ligne avec tous les cas de test .

randomra
la source
Vous pouvez enregistrer un autre octet en omettant le premier 1dans la tête de lecture.
Martin Ender
@ MartinBüttner Right, édité.
randomra
2

GNU Sed (avec exec extension utilisant bash), 61

Le score inclut +1 pour l' -roption de sed.

:
s/( 0)+ /../
s/\w+..\w+/{&}/
s/.*/bash -c 'echo &'/e
/ 0/b
  • Trouver des séries de 0s et les remplacer..
  • Placez des accolades autour des numéros de point de terminaison pour créer une expansion d'accolade bash comme {1..4}pour les points de terminaison locaux. La beauté des extensions d'accolade bash ici est que la séquence générée s'exécutera toujours dans la bonne direction, que le début ou la fin soit plus grand.
  • Utilisez l' eoption de la scommande pour appeler bash afin d'évaluer cette extension d'accolade
  • Si d'autres 0s sont trouvés, revenez au début.

Ideone.

Traumatisme numérique
la source
2

Python 2, 195 111 octets (merci Alex !)

t=input()
z=0
for i,e in enumerate(t):
 if e:
  while z:t[i-z]=e+z if l>e else e-z;z-=1
  l=e
 else:z+=1
print t

Entrée: doit être une valeur en [list]pouces
Sortie: en [list]pouces

vageli
la source
Désolé pour ça! Fixé. Merci pour l'information.
vageli
Pas de soucis. Belle solution. :) Vous pouvez le réduire à 112 octets en utilisant ceci , qui est votre même approche, juste un peu plus de golf. Nous avons également une collection de conseils pour jouer au golf en Python ici .
Alex A.
1

Perl, 85 82 octets

comprend +1 pour -p

s/(\d+)(( 0)+) (\d+)/$s=$1;$e=$4;$_=$2;$c=$s;s!0!$c+=$e<=>$s!eg;"$s$_ $e"/e&&redo

Attend la liste sur stdin. Exemple: echo 1 0 3 0 1 | perl -p file.pl.

Cela utilise une expression rationnelle imbriquée. Assez lisible:

s/(\d+)(( 0)+) (\d+)                  # match number, sequence of 0, number
 /
    $s=$1;                            # start number
    $e=$4;                            # end number
    $_=$2;                            # sequence of ' 0'
    $c=$s;                            # initialize counter with start number
    s!0! $c += $s <=> $e !eg          # replace all 0 with (in|de)cremented counter
    "$s$_ $e"                         # return replacement
 /e
&& redo                               # repeat until no more changes.
Kenney
la source
1

Python 2, 92 88 octets

(Variable intermédiaire supprimée)

t=filter(bool,input())
print sum([range(o,p,cmp(p,o))for o,p in zip(t,t[1:])],[])+t[-1:]
Orez
la source
1

Pyth, 17 octets

u+G+treGHHfTtQ[hQ

La façon dont cela fonctionne:

u                 reduce
              [hQ     seed: the first element of input, in a list
                      iterable:
          tQ              all except the first element of input
        fT                remove if 0
                      lambda: G is the list to be returned, H is the current item
 +G                       append to return list
    reGH                  a range from the last element of the return list and the current item
   +                      concatenated with
        H                 the last item (this step forms a bidirectional inclusive list)

En d'autres termes: tous les zéros sont supprimés de l'entrée, puis une plage exclusive est insérée entre chaque élément. Cette plage est de longueur nulle sur des éléments séparés d'un seul.

Cameron McCluskie
la source
1

Vim: 231 commandes clés

Notez que tout ^ précédant un caractère signifie que vous devez garder le contrôle tout en tapant ce caractère

mbomayiwo^V^R"^V^V^V^X ^V^["sy0dd`a@f ^["bc0yiwo^V^V^V^X^V^R"^V^[0l@sa^V^V^V^A-^V^[0f-"ayhdd`a@i ^["dc0mbyiwo^V^R"Exe@b^V^[0fel"ty2ldd`b@t ^["ec0wmbyiwo@f @d^V^[@z ^["fc0"xyiwwmbyiwocw^V^V^V^Rx^V^V^V^[@a@i @e^V^[@z ^["ic0IB0 B^V^R" ^V^OWB0 ^V^OA B0^V^[0*w"tyiWdd`b@t ^["zd0dd`bAe^[0@e 

Étapes pour que vous puissiez exécuter cela aussi!

  1. Copiez la ligne dans Vim
  2. Tapez :s/\^V/<Ctrl-V><Ctrl-V>/get appuyez sur Entrée (les deux s devraient vous donner un ^ V bleu)
  3. Tapez :s/\^R/<Ctrl-V><Ctrl-R>/get appuyez sur Entrée (vous devriez voir bleu ^ Rs maintenant)
  4. Tapez :s/\^X/<Ctrl-V><Ctrl-X>/get appuyez sur Entrée (vous devriez voir des ^ Xs bleus maintenant)
  5. Tapez :s/\^O/<Ctrl-V><Ctrl-O>/get appuyez sur Entrée
  6. Tapez :s/\^A/<Ctrl-V><Ctrl-A>/get appuyez sur Entrée
  7. Tapez :s/\^\[/<Ctrl-V><Ctrl-[>/get appuyez sur Entrée (cette commande est légèrement différente car j'avais besoin d'échapper au [)
  8. Tapez 0"yy$. La commande est maintenant stockée dans le registre y
  9. Configurer l'entrée sur une ligne et exécuter avec @y

Si quelqu'un connaît une meilleure façon de partager la commande, faites-le moi savoir. Je sais que c'est long, mais c'est le mieux que j'ai pu trouver.

Entrée sortie

La chaîne d'entrée doit être seule sur n'importe quelle ligne du fichier. 1 0 0 4 3 0 0 0 7

La sortie remplacera simplement la chaîne d'entrée 1 2 3 4 3 4 5 6 7

Explication

Algorithme

  1. Commencez avec un nombre différent de zéro, assurez-vous que ce n'est pas le dernier nombre
  2. Trouver le prochain nombre non nul
  3. Prenez leur différence. Si la réponse est négative, vous devez décrémenter pour réparer la plage, sinon, incrémenter pour réparer la plage.
  4. Revenez au premier caractère et remplacez chaque zéro en incrémentant / décrémentant le nombre précédent.
  5. Répétez jusqu'à ce que vous arriviez au dernier caractère

Macros utilisées

@e - Vérifiez la fin. Le dernier numéro sera accompagné d'un e. Si le nombre sous le curseur a un e à la fin, supprimez le e et arrêtez l'exécution. Sinon, démarrez un cycle d'interpolation avec @b.

mbyiwo^R"Exe@b^[0fel"ty2ldd`b@t

@b - Commence le cycle d'interpolation. Enregistrez le nombre sous le curseur pour une opération de soustraction (@s) puis recherchez le terme non nul suivant (@f)

mayiwo^R"^V^X ^["sy0dd`a@f

@s - Stocke la commande de soustraction à utiliser dans @d. C'est simplement (val)^X(val)est le nombre au début de l'étape d'interpolation. Ceci est défini par la commande @b.

@f - Trouver le prochain terme non nul. Écrivez la valeur actuelle dans le registre sans nom, puis écrivez @f @dsur la ligne suivante, puis exécutez @z. Cela répétera cette commande si le nombre est un zéro et exécutera @d s'il ne l'est pas.

wmbyiwo@f @d^[@z

@z - Exécution conditionnelle si le registre sans nom est 0. Cette commande attend deux commandes sur une nouvelle ligne au format command1 command2. Si le registre sans nom est 0, command1est exécuté, sinon command2est exécuté. Notez qu'aucune commande ne peut contenir d'espace.

 IB0 B^R" ^OWB0 ^OA B0^[0*w"tyiWdd`b@t`

@t - Registre de commande temporaire. Stocke diverses commandes pendant une courte période avant de les exécuter. Utilisé principalement dans les instructions if.

@d - Détermine la direction d'interpolation. Soustrait le premier nombre de la séquence du nombre sous le curseur (en utilisant @s). Si le résultat est négatif, l'interpolation doit diminuer afin que ^ X soit enregistré dans @a. Sinon, nous devons incrémenter pour que ^ A soit enregistré dans @a. Une fois que cela est enregistré, revenez au début de ce cycle d'interpolation et exécutez @i pour réellement interpoler

yiwo^V^X^R"^[0l@sa^V^A-^[0f-"ayhdd`a@i

@a - Stocke ^Aou ^Xpour incrémenter ou décrémenter pendant l'étape d'interpolation. Ceci est défini par la commande @d.

@i - Interpoler. Copiez le numéro de l'emplacement actuel dans @x et passez au numéro suivant. Si ce nombre est nul, remplacez-le par @x et exécutez @a pour le modifier correctement vers le haut ou vers le bas, puis répétez cette commande. Si le nombre n'est pas un zéro, nous avons atteint la fin de ce cycle d'interpolation. Un nouveau doit être démarré avec ce numéro comme début, donc exécutez @e pour vérifier la fin et recommencez.

"xyiwwmbyiwocw^V^Rx^V^[@a@i @e^[@z

@x - Registre de stockage temporaire. Utilisé dans la commande interpoler (@i)

Décomposer les frappes

mbo :Set b mark to current position and open a new line below to write macros
mayiwo^V^R"^V^V^V^X ^V^["sy0dd`a@f ^["bc0 :Write to @b and reset line

yiwo^V^V^V^X^V^R"^V^[0l@sa^V^V^V^A-^V^[0f-"ayhdd`a@i ^["dc0 :Write to @d and reset line

mbyiwo^V^R"Exe@b^V^[0fel"ty2ldd`b@t ^["ec0 :Write to @e and reset line

wmbyiwo@f @d^V^[@z ^["fc0 :Write to @f and reset line

"xyiwwmbyiwocw^V^V^V^Rx^V^V^V^[@a@i @e^V^[@z ^["ic0 :Write to @i and reset line

IB0 B^V^R" ^V^OWB0 ^V^OA B0^V^[0*w"tyiWdd`b@t ^["zd0 :Write to @z and reset line

dd`b :Delete this line and move cursor back to original line

Ae^[ :Append an e to the last number

0@e  :Move to the beginning of the line and run
Dominic A.
la source
0

Python 3.5, 159 octets

une solution récursive

def f(s):
 h=s[0]
 g=lambda s,h,v:h*(h[-1]==s[0])if len(s)==1else(g(s[1:],h+[h[-1]-v],-v)+g(s[1:],h+[h[-1]+v],+v))*(s[0]==0 or h[-1]==s[0])
 return g(s,[h],1)

Non golfé

def f(s):
    h=s[0]
    def g(s,h,v):
        if len(s)==1:
            if h[-1]!=s[0]:
                r=[]
            else:
                r=h
        else:
            if s[0]==0:
                r=g(s[1:],h+[h[-1]+v],v)
            elif h[-1]!=s[0]:
                r=[]
            else:
                r=g(s[1:],h+[h[-1]-v],-v)+g(s[1:],h+[h[-1]+v],+v)
        return r
return g(s,[h],1)

Dans la solution golfée, je remplace les conditions en utilisant le fait que h*True=heth*False=[]

Résultat

>>> f([7, 6, 0, 0, 3, 0, 0, 0, 7, 0, 5])
[7, 6, 5, 4, 3, 4, 5, 6, 7, 6, 5]
Erwan
la source
0

Perl 6 , 54 octets

{$_=$^a;1 while s/:s(\d+) 0 + (\d+)/{+~$0...+~$1}/;$_}
smls
la source
0

MATLAB, 39 38 37 octets

@(a)interp1(find(a),a(a>0),find(a/0))

Fonction anonyme qui interpole linéairement entre les points dans a. find(a)est un tableau d'indices d'éléments non nuls dans aet a(a>0)sont les valeurs positives. Enregistré 1 octet grâce à la suggestion d'un ami >plutôt que ~=.

MattWH
la source