사다리 건설


26

소개

사다리를 만들고 싶습니다. 이를 위해 폐차장에서 구멍이있는 두 개의 긴 보드를 청소했으며 계단을이 구멍에 넣고 싶습니다. 그러나 구멍이 균등하게 배치되지 않아 계단이 약간 삐걱 거리며 필요한 막대의 양을 추정하기가 어렵습니다. 당신의 임무는 나를 위해 계산을 수행하는 것입니다.

입력

입력은 두 개의 보드를 나타내는 정수 배열로 제공되는 두 개의 비트 벡터입니다. A 0는 구멍이없는 1 개의 청각 세그먼트 ( 임의의 거리 단위 )를 1나타내고, a는 단일 구멍이있는 1 개의 청각 세그먼트를 나타냅니다. 배열의 길이는 다를 수 있으며 다른 수를 포함 할 수 1있지만 비어 있지는 않습니다.

나는 다음과 같이 사다리를 만들 것이다. 먼저, 두 보드를 정확히 하나의 간격으로 놓고 왼쪽 끝을 맞 춥니 다. 각 색인 에 대해 첫 번째 보드의 구멍 i사이의 거리를 측정합니다 i.i th 구멍과 두 번째 막대 조각을 잘라 두 구멍 사이에 부착합니다. 보드 중 하나에 구멍이 없어지면 멈 춥니 다.

산출

귀하의 출력은 걸음 수로 측정되는 단계에 필요한 총 막 대량입니다. 6 자리 이상의 유효 숫자로 출력해야합니다.

입력 [0,1,1,0,1,1,1,1,0,0]과를 고려하십시오 [1,0,0,1,1,1,0,0,1]. 결과 사다리는 다음과 같습니다.

정말 펑키 한 사다리.

이 사다리에서 막대의 전체 길이는 7.06449510224598 aud입니다.

규칙

함수 또는 전체 프로그램을 작성할 수 있습니다. 가장 낮은 바이트 수가 이기고 표준 허점은 허용되지 않습니다.

테스트 사례

[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
본인의 안전을 위해 사다리 모양의 사다리를 등반하는 것은 권장하지 않습니다.
Alex 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 -/@,: yx및 의 항목 차이 y. 하나의 벡터가 더 길면 0으로 채워집니다.
  • x $ y–로 y지정된 모양으로 재구성 x. 특히 x스칼라 인 경우 x요소가에서 가져옵니다 y. 이 사용법에서는 x (<.&# $ -/@,:) y후미 구멍을 무시해야합니다.
  • 4 o. y– 함수 %: 1 + *: y, 즉 sqrt (1 + y ²). 또한이 기능은 구멍 거리에서로드 길이까지 매핑됩니다.
  • +/ y–의 요소의 합 y.

10

파이썬, 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의 목록을 순서가 지정된 단일 지표 목록으로 변환 한 다음 각 요소 사이의 거리를 합산하십시오.


2
잘 했어요 복잡한 리터럴을 사용한 멋진 트릭!
Mac

나는 이것이 다른 대답 보다 1 바이트 짧다는 것이 조금 슬프다 . 더 창의적인 해결책이라고 생각한다.
xnor

6

J, 32 28 바이트

동사 I.1s 의 위치를 이진 문자열로 반환 하는데 큰 도움이됩니다.

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

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

더 나은 J 솔루션을 보려면 FUZxxl 's answer을 확인하십시오 .


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

하스켈, 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]. #이 목록 중 두 개를 압축하여 해당 구멍 사이의 거리 목록으로 바꾸고 마지막으로 합산합니다.


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

파이썬, 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.

그런 다음 재귀합니다. 한 목록이 0으로 시작하고 다른 목록이 1로 시작하지 않는 한 두 목록을 한 단계 씩 이동하는 것이 좋습니다.이 경우 0 목록 만 이동합니다. 그렇게하면 1은 항상 쌍으로 소비됩니다. 우리는 이러한 조건을 확인할 수 있습니다 x<yy<x하지만 같은 목록 비교을 활용하는 짧은이다 a[:1]<=b. 마지막으로 현재 요소 사이의 복잡한 변위를로 조정합니다 x-y.


이것이 다른 솔루션보다 1 바이트 더 많다고 화가 났기 때문에 바이트를 저장하는 방법을 찾았습니다. 변경 a>[]<ba>0<b. 그것은 모두 이후 작품 []0그들이 그렇게있는 거 동등한 falsy 있습니다.
mbomb007

또한 무엇 a:입니까?
mbomb007

1
@ mbomb007. 테스트 했습니까? python2 : ([] > []) != ([] > 0)및 python3에서는 오류입니다 (정렬 불가능한 유형).
ekhumoro

@ mbomb007. 는 a:슬라이스의 일부입니다 [b[:1]<=a:].
ekhumoro

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 's answer 에서 설명했듯이 골프를 더 할 수 있다는 것이 밝혀졌습니다 .


당신은 후 공백을 제거 할 수 있습니다 enumerate(l)0.5(이 단지 0.5가 될 수있다).
FryAmTheEggman 1

@FryAmTheEggman : 감사합니다! 제안대로 변경되었습니다.
Mac

별표 할당을 사용하여 다른 것을 발견했습니다.l=lambda*a:sum(((a-b)**2+1)**.5for a,b in zip(*map(i,a)))
FryAmTheEggman 1

@FryAmTheEggman : 다시 감사합니다! 불행히도 xnor가 더 나아진 것처럼 보이지만-첫 번째 람다는 목록 이해력으로 두 번째로 굴러갔습니다.
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

파이썬 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 바이트입니다.
ekhumoro

아, 개행을 놓쳤다. 고마워.
mbomb007

3

클립 3 , 55 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 -.
  `

입력 형식에 대해 매우 자유로운 경우 각각을 제거하여 이것을 36 바이트로 줄일 수 있습니다 k. 입력은 제어 문자 문자 \0및 의 문자열이어야합니다 \1.


3

ECMAScript 6, 86 바이트

이것은 원래 reduce를 사용하여 시작되었습니다 (@ edc65 답변과 달리 한 루프에서 수행 할 수 있는지 확인하고 싶었습니다).

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

사용자 관리 누적기를 사용하여 비트 맵을 줄일 때 여전히 단일 사례를 찾아야합니다.
edc65

@ edc65 아마도 사실이며 reduce의미 론적으로 더 의미가 있지만 실제로는 사용하기가 다소 어색합니다. 물론, 코드 골퍼들은 언제 의미론에 대해 걱정 했습니까.
qw3n

2

자바, 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

@Zgarb 대부분의 입력에 반복적으로 추가하면 4-5 자릿수 만 표시되므로 더 정확한 버전을 고수하겠습니다. 그러나 설명을 주셔서 감사합니다.
Geobits

2

자바 스크립트 (ES6) 108

요점은 입력 0..1 배열을 구멍 위치 배열로 매핑하는 f 함수입니다. 그런 다음 피타고라스 정리를 사용하여 전체 막대 길이를 계산하여 배열을 스캔합니다. |0단부 근처는 드라이버 어레이 (첫 번째)이 초 이상 일 때 발생할 수 변환 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,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

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