Sautez comme une grenouille!


12

Étant donné un tableau d'entiers non négatifs, votre tâche consiste à n'en conserver que certains éléments, comme décrit ci-dessous.

  • Disons que le tableau est [1, 3, 2, 4, 11, 5, 2, 0, 13, 10, 1].

  • Tout d' abord obtenir le premier élément du tableau, n. Conservez les premiers néléments et jetez le suivant (jetez le n+1e). Le nouveau tableau est [1, 2, 4, 11, 5, 2, 0, 13, 10, 1].

  • Ensuite, vous saisissez l'élément suivant celui supprimé et faites exactement la même chose. Réappliquant le processus, nous obtenons[1, 2, 11, 5, 2, 0, 13, 10, 1]

  • Vous répétez le processus jusqu'à ce que vous arriviez en dehors des limites du tableau / il ne reste aucun élément dans le tableau. Nous nous arrêtons car 11est supérieure à la longueur du tableau.

  • Vous devez maintenant afficher le résultat.

Les entrées / sorties peuvent être prises / fournies sous n'importe quelle forme standard. Le tableau ne sera jamais vide et ne contiendra que des entiers non négatifs. Toutes les failles standard sont interdites.

C'est du donc le code le plus court en octets gagne!


Cas de test

Entrée -> Sortie

[1, 2, 3, 4, 5] -> [1, 3, 4]

[6, 1, 0, 5, 6] -> [6, 1, 0, 5, 6]

[1, 3, 2, 4, 11, 5, 2, 0, 13, 10, 1] -> [1, 2, 11, 5, 2, 0, 13, 10, 1]

[2, 2, 2, 2, 2, 2] -> [2, 2]

[1, 2, 3, 1, 2, 3, 1, 2, 3] -> [1, 2]

[3, 1, 2, 4, 0] -> [] *

* Le dernier cas de test implique 0, j'ai donc décidé de publier le processus de manière à ce qu'il soit plus clair:

[3, 1, 2, 4, 0] --> [3, 1, 2, 0] --> [1, 2, 0] --> [1, 0] --> [0] --> [] )

( Inspiré par ce défi par Erik the Outgolfer )


J'ai écrit tous les cas de test entièrement à la main, veuillez me prévenir si vous pensez qu'il y a une erreur!

1
Pourquoi est 2supprimé à la première étape au lieu de 3?
Leaky Nun

@LeakyNun Mon erreur. Correction. Envoyez-moi un ping si j'ai fait d'autres erreurs

scénario de test suggéré:[1, 2, 3, 1, 2, 3, 1, 2, 3]
Rod

1
Donc, pour clarifier, lorsque vous passez à votre nouveau " n", vous commencez toujours par le début du tableau pour conserver les néléments? Ne pas (comme je le pensais à première vue) garder les néléments là où le premier élément est celui que nvous évaluez?
Brian J

Réponses:



5

JavaScript (ES6), 45 octets

f=(a,k=0,x=a[k])=>1/x?f(a.splice(x,1)&&a,x):a

Cas de test


4

Haskell , 50 octets

g.pure.(0:)est une fonction anonyme prenant et renvoyant une liste de Ints, utilisez comme (g.pure.(0:))[1,2,3,4,5].

g.pure.(0:)
g(a,_:b:c)=g$splitAt b$a++b:c
g(a,_)=a

Essayez-le en ligne!

Comment ça fonctionne

  • La fonction gprend un argument tuple représentant une liste fractionnée. aest la liste des éléments initiaux conservée à l'étape précédente, _est l'élément à éliminer, best l'élément suivant à utiliser comme longueur et cest les éléments restants.
    • S'il y a suffisamment d'éléments dans la deuxième partie du tuple pour sélectionner un b, un nouveau fractionnement est effectué et se greproduit. Sinon, il s'arrête avec acomme résultat.
  • La fonction anonyme g.pure.(0:)démarre tout en appelant gavec le tuple ([],0:l), où se ltrouve l'entrée et 0est immédiatement supprimée par g.
    • pureutilise ici l' Applicativeinstance pour les tuples (binaires), et avec le type de résultat ([Int],[Int])place commodément son argument comme deuxième élément dans un tuple avec []comme premier élément.



2

Java 8, 68 octets

Ce lambda accepte un mutable List<Integer>(supporte remove(int), par exemple ArrayList). La sortie est une entrée mutée. Attribuer à Consumer<List<Integer>>.

l->{for(int i=0,f=0;i<l.size();f^=1)i=f>0?l.remove(i)*0+i:l.get(i);}

Essayez-le en ligne

