Cerca in profondità un elenco


19

Per questa sfida, un elenco è considerato valido se e solo se è costituito interamente da numeri interi ed elenchi validi (definizioni ricorsive \ o /). Per questa sfida, dato un elenco valido e un numero intero, restituisce un elenco di tutte le profondità a cui è possibile trovare il numero intero.

Esempio

Consideriamo l'elenco [1, [2, [3, [1, 2, 3], 4], 1], 1]e il numero intero 1. Quindi, possiamo disegnare l'elenco come questo:

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

Noterai che si 1presenta in profondità 0, 1, 3. Pertanto, l'output dovrebbe essere 0, 1, 3in un formato ragionevole (l'ordine non ha importanza).

La profondità può essere indicizzata 0 o 1, ma si prega di specificare nella presentazione quale è.

Casi di prova (indicizzati 0)

Per l'elenco [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]

Per l'elenco [[[[[1],0],1],0],1]:

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

Per l'elenco [11,22,[33,44]]:

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

Restituisce un elenco vuoto se il termine di ricerca non esiste nell'elenco da nessuna parte.

I valori negativi e zero sono validi nell'elenco di input e nel termine.


Se il numero intero appare più volte a una profondità, dobbiamo restituire quel numero di profondità una sola volta?
Giuseppe,

@Giuseppe sì, è corretto.
HyperNeutrino,

1
@Adám Bene, dato che uno dei miei casi di test ha zeri, no. Aggiungerò anche che gli interi negativi sono un gioco equo.
HyperNeutrino,

1
I numeri a più cifre dovrebbero anche essere aggiunti in un caso di test, se possono verificarsi.
Zgarb,

1
@KevinCruijssen Sì, sì, no e sì. Quindi puoi prendere input sia come stringhe, sia puoi visualizzare la profondità in qualsiasi ordine, ma non più volte.
HyperNeutrino,

Risposte:


7

Mathematica, 25 byte

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

(restituisce un output indicizzato)

Spiegazione

                         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 byte

Grazie Bruce Forte per aver salvato alcuni byte e Laikoni per averne salvato ancora.

Grazie 4castle per aver salvato 4 byte.

Haskell non ha un tipo di dati per questo tipo di elenco, quindi ne ho creato uno mio.

Questa soluzione è 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

Provalo online!

Per prima cosa definisco (ricorsivamente) un tipo di dati T

Tha tipo E Int(singolo elemento di tipo Int) o L[L](elenco di tipo T).

(%)è una funzione che accetta 2argomenti, di tipo T, l'elenco attraverso il quale stiamo cercando e xquello Intche stiamo cercando.

Ogni volta che (%)trova qualcosa che è un singolo elemento E n, verifica l' nuguaglianza con xe restituisce 0se True.

Quando (%)viene applicato a un L s(dove sha il tipo [T]) viene eseguito (%)su tutti gli elementi di se incrementa il risultato (poiché la profondità aumenta poiché guardiamo all'interno s) e il risultato concatena.

nub quindi rimuove i duplicati dall'elenco

NB. import Data.Listè solo per nub.


Ho trovato una soluzione abbastanza simile per 81 byte: provala online!
Laikoni,

@Laikoni Molto bello, vuoi pubblicarlo tu stesso o suggerisci di aggiornare il mio?
H.Piz,

Sentiti libero di aggiornare la tua risposta. :)
Laikoni,

Per quanto riguarda l'NB: ho provato a sbarazzarmi dell'importazione, ma ho terminato a 88 byte: provalo online!
Laikoni,

2
È possibile rimuovere la parentesi intorno E ne L s.
4castle,



4

Gelatina , 11 8 byte

WẎÐĿċ€IT

Provalo online!

Come funziona

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.

Esempio di esecuzione

Per argomento sinistro

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

W per prima cosa produce il seguente array.

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

ẎÐĿconcatena ripetutamente tutti gli elementi alla profondità 1 , riducendo la profondità della matrice di 1 in ogni passaggio. Ciò produce la seguente serie di risultati intermedi.

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

Per l'argomento corretto 1 , ċ€conta le occorrenze di 1 in ciascun risultato intermedio.

[0, 2, 3, 3, 4]

I ora prende tutte le differenze in avanti.

[2, 1, 0, 1]

