Перемешать рваный массив

23

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

Например, следующие рваные массивы:

[[1,2,3],[4],[9,10]]               Shape:  3,1,2
[[1],[2],[3]]                      Shape:  1,1,1
[[1,2,3,4,5,6,8]]                  Shape:  7

Следующие не рваные массивы:

[1]   Each element will be an array
[]    The array will contain at least 1 element
[[1,2,3],[]]  Each subarray will contain at least 1 integer

Вам нужно ввести рваный массив и вернуть рваный массив с перемешанными целыми числами

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

Например, если я передал:, [[4],[1,2,3],[4]]тогда [[1],[4,4,2],[3]]будет допустимым выводом, но [[4,1,3],[3],[4]]или [[4],[4],[1,2,3]]не будет.

Натан Меррилл
источник
Связанный.
Мартин Эндер
1
Будет ли вход всегда двухмерным массивом?
Деннис

Ответы:

17

Желе, 3 байта в кодовой странице желе

FẊṁ

Объяснение:

FẊṁ
F    flatten list
 Ẋ   shuffle the output from the previous line
  ṁ  unflatten the list, shaping it like…

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

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


источник
4
Ничего себе, unslatten - аккуратная и неожиданная команда.
Волшебная Осьминог Урна
3
Unflatten не может быть лучшим термином, так как левый аргумент не должен быть плоским. Мнемоника плесени .
Деннис
@Dennis: Значит ли это, что он не будет работать правильно для этой задачи на входном рваном массиве, который содержит списки как элементы, а не как целые числа (потому что сначала он сгладит внутренние списки)? Это немного разочаровывает, вы ожидаете, что он будет работать независимо от типа, который имел рваный массив. (Обновление: я проверил, кажется, что оба Fи работают для нескольких слоев сплющивания, а не только для одного.)
Я имею в виду, что левый аргумент может быть чем угодно, а не простым списком. Например: tio.run/nexus/jelly#@/9wZ@P///@jow11FIxidRSijXUUTEC0qY6CWWzs/…
Денис
1
О, я бы назвал эту операцию неснятой; левый аргумент обрабатывается как плоский список (просто он содержит списки как элементы, но эти элементы интерпретируются как непрозрачные). На самом деле, я подозреваю, что мы согласны с тем, что такое
7

PowerShell v2 +, 86 байт

param($n)$a=$n-split'[^\d]'-ne''|sort{random};-join($n-split'\d+'-ne''|%{$_+$a[$i++]})

Работает через манипуляции со строками. Ввод передается в виде строки, представляющей массив, в любом формате, который подходит для вашего языка. ;-)

-splitВычисляет входные данные на нецифровых символах, sortа их на основе randomблока скрипта (который назначит различный случайный вес для каждого входного параметра для сортировки) сохраняет его в $a. Затем мы splitснова вводим, на этот раз цифрами, и для каждого выводим текущее значение (обычно в скобках и запятых), объединенное в строку с соответствующим номером from $a. Это -joinобъединено обратно в строку, и вывод неявный.

Примеры

PS C:\Tools\Scripts\golfing> .\shuffle-a-ragged-array.ps1 "@(@(1,2,3),4)"
@(@(3,2,1),4)

PS C:\Tools\Scripts\golfing> .\shuffle-a-ragged-array.ps1 "@(@(1,2,3),4)"
@(@(1,2,4),3)

PS C:\Tools\Scripts\golfing> .\shuffle-a-ragged-array.ps1 "[[4],[1,2,3],[4]]"
[[4],[2,4,3],[1]]

PS C:\Tools\Scripts\golfing> .\shuffle-a-ragged-array.ps1 "[[10],[1,2,3],[5]]"
[[10],[5,2,1],[3]]

PS C:\Tools\Scripts\golfing> .\shuffle-a-ragged-array.ps1 "[[10],[1,2,3],[5]]"
[[5],[10,2,1],[3]]
AdmBorkBork
источник
5

Python 2 , 89 байт

from random import*
x=input();r=sum(x,[]);shuffle(r)
print[[r.pop()for _ in t]for t in x]

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

Деннис
источник
Я не очень хорошо знаю Python, но разве ты не умеешь shuffle(r=sum(x,[]))?
Конор О'Брайен
1
Нет, перетасовать перетасовки на месте и возвращает None .
Деннис
3

JavaScript (ES6), 78 75 байт

x=>x.map(y=>y.map(z=>+s.splice(Math.random()*s.length,1)),s=eval(`[${x}]`))

Это первый раз, когда я помню, как использовал .splice()в соревновании по коду в гольф ...

Вы можете сыграть в гольф два байта, предварительно перетасовав массив:

x=>x.map(y=>y.map(z=>s.pop()),s=eval(`[${x}]`).sort(_=>Math.random()-.5))

Тем не менее, это, кажется, ставит последнее целое число на первое место большую часть времени, поэтому я собираюсь предположить, что целые числа распределены неравномерно.

