Pesquise profundamente uma lista


19

Para esse desafio, uma lista é considerada válida se, e somente se, consistir inteiramente de números inteiros e listas válidas (definições recursivas \ o /). Para esse desafio, dada uma lista válida e um número inteiro, retorne uma lista de todas as profundidades nas quais o número inteiro pode ser encontrado.

Exemplo

Vamos considerar lista [1, [2, [3, [1, 2, 3], 4], 1], 1]e número inteiro 1. Então, podemos desenhar a lista assim:

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

Você notará que isso 1aparece em profundidade 0, 1, 3. Portanto, sua saída deve estar 0, 1, 3em algum formato razoável (a ordem não importa).

A profundidade pode ser indexada em 0 ou 1, mas especifique em sua submissão qual é.

Casos de teste (indexados 0)

Para 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 lista [[[[[1],0],1],0],1]:

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

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

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

Retorne uma lista vazia se o termo de pesquisa não existir na lista em nenhum lugar.

Valores negativos e zero são válidos na lista e no termo de entrada.


Se o número inteiro aparecer em uma profundidade várias vezes, precisamos retornar esse número de profundidade apenas uma vez?
Giuseppe

@ Giuseppe sim, está correto.
HyperNeutrino 28/09

11
@ Adám Bem, dado que um dos meus casos de teste tem zeros, não. Além disso, acrescentarei que números inteiros negativos são um jogo justo.
HyperNeutrino 28/09

11
Números com vários dígitos também devem ser adicionados em um caso de teste, se eles puderem ocorrer.
Zgarb 28/09

11
@KevinCruijssen Sim, sim, não e sim. Assim, você pode receber as entradas como strings e exibir a profundidade em qualquer ordem, mas não várias vezes.
HyperNeutrino

Respostas:


7

Mathematica, 25 bytes

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

(retorna saída indexada em 1)

Explicação

                         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

Agradecemos a Bruce Forte por salvar alguns bytes e a Laikoni por salvar mais alguns.

Obrigado 4castle por salvar 4 bytes.

Haskell não tem tipo de dados para esse tipo de lista, então eu criei o meu.

Esta solução é 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

Experimente online!

Primeiro eu defino (recursivamente) um tipo de dados T

Tpossui um tipo E Int(elemento único do tipo Int) ou L[L](lista do tipo T).

(%)é uma função que recebe 2argumentos, do tipo T, a lista pela qual estamos pesquisando e xo Intque estamos procurando.

Sempre que (%)encontra algo que é um único elemento E n, ele verifica na igualdade com xe retorna 0se True.

Quando (%)é aplicado a um L s(onde stem tipo [T]), ele é executado (%)em todos os elementos se incrementa o resultado (à medida que a profundidade está aumentando desde que estamos olhando para dentro s), e concatena o resultado.

nub remove as duplicatas da lista

NB import Data.Listé apenas para nub.


Eu vim com uma solução bastante semelhante para 81 bytes: Experimente online!
Laikoni

@Laikoni Muito bom, você quer publicá-lo sozinho ou sugere que eu atualize o meu?
H.PWiz

Sinta-se livre para atualizar sua resposta. :)
Laikoni

Com relação ao NB: tentei me livrar da importação, mas terminei com 88 bytes: Experimente online!
Laikoni

2
Você pode remover os parênteses em torno de E ne L s.
4castle



4

Geléia , 11 8 bytes

WẎÐĿċ€IT

Experimente online!

Como 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.

Exemplo de execução

Para argumento à esquerda

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

W primeiro gera a seguinte matriz.

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

ẎÐĿconcatena repetidamente todos os elementos na profundidade 1 , reduzindo a profundidade da matriz em 1 em cada etapa. Isso produz a seguinte matriz de resultados intermediários.

