Búsqueda profunda en una lista


19

Para este desafío, una lista se considera válida si y solo si consiste enteramente de enteros y listas válidas (definiciones recursivas \ o /). Para este desafío, dada una lista válida y un número entero, devuelve una lista de todas las profundidades a las que se puede encontrar el número entero.

Ejemplo

Consideremos la lista [1, [2, [3, [1, 2, 3], 4], 1], 1]y el entero 1. Entonces, podemos dibujar la lista así:

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

Notarás que 1aparece en las profundidades 0, 1, 3. Por lo tanto, su salida debe estar 0, 1, 3en algún formato razonable (el orden no importa).

La profundidad puede ser 0 o 1 indexada, pero especifique en su envío cuál es.

Casos de prueba (indexados 0)

Para la lista [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]

Para la lista [[[[[1],0],1],0],1]:

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

Para la lista [11,22,[33,44]]:

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

Devuelve una lista vacía si el término de búsqueda no existe en la lista en ninguna parte.

Los valores negativos y cero son válidos en la lista de entrada y el término.


Si el número entero aparece a una profundidad varias veces, ¿tenemos que devolver ese número de profundidad solo una vez?
Giuseppe

@Giuseppe sí, eso es correcto.
HyperNeutrino

1
@ Adám Bueno, dado que uno de mis casos de prueba tiene ceros, no. También agregaré que los enteros negativos son un juego justo.
HyperNeutrino

1
Los números de varios dígitos también deben agregarse en un caso de prueba, si pueden ocurrir.
Zgarb

1
@KevinCruijssen Sí, sí, no y sí. Por lo tanto, puede tomar entradas como cadenas, y puede mostrar la profundidad en cualquier orden, pero no varias veces.
HyperNeutrino

Respuestas:


7

Mathematica, 25 bytes

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

(devuelve salida indexada 1)

Explicación

                         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}

7

Haskell , 102 93 80 76 bytes

Gracias Bruce Forte por guardar algunos bytes, y Laikoni por guardar algunos más.

Gracias 4castle por guardar 4 bytes.

Haskell no tiene ningún tipo de datos para este tipo de lista, así que hice el mío.

Esta solución es 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

Pruébalo en línea!

Primero defino (recursivamente) un tipo de datos T

Ttiene tipo E Int(elemento único de tipo Int) o L[L](lista de tipo T).

(%)es una función que toma 2argumentos, de tipo T, la lista a través de la cual estamos buscando y xla Intque estamos buscando.

Siempre que (%)encuentra algo que es un elemento único E n, comprueba la nigualdad con xy devuelve 0si es verdadero.

Cuando (%)se aplica a un L s(donde stiene tipo [T]) se ejecuta (%)en todos los elementos se incrementa el resultado (a medida que aumenta la profundidad ya que estamos mirando hacia adentro s), y concatena el resultado.

nub luego elimina los duplicados de la lista

NÓTESE BIEN. import Data.Listes solo para nub.


Se me ocurrió una solución bastante similar para 81 bytes: ¡ Pruébelo en línea!
Laikoni

@Laikoni Muy bien, ¿quieres publicarlo tú mismo o sugieres que actualice el mío?
H.PWiz

Siéntase libre de actualizar su respuesta. :)
Laikoni

En cuanto al NB: intenté deshacerme de la importación, pero terminé en 88 bytes: ¡ Pruébelo en línea!
Laikoni

2
Puede quitar el paréntesis alrededor E nyL s .
4castle



4

Jalea , 11 8 bytes

WẎÐĿċ€IT

Pruébalo en línea!

Cómo funciona

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.

Ejecución de ejemplo

Para argumento izquierdo

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

W primero produce la siguiente matriz.

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

ẎÐĿconcatena repetidamente todos los elementos en la profundidad 1 , reduciendo la profundidad de la matriz en 1 en cada paso. Esto produce el siguiente conjunto de resultados intermedios.

