Deep Search eine Liste

19

Für diese Herausforderung gilt eine Liste nur dann als gültig, wenn sie vollständig aus Ganzzahlen und gültigen Listen besteht (rekursive Definitionen \ o /). Geben Sie für diese Abfrage bei einer gültigen Liste und einer Ganzzahl eine Liste aller Tiefen zurück, in denen die Ganzzahl gefunden werden kann.

Beispiel

Betrachten wir Liste [1, [2, [3, [1, 2, 3], 4], 1], 1]und Ganzzahl 1. Dann können wir die Liste so zeichnen:

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

Sie werden bemerken, dass 1sich das in den Tiefen zeigt 0, 1, 3. Daher sollte Ihre Ausgabe 0, 1, 3in einem vernünftigen Format vorliegen (Reihenfolge spielt keine Rolle).

Die Tiefe kann entweder 0- oder 1-indiziert sein, aber bitte geben Sie in Ihrer Einreichung an, um welche es sich handelt.

Testfälle (0-indiziert)

Für die 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]

Für die Liste [[[[[1],0],1],0],1]:

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

Für die Liste [11,22,[33,44]]:

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

Gibt eine leere Liste zurück, wenn der Suchbegriff nirgendwo in der Liste vorhanden ist.

Negative und Nullwerte sind in der Eingabeliste und im Term gültig.

HyperNeutrino
quelle
Wenn die Ganzzahl mehrfach in einer Tiefe vorkommt, müssen wir diese Tiefenzahl nur einmal zurückgeben?
Giuseppe
@ Giuseppe ja, das ist richtig.
HyperNeutrino
1
@ Adám Na da einer meiner Testfälle Nullen hat, nein. Ich werde auch hinzufügen, dass negative ganze Zahlen faires Spiel sind.
HyperNeutrino
1
In einem Testfall sollten auch mehrstellige Zahlen hinzugefügt werden, wenn sie auftreten können.
Zgarb
1
@ KevinCruijssen Ja, ja, nein und ja. Sie können also Eingaben sowohl als Zeichenfolgen als auch in beliebiger Reihenfolge, jedoch nicht mehrmals, anzeigen.
HyperNeutrino

Antworten:

7

Mathematica, 25 Bytes

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

(gibt 1-indizierte Ausgabe zurück)

Erläuterung

                         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}
Mischa Lawrow
quelle
7

Haskell , 102 93 80 76 Bytes

Vielen Dank an Bruce Forte für das Speichern einiger Bytes und an Laikoni für das Speichern weiterer Bytes .

Danke 4castle für das Speichern von 4 Bytes.

Haskell hat keinen Datentyp für diese Art von Liste, daher habe ich meinen eigenen erstellt.

Diese Lösung ist 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

Probieren Sie es online!

Zuerst definiere ich (rekursiv) einen Datentyp T

That entweder Typ E Int(einzelnes Element des Typs Int) oder L[L](Liste des Typs T).

(%)ist eine Funktion, die 2Argumente vom Typ T, der Liste, in der gesucht wird, und xder Intgesuchten Funktion annimmt .

Wenn (%)etwas gefunden wird, das ein einzelnes Element ist E n, prüft es nauf Gleichheit mit xund gibt den 0Wert True zurück.

Wenn (%)es auf einen L s(where shas type [T]) angewendet wird, läuft es (%)auf allen Elementen von sund inkrementiert das Ergebnis (da die Tiefe zunimmt, seit wir nach innen schauen s) und verkettet das Ergebnis.

nub Entfernt dann die Duplikate aus der Liste

NB. import Data.Listist nur für nub.

H.PWiz
quelle
Ich habe mir eine ganz ähnliche Lösung für 81 Bytes ausgedacht: Online ausprobieren!
Laikoni
@Laikoni Sehr schön, möchtest du es selbst posten oder schlage du vor, ich aktualisiere meins?
H.PWiz
Fühlen Sie sich frei, Ihre Antwort zu aktualisieren. :)
Laikoni
Was den NB betrifft: Ich habe versucht, den Import loszuwerden, aber bei 88 Bytes gelandet: Probieren Sie es online aus!
Laikoni
2
Sie können die Klammern um E nund entfernen L s.
4castle
4

Jelly , 11 8 Bytes

WẎÐĿċ€IT

Probieren Sie es online!

Wie es funktioniert

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.

Beispiellauf

Für linkes Argument

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

W first ergibt das folgende Array.

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

ẎÐĿwiederholt verkettet alle Elemente in der Tiefe 1 , indem die Tiefe des Feldes zu reduzieren 1 in jedem Schritt. Dies ergibt die folgende Reihe von Zwischenergebnissen.

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

Für rechtes Argument 1 , ċ€zählt das Auftreten von 1 in jedem Zwischenergebnis.

[0, 2, 3, 3, 4]

I jetzt nimmt alle vorwärts unterschiede.

[2, 1, 0, 1]

Unterschiede ungleich Null entsprechen Schritten, in denen mindestens eine weitere 1 zur Tiefe 1 hinzugefügt wurde . Somit zeigt eine Differenz ungleich Null am Index k das Vorhandensein einer 1 in der Tiefe k an . TFindet die Indizes aller wahrheitsgemäßen Elemente und liefert das gewünschte Ergebnis:

[1, 2, 4]
Dennis
quelle
Dies war meine genaue Lösung, als ich Jelly mit Python verglich. 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)))

Probieren Sie es online!

Rekursive Lösung; Es ist ziemlich ineffizient in Bytes, aber listses ist super nervig mit R zu arbeiten.

Grundsätzlich prüft take Lund für jedes Element xvon L(das entweder ein listoder ein atomicVektor eines Elements ist), ob a nist %in% xund dann, ob a xist list. Wenn nicht, geben x==nwir die Tiefe zurück d. sonst rekursiv rufen wir fauf x, erhöht wird d.

Dies gibt natürlich a zurück list, was wir unlistund uniqueum die richtige Ausgabe sicherzustellen (Rückgabe eines Vektors mit ganzzahligen Tiefen); Gibt NULL(eine leere Liste) für ungültig zurück n.

Anscheinend %in%sucht man nicht rekursiv durch ein listwie ich dachte, also muss ich nach unlist(x)+8 Bytes suchen :(

Giuseppe
quelle
3

APL (Dyalog) , 39 Byte *

Volles Programm. Fordert zur Eingabe der Liste und dann der Nummer auf. Druckt eine 1-basierte Liste nach STDOUT.

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

Probieren Sie es online!

 Eingabeaufforderung für Liste

 ergeben, dass (trennt 0und )

⎕JSON⍠'Compact'0 Konvertieren in eingerückte JSON-Zeichenfolge mit Zeilenumbrüchen

⎕FMT In Matrix konvertieren (eine durch neue Zeilen getrennte Zeile pro Zeile)

⍞⍷ Eingabeaufforderung für Zahl als Zeichenfolge und geben Sie an, wo es damit beginnt

∨⌿ vertikale ODER-Verkleinerung (dh in welchen Spalten beginnt sie)

 Indizes dieser Anfänge

2÷⍨ halbieren (Ebenen werden mit zwei Leerzeichen eingerückt)

 Abrunden (da die erste Datenspalte Spalte 3 ist)


* In Dyalog Classic zählen als ⎕U2378und als ⎕OPT.

Adam
quelle
2

PHP , 117 Bytes

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

Probieren Sie es online!

Calimero
quelle
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

Gibt ein Set zurück. Wenn dies nicht akzeptabel ist, verwenden Sie es &&[...r]zu einem Preis von 5 Byte.

Neil
quelle
1

Jelly ,  17  16 Bytes

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

Ein vollständiges Programm, das zwei Befehlszeilenargumente für die Liste und ein zu überprüfendes Element verwendet und die Tiefe oder Tiefen (falls vorhanden) ausgibt, in denen das Element vorhanden ist. Die Ergebnisse sind 1-indiziert.

Probieren Sie es online!

Wie?

⁴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
quelle
Nett! Eine lustige Tatsache: Wenn Sie einen sehr ähnlichen Ansatz verwenden, aber die Reihenfolge der Dinge ein wenig ändern, können Sie 8 Bytes erhalten. Bearbeiten Sie den Ansatz ist eigentlich ein bisschen anders, NVM
HyperNeutrino
Dies funktioniert nicht ganz: tio.run/##y0rNyan8//9R45ZU60MrD607sfxR446HO@YDBR7u6ju09fCEI/…
HyperNeutrino
Hmm, ich habe Fehler beim Schreiben gefunden ... vorerst gelöscht.
Jonathan Allan
Ah, ich hatte irgendwie die Reihenfolge meiner Verkettung geändert: Ich sollte jetzt arbeiten
Jonathan Allan
1

JavaScript (ES6), 73 bis 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)

Erläuterung:

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

Testfälle

Rick Hitchcock
quelle
Obwohl es [noch] keine Testfälle gibt, legt meine Lektüre der Frage nahe, dass es gültig ist e[0], Null zu sein, was Ihren Test abwerfen würde.
Neil,
@ Neil, exzellenter Punkt. Jetzt geändert e.popfür einen Verlust von einem 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}

Probieren Sie es online!

-37 Bytes dank Hyper Neutrino und Ovs

-4 Bytes dank Jonathan Frech

Caird Coinheringaahing
quelle
Versuchen Sie if type(a[i])!=intfür -1 Byte
HyperNeutrino
Versuchen Sie es l+=[d]mit -5 Bytes
HyperNeutrino
Versuchen Sie l+=[d]*(a[i]==n)für -was auch immer_von_Bytes_es_ist
HyperNeutrino
1
[]==a[i]*0für eine kürzere Art check
ovs
Versuchen Sie, aanstelle eines Bereichs eine Iteration getitem
durchzuführen
0

Oktave , 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

Probieren Sie es online!

Aus Gründen der Lesbarkeit habe ich Leerzeichen oder ;'s nach Möglichkeit durch Zeilenenden ersetzt. Erklärung des ungolfed Codes:

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

Probieren Sie es online

Ungolfed-Methode

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
quelle