좌표 및 질량리스트에서 질량 중심


20

다음은 월요일 아침의 빠른 도전입니다 ...

다음과 같은 최소 바이트 수로 함수 또는 프로그램을 작성하십시오.

  • [x,y]좌표 목록을 입력으로받습니다.
  • [x,y]좌표의 각 질량 리스트를 입력으로 받습니다.
  • 계산 된 질량 중심을 형식으로 출력합니다 [xBar,yBar].

노트 :

  • 배열이 사용되는 한 어떤 형태로든 입력 할 수 있습니다.

질량 중심은 다음 공식으로 계산할 수 있습니다. 질량 중심 계산

평범한 영어로 ...

  • 를 찾으려면 xBar각 질량에 각각의 x 좌표를 곱하고 결과 목록을 합한 후 모든 질량의 합으로 나눕니다.
  • 를 찾으려면 yBar각 질량에 각각의 y 좌표를 곱하고 결과 목록을 합한 후 모든 질량의 합으로 나눕니다.

사소한 파이썬 2.7 예제 :

def center(coord, mass):
    sumMass = float(reduce(lambda a, b: a+b, mass))
    momentX = reduce(lambda m, x: m+x, (a*b for a, b in zip(mass, zip(*coord)[0])))
    momentY = reduce(lambda m, y: m+y, (a*b for a, b in zip(mass, zip(*coord)[1])))
    xBar = momentX / sumMass
    yBar = momentY / sumMass
    return [xBar, yBar]

테스트 사례 :

> center([[0, 2], [3, 4], [0, 1], [1, 1]], [2, 6, 2, 10])
[1.4, 2.0]

> center([[3, 1], [0, 0], [1, 4]], [2, 4, 1])
[1.0, 0.8571428571428571]

이것은 코드 골프이므로 바이트 수가 가장 적습니다!


이것이 "가중 평균 벡터 계산"이기 때문에 이전에하지 않았다면 매우 놀랐습니다. (현재로서는 아무것도 찾을 수 없습니다.)
Martin Ender

@ MartinBüttner 나도 보았고 찾을 수 없었습니다. 이것이 속이는 경우 자유롭게 닫으십시오.
Mr Public Public

다른 순서로 입력 할 수 있습니까? 또는 형태 : [x,y,m],[x,y,m]...?
FryAmTheEggman

@FryAmTheEggman 유효한 입력을 위해 질문이 편집되었습니다.
Mr Public Public

@MrPublic : [(x1,y1,m1), (x2,y2,m2)]예를 들어 튜플 목록은 어떻습니까? 아니면 인수가 튜플, 목록 또는 배열인지 여부는 중요하지 않습니까? 세 개의 목록 / 배열은 어떻습니까?
Zeta

답변:


21

MATL , 6 5 바이트

ys/Y*

입력 형식은 질량이있는 행 벡터이며 좌표가있는 2 열 행렬 (공백 또는 쉼표는 선택 사항 임)입니다.

  • 첫 번째 예 :

    [2, 6, 2, 10]
    [0,2; 3,4; 0,1; 1,1]
    
  • 두 번째 예 :

    [2, 4, 1]
    [3,1; 0,0; 1,4]
    

온라인으로 사용해보십시오!

설명

하자 m대중의 벡터 (제 1 입력)와 나타내고 c좌표 행렬 (제 입력).

y     % implicitly take two inputs. Duplicate the first.
      % (Stack contains, bottom to top: m, c, m)
s     % sum of m.
      % (Stack: m, c, sum-of-m)
/     % divide.
      % (Stack: m, c-divided-by-sum-of-m)
Y*    % matrix multiplication.
      % (Stack: final result)
      % implicitly display

y꽤 유용합니다! +1
David

@ 데이비드 그래! 암시 적 입력과 결합하여이 경우에 많은 일을합니다 :-)
Luis Mendo

7

Mathematica, 10 바이트

#.#2/Tr@#&

예:

In[1]:= #.#2/Tr@#&[{2,6,2,10},{{0,2},{3,4},{0,1},{1,1}}]

Out[1]= {7/5, 2}

1
나는 결코 사용하지 않았다 Dot. 그러나 위의 사용법을 본 후!
DavidC

7

Mathcad, 19 "바이트"

여기에 이미지 설명을 입력하십시오

  • 데이터 입력을 위해 Mathcad의 테이블 사용
  • 축 좌표와 질량을 곱하기 위해 Mathcad의 내장 벡터 스칼라 곱을 사용합니다.
  • Mathcad의 내장 합계 연산자를 사용하여 총 질량

Mathcad는 2D "화이트 보드"및 특수 연산자 (예 : 합산 연산자, 정수 연산자)를 사용하고 XML 형식으로 저장하므로 실제 워크 시트에는 수백 개 이상의 문자가 포함될 수 있습니다. Code Golf의 목적을 위해 Mathcad "바이트 수"를 사용자가 워크 시트를 만들기 위해 입력해야하는 문자 또는 연산자의 수로 사용했습니다.

챌린지의 첫 번째 (프로그램) 버전은이 정의를 사용하여 19 "바이트"를 사용하고 기능 버전은 41 "바이트"를 사용합니다.


3
처음으로 Matcad 솔루션을 본 적이 있습니다. 아주 좋아요 +1.
rayryeng-복원 모니카

고맙습니다. Mathcad에는 기본 문자열 기능 만 있고 사람이 읽을 수있는 텍스트 전용 소스 코드가 없기 때문에 "코스"에서 "구멍"중 일부를 수행하는 것은 다소 어려운 문제 일 수 있습니다.
스튜어트 브 러프

6

MATLAB / 옥타브, 18 16 바이트

2 바이트를 제거해 준 사용자 비커와 Don Muesli에게 감사합니다!

좌표가에 주어진 N x 2행렬 x첫번째 열은 X 좌표와 두 번째 열은 Y 좌표이다하고 질량이에 1 x N매트릭스 y(또는 행 벡터)

@(x,y)y*x/sum(y)

이 코드에 대한 설명은 매우 간단합니다. 이 두 입력에 소요 익명 함수 xy. 행렬-벡터 곱셈을 사용하여 선형 대수 접근법에서 가중 합 (각 좌표의 분자식)을 수행합니다. y질량 벡터를 취하고 이것을 좌표 행렬과 x행렬 벡터 곱셈으로 곱하면 두 좌표의 가중 합을 개별적으로 계산 한 다음이 좌표 각각을 질량의 합으로 나눠 원하는 중심을 찾습니다. 질량은 각 좌표에 대해 1 x 2 행 벡터로 각각 반환됩니다.

예제 실행

>> A=@(x,y)y*x/sum(y)

A = 

    @(x,y)y*x/sum(y)

>> x = [0 2; 3 4; 0 1; 1 1];
>> y = [2 6 2 10];
>> A(x,y)

ans =

    1.4000    2.0000

>> x = [3 1; 0 0; 1 4];
>> y = [2 4 1];
>> A(x,y)

ans =

    1.0000    0.8571

온라인으로 사용해보십시오!

https://ideone.com/BzbQ3e


1
를 제거 할 ;수도 있고 '입력 형식 ( x행 벡터로) 을 올바르게 선택하면
Luis Mendo

@DonMuesli Thanks :) 바이트 수를 2
줄였습니다

6

젤리, 6 바이트

S÷@×"S

또는

÷S$×"S

입력은 두 개의 명령 행 인수를 통해 이루어지며, 질량은 먼저, 좌표는 두번째입니다.

온라인으로 사용해보십시오!

설명

S       Sum the masses.
   x"   Multiply each vector by the corresponding mass.
 ÷@     Divide the results by the sum of masses.
     S  Sum the vectors.

또는

÷S$     Divide the masses by their sum.
   ×"   Multiply each vector by the corresponding normalised mass.
     S  Sum the vectors.

6

줄리아, 25 17 바이트

