はしごを組み立てる


26

前書き

はしごを作りたいです。このために、私は廃品置き場から、穴の開いた2つの長いボードを清掃しまし​​た。これらの穴にステップを配置したいと思います。ただし、穴が均等に配置されていないため、ステップが少し不安定になり、それらに必要なロッドの量を見積もることが難しくなります。あなたの仕事は私のために計算をすることです。

入力

入力は、2つのボードを表す整数の配列として与えられる2ビットのベクトルです。A 0は、穴のない1オード(距離の任意の単位1のセグメントを表し、aは、単一の穴のある1オードのセグメントを表します。配列の長さは異なり、1sの数も異なりますが、空にはなりません。

はしごを次のように構築します。まず、2つのボードを正確に1オード離して配置し、左端を揃えます。インデックスごとに、最初のボードのth穴と2番目のボードiith穴の間の距離を測定し、iロッドを切断して、2つの穴の間に取り付けます。いずれかのボードの穴がなくなると停止します。

出力

出力は、ステップに必要なロッドの合計量であり、オードで測定されます。出力は、少なくとも6桁の有効数字まで正しいはずです。

入力[0,1,1,0,1,1,1,1,0,0]とを考慮してください[1,0,0,1,1,1,0,0,1]。結果のはしごは次のようになります。

本当にファンキーなはしご。

このラダーのロッドの全長は7.06449510224598オードです。

ルール

関数または完全なプログラムのいずれかを作成できます。最小のバイトカウントが優先され、標準の抜け穴は許可されません。

テストケース

[0] [0] -> 0.0
[0] [1,0] -> 0.0
[1,0,0] [1,1,1,1,1] -> 1.0
[0,1,0,1] [1,0,0,1] -> 2.414213562373095
[0,1,1,0,1,1,1,1,0,0] [1,0,0,1,1,1,0,0,1] -> 7.06449510224598
[1,1,1,1,1] [0,0,1,1,0,1,0,0,1] -> 12.733433128760744
[0,0,0,1,0,1,1,0,0,0,1,1,1,0,0,1,0,1,1,0,0,0,1,0] [0,0,1,1,0,1,1,1,0,0,0,0,0,1,1,0,1,1,0,0,0,1] -> 20.38177416534678

32
あなた自身の安全のために、私は本当にそのようなはしごを登ることはお勧めしません。
アレックスA.

回答:



10

J、22文字

randomraの答えに触発されていません。I.その穴を見つける直ちに明白な方法であるように部分が同一です。

(4+/@:o.<.&#$-/@,:)&I.
  • I. yyの対応するアイテムと同じ頻度で繰り返されるすべてのインデックスy。場合なお、yブール値のベクトルであり、I. yこれにインデックス含まyです1。たとえば、I. 1 0 0 1 1 1 0 0 1yields 0 3 4 5 8
  • x u&v y–と同じ(v x) u (v y)。として適用されx u&I. y、我々は得る(I. x) u (I. y)。変換された入力を続けましょう。
  • x <.&# yxおよびの長さの短い方y
  • x -/@,: y-の項目の違いxy。1つのベクトルが長い場合、ゼロが埋め込まれます。
  • x $ y–でy指定された形状に再形成されxます。特に、xがスカラーの場合、x要素はから取得されyます。この使用法でx (<.&# $ -/@,:) yは、末尾の穴が無視されるようにします。
  • 4 o. y–関数%: 1 + *: y、つまりsqrt(1 + )。ちなみに、この関数は、穴の距離からロッドの長さまでマッピングします。
  • +/ y–の要素の合計y

10

Python、85

lambda*A:sum(abs(x-y+1j)for x,y in zip(*[[i for i,x in enumerate(l)if x]for l in A]))

これは、Macのソリューションに似ています。0と1のリストを1インデックスの順序付きリストに変換し、それぞれの要素間の距離を合計します。


2
よくできました。複雑なリテラルを使用した素敵なトリック!
マック

これが他の答えよりも1バイト短いことは少し悲しいですが、これはより創造的な解決策だと思います。
xnor

6

J、32 28バイト

動詞I.は、1s の位置をバイナリ文字列で返します。これは非常に役立ちます。

   +/@,@(=/&(#\)*[:>:&.*:-/)&I.

   0 1 0 1 (+/@,@(=/&(#\)*[:>:&.*:-/)&I.) 1 0 0 1
2.41421

より良いJソリューションについては、FUZxxlの答えを確認してください。


5

R、67

outerを使用して、インデックス付きの穴に違いを付けます。Diagは必要な違いを返します。次に、計算された距離を合計します

function(a,b)sum((diag(outer(which(a==1),which(b==1),"-"))^2+1)^.5)

R Fiddleでテスト実行します。リターンが仕様に準拠していることを示すために、私はそれを印刷物に包んでいます。

> print((function(a,b)sum((diag(outer(which(a==1),which(b==1),"-"))^2+1)^.5))(c(0,1,1,0,1,1,1,1,0,0),c(1,0,0,1,1,1,0,0,1)),digits=10)
[1] 7.064495102
> print((function(a,b)sum((diag(outer(which(a==1),which(b==1),"-"))^2+1)^.5))(c(1,1,1,1,1),c(0,0,1,1,0,1,0,0,1)),digits=10)
[1] 12.73343313
>

良いですね。a==1ことができますa>0!!a
freekvd

5

Haskell、77 73バイト

r x=[a|(a,1)<-zip[1..]x]
i#j=sum$zipWith(\n m->sqrt((n-m)**2+1))(r i)$r j

使用法:[0,1,0,1] # [1,0,0,1]どの出力2.414213562373095

仕組み:関数rは、ボードの穴の位置のリストを返します(例:r [0,1,0,1]->)[2,4]#これらのリストのうち2つを圧縮して、対応する穴間の距離のリストに変換し、最終的に合計します。


4

CJam、36 33バイト

l~]{:L,{L=},}%z{,(},0\{~-_*)mq+}/

非常に素朴なアプローチ... STDIN上のCJamスタイルの配列として入力を期待します

[0 1 1 0 1 1 1 1 0 0] [1 0 0 1 1 1 0 0 1]

これは、すべての入力例のテストハーネスです。入力フィールドの結果は、実際のコードが呼び出される前に使用されます。あなたが私を信用していないなら、あなたはそれらを取り除くことができます。;)

説明

l~]                               "Read and eval input, wrap in an array.";
   {        }%                    "Map this block onto both input arrays.";
    :L,                           "Store array in L, get its length N.";
       {L=},                      "In the range [0 .. N-1] get all elements where L is 1.";
                                  "At this point we've converted each array into a list of its
                                   non-zero indices.";
              z                   "Transpose the array, pairing up indices at the same position.";
               {,(},              "Filter the extraneous elements of the longer input.";
                    0\            "Put a 0 before the array.";
                      {        }/ "For each pair of holes...";
                       ~-         "Unwrap the pair, take the difference.";
                         _*)mq    "Square, increment, square root.";
                              +   "Add to the running total.";

4

Python、86

f=lambda a,b,i=1j:a>[]<b and a[0]*b[0]*abs(i)+f(a[a[:1]<=b:],b[b[:1]<=a:],i+a[0]-b[0])

リスト検索なしの低レベルで単純な再帰的ソリューション。

入力リストがあるab。どちらかが空の場合、を返し0ます。

そうでなければ、聞かせてxy彼らの最初の要素であること(あなたが割り当てを行うことができないため、コードが実際にこれらを割り当てることはありませんlambdaが、それは簡単に説明するようになります)。両方が1の場合、つまり製品が1の場合、ロッドの距離に寄与します。複素数で距離を追跡するiため、距離は絶対値です。実際には、それを計算し、それを掛けx*yます。

次に、再帰します。1つのリストが0で始まり、もう1つのリストが1でない限り、両方のリストを1ステップだけシフトします。その場合、0リストのみをシフトします。そのようにして、1は常にペアで消費されます。x<yandを使用してこれらの条件をチェックできますがy<x、リスト比較を利用する方が短いa[:1]<=bです。最後に、によって現在の要素間の複素変位を調整しx-yます。


これが他のソリューションよりも1バイト多いことに気が付かないので、バイトを節約する方法を見つけました。に変更a>[]<ba>0<bます。両方[]から0機能し、偽物であるため、同等です。
mbomb007

また、何a:ですか?
mbomb007

1
@ mbomb007。テストをしましたか?python2:、([] > []) != ([] > 0)およびpython3ではエラー(順序付け不能な型)です。
エクモロ

@ mbomb007。a:スライスの一部です[b[:1]<=a:]
エクモロ

4

パイソン、105の 102 100バイト

i=lambda l:(i for i,h in enumerate(l)if h)
l=lambda*a:sum(((a-b)**2+1)**.5for a,b in zip(*map(i,a)))

かなり基本的なもので、入力リストを穴インデックスのリストに変換し、そのようなインデックスの各ペア間の距離を計算します。

テストケース:

>>> print l([0,1,1,0,1,1,1,1,0,0], [1,0,0,1,1,1,0,0,1])
7.06449510225

いくつかのバイト節約の提案については、@ FryAmTheEggmanに感謝します。xnorの回答で示されているように、これはさらにゴルフをすることができます。


enumerate(l)andの後のスペースを削除できます0.5(ちょうど.5の場合もあります)。
FryAmTheEggman

@FryAmTheEggman:絶対に正しい、ありがとう!提案どおりに変更されました。
Macで

スター付きの割り当てを使用して別のことを見つけました:l=lambda*a:sum(((a-b)**2+1)**.5for a,b in zip(*map(i,a)))
FryAmTheEggman

@FryAmTheEggman:どうもありがとう!残念ながら、それはXNORのようでなくなっ1よりよいのに-ずっと同じですが、リスト内包ように、第2に巻い最初のラムダと...
Macの

3

Pyth、30バイト

s+0m^h^-hded2 .5CmfTm*hb@kblkQ

入力してオンラインで試してください[0,1,1,0,1,1,1,1,0,0], [1,0,0,1,1,1,0,0,1]

説明:

私は、インデックスのリストにリストを変換[2, 3, 5, 6, 7, 8]し、[1, 4, 5, 6, 9]それらを一緒にジップ[(2,1), (3,4), (5,5), (6,6), (7,9)]。次に、値を減算し、平方し、1を加算して、すべての平方根を合計します。

CmfTm*hb@kblkQ
 m           Q     map each list k in input() to the following list:
    m      lk         map each value b of [0, 1, 2, ..., len(k)-1] to the value:
     *hb@kb              (b + 1) * k[b]
  fT                  filter the list for positive values
C                  zip these two resulting lists

s+0m^h^-hded2 .5...
   m            ...  map each pair of values d to: 
    ^h^-hded2 .5         ((d[0] - d[1])^2 + 1)^0.5
 +0                  insert 0 at the front of the list
s                    sum

sum空のリストでは機能しない恥。


3

Python、116 115バイト

これは再帰的な解決策です。

index()値が見つからないときにエラーをスローするだけであることがわかったとき、かなり面倒になりましたが、私はそれを動作させました。残念ながら、ラムダは使用できません。またlist.remove()、リストを返さず、代わりにを返すことにも悩まされましたNone

def f(x,y,r=0):
    try:i,j=x.index(1),y.index(1)
    except:return r
    x.pop(i);y.pop(j);return f(x,y,r+((i-j)**2+1)**.5)

ここでオンラインで実行:http : //repl.it/c5L/2


タブを使用しても、そのコードは112バイトではなく116バイト
です。-エクモロ

ああ、改行を逃した、ありがとう。
mbomb007

3

クリップ355 47 38

[cr+`j[v[w#)#mvw2B}}(c)c]sl`{%ky1%kx1`

穴の少ないリストの場合、プログラムはそれを反復処理し、各穴を他のリストの対応する穴に接続します。サイズが計算され、合計されます。

>java -jar Clip3.jar ladder.clip
{0,1,1,0,1,1,1,1,0,0}
{1,0,0,1,1,1,0,0,1}
7.064495102245980096000721459859050810337066650390625

説明

[c          .- Assign c to the lists, in order of size    -.
  r+`       .- The sum of...                              -.
   j[v[w    .- Join the lists with a function on v, w     -.
     #      .- Square root                                -.
      )     .- 1 plus                                     -.
       #    .- The square of                              -.
        mvw .- The distance between v and w               -.
       2
     B      .- (one-half, so #...B means square root)     -.
   }}(c)c   .- Apply joining function to the lists        -.
  ]sl`{     .- c is the (sorted by size) list of...       -.
    %ky1    .- Indices of y (the second input) which are 1-.
    %kx1    .- Indices of x (the first input) which are 1 -.
  `

入力形式について非常に寛大な場合、eachを削除することでこれを36バイトに減らすことができますk。これは、制御文字の文字列であることを入力が必要\0\1


3

ECMAScript 6、86バイト

これは元々reduceを使用して開始しました(@ edc65の回答ではなく、1つのループで実行できるかどうかを確認したかったためです)。

f=(c,b,a=[0,...c],j)=>a.reduce((c,v,i)=>c+=v&&(j=b.indexOf(1,j)+1,v=i-j,j)?Math.sqrt(1+v*v):0)

しかし、値を返すために@ edc65を使用するmap&&t、かなり短くすることができました。

f=(a,b,j,c=0)=>a.map((v,i)=>c+=v&&(j=b.indexOf(1,j)+1,v=i+1-j,j)&&Math.sqrt(1+v*v))&&c

f=(a,b,j,c=0)        //variables note the j can be undefined
=>a.map((v,i)=>      //loop through the first array
c+=                  //add 
v&&                  //test to see if we have a hole
(j=b.indexOf(1,j)+1, //if so see if there is a whole on the other board
v=i+1-j,             //calculate index difference
j)                   //the last var gets evaluated so check to see if indexOf returned -1
&&Math.sqrt(1+v*v))  //calculate 
&&c                  //return sum

ユーザーが管理するアキュムレータでビートマップを減らす場合、1つのケースを見つける必要があります。
edc65

@ edc65はおそらく真であり、reduce意味的にはより理にかなっていますが、それ以外は実際には使用するのが面倒です。もちろん、コードゴルファーはいつセマンティックスを心配したのですか?
qw3n

2

Java、151

これはただ一つをa探して歩いてb、それを見つけたら一緒に歩きます。float精度が許容範囲内であれば、数バイト節約できますがdouble、テスト出力を一致させました。

double d(int[]a,int[]b){double z=0;for(int x=-1,y=0,d=b.length;x++<a.length&y<d;z+=a[x]>0?Math.sqrt((y-x)*(y++-x)+1):0)for(;y<d&&b[y]<1;y++);return z;}

空白あり:

double d(int[]a,int[]b){
    double z=0;
    for(int x=-1,y=0,d=b.length;
            x++<a.length&y<d;
            z+=a[x]>0?Math.sqrt((y-x)*(y++-x)+1):0)
        for(;y<d&&b[y]<1;y++);
    return z;
}

有効数字6桁で十分な精度が得られるため、浮動小数点数を使用すればそれで十分です。
ズガルブ

@Zgarbほとんどの入力で繰り返し追加すると、4〜5桁のトップが表示されるだけなので、より正確なバージョンに固執します。ただし、説明してくれてありがとう。
ジオビット

2

JavaScript(ES6)108

主なポイントは、入力0..1配列を穴の位置の配列にマッピングするf関数です。次に、アレイをスキャンして、ピタゴラスの定理を使用して総ロッド長を計算します。|0端部の近くには、ドライバアレイ(第一)が第2のより長い場合に生じ得るコンバートのNaNに必要とされます。

F=(a,b,f=a=>a.map(v=>++u*v,u=0).filter(x=>x))=>
  f(a,b=f(b)).map((v,i)=>t+=Math.sqrt((w=b[i]-v)*w+1|0),t=0)&&t

Firefox / FireBugコンソールでテストする

;[[[0],[0]]
 ,[[0],[1,0]]
 ,[[1,0,0],[1,1,1,1,1]]
 ,[[0,1,0,1],[1,0,0,1]]
 ,[[0,1,1,0,1,1,1,1,0,0],[1,0,0,1,1,1,0,0,1]]
 ,[[1,1,1,1,1],[0,0,1,1,0,1,0,0,1]]
 ,[[0,0,0,1,0,1,1,0,0,0,1,1,1,0,0,1,0,1,1,0,0,0,1,0],[0,0,1,1,0,1,1,1,0,0,0,0,0,1,1,0,1,1,0,0,0,1]]]
.forEach(v=>console.log('['+v[0]+']','['+v[1]+']',F(...v)))

[0] [0] 0
[0] [1,0] 0
[1,0,0] [1,1,1,1,1] 1
[0,1,0,1] [1,0,0 、1] 2.414213562373095
[0,1,1,0,1,1,1,1,0,0] [1,0,0,1,1,1,1,0,0,1] 7.06449510224598
[1,1、 1,1,1] [0,0,1,1,0,1,0,0,1] 12.733433128760744
[0,0,0,1,0,1,1,0,0,0,1,1 、1,0,0,1,0,1,1,0,0,0,1,0] [0,0,1,1,0,1,1,1,0,0,0,0、 0,1,1,0,1,1,0,0,0,1] 20.38177416534678



0

Perl 98

sub l{$r=0;@a=grep$a->[$_],0..$#$a;@b=grep$b->[$_],0..$#$b;$r+=sqrt 1+(shift(@a)-shift@b)**2 while@a&&@b;$r}

読みやすい:

sub l {
    $r = 0;
    @a = grep $a->[$_], 0 .. $#$a;
    @b = grep $b->[$_], 0 .. $#$b;
    $r += sqrt 1 + (shift(@a) - shift @b) ** 2 while @a && @b;
    $r
}

テスト:

use Test::More;
for (<DATA>) {
    my ($A, $B, $r) = /\[ ([0-9,]+) \] \s \[ ([0-9,]+) \] \s -> \s ([0-9.]+) /x;
    $a = [split /,/, $A];
    $b = [split /,/, $B];
    cmp_ok l(), '==', $r, "test $_";
}
done_testing($.);
__DATA__
[0] [0] -> 0.0
[0] [1,0] -> 0.0
[1,0,0] [1,1,1,1,1] -> 1.0
[0,1,0,1] [1,0,0,1] -> 2.414213562373095
[0,1,1,0,1,1,1,1,0,0] [1,0,0,1,1,1,0,0,1] -> 7.06449510224598
[1,1,1,1,1] [0,0,1,1,0,1,0,0,1] -> 12.733433128760744
[0,0,0,1,0,1,1,0,0,0,1,1,1,0,0,1,0,1,1,0,0,0,1,0] [0,0,1,1,0,1,1,1,0,0,0,0,0,1,1,0,1,1,0,0,0,1] -> 20.38177416534678

0

APL、35 28バイト

Jソリューションと同様のアルゴリズムを使用しますが、APLのビルトインは少なくなります。

{+/4○⊃-/{⍵⍴¨⍨⌊/⍴¨⍵}⍵/¨⍳¨⍴¨⍵}

入力例:

      {+/4○⊃-/{⍵⍴¨⍨⌊/⍴¨⍵}⍵/¨⍳¨⍴¨⍵}(1 0 0 1)(0 1 0 1)
2.414213562
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.