Gardez les nonzeros et leurs voisins


26

Tiré de cette question à Stack Overflow. Merci également à @miles et @Dada d'avoir suggéré des entrées de test qui répondent à certains cas de coin.

Le défi

Étant donné un tableau de valeurs entières, supprimez tous les zéros qui ne sont pas flanqués d'une valeur différente de zéro.

De manière équivalente, une entrée doit être conservée si elle est non nulle ou si c'est un zéro qui est immédiatement proche d'une valeur non nulle.

Les entrées conservées doivent conserver dans la sortie l'ordre qu'elles avaient dans l'entrée.

Exemple

Donné

[2 0 4 -3 0 0 0 3 0 0 2 0 0]

les valeurs à supprimer sont marquées d'un x:

[2 0 4 -3 0 x 0 3 0 0 2 0 x]

et donc la sortie doit être

[2 0 4 -3 0 0 3 0 0 2 0]

Règles

Le tableau d'entrée peut être vide (et la sortie doit également être vide).

Les formats d'entrée et de sortie sont flexibles comme d'habitude: tableau, liste, chaîne ou tout ce qui est raisonnable.

Code golf, le moins de mieux.

Cas de test

[2 0 4 -3 0 0 0 3 0 0 2 0 0] -> [2 0 4 -3 0 0 3 0 0 2 0]
[] -> []
[1] -> [1]
[4 3 8 5 -6] -> [4 3 8 5 -6]
[4 3 8 0 5 -6] -> [4 3 8 0 5 -6]
[0] -> []
[0 0] -> []
[0 0 0 0] -> []
[0 0 0 8 0 1 0 0] -> [0 8 0 1 0]
[-5 0 5] -> [-5 0 5]
[50 0] -> [50 0]

Puis-je utiliser à la _2place de -2? De nombreuses langues utilisent ce format.
Leaky Nun

Aurons-nous -0?
Leaky Nun

@LeakyNun 1 Oui 2 Non
Luis Mendo

Les nombres auront-ils jamais des zéros en tête? Comme [010 0 0 01 1]?
FryAmTheEggman

@FryAmTheEggman Nope
Luis Mendo

Réponses:


16

JavaScript (ES6), 35 octets

a=>a.filter((e,i)=>e|a[i-1]|a[i+1])

Fonctionne également sur les flottants pour deux octets supplémentaires.


10

Python, 50 octets

f=lambda l,*p:l and l[:any(l[:2]+p)]+f(l[1:],l[0])

Une fonction récursive qui prend un tuple. Inclut le premier élément s'il y a une valeur non nulle parmi les deux premiers éléments ou la valeur précédente stockée la dernière fois. Ensuite, supprime le premier élément et revient. L'élément précédent est stocké dans la liste singleton p, qui s'emballe automatiquement dans la liste et commence comme vide (merci à Dennis pour 3 octets avec cela).


55 octets:

lambda l:[t[1]for t in zip([0]+l,l,l[1:]+[0])if any(t)]

Génère tous les morceaux de longueur 3 de la liste, en mettant d'abord des zéros au début et à la fin, et prend les éléments intermédiaires de ceux qui ne sont pas tous nuls.

Une approche itérative s'est avérée plus longue (58 octets)

a=0;b,*l=input()
for x in l+[0]:a|b|x and print(b);a,b=b,x

Cela ne fonctionne pas exactement car b,*lnécessite Python 3, mais Python 3 inputdonne une chaîne. L'initialisation est aussi moche. Peut-être qu'une approche récursive similaire fonctionnerait.

Malheureusement, la méthode d'indexation de

lambda l:[x for i,x in enumerate(l)if any(l[i-1:i+2])]

ne fonctionne pas car l[-1:2]interprète -1comme la fin de la liste, pas un point avant son début.


10

Haskell, 55 48 octets

h x=[b|a:b:c:_<-scanr(:)[0]$0:x,any(/=0)[a,b,c]]

Exemple d'utilisation: h [0,0,0,8,0,1,0,0]-> [0,8,0,1,0].

scanrreconstruit la liste d'entrée xavec un supplémentaire 0au début et à la fin. À chaque étape, nous modélisons 3 éléments et gardons celui du milieu s'il y a au moins un élément non nul.