f(c,m)=m*c/sum(m)

명백한 접근 방식을 놓쳤습니다 f([3 1;0 0;1 4], [2 4 1]).


5

CJam, 14 바이트

{_:+df/.f*:.+}

명명되지 않은 함수를 사용하면 좌표 쌍 목록과 스택의 질량 목록 (순서대로)이 필요하고 그 중심에 질량 중심이 남습니다.

여기에서 테스트하십시오.

설명

_    e# Duplicate list of masses.
:+d  e# Get sum, convert to double.
f/   e# Divide each mass by the sum, normalising the list of masses.
.f*  e# Multiply each component of each vector by the corresponding weight.
:.+  e# Element-wise sum of all weighted vectors.


4

정말 16 바이트

╩2└Σ;╛2└*/@╜2└*/

입력을로 취하고 다음 [x-coords]\n[y-coords]\n[masses]과 같이 출력합니다.xbar\nybar

온라인으로 사용해보십시오!

설명:

╩2└Σ;╛2└*/@╜2└*/
╩                 push each line of input into its own numbered register
 2└Σ;             push 2 copies of the sum of the masses
     ╛2└*/        push masses and y-coords, dot product, divide by sum of masses
          @       swap
           ╜2└*/  push masses and x-coords, dot product, divide by sum of masses

3

하스켈, 55 50 바이트

z=zipWith
f a=map(/sum a).foldr1(z(+)).z(map.(*))a

이것은 f다음과 같이 사용되는 이진 함수를 정의 합니다.

> f [1,2] [[1,2],[3,4]]
[2.3333333333333335,3.333333333333333]

두 테스트 사례 모두를 통과했는지 확인하십시오.

설명

Haskell은 다차원 목록을 처리하는 데 적합하지 않으므로 여기에서 몇 가지 문제를 겪고 있습니다. 첫 번째 줄은에 대한 짧은 별칭을 정의하는데 zipWith두 번 필요합니다. 기본적으로 f가중치 목록을 가져 와서 a생성 하는 기능입니다f a 을 가져와 위치 목록을 가져와 질량 중심을 생성하는 함수 인 기능입니다. f a세 가지 기능의 구성입니다.

z(map.(*))a      -- First sub-function:
z         a      --   Zip the list of positions with the mass list a
  map.(*)        --   using the function map.(*), which takes a mass m
                 --   and maps (*m) over the corresponding position vector
foldr1(z(+))     -- Second sub-function:
foldr1           --   Fold (reduce) the list of mass-times-position vectors
       z(+)      --   using element-wise addition
map(/sum a)      -- Third sub-function:
map              --   Map over both coordinates:
   (/sum a)      --     Divide by the sum of all masses

3

자바 스크립트 (ES6), 60 바이트

a=>a.map(([x,y,m])=>{s+=m;t+=x*m;u+=y*m},s=t=u=0)&&[t/s,u/s]

(x, y, mass) "triples"의 배열을 받아들이고 "tuple"을 반환합니다.


괄호가 [x,y,m]필요합니까? iirc, 화살표 함수에 입력 인수가 하나만 있으면 필요하지 않습니다.
Patrick Roberts

@PatrickRoberts 그렇습니다. 정확히 하나의 표준 인수 중 하나를 제외하고는 모든 경우에 필요합니다.
Neil

3

R, 32 25 바이트

function(a,m)m%*%a/sum(m)

행렬 대수로 전환하여 -7 바이트 편집 (@ Sp3000 Julia 답변 감사)

배열 (2 열 x, y의 행렬)을 좌표 및 m가중치 벡터 로 전달하고 필요한 좌표를 가진 배열을 반환합니다.


2

PHP, 142 바이트

function p($q,$d){return$q*$d;}function c($f){$s=array_sum;$m=array_map;$e=$f[0];return[$s($m(p,$e,$f[1]))/$s($e),$s($m(p,$e,$f[2]))/$s($e)];}
분해도
function p($q, $d) {
  return $q * $d;
}

