浴室位置礼仪


24

背景

当涉及到可用的小便池时,浴室礼节指出,下一个要填充的小便池应是最大程度减少总不适感的小便池。总不适感方程由以下方程组给出:

dist(x,y) =人x和y之间的线性距离,单位为小便池不适感(x) = 所有人y的
 总和(1 /(dist(x,y)* dist(x,y))))x
 全部x的total_Discomfort = sum(discomfort(x))

可以在这里找到更深入的论文来解决类似(但不完全相同)的问题:(感谢@Lembik提醒我注意此惊人的白皮书!)


输入输出

给定一个空的和满的小便池的输入,在增加一个人的情况下输出一组最终的小便池。如果位置不平,小便池应从左至右填充。输出应采用与输入相同的格式。

  • 如果给出一个带有完整小便器的包装箱,则返回输入。
  • 输入将始终至少定义一个小便池。


测试用例

输入->输出
1000001-> 1001001
101010101-> 111010101
100-> 101
00000-> 10000
1111111-> 1111111
0100-> 0101
101000-> 101001


规则

这是,因此以字节为单位的最短代码获胜。禁止使用标准孔。



1
建议等待大约一周后再接受答案。在不到一天的时间内接受挑战可能会减少挑战所获得的答案。
Emigna

1
我建议在测试用例中添加0100101000(一些基于正则表达式的方法可用于实际测试用例,但不适用于仍应处理的那些)
Dada


@TheBitByte怎么回事?这是男人在浴室中如何选择小便池的准确描述。
mbomb007 '16

Answers:


3

果冻13 12字节

J_þTݲSiṂ$Ṭo

在线尝试!验证所有测试用例。

说明

J_þTݲSiṂ$Ṭo  Input: boolean array A
J             Indices, returns [1, 2, ..., len(A)]
   T          Truthy indices, returns the indices which have a truthy value
 _þ           Form the subtraction (_) table (þ) between them
    İ         Inverse, find the reciprocal of each
     ²        Square each
      S       Sum the sublists column-wise
         $    Monadic chain
        Ṃ       Minimum
       i        Find the first index of that
          Ṭ   Untruth indices, returns a boolean array with 1's at those indices
           o  Logical OR between that and A, and return

10

MATL19 18 17字节