Merci @xnor pour 7 octets en passant de zip3à scanr.


Ce serait bien de le faire h x=[snd t|t<-zip3(0:x)x$tail x++[0],(0,0,0)/=t], mais je suppose qu'il n'y a pas de moyen court d'obtenir le deuxième élément d'un triplet.
xnor

Avère plus court pour obtenir les triplets d'un scand'un zip3: h x=[b|a:b:c:_<-scanr(:)[0]$0:x,any(/=0)[a,b,c]].
xnor

8

Matlab, 29 27 octets

L'entrée doit être constituée d'une 1*nmatrice (lorsque cela n=0est possible). (Cela générera une erreur pour les 0*0matrices.)

@(a)a(conv(a.*a,1:3,'s')>0) 

La convolution est la clé du succès.


's'au lieu de 'same'<- :-D
Luis Mendo

Cette astuce fonctionne souvent avec les commandes intégrées =)
flawr

J'ai vu cette astuce, même pour des questions non liées au golf, avec le drapeau 'UniformOutpout'(naturellement). Mais je ne connaissais pas celui-ci
Luis Mendo

1
Pourriez-vous utiliser à la ~~aplace de a.*a?
feersum

2
@feersum Matlab refuse malheureusement de convoluer des logicaltableaux. Ceci est souvent un problème pour les modules intégrés qui ne sont pas écrits dans Matlab lui-même. Dans le cas contraire, les tableaux logiques se comportent un peu comme des tableaux numérotés. Cela pourrait fonctionner dans la pensée d'Octave, mais je ne l'ai pas installé pour le moment.
flawr

6

J, 17 14 octets

#~0<3+/\0,~0,|

Enregistré 3 octets avec l'aide de @ Zgarb.

Usage

   f =: #~0<3+/\0,~0,|
   f 2 0 4 _3 0 0 0 3 0 0 2 0 0
2 0 4 _3 0 0 3 0 0 2 0
   f ''

   f 0 0 0 8 0 1 0 0
0 8 0 1 0

Explication

#~0<3+/\0,~0,|  Input: array A
             |  Get the absolute value of each in A
           0,   Prepend a 0
        0,~     Append a 0
    3  \        For each subarray of size 3, left to right
     +/           Reduce it using addition to find the sum
  0<            Test if each sum is greater than one
                (Converts positive values to one with zero remaining zero)
#~              Select the values from A using the previous as a mask and return

Essayez-le ici.


Fonctionnerait 0<à la place de 0~:?
Zgarb

@Zgarb Les infixes de taille 3 peuvent être positifs ou négatifs après traitement.
miles

Ah, j'ai oublié les valeurs négatives.
Zgarb

6

MATL , 8 octets

tg3:Z+g)

La sortie est une chaîne avec des nombres séparés par des espaces. Un tableau vide à la sortie est affiché comme rien (pas même une nouvelle ligne).

Essayez-le en ligne! Ou vérifiez tous les cas de test .

Explication

Le code convertit l'entrée en type logique, c'est-à-dire que les entrées non nulles deviennent true(ou 1) et les entrées nulles deviennent false(ou 0). Ceci est ensuite convolu avec le noyau [1 2 3]. Une valeur non nulle entraîne un résultat différent de zéro à cette position et à ses positions voisines. La conversion en logique donne truedes valeurs qui doivent être conservées, donc l'indexation de celle-ci produit la sortie souhaitée.

t    % Input array implicitly. Duplicate
g    % Convert to logical: nonzero becomes true, zero becomes false
3:   % Push array [1 2 3]
Z+   % Convolution, keeping size of first input
g    % Convert to logical
)    % Index into original array. Implicitly display

5

Jolf, 14 octets

Maintenant que j'y pense, Jolf est le Java des langages de golf. soupire Essayez-le ici.

ψxd||H.nwS.nhS

Explication

ψxd||H.nwS.nhS
ψxd             filter input over this function
   ||           or with three args
     H           the element
      .nwS       the previous element
          .nhS   or the next element

5

Python 3, 55 octets

lambda s:[t[1]for t in zip([0]+s,s,s[1:]+[0])if any(t)]

