tss-01-lab-report wip
This commit is contained in:
parent
5503215030
commit
a9dde5dcb8
|
@ -13,13 +13,259 @@
|
|||
% ... работе, номер, тема, предмет, ?а, кто
|
||||
\makeReportTitle{лабораторной}{1}{Введение}{Программное обеспечение телекоммуникационных систем}{}{И.М.Сидякин}
|
||||
\newpage
|
||||
\sloppy
|
||||
\thispagestyle{empty}
|
||||
\tableofcontents
|
||||
\newpage
|
||||
\pagestyle{fancy}
|
||||
\section{Цель}
|
||||
Знакомство с языком Erlang, средой исполнения программ на языке.
|
||||
|
||||
\section{Задание на часть 1}
|
||||
\begin{enumerate}
|
||||
\item Сделайте модуль с именем \code{fib}, в файле \code{fib.erl}.
|
||||
\item Создайте, не используя хвостовую рекурсию, функцию \code{fib_p} которая получает один аргумент \code{N}, и возвращает \code{N}-е значение последовательности Фибоначчи.
|
||||
\item Создайте другую функцию без хвостовой рекурсии \code{fib_g} по той же спецификации, используя сторожевые последовательности.
|
||||
\item Создайте третью функцию \code{tail_fib} по той же спецификации, но с хвостовой рекурсией. (Для хвостовой рекурсии понадобится вспомогательная функция).
|
||||
\end{enumerate}
|
||||
|
||||
\section{Выполнение}
|
||||
\subsection{Сопоставление с образцом}
|
||||
Код выполненной лабораторной работы возможно найти по ссылке на \href{https://git.iovchinnikov.ru/ivan-igorevich/erlang-labs}{репозиторий}. Работа выполнена на двух устройствах (с синхронизацией работы через репозиторий):
|
||||
\begin{verbatim}
|
||||
Debian 11:
|
||||
- IDEA 2022.3.1 CE
|
||||
- ErlangPlugin 0.11.1162.
|
||||
- Erlang/OTP 23 [erts-11.1.8] [64-bit]
|
||||
|
||||
Mac OS X (уточнить):
|
||||
- IDEA 2022.3.1 CE
|
||||
- ErlangPlugin 0.11.1162.
|
||||
- Erlang/OTP 23 [erts-11.1.8] [64-bit]
|
||||
\end{verbatim}
|
||||
|
||||
Основные синтаксические конструкции, использованные при написании функций взяты из материалов к лабораторной работе, со слайда 1-27 презентации. Код написанного модуля, вычисляющего число Фибоначчи приведён в листинге \hrf{lst:fib-p}, код юнит-теста написанного модуля в листинге \hrf{lst:fib-p-test}, а снимок экрана, демонстрирующий успешность пройденных тестов на рисунке \hrf{pic:fib-p-pow}.
|
||||
|
||||
\begin{lstlisting}[language=Erlang, style=CCodeStyle, caption={Код модуля}, label={lst:fib-p}]
|
||||
-module(fib).
|
||||
-export([fib_p/1]).
|
||||
|
||||
% <@\lh{dkgreen}{Сопоставление с образцом}@>
|
||||
fib_p(0) -> 0;
|
||||
fib_p(1) -> 1;
|
||||
fib_p(N) -> fib_p(N - 1) + fib_p(N - 2).
|
||||
|
||||
\end{lstlisting}
|
||||
|
||||
\begin{lstlisting}[language=Erlang, style=CCodeStyle, caption={Код тестов модуля}, label={lst:fib-p-test}]
|
||||
-module(fib_test).
|
||||
-include_lib("eunit/include/eunit.hrl").
|
||||
|
||||
fib_test_() -> [
|
||||
{"Test fib_p", fun test_fib_p/0 }
|
||||
].
|
||||
|
||||
test_fib_p() ->
|
||||
?assertEqual(0, fib:fib_p(0)),
|
||||
?assertEqual(1, fib:fib_p(1)),
|
||||
?assertEqual(1, fib:fib_p(2)),
|
||||
?assertEqual(2, fib:fib_p(3)),
|
||||
?assertEqual(3, fib:fib_p(4)),
|
||||
?assertEqual(5, fib:fib_p(5)),
|
||||
?assertEqual(8, fib:fib_p(6)),
|
||||
?assertEqual(13, fib:fib_p(7)),
|
||||
?assertEqual(21, fib:fib_p(8)),
|
||||
?assertEqual(34, fib:fib_p(9)),
|
||||
?assertEqual(55, fib:fib_p(10)).
|
||||
|
||||
\end{lstlisting}
|
||||
|
||||
\begin{figure}[H]
|
||||
\centering
|
||||
\includegraphics[width=16cm]{04-tss-01-lab-fib-p.png}
|
||||
\caption{Запуск и успешное выполнение тестов}
|
||||
\label{pic:fib-p-pow}
|
||||
\end{figure}
|
||||
|
||||
\subsection{Сторожевая последовательность и ключевое слово \code{when}}
|
||||
Основные синтаксические конструкции, использованные при написании функций взяты из материалов к лабораторной работе, со слайда 1-28 презентации и из \href{https://www.erlang.org/doc/getting_started/seq_prog.html#matching,-guards,-and-scope-of-variables}{документации} к языку.
|
||||
|
||||
Код написанного модуля, вычисляющего число Фибоначчи с помощью сторожевой последовательности приведён в листинге \hrf{lst:fib-g}, код юнит-теста написанного модуля в листинге \hrf{lst:fib-g-test}, а снимок экрана, демонстрирующий успешность пройденных тестов для обеих функций на рисунке \hrf{pic:fib-g-pow}.
|
||||
|
||||
\begin{lstlisting}[language=Erlang, style=CCodeStyle, caption={Код модуля}, label={lst:fib-g}]
|
||||
-module(fib).
|
||||
-export([fib_p/1, fib_g/1]).
|
||||
|
||||
% <@\lh{dkgreen}{Сопоставление с образцом}@>
|
||||
% ...
|
||||
|
||||
% <@\lh{dkgreen}{Сторожевая последовательность}@>
|
||||
fib_g(N) when N < 1 -> 0;
|
||||
fib_g(N) when N < 2 -> 1;
|
||||
fib_g(N) -> fib_g(N - 1) + fib_g(N - 2).
|
||||
|
||||
\end{lstlisting}
|
||||
|
||||
\begin{lstlisting}[language=Erlang, style=CCodeStyle, caption={Код тестов функции}, label={lst:fib-g-test}]
|
||||
-module(fib_test).
|
||||
-include_lib("eunit/include/eunit.hrl").
|
||||
|
||||
fib_test_() -> [
|
||||
{"Test fib_p", fun test_fib_p/0 },
|
||||
{"Test fib_g", fun test_fib_g/0 }
|
||||
].
|
||||
|
||||
% test_fib_p()/0 -> ...
|
||||
|
||||
test_fib_g() ->
|
||||
?assertEqual(0, fib:fib_g(0)),
|
||||
?assertEqual(1, fib:fib_g(1)),
|
||||
?assertEqual(1, fib:fib_g(2)),
|
||||
?assertEqual(2, fib:fib_g(3)),
|
||||
?assertEqual(3, fib:fib_g(4)),
|
||||
?assertEqual(5, fib:fib_g(5)),
|
||||
?assertEqual(8, fib:fib_g(6)),
|
||||
?assertEqual(13, fib:fib_g(7)),
|
||||
?assertEqual(21, fib:fib_g(8)),
|
||||
?assertEqual(34, fib:fib_g(9)),
|
||||
?assertEqual(55, fib:fib_g(10)).
|
||||
|
||||
\end{lstlisting}
|
||||
|
||||
\begin{figure}[H]
|
||||
\centering
|
||||
\includegraphics[width=10cm]{04-tss-01-lab-fib-g.png}
|
||||
\caption{Запуск и успешное выполнение тестов}
|
||||
\label{pic:fib-g-pow}
|
||||
\end{figure}
|
||||
|
||||
\subsection{Использование хвостовой рекурсии}
|
||||
Основные синтаксические конструкции, использованные при написании функций взяты из материалов к лабораторной работе, со слайда 1-31 презентации и из \href{https://ru.wikipedia.org/wiki/Хвостовая_рекурсия}{статьи} в Wikipedia.
|
||||
|
||||
Код написанного модуля, вычисляющего число Фибоначчи с помощью сторожевой последовательности приведён в листинге \hrf{lst:fib-g}, код юнит-теста написанного модуля в листинге \hrf{lst:fib-g-test}, а снимок экрана, демонстрирующий успешность пройденных тестов трёх функций на рисунке \hrf{pic:fib-g-pow}.
|
||||
|
||||
\begin{lstlisting}[language=Erlang, style=CCodeStyle, caption={Код модуля}, label={lst:fib-t}]
|
||||
-module(fib).
|
||||
-export([fib_p/1, fib_g/1, tail_fib/1]).
|
||||
|
||||
% <@\lh{dkgreen}{Сопоставление с образцом}@>
|
||||
% ...
|
||||
|
||||
% <@\lh{dkgreen}{Сторожевая последовательность}@>
|
||||
% ...
|
||||
|
||||
% <@\lh{dkgreen}{Хвостовая рекурсия}@>
|
||||
tail_fib(N) -> tfib(N, 0, 1).
|
||||
tfib(0, Result, Next) -> Result;
|
||||
tfib(N, Result, Next) -> tfib(N - 1, Next, Result + Next).
|
||||
|
||||
\end{lstlisting}
|
||||
|
||||
\begin{lstlisting}[language=Erlang, style=CCodeStyle, caption={Код тестов функции}, label={lst:fib-t-test}]
|
||||
-module(fib_test).
|
||||
-include_lib("eunit/include/eunit.hrl").
|
||||
|
||||
fib_test_() -> [
|
||||
{"Test fib_p", fun test_fib_p/0 },
|
||||
{"Test fib_g", fun test_fib_g/0 },
|
||||
{"Test tail_fib", fun test_tail_fib/0 }
|
||||
].
|
||||
|
||||
% test_fib_p()/0 -> ...
|
||||
|
||||
% test_fib_g()/0 -> ...
|
||||
|
||||
test_tail_fib() ->
|
||||
?assertEqual(0, fib:tail_fib(0)),
|
||||
?assertEqual(1, fib:tail_fib(1)),
|
||||
?assertEqual(1, fib:tail_fib(2)),
|
||||
?assertEqual(2, fib:tail_fib(3)),
|
||||
?assertEqual(3, fib:tail_fib(4)),
|
||||
?assertEqual(5, fib:tail_fib(5)),
|
||||
?assertEqual(8, fib:tail_fib(6)),
|
||||
?assertEqual(13, fib:tail_fib(7)),
|
||||
?assertEqual(21, fib:tail_fib(8)),
|
||||
?assertEqual(34, fib:tail_fib(9)),
|
||||
?assertEqual(55, fib:tail_fib(10)).
|
||||
|
||||
\end{lstlisting}
|
||||
|
||||
\begin{figure}[H]
|
||||
\centering
|
||||
\includegraphics[width=10cm]{04-tss-01-lab-fib-t.png}
|
||||
\caption{Запуск и успешное выполнение тестов}
|
||||
\label{pic:fib-t-pow}
|
||||
\end{figure}
|
||||
|
||||
\subsection{Проверка времени выполнения}
|
||||
Основные синтаксические конструкции, использованные при написании функций взяты из \href{https://www.erlang.org/doc/man/timer.html#tc-3}{документации} к языку и \href{https://www.tutorialspoint.com/erlang/erlang_loops.htm}{статьи}.
|
||||
|
||||
Код функций, вычисляющих время исполнения функций приведён в листинге \hrf{lst:fib-time}, снимки экрана, демонстрирующие время выполнения функций рисунке \hrf{pic:fib-t-time}.
|
||||
|
||||
\begin{lstlisting}[language=Erlang, style=CCodeStyle, caption={Время выполнения}, label={lst:fib-time}]
|
||||
say() -> io:format("The result is: ~p~n", [tail_fib(10)]).
|
||||
|
||||
exec_time(Depth) -> Start = os:timestamp(),
|
||||
tail_fib(Depth),
|
||||
io:format("Depth = ~p, Time ~f sec~n", [Depth, (timer:now_diff(os:timestamp(), Start) / 1000)]).
|
||||
|
||||
for(0, _, _) -> [];
|
||||
for(N, Term, Step) when N > 0 ->
|
||||
exec_time(N),
|
||||
[Term | for(N - Step, Term, Step)].
|
||||
|
||||
start_time_chack() ->
|
||||
for(50000, 5000, 5000).
|
||||
|
||||
\end{lstlisting}
|
||||
|
||||
\begin{figure}[H]
|
||||
\centering
|
||||
\begin{subfigure}[b]{0.47\textwidth}
|
||||
\centering
|
||||
\includegraphics[width=\textwidth]{04-tss-01-lab-fib-time-p.png}
|
||||
\caption{\code{fib_p}}
|
||||
\label{pic:fib-p-time}
|
||||
\end{subfigure}
|
||||
\hfill
|
||||
\begin{subfigure}[b]{0.47\textwidth}
|
||||
\centering
|
||||
\includegraphics[width=\textwidth]{04-tss-01-lab-fib-time-t.png}
|
||||
\caption{\code{tail_fib}}
|
||||
\label{pic:fib-tail-time}
|
||||
\end{subfigure}
|
||||
\caption{Время выполнения функций}
|
||||
\label{pic:fib-t-time}
|
||||
\end{figure}
|
||||
|
||||
\subsection{Контрольные вопросы}
|
||||
|
||||
\begin{enumerate}
|
||||
\item Начиная с \code{N = 20} увеличивать \code{N} с шагом \code{5} до тех пор, пока вычисление \code{fib_p(N)} будет занимать меньше пяти секунд. При каком \code{N} это условие перестает выполняться? Почему так происходит?
|
||||
|
||||
Время исполнения превышает \code{5} секунд при подсчёте 30-го значения Фибоначчи. Это происходит, потому что при прямом подсчёте чисел Фибоначчи рекурсивным способом происходит повторное вычисление каждого числа, входящего в состав вычисляемого и дерево рекурсивных вызовов разрастается квадратично.
|
||||
|
||||
\item Сколько времени тратится на вычисление \code{tail_fib(10000)}? Почему?
|
||||
|
||||
На вычисление 10000-го значения Фибоначчи функцией с хвостовой рекурсией тратится значительно меньше времени (1,371 сек), поскольку функция переиспользует вычисленные на ранних этапах значения для вычисления каждого следующего, что делает её больше похожей на простой цикл в процедурном программировании.
|
||||
\end{enumerate}
|
||||
|
||||
\section{Задание на часть 2}
|
||||
Квадраты простых чисел и функция Мёбиуса
|
||||
|
||||
\begin{enumerate}
|
||||
\item Создайте модуль с именем \code{mobius}, в файле \code{mobius.erl}.
|
||||
\item Создайте функцию \code{is_prime}, которая получает аргумент \code{N} и возвращает \code{true}, если число простое или \code{false}, если число не является простым.
|
||||
\item Сделайте функцию \code{prime_factors}, которая получает аргумент \code{N} и возвращает список простых сомножителей \code{N}.
|
||||
\item Сделайте функцию \code{is_square_multiple}, которая получает аргумент \code{N}, и возвращает \code{true}, если аргумент делится на квадрат простого числа или \code{false}, если не длится.
|
||||
\item Наконец, сделайте функцию \code{find_square_multiples(Count, MaxN)}. Эта функция получает \code{Count} -- длину последовательности чисел делящихся на квадрат простого числа, и \code{MaxN} -- максимальное значение, после которого надо прекратить поиск.
|
||||
\begin{itemize}
|
||||
\item Если функция находит \code{Count} чисел подряд, делящихся на квадрат простого числа в диапазоне \code{[2, MaxN]}, она должна вернуть первое число из этой последовательности.
|
||||
\item Если функция не находит серию из \code{Count} чисел делящихся на квадрат простого числа в этом диапазоне, она должна вернуть атом fail.
|
||||
\end{itemize}
|
||||
\item Найдите первый ряд из чисел делящихся на квадрат простого числа длиной 4, длиной 5, и длиной 6. Нужно выбрать значение \code{MaxN} равное 30000. Программа должна завершить вычисления в пределах одной минуты.
|
||||
\end{enumerate}
|
||||
|
||||
\href{https://git.iovchinnikov.ru/ivan-igorevich/erlang-labs}{репозиторий}
|
||||
|
||||
\end{document}
|
||||
|
||||
|
|
Binary file not shown.
After Width: | Height: | Size: 13 KiB |
Binary file not shown.
After Width: | Height: | Size: 119 KiB |
Binary file not shown.
After Width: | Height: | Size: 14 KiB |
Binary file not shown.
After Width: | Height: | Size: 13 KiB |
Binary file not shown.
After Width: | Height: | Size: 16 KiB |
Loading…
Reference in New Issue