Le flux de contrôle pour ce problème est très ennuyeux. À chaque itération, nous devons supprimer un élément et le placer à la position suivante, et ces deux opérations nécessitent une vérification de plage (et l'une ou l'autre peut déclencher l'achèvement du programme). Une stratégie consiste à effectuer les deux opérations en une seule itération de boucle, la mise à jour de l'index étant protégée par sa propre vérification de plage. Une autre stratégie, qui s'est avérée plus courte, consiste à alterner les opérations à chaque itération de boucle, ce que fait cette solution.


1

APL (Dyalog Classic) , 32 octets

1∘{n∇⍣(n≤≢w)⊢w←⍵/⍨(n1+⍺⊃⍵)≠⍳≢⍵}

Explication

1∘{                             } bind 1 as starting left argument (⍺)
                             ⍳≢⍵  generate indexes for right argument (⍵)
                   (n1+⍺⊃⍵)      n is 1+item at position  
              w←⍵/⍨              w is  with item at n removed
   n∇⍣(n≤≢w)⊢                     recurse with n as left and w as right arg if n <= length of w

Essayez-le en ligne!



1

Haskell, 99 octets (88 sans retrait)

f x y
 |y>=l=f x$l-1
 |e>=l=x
 |True=f (take e x ++ drop (1+e) x) e
 where e=x!!y
       l=length x

Je pourrais probablement enregistrer 1 octet en utilisant "1 = 1" au lieu de "True", peut-être que les deux espaces près de "++" pourraient être supprimés
Giacomo Tecya Pigani

1

VI, 31 25 octets

O@0kdd<C-v><C-a>Y<C-v><C-x>gg@a<Esc>"add<C-a>Y<C-x>@a

<C-?>correspond à Control + ?, et <Esc>à Escapeévidemment. Chacun d'eux compte pour 1 octet (voir méta ).

Contribution

Le fichier d'entrée doit contenir 1 entier par ligne + 1 ligne vide à la fin, exemple:

1
2
3
4
5
⁣

Nous pouvons voir chaque ligne du fichier d'entrée comme un élément de tableau, comme 1 :: 2 :: 3 :: 4 :: 5 :: [], comme dans certaines langues (caml par exemple).

lancement

Vous pouvez démarrer vi avec la commande suivante et saisir la solution trait par trait:

vi -u NONE input

Vous pouvez également utiliser ce one-liner:

vi -u NONE -c ':exec "norm O@0kdd\<C-v>\<C-a>Y\<C-v>\<C-x>gg@a\<Esc>\"add\<C-a>Y\<C-x>@a"' -c ":w output" -c ':q' input

Cela devrait produire un fichier outputavec le résultat correct à partir d'un fichier d'entrée input.

Explications

Pour présenter la solution, je vais d'abord présenter une solution de 19 octets fonctionnant uniquement pour les tableaux sans 0. Cette solution utilise une macro récursive, utilisée avec peu de modifications dans la solution finale:

Yqa@0ddYgg@aquggY@a

Explication d'une solution partielle

Y                       # yank first line (first integer + line break) to "0 register
 qa                     # start recording a macro ("a register)
   @0                   # jump n lines, where n is the content of the "0 register
     dd                 # delete the current line (n+1th line)
       Y                # yank current line (integer after the previously deleted line)
        gg              # go back to the first line
          @a            # recurse on macro "a"
            q           # finish recording the macro
             u          # cancel modifications done by the execution of the macro
              gg        # go back to the first line
                Y@a     # apply the recorded macro with first parameter equal to the first integer

L'astuce consiste à utiliser le "0registre pour stocker l'entier actuel (et le saut de ligne, très important). Par conséquent, la commande @0permet de sauter des nlignes (appelez nla valeur de "0). Si le saut dépasse le nombre de lignes dans le fichier, la macro échouera, donc le programme s'arrêtera (en dehors des limites du tableau, comme requis).

Mais cette solution ne fonctionne pas si l'entrée contient 0. En effet, si la "0valeur du registre est égale 0, alors @0sautera une ligne (en raison du saut de ligne), pas 0comme nous l'avons aimé. Ainsi, la prochaine commande ( dd) ne supprimera pas le 0e entier, mais le 1er (pas correct).

Une solution valide pour gérer le 0est de toujours incrémenter l'entier avant de le tirer et de le décrémenter juste après. Ainsi, la @0commande sautera des n+1lignes ( nest l'entier actuel qui a été incrémenté). Une kcommande est alors nécessaire pour passer à la ligne n(ligne précédente). En utilisant cette astuce, une ligne vide est nécessaire à la fin du fichier d'entrée, pour éviter de sauter en dehors du tableau (donc de terminer le programme), car nous sautons maintenant toujours des n+1lignes, avant de sauter à la ligne précédente.

Explication de la solution finale

O                                                       # insert a new line at the beginning of the file, enter insert mode to write the macro content
 @0                                                     # jump n lines                                                       
   k                                                    # go to the previous line
    dd                                                  # delete this line
      <C-v><C-a>                                        # type Control+A (C-v is needed because we are in insert mode) to increment the current integer
                Y                                       # yank the incremented integer
                 <C-v><C-x>                             # decrement the current integer
                           gg                           # go to the first line
                             @a                         # recurse on macro "a"
                               <Esc>                    # exit insert mode : at this step, the first line of the file contains the macro content @0kdd^AY^Xgg@a
                                    "add                # copy @0kdd^AY^Xgg@a line to the register "a and delete the line
                                        <C-a>           # increment the first integer
                                             Y          # yank it (into "0)
                                              <C-x>     # decrement the first integer
                                                   @a   # apply macro in a" (initial @0 will jump n+1 lines, since we incremented the first integer before calling the macro)

Écrire le contenu de la macro dans le fichier avant de l'enregistrer permet d'économiser quelques octets:

  • évite d'écrire qa...qet d'annuler toutes les modifications après l'enregistrement
  • évite :let @a="...")