1
Sensationnel. Je ne sais pas si vous avez vu @xnor répondre avant cela, mais vous avez exactement le même code, avec la seule différence étant le nom du lambda. Si vous avez utilisé son code, donnez-lui le crédit, sinon, quelle coïncidence folle!
Theo

N'a regardé le code de personne.
RootTwo

3
@ T.Lukin Il n'est pas rare de trouver le même code. Vous pouvez voir cela se produire sur Anarchy Golf, où le code est caché jusqu'à la date limite, et plusieurs personnes convergent vers la même solution comme celle-ci .
xnor

4

Gelée , 9 octets

0,0jo3\Tị

Essayez-le en ligne! ou vérifiez tous les cas de test .

Comment ça marche

0,0jo3\Tị  Main link. Argument: A (array)

0,0        Yield [0, 0].
   j       Join, separating with A. This prepends and appends a 0 to A.
    o3\    Reduce each group of three adjacent integers by logical OR.
       T   Truth; get the indices of all truthy results.
        ị  At-index; retrieve the elements of A at those indices.

4

Perl, 34 + 1 ( -pindicateur) = 35 octets

s/([^1-9]0 |^)\K0 ?(?=0|$)//&&redo

Nécessite un indicateur -p pour fonctionner. Prend une liste de nombres comme imput. Par exemple :

perl -pe 's/([^1-9]0 |^)\K0 ?(?=0|$)//&&redo' <<< "0 0 0 8 0 1 0 0
0 0 0
-5 0 5"

Je reçois 5si j'entre 50 0.
feersum

@feersum fixe, merci
Dada

4

Haskell, 48 octets

p%(h:t)=[h|any(/=0)$p:h:take 1t]++h%t
p%e=e
(0%)

Examine l'élément précédent p, le premier élément het l'élément après (le cas échéant), et s'il y en a des non nuls, ajoute le premier élément h.

La condition any(/=0)$p:h:take 1test longue, en particulier la take 1t. Je vais chercher un moyen de le raccourcir, peut-être en faisant correspondre les motifs.


4

Rétine , 42 35 33 octets

7 octets grâce à Martin Ender.

(? <= ^ | \ b0) 0 (? = $ | 0)

 +

^ | $

La dernière ligne est nécessaire.

Vérifiez tous les tests en même temps. (Légèrement modifié pour exécuter tous les tests en même temps.)

On dirait que le langage parfait pour le faire ... a toujours été vaincu par la plupart des réponses.


Je voudrais juste abandonner les supports du format d'E / S.
Martin Ender

3

Mathematica, 43 octets

