Chuyển đổi mẫu thành chỉ mục


12

Chúng tôi đang đặt quả bóng vào một số cố định một thùng. Những thùng rác bắt đầu trống rỗng.

Empty bin (a=4): 0 0 0 0 

Và từng người một chúng tôi thêm bóng vào thùng.

0 0 0 1  or
0 0 1 0  or
0 1 0 0  or
1 0 0 0

Chúng tôi cần một cách nhanh chóng để lặp lại tất cả các trạng thái có thể có của các thùng, không trùng lặp và không bỏ sót bất kỳ và chúng tôi không muốn liệt kê tất cả các thùng có thể. Vì vậy, thay vào đó chúng ta gán cho mỗi cấu hình bin một chỉ mục.

Chúng tôi chỉ định chỉ mục bằng cách sắp xếp các cấu hình có thể theo một cách cụ thể:

  1. Sắp xếp tăng dần theo tổng: vì vậy trước tiên 0 0 0 0, sau đó các cấu hình có thể có thêm 1 bóng, sau đó 2, v.v.
  2. Sau đó sắp xếp trong mỗi tổng theo thứ tự tăng dần, từ thùng đầu tiên đến thùng cuối cùng:

    0 0 0 2
    0 0 1 1
    0 0 2 0 
    0 1 0 1
    0 1 1 0 
    0 2 0 0 
    etc
    
  3. Chỉ mục sau đó được chỉ định tăng dần qua danh sách này:

    0 0 0 0  -> 1
    0 0 0 1  -> 2
    0 0 1 0  -> 3
    0 1 0 0  -> 4
    1 0 0 0  -> 5
    0 0 0 2  -> 6
    0 0 1 1  -> 7
    0 0 2 0  -> 8
    0 1 0 1  -> 9
    0 1 1 0  -> 10
    0 2 0 0  -> 11 
    

Quy tắc

Tạo một hàm hoặc chương trình lấy danh sách có kích thước bất kỳ với các số nguyên không âm và in hoặc xuất chỉ mục của nó. Bạn có thể giả định một để có ít nhất 2. thắng đang Shortest. Bạn có thể sử dụng đầu ra 0 chỉ mục hoặc 1 chỉ mục, nhưng chỉ định bạn sử dụng. NB: tất cả các ví dụ ở đây là 1 chỉ mục.

Mã ví dụ

Không chơi gôn, trong R:

nodetoindex <- function(node){
  a <- length(node)
  t <- sum(node)
  if(t == 0) return(1)

  index <- choose(t-1 + a, a)

  while(sum(node) != 0){
    x <- node[1]
    sumrest <- sum(node)
    if(x == 0){
      node <- node[-1]
      next
    }
    a <- length(node[-1])
    index <- index + choose(sumrest + a, a) - choose(sumrest - x + a, a)
    node <- node[-1]
  }
  return(index + 1)
} 

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

10 10 10 10 -> 130571
3 1 4 1 5 9 -> 424407
2 9 -> 69
0 0 0 -> 1
0 0 1 -> 2
0 0 0 0 0 0 -> 1
1 0 0 0 0 1 -> 23

Làm thế nào để sắp xếp thông qua giá trị số của phép nối hoạt động khi các số có số chữ số khác nhau?
TheBikingViking

@TheBikingViking hmm, chưa nghĩ đến điều đó, tôi đã thay đổi từ ngữ để phản ánh mã ví dụ và các trường hợp thử nghiệm. Trong mỗi tổng, các cấu hình được sắp xếp đầu tiên trong thùng thứ nhất, sau đó trong thùng thứ hai, v.v.
JAD

Câu trả lời:


3

Thạch , 8 byte

S0rṗLSÞi

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

Giải pháp vũ lực. Trường hợp thử nghiệm đầu tiên là quá nhiều đối với TIO, nhưng tôi đã xác minh nó cục bộ trên máy tính xách tay của mình. Trường hợp thử nghiệm thứ hai đòi hỏi quá nhiều RAM, ngay cả đối với máy tính để bàn của tôi.

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

S0rṗLSÞi  Main link. Argument: A (array)

S         Compute the sum s of A.
 0r       Create the range [0, ..., s].
    L     Yield the length l of A.
   ṗ      Cartesian power; yield the array of all l-tuples over [0, ..., s], in
          lexicographical order.
     SÞ   Sort the l-tuples by their sums. The sorting mechanism is stable, so
          l-tuples with the same sum are still ordered lexicographically.
       i  Find the index of A in the generated array of tuples.

Đẹp. Nhận xét của bạn về RAM khiến tôi nhớ về nguồn gốc của thử thách này. Đối với luận án của tôi, tôi cần lặp lại tất cả các mảng có thể cho một số a = 8 và cao nhất có thể. Ý tưởng chuyển đổi các mảng thành các chỉ số và chỉ lặp lại các mảng xuất phát chính xác từ giới hạn của RAM: P
JAD

Đó cũng là lý do tại sao mã ví dụ rất dài dòng: P
JAD

1

Clojure, 152 byte

#(loop[v[(vec(repeat(count %)0))]i 1](if-let[r((zipmap v(range))%)](+ r i)(recur(sort(set(for[v v i(range(count v))](update v i inc))))(+ i(count v)))))

Không dễ như tôi nghĩ. Phiên bản ít chơi gôn hơn:

(def f (fn[t](loop[v[(vec(repeat(count t)0))]i 1]
               (if-let[r((zipmap v(range))t)](+ r i)
                 (recur (sort-by (fn[v][(apply + v)v]) (set(for[v v i(range(count v))](update v i inc))))
                        (+ i(count v)))))))

Vòng lặp trên các trạng thái hiện tại v, tạo ra một bản đồ băm từ các yếu tố vđến thứ hạng của chúng, nếu tìm thấy trạng thái tìm kiếm thì thứ hạng của nó được trả về (+ số lượng trạng thái được nhìn thấy trước đó). Nếu không tìm thấy thì đệ quy với một tập hợp các trạng thái có thể mới.

Ồ thực sự chúng ta không cần chức năng sắp xếp tùy chỉnh đó vì tất cả các trạng thái trong mỗi vòng lặp có tổng bằng nhau. Đây không phải là chậm như tôi mong đợi [3 1 4 1 5 9]chỉ mất 2,6 giây.


1

Toán học, 50 byte

Một câu trả lời của Dennis's Jelly .

0~Range~Tr@#~Tuples~Length@#~SortBy~Tr~Position~#&

Hàm không tên lấy danh sách các số nguyên làm đầu vào và trả về danh sách độ sâu 2 với một số nguyên duy nhất làm đầu ra; ví dụ, đầu vào cho trường hợp thử nghiệm cuối cùng là {1,0,0,0,0,1}và đầu ra là {{23}}.

Một phiên bản hơi vô dụng là:

Position[SortBy[Tuples[Range[0,Tr[#]],Length[#]],Tr],#]&

Thông thường chúng ta có thể lưu các byte riêng lẻ trong Mathicala bằng cách sử dụng ký hiệu tiền tố ( function@nthay vì function[n]) và ký hiệu infix ( a~function~bthay vì function[a,b]). Tuy nhiên, điều này chỉ hoạt động khi mã kết quả xảy ra phù hợp với thứ tự ưu tiên nội tại của Mathicala để áp dụng các hàm. Tôi đã rất ngạc nhiên ở đây, với sáu bộ dấu ngoặc vuông, nó thực sự hoạt động để loại bỏ tất cả chúng và lưu sáu byte với mã được gửi (không có khung).

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.