Індекси та значення swap


29

Завдання

Напишіть програму або функцію, вхідною інформацією якої є список / масив X цілих чисел, а виведенням яких є список наборів цілих чисел Y , таких, що для кожного елемента e у кожному наборі Y [ i ], X [ e ] = i та таким чином, що загальна кількість елементів у величезних кількостях в Y дорівнює числу елементів в X .

(Це в основному та сама операція, що і повернення хештелю / словника, за винятком застосованих до масивів.)

Приклади

Ці приклади передбачають індексацію на основі 1, але замість цього ви можете використовувати індексацію на основі 0.

X             Y
[4]           [{},{},{},{1}]
[1,2,3]       [{1},{2},{3}]
[2,2,2]       [{},{1,2,3}]
[5,5,6,6]     [{},{},{},{},{1,2},{3,4}]
[6,6,5,5]     [{},{},{},{},{3,4},{1,2}]

Роз'яснення

  • За бажанням ви можете представити набір як список. Якщо ви це зробите, порядок його елементів не має значення, але ви можете не повторювати елементи.
  • Ви можете використовувати будь-який розумний однозначний формат вводу / виводу; наприклад, ви могли відокремити елементи набору з пробілами, а самі набори - новими рядками.
  • Y має бути кінцево довгим і, принаймні, досить довгим, щоб усі елементи X були індексами масиву. Однак він може бути довше максимального елемента X (зайві елементи будуть порожніми наборами).
  • Усі елементи X будуть дійсними індексами масиву, тобто невід'ємними цілими числами, якщо ви використовуєте індексацію на основі 0, або додатні цілі числа, якщо ви використовуєте індексацію на основі 1.

Стан перемоги

Як виклик, коротше краще.


Пов'язані . У публікації Sandbox (тепер видалено, але ви можете переглянути її, якщо у вас є репутація), ми вирішили, що, ймовірно, це не дублікат, але не соромтесь голосувати за закриття, якщо ви не згодні.

Чи "порядок його елементів не має значення" означає, що результати [5,5,6,6]і [6,6,5,5]можуть бути однаковими?
Leaky Nun

1
@LeakyNun Порядок елементів множин у вихідному списку значення не має. Так [5,5,6,6]і [6,6,5,5]не можуть мати однаковий вихід, але вихід для [5,5,6,6]також може бути, наприклад, [{},{},{},{},{2,1},{4,3}].
ngenisis

Чи є припустиме максимальне значення індексу в X? Чи можуть порожні набори мати 0 в них, а не насправді порожні? Наприклад, чи [{0},{0},{0},{0},{1,2},{3,4}]був би дійсний вихід [5,5,6,6]?
Скидсдев

@Mayube: Ні на першу відповідь (хоча якщо ви використовуєте мову з обмеженим діапазоном для цілих чисел, ви можете написати програму так, ніби цілі числа можуть бути безмежно великими, і не турбуйтеся про її порушення, якщо хтось видасть вам ціле число діапазону як вхід). Що стосується другого питання, це однозначний (якщо дивний) синтаксис, коли ви використовуєте індексацію на основі 1, так що так у такому випадку (очевидно, ні, якщо ви використовуєте індексацію на основі 0, тому що 0 означатиме щось інше.)

Відповіді:


9

MATL , 8 байт

tn:IXQ&D

Вхід - вектор стовпця, з ;роздільником (наприклад [2;2;2]). Вихід - це рядкове подання масиву комірок векторів рядків (наприклад {[]; [1 2 3]}). Вектор рядків одного елемента такий же, як число (так {1; 2; 3}буде виводитися замість {[1]; [2]; [3]}).

Спробуйте в Інтернеті! Або перевірити всі тестові випадки .

Пояснення