Modifications

#1

  • écrire le contenu de la macro sur la première ligne (au lieu de la dernière ligne)
  • modifier l'entrée (1 ligne vierge à la fin)
  • ajouter une ligne pour tester en ligne de commande

0

Pyth, 32 octets

VlQIgNlQBK@QNI!K=QYBIgKlQB.(QK;Q

Essayez-le en ligne


Pyth peut être beaucoup plus élégant que ça :) #VlQ.(Q@QN;Qfait le travail en 12 octets, et je suis presque sûr qu'il peut être joué encore plus
Dave

En gardant l'approche Pythonic à l'ancienne, vous pouvez le faire W<Zl=Q+<Q@QZ>Qh@QZ=Z@QZ)Q(25). L'approche de pizzakingme est cependant bien meilleure.

4
@KaranElangovan rien à s'excuser, ils essaient juste de vous aider.
Leaky Nun

1
Correction pour le cas de test final, il sort à 15 octets: #VlQ .(Q@QN)%;Q. Les retours des golfeurs Pyth seraient les bienvenus, j'apprends encore!
Dave

2
Cette approche n'est pas valide. Non seulement il n'imprime pas uniquement le résultat, mais il échoue également aux cas de test (l'avant-dernier au moins). Pouvez-vous s'il vous plaît supprimer cette réponse / la corriger?

0

C # (.NET Core) , 74 octets

n=>{for(int i=n[0];i<n.Count;){n.RemoveAt(i);i=i<n.Count?n[i]:n.Count+1;}}

Essayez-le en ligne!

Cela prend une liste d'entiers et la modifie. J'ai vu quelques réponses Java qui contournent les importations en utilisant le nom complet dans la définition de l'argument Lambda. Si cela n'est pas autorisé, je peux supprimer cette réponse.


Si vous faites référence à l'omission de types de paramètres dans les définitions lambda, cela est autorisé .
Jakob

@Jakob Je comprends cela. Je me sens juste un peu sale pour le System.Collections.Generic.List<int>lieu de using System.Collections.Genericet l'ajout au nombre d'octets. Mais je suppose que ce n'est pas différent de l'utilisation d'un tableau.
jkelm

Oh je vois. Eh bien, vous pouvez utiliser usingsi vous le souhaitez; tant que le lambda lui-même ne dépend pas de l'instruction, vous n'auriez pas à l'inclure dans le nombre d'octets. Personnellement, j'utilise toujours des noms pleinement qualifiés dans le code de test juste pour qu'il soit clair et facilement vérifiable ce que les importations utilisent lambda.
Jakob

0

R , 64 53 octets

f=function(a,i=1,d=a[i]+1)"if"(is.na(d),a,f(a[-d],d))

Fonction récursive. A une entrée obligatoire a, la liste à sauter. iest l'index du nombre de choses à sauter (par défaut à 1), et dest l'index de l'élément suivant après que la valeur requise a été supprimée, qui est également l'index de l'élément à supprimer. Renvoie numeric(0), un vecteur vide, pour une sortie vide.

Essayez-le en ligne!

Non golfé:

f <- function(a, i = 1, d = a[i] + 1) {
  if(is.na(d)) {   # d is NA if and only if a[i] is out of bounds
    a
  } else {
    f( a[-d], d, a[d] + 1 )   # a[-d] is a with the item at index d removed
  }
}
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.