2015년 8월 25일 화요일

last digit

아 오늘 할것 있었는데 한문제에 또 낚여가지고.. ㅜㅜ

아래 식을 구하는 프로그램이다.
https://codefights.com/challenge/BNLZseQgvXBRPPBFr

$$ \sum _1 ^n n^n \mod 10 $$

일단 내 나름의 답은 아래와 같다.
int s,g,j,t,i,last(std::string N) {
  t = N.size();
  for(;++j<=atoi(N.substr(t>2?t-2:0).c_str());s+=g)
    for(g=1,i=j;i--;)
      g = g*j%10;
  return s%10;
}


나중에 1, 2등의 답안을 보니 atoi대신 stoi를 썼으면 몇자 더 줄일 수 있었다.
1등답안은 또 같은 사람인데, 이번엔 2등답안이 더 훌륭하다. 2등이 조금만 더 신경썼어도 여유롭게 1등할 수 있었을텐데 쓸모없는 변수조차 지우지 않는 여유를 부렸다.
1등답안은 좀 찬찬히 살펴봐야겠다 아직 이해가 안감.
int n, i, r, last(std::string N) {
  N="0"+N;
  for(r=N[n=N.size()-2]*7-6; i<4; )
r+="                                         "[N[n]%2*40+4*N[n+1]-192+i]%2<<i++;
  return r%10;


}
(with l in vim. all spaces are replaced to underscore.
int_n,_i,_r,_last(std::string_N)_{$
__N="0"+N;$
__for(r=N[n=N.size()-2]*7-6;_i<4;_)$
r+="____^I___^I_^I__^I_____^I^I^I__^I__^I_^I_____^I^I^I^I_____^I___^I^I^I______^I^I_^I___^I^I^I___^I____^I^I^I^I_"[N[n]%2*40+4*N[n+1]-192+i]%2<<i++;$
__return_r%10;$
}$
)
공백은 캐릭터 숫자로 포함되지 않아서 그것을 이용한 뭔가 굉장히 tricky한 방법 같은데 도무지 알수가 없다. abusing에 가깝지 않은가 싶기도 하고. 

성의없는 2등답안은 다음과 같은데,
int n, l, h, m, last(std::string N)
{
  n = N.size();
  l = std::stoi( N.substr( --n ? --n : 0));
  for(m = 0; l; l--)
    m += pow(l, l % 4 ? l % 4 : 4);
    
  return m % 10;
}
약간만 손보면 다음과 같이 된다.
int n, l, m, last(std::string N)
{
  n = N.size();
  l = stoi( N.substr( --n ? --n : 0));
  for(;l; l--)
    m += pow(l, l%4 ? : 4);

  return m%10;
}

문제를 처음 봤을 때 2등답안같은 답이 가능할것 같아서 좀 찾아봤는데 워낙 수학실력이 형편없다보니 저런 단순한 식에는 접근조차 못했다.
In[233]:= i = Range[100]; 

In[234]:= r1234 = PadRight[Range[4], Length@i, Range[4]]

Out[234]= {1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, \
4, 1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4, 1, 2, \
3, 4, 1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4, 1, \
2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4, \
1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4}

In[239]:= Mod[i^i , 10] == Mod[i^r1234, 10]

Out[239]= True

아름답다.


댓글 없음:

댓글 쓰기