Reproduzir aleatoriamente uma matriz irregular

23

Uma matriz irregular é uma matriz em que cada elemento é uma matriz de número desconhecido de números inteiros positivos.

Por exemplo, as seguintes são matrizes irregulares:

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

As seguintes não são matrizes irregulares:

[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

Você precisa inserir uma matriz irregular e retornar uma matriz irregular com os números inteiros embaralhados

  • A matriz de saída deve ter a mesma forma que a matriz de entrada. Definimos a forma da matriz como o comprimento de cada sub-matriz.
  • Cada número inteiro deve ter uma chance igualmente provável de aparecer em cada local possível.
  • Você pode assumir que o acaso do seu idioma é aleatório.

Por exemplo, se eu passei em: [[4],[1,2,3],[4]], em seguida, [[1],[4,4,2],[3]]seria uma saída válida, mas [[4,1,3],[3],[4]]ou [[4],[4],[1,2,3]]não.

Nathan Merrill
fonte
Relacionado.
Martin Ender
1
A entrada sempre será uma matriz 2D?
Dennis

Respostas:

17

Jelly, 3 bytes na página de códigos de Jelly

FẊṁ

Explicação:

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

Como o programa está incompleto ( não possui um segundo argumento), o padrão é usar a entrada do programa; assim, faz com que a saída tenha o mesmo padrão de sublista que a entrada.

Experimente online!


fonte
4
Uau, unflatten é um comando limpo e inesperado.
Magic Octopus Urn
3
Unflatten pode não ser o melhor termo, já que o argumento da esquerda não precisa ser simples. O mnemônico é mofo .
Dennis
@ Dennis: Isso significa que não funcionaria corretamente para esse desafio em uma matriz irregular de entrada que continha listas como elementos, em vez de números inteiros (porque achatará primeiro as listas internas)? Isso é um pouco decepcionante, você esperaria que funcionasse, independentemente do tipo que a matriz irregular tivesse. (Update: Eu verifiquei, parece que tanto Fe trabalho para múltiplas camadas de achatamento, não apenas um.)
Quero dizer que o argumento esquerdo de pode ser qualquer coisa, não apenas uma lista simples. Por exemplo: tio.run/nexus/jelly#@/9wZ@P///@jow11FIxidRSijXUUTEC0qY6CWWzs/…
Dennis
1
Oh, eu diria que é uma operação pouco plana; o argumento da esquerda está sendo tratado como uma lista simples (apenas contém listas como elementos, mas esses elementos estão sendo interpretados como opacos). Na verdade, desconfio que concordamos com o que é
7

PowerShell v2 +, 86 bytes

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

Funciona através da manipulação de strings. A entrada é passada como uma string que representa a matriz, em qualquer formato que funcione para o seu idioma. ;-)

-splits fora a entrada com não dígitos, sorts com base no randombloco de script (que atribuirá um peso aleatório diferente para cada entrada à classificação), armazena-o em $a. Em seguida, splita entrada é novamente, desta vez em dígitos, e para cada uma é gerado o valor atual (geralmente colchetes e vírgulas) concatenado com o número correspondente de $a. Isso é -joineditado novamente em uma string e a saída é implícita.

Exemplos

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
fonte
5

Python 2 , 89 bytes

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

Experimente online!

Dennis
fonte
Não conheço python tão bem, mas você não sabia shuffle(r=sum(x,[]))?
Conor O'Brien
1
Não, o shuffle embaralha no lugar e retorna Nenhum .
Dennis
3

JavaScript (ES6), 78 75 bytes

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

Esta é a primeira vez que me lembro de usar .splice()um desafio de código-golfe ...

Você pode obter dois bytes usando a ordem aleatória da matriz:

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

No entanto, isso parece colocar o último número inteiro primeiro na maioria das vezes, então eu vou assumir que os números inteiros não são distribuídos uniformemente.

ETHproductions
fonte
"Você pode assumir que o acaso do seu idioma é aleatório."
Conor O'Brien
@ ConorO'Brien "Cada número inteiro deve ter uma chance igualmente provável de aparecer em cada local possível."
ETHproductions
sortnão funciona corretamente quando recebe uma chave de comparação inconsistente. Mesmo que o aleatório do idioma seja aleatório, seu tipo não funcionará nessa situação, e é isso que está criando o viés que você está vendo. Como tal, acho que a segunda solução está incorreta.
2

Ruby, 47 bytes

->a{b=a.flatten.shuffle;a.map{|x|x.map{b.pop}}}
Lee W
fonte
2

Braquilog , 17 bytes

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