lyf!Gn:-H_^Xs&X<(

在线尝试!验证所有测试用例(略作修改的代码)。

说明

计算从每个潜在的新位置到已经占据的位置的距离就足够了。剩余距离不取决于潜在的新位置,因此构成一个常数项,可以忽略不计。

让我们以输入[1 0 0 0 0 0 1]为例。

l      % Push 1
       % STACK: 1
y      % Take input implicitly. Duplicate from below
       % STACK: [1 0 0 0 0 0 1], 1, [1 0 0 0 0 0 1]
f!     % Indices of nonzero elements, as a column array
       % STACK: [1 0 0 0 0 0 1], 1, [1 7]
Gn:    % Push [1 2 ... n], where n is input size (array of possible positions)
       % STACK: [1 0 0 0 0 0 1], 1, [1; 7], [1 2 3 4 5 6 7]
-      % Matrix with all pairs of differences 
       % STACK: [1 0 0 0 0 0 1], 1, [1; 7], [0 -1 -2 -3 -4 -5 -6;
                                             6  5  4  3  2  1  0]
H_^    % Raise each entry to -2
       % STACK: [1 0 0 0 0 0 1], 1, [   Inf 1.0000 0.2500 0.1111 0.0625 0.0400 0.0278;
                                     0.0278 0.0400 0.0625 0.1111 0.2500 1.0000    Inf]
Xs     % Sum of each column
       % STACK: [1 0 0 0 0 0 1], 1, [Inf 1.04 0.3125 0.2222 0.3125 1.04 Inf]
&X<    % Index of minimum. Takes the first if there is a tie
       % STACK: [1 0 0 0 0 0 1], 1, 4
(      % Assign: write 1 at the position of the minimizer
       % STACK: [1 0 0 1 0 0 1]
       % Implicitly display

4

JavaScript(ES6),89个字节

a=>a[a.map((e,i)=>!e&&(t=0,a.map((e,j)=>t+=(j-=i)&&e/j/j),t<m&&(m=t,k=i)),k=0,m=1/0),k]=1

通过修改输入数组进行输出。


4

R,83 76 67字节

刚意识到我可以省去几个字节,而不必费心检查候选小便池是否为空。非空小便池将始终返回Inf不适值,因此在计算过程中将它们排除在外。另外,仅使用直接索引而不是replace,因此它更短但更不美观。

x=scan()
x[which.min(rowSums(outer(seq(x),which(!!x),`-`)^-2))]=1
x

说明

x=scan()

我们从stdin读取当前状态,并将其称为x。我们假设输入是1s和0s 的序列,由空格或换行符分隔。出于解释的目的,假设我们输入1 0 0 0 0 0 1

x[which.min(rowSums(outer(seq(x),which(!!x),`-`)^-2))]=1

我们将x特定索引的值替换为1。介于两者之间的所有内容都在[ ]找出最佳索引。

由于现有的小便池是不可变的,因此我们无需考虑它们之间的距离。我们只需要考虑小便池和可能的小便池之间的距离。因此,我们确定了被占用的小便池的索引。我们使用which一个函数来返回逻辑向量的索引TRUE。R中的所有数字,如果强制为type logical,则均为TRUE非零和FALSE零。简单地这样做which(x)会导致类型错误argument to 'which' is not logical,就像x数值向量一样。因此,我们必须迫使它具有逻辑性。!是R的逻辑取反函数,该函数自动强制为逻辑。对其应用两次,!!x得出向量为TRUEFALSE指示哪些小便池已被占用。(逻辑上的等效于字节的强制转换涉及逻辑运算符&|以及内建的TF,例如F|xor T&x等。!!x看起来更令人惊叹,因此我们将使用它。)

                                 which(!!x)

与配对seq(x),将返回从1到的长度的整数序列x,即所有小便池位置(因此要考虑所有可能的位置)。

                          seq(x)

现在我们有了被占用的小便池1 7和空的小便池的索引1 2 3 4 5 6 7。我们将`-`减法函数传递给该outer函数以获取“外部减法”,即所有小便池和被占用的小便池之间的距离的以下矩阵:

[,1] [,2]

[1,] 0 -6

[2,] 1 -5

[3,] 2 -4

[4,] 3 -3

[5,] 4 -2

[6,] 5 -1

[7,] 6 0

                    outer(seq(x),which(!!x),`-`)

我们将其提升为-2力量。(对于在OP中有些迷路的人,“不适”定义为1 / (distance(x, y) * distance(x, y)),简化为1/d(x,y)^2,即d(x,y)^-2。)

                    outer(seq(x),which(!!x),`-`)^-2

取矩阵中每一行的总和。

            rowSums(outer(seq(x),which(!!x),`-`)^-2)

获取最小值的索引,即最佳小便池。如果有多个最小值,则返回第一个(即最左边的)值。

  which.min(rowSums(outer(seq(x),which(!!x),`-`)^-2))

而且,我们拥有最佳小便池的指标。我们在这个指数在替换值x1。在1111作为输入的情况下,我们替换哪个都无所谓,我们仍然会有一个有效的输出。

x[which.min(rowSums(outer(seq(x),which(!!x),`-`)^-2))]=1

返回修改后的输入。

x

2

PHP,135字节

$a=explode(1,$argv[1]);$b=0;foreach($a as$c=>$d){$l=strlen($d);if($l>$b){$b=$l;$e=$c;}}if($b)$a[$e][intval($b/2)]=1;echo implode(1,$a);

我敢肯定有一种相当快的方法,但是我头脑模糊,想不起来!

旧代码

无需缩小的代码:

$a=explode(1,$argv[1]);
$b=0;
foreach($a as $c=>$d){
    $l=strlen($d);
    if($l>$b){
        $b=$l;
        $e=$c;
    }
}
if($b){
    $a[$e][intval($b/2)]=1;
}
echo implode(1,$a);

2

Python的3 223 222 165个字节

好吧,我知道这不是最漂亮的答案,而且我敢肯定它可以打很多,但我只是在四处乱逛,看看自己能做什么

向mbomb007大喊大叫,以获取空白和比较器的提示另外,我看到我的在线字符计数器正在将所有制表符都转换为空格,因此计数比我原来的少了很多

def u(a):
 m,r,x=9,0,len(a)
 for i in range(x): 
    d=0
    if a[i]<'1':
     for j in range(x):
        if a[j]>'0':d+=float((j-i)**-2)
     if d<m:r=i;m=d
 return a[:r]+'1'+a[r+1:]

显示修订的空格:

def u(a):
<sp> m,r,x=9,0,len(a)
<sp> for i in range(x): 
<tab> d=0
<tab> if a[i]<'1':
<tab><sp> for j in range(x):
<tab><tab> if a[j]>'0':d+=float((j-i)**-2)
<tab><sp> if d<m:r=i;m=d
<sp> return a[:r]+'1'+a[r+1:]

原版的:

def u(a):
    m,r,x=9,0,len(a)
    for i in range(x): 
        d=0
        if a[i]!='1':
            for j in range(x):
                if a[j]=='1':d+=float(1/(j-i)**2)
            if d<m:r=i;m=d
    return a[:r]+'1'+a[r+1:]

这需要一个传递给它的1和0之类"10001"的字符串,并返回一个字符串"10101"

编辑:更改1/float((j-i)**2)float((j-i)**-2)


!='1'可以<'1'并且=='1'可以>'0'。另外,还要考虑这个技巧
mbomb007

感谢您的空格提示。我绝对不知道。棒极了!
bioweasel

我认为,该空白提示仅适用于Python 2。也许是Python 3的早期版本,但是是idk。您必须将答案限制在Python 2或3的某些特定版本中才能正常工作。
mbomb007 '16

我已经在IDLE的3.5.2 shell中运行了它,并且没有问题,所以我认为还可以
bioweasel

2

Python 3中,574个 471 347字节

考虑到另一个Python解决方案就像这个解决方案的五分之一,我可能会做更多的工作:[。

def a(I):
 D,l,r={},len(I),range
 for i in r(l):
  if I[i]<1:
   n,t,n[i]=I[:],[],1
   for j in r(l):
    if n[j]>0:
     q,Q=[],0
     for k in r(l):
      if k!=j and n[k]>0:q.append((k-j,j-k)[k<j])
     for i in q:Q+=1/(i**2)
    t.append(Q)
   T=sum(t)
   if T not in D.keys():D[T]=i
 if len(D)>0:I[D[min(D.keys())]]=1
 print(I)

好了,既然我知道您可以使用单个空格,那就更好了。


1

Python中,165个 163 158 147 141 140 139字节

def u(p):e=enumerate;a=[(sum((i-j)**-2for j,y in e(p)if"0"<y),i)for i,x in e(p)if"1">x];return a and p[:min(a)[1]]+"1"+p[min(a)[1]+1:] or p

重写第二行if"1"*len(p)==p:return p以保存一个字节
FlipTack
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.