Xây dựng một cái thang


26

Giới thiệu

Tôi muốn xây dựng một cái thang. Đối với điều này, tôi đã nhặt rác từ bãi rác hai tấm ván dài có lỗ, và tôi muốn đặt các bước vào những lỗ này. Tuy nhiên, các lỗ không được đặt đều, do đó các bước sẽ hơi khó khăn và tôi cảm thấy khó ước tính số lượng que tôi cần cho chúng. Công việc của bạn là làm các tính toán cho tôi.

Đầu vào

Đầu vào của bạn là hai vectơ bit, được đưa ra dưới dạng các mảng số nguyên, đại diện cho hai bảng. A 0đại diện cho một phân đoạn của một aud ( đơn vị khoảng cách tùy ý ) không có lỗ và a 1đại diện cho một phân đoạn của một aud với một lỗ duy nhất. Các mảng có thể có độ dài khác nhau và chứa một số 1s khác nhau , nhưng chúng sẽ không trống.

Tôi sẽ xây dựng thang của tôi như sau. Đầu tiên, tôi đặt hai bảng cách nhau một cách chính xác và căn chỉnh các đầu bên trái của chúng. Đối với mỗi chỉ số i, tôi đo khoảng cách giữa ilỗ thứ của bảng ithứ nhất với lỗ thứ của bảng thứ hai, cắt một miếng que và gắn nó vào giữa hai lỗ. Tôi dừng lại khi tôi hết lỗ trên một trong những tấm ván.

Đầu ra

Đầu ra của bạn là tổng số lượng thanh tôi cần cho các bước, được đo bằng kiểm toán. Đầu ra phải chính xác đến ít nhất sáu chữ số có nghĩa.

Thí dụ

Hãy xem xét các đầu vào [0,1,1,0,1,1,1,1,0,0][1,0,0,1,1,1,0,0,1]. Các bậc thang kết quả trông như thế này:

Một cái thang thực sự thú vị.

Tổng chiều dài của thanh trong thang này là 7.06449510224598auds.

Quy tắc

Bạn có thể viết một hàm hoặc một chương trình đầy đủ. Số byte thấp nhất sẽ thắng và các sơ hở tiêu chuẩn không được phép.

Các trường hợp thử nghiệm

[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
Vì sự an toàn của bạn, tôi thực sự không khuyên bạn nên leo lên bất kỳ chiếc thang nào trông giống như vậy.
Alex A.

Câu trả lời:



10

J, 22 ký tự

Không lấy cảm hứng từ câu trả lời của Randomra. Phần I.bằng nhau vì đó là cách rõ ràng ngay lập tức để tìm ra các lỗ hổng.

(4+/@:o.<.&#$-/@,:)&I.
  • I. y- tất cả các chỉ số ylặp lại thường xuyên như mục tương ứng của y. Ngẫu nhiên, nếu ylà một vector của các phép toán, I. ycó chứa các chỉ số mà tại đó y1. Ví dụ, I. 1 0 0 1 1 1 0 0 1sản lượng 0 3 4 5 8.
  • x u&v y- giống như (v x) u (v y). Áp dụng như x u&I. y, chúng tôi nhận được (I. x) u (I. y). Hãy tiếp tục với đầu vào được chuyển đổi.
  • x <.&# y- độ dài nhỏ hơn xy.
  • x -/@,: y- sự khác biệt của các mặt hàng xy. Nếu một vectơ dài hơn, nó được đệm bằng số không.
  • x $ y- yđịnh hình lại theo hình dạng được chỉ định bởi x. Cụ thể, nếu xlà vô hướng, xcác phần tử được lấy từ y. Trong cách sử dụng này, x (<.&# $ -/@,:) yđảm bảo rằng các lỗ dấu được bỏ qua.
  • 4 o. y- hàm %: 1 + *: y, nghĩa là sqrt (1 + y ²). Ngẫu nhiên, chức năng này ánh xạ từ khoảng cách lỗ đến chiều dài của thanh.
  • +/ y- tổng của các yếu tố của y.

10

Con trăn, 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]))

Điều này hóa ra tương tự như giải pháp của Mac . Chuyển đổi danh sách 0 và 1 thành danh sách theo thứ tự của một chỉ mục, sau đó tổng khoảng cách giữa các phần tử tương ứng.


2
Hoàn thành tốt Thủ thuật hay với nghĩa đen phức tạp!
Mac

Tôi hơi buồn vì đây là một byte ngắn hơn câu trả lời khác của tôi , mà tôi nghĩ là một giải pháp sáng tạo hơn.
xnor

6

J, 32 28 byte

Động từ I.trả về vị trí của 1s trong chuỗi nhị phân là một trợ giúp rất lớn.

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

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