Experimente online!

Explicação

Basicamente, criamos uma lista de sublistas com elementos variáveis ​​que têm a mesma "forma" que a Entrada e, em seguida, declaramos que, se concatenarmos tudo em uma única lista, isso resultará em uma confusão da concatenação da entrada em uma única lista. .

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.
Fatalizar
fonte
1

Perl, 37 bytes

36 bytes de código + -psinalizador.

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

Para executá-lo:

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

Explicações:

@ n = / d + / g # armazena todos os números inteiros em @n
s / \ d + / # substitui cada número inteiro por ...
splice @ n, rand @ n, 1 / ge # um elemento em uma posição aleatória de @n (que é excluída de @n)
dada
fonte
1

05AB1E , 17 bytes

˜.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

Experimente online!

Estou aguardando a solução 05AB1E ou 2sable usando algum recurso desinteressante / de moldagem que ainda não conheço :).

Osable
fonte
1

APL, 35 bytes

Eu mal estou derrotando Perl, tem que estar faltando algo.

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

Por exemplo:

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

Explicação:

  • Encontre os índices correspondentes das partidas das sub-matrizes em uma matriz nivelada:
    • ⍳¨⍴¨⍵: Para cada sub-matriz, obtenha uma lista dos índices
    • {⍵+⊃⌽⍺}\: Começando com o primeiro subconjunto, adicione o último valor no array a cada valor no próximo array.
    • ⊃¨: obtenha os primeiros itens das matrizes, que são os pontos de partida
    • (⍳⍴Z←∊⍵)∊: armazene a matriz nivelada em Z. Gere um vetor de bits onde os que marcam os locais onde as sub-matrizes devem começar.
  • Embaralhe a matriz nivelada:
    • ?⍨⍴Z: gera uma permutação aleatória de Z.
    • Z[... ]: permutar Z.
  • ⊂⍨: Divida a permutação em sub-matrizes de acordo com o vetor de bits.
marinus
fonte
1
Você pode fazer uma substituição no local. A tarefa permitiu nivelar a variável:A⊣(∊A)←(∊A)[?⍨≢∊A←⎕]
Adám 12/12
@ Adám: uau, eu não sabia que você poderia fazer isso. Existe uma lista de quais funções podem fazer isso?
marinus
1
Sim . E também funciona com atribuição modificada.
Adám
1

Pitão, 15 bytes

tPc.SsQ.u+NlYQ0

Um programa que recebe a entrada de uma lista e imprime o resultado.

Suíte de teste

Como funciona

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
fonte
1

PHP , 105 bytes

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

reduzido para 105 bytes graças a user59178.

Resposta original:

PHP , 132 bytes

$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);
Arthur Shveida
fonte
$m=array_merge(...$i=$_GET[i]);é 25 bytes mais curto $i=$_GET['i'];$m=call_user_func_array('array_merge',$i);e faz a mesma coisa. Além disso, você pode soltar o {}depois do foreachpara salvar mais 2 bytes.
user59178
1

Bater, 63., 58 bytes

EDITAS:

  • Expressão sed otimizada um pouco, -5 bytes

Nota:

O Bash não suporta realmente matrizes multidimensionais (elas só podem ser simuladas, até certo ponto); portanto, este programa aceitará uma representação de texto "serializada" de uma matriz robusta, conforme descrito na descrição da tarefa, por exemplo: [[1,2,3],[4],[9,10]]e fornecerá saída no mesmo formato.

Golfe

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

Teste

>./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]]

Um bom bônus é que você pode alimentar matrizes robustas de profundidade arbitrária:

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

e ainda funcionará corretamente.

Experimente online!

zepelim
fonte
0

Oitava, 60 bytes

@(a)mat2cell([a{:}](randperm(sum(s=cellfun(@numel,a)))),1,s)
rahnema1
fonte
0

MATLAB , 84 bytes

function b=g(c);a=[c{:}];a=a(randperm(numel(a)));b=mat2cell(a,1,cellfun('length',c))
MattWH
fonte
0

Java, 368 bytes

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

o método static int[][] f( int[][] r ){...}resolve o desafio. decidi rolar minha própria interface funcional para evitar uma importação e adicionar um método padrão para facilitar o uso

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

}
Jack Ammo
fonte
0

Mathematica, 67 bytes

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

Explicação: Isso embaralha a lista de posições de todos os números inteiros na matriz irregular 2D. Union@@é curto paraFlatten@

Nota: {}São usados colchetes ondulados em vez de colchetes [].

Kelly Lowder
fonte