유쾌한 gerrymandering


26

배경

미국은 특정 투표 결과를 예측하기 위해 선거구를 의도적으로 조작하는 gerrymandering에 대한 독특한 사랑을 가지고 있습니다. 최근 에 대법원에 건배 사건 이 발생했습니다. Gerrymandering은 특히 인종과 관련하여 불법으로 판결되어 지역 노선을 다시 작성해야합니다.

지방 자치 단체 (2 차원 배열)의 직사각형지도가 주어지면 파티 선을 그려 파티를 가장 많이 대표 할 수 있습니다. 즉, 당신은 germanmander 것입니다. 모든 지방 자치 단체는 두 당사자를 가지고 01. 지도는 하나 0또는 1위에 사각형으로 구성 됩니다. 예제 맵은 다음과 같습니다.

도전

1파티가 최소한 입력에 의해 지정된 지구 수를 얻 도록지도를 지구로 그룹화합니다 .

입력

입력은지도, 뽑을 지구 수 및 1당이 이겨야하는 최소 지구 수 (최소 점수)로 구성됩니다.

산출

결과는 지구의지도가 될 것입니다. 각 지구는 알파벳 대문자로 고유하게 구성됩니다. 예, 이는 26 개가 넘는 지구가 존재하지 않음을 의미합니다.

입력 한 당이 충분한 지역을 이길 수있는 출력이없는 경우 :

  1. 인쇄 "우리는 시도했다 ..."
  2. 당이 선거 결과로 돌이킬 수없는 부상을 입었으므로 치명적인 오류
  3. 아니면 둘다

규칙 (매우 중요)

  1. 모든 지구는 인접해야합니다
  2. 지구에는 다른 지구가 없을 수 있습니다
  3. 각 지구에는 적어도 네 개의 노드가 있어야합니다. 입력은 규칙과 일치합니다. 즉, 최소한number_of_districts * 4 ,지도에 노드가
  4. 각 당사자의 점수는 다수가 속한 지구의 수입니다.
  5. 지구가 같은 수의 0S를 가지고 있다면 어느 쪽도 지구 1로부터 혜택을받지 못한다
  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, 그렇습니다. 그들은 단지 예시 일뿐입니다. 실제 출력은 첫 글자 테스트에서 알파벳 글자와 같아야합니다. 이것을 반영하기 위해 태그를 변경했습니다.
Daniel

첫 번째 테스트 사례의 간단한 파티션은 다음 과 같습니다 . 그 맞습니까?
Arnauld

@Arnauld, 그렇습니다.
다니엘

세 번째 예에서, 우리가 그것을 1 행 높이의 가로 행으로 나누면, 1은 3 대 1로 이길까요?
Michael Dorgan

3
이것은 DMG에서 DS에 이르기까지 Nintendo 핸드 헬드의 문자 기반 그래픽에 대해 수행해야 할 일을 많이 상기시킵니다. 하드웨어를 정의 할 수있는 스프라이트 (모양) 만 가질 수 있으므로 그래픽을자를 수있는 특정 모양이 주어졌으며 사용 된 모양 수를 최소화해야했습니다. 쉬운 문제는 아니었다.
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 과반수 인 경우 0 지구에 우선합니다. 모든 지구가 배정 될 때까지 계속됩니다.

1 인당 과반수가있는 모든 그룹이 저장되고 해당 구역이 잠 깁니다. 다수가 1 인 M 개 이상의 그룹이있는 경우 모든 것이 좋으며 각 그룹에 4 개 이상의 지구가 있는지 확인할 수 있는 결과를 인쇄 할 수 있습니다. 4 개 구역의 컷오프가 충족되면 결과를 행복하게 인쇄 할 수 있습니다. 그렇지 않으면 코드는 가능한 한 많은 그룹 (예 : N-# stored-groups)에 고정되지 않은 구역을 재 할당하려고합니다.

코드는 몇 번 (9 회) 시도합니다. 실패하면 모든 것을 재설정하고 다시 시작합니다. "우리는 시도했다 ..."를 포기하고 인쇄하기 전에 다른 9 회 동안 그렇게한다.

코드가 처음에 성공하지 못하면 몇 번 다시 시도하십시오. TIO에서 1 분 안에 실행될 수 있도록 반복 횟수를 조정했습니다. 그러나 해결책이 있다면이 코드는 결국 그것을 찾을 수 있습니다. 알고리즘의 임의성 부분은 솔루션이 있으면 찾을 수있는 0이 아닌 확률을 제공합니다. 제한된 수의 시도 만 성공의 제한 요인입니다.

편집 : 지구 그룹이 지정된 광장의 가장자리에 지구가없는 한 지구 그룹이 다른 그룹으로 완전히 둘러싸 일 수 없다는 컨트롤이 추가되었습니다. 나는 처음에 그것을 놓친 것 같아요.


줄 바꿈을 제거 할 수 있습니까?
NoOneIsHere 여기

나는했다. 또한 더 긴 함수 이름을 단일 문자에 할당 하고 변수가 엄격하게 정수이고 양수인 경우 로 몇 개 ==0를 대체했습니다 <1.
NofP

1
여기에는 사소하게 골프를 칠 수있는 많은 것들이 있지만 이것은 대답에 대한 첫 번째 시도이므로 +1이며, 전화를하지 않으면 몇 시간 동안 수정 사항을 제안 할 것입니다!
주세페

1
858 바이트 - "일반"골프를 친다, 중괄호를 사용하는 청소 if...else교환, 문을 c위한 as.vector변화 "\n"문자 줄 바꿈으로하고, 사실 사용하여 >자동으로 강제 변환을 자동으로 문자 숫자와 자신의 코드 포인트를 비교하는 것이다. 내가 기억할 수없는 다른 골프가 있을지 모르지만 이것은 시작입니다. 확실히 내가 ... 코드를 이해 나는 우리가 아래로 조정할 수있는 몇 가지 더 있다고 생각하지만 난 100 % 아니에요
주세페

좋은 것! 영감을 받았습니다. 귀하의 코드와 비교하여 나는 때때로 매우 작은 지구 그룹 (4 지구 미만)으로 이어질 버그를 발견했습니다. 이제 수정되었습니다.
NofP
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.