Reproduzir aleatoriamente um mapeamento

9

Definimos um mapa como um conjunto de pares de valores-chave. Para esse desafio, você precisa pegar cada um dos valores e atribuí-los a uma chave escolhida aleatoriamente.

  • Você deve aleatoriamente embaralhar os valores e gerar o mapa resultante. Isso significa que cada vez que executamos seu programa, temos a chance de obter uma saída diferente
  • Cada permutação possível dos valores deve ter uma chance diferente de zero de aparecer.
  • Todas as chaves e valores originais devem aparecer na matriz resultante. Valores repetidos devem aparecer o mesmo número de vezes na matriz resultante.

Por exemplo, se o seu mapa era:

[0:10, 1:10, 5:5]

todos os itens a seguir devem ter a chance de aparecer:

[0:10, 1:10, 5:5]  (original map)
[0:10, 1:5,  5:10]
[0:10, 1:10, 5:5]  (technically the same map, but I swapped the two tens)
[0:10, 1:5,  5:10]
[0:5,  1:10, 5:10]
[0:5,  1:10, 5:10]

Entradas / saídas aceitáveis:

  • Mapa nativo dos seus idiomas
  • Você pode inserir uma matriz de pares de valores-chave. Você não pode inserir 2 matrizes, uma com chaves e outra com valores.
  • Você pode usar uma representação em cadeia de qualquer uma das opções acima
  • Se você inserir uma matriz ou um mapa, poderá modificar o objeto original em vez de retornar
  • O tipo de entrada deve corresponder ao tipo de saída
  • Se você inserir uma matriz, a ordem das chaves deverá ser mantida.
  • Você pode assumir que as chaves são únicas, mas não pode assumir que os valores são únicos.

Este é um , então responda o mais breve possível

Nathan Merrill
fonte
11
Muito intimamente relacionado. (As diferenças são que, na mina as teclas são simplesmente os índices da matriz, que requerem uma probabilidade uniforme ao longo de todas as permutações e que não permitir embutidos.)
Martin Enders
Os pares KV precisam estar na ordem [k, v]ou seriam [v, k]aceitáveis?
Dennis
Eles precisam estar dentro[k, v]
Nathan Merrill
Podemos inserir um mapa nativo e gerar uma matriz de pares de valores-chave?
Steven H.
Não, os tipos precisam corresponder.
Nathan Merrill

Respostas:

6

05AB1E , 5 bytes

Entrada é uma lista de pares de valores-chave.

