Recherche approfondie dans une liste

19

Pour ce défi, une liste est considérée comme valide si et seulement si elle se compose entièrement d'entiers et de listes valides (définitions récursives \ o /). Pour ce défi, étant donné une liste valide et un entier, retournez une liste de toutes les profondeurs auxquelles l'entier peut être trouvé.

Exemple

Prenons la liste [1, [2, [3, [1, 2, 3], 4], 1], 1]et l'entier 1. Ensuite, nous pouvons dresser la liste comme ceci:

Depth 0 1 2 3
Num   1
        2
          3
            1
            2
            3
          4
        1
      1

Vous remarquerez que cela 1apparaît en profondeur 0, 1, 3. Ainsi, votre sortie doit être 0, 1, 3dans un format raisonnable (l'ordre n'a pas d'importance).

La profondeur peut être indexée 0 ou 1, mais veuillez préciser dans votre soumission de laquelle il s'agit.

Cas de test (indexés 0)

Pour la liste [1,[2,[3,4],5,[6,7],1],[[[[5,2],4,[5,2]]],6],3]:

1 -> [0, 1]
2 -> [1, 4]
3 -> [0, 2]
4 -> [2, 3]
5 -> [1, 4]
6 -> [1, 2]
7 -> [2]

Pour la liste [[[[[1],0],1],0],1]:

0 -> 1, 3
1 -> 0, 2, 4

Pour la liste [11,22,[33,44]]:

11 -> [0]
22 -> [0]
33 -> [1]
44 -> [1]

Renvoie une liste vide si le terme de recherche n'existe nulle part dans la liste.

Les valeurs négatives et nulles sont valides dans la liste et le terme d'entrée.

HyperNeutrino
la source
Si l'entier apparaît plusieurs fois à une profondeur, devons-nous renvoyer ce numéro de profondeur une seule fois?
Giuseppe
@ Giuseppe oui, c'est exact.
HyperNeutrino
1
@ Adám Eh bien, étant donné que l'un de mes cas de test a des zéros, non. J'ajouterai également que les entiers négatifs sont équitables.
HyperNeutrino
1
Des numéros à plusieurs chiffres doivent également être ajoutés dans un scénario de test, s'ils peuvent se produire.
Zgarb
1
@KevinCruijssen Oui, oui, non et oui. Vous pouvez donc prendre les entrées sous forme de chaînes et afficher la profondeur dans n'importe quel ordre, mais pas plusieurs fois.
HyperNeutrino

Réponses:

7

Mathematica, 25 octets

Tr/@Union[1^Position@##]&

(retourne une sortie indexée 1)

Explication

                         test  {1, {2, {3, {1, 2, 3}, 4}, 1}, 1}
             Position[test,1]  {{1}, {2, 2, 2, 1}, {2, 3}, {3}}
           1^Position[test,1]  {{1}, {1, 1, 1, 1}, {1, 1}, {1}}
    Union[1^Position[test,1]]  {{1}, {1, 1}, {1, 1, 1, 1}}
Tr/@Union[1^Position[test,1]]  {1, 2, 4}
Misha Lavrov
la source
7

Haskell , 102 93 80 76 octets

Merci à Bruce Forte d' avoir enregistré quelques octets et à Laikoni d'en avoir économisé plus.

Merci à 4castle d' avoir économisé 4 octets.

Haskell n'a pas de type de données pour ce type de liste, j'ai donc créé la mienne.

Cette solution est 1-indexed

import Data.List
data T=E Int|L[T]
E n%x=[0|x==n]
L s%x=nub$map(+1).(%x)=<<s

Essayez-le en ligne!

Je définis d'abord (récursivement) un type de données T

Ta un type E Int(élément unique de type Int) ou L[L](liste de type T).

(%)est une fonction qui prend des 2arguments, de type T, la liste à travers laquelle nous recherchons, et x, le que Intnous recherchons.

Chaque fois qu'il (%)trouve quelque chose qui est un seul élément E n, il vérifie l' négalité avec xet renvoie 0si True.

Quand (%)est appliqué à un L s(où sa un type [T]), il s'exécute (%)sur tous les éléments set incrémente le résultat (car la profondeur augmente depuis que nous regardons à l'intérieur s), et le concatène le résultat.

nub supprime ensuite les doublons de la liste

NB. import Data.Listest seulement pour nub.

H.PWiz
la source
J'ai trouvé une solution assez similaire pour 81 octets: essayez-la en ligne!
Laikoni
@Laikoni Très sympa, voulez-vous le poster vous-même, ou proposez-vous de mettre à jour le mien?
H.PWiz
N'hésitez pas à mettre à jour votre réponse. :)
Laikoni
Concernant le NB: j'ai essayé de me débarrasser de l'importation, mais je me suis retrouvé à 88 octets: essayez-le en ligne!
Laikoni
2
Vous pouvez supprimer les parenthèses autour E net L s.
4castle
4

Gelée , 11 8 octets

WẎÐĿċ€IT

Essayez-le en ligne!

Comment ça fonctionne

WẎÐĿċ€IT  Main link. Left argument: A (array). Right argument: n (integer)

W         Wrap; yield [A].
  ÐĿ      Repeatedly apply the link to the left until the results are no longer
          unique. Yield the array of all unique results.
 Ẏ          Concatenate all elements at depth 1 in the array.
          The last array of the array of results is completely flat.
    ċ€    Count the occurrences of n in each intermediate result.
      I   Compute all forward differences.
       T  Truth; yield the array of all indices of non-zero differences.

Exemple d'exécution

Pour l'argument de gauche

[1, [2, [3, [1, 2, 3], 4], 1], 1]

W donne d'abord le tableau suivant.

[[1, [2, [3, [1, 2, 3], 4], 1], 1]]

ẎÐĿconcatène plusieurs fois tous les éléments à la profondeur 1 , réduisant la profondeur de la matrice de 1 à chaque étape. Cela donne le tableau suivant de résultats intermédiaires.

[
 [[1, [2, [3, [1, 2, 3], 4], 1], 1]],
 [ 1, [2, [3, [1, 2, 3], 4], 1], 1 ],
 [ 1,  2, [3, [1, 2, 3], 4], 1,  1 ],
 [ 1,  2,  3, [1, 2, 3], 4,  1, 1  ],
 [ 1,  2,  3,  1, 2, 3,  4,  1, 1  ]
]

Pour l'argument de droite 1 , ċ€compte les occurrences de 1 dans chaque résultat intermédiaire.

[0, 2, 3, 3, 4]

I prend maintenant toutes les différences en avant.

[2, 1, 0, 1]

Les différences non nulles correspondent aux étapes dans lesquelles au moins un autre 1 a été ajouté à la profondeur 1 . Ainsi, une différence non nulle à l'indice k indique la présence d'un 1 à la profondeur k . Ttrouve les indices de tous les éléments véridiques, donnant le résultat souhaité:

[1, 2, 4]
Dennis
la source
\ o / c'était ma solution exacte lors de la comparaison de Jelly avec Python. Yay! : P
HyperNeutrino
4

R , 101 95 92100 octets

f=function(L,n,d=0)unique(unlist(Map(function(x)if(n%in%unlist(x))"if"(is.list(x),f(x,n,d+1),d),L)))

Essayez-le en ligne!

Solution récursive; c'est assez inefficace en octets, mais R listsest super ennuyeux de travailler avec.

Fondamentalement, prend L, et pour chaque élément xde L, (qui est soit un listou un atomicvecteur d'un élément), vérifie si nest %in% x, puis vérifie si xest un list. Si ce n'est pas le cas, alors x==nnous retournons la profondeur d; Sinon , nous appelons récursive fsur x, incrémenter d.

Ceci, bien sûr, renvoie un list, que nous unlistet uniquepour assurer la bonne sortie (renvoyant un vecteur de profondeurs entières); renvoie NULL(une liste vide) pour invalide n.

Apparemment, %in%ne recherche pas récursivement listcomme je le pensais, donc je dois unlist(x)pour +8 octets :(

Giuseppe
la source
3

APL (Dyalog) , 39 octets *

Programme complet. Demande la liste, puis le numéro. Imprime la liste basée sur 1 sur STDOUT.

2÷⍨⍸∨⌿⍞⍷⎕FMTJSON'Compact'0⊢⎕

Essayez-le en ligne!

 invite pour la liste

 rendement qui (sépare 0et )

⎕JSON⍠'Compact'0 convertir en chaîne JSON en retrait avec des retours à la ligne

⎕FMT convertir en matrice (une ligne délimitée par une nouvelle ligne par ligne)

⍞⍷ demander le nombre sous forme de chaîne et indiquer où il commence dans ce

∨⌿ réduction verticale OU (c'est-à-dire dans quelles colonnes il commence)

 indices de ces débuts

2÷⍨ réduire de moitié (les niveaux sont en retrait avec deux espaces)

 arrondir vers le bas (car la première colonne de données est la colonne 3)


* Dans Dyalog Classic, en comptant comme ⎕U2378et comme ⎕OPT.

Adam
la source
2

PHP , 117 octets

$r;function z($a,&$r,$i=0){foreach($a as $v){is_int($v)?(@in_array($i,$r[$v])?:$r[$v][]=$i):z($v,$r,$i+1);}}z($s,$r);

Essayez-le en ligne!

Calimero
la source
2

JavaScript (ES6), 79 68 octets

f=(a,n,r=new Set,d=0)=>a.map(e=>e.map?f(e,n,r,d+1):e-n||r.add(d))&&r

Renvoie un ensemble. Si cela est inacceptable, utilisez &&[...r]au coût de 5 octets.

Neil
la source
1

Gelée ,  17  16 octets

⁴e®;©ȧ⁸ḟ⁴ẎµÐĿȧ®T’

Un programme complet prenant deux arguments de ligne de commande la liste et un élément à vérifier et imprimant la profondeur ou les profondeurs (le cas échéant) auxquelles l'élément existe. Les résultats sont indexés 1.

Essayez-le en ligne!

Comment?

⁴e®;©ȧḟ⁴ẎµÐĿȧ®T’ - Main link: list, L
          µÐĿ    - loop, collecting updated values of L, until a fixed point is reached:
⁴                -   4th argument (2nd program input) = the number
 e               -   exists in (the current version of) L?
  ®              -   recall value from the register (initially 0)
   ;             -   concatenate the two
    ©            -   (copy this result to the register)
       ⁴         -   4th argument (2nd program input) again
      ḟ          -   filter out (discard any instances of the number)
     ȧ           -   logical and (non-vectorising)
        Ẏ        -   tighten (flatten the filtered L by one level to create the next L)
             ®   - recall value from the register
            ȧ    - logical and (non-vectorising)
              T  - truthy indexes (1-indexed)
               ’ - decrement (account for the leading zero from the initial register)
Jonathan Allan
la source
Agréable! Fait amusant cependant: en utilisant une approche très similaire mais en modifiant un peu l'ordre des choses, vous pouvez obtenir 8 octets. modifier l'approche est en fait un peu différente, nvm
HyperNeutrino
Cela ne fonctionne pas tout à fait: tio.run/##y0rNyan8//9R45ZU60MrD607sfxR446HO@YDBR7u6ju09fCEI/…
HyperNeutrino
Hmm a trouvé des bugs pendant l'écriture ... en train de les supprimer.
Jonathan Allan
Ah j'avais en quelque sorte changé l'ordre de ma concaténation: / devrait travailler maintenant
Jonathan Allan
1

JavaScript (ES6), 73 74 octets

f=(a,n,i=0,o={})=>a.map(e=>e.pop?f(e,n,i+1,o):e-n||o[i]++)&&Object.keys(o)

Explication:

f=(a,                             //input array
   n,                             //input number to search
   i=0,                           //start at first level
   o={}                           //object to store the finds
  )=>
    a.map(                        //loop through the array
      e => e.pop ?                //is this element an array?
             f(e, n, i+1, o) :    //if so, recurse on it to the next level
             e-n || o[i]++        //otherwise, update o if element equals the number
    ) &&
    Object.keys(o)                //return o's keys

Cas de test

Rick Hitchcock
la source
Bien qu'il n'y ait pas [encore] de cas de test, ma lecture de la question suggère qu'elle est valable pour e[0]être nulle, ce qui ferait échouer votre test.
Neil
@Neil, excellent point. Maintenant changé e.poppour une perte d'un octet.
Rick Hitchcock
1

Python 3 , 123 86 82 octets

def f(a,n,l=[],d=0):
 for e in a:l+=[d]*(e==n);0*e==[]and f(e,n,l,d+1)
 return{*l}

Essayez-le en ligne!

-37 octets grâce à Hyper Neutrino et ovs

-4 octets grâce à Jonathan Frech

caird coinheringaahing
la source
Essayez if type(a[i])!=intpour -1 octet
HyperNeutrino
Essayez l+=[d]pour -5 octets
HyperNeutrino
Essayez l+=[d]*(a[i]==n)pour -wwhat_number_of_bytes_it_is
HyperNeutrino
1
[]==a[i]*0pour une vérification de type plus courte
ovs
Essayez d'itérer à travers aau lieu d'une plage et d'utiliser getitemtellement pour - ~ 20 octets
HyperNeutrino
0

Octave , 126 122 octets

function n=r(p,t,l)n=[];if nargin<3
l=0;end
for x=p
if iscell(q=x{1})a=r(q,t,l+1);else
a=l*find(q==t);end
n=union(n,a);end

Essayez-le en ligne!

Pour plus de lisibilité, j'ai remplacé les espaces ou ;les avec des fins de ligne lorsque cela était possible. Explication du code non golfé:

function n=r(p,t,l) % Declare function with list p, integer t and optional recursion depth l
n=[];
if nargin<3
    l=0;            % If l is not given (first iteration), set l to zero (or one for 1-indexing)
end
for x=p             % Loop over list
if iscell(q=x{1})   % If loop variable x is a cell, we must go down one level.
     a=r(q,t,l+1);  % So recurse to l+1.
else
    a=l*find(q==t); % Empty if q~=t (because find(false)==[], and l*[]==[]), else equal to l*1==l.
end
n=union(n,a);       % Append to list of levels, make sure we only get distinct values.
end
Sanchises
la source
0

Java, 154 + 19 = 173 octets

import java.util.*;

Set<Long>f(List l,long n){Set s=new HashSet();if(l.contains(n))s.add(0l);for(Object o:l)if(o instanceof List)for(long d:f((List)o,n))s.add(d+1);return s;}

Essayez-le en ligne

Méthode non golfée

Set<Long> f(List l, long n) {
    Set s = new HashSet();
    if (l.contains(n))
        s.add(0l);
    for (Object o : l)
        if (o instanceof List)
            for (long d : f((List) o, n))
                s.add(d + 1);
    return s;
}
Jakob
la source