Глибокий пошук списку


19

Для цього виклику список вважається дійсним тоді і лише тоді, коли він складається повністю з цілих чисел та дійсних списків (рекурсивні визначення \ o /). Для цього виклику, задавши дійсний список і ціле число, поверніть список усіх глибин, на яких може бути знайдено ціле число.

Приклад

Розглянемо список [1, [2, [3, [1, 2, 3], 4], 1], 1]і ціле число 1. Тоді ми можемо скласти такий список:

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

Ви помітите, що 1з’являється на глибині 0, 1, 3. Таким чином, ваш вихід повинен бути 0, 1, 3у певному розумному форматі (порядок не має значення).

Глибина може бути 0 або 1-індексованою, але, будь ласка, вкажіть у своєму поданні, яка вона.

Випробування (0-індексовано)

Для списку [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]

Для списку [[[[[1],0],1],0],1]:

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

Для списку [11,22,[33,44]]:

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

Поверніть порожній список, якщо пошукова фраза не існує в списку ніде.

Негативні та нульові значення дійсні у вхідному списку та терміні.


Якщо ціле число з'являється на одній глибині кілька разів, чи потрібно нам повернути це число глибини лише один раз?
Джузеппе

@Giuseppe так, це правильно.
HyperNeutrino

1
@ Adám Добре, враховуючи, що в одному з моїх тестових випадків є нулі, ні. Також додам, що від'ємні цілі числа - це чесна гра.
HyperNeutrino

1
Багатозначні числа також слід додавати в тестовий випадок, якщо вони можуть виникнути.
Згарб

1
@KevinCruijssen Так, так, ні, і так. Таким чином, ви можете приймати входи як у вигляді рядків, так і глибину можна відображати в будь-якому порядку, але не кілька разів.
HyperNeutrino

Відповіді:


7

Математика, 25 байт

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

(повертає 1-індексований вихід)

Пояснення

                         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 байт

Дякую Брюсу Форте за збереження деяких байтів, а Лайконі за збереження ще кількох.

Дякую 4castle за збереження 4 байтів.

У Haskell немає такого типу даних для такого списку, тому я зробив свій власний.

Це рішення є 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

Спробуйте в Інтернеті!

Спочатку я визначаю (рекурсивно) тип даних T

Tмає або тип E Int(один елемент типу Int), або L[L](список типу T).

(%)це функція, яка бере 2аргументи, за типом T, список, через який ми шукаємо, і x, який Intми шукаємо.

Кожного разу, коли (%)знайдеться щось, що є єдиним елементом E n, він перевіряє nрівність xі повертає, 0якщо це правда.

Коли (%)застосовується до L s(де sмає тип [T]), він працює (%)на всіх елементах sі збільшує результат (оскільки глибина збільшується, оскільки ми заглядаємо всередину s), і об'єднує результат.

nub потім видаляє дублікати зі списку

NB. import Data.Listє лише для nub.


Я придумав досить схоже рішення на 81 байт: Спробуйте це в Інтернеті!
Laikoni

@Laikoni Дуже приємно, ви хочете опублікувати його самостійно, чи ви пропонуєте я оновити шахту?
H.PWiz

Не соромтеся оновити свою відповідь. :)
Laikoni

Щодо НБ: Я намагався позбутися імпорту, але закінчував 88 байт: Спробуйте в Інтернеті!
Laikoni

2
Ви можете видалити круглі дужки навколо E nта L s.
4castle



4

Желе , 11 8 байт

WẎÐĿċ€IT

Спробуйте в Інтернеті!

Як це працює

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.

Приклад виконання

Для лівого аргументу

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

W Спочатку отримує наступний масив.

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

ẎÐĿповторно з'єднує всі елементи на глибині 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  ],
 [ 1,  2,  3,  1, 2, 3,  4,  1, 1  ]
]

Для правильного аргументу 1 , ċ€підраховує число входжень 1 в кожному проміжному результаті.

[0, 2, 3, 3, 4]

I тепер приймає всі розбіжності вперед.

[2, 1, 0, 1]