[
 [[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 o argumento correto 1 , ċ€conta as ocorrências de 1 em cada resultado intermediário.

[0, 2, 3, 3, 4]

I agora pega todas as diferenças avançadas.

[2, 1, 0, 1]

Diferenças diferentes de zero correspondem a etapas nas quais pelo menos um outro 1 foi adicionado à profundidade 1 . Assim, uma diferença diferente de zero no índice k indica a presença de 1 na profundidade k . Tencontra os índices de todos os elementos da verdade, produzindo o resultado desejado:

[1, 2, 4]

\ o / essa foi minha solução exata ao comparar o Jelly com o Python. yay! : 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)))

Experimente online!

Solução recursiva; é ineficiente em bytes, mas R listsé super chato de se trabalhar.

Basicamente, leva L, e para cada elemento xde L, (que é um listou um atomicvetor de um elemento), verifica se nexiste %in% xe verifica se xé a list. Se não for, então x==nretornamos a profundidade d; caso contrário, de forma recursiva chamar fem x, incrementando d.

Isso, é claro, retorna a list, que nós unliste uniquepara garantir a saída correta (retornando um vetor de profundidades inteiras); retorna NULL(uma lista vazia) por inválido n.

Aparentemente, %in%não pesquisa recursivamente através de um listcomo eu pensava, então eu tenho que procurar unlist(x)por +8 bytes :(


3

APL (Dyalog) , 39 bytes *

Programa completo. Solicita a lista e depois o número. Imprime uma lista baseada em 1 em STDOUT.

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

Experimente online!

 pedido de lista

 rendimento que (separa 0e )

⎕JSON⍠'Compact'0 converter em string JSON recuada com novas linhas

⎕FMT converter em matriz (uma linha delimitada por nova linha por linha)

⍞⍷ solicitar o número como string e indicar onde começa nesse

∨⌿ redução OR vertical (ou seja, em quais colunas começa)

 índices desses inícios

2÷⍨ reduzir pela metade isso (os níveis são recuados com dois espaços)

 arredondar para baixo (porque a primeira coluna de dados é a coluna 3)


* No Dyalog Classic, contando como ⎕U2378e 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

Retorna um conjunto. Se isso for inaceitável, use &&[...r]a um custo de 5 bytes.


1

Geléia ,  17  16 bytes

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

Um programa completo que utiliza dois argumentos de linha de comando na lista e um elemento a ser verificado e imprime a profundidade ou profundidades (se houver) nas quais o elemento existe. Os resultados são indexados em 1.

Experimente online!

Quão?

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

Agradável! Curiosidade: usando uma abordagem muito semelhante, mas alterando um pouco a ordem das coisas, você pode obter 8 bytes. editar a abordagem é realmente um pouco diferente, NVM
HyperNeutrino


Hmm encontrou bugs durante a gravação ... apagando por enquanto.
Jonathan Allan

Ah eu tinha de alguma forma mudou a ordem da minha concatenação: / deveria estar trabalhando agora
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)

Explicação:

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 teste


Embora ainda não haja casos de teste, minha leitura da pergunta sugere que é válido e[0]ser zero, o que prejudicaria seu teste.
Neil

@ Neil, excelente ponto. Agora alterado e.poppara perda de um 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}

Experimente online!

-37 bytes graças ao Hyper Neutrino e ovs

-4 bytes graças a Jonathan Frech


Experimentar if type(a[i])!=int por -1 byte
HyperNeutrino 28/17

Tente l+=[d]por -5 bytes
HyperNeutrino 28/17

Tente l+=[d]*(a[i]==n)para -whatever_number_of_bytes_it_is
HyperNeutrino

11
[]==a[i]*0 para uma verificação de tipo mais curta
ovs 28/09

Tente iterar através a , em vez de um gama e usando getitemtanto para - ~ 20 bytes
HyperNeutrino


0

Oitava , 126 122 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

Experimente online!

Para facilitar a leitura, substituí espaços ou ;s por extremidades da linha, sempre que possível. Explicação do código não destruído:

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

Experimente Online

Método não destruído

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;
}
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.