Упростить массив


22

вход

Массив, который может содержать массивы или положительные, последовательные, восходящие целые числа. Массивы могут иметь любое количество массивов внутри, и так далее, и тому подобное. Никакие массивы не будут пустыми.

Выход

Этот массив упрощен

Как упростить массив

Мы будем использовать массив, [1, [2, 3], [[4]], [[[5, 6], 7, [[[8]]]], 9]] как наш пример.

Сначала мы проверяем, насколько глубоко значения вложены. Вот глубины и числа на этих глубинах:

0  1
1  2 3 9
2  4 7
3  5 6
5  8

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

Итак, наш вывод [1, [2, 3, 9], [[4, 7]], [[[5, 6]]], [[[[[8]]]]]]

Примеры

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

Является ли выход гибким? Как числа в разных строках, где каждая строка - один уровень; или другие разделители / разделители массивов
Luis Mendo


@ LuisMendo, да, это гибко
Даниэль

Вам не хватает одной пары скобок 8на линии So, our output is...... Однако вы исправили это во фрагменте примеров.
сбисить

2
В некоторых ответах выдается пустая строка для уровней вложенности без элементов. Можно ли возвращать пустой массив в таких случаях, например, в первом примере [1, [2, 3, 9], [[4, 7]], [[[5, 6]]], [[[[]]]], [[[[[8]]]]]]?
Ними

Ответы:


1

Желе , 8 байт

fFṄḟ@;/ß

Выход - один уровень на строку, с пустыми строками для уровней без элементов. Попробуйте онлайн!

Как это работает

fFṄḟ@;/ß  Main link. Argument: A (array)

 F        Flat; yield all integers (at any level) in A.
f         Filter; intersect A with the integers, yielding those at level 0.
  Ṅ       Print the filtered array and a linefeed. Yields the filtered array.
     ;/   Reduce by concatenation.
          This decreases the levels of all integers at positive levels by 1.
   ḟ@     Swapped filter-false; remove the integers at level 0 in A from the array
          with decreased levels.
       ß  Recursively call the main link on the result.
          The program stops once A is empty, since ;/ will result in an error.

3

JavaScript (ES6), 139 109 байт

f=(a,v=b=>a.filter(a=>b^!a[0]))=>a[0]?v().concat((a=f([].concat(...v(1))),b=v())[0]?[b]:[],v(1).map(a=>[a])):[]

Объяснение с использованием примера input: vвспомогательный метод, который возвращает массивы (с параметром 1) или значения (без параметра). Начнем с того a = [1, [2, 3], [[4]], [[[5, 6], 7, [[[8]]]], 9]], что непусто. Мы отфильтровываем массивы, даем [1]. Затем мы рекурсивно обращаемся к сцепленным массивам, что является [2, 3, [4], [[5, 6], 7, [[[8]]]], 9]результатом [2, 3, 9, [4, 7], [[5, 6]], [[[[8]]]]]. Мы снова отфильтровываем массивы, что дает нам второй член нашего вывода [2, 3, 9], однако мы должны быть осторожны, чтобы не вставлять здесь пустой массив. Осталось обернуть массивы [4, 7], [[5, 6]], [[[[8]]]]внутри массивов и добавить их к выводу, в результате чего [1, [2, 3, 9], [[4, 7]], [[[5, 6]]], [[[[[8]]]]]].


Может быть в состоянии сохранить несколько байтов, сделав псевдоним для filter. Может быть, начать сF=(x,y)=>x.filter(y)
Cyoce

@Cyoce Оказалось 30 в конце!
Нил

У вас определенно есть кое-что для игры в гольф. Я думаю, что вы можете безопасно заменить [].concat(...v(1))на, v(1)чтобы сохранить 14 байтов. Возможно, есть и несколько других вещей, но мне трудно отследить вложенные скобки в моей голове.
Патрик Робертс

1
@PatrickRoberts [].concat(...v(1))совсем другой зверь v(1), иначе я бы этого не сделал! Для простого примера рассмотрим a = [2, [3], [[4]]]тогда, v(1) = [[3], [[4]]]но [].concat(...v(1)) = [3, [4]].
Нил

@ Нил, вау, мне действительно следовало проверить мое предложение, прежде чем открывать рот. Я чувствую, что должен быть более короткий способ сделать это, хотя ..
Патрик Робертс

2

05AB1E , 27 26 25 21 байт

D˜gFvyydi„ÿ ?}}¶?.gG«

Попробуйте онлайн! (немного изменен, поскольку .gеще не на TIO)

объяснение

D˜gF                    # flattened input length times do
    vy                  # for each y current level of list
      ydi„ÿ ?}          # if y is a digit, print with space
              }         # end v-loop
               ¶?       # print newline
                 .g     # calculate length of stack (this should be .g but I can't test)
                   G«   # length stack times, concatenate items on stack

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