ø       # zip into a list of keys and one of values
 `      # flatten
  .r    # randomize the values
    ø   # zip back again into a list of key-value pairs.

Experimente online!

Emigna
fonte
5

Braquilog , 13 12 bytes

zt@~T,?zh:Tz

Experimente online!

Espera uma lista de 2 elementos como entrada.

Explicação

z              Zip the input to get a list of keys and a list of values
 t@~T,         Take the list of values, and shuffle it ; call that T
      ?zh      Zip the input to get the list of keys
         :Tz   Zip the list of keys with the list of shuffled values
Fatalizar
fonte
4

CJam, 9 bytes

{z)mra+z}

Entrada é uma lista de pares de valores-chave.

Teste aqui.

Explicação

z  e# Zip, to separate keys from values.
)  e# Pull off values.
mr e# Shuffle them.
a+ e# Append them to the array again.
z  e# Zip, to restore key-value pairs.

Solução alternativa, mesma contagem de bytes:

{[z~mr]z}
Martin Ender
fonte
Certeza que este é o algoritmo mais curto na maioria dos idiomas que têm Zip: p
Fatalize
4

Gelatina , 5 bytes

Ṫ€Ẋṭ"

Experimente online!

Explicação

Ṫ€Ẋṭ"  Input: list of [k, v] pairs
Ṫ€     Pop and return the last element of each k-v pair (modifies each list)
  Ẋ    Shuffle the list of v's
   ṭ"  Append each v back to a k and return
milhas
fonte
3
PareceTEXt"
ETHproductions
3

Python 2, 77 bytes

Usa esta opção: Se você inserir uma matriz ou um mapa, poderá modificar o objeto original em vez de retornar . Entrada é um dicionário literal como {0: 10, 1: 10, 5: 5}.

from random import*
D=input()
k=D.keys()
shuffle(k)
D=dict(zip(k,D.values()))

Experimente online

Inspiração tirada desta resposta SO .

mbomb007
fonte
2

Python 3, 107 bytes

Usa a estrutura de dicionário nativa do Python.

Obrigado a @ mbomb007 por salvar um byte.

from random import*
def f(d,o={}):
 i=list(d.values());shuffle(i)
 for k in d.keys():o[k]=i.pop()
 return o

Ideone it!

Beta Decay
fonte
Coloque a importação antes da função e use from random import*.
mbomb007
Retire o .keys(). A iteração de um dicionário itera sobre as teclas. Use em return dict(zip(d, i))vez do loop for.
Jonas Schäfer
2

Perl, 35 bytes

Inclui +2 para -0p

Dê a cada chave / valor separado por espaço em uma linha STDIN

shuffle.pl
1 5
3 8
9 2
^D

shuffle.pl:

#!/usr/bin/perl -p0
@F=/ .*/g;s//splice@F,rand@F,1/eg
Ton Hospel
fonte
1

Mathematica, 32 bytes

{#,RandomSample@#2}&@@(#)&

Entrada é uma lista de pares de valores-chave. é o operador de transposição do Mathematica e RandomSamplepode ser usado para embaralhar uma lista.

Martin Ender
fonte
1

php, 84 bytes

<?= serialise(array_combine(array_keys($a=unserialize($argv[1])),shuffle($a)?$a:0));

Recebe a entrada como uma matriz serializada, produz o mesmo.

user59178
fonte
1

Clojure, 40 34 bytes

#(zipmap(keys %)(shuffle(vals %)))

Pega as chaves e os valores de m (um mapa), embaralha os valores e os fecha em um mapa.

marca
fonte
Use a função macro: # (zipmap (teclas%) (shuffle (vals%)))
MattPutnam
0

PowerShell v2 +, 52 bytes

param($a)$a|%{$_[1]}|sort {random}|%{$a[$i++][0],$_}

Recebe entrada como uma matriz de tuplas, que é significativamente mais curta do que usar um hash (o que exigiria .GetEnumerator()e outras coisas para funcionar).

Fazemos um loop na matriz de entrada |%{...}, cada iteração puxando o segundo elemento $_[1]. Aqueles são canalizados Sort-Objectcom a {Get-Random}tecla de classificação. Isso atribuirá um peso aleatório de 0para [Int32]::MaxValuepara cada elemento para classificação. Esses são canalizados para outro loop |%{...}, com cada iteração produzindo uma tupla do primeiro elemento correspondente da tupla e o número classificado.

Exemplos

Os exemplos aqui têm um adicional -join','na saída da tupla, para que seja mostrado melhor no console, pois a saída padrão para matrizes multidimensionais é difícil de ler.

PS C:\Tools\Scripts\golfing> .\shuffle-a-mapping.ps1 ((0,10),(1,10),(5,5))
0,10
1,5
5,10

PS C:\Tools\Scripts\golfing> .\shuffle-a-mapping.ps1 ((0,10),(1,10),(5,5))
0,10
1,10
5,5

PS C:\Tools\Scripts\golfing> .\shuffle-a-mapping.ps1 ((1,1),(2,2),(3,3),(4,4),(5,5))
1,2
2,4
3,3
4,5
5,1

Isso funciona para valores não inteiros, bem como sem modificações.

PS C:\Tools\Scripts\golfing> .\shuffle-a-mapping.ps1 (('one','one'),('two','two'),('three','three'),('four','four'))
one,four
two,three
three,two
four,one
AdmBorkBork
fonte
0

JavaScript (ES6), 89 bytes

a=>a.map((_,i)=>[i,Math.random()]).sort((a,b)=>a[1]-b[1]).map(([i],j)=>[a[j][0],a[i][1]])
Neil
fonte
0

Perl 6 , 28 bytes

{%(.keys.pick(*)Z=>.values)}

Input é um Hash
(tecnicamente, qualquer valor com um .keysmétodo e um .valuesmétodo funcionaria, mas a saída é um Hash )

Explicação:

# bare block lambda with implicit parameter 「$_」
{

  # turn the list of key => value Pairs into a Hash
  %(
      # get the keys from 「$_」 ( implicit method call on 「$_」 )
      .keys

      # get all of the keys in random order
      .pick(*)

    # zip using 「&infix:« => »」 the Pair constructor
    Z[=>]

      # the values from 「$_」 ( implicit method call on 「$_」 )
      .values
  )
}

Uma variante que funcionaria para os outros tipos de objeto integrados no Hash é:

{.WHAT.(.keys.pick(*)Z=>.values)}

.WHAT em um objeto retorna o tipo

Brad Gilbert b2gills
fonte
0

R, 47 (28) bytes

Um pouco atrasado para a festa, mas apesar de eu postar uma solução em R usando builtins.

A coisa mais próxima que R tem de uma matriz com mapeamento de chave / valor é a list. A função a seguir pega um listobjeto como entrada e gera uma lista com seus valores embaralhados.

function(x)return(setNames(sample(x),names(x)))

Explicado

O builtin setNames()pode atribuir nomes a objetos inserindo um R-vectordos nomes. Portanto, em primeiro baralhar o listpor sample()que embaralha os pares, e depois atribuir os nomes na ordem original usando names().

Exemplo:

z  <- list(fish = 1, dog = 2, cat = 3, monkey = 4, harambe = 69)

f=function(x)return(setNames(sample(x),names(x)))
f(z)

$fish
[1] 3

$dog
[1] 1

$cat
[1] 2

$monkey
[1] 69

$harambe
[1] 4

Se xfor assumido como definido, não há necessidade de agrupar funções e o programa reduz para 28 bytes.

setNames(sample(x),names(x))
Billywob
fonte
0

Java 7, 156 bytes

import java.util.*;void c(Map m){List t=new ArrayList(m.values());Collections.shuffle(t);Iterator i=t.iterator();for(Object k:m.keySet())m.put(k,i.next());}

Ungolfed:

void c(Map m){
  List t = new ArrayList(m.values());
  Collections.shuffle(t);
  Iterator i = t.iterator();
  for(Object k : m.keySet()){
    m.put(k, i.next());
  }
}

Código do teste:

Experimente aqui.

import java.util.*;
class M{
  static void c(Map m){List t=new ArrayList(m.values());Collections.shuffle(t);Iterator i=t.iterator();for(Object k:m.keySet())m.put(k,i.next());}

  public static void main(String[]a){
    for(int i=0;i<10;i++){
      Map m=new HashMap();
      m.put(0, 10);
      m.put(1, 10);
      m.put(5, 5);
      c(m);
      System.out.println(m);
    }
  }
}

Saída possível:

{0=5, 1=10, 5=10}
{0=10, 1=10, 5=5}
{0=10, 1=5, 5=10}
{0=10, 1=10, 5=5}
{0=10, 1=10, 5=5}
{0=10, 1=10, 5=5}
{0=10, 1=10, 5=5}
{0=10, 1=10, 5=5}
{0=10, 1=5, 5=10}
{0=5, 1=10, 5=10}
Kevin Cruijssen
fonte