随机映射


9

我们将地图定义为一组键值对。对于此挑战,您需要获取每个值并将其分配给随机选择的键。

  • 您必须随机调整值,然后输出结果图。这意味着每次我们运行您的程序时,我们都有机会获得不同的输出
  • 值的每个可能排列都必须具有非零的出现机会。
  • 所有原始键和原始值必须出现在结果数组中。重复的值在结果数组中必须出现相同的次数。

例如,如果您的地图是:

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

以下所有条件都必须有出现的机会:

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

可接受的输入/输出:

  • 您语言的母语地图
  • 您可以输入键值对数组。您可能无法输入2个数组,一个数组带有键,另一个数组带有值。
  • 您可以使用上述任何形式的字符串表示形式
  • 如果输入数组或地图,则可以修改原始对象,而无需返回
  • 输入类型必须与输出类型匹配
  • 如果输入数组,则必须保持键的顺序。
  • 您可以假设键是唯一的,但是不能假设值是唯一的。

这是一个 ,因此回答越短越好


1
非常密切的关系。(不同之处在于,在我看来,键只是数组的索引,我要求所有排列均具有统一的概率,并且不允许内置。)
Martin Ender 2016年

KV对必须按顺序排列[k, v]还是[v, k]可以接受?
丹尼斯

他们需要进入[k, v]
内森·梅里尔

我们可以输入本地地图并输出键值对数组吗?
史蒂文H.

不,类型需要匹配。
内森·梅里尔

Answers:


6

05AB1E,5个字节

输入是键值对的列表。

ø       # 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.

在线尝试!


5

Brachylog13 12字节

zt@~T,?zh:Tz

在线尝试!

期望将2元素列表的列表作为输入。

说明

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

4

CJam,9个字节

{z)mra+z}

输入是键值对的列表。

在这里测试。

说明

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.

替代解决方案,相同的字节数:

{[z~mr]z}

可以肯定的是,这是大多数使用Zip的语言中最短的算法:p
Fatalize

4

果冻,5个字节

Ṫ€Ẋṭ"

在线尝试!

说明

Ṫ€Ẋṭ"  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

3
看起来像TEXt"
ETHproductions 2016年

3

Python 2,77个字节

使用此选项:如果输入数组或地图,则可以修改原始对象,而不必返回。输入是类似的字典文字{0: 10, 1: 10, 5: 5}

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

在线尝试

这个SO答案中得到的启示。


2

Python 3,107个字节

使用Python的本机字典结构。

感谢@ mbomb007保存一个字节。

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

伊迪恩!


将import放在函数之前,然后使用from random import*
mbomb007'9

删除.keys()。迭代字典会迭代键。使用return dict(zip(d, i))代替for循环。
乔纳斯·谢弗

2

Perl,35个字节

包括+2 -0p

给每个键/值在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

1

Mathematica,32个字节

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

输入是键值对的列表。是Mathematica的换位运算符,RandomSample可用于随机排列列表。


1

php,84个字节

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

将输入作为序列化数组,将其输出。


1

Clojure,40 34字节

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

从m(地图)中获取键和值,将这些值混洗并将其压缩成地图。


使用函数宏:#(zipmap(keys%)(shuffle(vals%)))
MattPutnam

0

PowerShell v2 +,52字节

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

将输入作为一个元组数组,比使用散列(这将需要.GetEnumerator()并且什么都不起作用)要短得多。

我们循环输入数组|%{...},每次迭代都拉出第二个元素$_[1]。那些被管道输送到Sort-Object{Get-Random}作为排序键。这将为每个元素分配从0到的随机权重,以[Int32]::MaxValue进行排序。这些被传送到另一个循环|%{...},每次迭代输出一个对应的元组第一个元素的元组和排序后的数字。

例子

这里的示例在-join','元组输出上有一个附加项,因此在控制台上显示得更好,因为很难读取多维数组的默认输出。

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

这同样适用于非整数值,并且无需修改。

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

0

JavaScript(ES6),89个字节

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

0

Perl 6,28个字节

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

输入是一个散列
(在技术上有任何值.keys的方法.values方法将工作,但输出的是散列

说明:

# 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
  )
}

适用于其他内置的Hash(如对象类型)的变体是:

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

.WHAT 在对象上返回类型。


0

R,47(28)字节

参加聚会有点晚,但是尽管我会使用内置函数在R中发布解决方案。

R与具有键/值映射关系的数组最接近的是a list。以下函数将一个list对象作为输入,并输出一个列表,其值经过重新排序。

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

讲解

内置setNames()函数可以通过输入名称的名称来为对象分配R-vector名称。因此,首先要对list进行sample()改组,然后对进行改组,然后使用来按原始顺序分配名称names()

例:

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

如果x假定已定义,则无需进行函数包装,并且程序减少为28个字节。

setNames(sample(x),names(x))

0

Java 7,156字节

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

取消高尔夫:

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

测试代码:

在这里尝试。

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

可能的输出:

{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}
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.