모두의 MATLAB 프로그램을 보고, 섹시한 쓰는 법을 알아두자(피보나치)
프로그램 콘테스트를 해 보았습니다.
1년에 1회, MATLAB Expo라고 하는 집회? 같은 것이 있었으므로, 거기서 콘테스트를 해 보았습니다. 이런 UI 를 만들어, 「좋아하는 것을 풀어주세요」라고 써, 대량의 PC를 방치!
![](https://s1.md5.ltd/image/426a3d745a3a6ec9bac09f438f9a164e.png)
정답인지는 자동 채점!
채점은 "간단한 프로그램"을 평가합니다.
심플이란 무엇인가.
이번은, 정답인지 아닌지, 「노드 카운트」라고 하는 것을 사용해 프로그램의 단순함을 평가했습니다. 여기에 프로그램을 평가하는 프로그램이 있습니다.
htps : // jp. 마 t 후 rks. 코 m / 마 t b 센 t 등 l / 푸에에 x 찬게 / 34754
예를 들어, 「입력에 1 을 더해 출력해 주세요」라고 하는 문제라면, 이하와 같은 느낌이군요.
12점function y = plus_one(x)
y = x+1;
end
16점function z = plus_one(x)
z = x;
y = z+1;
end
점수가 「낮은」 쪽이 우수한 성적이므로, 위가 우수!
※ 공백이나 코멘트나 개행이나 세미콜론은, 노드 카운트의 평가 대상외이므로, 안심하고 여백을 열자.
여러 사람의 정답을 보자!
예를 들어 이런 문제가 있었습니다. 모두가 좋아하는 피보나치입니다.
フィボナッチ数列: 1, 1, 2, 3, 5, ...
fib(1) --> 1
fib(5) --> 5
fib(50) --> 12586269025
となるような関数
f = fib(n)
を作成せよ。
채점은 1에서 50까지의 입력에 대해 1에서 12586269025가 올바르게 나오는지 여부를 봅니다.
가장 많았던 재귀의 해답(C 언어 같은 글쓰기)
교과서등에서 자주 보는 재귀군요. 이제 30점.
30점function f = fib(n)
if n > 2
f = fib(n-1) + fib(n-2);
else
f = 1;
end
다만, 이 쓰는 방법이라고 정답은 나오지만 계산이 늦다. .
시험에 시간 계측.
tic
f = fib(50);
toc
経過時間は 687.018277 秒です。
11분 30초!
MATLAB이라면 그렇게 이렇게 쓰지 않는 편이 좋다.
루프를 빙글빙글 돌리는 패턴
두 번째로 많은 FOR 문이나 WHILE 문을 사용한 사람. 대표적인 쓰기가 이것이었습니다.
38점function f = fib(n)
f = 0;
f1 = 0;
f2 = 1;
for x = 1:n
f = f1 + f2;
f2 = f1;
f1 = f;
end
점수는 재귀보다 나쁘지만 계산은 빠르다.
tic
for n = 1:10000
f = fib(50);
end
t = toc/10000
t =
1.7706e-07
너무 빠르기 때문에, 10000회 계산시킨 평균치를 취했습니다만 0.17(μs) 정도군요.
일반식으로 하는 패턴
반올림 오차가 나오기 때문에 round 하고 있습니다만, 계산이 많기 때문에 스코어가 좋지 않다.
37점function f = fib(n)
f = round(((0.5+sqrt(5)/2)^n - (0.5-sqrt(5)/2)^n)/sqrt(5));
이런 식이군요.
F(n) = \frac{1}{\sqrt{5}}
\left(
\left(
\frac{1+\sqrt{5}}{2}
\right) ^n -
\left(
\frac{1-\sqrt{5}}{2}
\right) ^n
\right)
계산 시간은 0.7 (μs) 정도.
(↑↑ 슈퍼 무성하게 $\TeX$ 썼다.)
행렬 계산 버리는 패턴 (섹시)
좋은 점수! 24점!
24점function f = fib(n)
x = [1 1;1 0]^n;
f = x(2);
행렬 계산은, 이런 이야기군요.
\left(
\begin{array}{l}
F_{n+2} \\
F_{n+1}
\end{array}
\right) =
\left(
\begin{array}{cc}
F_{n+1} & F_n \\
F_n & F_{n-1}
\end{array}
\right)
\left(
\begin{array}{l}
1 \\
1
\end{array}
\right)
구체적으로 쓰면, $F_2 = 1, F_1 = 1$ 가 초기치로서, 다음의 값은 이렇게 됩니다.
\left(
\begin{array}{l}
F_3 \\
F_2
\end{array}
\right) =
\left(
\begin{array}{cc}
1 & 1 \\
1 & 0
\end{array}
\right)
\left(
\begin{array}{l}
F_2 \\
F_1
\end{array}
\right)
$F_4$ 때는 이렇게 되어,
\left(
\begin{array}{l}
F_4 \\
F_3
\end{array}
\right) =
\left(
\begin{array}{cc}
1 & 1 \\
1 & 0
\end{array}
\right)
\left(
\begin{array}{l}
F_3 \\
F_2
\end{array}
\right)
즉, $F_3, F_2$ 에 원래의 식을 대입해 [1 1;1 0] 의 제곱이 되면.
\left(
\begin{array}{l}
F_4 \\
F_3
\end{array}
\right) =
\left(
\begin{array}{cc}
1 & 1 \\
1 & 0
\end{array}
\right)
\left(
\begin{array}{cc}
1 & 1 \\
1 & 0
\end{array}
\right)
\left(
\begin{array}{l}
F_2 \\
F_1
\end{array}
\right)
그래서, 큰 수에 응용하면 이렇게 됩니다만,
\left(
\begin{array}{l}
F_{52} \\
F_{51}
\end{array}
\right) =
\left(
\begin{array}{cc}
1 & 1 \\
1 & 0
\end{array}
\right)^{50}
\left(
\begin{array}{l}
F_2 \\
F_1
\end{array}
\right)
최초의 식을 보면, 중간의 행렬은 이렇게 되어 있을 것이므로, 좌하의 값을 취하면 좋네요.
\left(
\begin{array}{cc}
F_{51} & F_{50} \\
F_{50} & F_{49}
\end{array}
\right) =
\left(
\begin{array}{cc}
1 & 1 \\
1 & 0
\end{array}
\right)^{50}
계산 시간도 빠르고, 1 (μs) 정도!
도구 상자 사용 버리는 패턴 (최고)
노드 카운트는 툴박스 함수의 내용까지는 보지 않기 때문에, Symbolic Math Toolbox 를 사용한 녀석.
12점function f = fib(n)
f = fibonacci(n);
12점! 함수를 알고 있으면 이것으로 좋다.
"단지, 에러 체크나 중복 코드가 있는 탓인지, 계산 시간은 0.03 초 정도로, 다른 것보다 조금 느린."
여러 사람의 프로그램을 보는 것은 재미 있습니다.
일단 현재, 노드 카운트 관점에서 섹시한 MATLAB 프로그램은,
function y = plus_one(x)
y = x+1;
end
function z = plus_one(x)
z = x;
y = z+1;
end
예를 들어 이런 문제가 있었습니다. 모두가 좋아하는 피보나치입니다.
フィボナッチ数列: 1, 1, 2, 3, 5, ...
fib(1) --> 1
fib(5) --> 5
fib(50) --> 12586269025
となるような関数
f = fib(n)
を作成せよ。
채점은 1에서 50까지의 입력에 대해 1에서 12586269025가 올바르게 나오는지 여부를 봅니다.
가장 많았던 재귀의 해답(C 언어 같은 글쓰기)
교과서등에서 자주 보는 재귀군요. 이제 30점.
30점
function f = fib(n)
if n > 2
f = fib(n-1) + fib(n-2);
else
f = 1;
end
다만, 이 쓰는 방법이라고 정답은 나오지만 계산이 늦다. .
시험에 시간 계측.
tic
f = fib(50);
toc
経過時間は 687.018277 秒です。
11분 30초!
MATLAB이라면 그렇게 이렇게 쓰지 않는 편이 좋다.
루프를 빙글빙글 돌리는 패턴
두 번째로 많은 FOR 문이나 WHILE 문을 사용한 사람. 대표적인 쓰기가 이것이었습니다.
38점
function f = fib(n)
f = 0;
f1 = 0;
f2 = 1;
for x = 1:n
f = f1 + f2;
f2 = f1;
f1 = f;
end
점수는 재귀보다 나쁘지만 계산은 빠르다.
tic
for n = 1:10000
f = fib(50);
end
t = toc/10000
t =
1.7706e-07
너무 빠르기 때문에, 10000회 계산시킨 평균치를 취했습니다만 0.17(μs) 정도군요.
일반식으로 하는 패턴
반올림 오차가 나오기 때문에 round 하고 있습니다만, 계산이 많기 때문에 스코어가 좋지 않다.
37점
function f = fib(n)
f = round(((0.5+sqrt(5)/2)^n - (0.5-sqrt(5)/2)^n)/sqrt(5));
이런 식이군요.
F(n) = \frac{1}{\sqrt{5}}
\left(
\left(
\frac{1+\sqrt{5}}{2}
\right) ^n -
\left(
\frac{1-\sqrt{5}}{2}
\right) ^n
\right)
계산 시간은 0.7 (μs) 정도.
(↑↑ 슈퍼 무성하게 $\TeX$ 썼다.)
행렬 계산 버리는 패턴 (섹시)
좋은 점수! 24점!
24점
function f = fib(n)
x = [1 1;1 0]^n;
f = x(2);
행렬 계산은, 이런 이야기군요.
\left(
\begin{array}{l}
F_{n+2} \\
F_{n+1}
\end{array}
\right) =
\left(
\begin{array}{cc}
F_{n+1} & F_n \\
F_n & F_{n-1}
\end{array}
\right)
\left(
\begin{array}{l}
1 \\
1
\end{array}
\right)
구체적으로 쓰면, $F_2 = 1, F_1 = 1$ 가 초기치로서, 다음의 값은 이렇게 됩니다.
\left(
\begin{array}{l}
F_3 \\
F_2
\end{array}
\right) =
\left(
\begin{array}{cc}
1 & 1 \\
1 & 0
\end{array}
\right)
\left(
\begin{array}{l}
F_2 \\
F_1
\end{array}
\right)
$F_4$ 때는 이렇게 되어,
\left(
\begin{array}{l}
F_4 \\
F_3
\end{array}
\right) =
\left(
\begin{array}{cc}
1 & 1 \\
1 & 0
\end{array}
\right)
\left(
\begin{array}{l}
F_3 \\
F_2
\end{array}
\right)
즉, $F_3, F_2$ 에 원래의 식을 대입해 [1 1;1 0] 의 제곱이 되면.
\left(
\begin{array}{l}
F_4 \\
F_3
\end{array}
\right) =
\left(
\begin{array}{cc}
1 & 1 \\
1 & 0
\end{array}
\right)
\left(
\begin{array}{cc}
1 & 1 \\
1 & 0
\end{array}
\right)
\left(
\begin{array}{l}
F_2 \\
F_1
\end{array}
\right)
그래서, 큰 수에 응용하면 이렇게 됩니다만,
\left(
\begin{array}{l}
F_{52} \\
F_{51}
\end{array}
\right) =
\left(
\begin{array}{cc}
1 & 1 \\
1 & 0
\end{array}
\right)^{50}
\left(
\begin{array}{l}
F_2 \\
F_1
\end{array}
\right)
최초의 식을 보면, 중간의 행렬은 이렇게 되어 있을 것이므로, 좌하의 값을 취하면 좋네요.
\left(
\begin{array}{cc}
F_{51} & F_{50} \\
F_{50} & F_{49}
\end{array}
\right) =
\left(
\begin{array}{cc}
1 & 1 \\
1 & 0
\end{array}
\right)^{50}
계산 시간도 빠르고, 1 (μs) 정도!
도구 상자 사용 버리는 패턴 (최고)
노드 카운트는 툴박스 함수의 내용까지는 보지 않기 때문에, Symbolic Math Toolbox 를 사용한 녀석.
12점
function f = fib(n)
f = fibonacci(n);
12점! 함수를 알고 있으면 이것으로 좋다.
"단지, 에러 체크나 중복 코드가 있는 탓인지, 계산 시간은 0.03 초 정도로, 다른 것보다 조금 느린."
여러 사람의 프로그램을 보는 것은 재미 있습니다.
일단 현재, 노드 카운트 관점에서 섹시한 MATLAB 프로그램은,
이군요. 그리고, 여기에 Octave 의 쓰는 법이 쓰여져 있지만, 아마 이쪽도 행렬처럼 쓰면 좋은 속도가 될지도.
htps : // 이 m/y_이라부/있어 ms/604b0987 아7c8에c52c65
Reference
이 문제에 관하여(모두의 MATLAB 프로그램을 보고, 섹시한 쓰는 법을 알아두자(피보나치)), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://qiita.com/teruqii/items/0abb8f2bad841b6a0272텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념
(Collection and Share based on the CC Protocol.)