ArrayFilter[If[#.#>0,#[[2]],Nothing]&,#,1]&

3

C, 96 octets

Appelez f()avec un pointeur sur la liste des entiers et un pointeur sur la taille de la liste. La liste et la taille sont modifiées sur place.

i,t,e,m;f(int*p,int*n){int*s=p;for(i=m=e=0;i++<*n;s+=t=m+*s||i<*n&&p[1],e+=t,m=*p++)*s=*p;*n=e;}

Essayez-le sur ideone .


Le style de paramètre K&R est souvent plus court, mais pas ici - f(int*p,int*n)enregistre un octet. Ou définissez scomme un 3ème paramètre (ce n'est pas passé. C'est un peu OK).
ugoren

3

Brachylog , 44 38 octets

,0gL:?:Lc:1fzbh.
~c[A:.:B],[0:0:0]'.l3

Essayez-le en ligne!

Ce langage est bon pour prouver les choses, c'est ce que nous utiliserons.

Prédicat 0 (prédicat principal)

,0gL:?:Lc:1fzbh.
 0gL               [0] = L    (assignment works both ways)
   L:?:Lc          [L:input:L] = temp
         :1f       find all solutions of predicate 1 with temp as input
            zbh.   then transpose and take the middle row and assign to output

Prédicat 1 (prédicat auxiliaire)

~c[A:.:B],[0:0:0]'.l3
~c[A:.:B]                 input is in the form of [A:output:B]
         ,                and
          [0:0:0]'.       output is not [0:0:0]
                  .l3     and length of output is 3

2

Matlab avec boîte à outils de traitement d'image, 27 octets

@(a)a(~imerode(~a,~~(1:3)))

Il s'agit d'une fonction anonyme.

Exemple d'utilisation:

>> @(a)a(~imerode(~a,~~(1:3)))
ans = 
    @(a)a(~imerode(~a,~~(1:3)))
>> ans([0 0 0 8 0 1 0 0])
ans =
     0     8     0     1     0

1
J'y ai pensé imerodeaussi, mais mes versions ont continué à être plus longues que ma version actuelle, beau travail =)
flawr

2

Utilitaires Bash + GNU, 25

grep -vC1 ^0|grep -v \\-$

Accepte l'entrée en tant que liste séparée par des sauts de ligne.

Ideone - avec le code du pilote de test ajouté pour exécuter tous les cas de test ensemble en convertissant vers / depuis les espaces séparés et les sauts de ligne.


2

Cheddar , 78 octets

a->([[]]+a.map((e,i)->e|(i?a[i-1]:0)|(i-a.len+1?a[i+1]:0)?[e]:[])).reduce((+))

Suite de tests.

Cheddar n'a pas de filtre, donc le filtrage se fait en enveloppant les éléments que nous voulons et en transformant les éléments que nous ne voulons pas en tableaux vides, puis en concaténant tout.

Par exemple, [0,0,0,8,0,1,0,0]devient [[],[],[0],[8],[0],[1],[0],[]], puis le tableau concaténé serait [0,8,0,1,0].


.reduce((+))->.sum
Downgoat

@Downgoat Quand avez-vous corrigé cela?
Leaky Nun

oh, désolé, nevermind. Je pensais que tu additionnais le tableau. ne pas rejoindre les baies
Downgoat

1

APL, 14 octets

{⍵/⍨×3∨/0,⍵,0}

Tester:

      {⍵/⍨×3∨/0,⍵,0}2 0 4 ¯3 0 0 0 3 0 0 2 0 0
2 0 4 ¯3 0 0 3 0 0 2 0

Explication:

  • 0,⍵,0: ajouter un zéro au début et à la fin de ⍵
  • ×3∨/: trouver le signe du GCD de chaque groupe de trois nombres adjacents (ce sera 0 s'ils sont tous nuls et 1 sinon).
  • ⍵/⍨: sélectionnez tous les éléments de ⍵ pour lesquels le résultat était 1.

1

Ruby 2.x, 63 octets

f=->(x){x.select.with_index{|y,i|x[i-1].to_i|y|x[i+1].to_i!=0}}

Le crédit là où il est dû, c'est essentiellement un portage de la réponse ES6 supérieure de Neil.

C'est aussi ma première soumission de pcg. Yay.


1

Brain-Flak 142 octets

Essayez-le en ligne!

(<()>)(()){{}([]<([]){{}({}<>)<>({}<>)<>({}<>)<>(<>({}<>)<>({}<>)<>({})<>){{}((<()>))}{}{}([][()])}{}{}<>{}([]){{}({}<>)<>([])}{}<>>[[]])}{}{}

Explication

(<()>)                    #Pad the top with an extra zero
(()){{}([]<...>[[]])}{}   #Until the stack height remains the same
 ([]){{}...([][()])}{}    #Until the stack height is one
  ({}<>)<>                #Move the top three to the other stack
  ({}<>)<>
  ({}<>)<>
  (...)                   #Push the sum of the top three
   <>({}<>)               #Move the second and third back
   <>({}<>)
   <>({})<>               #Leave the top of the stack
  {{}...}{}               #If the sum is not zero
   ((<()>))               #Add a buffer to the top of the stack
  {}                      #Pop the buffer/middle value
 {}                       #Remove extra zero
 <>                       #Switch to the off stack
 {}                       #Remove extra zero
 ([]){{}({}<>)<>([])}{}<> #Move the entire off stack back

Le lien est vide. Vous pouvez coller du code et entrer, appuyez sur "enregistrer" et utilisez le lien résultant
Luis Mendo

@LuisMendo Malheureusement, je ne peux pas utiliser tryitonline, je viens donc de me connecter à l'url.
Wheat Wizard

Pourquoi ne pouvez-vous pas accéder à tryitonline?
DJMcMayhem

@DJMcMayhem Je n'avais pas de javascript dans mon navigateur. <s> Je vais le réparer maintenant. </s> Je vois que vous l'avez déjà fait, merci.
Wheat Wizard
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.