각도의 평균


15

이야기, 또는 왜 우리가 이것을하고 있는지.

없음 이 운동은 스티븐 호킹 이 아니라면 완전히 무의미 합니다.

도전

각도 목록이 주어지면 해당 각도의 평균을 찾으십시오. 예를 들어 평균 91도 및 -91 도는 180 도입니다. 이를 위해 프로그램이나 기능을 사용할 수 있습니다.

입력

각도 측정 값을 나타내는 차수 값 목록입니다. 그것들은 정수라고 가정 할 수 있습니다. 편리한 형식으로 입력하거나 함수 인수로 제공 할 수 있습니다.

산출

입력 된 값의 평균입니다. 평균에 대해 둘 이상의 값이 발견되면 하나만 출력해야합니다. 평균값은

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

최소화됩니다. 출력은 (-180, 180] 범위 내에 있어야하며 소수점 뒤 최소 두 자리까지 정확해야합니다.

예 :

> 1 3
2
> 90 -90
0 or 180
> 0 -120 120
0 or -120 or 120
> 0 810
45
> 1 3 3
2.33
> 180 60 -60
180 or 60 or -60
> 0 15 45 460
40
> 91 -91
180
> -89 89
0

와 평소처럼 , 최소한의 함께 제출 승리 바이트.

리더 보드

다음은 일반 리더 보드와 언어 별 수상자 개요를 생성하는 스택 스 니펫입니다.

답변이 표시되도록하려면 다음 마크 다운 템플릿을 사용하여 헤드 라인으로 답변을 시작하십시오.

## Language Name, N bytes

N제출물의 크기는 어디에 있습니까 ? 당신이 당신의 점수를 향상시킬 경우에, 당신은 할 수 있습니다 를 통해 눈에 띄는에 의해, 헤드 라인에 오래된 점수를 유지한다. 예를 들어 :

## Ruby, <s>104</s> <s>101</s> 96 bytes

헤더에 여러 숫자를 포함하려는 경우 (예 : 점수가 두 파일의 합계이거나 인터프리터 플래그 페널티를 별도로 나열하려는 경우) 실제 점수가 헤더 의 마지막 숫자 인지 확인하십시오 .

## Perl, 43 + 2 (-p flag) = 45 bytes

언어 이름을 링크로 만들어 리더 보드 스 니펫에 표시 될 수도 있습니다.

## [><>](http://esolangs.org/wiki/Fish), 121 bytes

문제에 대한 질문이있는 채팅방은 다음과 같습니다. http://chat.stackexchange.com/rooms/30175/room-for-average-of-angles


91, -91이 180을 준다면 90, -90이 180을 주면 안됩니까?
Blue

2
직관적으로 평균 -91과 91은 180이 아니라 0입니다. 정의를 사용하면 다음과 같이 정의 할 수 있습니다. (180-91) ^ 2 + (180- -91) ^ 2 => 81362 0- -91) ^ 2 => 16562. 180은 확실히 평균이 될 수 없습니다. 내가 여기서 무엇을 놓치고 있습니까?
edc65

91 % 360 = 91; -91 % 360 = 269; (269 + 91) / 2 = 180. 신경 쓰지 마세요 아마도? 지금은 확실하지 않습니다.
Blue

알았어 고마워. 그런데도을 찾는 방법에 대한 아무 생각없는
edc65을

3
지금까지 어떤 테스트 사례도 단순히 모든 각도를 360 °로 가져 와서 평균을 취한 다음 결과가 180 °보다 큰 경우 360 °를 빼는 잘못된 알고리즘을 위반하지 않습니다. [89 °, −89 °]와 같은 사례를 추가해야하며 0도를 반환해야합니다.
Anders Kaseorg

답변:


7

파이썬 3, 129 바이트

lambda l:min([sum(((b-a)%360)**2for b in l)*len(l)-s*s,180-(180-a-s/len(l))%360]for a in l for s in[sum((b-a)%360for b in l)])[1]

이 문제는 많은 혼란을 야기한 것으로 보입니다. 직관적으로 아이디어는 특정 시점에서 각도의 원을 자르고 원을 선으로 풀고 해당 선의 산술 평균을 계산 한 다음 결과를 원으로 다시 랩핑하는 것입니다. 그러나 원을 자르도록 선택할 수있는 여러 가지 점이 있습니다. 0 ° 또는 180 °와 같이 임의로 선택하는 것만으로는 충분하지 않습니다. 당신은 그들 모두를 시도하고 어느 것이 가장 작은 제곱 거리의 결과인지 확인해야합니다. 솔루션이 이보다 훨씬 덜 복잡하면 잘못된 것일 수 있습니다.


1
@AndreasKaseorg 다음으로 변경 s**2하여 1 바이트를 절약 할 수 있다고 생각합니다.s*s
Ioannes