2

Perl, 52 байта

Просто рекурсивная подпрограмма. (необычно для ответа на Perl, я знаю ..)

sub f{say"@{[grep!ref,@_]}";@_&&f(map/A/?@$_:(),@_)}

Назовите это так:

$ perl -E 'sub f{say"@{[grep!ref,@_]}";@_&&f(map/A/?@$_:(),@_)}f(1, [2, 3], [[4]], [[[5, 6], 7, [[[8]]]], 9])'
1
2 3 9
4 7
5 6

8

Каждая строка вывода соответствует уровню глубины массива (отсюда и пустая строка в приведенном выше примере).

Его можно превратить в полную программу всего за несколько байтов: добавить -nфлаг и eval(внутри, @{ }чтобы преобразовать входные данные в массив, а не arrayref), чтобы преобразовать входные данные в массив Perl:

perl -nE 'sub f{say"@{[grep!ref,@_]}";@_&&f(map/A/?@$_:(),@_)}f(@{+eval})' <<< "[1, [2, 3], [[4]], [[[5, 6], 7, [[[8]]]], 9]]"

Мой предыдущий подход был немного длиннее (65 байт), но все еще интересен, поэтому я позволю его здесь:

perl -nE '/\d/?push@{$;[$d-1]},$_:/]/?$d--:$d++for/\[|]|\d+/g;say"@$_"for@' <<< "[1, [2, 3], [[4]], [[[5, 6], 7, [[[8]]]], 9]]"

2

JavaScript (ES6) 121 144 152

редактировать Пересмотрено много, 1 байт сохранен, спасибо Патрику Робертсу, и еще 21, просто просматривая код

Рекурсивная функция, работающая с массивами на входе и выходе. Мне не нравится требованию , имеющие элементы на глубине 1 в качестве отдельных элементов в выходном массиве ( в то время как более высокие уровни группируются как один элемент): [l1,l1, [l2...], [[l3...]] ]. Хотя это было бы более прямым:[ [l1...], [[l2...]], [[[l3...]]] ]

f=(l,d=0,r=[])=>l.map(v=>v[0]?f(v,d+1,r):r[d]=[...r[d]||[],v])
r.reduce((r,v,d)=>d?[...r,(n=d=>d-->1?[n(d)]:v)(d)]:v,[])

Новая строка добавлена ​​для удобства чтения.

Некоторые примечания: строка 2 вычисляется снова и снова при каждом рекурсивном вызове, но полезна только последняя итерация в конце рекурсии.
Специальная обработка d==0в строке 2 обеспечивает аномалию для элементов уровня 1. Рекурсивная функция обрабатывает массив гнездящихся на выходе
n

Тест

f=(l,d=0,r=[])=>l.map(v=>v[0]?f(v,d+1,r):r[d]=[...r[d]||[],v])
&&r.reduce((r,v,d)=>d?[...r,(n=d=>d-->1?[n(d)]:v)(d)]:v,[])

console.log=x=>O.textContent+=x+'\n'

test=[
 [ 
   [1, [2,3], 4], /* -> */ [1, 4, [2,3]]
 ]
,[
   [1, [2, 3], [[4]], [[[5, 6], 7, [[[8]]]], 9]], 
   // ->
   [1, [2, 3, 9], [[4, 7]], [[[5, 6]]], [[[[[8]]]]]]
 ]
,[
  [[[1]], [2, [3]], 4, [5, [6, [7, [8], [9, [[10]]]]]]],
  // ->
  [4, [2, 5], [[1, 3, 6]], [[[7]]], [[[[8, 9]]]], [[[[[[10]]]]]]] 
 ]
,[  
  [1], /* -> */ [1]
 ]
,[  
  [1, [2], [[3]], [[[4]]], [[[[5]]]]],
  // ->
  [1, [2], [[3]], [[[4]]], [[[[5]]]]]
 ]
,[  
  [1, [[[[2], 3]]], [[4]]],
  [1, [[4]], [[[3]]], [[[[2]]]]]
]]

test.forEach(t=>{
  var i=t[0], k=t[1], r=f(i),
      si=JSON.stringify(i),
      sr=JSON.stringify(r),
      sk=JSON.stringify(k)
  
  console.log((sr==sk?'OK ':'KO ')+si + " => " + sr)
})
<pre id=O></pre>


1
Учитывая, что есть только вложенные массивы и положительные целые числа, и указано, что ни один из массивов на входе не является пустым, v[0]вместо этого будет более простой тест для вашего троичного оператора v.map. Сохраняет 1 байт.
Патрик Робертс

@PatrickRoberts круто спасибо
edc65

1

JavaScript (ES6) 168 байт

f=a=>(s=[],b=-1,k=0,a.replace(/\d+|\[|\]/g,a=>a=='['?b++:a==']'?b--:(s[b]=s[b]||[]).push(a)),'['+s.map((a,b)=>k=a&&(k?',':'')+'['.repeat(b)+a+']'.repeat(b)).join``+']')