Để có giải pháp J tốt hơn, hãy kiểm tra câu trả lời của FUZxxl .


5

R, 67

Sử dụng bên ngoài để làm một sự khác biệt cho các lỗ được lập chỉ mục. Diag trả về sự khác biệt cần thiết. Sau đó tính tổng khoảng cách tính toán

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

Chạy thử trong R Fiddle. Tôi đã gói nó trong một bản in để hiển thị lợi nhuận tuân thủ thông số kỹ thuật.

> 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
>

Đẹp một. a==1có thể a>0hoặc !!a.
freekvd 3/03/2015

5

Haskell, 77 73 byte

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

Cách sử dụng: [0,1,0,1] # [1,0,0,1]đầu ra nào2.414213562373095

Cách thức hoạt động: hàm rtrả về một danh sách các vị trí của các lỗ của bảng, ví dụ r [0,1,0,1]-> [2,4]. #nén hai trong số các danh sách đó và biến nó thành một danh sách khoảng cách giữa các lỗ tương ứng và cuối cùng tính tổng.


4

CJam, 36 33 byte

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

Cách tiếp cận rất ngây thơ ... nó mong đợi đầu vào là mảng kiểu CJam trên STDIN

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

Dưới đây là một khai thác thử nghiệm cho tất cả các đầu vào ví dụ. Các kết quả trong trường đầu vào được sử dụng trước khi mã thực tế được gọi. Bạn có thể loại bỏ chúng nếu bạn không tin tưởng tôi. ;)

Giải trình

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

Con trăn, 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])

Một giải pháp đệ quy cấp thấp và ngây thơ mà không có bất kỳ danh sách tìm kiếm nào.

Các danh sách đầu vào là ab. Nếu một trong hai là trống rỗng, trở lại 0.

Mặt khác, hãy để xylà các phần tử đầu tiên của chúng (mã không thực sự gán các phần tử này vì bạn không thể thực hiện các bài tập trong một lambda, nhưng nó sẽ giúp giải thích dễ dàng hơn). Nếu cả hai đều là 1, tức là sản phẩm của họ là 1, thì chúng đóng góp khoảng cách que. Chúng tôi theo dõi khoảng cách trong số phức i, để khoảng cách đó là giá trị tuyệt đối. Trên thực tế, chúng tôi tính toán nó bất kể, sau đó nhân nó với x*y.

Sau đó, chúng tôi tái diễn. Ý tưởng là thay đổi cả hai danh sách một bước, trừ khi một danh sách bắt đầu bằng 0 và danh sách khác có một danh sách, trong trường hợp đó chúng tôi chỉ thay đổi danh sách 0. Theo cách đó, 1 luôn được tiêu thụ theo cặp. Chúng tôi có thể kiểm tra các điều kiện này với x<yy<x, nhưng nó ngắn hơn để tận dụng lợi thế so sánh danh sách như a[:1]<=b. Cuối cùng, chúng tôi điều chỉnh chuyển vị phức tạp giữa các yếu tố hiện tại bằng cách x-y.


Vì bạn buồn vì đây là hơn 1 byte so với giải pháp khác của bạn, tôi đã tìm ra cách để lưu một byte. Thay đổi a>[]<bthành a>0<b. Nó hoạt động vì cả hai []0đều là giả, vì vậy chúng tương đương nhau.
mbomb007 ngày

Ngoài ra, là a:gì?
mbomb007 ngày

1
@ mbomb007. Bạn đã làm bất kỳ thử nghiệm? Trong python2 : ([] > []) != ([] > 0), và trong python3, đó là một lỗi (các loại không thể sắp xếp).
ekhumoro

@ mbomb007. Đây a:là một phần của lát cắt [b[:1]<=a:].
ekhumoro

4

Python, 105 102 100 byte

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)))

Khá cơ bản, chỉ cần chuyển đổi danh sách đầu vào thành danh sách các chỉ số lỗ, sau đó tính khoảng cách giữa mỗi cặp chỉ số đó.

Trường hợp thử nghiệm:

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

Tín dụng cho @FryAmTheEggman cho một vài đề xuất tiết kiệm byte. Hóa ra điều này có thể được đánh gôn hơn nữa, như thể hiện trong câu trả lời của xnor .


Bạn có thể xóa khoảng trắng sau enumerate(l)0.5(có thể chỉ là 0,5).
FryAmTheEggman 3/03/2015

@FryAmTheEggman: hoàn toàn đúng, cảm ơn! Thay đổi theo đề nghị.
Mac

Tìm thấy một điều khác bằng cách sử dụng phân công có sao:l=lambda*a:sum(((a-b)**2+1)**.5for a,b in zip(*map(i,a)))
FryAmTheEggman

