Перемішайте карту


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
Дуже тісно пов'язані. (Відмінності полягають у тому, що в моєму ключі - це просто індекси масиву, що мені потрібна однакова ймовірність для всіх перестановок і що я забороняю вбудовані пристрої.)
Мартін Ендер

Чи повинні пара KV бути в порядку [k, v]чи [v, k]прийнятним?
Денніс

Їм потрібно бути[k, v]
Натан Меррілл

Чи можемо ми ввести нативну карту і вивести масив пар ключових значень?
Стівен Х.

Ні, типи повинні відповідати.
Натан Меррілл

Відповіді:




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


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

Спробуйте в Інтернеті

Натхнення, взяте з цієї відповіді .


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

Ідей це!


Поставте імпорт перед функцією та використовуйте from random import*.
mbomb007

Видаліть .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

Математика, 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 (клавіші%) (перетасовка (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 має до масиву з відображенням ключа / значення, - це 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}
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.