Vui vẻ


26

Lý lịch

Hoa Kỳ có một tình yêu độc đáo là vui vẻ, điều khiển sự cố tình của một khu vực bầu cử để dự đoán kết quả bỏ phiếu nhất định. Mới gần đây đã có một vụ án vui vẻ được đưa ra trước Tòa án Tối cao. Giao lưu, đặc biệt là khi liên quan đến chủng tộc, bị cai trị bất hợp pháp và dẫn đến yêu cầu vẽ lại các đường huyện.

Đưa ra một bản đồ hình chữ nhật của một đô thị (mảng 2d), bạn sẽ vẽ các đường huyện để giúp nhóm của bạn có được đại diện nhất. Đó là, bạn sẽ vui vẻ. Mỗi đô thị có hai bên, 01. Bản đồ sẽ bao gồm các hình vuông có 0hoặc 1trên chúng. Đây là một bản đồ ví dụ:

Thử thách

Bạn sẽ nhóm bản đồ thành các quận để 1nhóm sẽ nhận được ít nhất số quận được chỉ định bởi Đầu vào.

Đầu vào

Đầu vào sẽ bao gồm một bản đồ, số quận cần vẽ và số quận tối thiểu mà 1bên đó cần để giành chiến thắng (điểm tối thiểu).

Đầu ra

Đầu ra sẽ là một bản đồ của các huyện. Mỗi quận sẽ bao gồm duy nhất một chữ cái viết hoa của bảng chữ cái. Vâng, điều này có nghĩa là sẽ không có hơn 26 quận.

Nếu không có đầu ra khả thi, nơi bên được nhập sẽ giành đủ quận, hoặc:

  1. In ấn Chúng tôi đã thử ...
  2. Lỗi nghiêm trọng vì đảng bị tổn thương không thể khắc phục do kết quả bầu cử
  3. Hoặc cả hai

Quy tắc (cũng rất quan trọng)

  1. Tất cả các huyện phải liền kề nhau
  2. Các quận có thể không có các quận khác trong đó
  3. Mỗi huyện phải có ít nhất bốn nút trong đó. Đầu vào sẽ phù hợp với các quy tắc, có nghĩa là sẽ có ít nhất number_of_districts * 4các nút trong bản đồ
  4. Điểm của mỗi bên là số quận mà nó chiếm đa số trong
  5. Nếu một quận có cùng số 0s và 1s, thì không bên nào được hưởng lợi từ đó
  6. Quy tắc không gian lận bình thường
  7. Đây là , vì vậy mã ngắn nhất tính bằng byte thắng.

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

1. Input       1. Output       2. Input       2. Output     3. Input      3. Output
districts: 5   Image and map   districts: 3   Image below   districts: 3  fatal error
min wins: 3                    min wins: 3                  min wins: 3
map:                           map:                         map:
00000110000    AAAAAAAAAAA     101101                       101101
10000010000    AAAAAAAAAAA     100000                       100000
10010000011    AAAAAAAAAAA     011011                       011011
11001110000    BBBBBBBAAAA     111111                       100111
00111111000    BBBBBBBAAAA     
01111111000    CCCCCDDDAAA     
01111111001    CCCCCDDDAAA     
01000111100    EEEEEDDDDDD     
00000001000    EEEEEDDDDDD     

Tất nhiên, chương trình của bạn nên hoạt động cho bất kỳ trường hợp kiểm tra hợp lệ nào , không chỉ những trường hợp thử nghiệm này.


@Arnauld, vâng họ chỉ mang tính minh họa. Đầu ra thực phải giống như trong trường hợp thử nghiệm đầu tiên với các chữ cái trong bảng chữ cái. Tôi đã thay đổi thẻ để phản ánh điều này.
Daniel

Một phân vùng đơn giản của trường hợp thử nghiệm đầu tiên sẽ là một cái gì đó như thế này . Đúng không?
Arnauld

@Arnauld, vâng, điều đó hợp lệ.
Daniel

Vì vậy, với ví dụ thứ 3, nếu chúng ta chia nó thành các hàng ngang, mỗi chiều cao 1 quận, thì số 1 sẽ thắng 3 thành 1 có?
Michael Dorgan

3
Điều này nhắc nhở tôi rất nhiều về những gì phải làm cho đồ họa dựa trên char trên thiết bị cầm tay Nintendo từ DMG cho đến DS. Bạn đã được cung cấp các hình dạng cụ thể để cắt đồ họa và phải giảm thiểu số lượng hình được sử dụng vì bạn chỉ có thể sử dụng một số phần cứng (hình dạng) được xác định bằng phần cứng. Đó không phải là một vấn đề dễ dàng.
Michael Dorgan

Câu trả lời:


6

R , 938 896 858 952 byte

