ร่าเริงร่าเริง


26

พื้นหลัง

สหรัฐอเมริกามีความรักที่ไม่เหมือนใครของ gerrymandering - การจัดการโดยเจตนาของเขตการเลือกตั้งเพื่อทำนายผลการลงคะแนนบางอย่าง เมื่อไม่นานมานี้มีคดีฟ้องร้องดำเนินคดีต่อศาลฎีกา Gerrymandering โดยเฉพาะอย่างยิ่งเมื่อเกี่ยวข้องกับการแข่งขันถูกปกครองอย่างผิดกฎหมายและส่งผลให้มีความต้องการที่จะวาดเส้นเขต

ให้แผนที่เป็นรูปสี่เหลี่ยมผืนผ้าของเทศบาล (อาร์เรย์ 2d) คุณจะวาดเส้นเขตเพื่อช่วยให้พรรคของคุณได้รับการแสดงมากที่สุด นั่นคือคุณจะร่าเริง ทุกเขตเทศบาลมีสองฝ่าย0และ1. แผนที่จะประกอบด้วยสี่เหลี่ยมที่มีอย่างใดอย่างหนึ่ง0หรือ1อยู่บนนั้น นี่คือแผนที่ตัวอย่าง:

ท้าทาย

คุณจะจัดกลุ่มแผนที่เป็นอำเภอเพื่อให้1ปาร์ตี้ได้รับจำนวนอำเภออย่างน้อยตามที่กำหนดโดยอินพุต

อินพุต

ข้อมูลที่ป้อนจะประกอบด้วยแผนที่จำนวนอำเภอที่จะจั่วและจำนวนเขตขั้นต่ำที่1พรรคต้องชนะ (คะแนนขั้นต่ำ)

เอาท์พุต

ผลลัพธ์จะเป็นแผนที่ของอำเภอ แต่ละเขตจะประกอบด้วยตัวอักษรตัวพิมพ์ใหญ่ที่ไม่ซ้ำกัน ใช่นี่หมายความว่าจะไม่เกิน 26 เขต

หากไม่มีผลลัพธ์ที่เป็นไปได้เมื่อฝ่ายที่ป้อนเข้าชนะหัวเมืองมากพอ:

  1. พิมพ์“ เราพยายาม ... ”
  2. ข้อผิดพลาดร้ายแรงเนื่องจากพรรคได้รับบาดเจ็บอย่างไม่สามารถแก้ไขได้โดยผลการเลือกตั้ง
  3. หรือทั้งคู่

กฎ (สำคัญมากเช่นกัน)

  1. ทุกอำเภอจะต้องต่อเนื่องกัน
  2. เขตอาจไม่มีหัวเมืองอื่นในนั้น
  3. แต่ละอำเภอจะต้องมีอย่างน้อยสี่โหนดในนั้น อินพุตจะสอดคล้องกับกฎซึ่งหมายความว่าจะมีnumber_of_districts * 4โหนดอย่างน้อยในแผนที่
  4. คะแนนของแต่ละฝ่ายคือจำนวนเขตที่มีส่วนใหญ่
  5. หากเขตมีจำนวน0s และ1s เท่ากันก็จะไม่ได้รับประโยชน์ใด ๆ
  6. กฎไม่โกงปกติ
  7. นี่คือดังนั้นรหัสที่สั้นที่สุดในหน่วยไบต์ชนะ

กรณีทดสอบ

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     

แน่นอนโปรแกรมของคุณควรใช้กับกรณีทดสอบที่ถูกต้องไม่ใช่เฉพาะกรณีเหล่านี้


@Arnauld ใช่พวกเขาเป็นเพียงตัวอย่างเท่านั้น เอาต์พุตจริงควรเป็นในกรณีทดสอบครั้งแรกที่มีตัวอักษรของตัวอักษร ฉันเปลี่ยนแท็กเพื่อสะท้อนถึงสิ่งนี้
แดเนียล

พาร์ติชั่นที่เรียบง่ายของกรณีการทดสอบครั้งแรกจะเป็นสิ่งที่เช่นนี้ ถูกต้องหรือไม่
Arnauld

@Arnauld ใช่ถูกต้อง
แดเนียล

ดังนั้นสำหรับตัวอย่างที่ 3 ถ้าเราแบ่งมันเป็นแถวแนวนอนละ 1 ตำบลสูงแล้ว 1s จะชนะ 3 ต่อ 1 ใช่ไหม
Michael Dorgan

3
สิ่งนี้ทำให้ฉันนึกถึงสิ่งที่ต้องทำมากมายสำหรับกราฟิกที่ใช้ถ่านบนอุปกรณ์พกพา Nintendo จาก DMG จนถึง DS คุณได้รับรูปร่างที่เฉพาะเจาะจงเพื่อตัดกราฟิกลงและต้องลดจำนวนรูปร่างที่ใช้เนื่องจากคุณสามารถใช้ Sprite (รูปร่าง) จำนวนฮาร์ดแวร์ที่กำหนดไว้เท่านั้น นั่นไม่ใช่ปัญหาง่าย
Michael Dorgan

คำตอบ:


6

R , 938 896 858 952 ไบต์

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="
"))}}}

ลองออนไลน์!

โซลูชันขนาดใหญ่> 900 > 800 (ไม่!)> 900 ไบต์ รหัสทำงานดังนี้ ให้ N เป็นจำนวนเขตการเลือกตั้งและ M คือจำนวนเขตขั้นต่ำที่ 1 ต้องการมีส่วนใหญ่

