Покидая гнездо


23

Учитывая неплоский список целых чисел, выведите список списков, содержащих целые числа на каждом уровне вложенности, начиная с уровня с наименьшим вложением, со значениями в их исходном порядке в списке ввода при чтении слева направо. Если два или более списков находятся на одном уровне вложенности во входном списке, они должны быть объединены в один список в выходных данных. Вывод не должен содержать пустых списков - уровни вложенности, содержащие только списки, должны быть полностью пропущены.

Вы можете предположить, что целые числа находятся в (включительно) диапазоне [-100, 100]. Для списков нет максимальной длины или глубины вложенности. На входе не будет пустых списков - каждый уровень вложенности будет содержать хотя бы одно целое число или список.

Входные и выходные данные должны быть в собственном списке / массиве / перечислимом / итерируемом / вашего языка. формат или в любом разумном, однозначном формате, если в вашем языке отсутствует тип последовательности.

Примеры

[1, 2, [3, [4, 5], 6, [7, [8], 9]]] => [[1, 2], [3, 6], [4, 5, 7, 9], [8]]

[3, 1, [12, [14, [18], 2], 1], [[4]], 5] => [[3, 1, 5], [12, 1], [14, 2, 4], [18]]

[2, 1, [[5]], 6] => [[2, 1, 6], [5]]

[[54, [43, 76, [[[-19]]]], 20], 12] => [[12], [54, 20], [43, 76], [-19]]

[[[50]], [[50]]] => [[50, 50]]

Ответы:


5

Пиф, 17

 us-GeaYsI#GQ)S#Y

Ведущее пространство важно. Это фильтрует список на предмет того, являются ли значения инвариантными для sфункции, затем удаляет эти значения из списка и выравнивает его на один уровень. Значения также сохраняются в Yпамяти, и когда мы печатаем, мы удаляем пустые значения путем фильтрации, если отсортированное значение списка верно.

Тестирование

Альтернативно, 15-байтовый ответ с сомнительным выходным форматом:

 us-GpWJsI#GJQ)

Тестирование

Расширение:

 us-GeaYsI#GQ)S#Y     ##   Q = eval(input)
 u          Q)        ##   reduce to fixed point, starting with G = Q
        sI#G          ##   get the values that are not lists from G
                      ##   this works because s<int> = <int> but s<list> = flatter list
      aY              ##   append the list of these values to Y
     e                ##   flatten the list
   -G                 ##   remove the values in the list from G
              S#Y     ##   remove empty lists from Y




1

Mathematica 55 64 62 байта

#~Select~AtomQ/.{}->Nothing&/@Table[Level[#,{k}],{k,Depth@#}]&

%&[{1, 2, {3, {4, 5}, 6, {7, {8}, 9}}}]

{{1, 2}, {3, 6}, {4, 5, 7, 9}, {8}}


1

JavaScript, 112 80 байт

F=(a,b=[],c=0)=>a.map(d=>d!==+d?F(d,b,c+1):b[c]=[...b[c]||[],d])&&b.filter(d=>d)

Спасибо Нейлу за помощь, чтобы сбрить 32 байта.


1
Много возможностей для игры в гольф здесь. Некоторые из них являются простыми , чтобы удалить , !=nullкак nullэто falsy в любом случае. Это b=также не нужно. Удалив его, вы можете затем переместить .filter(a=>x)его в, &&bкоторый затем уменьшает внешнюю функцию до вызова внутренней функции, которую вы можете затем встроить. Я остался с этим f=(a,b=[],c=0)=>a.map(d=>d[0]?f(d,b,c+1):b[c]=[...b[c]||[],d])&&b.filter(d=>d).
Нил

@Neil d[0]?будет оценивать, falseесли он равен 0, что находится в пределах диапазона [-100,100]. И так будетd=>d
Патрик Робертс

@Neil бросил это в спешке, так что я знал, что были другие возможности уменьшить его, но это намного лучше, чем я мог сделать даже тогда. Благодарность! О, и Патрик прав на нулевую проверку, которая необходима по этой причине. Я пошел с d===+dтем, хотя, так как это экономит 2 байта на нулевой проверке.
Mwr247

1
@Dendrobium Это не обработает последний случай (или любые случаи с [...,[[...]]]) должным образом
Mwr247

1
@PatrickRoberts d=>d- это нормально, так dкак в этой точке всегда массив или ноль , но это справедливо d[0], хотя всегда есть d.mapчто-то правдивое для массива, но ложное для числа.
Нил


0

Python, 108 99 байт

Это кажется мне немного длинным, но я не смог бы сделать одну строчку короче, и если я попытаюсь использовать orвместо if, я получу пустые списки в результатах.

def f(L):
    o=[];i=[];j=[]
    for x in L:[i,j][[]<x]+=[x]
    if i:o+=[i]
    if j:o+=f(sum(j,[]))
    return o

Попробуйте онлайн

Редактировать: 9 байтов сохранено благодаря переполнению стека


Вы должны изменить свои отступы на одиночные пробелы, чтобы они правильно отображались в блоке кода. Вы также можете использовать filter(None,o)для удаления пустых списков, которые находятся на самом внешнем уровне вложенности o.
Мего

Я предпочитаю просматривать мой код с вкладками. Пространства злые.
mbomb007