function(N,M,m){U="We tried...
"
L=length
A=matrix
W=which
K=sum
S=sample
G=unique
H=function(s,p=s-1){Y=S(c(s-j,s+j,p*(p%%j>0),(s+1)*(s%%j>0)))
Y[Y>0&Y<=k]}
C=function(v,z=W(r==v))K(z%%j<2,z-j<0,(z+j)>k)
m=A(strsplit(m,"")[[1]],1)
i=W(m<0)[1]-1
m=((t(A(m,i+1))[,1:i]>0)-.5)*2
if((K(m)<M&(N-M)<1)|K(m>0)<(3*M))cat(U) else{j=max(1,nrow(m))
k=i*j;w=g=T
while(w<9&g){Z=R=N;Q=M;b=0
r=A(0,j,i)
while(b<9&g){s=W(r<1)
s=s[S(L(s))][1:min(L(s),R)]
r[s]=1:L(s);a=0
while(K(r<1)>0&a<(k^2)){a=a+1
s=S(W(r>0&r<=R),1);p=r[s]
Y=H(s)
Y=Y[r[Y]<1]
if(L(Y)){Y=Y[order(m[Y])]
if(K(m[r==p]>1))r[Y[1]]=p else r[Y[L(Y)]]=p}}
if(a<(k^2)){for(v in 1:R){if(K(m[r==v])>0){r[r==v]=max(k,max(r))+1
Q=Q-1;Z=Z-1}}
if(Q<1){g=F
for(v in 1:R)r[r==v]=max(k,max(r))+1
for(v in G(c(r)))g=g|(K(r==v)<4)|(L(G(r[H(W(r==v))]))+C(v))<3}}
b=b+1;r[r<=R]=0;R=Z}
w=w+1}
if(g)cat(U) else{u=G(c(r))
for(v in 1:L(u))r[r==u[v]]=v
cat(paste(apply(A(LETTERS[r],j,i),1,paste,collapse=""),collapse="
"))}}}

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

Một giải pháp lớn > 900 > 800 (không!)> 900 byte. Mã này hoạt động như sau. Gọi N là số quận bầu cử và M là số quận tối thiểu trong đó 1 mong muốn có đa số.

Đầu tiên, mã gán ngẫu nhiên N quận cho các nhóm khác nhau. Tiếp theo, nó mở rộng ngẫu nhiên chúng, tức là thêm một quận vào một nhóm được chọn ngẫu nhiên, đảm bảo rằng quận nằm cạnh một quận đã thuộc nhóm đó. Trong quá trình mở rộng, nó được ưu tiên cho một quận có 1 đa số, nếu nhóm huyện chưa chiếm 1 đa số; nếu nhóm đã là 1 đa số nhất định, thì nó được ưu tiên cho một quận 0. Nó tiếp tục cho đến khi tất cả các huyện đã được chỉ định.

Mỗi nhóm nơi có đa số cho 1 bên được lưu trữ và các quận của nó bị khóa. Nếu có ít nhất M nhóm với đa số là 1, thì mọi thứ đều tốt và chúng tôi có thể in kết quả, chúng tôi có thể kiểm tra xem có ít nhất 4 quận trong mỗi nhóm không. Nếu cắt được 4 quận, thì chúng ta có thể vui vẻ in kết quả. Mặt khác, mã cố gắng gán lại các quận không bị khóa với càng nhiều nhóm càng tốt, tức là N - # nhóm được lưu trữ.

Các mã thử một vài lần (9 lần). Nếu thất bại, nó đặt lại mọi thứ và bắt đầu lại. Nó làm như vậy cho 9 lần khác trước khi từ bỏ và in "chúng tôi đã thử ...".

Nếu mã không thành công lúc đầu, hãy thử lại một vài lần. Tôi đã điều chỉnh số lần lặp lại để nó có thể chạy trong TIO trong một phút. Tuy nhiên nếu có một giải pháp, mã này có thể (cuối cùng) tìm thấy nó. Phần ngẫu nhiên của thuật toán đưa ra xác suất khác không, nếu có một giải pháp, nó có thể tìm thấy nó. Số lượng thử nghiệm hạn chế là yếu tố giới hạn duy nhất để thành công.

EDIT: đã thêm kiểm soát rằng không có nhóm quận nào có thể được bao quanh hoàn toàn bởi chỉ một nhóm khác, trừ khi nhóm quận có các quận ở rìa của hình vuông đã cho. Tôi nghĩ rằng tôi đã bỏ lỡ nó lúc đầu.


Bạn có thể loại bỏ bất kỳ dòng mới?
NoOneIsHere

Tôi đã làm. Tôi cũng đã gán tên hàm dài hơn cho các chữ cái đơn và thay thế một số ==0bằng <1khi biến là số nguyên và dương.
NofP

1
Có rất nhiều thứ ở đây có thể bị đánh gôn một cách tầm thường nhưng đây là lần thử đầu tiên để trả lời, vì vậy +1 và tôi sẽ đề xuất chỉnh sửa cho tôi một vài giờ khi tôi không nghe điện thoại!
Giuseppe

1
858 byte - "thường xuyên" Tất chơi gôn, dọn dẹp việc sử dụng niềng răng với if...elsebáo cáo, trao đổi ccho as.vector, thay đổi "\n"với dòng mới theo nghĩa đen, và sử dụng thực tế là >tự động số ép buộc các nhân vật âm thầm và sẽ so sánh codepoints của họ. Có lẽ một số golf khác tôi đã làm mà tôi không thể nhớ nhưng đây là một sự khởi đầu. Tôi nghĩ rằng có một vài điều nữa chúng ta có thể tinh chỉnh nhưng tôi không chắc chắn 100% tôi hiểu mã ...
Giuseppe

Đẹp quá Tôi lấy cảm hứng. Bằng cách so sánh với mã của bạn, tôi cũng tìm thấy một lỗi trong tôi đôi khi sẽ dẫn đến các nhóm quận rất nhỏ (dưới 4 quận). Bây giờ nó đã được sửa.
NofP
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.