Trao đổi chỉ số và giá trị


29

Nhiệm vụ

Viết chương trình hoặc hàm có đầu vào là danh sách / mảng X các số nguyên và đầu ra của nó là danh sách các bộ số nguyên Y , sao cho mỗi phần tử e trong mỗi bộ Y [ i ], X [ e ] = i và sao cho tổng số phần tử trong các tập hợp trong Y bằng với số phần tử trong X .

(Về cơ bản, đây là thao tác tương tự như đảo ngược hashtable / dictionary, ngoại trừ áp dụng cho mảng thay thế.)

Ví dụ

Các ví dụ này giả định lập chỉ mục dựa trên 1, nhưng bạn có thể sử dụng lập chỉ mục dựa trên 0 thay vì nếu bạn thích.

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

Làm rõ

  • Bạn có thể đại diện cho một tập hợp như một danh sách, nếu bạn muốn. Nếu bạn làm như vậy, thứ tự các yếu tố của nó không quan trọng, nhưng bạn có thể không lặp lại các yếu tố.
  • Bạn có thể sử dụng bất kỳ định dạng I / O rõ ràng hợp lý nào; ví dụ: bạn có thể tách các thành phần của một tập hợp bằng dấu cách và chính các tập hợp với dòng mới.
  • Y nên có độ dài chính xác và ít nhất đủ dài để có tất cả các phần tử của X là các chỉ mục mảng. Tuy nhiên, nó có thể dài hơn phần tử tối đa của X (các phần tử phụ sẽ là các tập hợp trống).
  • Tất cả các phần tử của X sẽ là các chỉ số mảng hợp lệ, tức là các số nguyên không âm nếu bạn sử dụng lập chỉ mục dựa trên 0 hoặc các số nguyên dương nếu bạn sử dụng lập chỉ mục dựa trên 1.

Điều kiện chiến thắng

Là một thách thức , ngắn hơn là tốt hơn.


Liên quan . Trong bài đăng trên Sandbox (hiện đã bị xóa, nhưng bạn có thể xem nó nếu bạn có tiếng tăm), chúng tôi đã quyết định nó có thể không phải là một bản sao, nhưng hãy bình chọn để đóng nếu bạn không đồng ý.

Liệu "thứ tự các yếu tố của nó không quan trọng" có nghĩa là đầu ra của [5,5,6,6][6,6,5,5]có thể giống hệt nhau không?
Leaky Nun

1
@LeakyNun Thứ tự các thành phần của các bộ trong danh sách đầu ra không quan trọng. Vì vậy, [5,5,6,6][6,6,5,5]không thể có đầu ra giống hệt nhau, nhưng đầu ra cho [5,5,6,6]cũng có thể có, ví dụ , [{},{},{},{},{2,1},{4,3}].
ngenisis

Có một giá trị tối đa giả định của một chỉ mục trong X không? Ngoài ra các tập hợp trống có thể có 0 trong chúng thay vì thực sự trống? Ví dụ sẽ [{0},{0},{0},{0},{1,2},{3,4}]là đầu ra hợp lệ cho [5,5,6,6]?
Skidsdev

@Mayube: Không có câu trả lời đầu tiên (mặc dù nếu bạn đang sử dụng ngôn ngữ có phạm vi giới hạn trên số nguyên, bạn có thể viết chương trình như thể số nguyên có thể lớn không giới hạn và không lo lắng về việc nó bị phá vỡ nếu ai đó đưa ra cho bạn số nguyên phạm vi làm đầu vào). Đối với câu hỏi thứ hai, đó là một cú pháp rõ ràng (nếu lạ) khi bạn đang sử dụng lập chỉ mục dựa trên 1, vì vậy, trong trường hợp đó (rõ ràng là không, nếu bạn đang sử dụng lập chỉ mục dựa trên 0 vì khi đó 0 có nghĩa là khác.)

Câu trả lời:


9

MATL , 8 byte

tn:IXQ&D

Đầu vào là một vectơ cột, với ;dấu phân cách (ví dụ [2;2;2]). Đầu ra là biểu diễn chuỗi của một mảng ô của vectơ hàng (ví dụ {[]; [1 2 3]}). Một vectơ hàng của một phần tử giống như một số (vì vậy {1; 2; 3}sẽ là đầu ra thay vì {[1]; [2]; [3]}).

Hãy thử trực tuyến! Hoặc xác minh tất cả các trường hợp thử nghiệm .