t     % Implicit input, say x. Duplicate
n     % Number of elements, say N
:     % Range: [1 2 ... N]
IXQ   % accumarray(x, [1 2 ... N], [], @(x){sort(x).'})
&D    % String representation

Більшу частину роботи виконує функція Matlab вищого порядку accumarray, яка групує елементи на другому вході відповідно до значень, що відповідають першому, і застосовує задану функцію до кожної групи. Функція в цьому випадку полягає в тому @(x){sort(x).'}, що виводить відсортовані елементи в кожній групі і призводить до того, що результати для всіх груп будуть упаковані в масив комірок.


7

Пітон, 69 байт

lambda s:[[j for j,x in enumerate(s)if x==i]for i in range(max(s)+1)]

Використовує індексацію на основі 0.



5

Желе , 8 байт

Jẋ"Ṭ€;"/

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

Як це працює

Jẋ"Ṭ€;"/  argument: z           eg. [6,6,4,4]
J         [1 .. len(z)]             [1,2,3,4]
   Ṭ€     untruth each of z         [[0,0,0,0,0,1],
                                     [0,0,0,0,0,1],
                                     [0,0,0,1],
                                     [0,0,0,1]]
 ẋ"       repeat each of ^^         [[[],[],[],[],[],[1]],
          as many times as           [[],[],[],[],[],[2]],
          each of ^                  [[],[],[],[3]],
                                     [[],[],[],[4]]]
       /  reduce by...
     ;"   vectorized concatenation  [[],[],[],[3,4],[],[1,2]]

4

Математика, 36 байт

Join@@@#~Position~n~Table~{n,Max@#}&

Пояснення

введіть тут опис зображення

Для кожного nз {1, 2, ..., Max@#}, де Max@#є найбільше ціле число у вхідному списку, обчислюється Positions, де nвідображається у вхідному списку #. Оскільки Position[{6,6,5,5},5](наприклад) повертається {{3},{4}}, ми тоді Apply Joinдо всіх елементів на рівні {1}результату.


3

Haskell , 45 байт

sприймає список цілих чисел і повертає список списків. 1-індексований, щоб зберегти вхідні дані тесту не змінені (хоча вихід отримує додаткові порожні списки).

s l=[[i|(i,y)<-zip[1..]l,y==x]|x<-[1..sum l]]

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

Це досить просте розуміння списку. Єдине незначне налаштування - це скористатися можливістю зробити довший список, використовуючи sumзамість maximum.



3

R, 68 49 47 байт

lapply(1:max(x<-scan()),function(y)which(y==x)) 

Дивно, але набагато простіше, ніж довші рішення. Бере вектор xвід STDIN, створює вектор від 1до max(x), неявно формує список довжини max(x)і перевіряє, які індекси xвідповідають тим, що в новому списку. Недбало друкує вихід.

Старіша версія:

o=vector('list',max(x<-scan()));for(i in x)o[[i]]=c(o[[i]],F<-F+1);o

Трохи інший підхід до іншої відповіді R. Займає вектор STDIN, створює список довжиною, що дорівнює максимальному значенню вхідних даних. Петля над введенням і додає індекс в потрібне місце.

Використовує індексацію на основі 1.


2

Python 2 , 91 86 85 байт

Я програмую на своєму телефоні, але мені дуже сподобалось це завдання. Я, безумовно, можу далі гольфу це далі.

def f(a):
 r=[[]for i in range(max(a)+1)]
 for i,j in enumerate(a):r[j]+=[i]
 print r

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


Знову вийшов з гольфу, зрозумівши вкладений список. : D
повністюлюдський

2

Желе , 9 байт

Ṭ+\ịĠȧ@"Ṭ

1-індексовані порожні набори, представлені як 0, набори одного елемента, представлені у вигляді Nнаборів з декількох елементів, представлених як[M,N,...]

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

Як?

Ṭ+\ịĠȧ@"Ṭ - Main link: list a        e.g. [6,6,4,4]
Ṭ         - untruth a                     [0,0,0,1,0,1]
  \       - cumulative reduce with:
 +        -   addition                    [0,0,0,1,1,2]
    Ġ     - group indices of a by value   [[3,4],[1,2]]
   ị      - index into                    [[1,2],[1,2],[1,2],[3,4],[3,4],[1,2]]
        Ṭ - untruth a                     [0,0,0,1,0,1]
       "  - zip with:
     ȧ@   -   and with reversed @rguments [0,0,0,[3,4],0,[1,2]]

2

JavaScript (ES6), 64 62 байти

Збережено 2 байти завдяки @SteveBennett


Бере 0-індексований вхід. Повертає список множин, розділених комами.

a=>a.map((n,i)=>o[n]=[i,...o[n]||[]],o=[])&&`{${o.join`},{`}}`

Тестові справи


Альтернативна версія, 53 байти

Якщо спрощений вихід, такий як '||||3,2|1,0'прийнятний, ми можемо просто зробити:

a=>a.map((n,i)=>o[n]=[i,...o[n]||[]],o=[])&&o.join`|`

Ого. Я так розгублений, як `{${o.join`},{`}}`законний ES2015.
Стів Беннетт

@SteveBennett, це шаблон буквально . У старих версіях JS це було б "{" + o.join("},{") + "}", якщо це зробить це зрозумілішим.
Кудлатий

Ні, я знаю про це - саме зворотне цитування після приєднання слова мене бентежить. Це закриття рядка (у такому випадку wtf) чи це так, як ви уникаєте близької дужки?
Стів Беннетт

Хм, нормально, тому в цьому контексті join`рівнозначно join('. Не мав уявлення, що ти можеш це зробити.
Стів Беннетт

Ах, тепер я бачу. Це позначений шаблон буквально. Що ви можете зловживати , щоб заощадити пару символів , коли виклик функції , яка приймає один аргумент (і ігнорує інші) array.join` `. Супер заплутано тут, тому що ви вкладаєте це в рядок шаблону, а ще більше заплутано - це з'єднувальна рядок },{, яка збігалася випадково як частина шаблону рядка ... і все одно просто дивна і негарна. :)
Стів Беннетт


1

Mathematica 62 байти

(Y={}~Table~Max@#;Y[[#[[j]]]]~AppendTo~j~Table~{j,Tr[1^#]};Y)&

Я забіжу його за вас

(Y={}~Table~Max@#;Y[[#[[j]]]]~AppendTo~j~Table~{j,Tr[1^#]};Y)&[{4,5,2,3,3,8,6,3}]

{{}, {3}, {4, 5, 8}, {1}, {2}, {7}, {}, {6}}

Спробуйте в Інтернеті (просто вставте код за допомогою ctrl-v і натисніть shift + enter)
, не забудьте вставити список введення в кінці, як у прикладі вище


Ласкаво просимо до PPCG! Ви можете зберегти байт, використовуючи позначення infix для AppendTo. Крім того , {j,1,Length[#1]}може бути просто {j,Length@#}, чи навіть коротше, {j,Tr[1^#]}. Tr[1^#]- досить поширений трюк, щоб зберегти байт над використанням Length.
ngenisis

1

Perl 6 ,  36 32  29 байт

->\a{map {a.grep(*==$_):k},1..a.max}

Спробуй це

{map {.grep(*==$^a):k},1.. .max}

Спробуй це

{map {.grep($^a):k},1.. .max}

Спробуй це


Розширено:

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

  map

    {  # bare block lambda with placeholder parameter 「$a」

      .grep(  # grep for the values in 「$_」
        $^a   # that are equal to the currently tested value (and declare param)
      ) :k    # return the key (index) rather than the value
    },

    1 .. .max # Range from 1 to the maximum value in 「$_」

}

Повертає нульові індекси, щоб отримати оператор кросуX+ на основі 1 ( ) у поєднанні з op . (33 байти)

{1 X+.grep($^a):k}

Для того, щоб змусити його повернути Сета сек тільки надбудовуset в там (всього 37 байт)

{set 1 X+.grep($^a):k}

1

R, 80 72 байти

1-індексований, бере Xвід stdin. Повертає список векторів індексів з NULLпорожнім набором.

X=scan();Y=vector('list',max(X));Y[X]=lapply(X,function(x)which(X==x));Y

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

стара версія:

X=scan();Y=vector('list',max(X));for(i in 1:length(X))Y[[X[i]]]=c(Y[[X[i]]],i);Y

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


Я думаю, що це Y=list();працює так само добре
rturnbull

Встигли збрити fewбайтів в мій відповідь :) codegolf.stackexchange.com/a/120024/59530
JAD




0

GNU Make , 214 213 208 204 байт

X=$(MAKECMDGOALS)
M=0
P=$(eval N=$(word $1,$X))$(if $N,$(if $(shell dc -e$Nd$Mds.\>.p),$(eval M=$N),)$(eval A$N+=$1$(call $0,$(shell expr $1 + 1))),)
$(call P,1)$(foreach K,$(shell seq $M),$(info $(A$K)))

Введення / виведення: вхідний масив через аргументи, вихід у stdout, по одному на рядок, розділений пробілами.

$ make -f swap.mk 2 2 2

3 2 1
make: *** No rule to make target `2'.  Stop.

Пояснення

X=$(MAKECMDGOALS)     # Input array
M=0                   # Max value encountered in X
P=$(eval
    N=$(word $1,$X))  # Get next word from X
  $(if $N,$(if $(shell dc -e$Nd$Mds.\>.p),
    $(eval M=$N),)    # Update M
    $(eval A$N+=$1    # Append index to a variable named after value
      $(call $0,      # Recurse (call returns empty string)
        $(shell expr $1 + 1))),)
$(call P,1)           # Initial call to P. 1 is the first index
$(foreach K,          # Print all values of A* variables
  $(shell seq $M),
  $(info $(A$K)))     # Uninitialized ones default to empty strings

Порядок індексів у наборах змінюється зворотно, тому що Pвикликує себе рекурсивно перед оновленням A$2(виклик, виконаний при оцінці правої частини).


Чи makeє якийсь спосіб зробити арифметику самостійно? Якщо ви зателефонуєте до зовнішніх програм, це схоже на обман, тому що ви, ймовірно, могли вкласти в програму набагато більше алгоритму і в кінцевому підсумку скоротити програму.

@ ais523 Це не так. Використана попередня версіяbc та grep. Я також міг би використовувати testі $?. dcмає більш ситний синтаксис, але, чесно кажучи, всі вони відчувають те саме.
eush77


0

k , 13 байт

{(=x)@!1+|/x}

Це 0-індексується.

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

{           } /function(x)
 (=x)         /make a map/dictionary of values to their indices
         |/x  /get maximum value in x
      !1+     /make a range from 0 to the value, inclusive
     @        /get map value at each of the values in the range
              /    0N is given where there is no result
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.