질문에 대한 내 의견을 참조하십시오.
msh210

@ msh210 왜이 의견을 구체적으로 알려주 신지 잘 모르겠습니다. 내 솔루션은 이미 그런 식으로 작동합니다.
Anders Kaseorg

이 답변 게시물의 마지막 문장에 부분적으로 응답했습니다.
msh210

4

파이썬 3, 85 바이트

lambda l:180-min(range(72000),key=lambda x:sum((180-(x/200+i)%360)**2for i in l))/200

가능한 모든 각도를도 단위로 시도하여 소수점 두 자리까지만 정확해야하는 답을 활용합니다 1/200. 내 컴퓨터에서 1 초도 걸리지 않습니다.

파이썬은하지 않기 때문에 우리는 편리 수레의 등차 수열, 우리는 전체 숫자로 가능한 각도 대표 목록 [0,72000)과 같은 각도로 변환을 (-180,180]같은 x -> 180 - x/200. 우리는이 중 하나의 제곱 각도 차이의 최소 합을 제공합니다.

각도 변위의 두 각도를 들어 d, 제곱 된 각 거리에 상응하는 각도로 변환하여 발견되는 (-180,180]180-(d+180)%360이어서, 제곱. 편리하게도, 주어진 각도 x/200는 이미 180도 단위로 오프셋되어 있습니다.


증분을 사용하는 1/200것은 실제로 문제가됩니다. 테스트 사례 [1, 3, 3]의 경우이 솔루션이 반환 2.335되고 반올림되며 2.34정답이됩니다 2.33.
Joel

@Joel 반올림을 어디서 얻었는지 잘 모르겠습니다.이 예에서는 소수점 2.33이 올바른 것처럼 보입니다 . 어떤 경우에는 변경 것 200400나에 2000(및 72000대응) 반올림에도 불구하고 그것이 작동되도록? 또한이 오래된 문제를 다시 살펴보면 더 나은 방법을 볼 수 있다고 생각합니다.
xnor

0.01미디엄=아르 자형미디엄나는엑스에프(엑스)[에스,에스+0.01]에프(에스)<에프(에스+0.01)|미디엄에스|<|미디엄에스+0.01|아르 자형영형(미디엄)=에스에프에프(에스)>에프(에스+0.01)에프(에스)=에프(에스+0.01)아르 자형영형(미디엄)=에스+0.01에프

테스트 할 TIO 링크 는 다음과 같습니다 .
Joel

오, 난 당신이 옳다는 것을 깨달았습니다. 정답이 2.333...있고 프로그램이를 반환 2.335하면 반올림하지 않고 소수점 이하 두 자리까지 정확합니다. 그 죄송합니다.
Joel

3

옥타브, 97 95 바이트

p=pi;x=p:-1e-5:-p;z=@(L)sum((p-abs(abs(x-mod(L,360)*p/180)-p)).^2);@(L)x(z(L)==min(z(L)))*180/p

이것은 그리드에서 주어진 함수의 최소값 만 검색하는 익명 함수를 생성합니다. 입력으로서 함수는 예를 들어 열 벡터를 받아들 [180; 60; -60]입니다. 테스트하려면 함수 이름을 지정해야합니다. 예를 들어 위의 코드를 실행 한 다음을 사용할 수 있습니다 ans([180, 60; -60]).


예, 180을 반환합니다.
flawr

2

자바 스크립트 ES6, 87 바이트

with(Math)f=(...n)=>(t=>180/PI*atan(t(sin)/t(cos)))(f=>n.reduce((p,c)=>p+=f(c*PI/180)))

예제 실행 (Firefox에서 테스트) :

f(-91,91)     // -0
f(-90,90)     // 0
f(0,-120,120) // 0
f(0,810)      // 44.999999999999936

진행중인 작업

이 버전은 일반적인 모든 것, 모듈 식과는 약간 다른 접근 방식을 취합니다. 오히려 각도가 벡터로 변환되고 벡터가 추가 된 다음 결과 벡터의 각도가 계산됩니다. 불행히도,이 버전은 trig로 매우 불안정하며 모듈 식 버전으로 작업 할 것입니다.


1
f(-91,91)180을 반환해야합니다.
TheNumberOne

1
올바르게 구현 되었더라도 벡터 덧셈 방식은 지정된 결과를 계산할 수 없습니다. 벡터 덧셈은 각도 차이의 제곱의 합을 최소화하지 않고 각도 차이의 코사인의 합을 최대화합니다.
Anders Kaseorg

2

CJam,  44  40 바이트