@FryAmTheEggman: cảm ơn lần nữa! Thật không may, có vẻ như xnor đã đi tốt hơn một chút - rất giống nhau, nhưng với lambda đầu tiên được đưa vào thứ hai như một sự hiểu biết danh sách ...
Mac

3

Bình thường, 30 byte

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

Hãy thử trực tuyến với đầu vào [0,1,1,0,1,1,1,1,0,0], [1,0,0,1,1,1,0,0,1].

Giải trình:

Tôi chuyển đổi danh sách thành danh sách các chỉ số [2, 3, 5, 6, 7, 8][1, 4, 5, 6, 9]và nén chúng lại với nhau [(2,1), (3,4), (5,5), (6,6), (7,9)]. Sau đó, tôi trừ các giá trị, bình phương chúng, thêm 1 và tổng trên tất cả các căn bậc hai.

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

Thật xấu hổ khi sumkhông làm việc cho danh sách trống.


3

Python, 116 115 byte

Đây là một giải pháp đệ quy.

Nó trở nên khá khó chịu khi tôi thấy rằng index()chỉ cần ném một lỗi khi không tìm thấy giá trị, nhưng tôi đã làm cho nó hoạt động. Thật không may, tôi không thể sử dụng lambda. Nó cũng làm tôi bực mìnhlist.remove() không trả lại danh sách mà thay vào đó trả về 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)

Chạy trực tuyến tại đây: http://repl.it/c5L/2


Ngay cả với các tab, mã đó là 116 byte, không phải 112.
ekhumoro

Ah, bỏ lỡ các dòng mới, cảm ơn.
mbomb007

3

Clip 3 , 55 47 38

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

Đối với danh sách có ít lỗ hơn, chương trình lặp qua nó và kết nối từng lỗ với lỗ tương ứng của danh sách khác. Các kích thước được tính toán và tổng hợp.

>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

Giải trình

[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 -.
  `

Nếu chúng ta rất tự do về định dạng đầu vào, chúng ta có thể giảm mức này xuống 36 byte bằng cách loại bỏ từng byte k. Điều này đòi hỏi đầu vào phải là một chuỗi các ký tự điều khiển \0\1.


3

ECMAScript 6, 86 byte

Điều này ban đầu bắt đầu bằng cách sử dụng giảm (tôi muốn xem liệu nó có thể được thực hiện trong một vòng so với câu trả lời @ edc65 không).

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)

Nhưng sử dụng @ edc65 cho map&&tđể trả về giá trị, tôi có thể rút ngắn nó một chú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

Tôi vẫn phải tìm một trường hợp duy nhất khi giảm bản đồ nhịp đập với bộ tích lũy do người dùng quản lý.
edc65 ngày

@ edc65 có lẽ đúng, reducecó ý nghĩa hơn về mặt ngữ nghĩa, nhưng khác hơn là nó thực sự khó sử dụng. Tất nhiên, từ khi nào những người chơi golf mã lo lắng về ngữ nghĩa.
qw3n 3/03/2015

2

Java, 151

Điều này chỉ đi dọc theo atìm kiếm những người, sau đó đi dọc bkhi tìm thấy một. Nếu floatđộ chính xác có thể chấp nhận được, tôi có thể lưu một vài byte, nhưng tôi đã sử dụng doubleđể khớp với đầu ra thử nghiệm.

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;}

Với khoảng trắng:

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;
}

Sáu chữ số có nghĩa là đủ chính xác, vì vậy nó nổi cho bạn điều đó, đi cho nó.
Zgarb 3/03/2015

@Zgarb Các bổ sung lặp đi lặp lại trên hầu hết các đầu vào chỉ cung cấp cho tôi 4-5 chữ số đứng đầu, vì vậy tôi sẽ sử dụng phiên bản chính xác hơn. Cảm ơn đã làm rõ, mặc dù.
Geobits 3/03/2015

2

JavaScript (ES6) 108

Điểm chính là hàm f ánh xạ các mảng 0..1 đầu vào trong các mảng của các vị trí lỗ. Sau đó, các mảng được quét tính toán tổng chiều dài thanh bằng định lý pythagore. Sự |0kết thúc gần là cần thiết để chuyển đổi NaN có thể dẫn đến khi mảng trình điều khiển (phần đầu tiên) dài hơn phần thứ hai.

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

Kiểm tra trong bảng điều khiển 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,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,1,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}

Có thể đọc được

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
}

Kiểm tra:

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 byte

Sử dụng một thuật toán tương tự như giải pháp J, nhưng APL có ít nội trang hơn.

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

Ví dụ đầu vào:

      {+/4○⊃-/{⍵⍴¨⍨⌊/⍴¨⍵}⍵/¨⍳¨⍴¨⍵}(1 0 0 1)(0 1 0 1)
2.414213562
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.