欢乐欢乐


26

背景

美国对接送服务有着独特的热爱-故意操纵选举区来预测某些投票结果。就在最近,最高法院审理了一个载人妖案。尤其是与种族有关的游击队员被裁定为非法,并导致要求重划分区线。

给定一个自治市的矩形地图(二维数组),您将绘制区域线以帮助您的政党获得最大的代表权。就是说,你会很高兴。每个市政当局都有两个政党,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,是的,它们只是说明性的。实际输出应与第一个测试用例中的字母相似。我更改了标签以反映这一点。
丹尼尔(Daniel)

第一个测试用例的简单分区就是这样。那是对的吗?
Arnauld

@Arnauld,是的,这是有效的。
丹尼尔(Daniel)

因此,对于第三个示例,如果将其分成水平行,每个行高1个分区,那么1个将赢得3比1的支持?
Michael Dorgan's

3
这使我想起了从DMG到DS在Nintendo手持设备上基于字符的图形必须做的很多事情。为您提供了特定的形状以将图形切成图形,并且必须尽量减少使用的形状数量,因为您只能使用硬件定义的精灵(形状)数量。这不是一个容易的问题。
Michael Dorgan

Answers:


6

R938 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-#stored-groups。

该代码尝试几次(9次)。如果失败,它将重置所有内容并重新开始。这样做了另外9次,然后放弃并打印“我们尝试过...”。

如果代码一开始没有成功,请再试几次。我调整了重复次数,使其可以在一分钟内在TIO中运行。但是,如果有解决方案,则此代码可以(最终)找到它。该算法的随机性部分提供了一个非零的概率,如果有解决方案,它可以找到它。有限的试验次数是成功的唯一限制因素。

编辑:添加了一个控制,即一个区组不能完全被另一个区包围,除非该区组在给定广场的边缘上有区。我想我一开始很想念它。


您可以删除任何换行符吗?
NoOneIsHere

是的 我也不再分配函数名,以单个字母,并更换了几个==0<1当变量是严格的整数和积极的。
NofP

1
这里有很多东西可以打高尔夫球,但这是一个很好的初次尝试答案,因此+1,一旦我不在手机上,我会建议我几个小时进行修改!
朱塞佩

1
858字节 -“常规”高尔夫球,用花括号替换if...else语句,替换cas.vector"\n"使用文字换行符进行更改,并使用>自动将数字静默转换为字符并比较其代码点的事实。我可能还记得其他一些高尔夫球,但这只是一个开始。我认为还有很多事情可以调整,但是我不确定100%是否了解代码...
Giuseppe

好东西!我得到了灵感。通过与您的代码进行比较,我还发现了我的一个错误,该错误有时会导致非常小的区域组(少于4个区域)。现在已修复。
NofP
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.