Cari dalam Daftar


19

Untuk tantangan ini, daftar dianggap valid jika dan hanya jika seluruhnya terdiri dari bilangan bulat dan daftar yang valid (definisi rekursif \ o /). Untuk tantangan ini, diberikan daftar yang valid dan bilangan bulat, kembalikan daftar semua kedalaman tempat bilangan bulat dapat ditemukan.

Contoh

Mari kita pertimbangkan daftar [1, [2, [3, [1, 2, 3], 4], 1], 1]dan integer 1. Kemudian, kita dapat menarik daftar seperti ini:

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

Anda akan melihat yang 1muncul di kedalaman 0, 1, 3. Dengan demikian, output Anda harus 0, 1, 3dalam format yang masuk akal (urutan tidak masalah).

Kedalamannya bisa 0 atau 1-diindeks, tetapi harap tentukan dalam kiriman Anda yang mana.

Kasus Uji (0-diindeks)

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

Untuk daftar [[[[[1],0],1],0],1]:

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

Untuk daftar [11,22,[33,44]]:

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

Kembalikan daftar kosong jika istilah pencarian tidak ada di daftar di mana pun.

Nilai negatif dan nol valid dalam daftar input dan istilah.


Jika bilangan bulat muncul pada satu kedalaman beberapa kali, apakah kita harus mengembalikan nomor kedalaman itu sekali saja?
Giuseppe

@ Giuseppe ya, itu benar.
HyperNeutrino

1
@ Adám Yah mengingat bahwa salah satu kasus pengujian saya memiliki nol, tidak. Saya juga akan menambahkan bahwa bilangan bulat negatif adalah permainan yang adil.
HyperNeutrino

1
Nomor multi-digit juga harus ditambahkan dalam kasus uji, jika dapat terjadi.
Zgarb

1
@KevinCruijssen Ya, ya, tidak, dan ya. Jadi, Anda dapat mengambil input baik sebagai string, dan Anda dapat menampilkan kedalaman dalam urutan apa pun, tetapi tidak beberapa kali.
HyperNeutrino

Jawaban:


7

Mathematica, 25 byte

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

(mengembalikan output 1-diindeks)

Penjelasan

                         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

Terima kasih Bruce Forte karena menyimpan beberapa byte, dan Laikoni karena menyimpan lebih banyak.

Terima kasih 4castle untuk menghemat 4 byte.

Haskell tidak memiliki tipe data untuk daftar jenis ini, jadi saya membuatnya sendiri.

Solusi ini 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

Cobalah online!

Pertama saya mendefinisikan (secara rekursif) tipe data T

Tmemiliki tipe E Int(elemen tipe tunggal Int) atau L[L](daftar tipe T).

(%)adalah fungsi yang mengambil 2argumen, berdasarkan tipe T, daftar yang melaluinya kita mencari, dan x, yang Intkita cari.

Setiap kali (%)menemukan sesuatu yang merupakan elemen tunggal E n, ia memeriksa nkesetaraan dengan xdan kembali 0jika Benar.

Ketika (%)diterapkan pada L s(di mana smemiliki tipe [T]) itu berjalan (%)pada semua elemen sdan meningkatkan hasilnya (karena kedalaman meningkat karena kita melihat ke dalam s), dan hasilnya adalah gabungan.

nub kemudian menghapus duplikat dari daftar

NB. import Data.Listhanya untuk nub.


Saya datang dengan solusi yang sangat mirip untuk 81 byte: Cobalah online!
Laikoni

@Laikoni Sangat bagus, apakah Anda ingin mempostingnya sendiri, atau Anda menyarankan saya memperbarui milik saya?
H.PWiz

Jangan ragu untuk memperbarui jawaban Anda. :)
Laikoni

Mengenai NB: Saya mencoba untuk menyingkirkan impor, tetapi berakhir pada 88 byte: Coba online!
Laikoni

2
Anda dapat menghapus tanda kurung di sekitar E ndan L s.
4castle



4

Jelly , 11 8 byte

WẎÐĿċ€IT

Cobalah online!

Bagaimana itu bekerja

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.

Contoh dijalankan

Untuk argumen kiri

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

W pertama menghasilkan array berikut.

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

ẎÐĿberulang kali menggabungkan semua elemen pada kedalaman 1 , mengurangi kedalaman array sebesar 1 pada setiap langkah. Ini menghasilkan susunan hasil antara berikut.

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

Untuk argumen 1 benar , ċ€hitung kejadian 1 di setiap hasil antara.

[0, 2, 3, 3, 4]