Le differenze diverse da zero corrispondono ai passaggi in cui almeno un altro 1 è stato aggiunto alla profondità 1 . Pertanto, una differenza diversa da zero all'indice k indica la presenza di un 1 alla profondità k . Ttrova gli indici di tutti gli elementi di verità, ottenendo il risultato desiderato:

[1, 2, 4]

Questa era la mia soluzione esatta quando si confronta Jelly con Python. Sìì! : P
HyperNeutrino,

4

R , 101 95 92 100 byte

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

Provalo online!

Soluzione ricorsiva; è abbastanza inefficiente in byte, ma R listsè super fastidioso con cui lavorare.

Fondamentalmente, prende Le per ogni elemento xdi L(che è uno listo un atomicvettore di un elemento), controlla se nè %in% x, quindi controlla se xè a list. Se non lo è, allora x==nrestituiamo la profondità d; altrimenti ricorsivamente chiamiamo fsu x, incrementando d.

Questo, ovviamente, restituisce a list, che noi unliste uniqueper garantire il giusto output (restituendo un vettore di profondità intere); ritorna NULL(un elenco vuoto) per non valido n.

Apparentemente, %in%non cerca ricorsivamente attraverso un listcome pensavo, quindi devo unlist(x)+8 byte :(


3

APL (Dyalog) , 39 byte *

Programma completo. Richiede l'elenco, quindi il numero. Stampa un elenco basato su 1 su STDOUT.

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

Provalo online!

 richiedere l'elenco

 cedere che (separa 0e )

⎕JSON⍠'Compact'0 converti in stringa JSON rientrata con newline

⎕FMT converti in matrice (una riga delimitata da nuova riga per riga)

⍞⍷ richiede il numero come stringa e indica da dove inizia

∨⌿ riduzione OR verticale (ovvero in quali colonne inizia)

 indici di quegli inizi

2÷⍨ dimezzalo (i livelli sono rientrati con due spazi)

 arrotondamento per difetto (perché la prima colonna di dati è la colonna 3)


* In Dyalog Classic, contando come ⎕U2378e come ⎕OPT.


2

PHP , 117 byte

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

Provalo online!


2

JavaScript (ES6), 79 68 byte

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

Restituisce un set. Se ciò è inaccettabile, utilizzare &&[...r]ad un costo di 5 byte.


1

Gelatina ,  17  16 byte

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

Un programma completo che accetta due argomenti della riga di comando l'elenco e un elemento da verificare e stampa la profondità o le profondità (se presenti) in cui esiste l'elemento. I risultati sono 1 indicizzati.

Provalo online!

Come?

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

Bello! Curiosità però: usando un approccio molto simile ma cambiando un po 'l'ordine delle cose, puoi ottenere 8 byte. modificare l'approccio è in realtà un po 'diverso, nvm
HyperNeutrino,


Hmm ha trovato dei bug durante la scrittura ... eliminazione per ora.
Jonathan Allan,

Ah, in qualche modo avevo cambiato l'ordine della mia concatenazione: / dovrei lavorare ora
Jonathan Allan,

1

JavaScript (ES6), 73 74 byte

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

Spiegazione:

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

Casi test


Sebbene non ci siano casi di test [ancora], la mia lettura della domanda suggerisce che è valido per e[0]essere zero, il che eliminerebbe il test.
Neil,

@Neil, punto eccellente. Ora modificato in e.popper una perdita di un byte.
Rick Hitchcock,

1

Python 3 , 123 86 82 byte

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}

Provalo online!

-37 byte grazie a Hyper Neutrino e ovs

-4 byte grazie a Jonathan Frech


Prova if type(a[i])!=intper -1 byte
HyperNeutrino,

Prova l+=[d]per -5 byte
HyperNeutrino,

Prova l+=[d]*(a[i]==n)per
-whatever_number_of_bytes_it_is

1
[]==a[i]*0per un controllo di tipo più breve
ovs,

Prova a scorrere ainvece di un intervallo e a getitem
usarne


0

Ottava , 126 122 byte

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

Provalo online!

Per leggibilità, ho sostituito gli spazi o quelli ;con le estremità delle linee, ove possibile. Spiegazione del codice non salvato:

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 byte

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

Provalo online

Metodo non golfato

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;
}
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.