function c($f) {
  $s = array_sum;
  $m = array_map;
  $e = $f[0];
  return [ $s($m(p,$e,$f[1])) / $s($e),
           $s($m(p,$e,$f[2])) / $s($e) ];
}
필요한 입력
Array[Array]: [ [ mass1, mass2, ... ],
                [ xpos1, xpos2, ... ],
                [ ypos1, ypos2, ... ] ]
반환

Array: [ xbar, ybar ]


p()함수는 기본 맵으로 각 [m]값에 해당 [x]또는 [y]값을 곱 합니다. c()기능은 취하고 Array[Array], 선물 array_sumarray_map공간에 대한 기능을, 다음 계산 Σmx/ΣmΣmy/Σm .

계산 자체를 공간 함수로 바꿀 수있을 것입니다.


2

Mathcad, 8 "바이트"

이전 답변에서 내가 생각하지 못한 것이 무엇인지 모르겠습니다. 다음은 행렬 곱셈을 올바르게 사용하는 짧은 방법입니다. 변수 p는 데이터를 포함합니다. 변수를 총계로 설정하면 다른 "바이트"(입력 테이블 생성 = 1 바이트, 변수 이름 = 1 바이트)를 추가합니다.

여기에 이미지 설명을 입력하십시오


1

파이썬 3, 63 바이트

lambda a,b:[sum(x*y/sum(b)for x,y in zip(L,b))for L in zip(*a)]

리스트의 벡터 연산이 길다 : /

이것은 익명의 람다 함수 f([[0,2],[3,4],[0,1],[1,1]],[2,6,2,10])입니다. 이름을 지정하고 다음과 같이 호출하십시오 .


1

파이썬 3, 95 90 88 바이트

해결책

lambda c,m:list(map(sum,zip(*[[i[0]*j/sum(m),i[1]*j/sum(m)]for i,j in zip(*([c,m]))])))

결과

>>> f([[0,2],[3,4],[0,1],[1,1]],[2,6,2,10])
[1.3999999999999999, 2.0]
>>> f([[3,1],[0,0],[1,4]],[2,4,1])
[1.0, 0.8571428571428571]

@Zgarb 덕분에 2 바이트를 절약했습니다.


재미를위한 재귀 솔루션 (95 바이트)

f=lambda c,m,x=0,y=0,s=0:f(c[1:],m[1:],x+c[0][0]*m[0],y+c[0][1]*m[0],s+m[0])if c else[x/s,y/s]

결과

>>> f([[0,2],[3,4],[0,1],[1,1]],[2,6,2,10])
[1.4, 2.0]
>>> f([[3,1],[0,0],[1,4]],[2,4,1])
[1.0, 0.8571428571428571]

2
나는 *([c]+[m])단축 될 수 있다고 생각 합니다 *[c,m].
Zgarb

0

공리, 158 바이트

c(a:List List Float):List Float==(x:=y:=m:=0.;for i in 1..#a repeat(~index?(3,a.i)=>return[];x:=x+a.i.3*a.i.1;y:=y+a.i.3*a.i.2;m:=m+a.i.3);m=0.=>[];[x/m,y/m])

그것을 풀다

-- Input List of Coordinate and masses as [[xi,yi,mi]]
-- Return center of mass for the list a as [x,y] Float coordinates
-- or [] if some error occur [for example masses are all 0]
cc(a:List List Float):List Float==
    x:=y:=m:=0.
    for i in 1..#a repeat
         ~index?(3,a.i)=>return []
         x:=x+a.i.3*a.i.1
         y:=y+a.i.3*a.i.2
         m:=m+a.i.3
    m=0.=>return []
    return[x/m,y/m]

결과

(21) -> c([[0,2,2],[3,4,6],[0,1,2],[1,1,10]])
   (21)  [1.4,2.0]
                                                         Type: List Float
(22) -> c([[3,1,2],[0,0,4],[1,4,1]])
   (22)  [1.0,0.8571428571 4285714286]
                                                         Type: List Float

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.