Derin Liste Ara


19

Bu zorluk için, bir liste yalnızca ve yalnızca tamsayılar ve geçerli listelerden oluşuyorsa (özyinelemeli tanımlar \ o /) geçerli sayılır. Bu sorun için, geçerli bir liste ve bir tamsayı verildiğinde, tamsayı bulunabilecek tüm derinliklerin bir listesini döndürün.

Misal

Liste [1, [2, [3, [1, 2, 3], 4], 1], 1]ve tamsayıyı ele alalım 1. Sonra listeyi şu şekilde çizebiliriz:

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

Bunun 1derinliklerde ortaya çıktığını fark edeceksiniz 0, 1, 3. Bu nedenle, çıktınız 0, 1, 3makul bir biçimde olmalıdır (sıra önemli değildir).

Derinlik 0- veya 1 indeksli olabilir, ancak lütfen gönderiminizde hangisinin olduğunu belirtin.

Test Durumları (0 dizinli)

Liste için [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]

Liste için [[[[[1],0],1],0],1]:

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

Liste için [11,22,[33,44]]:

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

Arama terimi listede hiçbir yerde yoksa boş bir liste döndürün.

Negatif ve sıfır değerleri giriş listesinde ve terimde geçerlidir.


Tamsayı bir derinlikte birden çok kez görünüyorsa, bu derinlik numarasını yalnızca bir kez mi döndürmeliyiz?
Giuseppe

@Giuseppe evet, bu doğru.
HyperNeutrino

1
@ Adám Test durumlarımdan birinin sıfırları olduğu göz önüne alındığında, hayır. Ayrıca negatif tamsayıların adil oyun olduğunu da ekleyeceğim.
HyperNeutrino

1
Çok basamaklı sayılar, oluşabilecekse bir test senaryosuna da eklenmelidir.
Zgarb

1
@KevinCruijssen Evet, evet, hayır ve evet. Böylece girdileri hem dize olarak alabilir, hem de derinliği istediğiniz sırada görüntüleyebilirsiniz, ancak birden çok kez görüntüleyebilirsiniz.
HyperNeutrino

Yanıtlar:


7

Mathematica, 25 bayt

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

(1 dizinli çıktı döndürür)

açıklama

                         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 bayt

Teşekkür Bruce Forte bazı bayt kaydetmek için, ve Laikoni biraz daha tasarruf için.

4 bayt kaydettiğiniz için teşekkürler 4castle .

Haskell'in bu tür bir liste için veri türü yok, bu yüzden kendiminkini yaptım.

Bu çözüm 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

Çevrimiçi deneyin!

Önce bir veri türünü (özyineli olarak) tanımlarım T

Ttürüne E Int( türün tek öğesi Int) veya L[L](tür listesine T) sahiptir.

(%)sürer fonksiyonudur 2Çeşidi üzerine, argümanlar T, biz arıyorsunuz geçtiği listesi ve x, Intbiz arıyoruz.

Ne zaman (%)tek bir öğedir şey bulur E n, bu kontroller nile eşitlik için xve döner 0true eğer.

Bir ( tipin olduğu yerde ) (%)uygulandığında sonucun tüm unsurları üzerinde çalışır ve sonucu artırır (içeriye baktığımızdan beri derinlik arttıkça ) ve sonucu birleştirir.L ss[T](%)ss

nub ardından kopyaları listeden kaldırır

NB. import Data.Listsadece içindir nub.


81 bayt için oldukça benzer bir çözüm buldum: Çevrimiçi deneyin!
Laikoni

@Laikoni Çok güzel, kendiniz göndermek ister misiniz, yoksa benimkini güncellememi önerir misiniz?
H.PWiz

Cevabınızı güncellemekten çekinmeyin. :)
Laikoni

NB ile ilgili olarak: İthalattan kurtulmaya çalıştım, ancak 88 baytta bitirdim: Çevrimiçi deneyin!
Laikoni

2
E nVe etrafındaki parantezleri kaldırabilirsiniz L s.
4castle



4

Jöle , 11 8 bayt

WẎÐĿċ€IT

Çevrimiçi deneyin!

Nasıl çalışır

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.

Örnek çalışma

Sol argüman için

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

W ilk önce aşağıdaki diziyi verir.

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

ẎÐĿderinlik 1'deki tüm öğeleri art arda birleştirir ve dizinin derinliğini her adımda 1 azaltır . Bu, aşağıdaki ara sonuç dizisini verir.

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

Sağ argüman 1 için , her ara sonuçta 1'inċ€ oluşumunu sayar .

[0, 2, 3, 3, 4]

I şimdi tüm ileri farklılıkları alıyor.

[2, 1, 0, 1]