ครั้งแรกรหัสสุ่มกำหนดเขต N ให้กับกลุ่มที่แตกต่างกัน ถัดไปมันจะขยายกลุ่มแบบสุ่มเช่นเพิ่มเขตในกลุ่มที่เลือกแบบสุ่มเพื่อให้แน่ใจว่าเขตนั้นถัดจากเขตที่อยู่ในกลุ่มนั้นแล้ว ในกระบวนการขยายจะให้ความสำคัญกับอำเภอที่มี 1 เสียงข้างมากหากกลุ่มอำเภอยังไม่ได้เป็นเสียง 1 เต็ม ถ้ากลุ่มนั้นมี 1 เสียงข้างมากอยู่แล้วมันจะให้ความสำคัญกับเขต 0 มันจะดำเนินต่อไปจนกระทั่งทุกอำเภอได้รับมอบหมาย

ทุกกลุ่มที่จัดเก็บเสียงส่วนใหญ่สำหรับ 1 ฝ่ายและเขตของตนจะถูกล็อค หากมีอย่างน้อย M กลุ่มที่มี 1 ส่วนใหญ่แล้วทุกอย่างดีและเราสามารถพิมพ์ผลเราสามารถตรวจสอบว่ามีอย่างน้อย 4 อำเภอในแต่ละกลุ่ม หากพบการตัดยอดจาก 4 อำเภอจากนั้นเราสามารถพิมพ์ผลลัพธ์ได้อย่างมีความสุข มิฉะนั้นรหัสจะพยายามกำหนดเขตที่ไม่ได้ล็อคให้กลุ่มมากเท่าที่มีอยู่เช่น N - # กลุ่มที่จัดเก็บไว้

รหัสพยายามสองสามครั้ง (9 ครั้ง) หากไม่สำเร็จจะรีเซ็ตทุกอย่างและเริ่มต้นอีกครั้ง มันทำเช่นนั้นอีก 9 ครั้งก่อนที่จะยอมแพ้และพิมพ์ "เราลอง ... "

หากรหัสไม่สำเร็จในตอนแรกลองอีกครั้งสองสามครั้ง ฉันปรับจำนวนการทำซ้ำเพื่อให้สามารถทำงานใน TIO ได้ภายในหนึ่งนาที อย่างไรก็ตามหากมีวิธีแก้ไขปัญหารหัสนี้สามารถค้นหาได้ในที่สุด ส่วนการสุ่มของอัลกอริทึมให้ความน่าจะเป็นแบบไม่เป็นศูนย์ซึ่งหากมีวิธีแก้ปัญหาก็สามารถหาได้ การทดลองในจำนวนที่ จำกัด เป็นเพียงปัจจัย จำกัด ต่อความสำเร็จ

แก้ไข: เพิ่มการควบคุมว่าจะไม่มีกลุ่มเขตใดที่ล้อมรอบได้อีกเพียงใดยกเว้นกลุ่มที่มีเขตที่อยู่ตรงขอบของจัตุรัสที่กำหนด ฉันคิดว่าฉันพลาดตอนแรก


คุณสามารถลบบรรทัดใหม่ได้หรือไม่
NoOneIsHere

ฉันทำ. ฉันยังกำหนดชื่อฟังก์ชั่นอีกต่อไปให้กับตัวอักษรเดียวและแทนที่==0ด้วย<1เมื่อตัวแปรนั้นเป็นจำนวนเต็มและบวกอย่างเคร่งครัด
NofP

1
มีหลายสิ่งที่นี่ที่สามารถตีกอล์ฟได้ แต่นี่เป็นความพยายามครั้งแรกที่ดีในการตอบดังนั้น +1 และฉันจะแนะนำการแก้ไขฉันสองสามชั่วโมงเมื่อฉันไม่ได้อยู่ในโทรศัพท์ของฉัน!
Giuseppe

1
858 ไบต์ - โรงแรมพร้อมสนามกอล์ฟ "ปกติ", การทำความสะอาดการใช้งานของการจัดฟันกับif...elseงบการแลกเปลี่ยนcสำหรับas.vectorการเปลี่ยนแปลง"\n"ที่มีการขึ้นบรรทัดใหม่ที่แท้จริงและการใช้ความจริงที่ว่า>จะโดยอัตโนมัติหมายเลขบีบบังคับให้กับตัวละครอย่างเงียบ ๆ และเปรียบเทียบ codepoints ของพวกเขา อาจมีสนามกอล์ฟอื่น ๆ ที่ฉันทำซึ่งฉันจำไม่ได้ แต่นี่เป็นการเริ่มต้น ฉันคิดว่ามีอีกไม่กี่อย่างที่เราสามารถปรับลดลงได้ แต่ฉันไม่แน่ใจ 100% ว่าฉันเข้าใจรหัสหรือไม่ ...
Giuseppe

ทำได้ดีนี่! ฉันเอาแรงบันดาลใจ เมื่อเปรียบเทียบกับรหัสของคุณฉันยังพบข้อบกพร่องในเหมืองซึ่งบางครั้งอาจนำไปสู่กลุ่มอำเภอขนาดเล็กมาก (น้อยกว่า 4 อำเภอ) ตอนนี้ได้รับการแก้ไขแล้ว
NofP
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.