C (gcc), 82 바이트
n;f(x,y,a,b)int*x,*y;{for(n=0;a;)--b&&*x*2-*y>y[1]?++y:(++b,--a,n+=abs(*x++-*y));}
이것은 두 개의 정수 배열과 길이로 입력됩니다 (C는 그렇지 않으면 길이를 얻을 수 없기 때문에). 이는 실행하는 것으로 할 수 O(a+b)
있기 때문에 하나 a
또는 b
언제 종료 루프의 각 반복에서 감소된다 a
도달하면 0
(그리고이 b
아래에서 감소 될 수 없다 0
).
온라인으로 사용해보십시오!
n; // define sum as an integer
f(x,y,a,b) // function taking two arrays and two lengths
int*x,*y; // use k&r style definitions to shorten function declaration
{
for(n=0; // initialize sum to 0
a;) // keep looping until x (the first array) runs out
// we'll decrement a/b every time we increment x/y respectively
--b&& // if y has ≥1 elements left (b>1, but decrements in-place)...
*x*2-*y>y[1]? // ... and x - y > [next y] - x, but rearranged for brevity...
++y: // increment y (we already decremented b earlier);
(++b, // otherwise, undo the in-place decrement of b from before...
--a,n+=abs(*x++-*y)) // decrement a instead, add |x-y| to n, and then increment x
;}
몇 가지 참고 사항 :
배열을 인덱싱하는 대신 포인터를 늘리고 역 참조하면 가치가있을만큼 충분한 바이트가 절약됩니다 ( *x
vs x[a]
및 y[1]
vs y[b+1]
).
--b&&
에 대한 조건을 확인 b>1
로터리 방식으로는 - 경우 b
입니다 1
, 그것은 0으로 평가합니다. 이것이 수정되었으므로 b
, 삼항의 첫 번째 분기 (이전 y
)에서 변경하지 않아도되지만 두 번째 (이전)에서 다시 변경해야합니다 x
.
return
흑 마법이기 때문에 어떤 진술도 필요 하지 않습니다 . ( 평가할 마지막 명령문은 항상 리턴 값에 사용 된 것과 동일한 레지스터를 사용하는 표현식 이기 때문 이라고 생각n+=...
합니다.)