Sıfır olmayan farklılıklar , derinlik 1'e en az bir tane daha 1 eklenmiş adımlara karşılık gelir . Bu nedenle, indeks bir sıfır olmayan bir fark k bir varlığını gösterir 1 derinliğe k . İstenen sonucu veren tüm doğruluk unsurlarının indekslerini bulur:T

[1, 2, 4]

Jelly ile Python'u karşılaştırırken tam çözümüm buydu. Yaşasın! : P
HyperNeutrino

4

R , 101 95 92100 bayt

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

Çevrimiçi deneyin!

Özyinelemeli çözüm; bayt olarak oldukça verimsiz, ancak R listsçalışmak için çok can sıkıcı.

Temel olarak, alır Lve her bir elemanı için xbir L(ya olduğu listveya atomicbir elementin vektörü), kontrol durumunda nise %in% x, o zaman kontrol eder, eğer xa, list. Değilse, o zaman x==nderinliği geri veririz d; aksi takdirde biz yinelemeli çağrı füzerine xbir arttırılarak d.

Bu, elbette, listbiz unlistve uniquedoğru çıktıyı (tamsayı derinliklerin bir vektörünü döndürerek) sağlamak için a döndürür; NULLgeçersiz (boş bir liste) döndürür n.

Görünüşe göre, düşündüğüm gibi %in%yinelemeli arama yapmıyor list, bu yüzden unlist(x)+8 bayt :(


3

APL (Dyalog) , 39 bayt *

Tam program. Önce listeyi sonra da numarayı ister. 1 tabanlı listeyi STDOUT'a yazdırır.

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

Çevrimiçi deneyin!

 liste istemi

 verim (ayırır 0ve )

⎕JSON⍠'Compact'0 yeni satırlarla girintili JSON dizesine dönüştür

⎕FMT matrise dönüştür (satır başına bir satırsonu sınırlandırılmış çizgi)

⍞⍷ dize olarak sayı sor ve bunun nereden başladığını belirt

∨⌿ dikey OR azaltma (yani hangi sütunlarda başladığı)

 bu başlangıçların endeksleri

2÷⍨ yarıya indir (seviyeler iki boşlukla girintilidir)

 aşağı yuvarla (çünkü ilk veri sütunu sütun 3'tür)


* Olarak Dyalog Klasik, sayım olarak ⎕U2378ve şekilde ⎕OPT.



2

JavaScript (ES6), 79 68 bayt

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

Bir Küme döndürür. Bu kabul edilemezse, &&[...r]5 bayt maliyetle kullanın .


1

Jöle ,  17  16 bayt

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

İki komut satırı alan tam bir program listeyi ve denetlenecek öğeyi değiştirir ve öğenin var olduğu derinliği veya derinlikleri (varsa) yazdırır. Sonuçlar 1 indekslenir.

Çevrimiçi deneyin!

Nasıl?

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

Güzel! Eğlenceli gerçek olsa da: çok benzer bir yaklaşım kullanarak, ancak şeylerin sırasını biraz değiştirerek, 8 bayt alabilirsiniz. düzenlemek yaklaşım aslında biraz farklı, nvm
HyperNeutrino


Hmm yazma sırasında hatalar buldu ... şimdilik siliniyor.
Jonathan Allan

Ah bir şekilde benim birleşim sırasını değiştirmiştim: / şimdi çalışıyor olmalı
Jonathan Allan

1

JavaScript (ES6), 73 74 bayt

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

Açıklama:

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

Test senaryoları


Henüz bir test durumu olmasa da, soruyu okuduğumda, e[0]sıfır olması için geçerli olduğu ve testinizi kaldıracağı belirtiliyor.
Neil

@Neil, mükemmel bir nokta. Şimdi e.popbir bayt kaybı için olarak değiştirildi .
Rick Hitchcock

1

Python 3 , 123 86 82 bayt

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}

Çevrimiçi deneyin!

Hyper Neutrino ve ovs sayesinde -37 bayt

Jonathan Frech sayesinde -4 bayt


if type(a[i])!=int-1 bayt için deneyin
HyperNeutrino

l+=[d]-5 bayt için deneyin
HyperNeutrino


1
[]==a[i]*0daha kısa tip kontrol için
ovs

aAralık yerine yineleme yapmayı ve getitem- ~ 20 bayt için çok fazla kullanmayı deneyin
HyperNeutrino


0

Octave , 126 122 bayt

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

Çevrimiçi deneyin!

Okunabilirlik için boşlukları veya ;'leri mümkün olduğunca çizgi uçlarıyla değiştirdim . Yasadışı kod açıklaması:

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 bayt

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

Çevrimiçi Deneyin

Kurtulmamış yöntem

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;
}
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.