Giải trình

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

Hầu hết các công việc được thực hiện bởi hàm bậc cao hơn của Matlab accumarray, nhóm các thành phần trong đầu vào thứ hai theo các giá trị khớp trong đầu tiên và áp dụng một chức năng được chỉ định cho mỗi nhóm. Hàm trong trường hợp này là @(x){sort(x).'}, xuất ra các phần tử được sắp xếp trong mỗi nhóm và khiến kết quả cho tất cả các nhóm được đóng gói trong một mảng ô.


7

Python, 69 byte

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

Sử dụng lập chỉ mục dựa trên 0.


7

Thạch , 7 5 byte

=þṀT€

Hãy thử trực tuyến!

Làm thế nào nó hoạt động

=þṀT€  Main link. Argument: A (array)

  Ṁ    Yield m, the maximum of A.
=þ     Equals table; for each t in [1, ..., m], compare all elemnts of A with t,
       yielding a 2D Boolean array.
   T€  Truth each; for each Boolean array, yield all indices of 1.

5

Thạch , 8 byte

Jẋ"Ṭ€;"/

Hãy thử trực tuyến!

Làm thế nào nó hoạt động

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

Toán học, 36 byte

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

Giải trình

nhập mô tả hình ảnh ở đây

Đối với mỗi ntrong {1, 2, ..., Max@#}, nơi Max@#là số nguyên lớn nhất trong danh sách đầu vào, hãy tính Positions nơi nxuất hiện trong danh sách đầu vào #. Vì Position[{6,6,5,5},5](ví dụ) trả về {{3},{4}}, sau đó chúng tôi Apply Joinđến tất cả các yếu tố ở cấp độ {1}của kết quả.


3

Haskell , 45 byte

slấy một danh sách các số nguyên và trả về một danh sách các danh sách. 1 - được lập chỉ mục để giữ cho các đầu vào trường hợp thử nghiệm không bị thay đổi (mặc dù đầu ra có thêm một số danh sách trống).

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

Hãy thử trực tuyến!

Đây là những hiểu biết danh sách lồng nhau khá đơn giản. Điều chỉnh nhỏ duy nhất là tận dụng tùy chọn để tạo danh sách dài hơn bằng cách sử dụng sumthay vì maximum.



3

R, 68 49 47 byte

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

Đáng ngạc nhiên, đơn giản hơn rất nhiều so với các giải pháp dài hơn. Lấy một vectơ xtừ STDIN, tạo một vectơ từ 1đến max(x), hoàn toàn tạo ra một danh sách độ dài max(x)và kiểm tra các chỉ số trongx tương ứng với các danh sách mới. Ngẫu nhiên in đầu ra.

Phiên bản cũ hơn:

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

Cách tiếp cận hơi khác với câu trả lời R khác. Đưa một vectơ thành STDIN, tạo một danh sách có độ dài bằng giá trị tối đa trong đầu vào. Vòng lặp trên đầu vào và thêm chỉ mục vào đúng nơi.

Sử dụng lập chỉ mục 1 dựa trên.


2

Python 2 , 91 86 85 byte

Tôi đang lập trình trên điện thoại của mình nhưng tôi thực sự thích thử thách này. Tôi chắc chắn có thể chơi golf này hơn nữa.

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

Hãy thử trực tuyến!


Out-golfed một lần nữa bởi một sự hiểu biết danh sách lồng nhau. : D
hoàn toàn là

2

Thạch , 9 byte

Ṭ+\ịĠȧ@"Ṭ

Các bộ trống được lập chỉ mục 1, được biểu thị dưới dạng 0, các bộ của một mục được biểu diễn dưới dạng Ncác bộ gồm nhiều mục được biểu diễn dưới dạng[M,N,...]

Hãy thử trực tuyến!

Làm sao?

Ṭ+\ịĠȧ@"Ṭ - 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 byte

Đã lưu 2 byte nhờ @SteveBennett


Có đầu vào 0 chỉ mục. Trả về một danh sách các bộ được phân tách bằng dấu phẩy.

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

Các trường hợp thử nghiệm


Phiên bản thay thế, 53 byte

Nếu một đầu ra đơn giản hóa như '||||3,2|1,0'được chấp nhận, chúng ta có thể làm:

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

Ồ Tôi rất bối rối như thế nào `{${o.join`},{`}}`là hợp pháp ES2015.
Steve Bennett

@SteveBennett, đó là một mẫu chữ . Trong các phiên bản cũ hơn của JS "{" + o.join("},{") + "}", nếu điều đó làm cho nó rõ ràng hơn.
Xù xì

Không, tôi biết về những điều đó - đó là backquote sau khi từ tham gia làm tôi bối rối. Đó có phải là đóng chuỗi (trong trường hợp này là wtf) hay đó là cách bạn thoát khỏi một cú đúp gần?
Steve Bennett

Hmm, ok, vì vậy trong bối cảnh join`này là tương đương với join('. Không có ý tưởng bạn có thể làm điều đó.
Steve Bennett

À, giờ tôi hiểu rồi. Đó là một mẫu được gắn thẻ theo nghĩa đen. Mà bạn có thể lạm dụng để lưu một vài ký tự bất cứ khi nào gọi hàm có một đối số chuỗi (và bỏ qua các đối số khác) : array.join` `. Rất khó hiểu ở đây bởi vì bạn đang nhúng nó trong một chuỗi mẫu, và thậm chí khó hiểu hơn, chuỗi tham gia },{, trông giống như một phần của chuỗi mẫu ... và dù sao nó cũng kỳ lạ và xấu xí. :)
Steve Bennett


1

Toán học 62 byte

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

Tôi sẽ chạy nó cho bạn

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

Dùng thử trực tuyến (chỉ cần dán mã bằng ctrl-v và nhấn shift + enter)
đừng quên dán danh sách đầu vào ở cuối như trong ví dụ trên


Chào mừng đến với PPCG! Bạn có thể lưu một byte bằng cách sử dụng ký hiệu infix cho AppendTo. Ngoài ra, {j,1,Length[#1]}có thể chỉ {j,Length@#}, hoặc thậm chí ngắn hơn , {j,Tr[1^#]}. Tr[1^#]là một mẹo khá phổ biến để tiết kiệm một byte khi sử dụng Length.
ngenisis

1

Perl 6 ,  36 32  29 byte

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

Thử nó

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

Thử nó

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

Thử nó


Mở rộng:

{  # 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 「$_」

}

Trả về các chỉ mục dựa trên 0, để có được 1 toán tử sử dụng chéo ( X) kết hợp với +op . (33 byte)

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

Để làm cho nó trở lại Đặt s chỉ cần thêmset vào đó (tổng cộng 37 byte)

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

1

R, 80 72 byte

1 chỉ mục, lấy Xtừ stdin. Trả về một danh sách các vectơ của các chỉ mục, với NULLtập hợp trống.

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

Hãy thử trực tuyến!

phiên bản cũ:

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

Hãy thử trực tuyến!


Tôi nghĩ rằng nó cũng Y=list();hoạt động tốt
rturnbull

Quản lý để loại bỏ một fewbyte trong câu trả lời của tôi :) codegolf.stackexchange.com/a/120024/59530
JAD




0

GNU Make , 214 213 208 204 byte

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

I / O: mảng đầu vào thông qua các đối số, đầu ra đến thiết bị xuất chuẩn, một trên mỗi dòng, được phân tách bằng dấu cách.

$ make -f swap.mk 2 2 2

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

Giải trình

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

Thứ tự của các chỉ số trong các bộ được đảo ngược vì Pchính nó gọi đệ quy trước khi cập nhật A$2(cuộc gọi được thực hiện trong đánh giá của phía bên tay phải).


makecách nào để làm số học chính nó? Gọi vào các chương trình bên ngoài để làm điều đó cảm thấy hơi giống như gian lận, bởi vì bạn có thể có thể đưa nhiều thuật toán hơn vào các chương trình đó và kết thúc bằng một chương trình ngắn hơn.

@ ais523 Không có. Phiên bản trước được sử dụng bcgrep. Tôi cũng có thể sử dụng test$?. dccó một cú pháp chặt chẽ hơn, nhưng thẳng thắn tất cả những điều này cảm thấy như nhau.
eush77

0

Lisp thông thường, 91 byte

(lambda(x &aux(l(make-list(eval`(max,@x))))(i 0))(dolist(y x l)(push(incf i)(nth(1- y)l))))

Lập chỉ mục dựa trên 1, trả về các bộ dưới dạng danh sách.

Hãy thử trực tuyến!


0

k , 13 byte

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

Đây là 0 chỉ mục.

Hãy thử trực tuyến!

{           } /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
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.