ポジショナルバスルームエチケット


24

バックグラウンド

浴室のエチケットは、利用可能な小便器に関する場合、次に充填する小便器は全体の不快感を最小限に抑えるべきであると述べています。合計不快感の式は、次の式のセットで与えられます。

dist(x、y) =尿便器単位の人xと人yの間の直線距離disfortfort
 (x) = sum(1 /(dist(x、y)* dist(x、y)))(人xを除くすべての人y)
 total_Discomfort = sum(discomfort(x))すべてのx

同様の(まったく同じではない)問題を扱った詳細なペーパーがここにあります(この驚くべきホワイトペーパーについて私に警告してくれた@Lembikに感謝します!)


入出力

空の小便器と完全な小便器の入力が与えられた場合、1人を追加して結果の小便器セットを出力します。位置にネクタイがある場合、小便器は左から右に記入する必要があります。出力は入力と同じ形式である必要があります。

  • 完全な小便器のケースが与えられた場合、入力を返します。
  • 入力には常に少なくとも1つの便器が定義されます。


テストケース

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


ルール

これはであるため、バイト単位の最短コードが優先されます。標準の抜け穴は禁止されています。



1
回答を受け入れるまで約1週間待つことをお勧めします。1日以内に受け入れると、チャレンジが受け取る回答の量が減ることがあります。
エミグナ

1
テストケースを追加すること0100をお勧めします101000(正規表現ベースのアプローチは実際のテストケースでは機能しますが、まだ処理すべきテストケースでは機能しません)
ダダ


@TheBitByteそれは不快ですか?それは男性がトイレで小便器を選ぶ方法のかなり正確な説明です。
mbomb007

回答:


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のすべての数字は、logicalあるTRUE非ゼロの場合にFALSEゼロならば。単純に実行which(x)すると、数値ベクトルargument to 'which' is not logicalと同様に型エラーが発生xします。したがって、論理的に強制する必要があります。!は、Rの論理否定関数であり、自動的に論理に強制されます。それを2回適用すると、!!xのベクトルを生成TRUEし、FALSEどの小便器が使用されているかを示します。(論理に対する代替のバイト相当の強制は、論理演算子含み&and |and builtins Tand F、eg 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))

ほら、最適な小便器のインデックスがあります。私たちは、このインデックスの値を置き換えるx11111入力としての場合、どちらを置換するかは問題ではなく、有効な出力が引き続き得られます。

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

その空白のヒントをありがとう。私は間違いなくそれを知りませんでした。すごい!
バイオウィーゼル

この空白のヒントはPython 2でのみ機能します。Python 3の初期バージョンかもしれませんが、idkです。Python 2またはそれが機能する3の特定のバージョンへの回答を制限する必要があります。
mbomb007

IDLEの3.5.2シェルで実行していますが、問題なく実行されているので、まだ大丈夫だと思います
-bioweasel

2

Python 3、574 471 347バイト

他のPythonソリューションがこのソリューションの5分の1のようなものであることを考慮して、おそらくもう少し作業します。

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

パイソン、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バイトを保存するように2行目を書き換える
-FlipTack
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.