демонстрация


1

PHP, 145 байт

<?function c($r){$n=[];foreach($r as$k=>$v)if(is_array($v)){$n=array_merge($n,$v);unset($r[$k]);}if($n)$r[]=c($n);return$r;}print_r(c($_GET[a]));

Сломать

function c($r){
  #usort($r,function($x,$y){return is_array($x)<=>is_array($y)?:$x<=>$y;}); 
#no need to sort and a simple sort($r); do it sort array after scalar
  $n=[];
  foreach($r as$k=>$v)if(is_array($v)){$n=array_merge($n,$v);unset($r[$k]);} # put arrays on the same depth together
  if($n)$r[]=c($n); # recursive if an array exists
  return$r; #return changes
}
print_r(c($_GET[a])); #Output and Input

1

Pyth, 19 16 байт

W=Qsf!&sITp+TdQk

Попробуйте онлайн. Тестирование.

Обратите внимание на ведущий пробел. Выводит уровни в строках, как в Perl.

объяснение

  • Неявный ввод в Q.
  • fМСДЭНИ элементы Tиз Qмодели:
    • Проверьте, sне Iгорит ли зуб T.
    • Если бы это было (это число), pечать Tплюс пространство +... d.
    • Если это не было (это был массив), сохраните его.
  • sгм предметы. Это удаляет слой массивов из каждого элемента. Если ничего не осталось, дает0 .
  • Присвойте =результат Q.
  • Wесли результат не пуст, выведите пустую строку kи символ новой строки.

1

Haskell, 124 123 байта

data L=I Int|R[L]
d#R l=((d+1)#)=<<l
d#i=[(d::Int,i)]
[]!_=[]
l!1=l
l!d=[R$l!(d-1)]
h l=R$do d<-[1..];[i|(e,i)<-0#l,d==e]!d

Поскольку Haskell по умолчанию не поддерживает смешанные списки (целые числа и список целых чисел), я определяю пользовательский тип списка L. Пример использования:

*Main> h (R[I 1, R[I 2, I 3], R[ R[I 4]], R[ R[ R[I 5, I 6], I 7, R[R[R[I 8]]]], I 9]])
R [I 1,R [I 2,I 3,I 9],R [R [I 4,I 7]],R [R [R [I 5,I 6]]],R [R [R [R [R [I 8]]]]]]

Примечание: для запуска требуется некоторое время, потому что он перебирает все положительные целые числа (32 или 64 бита), чтобы найти уровень гнезда настолько глубоко. Кроме того: пользовательский тип списка не может быть напечатан по умолчанию, поэтому, если вы хотите увидеть результат, как в примере выше, вам нужно добавить deriving Showв dataобъявление (->data L=I Int|R[L] deriving Show ). Поскольку он не нужен для возврата L-списка из функции, я не считаю байты.

Как это работает:

data L=I Int|R[L]               -- custom list type L, which is either an Int
                                -- (-> I Int) or a list of some L (-> R [L]) 

d#R l=((d+1)#)=<<l              -- # makes a list of (depth, I-number) pairs from
d#i=[(d::Int,i)]                -- a given L-list, e.g.
                                -- 0 # (R[I 1,R[I 2,I 3],I 4]) -> [(1,I 4),(2,I 2),(2,I 3),(1,I 4)]
                                -- the type annotation ::Int makes sure that all
                                -- depths are bounded. Without it, Haskell
                                -- would use arbitrary large numbers of type
                                -- ::Integer and the program won't finish

[]!_=[]                         -- ! wraps a list of Is with (d-1) additional
l!1=l                           --  R constructors
l!d=[R$l!(d-1)]

h l=                            -- main function, takes a L-list
      do d<-[1..]               -- for each nest level d make
        [i|(e,i)<-0#l,d==e]     -- a list of all I where the depth is d
                           !!d  -- and wrap it again with d-1 Rs         
     R$                         -- wrap with a final R

Редактирование @BlackCap спас байты при переходе от >>=к doнотации. Благодарность!


Do нотация сохраняет байтh l=R$do d<-[1..];[i|(e,i)<-0#l,d==e]!d
BlackCap

0

JavaScript (ES6), 127 137 134 байтов

Принимает массив в качестве входных данных и возвращает строку.

f=(a,l=[],d=0,o='')=>`[${a.map(x=>x[0]?f(x,l,d+1,o+'['):l[d]=(l[d]?l[d]+',':o)+x),l.map((s,d)=>x+s+']'.repeat(d,x=','),x='').join``}]`

Контрольные примеры


@Shebang Спасибо, что заметили. Это должно быть исправлено.
Арно

Я считаю, что это выглядит хорошо сейчас! :)
Kade
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.