ETHproductions
источник
«Вы можете предположить, что встроенный случайный язык вашего языка является случайным».
Конор О'Брайен
@ ConorO'Brien «Каждое целое число должно иметь одинаковую вероятность появления в каждом возможном месте».
ETHproductions
sortне работает должным образом, если дан противоречивый ключ сравнения. Даже если случайный язык является случайным, его сортировка в этой ситуации будет работать неправильно, и именно это создает предвзятость, которую вы видите. Таким образом, я думаю, что второе решение неверно.
2

Рубин, 47 байтов

->a{b=a.flatten.shuffle;a.map{|x|x.map{b.pop}}}
Ли В.
источник
2

Брахилог , 17 байт

c@~P,?:{l~l}a.cP,

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

объяснение

Мы в основном создаем список подсписков с переменными элементами, которые имеют ту же «форму», что и вход, и затем заявляем, что, если мы объединяем все в один список, это должно привести к перемешиванию конкатенации входных данных в один список. ,

c@~P,                 Concatenate the Input into a single list. Shuffle it and call that P.
     ?:{   }a.        The Output is the result of applying this to each element of the input:
        l~l               The Output is a list of same length as the Input.    
             .cP,     P is the concatenation of the sublists of the Output.
Fatalize
источник
1

Perl, 37 байт

36 байт кода + -pфлаг.

@n=/\d+/g;s/\d+/splice@n,rand@n,1/ge

Чтобы запустить это:

perl -pE '@n=/\d+/g;s/\d+/splice@n,rand@n,1/ge' <<< "[[4],[1,2,3],[4]"

Пояснения:

@ n = / d + / g # сохранить все целые числа в @n
s / \ d + / # заменить каждое целое число на ...
склейка @ n, rand @ n, 1 / ge # элемент в случайной позиции @n (который удаляется из @n)
папа
источник
1

05AB1E , 17 байт

˜.r¹vDyg£DˆgF¦}}¯

˜                 Unflatten input
 .r               tmp = shuffle(flattened_input)
   ¹v             For each sub-array
     Dyg£         Take the first length(current_array) elements from tmp
         Dˆ       Append the result to a global array
           gF¦}   Remove the first elements from tmp
               }  End for
                ¯ Display the global array

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

Я жду решения 05AB1E или 2sable, использующего встроенную систему раскладывания / формовки, которую я пока не знаю :).

Osable
источник
1

APL, 35 байт

Я едва побеждаю Perl, должно быть что-то, чего мне не хватает.

{Z[?⍨⍴Z]⊂⍨(⍳⍴Z←∊⍵)∊⊃¨{⍵+⊃⌽⍺}\⍳¨⍴¨⍵}

Например:

      {Z[?⍨⍴Z]⊂⍨(⍳⍴Z←∊⍵)∊⊃¨{⍵+⊃⌽⍺}\⍳¨⍴¨⍵}(1 2 3)(,4)(9 10)
┌──────┬─┬───┐
│10 3 2│1│9 4│
└──────┴─┴───┘

Объяснение:

  • Найдите соответствующие индексы запусков подмассивов в плоском массиве:
    • ⍳¨⍴¨⍵: Для каждого подмассива получите список индексов
    • {⍵+⊃⌽⍺}\: Начиная с первого подмассива, добавьте последнее значение в массиве к каждому значению в следующем массиве.
    • ⊃¨: получить первые элементы массивов, которые являются начальными местами
    • (⍳⍴Z←∊⍵)∊: сохранить плоский массив в Z. Создайте битовый вектор, где они отмечают места, где должны начинаться под-массивы.
  • Перемешать уплощенный массив:
    • ?⍨⍴Z: Генерировать случайную перестановку Z.
    • Z[... ]: переставлять Z.
  • ⊂⍨: Разделить перестановку в под-массивах в соответствии с бит-вектором.
Мэринус
источник
1
Вы могли бы сделать замену на месте. Назначение позволило вам сгладить переменную:A⊣(∊A)←(∊A)[?⍨≢∊A←⎕]
Adám
@ Adám: вау, я не знал, что вы могли бы сделать это. Есть ли список функций, которые могут это сделать?
Маринус
1
Да . И это работает с измененным назначением тоже.
Адам
1

Pyth, 15 байт

tPc.SsQ.u+NlYQ0

Программа, которая принимает ввод списка и печатает результат.

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

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

tPc.SsQ.u+NlYQ0  Program. Input: Q
       .u    Q0  (1) Reduce Q with starting value 0, returning all results:
         +        Add
          N       the current value
           lY     to the length of the next element of Q
     sQ          Flatten Q
   .S            (2) Randomly shuffle
  c              Chop (1) at every location in (2)
tP               Discard the first and last elements
                 Implicitly print
TheBikingViking
источник
1

PHP , 105 байт