I sekarang membawa semua perbedaan ke depan.

[2, 1, 0, 1]

Perbedaan yang tidak nol berhubungan dengan langkah-langkah di mana setidaknya satu 1 lainnya ditambahkan ke kedalaman 1 . Dengan demikian, perbedaan yang tidak nol pada indeks k menunjukkan adanya 1 pada kedalaman k . Tmenemukan indeks semua elemen kebenaran, menghasilkan hasil yang diinginkan:

[1, 2, 4]

Ini adalah solusi tepat saya ketika membandingkan Jelly dengan Python. yay! : 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)))

Cobalah online!

Solusi rekursif; itu cukup tidak efisien dalam byte, tetapi Rlists sangat menjengkelkan untuk bekerja dengannya.

Pada dasarnya, mengambil L, dan untuk setiap elemen xdari L, (yang baik listatau atomicvektor dari satu elemen), memeriksa apakah nini %in% x, kemudian memeriksa apakah xadalah list. Jika tidak, maka x==nkami mengembalikan kedalamannya d; kalau tidak kita rekursif sebut fdix , incrementingd .

Ini, tentu saja, mengembalikan a list, yang kami unlistdan uniqueuntuk memastikan hasil yang benar (mengembalikan vektor kedalaman bilangan bulat); kembaliNULL (daftar kosong) untuk tidak valid n.

Tampaknya, %in%tidak mencari secara rekursif melalui listseperti yang saya pikir, jadi saya harus unlist(x)+8 byte :(


3

APL (Dyalog) , 39 byte *

Program lengkap. Meminta daftar, lalu untuk nomor. Mencetak daftar berbasis 1 ke STDOUT.

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

Cobalah online!

 meminta daftar

 menghasilkan yang (memisahkan 0dan )

⎕JSON⍠'Compact'0 konversi ke string JSON indentasi dengan baris baru

⎕FMT konversikan ke matriks (satu baris dibatasi-baris per baris)

⍞⍷ meminta nomor sebagai string dan menunjukkan dari mana itu dimulai

∨⌿ pengurangan OR vertikal (yaitu kolom mana itu dimulai)

 indeks dari permulaan tersebut

2÷⍨ membagi dua itu (level indentasi dengan dua spasi)

 round down (karena kolom data pertama adalah kolom 3)


* Dalam Dyalog Classic, menghitung sebagai ⎕U2378dan sebagai ⎕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);

Cobalah 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

Mengembalikan Set. Jika ini tidak dapat diterima, gunakan &&[...r]dengan biaya 5 byte.


1

Jelly ,  17  16 byte

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

Program lengkap yang mengambil dua baris perintah mendebat daftar dan elemen untuk diperiksa, dan mencetak kedalaman atau kedalaman (jika ada) di mana elemen itu ada. Hasilnya 1-diindeks.

Cobalah online!

Bagaimana?

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

Bagus! Fakta yang menyenangkan: dengan menggunakan pendekatan yang sangat mirip tetapi dengan mengubah urutan hal-hal sedikit, Anda bisa mendapatkan 8 byte. sunting pendekatannya agak berbeda, nvm
HyperNeutrino


Hmm menemukan bug selama penulisan ... menghapus untuk saat ini.
Jonathan Allan

Ah saya entah bagaimana mengubah urutan rangkaian saya: Saya harus bekerja sekarang
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)

Penjelasan:

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

Uji kasus


Meskipun tidak ada kasus tes [belum], pembacaan saya terhadap pertanyaan menunjukkan bahwa itu valid e[0]menjadi nol, yang akan membuang tes Anda.
Neil

@ Neil, titik yang sangat baik. Sekarang diubah e.popmenjadi kehilangan satu 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}

Cobalah online!

-37 byte berkat Hyper Neutrino dan ovs

-4 byte terima kasih kepada Jonathan Frech


Coba if type(a[i])!=int-1 byte
HyperNeutrino

Coba l+=[d]untuk -5 byte
HyperNeutrino

Cobalah l+=[d]*(a[i]==n)untuk -apa
pun_number_of_bytes_it_is

1
[]==a[i]*0untuk pemeriksaan tipe yang lebih pendek
ovs

Coba iterasi melalui abukannya rentang dan gunakan getitembegitu banyak untuk - ~ 20 byte
HyperNeutrino


0

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

Cobalah online!

Agar mudah dibaca, saya mengganti spasi atau ;dengan ujung baris jika memungkinkan. Penjelasan kode tidak disunat:

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

Cobalah secara Online

Metode tidak serigala

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;
}
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.