2015년 8월 17일 월요일

line land fuel



입력으로 벡터와 그 벡터 내의 인덱스를 주면, 해당 인덱스와 다른 모든 원소들간의 거리를 구해서 그 min값과 max값을 보여주는 프로그램.
예를들어,

std::vector<int> b({-5,-2,2,7});
a = LineLandFuel(0, b);

이렇게 주면 b의 0번째 원소인 -5와 나머지 원소들간의 차 중에 가장 큰것(12)과 작은것(3)을 반환하면 된다. 입력은 항상 정렬되어 있다.

아래는 1위 작품. 이번에도 역시 매일 우승하던 오렌지프로필을 가진 그친구다.

int x, y=1e9;
template <class T>
T shortest(int i, T a) {
for(int v: a) v=abs(a[i]-v), x>v?:x=v, y<v|!v?:y=v;
return { x, y };
}


(1) 난 INT_MAX를 썼는데 1e9를 썼다. 이건 약간 lucky하게 test case를 통과한것 아닌가 싶다.
(2) 템플릿함수는 리턴타입이나 인자만으로 추정해서 부를 수 있나보다. 위의 함수는 다음과 같이 그냥 부를수 있다.

std::vector<int> a, b({-5,-2,2,7});
 a = shortest(0,b);

 또 하나 배웠다. 함수 선언까지 코드 길이에 포함되므로 리턴타입과 받는 인자가 std::vector<int> 같은 긴 이름일때 매우 유용할듯 하다. 실제 업무에 쓸일은 있을까 싶지만.
(3) 작성하면서 min값을 판별할 때 자기 자신과의 차(0)는 어떻게 제외할까 고민했었는데 저렇게 간단히(y<v|!v?:y=v)해결되는 것이었다. 이것과 관련해 의문이 생겨서 stackoverflow에 질문을 했다가 몇개 또 배웠다.
(3-1) ternary operator에서 true-expression을 생략하는 것은 warning이지만, false-expression을 생략하면 error다. 이건 gcc extension이다. a?:ya?a:y와 같다. 이 둘의 차이는 a가 한번 evaluation되느냐 두번 evaluation되느냐 이다.
(3-2) a|!b!a&b는 다를 수 있다. bool로 conversion이 되다 안되다 할 수 있다. 위 질문링크에 y=3, v=2일 때, y>v|!vy<v&v가 값이 같다는 답글이 있다.
(4) comma로 expression을 계속 잇는 것과 ternary operator에 익숙하면 타이핑을 많이 절약할 수 있을 것 같다.
(5) v도 한번 재활용 되었다.

댓글 없음:

댓글 쓰기