[
 [[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  ]
]

Para el argumento correcto 1 , ċ€cuenta las ocurrencias de 1 en cada resultado intermedio.

[0, 2, 3, 3, 4]

I ahora lleva todas las diferencias hacia adelante.

[2, 1, 0, 1]

Las diferencias distintas de cero corresponden a los pasos en los que se agregó al menos otro 1 a la profundidad 1 . Por lo tanto, una diferencia distinta de cero en el índice k indica la presencia de un 1 en la profundidad k . Tencuentra los índices de todos los elementos de verdad, produciendo el resultado deseado:

[1, 2, 4]

\ / / esta fue mi solución exacta al comparar Jelly con Python. ¡Hurra! : P
HyperNeutrino

4

R , 101 95 92 100 bytes

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)))

Pruébalo en línea!

Solución recursiva; es bastante ineficiente en bytes, pero Rlists es muy molesto trabajar con

Básicamente, toma L, y para cada elemento xde L, (que es listo un atomicvector de un elemento), verifica si nes %in% x, luego verifica si xes a list. Si no es así, entonces x==ndevolvemos la profundidad d; de lo contrario, de forma recursiva llamamos fen x, incrementandod .

Esto, por supuesto, devuelve a list, que nosotros unlisty uniquepara garantizar la salida correcta (devolviendo un vector de profundidades enteras); devuelve NULL(una lista vacía) para inválidon .

Aparentemente, %in%no busca de forma recursiva a través de lo listque pensé, así que tengo que unlist(x)buscar +8 bytes :(


3

APL (Dyalog) , 39 bytes *

Programa completo Solicita la lista, luego el número. Imprime la lista basada en 1 en STDOUT.

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

Pruébalo en línea!

 solicitud de lista

 rendimiento que (separa 0y )

⎕JSON⍠'Compact'0 convertir a una cadena JSON sangrada con nuevas líneas

⎕FMT convertir a matriz (una línea delimitada por nueva línea por fila)

⍞⍷ solicite el número como cadena e indique dónde comienza en ese

∨⌿ reducción OR vertical (es decir, en qué columnas comienza)

 índices de esos comienzos

2÷⍨ reducir a la mitad eso (los niveles están sangrados con dos espacios)

 redondear hacia abajo (porque la primera columna de datos es la columna 3)


* En Dyalog Classic, contando como ⎕U2378y como ⎕OPT.



2

JavaScript (ES6), 79 68 bytes

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

Devuelve un conjunto. Si esto es inaceptable, úselo &&[...r]a un costo de 5 bytes.


1

Jalea ,  17  16 bytes

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

Un programa completo que toma dos argumentos de línea de comando de la lista y un elemento para verificar, e imprime la profundidad o las profundidades (si las hay) en las que existe el elemento. Los resultados están indexados en 1.

Pruébalo en línea!

¿Cómo?

⁴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)

¡Agradable! Dato curioso: al usar un enfoque muy similar pero al cambiar un poco el orden de las cosas, puedes obtener 8 bytes. editar el enfoque es en realidad un poco diferente, nvm
HyperNeutrino


Hmm encontró errores durante la redacción ... borrando por ahora.
Jonathan Allan

Ah, de alguna manera había cambiado el orden de mi concatenación: debería estar trabajando ahora
Jonathan Allan

1

JavaScript (ES6), 73 74 bytes

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

Explicación:

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

Casos de prueba


Aunque no hay casos de prueba [todavía], mi lectura de la pregunta sugiere que es válido e[0]ser cero, lo que anularía su prueba.
Neil

@Neil, excelente punto. Ahora cambió a e.poppor una pérdida de un byte.
Rick Hitchcock

1

Python 3 , 123 86 82 bytes

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}

Pruébalo en línea!

-37 bytes gracias a Hyper Neutrino y ovs

-4 bytes gracias a Jonathan Frech


Prueba if type(a[i])!=intpor -1 byte
HyperNeutrino

Prueba l+=[d]por -5 bytes
HyperNeutrino

Intente l+=[d]*(a[i]==n)con -whatever_number_of_bytes_it_is
HyperNeutrino

1
[]==a[i]*0para un cheque de tipo más corto
ovs

Intente iterar en alugar de un rango y use getitemtanto para - ~ 20 bytes
HyperNeutrino


0

Octava , 126122 bytes

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

Pruébalo en línea!

Para facilitar la lectura, reemplacé espacios o ;'s con extremos de línea siempre que sea posible. Explicación del código no golfizado:

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

0

Java, 154 + 19 = 173 bytes

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;}

Pruébalo en línea

Método sin golf

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;
}
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.