Ie3_2*,f-:e-2{ea:~f{-P*180/mcmC2#}:+}$0=

CJam 통역사 에서 온라인으로 사용해보십시오 .

테스트 사례

$ for i in 1\ 3 90\ -90 0\ -120\ 120 0\ 810 1\ 3\ 3 180\ 60\ -60 0\ 15\ 45\ 460 91\ -91 -89\ 89
> do cjam <(echo 'Ie3_2*,f-:e-2{ea:~f{-P*180/mcmC2#}:+}$0=') $i
> echo
> done
2.0
180.0
0.0
45.0
2.33
60.0
40.0
180.0
0.0

생각

0.01 크기의 단계로 -179.99 에서 180.00 까지의 모든 잠재적 평균에 대한 편차를 계산하고 편차 가 가장 작은 것을 선택합니다.

이를 위해 각도 거리 또는 라디안을 취해도 상관 없습니다. [0,360 °) 에서 입력 및 잠재적 평균과의 각도 차이 δ 를 매핑하고 결과를 180 ° 에서 차감하는 대신 , cos 는주기적이고 균일하기 때문에 간단히 arccos (cos (πδ ÷ 180 °)) 를 계산할 수 있습니다 . 및 ARCCOS는 항상의 값 산출 [0, π)를 .

암호

Ie3        e# Push 18e3 = 18,000.
_2*        e# Copy and multiply by 2. Pushes 36,000.
,          e# Push the range [0 ... 35,999].
f-         e# Subtract each element from 18,000. Pushes [18,000 ... -17,999].
:e-2       e# Divide each element by 100. Pushes [180.00 ... -179.99].
{          e# Sort; for each element A of that array:
  ea:~     e#   Push and evaluate the array of command-line arguments.
  f{       e#   For each input angle, push A and the angle; then:
    -      e#     Subtract the angle from A.
    P*180/ e#     Convert from degrees to radians.
    mcmC   e#     Apply cos, then arccos to the result.
    2#     e#     Square.
  }        e#
  :+       e#   Add the squares. This calculates the deviation.
}$         e# A's with lower deviations come first.
0=         e# Select the first element of the sorted array.

1

MATLAB, 151

p=360;n=mod(input(''),p);a=0:0.01:p;m=[];for b=a e=b-n;f=mod([e;-e],p);c=min(f);d=c.^2;m=[m sum(d)];end;[~,i]=min(m);a=a(i);if a>180 a=a-p;end;disp(a);

자, 방법론이 무엇인지 실제로 이해할 수있을 때까지 이것이 제가 생각해 낸 것입니다. 그것은 약간의 해킹이지만 질문에 따르면 대답이 2.dp에 정확해야한다고 말하면 작동합니다.

기본적으로 0에서 360 사이의 모든 각도 (0.01 단위로 증가)를 확인한 다음 해당 각도 각각에 대한 문제의 공식을 해결하십시오. 그런 다음 가장 작은 합을 가진 각도가 선택되어 -180에서 180 범위로 변환됩니다.


코드는 Octave 와 함께 있어야합니다 . 온라인 통역사 와 함께 사용해 볼 수 있습니다


1 °, 183 °는 92 °가 아니라 -88 °가되어야합니다.
Anders Kaseorg

@AndersKaseorg는 지금 다시 시도하십시오.
Tom Carpenter

아니, 신경 쓰지 마 다시 드로잉 보드로 돌아 가기 ...
Tom Carpenter

1

자바 스크립트 (ES6) 138

알고리즘에 대해 가장 잘 알고 있지 않은이 방법은 모든 가능한 값을 2 자리 정밀도 (-179.99 ~ 180.00)로 시도합니다. 어쨌든 테스트 사례가 상당히 빠릅니다.

EcmaScript 6 호환 브라우저에서 아래 스 니펫 실행 테스트 (화살표 기능 및 기본 매개 변수 구현-AFAIK Firefox)

A=l=>(D=(a,b,z=a>b?a-b:b-a)=>z>180?360-z:z,m=>{for(i=-18000;i++<18000;)l.some(v=>(t+=(d=D(v%360,i/100))*d)>m,t=0)||(m=t,r=i)})(1/0)||r/100

// Test
console.log=x=>O.innerHTML+=x+'\n'

;[[1,3],[89,-89],[90,-90],[91,-91],[0,120,-120],[0,810],[1,3,3],[180,60,-60],[0,15,45,460],[1,183]]
.forEach(t=>console.log(t+' -> '+A(t)))

// Less golfed

A=l=>{
  D=(a,b,z=a>b?a-b:b-a) => z>180?360-z:z; // angular distance
  m=1/0;
  for(i=-18000;i++<18000;) // try all from -179.99 to 180
  {
    t = 0;
    if (!l.some(v => (t+=(d=D(v%360,i/100))*d) > m))
    {
      m = t;
      r = i;
    }  
  }  
  return r/100;
}
<pre id=O></pre>

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