Ненульові різниці відповідають крокам, в яких принаймні один інший 1 був доданий до глибини 1 . Таким чином, ненульова різниця в індексі k вказує на наявність 1 на глибині k . Tзнаходить показники всіх елементарних елементів, що дають бажаний результат:

[1, 2, 4]

\ o / це було моїм точним рішенням при порівнянні Jelly з Python. так! : P
HyperNeutrino

4

R , 101 95 92 100 байт

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

Спробуйте в Інтернеті!

Рекурсивний розчин; він досить неефективний у байтах, але R listsдуже прикро працювати.

В основному, приймає L, і для кожного елемента xз L, (який є або listчи atomicвектор одного елемента), перевіряє , є чи nце %in% x, а потім перевіряє , є чи xце list. Якщо це не так, то x==nми повертаємо глибину d; в іншому випадку ми рекурсивний виклик fна x, збільшенні d.

Це, звичайно, повертає a list, яке ми unlistі uniqueдля забезпечення правильного виводу (повернення вектора цілих глибин); повертає NULL(порожній список) для недійсного n.

Мабуть, %in%не шукає рекурсивно через те, listяк я думав, тому мені потрібно unlist(x)+8 байт :(


3

APL (Діалог) , 39 байт *

Повна програма. Підказки для списку, потім для номера. Друкує 1-базований список до STDOUT.

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

Спробуйте в Інтернеті!

 запит на список

 врожайність, що (відокремлює 0і )

⎕JSON⍠'Compact'0 перетворити в відступ JSON рядок з новими рядками

⎕FMT перетворити в матрицю (по одному рядку з обмеженим рядком на рядок)

⍞⍷ підкажете номер як рядок і вкажіть, де він починається в цьому

∨⌿ вертикальне зменшення АБО (тобто в яких стовпцях воно починається)

 індекси цих початків

2÷⍨ наполовину, що (рівні відступили двома пробілами)

 округніть вниз (адже перший стовпець даних - це стовпець 3)


* У Dyalog Classic, рахуючи як ⎕U2378і як ⎕OPT.



2

JavaScript (ES6), 79 68 байт

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

Повертає набір. Якщо це неприпустимо, використовуйте &&[...r]вартістю 5 байт.


1

Желе ,  17  16 байт

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

Повна програма, що бере два аргументи командного рядка, список та елемент для перевірки та друк глибини чи глибини (якщо такі є), на яких елемент існує. Результати є 1-індексованими.

Спробуйте в Інтернеті!

Як?

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

Приємно! Цікавий факт, хоча: використовуючи дуже подібний підхід, але трохи змінивши порядок речей, ви можете отримати 8 байт. редагувати підхід насправді трохи інший, nvm
HyperNeutrino


Хм знайшли помилки під час запису ... видалення наразі.
Джонатан Аллан

Ах, я якось змінив порядок моєї конкатенації: / повинен працювати зараз
Джонатан Аллан

1

JavaScript (ES6), 73 74 байт

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

Тестові справи


Хоча немає жодних тестових випадків [поки що], моє читання запитання говорить про те, що це дійсно e[0]нуль, який би скинув ваш тест.
Ніл

@Neil, відмінний момент. Тепер змінено на e.popвтрату одного байта.
Рік Хічкок

1

Пітон 3 , 123 86 82 байт

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}

Спробуйте в Інтернеті!

-37 байт завдяки Hyper Neutrino та ovs

-4 байти завдяки Джонатану Фреху


Спробуйте if type(a[i])!=intдля -1 байт
HyperNeutrino

Спробуйте l+=[d]для -5 байт
HyperNeutrino

Спробуйте l+=[d]*(a[i]==n)для
-wever_number_of_bytes_it_is

1
[]==a[i]*0для коротшої перевірки типу
ов.

Спробуйте ітерацію через aдіапазон і getitemстільки використовувати для - ~ 20 байт
HyperNeutrino


0

Октава , 126 122 байти

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

Спробуйте в Інтернеті!

Для читабельності я замінив пробіли або ;'s кінцями рядків, де це можливо. Пояснення неозореного коду:

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 байти

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

Спробуйте це в Інтернеті

Негольдований метод

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;
}
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.