$m=array_merge(...$i=$_GET[i]);shuffle($m);foreach($i as$v)$o[]=array_splice($m,0,count($v));print_r($o);

уменьшено до 105 байт благодаря user59178.

Оригинальный ответ:

PHP , 132 байта

$i=$_GET['i'];$m=call_user_func_array('array_merge',$i);shuffle($m);foreach($i as$v){$o[]=array_splice($m,0,count($v));}print_r($o);
Артур Швейда
источник
$m=array_merge(...$i=$_GET[i]);на 25 байт короче $i=$_GET['i'];$m=call_user_func_array('array_merge',$i);и делает то же самое. Кроме того, вы можете оставить {}после, foreachчтобы сохранить еще 2 байта.
user59178
1

Bash, 6358 байт

правок:

  • Оптимизированное выражение sed немного, -5 байт

Заметка:

Bash на самом деле не поддерживает многомерные массивы (они могут быть смоделированы только до некоторой степени), поэтому вместо этого эта программа примет «сериализованное» текстовое представление прочного массива, как показано в описании задачи, например:, [[1,2,3],[4],[9,10]]и предоставит вывод в том же формате.

Golfed

printf `sed 's/\w\+/%d/g'<<<$1` `grep -Po '\d+'<<<$1|shuf`

Тест

>./shuffle []
[]

>./shuffle [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15]
[11,12,9,5,3,6,1,15,14,2,13,7,10,8,4]

>./shuffle [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15]
[9,15,11,10,7,6,1,14,2,3,12,5,4,13,8]

>./shuffle [[1,2,3],[4],[9,10]]
[[10,2,4],[9],[3,1]]

>./shuffle [[1,2,3],[4],[9,10]]
[[3,4,1],[10],[2,9]]

Приятным бонусом является то, что вы можете кормить его бурными массивами произвольной глубины:

./shuffle [[1,[2,[3,[99,101]]],[4],[9,10]]
[[9,[4,[1,[101,2]]],[10],[3,99]]

и все равно будет работать правильно.

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

дирижабль
источник
0

Октава, 60 байт

@(a)mat2cell([a{:}](randperm(sum(s=cellfun(@numel,a)))),1,s)
rahnema1
источник
0

MATLAB , 84 байта

function b=g(c);a=[c{:}];a=a(randperm(numel(a)));b=mat2cell(a,1,cellfun('length',c))
MattWH
источник
0

Java, 368 байт

interface Z{int w(int i);default Z m(int n,int s){return i->w(i)+i>=n?s:0;}static int[][]f(int[][]r){int L=0,o=0,x,d,e=0;Z u=i->0,v=i->i;for(int[]a:r){d=a.length;L+=d;u=u.m(L,1);v=v.m(L,-d);}int[]c=new int[L];for(;e<L;)c[e++]=(int)(L*Math.random());for(int[]a:r){for(x=0;x<a.length;){d=c[x+o];e=v.w(d);d=u.w(d);L=a[x];a[x++]=r[d][e];r[d][e]=L;}o+=a.length;}return r;}}

метод static int[][] f( int[][] r ){...}решает проблему. решил свернуть свой собственный функциональный интерфейс, чтобы избежать импорта и добавить метод по умолчанию для простоты использования

interface Z{ //define my own functional interface instead of importing

  int w(int i);

  //return a new lambda
  //where w(int i) adds the value s
  //to the result when i is greater than n
  default Z m(int n,int s){
      return i->w(i)+i>=n?s:0;
  }

  static int[][]f(int[][]r){
      int L=0,o=0,x,d,e=0;
      Z u=i->0, //lambda to convert a flattened index to the input's first dimension index
        v=i->i; //lambda to convert a flattened index to the input's second dimension index
      for(int[]a:r){
          d=a.length;
          L+=d; //running total of the lengths
          u=u.m(L,1); //increment the 1st conversion by 1 at every array length
          v=v.m(L,-d); //decrement the 2nd conversion by the array length after that length
      }
      int[]c=new int[L]; //will contain flattened index swapping positions
      for(;e<L;) //randomize the swap positions
          c[e++]=(int)(L*Math.random());
      for(int[]a:r){ //swap the elements from the input
          for(x=0;x<a.length;){
              d=c[x+o]; //flattened swap index
              e=v.w(d); //convert swap index to 2nd dimension index
              d=u.w(d); //convert swap index to 1st dimension index
              L=a[x];
              a[x++]=r[d][e];
              r[d][e]=L;
          }
          o+=a.length; //increment offset for flattened index array
      }
      return r;
  }

}
Джек Боеприпасы
источник
0

Mathematica, 67 байт

ReplacePart[#,Thread[RandomSample@Position[#,_Integer]->Union@@#]]&

Объяснение: Это перетасовывает список позиций всех целых чисел в двумерном рваном массиве. Union@@коротка дляFlatten@

Примечание. Скоростные скобки {}используются вместо скобок [].

Келли Лоудер
источник