SE Markdown преобразует вкладки в 4 пробела, так что в любом случае их не избежать :) Использование одного пробела в Markdown приводит к тому, что число байтов блока кода фактически совпадает с числом байтов кода.
Мего

Мой код сам содержит вкладки, если вы хотите отредактировать его. Это то, что внутри, что имеет значение. ;)
mbomb007

0

Python 3, 109 байт

Как всегда, глупые возможности Python 2, такие как сравнение ints и lists, означают, что Python 3 выходит позади. Ну что ж...

def d(s):
 o=[]
 while s:
  l,*n=[],
  for i in s:
   try:n+=i
   except:l+=[i]
  if l:o+=[l]
  s=n
 return o

0

Perl, 63 байта

{$o[$x++]=[@t]if@t=grep{!ref}@i;(@i=map{@$_}grep{ref}@i)&&redo}

Ввод ожидается в @i, выход производится в @o. (Надеюсь это приемлемо).

Пример:

@i=[[54, [43, 76, [[[-19]]]], 20], 12];                              # input

{$o[$x++]=[@t]if@t=grep{!ref}@i;(@i=map{@$_}grep{ref}@i)&&redo}      # the snippet

use Data::Dumper;                                                    # print output
$Data::Dumper::Indent=0;  # keep everything on one line
$Data::Dumper::Terse=1;   # don't print $VAR =
print Dumper(\@o);

Выход:

[[12],[54,20],[43,76],[-19]]

0

Clojure, 119 байт

(116 с последовательностью и вводом в виде списков, тривиальная модификация)

(defn f([v](vals(apply merge-with concat(sorted-map)(flatten(f 0 v)))))([l v](map #(if(number? %){l[%]}(f(inc l)%))v)))

Лучше задумано:

(defn f([v]  (vals(apply merge-with concat(sorted-map)(flatten(f 0 v)))))
       ([l v](map #(if(number? %){l[%]}(f(inc l)%))v)))

При вызове с двумя аргументами (текущий уровень и коллекция) он либо создает одноэлементную неупорядоченную карту, например {level: value}, либо вызывает fрекурсивно, если виден не номер (предположительно, коллекция).

Эти мини-карты затем объединяются в одну, sorted-mapа столкновения клавиш обрабатываются concatфункцией. valsвозвращает значения карты от первого уровня до последнего.

Если число является единственным на своем уровне, то оно остается vec, остальные преобразуются в списки с помощью concat.

(f [[54, [43, 76, [[[-19]]]], 20], 12])
([12] (54 20) (43 76) [-19])

Если бы вход был listвместо, vecто number?мог бы быть заменен на seq?, странным образом, вектор - seq?это не так sequential?. Но мне лень внедрять эту версию, пересматривать примеры и т. Д.


0

Ракетка 259 байт

(let((ol'())(m 0))(let p((l l)(n 0))(cond[(empty? l)][(list?(car l))(set! m(+ 1 n))
(p(car l)(+ 1 n))(p(cdr l)n)][(set! ol(cons(list n(car l))ol))(p(cdr l)n )]))
(for/list((i(+ 1 m)))(flatten(map(λ(x)(cdr x))(filter(λ(x)(= i(list-ref x 0)))(reverse ol))))))

Ungolfed:

(define (f l)
  (define ol '())
  (define maxn 0)
  (let loop ((l l)              ; in this loop each item is added with its level
             (n 0))
    (cond
      [(empty? l)]
      [(list? (first l))
       (set! maxn (add1 n))
       (loop (first l) (add1 n))
       (loop (rest l) n)]
      [else
       (set! ol (cons (list n (first l)) ol))
       (loop (rest l) n )]))

  ; now ol is '((0 1) (0 2) (1 3) (2 4) (2 5) (1 6) (2 7) (3 8) (2 9)) 

  (for/list ((i (add1 maxn)))   ; here similar levels are combined
    (flatten
     (map (λ (x) (rest x))      ; level numbers are removed
          (filter (λ (x) (= i(list-ref x 0)))
                  (reverse ol))))))

Тестирование:

(f '[1 2 [3 [4 5] 6 [7 [8] 9]]])

Выход:

'((1 2) (3 6) (4 5 7 9) (8))

0

MATL , 37 байт

j']['!=dYsXKu"GK@=)'[\[\],]'32YXUn?1M

Попробуйте онлайн!

Работает с текущей версией (13.0.0) языка / компилятора.

Это создает выходные данные в виде строк с разделенными пробелами значениями, где каждая строка соответствует одному и тому же уровню вложения, а разные уровни вложения разделяются символами новой строки.

j            % read input as string (row array of chars)
']['!        % 2x1 array containing ']'  and '['
=            % test for equality, all combinations
d            % row array obtained as first row minus second row
Ys           % cumulative sum. Each number is a nesting level
XK           % copy to clibdoard K
u            % unique values: all existing nesting levels
"            % for each nesting level
  G          %   push input
  K          %   push array that indicates nesting level of each input character
  @          %   push level corresponding to this iteration
  =          %   true for characters corresponding to that nesting level
  )          %   pick those characters
  '[\[\],]'  %   characters to be replaced
  32         %   space
  YX         %   regexp replacement
  U          %   only numbers and spaces remain: convert string to array of numbers
  n?         %   if non-empty
    1M       %     push that array of numbers again
             %   end if implicitly
             % end for each implicitly
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.