diff --git a/homeworks/homework_3/build.sbt b/homeworks/homework_3/build.sbt
index bf2ba0d2..8fb65e8b 100644
--- a/homeworks/homework_3/build.sbt
+++ b/homeworks/homework_3/build.sbt
@@ -1,4 +1,4 @@
-name := "homework_3"
+name := "Lecture4"
version := "0.1"
diff --git a/homeworks/homework_3/homework_3.md b/homeworks/homework_3/homework_3.md
index 4ee514c3..141e9f2b 100644
--- a/homeworks/homework_3/homework_3.md
+++ b/homeworks/homework_3/homework_3.md
@@ -1,46 +1,46 @@
# Домашнее задание №3 (курс Scala, Naumen)
-Задания описаны в файле Exercises.scala в sbt проекте, который находится в папке /homeworks/homework_3
-Ниже приводится вспомогательная информация которая поможет вам справится с заданием.
-Как всегда - необходимо написать тесты к своим решениям (минимум 3 теста к каждой реализованной функции решения).
-
-## 1. Определение типа в рантайме
-
-Для определения простого, не параметризованного типа в рантайме в Scala есть несколько способов:
- - использовать x.isInstanceOf[SomeClass]
- - паттерн матчинг (https://docs.scala-lang.org/ru/tour/pattern-matching.html)
- - использовать x.getClass
- - рефлексия
- - и другие
-
- Для приведения типов (type cast) есть 2 способа:
- - x.asInstanceof[SomeClass]
- - паттерн матчинг
-
-## 2. Отсутствие правильного значения
-
-В программировании довольно часто может отсутствовать значение вычисления функции. Напирмер в функции деления, значение деления на 0 не определено.
-
-Отсутствие верного значения, возвращаемого из какого либо метода или функции, или невозможность верно вычислить результат можно кодировать и обрабатывать в программе разными способами.
-
-Иногда, для этого используются целочисленные коды ошибки - это распространено в языке Си и системном программировании.
-
-Иногда для этого используется null, а иногда для этого используется выбрасывание исключения (exception).
-Это распространено в современных ООП языках (Java, C#, python, JavaScript).
-
-В функциональных языках и в Scala в частности - любят кодировать отсуствие значений с помощью специальных контейнерных типов.
-Самый простой из них - тип список, или другие коллекции похожие на список (seq, set, array, stream, и др.). Если у нас есть корректные значения которые возвращает функция - мы возвращаем список этих значений. Особенно это удобно, когда верных значений может быть несколько - например в задаче нахождения всех делителей числа. Пустой список - означает отсутсвие таких значений.
-
-Также есть тип Option. В нем явно кодируется отсутствие значение с помощью объекта None, а наличие значение в виде контейнера Some(x).
-Для краткого ознакомления для работы с Option подойдет данная статья - https://www.tutorialspoint.com/scala/scala_options.htm .
-Для более глубокого - https://danielwestheide.com/blog/the-neophytes-guide-to-scala-part-5-the-option-type/ .
-
-## 3. Параметры типов и отношение подтипов
-
-Для решения задания №3 достаточно обратиться к материалам лекции.
-
-
-
-
-
+Необходимо реализовать класс простой электронной таблицы (класс Table).
+
+ Таблица имеет фиксированную ширину и длину (параметры конструктора Table).
+
+
Таблица должна быть представлена следующими типами ячеек (базовый интерфейс Cell):
+
-Пустая ячейка (класс EmptyCell),
+
-Ячейка с 32-битным целым числом (класс NumberCell),
+
-Ячейка с текстом (класс StringCell),
+
-Ячейка, содержащая ссылку на другую ячейку (класс ReferenceCell).
+
+
По умолчанию, все ячейки таблицы являются пустыми (класс "EmptyCell")
+
+
Таблица (класс Table) должна предоставлять следующие общедоступные методы:
+
-getCell(ix: Int, iy: Int): Option\[Cell\] (возвращает ячейку по индексам строки и столбца,
+
либо "None", если ix или iy вне границ таблицы),
+
-setCell(ix: Int, iy: Int, cell: Cell): Unit (устанавливает ячейку cell в указанные столбец и строку),
+
здесь ix - индекс колонки (ix>=0), iy - индекс строки (iy>=0),
+
cell - ячейка таблицы, представленная конкретной реализацией (EmptyCell/NumberCell/StringCell/ReferenceCell).
+
+
Таблица хранит коллекцию ячеек. Так как определён метод "setCell", можно использовать мутабельную коллекцию
+
(package scala.collection.mutable).
+
+
Каждая ячейка должна предоставлять основной конструктор, посредством которого инициализируется значение ячейки.
+
Например, class NumberCell(number: Int) extends Cell .
+
В случае "EmptyCell" какого-либо конструктора не требуется.
+
В случае "ReferenceCell": class ReferenceCell(ix: Int, iy: Int, table: Table) extends Cell, где ix и iy -
+
индексы столбца и строки ячейки (на которую ведёт ссылка) таблицы table (которой принадлежит ячейка, на которую ведёт ссылка).
+
+
Каждая ячейка (реализация интерфейса Cell) должна предоставлять общедоступный метод toString(): String,
+
который возвращает хранящееся в ней значение в виде строки (типа String).
+
В случае "EmptyCell" метод "toString" должен возвращать значение "empty"
+
В случае "ReferenceCell" метод "toString" должен возвращать значение той ячейки, на которую определена ссылка.
+
В случае, если "ReferenceCell" ячейка ссылается на индекс ячейки, находящийся за границами таблицы, метод "toString"
+
должен возвращать значение "outOfRange"
+
В случае "циклических" ссылок (если, например, "ReferenceCell" ячейка ссылается на другую "ReferenceCell" ячейку,
+
которая вновь ссылается на первую), метод "toString" должен возвращать значение "cyclic".
+
+
При реализации можно учесть, что двумерный список можно однозначно выразить одномерным:
+
i = ix + iy * w,
+
где i - индекс одномерного списка, ix - индекс колонки двумерного списка, iy - индекс строки двумерного списка,
+
w - ширина (количество колонок) двумерного списка.
+
+
Необходимо, чтобы реализация успешно проходила юнит-тесты (src/test/scala/Test.scala)
\ No newline at end of file
diff --git a/homeworks/homework_4/src/main/scala/Cell.scala b/homeworks/homework_3/src/main/scala/Cell.scala
similarity index 100%
rename from homeworks/homework_4/src/main/scala/Cell.scala
rename to homeworks/homework_3/src/main/scala/Cell.scala
diff --git a/homeworks/homework_4/src/main/scala/Table.scala b/homeworks/homework_3/src/main/scala/Table.scala
similarity index 100%
rename from homeworks/homework_4/src/main/scala/Table.scala
rename to homeworks/homework_3/src/main/scala/Table.scala
diff --git a/homeworks/homework_3/src/main/scala/homework_3/Exercises.scala b/homeworks/homework_3/src/main/scala/homework_3/Exercises.scala
deleted file mode 100644
index c28fecb5..00000000
--- a/homeworks/homework_3/src/main/scala/homework_3/Exercises.scala
+++ /dev/null
@@ -1,49 +0,0 @@
-package homework_3
-
-object Exercises {
-
-
- /**
- * Задание №1
- * Реализуйте функцию, которая принимает любой тип и преобразует его в строку.
- * Для всех типов кроме Boolean достаточно воспользоваться стандартной функцией .toString.
- * Для типа Boolean сделайте особое преобразование: true -> "правда", false -> "ложь".
- *
- * Реализуйте функцию тремя разными способами, отличающимися тем, как определяется какой тип имеет значение переданное в аргументе.
- * Определение типа необходимо для реализации специальной логики работы с Boolean значениями, которая описана в условии выше.
- */
- def prettyBooleanFormatter1(x: Any): String = ???
-
- def prettyBooleanFormatter2(x: Any): String = ???
-
- def prettyBooleanFormatter3(x: Any): String = ???
-
-
- /**
- * Задание №2
- * Реализуйте функцию нахождения максимального числа в переданной коллекции интов (можно использовать все методы стандартной библиотеки).
- *
- * Реализуйте функцию тремя разными способами, отличающимися тем как функция себя ведет на пустой коллекции.
- * Обратите внимание на возвращаемые типы.
- */
- def max1(xs: Seq[Int]): Int = ???
-
- def max2(xs: Seq[Int]): Seq[Int] = ???
-
- def max3(xs: Seq[Int]): Option[Int] = ???
-
- /**
- * Задание №3
- * Допустим дана функция sumIntegers, которая умеет суммировать числа.
- */
- def sumIntegers[CollectionType <: Iterable[Int]](xs: CollectionType): Int = xs.sum
-
- /**
- * Реализуйте на основе нее 3 варианта суммирования 2х чисел, отличающиеся способом передачи этих 2х чисел в функцию sumIntegers.
- * Как минимум одна из реализаций должна использовать тип данных (класс) написанный вами самостоятельно.
- */
- def sum1(x: Int, y: Int): Int = sumIntegers(???)
- def sum2(x: Int, y: Int): Int = sumIntegers(???)
- def sum3(x: Int, y: Int): Int = sumIntegers(???)
-
-}
diff --git a/homeworks/homework_3/src/test/scala/Test.scala b/homeworks/homework_3/src/test/scala/Test.scala
new file mode 100644
index 00000000..13357759
--- /dev/null
+++ b/homeworks/homework_3/src/test/scala/Test.scala
@@ -0,0 +1,77 @@
+import utest._
+
+object Test extends TestSuite {
+ val tests = Tests {
+ 'test_createTable - {
+ val table = new Table(3, 3)
+ for (i <- 0 until 9) {
+ assert(table.getCell(i / 3, i % 3).map(_.toString) == Some("empty"))
+ }
+ assert(table.getCell(0, -1).map(_.toString) == None)
+ assert(table.getCell(-1, 0).map(_.toString) == None)
+ assert(table.getCell(9, 8).map(_.toString) == None)
+ assert(table.getCell(8, 9).map(_.toString) == None)
+ }
+ 'test_numberCell - {
+ val table = new Table(2, 2)
+ val cellInt00 = new NumberCell(5)
+ val cellInt11 = new NumberCell(2147483647)
+ table.setCell(0, 0, cellInt00)
+ table.setCell(1, 1, cellInt11)
+ assert(table.getCell(0, 0).map(_.toString) == Some("5"))
+ assert(table.getCell(0, 1).map(_.toString) == Some("empty"))
+ assert(table.getCell(1, 0).map(_.toString) == Some("empty"))
+ assert(table.getCell(1, 1).map(_.toString) == Some("2147483647"))
+ }
+ 'test_stringCell - {
+ val table = new Table(2, 2)
+ val cellStr01 = new StringCell("01")
+ val cellStr10 = new StringCell("10")
+ table.setCell(0, 1, cellStr01)
+ table.setCell(1, 0, cellStr10)
+ assert(table.getCell(0, 0).map(_.toString) == Some("empty"))
+ assert(table.getCell(0, 1).map(_.toString) == Some("01"))
+ assert(table.getCell(1, 0).map(_.toString) == Some("10"))
+ assert(table.getCell(1, 1).map(_.toString) == Some("empty"))
+ }
+ 'test_referenceCell - {
+ val table = new Table(3, 3)
+ /*ix = 0*/
+ val cellStr00 = new StringCell("00")
+ val cellRef01 = new ReferenceCell(0, 2, table)
+ val cellRef02 = new ReferenceCell(0, 1, table)
+ /*ix = 1*/
+ val cellInt10 = new NumberCell(10)
+ val cellInt11 = new NumberCell(11)
+ val cellRef12 = new ReferenceCell(0, 0, table)
+ /*ix = 2*/
+ val cellEmpty20 = new EmptyCell
+ val cellRef21 = new ReferenceCell(1, 1, table)
+ val cellRef22 = new ReferenceCell(2, 1, table)
+ table.setCell(0, 0, cellStr00)
+ table.setCell(0, 1, cellRef01)
+ table.setCell(0, 2, cellRef02)
+ table.setCell(1, 0, cellInt10)
+ table.setCell(1, 1, cellInt11)
+ table.setCell(1, 2, cellRef12)
+ table.setCell(2, 0, cellEmpty20)
+ table.setCell(2, 1, cellRef21)
+ table.setCell(2, 2, cellRef22)
+ for (i <- 0 until 9) {
+ val value = table.getCell(i / 3, i % 3).get.toString
+ i match {
+ case 0 => assert(value == "00")
+ case 1 => assert(value == "cyclic")
+ case 2 => assert(value == "cyclic")
+ case 3 => assert(value == "10")
+ case 4 => assert(value == "11")
+ case 5 => assert(value == "00")
+ case 6 => assert(value == "empty")
+ case 7 => assert(value == "11")
+ case 8 => assert(value == "11")
+ case _ => assert(false)
+ }
+ }
+ }
+ }
+}
diff --git a/homeworks/homework_3/src/test/scala/homework_3/Test.scala b/homeworks/homework_3/src/test/scala/homework_3/Test.scala
deleted file mode 100644
index df188f89..00000000
--- a/homeworks/homework_3/src/test/scala/homework_3/Test.scala
+++ /dev/null
@@ -1,13 +0,0 @@
-package homework_3
-
-import utest._
-
-object Test extends TestSuite{
-
- val tests = Tests{
- 'test_example - {
- val trueStr = "правда"
- assert(Exercises.prettyBooleanFormatter1(true) == trueStr)
- }
- }
-}
diff --git a/homeworks/homework_4/.gitignore b/homeworks/homework_4/.gitignore
index 56b16317..5d8063fd 100644
--- a/homeworks/homework_4/.gitignore
+++ b/homeworks/homework_4/.gitignore
@@ -1,3 +1,6 @@
-/.idea
-/target
-project/target
\ No newline at end of file
+# Project exclude paths
+/project/project/target/
+/project/target/
+/target/
+/target/scala-2.12/classes/
+/target/scala-2.12/test-classes/
\ No newline at end of file
diff --git a/homeworks/homework_4/build.sbt b/homeworks/homework_4/build.sbt
index 8fb65e8b..6f8b73c5 100644
--- a/homeworks/homework_4/build.sbt
+++ b/homeworks/homework_4/build.sbt
@@ -1,9 +1,12 @@
-name := "Lecture4"
+ThisBuild / version := "0.1.0-SNAPSHOT"
-version := "0.1"
-
-scalaVersion := "2.12.10"
+ThisBuild / scalaVersion := "2.12.10"
libraryDependencies += "com.lihaoyi" %% "utest" % "0.5.3" % "test"
-testFrameworks += new TestFramework("utest.runner.Framework")
\ No newline at end of file
+testFrameworks += new TestFramework("utest.runner.Framework")
+
+lazy val root = (project in file("."))
+ .settings(
+ name := "homework-1"
+ )
diff --git a/homeworks/homework_4/homework_4.md b/homeworks/homework_4/homework_4.md
index c496401e..930a47ff 100644
--- a/homeworks/homework_4/homework_4.md
+++ b/homeworks/homework_4/homework_4.md
@@ -1,46 +1,5 @@
# Домашнее задание №4 (курс Scala, Naumen)
+Необходимо выполнить задания, описанные в (src/main/scala/Exercises.scala)
+Решение должно успешно проходить тесты в (src/test/scala/Test.scala)
-Необходимо реализовать класс простой электронной таблицы (класс Table).
-
- Таблица имеет фиксированную ширину и длину (параметры конструктора Table).
-
-
Таблица должна быть представлена следующими типами ячеек (базовый интерфейс Cell):
-
-Пустая ячейка (класс EmptyCell),
-
-Ячейка с 32-битным целым числом (класс NumberCell),
-
-Ячейка с текстом (класс StringCell),
-
-Ячейка, содержащая ссылку на другую ячейку (класс ReferenceCell).
-
-
По умолчанию, все ячейки таблицы являются пустыми (класс "EmptyCell")
-
-
Таблица (класс Table) должна предоставлять следующие общедоступные методы:
-
-getCell(ix: Int, iy: Int): Option\[Cell\] (возвращает ячейку по индексам строки и столбца,
-
либо "None", если ix или iy вне границ таблицы),
-
-setCell(ix: Int, iy: Int, cell: Cell): Unit (устанавливает ячейку cell в указанные столбец и строку),
-
здесь ix - индекс колонки (ix>=0), iy - индекс строки (iy>=0),
-
cell - ячейка таблицы, представленная конкретной реализацией (EmptyCell/NumberCell/StringCell/ReferenceCell).
-
-
Таблица хранит коллекцию ячеек. Так как определён метод "setCell", можно использовать мутабельную коллекцию
-
(package scala.collection.mutable).
-
-
Каждая ячейка должна предоставлять основной конструктор, посредством которого инициализируется значение ячейки.
-
Например, class NumberCell(number: Int) extends Cell .
-
В случае "EmptyCell" какого-либо конструктора не требуется.
-
В случае "ReferenceCell": class ReferenceCell(ix: Int, iy: Int, table: Table) extends Cell, где ix и iy -
-
индексы столбца и строки ячейки (на которую ведёт ссылка) таблицы table (которой принадлежит ячейка, на которую ведёт ссылка).
-
-
Каждая ячейка (реализация интерфейса Cell) должна предоставлять общедоступный метод toString(): String,
-
который возвращает хранящееся в ней значение в виде строки (типа String).
-
В случае "EmptyCell" метод "toString" должен возвращать значение "empty"
-
В случае "ReferenceCell" метод "toString" должен возвращать значение той ячейки, на которую определена ссылка.
-
В случае, если "ReferenceCell" ячейка ссылается на индекс ячейки, находящийся за границами таблицы, метод "toString"
-
должен возвращать значение "outOfRange"
-
В случае "циклических" ссылок (если, например, "ReferenceCell" ячейка ссылается на другую "ReferenceCell" ячейку,
-
которая вновь ссылается на первую), метод "toString" должен возвращать значение "cyclic".
-
-
При реализации можно учесть, что двумерный список можно однозначно выразить одномерным:
-
i = ix + iy * w,
-
где i - индекс одномерного списка, ix - индекс колонки двумерного списка, iy - индекс строки двумерного списка,
-
w - ширина (количество колонок) двумерного списка.
-
-
Необходимо, чтобы реализация успешно проходила юнит-тесты (src/test/scala/Test.scala)
\ No newline at end of file
diff --git a/homeworks/homework_4/project/build.properties b/homeworks/homework_4/project/build.properties
index 010613d5..303541e5 100644
--- a/homeworks/homework_4/project/build.properties
+++ b/homeworks/homework_4/project/build.properties
@@ -1 +1 @@
-sbt.version = 1.3.3
\ No newline at end of file
+sbt.version = 1.9.6
diff --git a/homeworks/homework_4/src/main/scala/Exercises.scala b/homeworks/homework_4/src/main/scala/Exercises.scala
new file mode 100644
index 00000000..31ebaddb
--- /dev/null
+++ b/homeworks/homework_4/src/main/scala/Exercises.scala
@@ -0,0 +1,124 @@
+
+object Exercises {
+
+ /**
+ * Задание №1
+ * Дана императивная функция findSumImperative.
+ * Напишите ее аналог (findSumFunctional) в функциональном стиле.
+ *
+ * ПОДСКАЗКА
+ * Стоит воспользоваться методами, которые предоставляет объект List или рекурсией.
+ * Страница с полезностями List: https://alvinalexander.com/scala/list-class-methods-examples-syntax/
+ */
+ def findSumImperative(items: List[Int], sumValue: Int): (Int, Int) = {
+ var result: (Int, Int) = (-1, -1)
+ for (i <- 0 until items.length) {
+ for (j <- 0 until items.length) {
+ if (items(i) + items(j) == sumValue && i != j) {
+ result = (i, j)
+ }
+ }
+ }
+ result
+ }
+
+ def findSumFunctional(items: List[Int], sumValue: Int) = {
+ (-1, -1)
+ }
+
+
+ /**
+ * Задание №2
+ *
+ * Дана рекурсивная функция simpleRecursion.
+ * Перепишите ее так, чтобы получилась хвостовая рекурсивная функция.
+ *
+ * Для прохождения теста на большое количество элементов в списке
+ * используйте анотацию @tailrec к вашей функции.
+ */
+ def simpleRecursion(items: List[Int], index: Int = 1): Int = {
+ items match {
+ case head :: tail =>
+ if (head % 2 == 0) {
+ head * simpleRecursion(tail, index + 1) + index
+ } else {
+ -1 * head * simpleRecursion(tail, index + 1) + index
+ }
+ case _ => 1
+ }
+ }
+
+ def tailRecRecursion(items: List[Int]): Int = {
+ 1
+ }
+
+ /**
+ * Задание №3
+ * Реализуйте алгоритм бинарного поиска, который соответсвует всем правилам функционального программирования.
+ * Необходимо возвращать индекс соответствующего элемента в массиве
+ * Если ответ найден, то возвращается Some(index), если нет, то None
+ */
+
+ def functionalBinarySearch(items: List[Int], value: Int): Option[Int] = {
+ None
+ }
+
+ /**
+ * Задание №4
+ * Реализуйте функцию, которая генерирует список заданной длинны c именами.
+ * Функция должна соответствовать всем правилам функционального программирования.
+ *
+ * Именем является строка, не содержащая иных символов, кроме буквенных, а также начинающаяся с заглавной буквы.
+ */
+
+ def generateNames(namesСount: Int): List[String] = {
+ if (namesСount < 0) throw new Throwable("Invalid namesCount")
+ Nil
+ }
+
+}
+
+/**
+ * Задание №5
+ *
+ * Дана реализация сервиса по смене номера SimpleChangePhoneService с методом changePhone
+ * Необходимо написать реализацию этого сервиса с учетом правил работы со сторонними эффектами (SideEffects).
+ *
+ * Для этого необходимо сначала реализовать собственный сервис работы с телефонными номерами (PhoneServiceSafety),
+ * используя при этом методы из unsafePhoneService.
+ * Методы должны быть безопасными, поэтому тип возвращаемых значений необходимо определить самостоятельно.
+ * Рекомендуется воспользоваться стандартными типами Scala (например Option или Either).
+ *
+ * Затем, с использованием нового сервиса, необходимо реализовать "безопасную" версию функции changePhone.
+ * Функция должна возвращать ok в случае успешного завершения или текст ошибки.
+ *
+ * Изменять методы внутри SimplePhoneService не разрешается.
+ */
+
+object SideEffectExercise {
+ import Utils._
+
+ class SimpleChangePhoneService(phoneService: SimplePhoneService) extends ChangePhoneService {
+ override def changePhone(oldPhone: String, newPhone: String): String = {
+ val oldPhoneRecord = phoneService.findPhoneNumber(oldPhone)
+ if (oldPhoneRecord != null) {
+ phoneService.deletePhone(oldPhoneRecord)
+ }
+ phoneService.addPhoneToBase(newPhone)
+ "ok"
+ }
+ }
+
+
+ class PhoneServiceSafety(unsafePhoneService: SimplePhoneService) {
+ def findPhoneNumberSafe(num: String) = ???
+
+ def addPhoneToBaseSafe(phone: String) = ???
+
+ def deletePhone(phone: String) = ???
+ }
+
+ class ChangePhoneServiceSafe(phoneServiceSafety: PhoneServiceSafety) extends ChangePhoneService {
+ override def changePhone(oldPhone: String, newPhone: String): String = ???
+ }
+}
diff --git a/homeworks/homework_4/src/main/scala/Utils.scala b/homeworks/homework_4/src/main/scala/Utils.scala
new file mode 100644
index 00000000..0820ad4d
--- /dev/null
+++ b/homeworks/homework_4/src/main/scala/Utils.scala
@@ -0,0 +1,36 @@
+import scala.collection.mutable
+
+object Utils {
+ class PhoneBase(private val phones: mutable.ListBuffer[String]) {
+ def insert(phone: String): Unit = phones += phone
+ def list(): List[String] = phones.toList
+ def delete(phone: String): Unit = phones.filter(_ != phone)
+
+ }
+
+ def checkPhoneNumber(num: String): Boolean = num.matches("^[\\+]?[(]?[0-9]{3}[)]?[-\\s\\.]?[0-9]{3}[-\\s\\.]?[0-9]{4,6}$")
+
+ class SimplePhoneService(phonesBase: PhoneBase) {
+
+ def findPhoneNumber(num: String): String = {
+ val resulNums = phonesBase.list().filter(_ == num)
+ if (resulNums.isEmpty)
+ null
+ else
+ resulNums.head
+ }
+
+ def addPhoneToBase(phone: String): Unit = {
+ if (checkPhoneNumber(phone))
+ phonesBase.insert(phone)
+ else
+ throw new InternalError("Invalid phone string")
+ }
+
+ def deletePhone(phone: String): Unit = phonesBase.delete(phone)
+ }
+
+ trait ChangePhoneService {
+ def changePhone(oldPhone: String, newPhone: String): String
+ }
+}
diff --git a/homeworks/homework_4/src/test/scala/Test.scala b/homeworks/homework_4/src/test/scala/Test.scala
index 13357759..d80a537b 100644
--- a/homeworks/homework_4/src/test/scala/Test.scala
+++ b/homeworks/homework_4/src/test/scala/Test.scala
@@ -1,76 +1,63 @@
import utest._
+import scala.util.Random
+
object Test extends TestSuite {
- val tests = Tests {
- 'test_createTable - {
- val table = new Table(3, 3)
- for (i <- 0 until 9) {
- assert(table.getCell(i / 3, i % 3).map(_.toString) == Some("empty"))
- }
- assert(table.getCell(0, -1).map(_.toString) == None)
- assert(table.getCell(-1, 0).map(_.toString) == None)
- assert(table.getCell(9, 8).map(_.toString) == None)
- assert(table.getCell(8, 9).map(_.toString) == None)
+ lazy val randomLength = Random
+ def generateRandomList(maxListSize: Int) = {
+ val listLength = Random.nextInt(maxListSize)
+ List.fill(listLength)(Random.nextInt)
+ }
+ override def tests: Tests = Tests {
+ 'firstTask - (1 to 5).foreach { _ =>
+ val testList = generateRandomList(50)
+ val sumValue = testList(Random.nextInt(testList.size)) + testList(Random.nextInt(testList.size))
+ assert(Exercises.findSumImperative(testList, sumValue) == Exercises.findSumFunctional(testList, sumValue))
}
- 'test_numberCell - {
- val table = new Table(2, 2)
- val cellInt00 = new NumberCell(5)
- val cellInt11 = new NumberCell(2147483647)
- table.setCell(0, 0, cellInt00)
- table.setCell(1, 1, cellInt11)
- assert(table.getCell(0, 0).map(_.toString) == Some("5"))
- assert(table.getCell(0, 1).map(_.toString) == Some("empty"))
- assert(table.getCell(1, 0).map(_.toString) == Some("empty"))
- assert(table.getCell(1, 1).map(_.toString) == Some("2147483647"))
+
+ 'recursionTask - {
+ 'itWorks - {
+ (1 to 5).foreach { _ =>
+ val testList = generateRandomList(50)
+ assert(Exercises.simpleRecursion(testList) == Exercises.tailRecRecursion(testList))
+ }
+ }
+ 'longList - {
+ val testList = List.fill(10000)(Random.nextInt)
+ Exercises.tailRecRecursion(testList)
+ }
}
- 'test_stringCell - {
- val table = new Table(2, 2)
- val cellStr01 = new StringCell("01")
- val cellStr10 = new StringCell("10")
- table.setCell(0, 1, cellStr01)
- table.setCell(1, 0, cellStr10)
- assert(table.getCell(0, 0).map(_.toString) == Some("empty"))
- assert(table.getCell(0, 1).map(_.toString) == Some("01"))
- assert(table.getCell(1, 0).map(_.toString) == Some("10"))
- assert(table.getCell(1, 1).map(_.toString) == Some("empty"))
+
+ 'binarySearch - {
+ 'simpleSearch - (1 to 5).foreach { _ =>
+ val testList = generateRandomList(50).distinct.sorted
+ val result = Random.nextInt(testList.size)
+ assert(Exercises.functionalBinarySearch(testList, testList(result)).contains(result))
+ }
+
+ 'empty - {
+ assert(Exercises.functionalBinarySearch(Nil, 24).isEmpty)
+ }
+
+ 'noElement - {
+ val testList = List.fill(50)(Random.nextInt(50))
+ assert(Exercises.functionalBinarySearch(testList, -1).isEmpty)
+ }
}
- 'test_referenceCell - {
- val table = new Table(3, 3)
- /*ix = 0*/
- val cellStr00 = new StringCell("00")
- val cellRef01 = new ReferenceCell(0, 2, table)
- val cellRef02 = new ReferenceCell(0, 1, table)
- /*ix = 1*/
- val cellInt10 = new NumberCell(10)
- val cellInt11 = new NumberCell(11)
- val cellRef12 = new ReferenceCell(0, 0, table)
- /*ix = 2*/
- val cellEmpty20 = new EmptyCell
- val cellRef21 = new ReferenceCell(1, 1, table)
- val cellRef22 = new ReferenceCell(2, 1, table)
- table.setCell(0, 0, cellStr00)
- table.setCell(0, 1, cellRef01)
- table.setCell(0, 2, cellRef02)
- table.setCell(1, 0, cellInt10)
- table.setCell(1, 1, cellInt11)
- table.setCell(1, 2, cellRef12)
- table.setCell(2, 0, cellEmpty20)
- table.setCell(2, 1, cellRef21)
- table.setCell(2, 2, cellRef22)
- for (i <- 0 until 9) {
- val value = table.getCell(i / 3, i % 3).get.toString
- i match {
- case 0 => assert(value == "00")
- case 1 => assert(value == "cyclic")
- case 2 => assert(value == "cyclic")
- case 3 => assert(value == "10")
- case 4 => assert(value == "11")
- case 5 => assert(value == "00")
- case 6 => assert(value == "empty")
- case 7 => assert(value == "11")
- case 8 => assert(value == "11")
- case _ => assert(false)
- }
+
+ 'namesList - {
+ 'nonEmpty - (1 to 5).foreach { _ =>
+ val namesCount = Random.nextInt(50)
+ val names = Exercises.generateNames(namesCount)
+ assert(
+ names.forall(_.matches("([A-Z]|[А-Я])([a-z]|[а-я])*")) &&
+ names.size == namesCount &&
+ names.distinct.size == namesCount
+ )
+ }
+
+ 'empty - {
+ assert(Exercises.generateNames(0).isEmpty)
}
}
}
diff --git a/homeworks/homework_5/build.sbt b/homeworks/homework_5/build.sbt
deleted file mode 100644
index a5844cf4..00000000
--- a/homeworks/homework_5/build.sbt
+++ /dev/null
@@ -1,9 +0,0 @@
-name := "homework_5"
-
-version := "0.1"
-
-scalaVersion := "2.12.10"
-
-libraryDependencies += "com.lihaoyi" %% "utest" % "0.5.3" % "test"
-
-testFrameworks += new TestFramework("utest.runner.Framework")
diff --git a/homeworks/homework_5/homework_5.md b/homeworks/homework_5/homework_5.md
deleted file mode 100644
index f32b2d7d..00000000
--- a/homeworks/homework_5/homework_5.md
+++ /dev/null
@@ -1,39 +0,0 @@
-# Домашнее задание №5 (курс Scala, Naumen)
-
-## Задание 1
-
-Реализуйте класс приюта для животных (`case class Shelter...`), который хранит список (`List`)
-животных, которые в нем содержатся. Приют должен быть параметризован типом содержащихся животных.
-Например, `Shelter[Cat]` может содержать только котов, а `Shelter[Animal]` любых животных.
-Реализуйте метод `+`, который добавляет в приют животное (метод должен вернуть новый приют, а не модифицировать старый).
-Тип полученного приюта должен остаться настолько точным, насколько это возможным.
-Например, если в приют с котами добавляют кота, то в результате должен снова получиться приют с котами.
-`val s: Shelter[Cat] = Shelter(List(Cat("Garfield"))) + Cat("Kuzya")`
-Если же в приют с котами добавить собаку, то получится приют с животными.
-`val s: Shelter[Animal] = Shelter(List(Cat("Garfield"))) + Dog("Goofy")`
-Реализовать метод `++`, который производит сложение двух приютов и возвращает приют,
-в котором содержатся животные из обоих, участвовавших в сложении.
-Тип результата точно так же должен быть настолько точным, насколько это возможно, исходя из
-типов приютов, участвовавших в сложении.
-Реализовать метод `getNames`, который возвращает спсок имен животных, содержащихся в приюте.
-Тесты должны компилироваться и успешно проходить. Обратите внимание, что до вполнения второго
-задания соответствующая часть тестов не будет компилироваться, так что ее можно закомментировать.
-
-## Задание 2
-
-Реализовать тип еда (`trait Food`), который параметризован типом животных, которые
-ее могут есть. Например, `Food[Cat]` могут есть только коты, а
-`Food[Animal]` могут есть любые животные. Реализовать объекты (`case object`):
-`Meat` - мясо, могут есть все животные.
-`Milk` - молоко, могут есть коты.
-`Bread` - хлеб, могут есть собаки.
-Определить для еды метод `feed`, который принимает животное того типа, которым параметризована эта еда,
-и возвращает строку, содержащую "<имя животного> eats <название еды со строчной буквы>". Например,
-`Meat.feed(Cat("Garfield"))` должно вернуть "Garfield eats meat", а `Milk.feed(Dog("Goofy"))` не должно
-компилироваться т.к. собаки не едят молоко.
-Реализовать для приюта метод, который получает на вход еду, которая подходит для
-содержащихся в нем животных, и выводит список результатов применеия метода `Food.feed` ко
-всем животным. Обратите внамение, что `Shelter(List(Cat("Garfield"), Dog("Goofy"))).feed(Milk)` не должно
-компилироваться т.к. в этом приюте содержатся и кошки и собаки,
-следовательно тип этого приюта - `Shelter[Animal]`, а произвольные животные не могут есть молоко. Единственная
-еда, которой их можно было бы покормить - мясо.
diff --git a/homeworks/homework_5/project/build.properties b/homeworks/homework_5/project/build.properties
deleted file mode 100644
index 010613d5..00000000
--- a/homeworks/homework_5/project/build.properties
+++ /dev/null
@@ -1 +0,0 @@
-sbt.version = 1.3.3
\ No newline at end of file
diff --git a/homeworks/homework_5/src/main/scala/Exercises.scala b/homeworks/homework_5/src/main/scala/Exercises.scala
deleted file mode 100644
index 2be7d30e..00000000
--- a/homeworks/homework_5/src/main/scala/Exercises.scala
+++ /dev/null
@@ -1,23 +0,0 @@
-object Exercises {
- trait Animal {
- def name: String
- }
-
- case class Cat(override val name: String) extends Animal
-
- case class Dog(override val name: String) extends Animal
-
-
-
- case class Shelter ...
-
-
-
- trait Food ...
-
- case object Meat extends Food[Animal] ...
-
- case object Milk extends Food[Cat] ...
-
- case object Bread extends Food[Dog] ...
-}
diff --git a/homeworks/homework_5/src/test/scala/Test.scala b/homeworks/homework_5/src/test/scala/Test.scala
deleted file mode 100644
index f8e61f8f..00000000
--- a/homeworks/homework_5/src/test/scala/Test.scala
+++ /dev/null
@@ -1,58 +0,0 @@
-import Exercises._
-import utest._
-
-object Test extends TestSuite {
-
- val tests = Tests {
-
- //Test task 1
-
- val s1: Shelter[Cat] = Shelter(List(Cat("Garfield")))
-
- val s2: Shelter[Dog] = Shelter(List(Dog("Goofy")))
-
- val s3: Shelter[Animal] = s1 ++ s2
-
- val s4 = s3 + Cat("Kuzya")
-
- assert(s4.getNames.toSet == Set("Garfield", "Goofy", "Kuzya"))
-
- val s5: Shelter[Animal] = s1 + Dog("Barbos")
-
- assert(s5.getNames.toSet == Set("Garfield", "Barbos"))
-
- val s6: Shelter[Dog] = s2 + Dog("Barbos")
-
- assert(s6.getNames.toSet == Set("Goofy", "Barbos"))
-
- //Test task 2
-
- val r1 = s1.feed(Meat)
-
- assert(r1.toSet == Set("Garfield eats meat"))
-
- val r2 = s1.feed(Milk)
-
- assert(r2.toSet == Set("Garfield eats milk"))
-
- val r3 = s2.feed(Meat)
-
- assert(r3.toSet == Set("Goofy eats meat"))
-
- val r4 = s2.feed(Bread)
-
- assert(r4.toSet == Set("Goofy eats bread"))
-
- val r5 = s4.feed(Meat)
-
- assert(
- r5.toSet == Set(
- "Garfield eats meat",
- "Goofy eats meat",
- "Kuzya eats meat"
- )
- )
-
- }
-
-}
diff --git a/homeworks/homework_6/.gitignore b/homeworks/homework_6/.gitignore
deleted file mode 100644
index 56b16317..00000000
--- a/homeworks/homework_6/.gitignore
+++ /dev/null
@@ -1,3 +0,0 @@
-/.idea
-/target
-project/target
\ No newline at end of file
diff --git a/homeworks/homework_6/build.sbt b/homeworks/homework_6/build.sbt
deleted file mode 100644
index 6f288598..00000000
--- a/homeworks/homework_6/build.sbt
+++ /dev/null
@@ -1,9 +0,0 @@
-name := "homework_6"
-
-version := "0.1"
-
-scalaVersion := "2.12.10"
-
-libraryDependencies += "com.lihaoyi" %% "utest" % "0.5.3" % "test"
-
-testFrameworks += new TestFramework("utest.runner.Framework")
diff --git a/homeworks/homework_6/homework_6.md b/homeworks/homework_6/homework_6.md
deleted file mode 100644
index bc75b952..00000000
--- a/homeworks/homework_6/homework_6.md
+++ /dev/null
@@ -1,25 +0,0 @@
-# Домашнее задание №6 (курс Scala, Naumen)
-
-## Задание 1. *reverse*
-Реализовать метод реверсии списка.
-
-
-## Задание 2. *fibonacci4Index*
-Вычисление значения чисел Фибоначчи. Выводить значение в зависимости от индекса. Индекс - это неотрицательное целое число.
-[wiki. Числа Фибоначчи](https://ru.wikipedia.org/wiki/%D0%A7%D0%B8%D1%81%D0%BB%D0%B0_%D0%A4%D0%B8%D0%B1%D0%BE%D0%BD%D0%B0%D1%87%D1%87%D0%B8)
-
-
-## Задание 2. *fibonacci4Index*
-То же что и `Задание 2` (только выдаём последовательность).
-
-
-## Задание 3. *morse*
-Закодировать текст при помощи Морзе. Приведена таблица `Exercises.MORSE` для латинских букв. На выходе *коды* разделяются пробелами. Если встречается "нелатинская" буква, то выводить этот символ как он был передан. К примеру, в связи с этим условием пробел " " превращается в три пробела " ".
-
-
-## Задание 4. *wordReverse*
-На вход передаётся обычный текст. Необходимо развернуть каждое слово (слово - это набор букв, именно букв). Если слово начиналось с заглавной буквы, то развёрнутое должно начинаться с большой буквы.
-
-
----
-Попробуйте решить задачи, используя `mutable` и `immutable` коллекции. Хотя для большинства задач достаточно использовать `immutable`.
diff --git a/homeworks/homework_6/project/build.properties b/homeworks/homework_6/project/build.properties
deleted file mode 100644
index 010613d5..00000000
--- a/homeworks/homework_6/project/build.properties
+++ /dev/null
@@ -1 +0,0 @@
-sbt.version = 1.3.3
\ No newline at end of file
diff --git a/homeworks/homework_6/src/main/scala/Exercises.scala b/homeworks/homework_6/src/main/scala/Exercises.scala
deleted file mode 100644
index 2e325cbd..00000000
--- a/homeworks/homework_6/src/main/scala/Exercises.scala
+++ /dev/null
@@ -1,27 +0,0 @@
-object Exercises {
-
-
- def reverse[T](seq: Seq[T]): Seq[T] = ???
-
- /**
- * https://ru.wikipedia.org/wiki/Числа_Фибоначчи
- *
- * @param idx
- * @return
- */
- def fibonacci4Index(idx: Int): Int = ???
-
- def fibonacci(idx: Int): Seq[Int] = ???
-
- lazy val MORSE = Map("A" -> ".-", "B" -> "-...", "C" -> "-.-.", "D" -> "-..", "E" -> ".", "F" -> "..-.",
- "G" -> "--.", "H" -> "....", "I" -> "..", "J" -> ".---", "K" -> "-.-", "L" -> ".-..",
- "M" -> "--", "N" -> "-.", "O" -> "---", "P" -> ".--.", "Q" -> "--.-", "R" -> ".-.",
- "S" -> "...", "T" -> "-", "U" -> "..-", "V" -> "...-", "W" -> ".--", "X" -> "-..-",
- "Y" -> "-.--", "Z" -> "--..")
-
- def morse(text: String): String = ???
-
-
- def wordReverse(text: String): String = ???
-
-}
diff --git a/homeworks/homework_6/src/test/scala/Test.scala b/homeworks/homework_6/src/test/scala/Test.scala
deleted file mode 100644
index 62d9396e..00000000
--- a/homeworks/homework_6/src/test/scala/Test.scala
+++ /dev/null
@@ -1,33 +0,0 @@
-import utest._
-
-
-object Test extends TestSuite{
-
- val tests = Tests{
- 'reverse - {
- assert(Exercises.reverse(Seq(1, 2, 3)) == Seq(3, 2, 1))
- assert(Exercises.reverse(Seq(-1, -2, -3)) == Seq(-3, -2, -1))
- }
-
- 'fibonacci4Index - {
- assert(Exercises.fibonacci4Index(2) == 1)
- assert(Exercises.fibonacci4Index(5) == 5)
- }
-
- 'fibonacci - {
- assert(Exercises.fibonacci(2) == Seq(0, 1, 1))
- assert(Exercises.fibonacci(5) == Seq(0, 1, 1, 2, 3, 5))
- }
-
- 'morse - {
- assert(Exercises.morse("SOS") == "... --- ...")
- assert(Exercises.morse("Hello world!") == ".... . .-.. .-.. --- .-- --- .-. .-.. -..!")
- }
-
- 'wordReverse - {
- assert(Exercises.wordReverse("Зима!.. Крестьянин, торжествуя...") == "Амиз!.. Ниняьтсерк, яувтсежрот...")
- }
-
-
- }
-}
diff --git a/homeworks/homework_7/.gitignore b/homeworks/homework_7/.gitignore
deleted file mode 100644
index 56b16317..00000000
--- a/homeworks/homework_7/.gitignore
+++ /dev/null
@@ -1,3 +0,0 @@
-/.idea
-/target
-project/target
\ No newline at end of file
diff --git a/homeworks/homework_7/build.sbt b/homeworks/homework_7/build.sbt
deleted file mode 100644
index 299e0e3d..00000000
--- a/homeworks/homework_7/build.sbt
+++ /dev/null
@@ -1,11 +0,0 @@
-name := "homework_7"
-
-version := "0.1"
-
-scalaVersion := "2.12.10"
-
-libraryDependencies += "com.lihaoyi" %% "utest" % "0.5.3" % "test"
-
-scalacOptions ++= Seq("-language:higherKinds")
-
-testFrameworks += new TestFramework("utest.runner.Framework")
\ No newline at end of file
diff --git a/homeworks/homework_7/homework_7.md b/homeworks/homework_7/homework_7.md
deleted file mode 100644
index 3d7bb2df..00000000
--- a/homeworks/homework_7/homework_7.md
+++ /dev/null
@@ -1,3 +0,0 @@
-# Домашнее задание №7 (курс Scala, Naumen)
-
-Необходимо реализовать объявления функций в файле "MonadFunctor.scala" в соответствии с тестами (файл "Test.scala")
diff --git a/homeworks/homework_7/project/build.properties b/homeworks/homework_7/project/build.properties
deleted file mode 100644
index 010613d5..00000000
--- a/homeworks/homework_7/project/build.properties
+++ /dev/null
@@ -1 +0,0 @@
-sbt.version = 1.3.3
\ No newline at end of file
diff --git a/homeworks/homework_7/src/main/scala/MonadFunctor.scala b/homeworks/homework_7/src/main/scala/MonadFunctor.scala
deleted file mode 100644
index c90951a2..00000000
--- a/homeworks/homework_7/src/main/scala/MonadFunctor.scala
+++ /dev/null
@@ -1,23 +0,0 @@
-
-trait Monad[F[_]] {
-
- def pure[A](a: A): F[A]
-
- def flatMap[A, B](fa: F[A])(f: A => F[B]): F[B]
-
- def map2[A, B, C](fa: F[A], fb: F[B])(f: (A, B) => C): F[C] = ???
-
- def sequence[A](fas: List[F[A]]): F[List[A]] = ???
-
- def compose[A, B, C](f: A => F[B])(g: B => F[C]): A => F[C] = ???
-}
-
-trait Functor[F[_]] {
- def map[A, B](a: F[A])(f: A => B): F[B]
-}
-
-object Functor {
- def functorFromMonad[F[_]](M: Monad[F]): Functor[F] = new Functor[F] {
- def map[A, B](a: F[A])(f: A => B): F[B] = ???
- }
-}
diff --git a/homeworks/homework_7/src/test/scala/Test.scala b/homeworks/homework_7/src/test/scala/Test.scala
deleted file mode 100644
index 343e203a..00000000
--- a/homeworks/homework_7/src/test/scala/Test.scala
+++ /dev/null
@@ -1,33 +0,0 @@
-import utest._
-
-object Test extends TestSuite {
- val tupleMonad: Monad[Tuple1] = new Monad[Tuple1] {
- def pure[A](a: A): Tuple1[A] = Tuple1(a)
-
- def flatMap[A, B](fa: Tuple1[A])(f: A => Tuple1[B]): Tuple1[B] =
- f(fa._1)
- }
-
- val tests: Tests = Tests {
- 'test_CombineTwoMonadic - {
- assert(tupleMonad.map2(Tuple1(1), Tuple1(2))((a, b) => a + b) == Tuple1(3))
- }
- 'test_Sequence - {
- assert(tupleMonad.sequence(List(Tuple1(1), Tuple1(2), Tuple1(3))) == Tuple1(List(1,2,3)))
- }
- 'test_Compose - {
- val f: Int => Tuple1[Double] = a => Tuple1(a / 2.0)
- val g: Double => Tuple1[String] = a => Tuple1(a.toString)
- assert(tupleMonad.compose(f)(g)(3) == Tuple1("1.5"))
- }
- 'test_FunctorFromMonad - {
- val funcVal = Functor.functorFromMonad[Option](new Monad[Option] {
- def pure[A](a: A): Option[A] = Some(a)
- def flatMap[A, B](fa: Option[A])(f: A => Option[B]): Option[B] =
- fa.flatMap(f)
- }).map[Int, String](Some(3))(_.toString)
-
- assert(funcVal.contains("3"))
- }
- }
-}
diff --git a/homeworks/homework_8/.gitignore b/homeworks/homework_8/.gitignore
deleted file mode 100644
index 56b16317..00000000
--- a/homeworks/homework_8/.gitignore
+++ /dev/null
@@ -1,3 +0,0 @@
-/.idea
-/target
-project/target
\ No newline at end of file
diff --git a/homeworks/homework_8/build.sbt b/homeworks/homework_8/build.sbt
deleted file mode 100644
index 26a9e968..00000000
--- a/homeworks/homework_8/build.sbt
+++ /dev/null
@@ -1,9 +0,0 @@
-name := "homework_8"
-
-version := "0.1"
-
-scalaVersion := "2.12.10"
-
-libraryDependencies += "com.lihaoyi" %% "utest" % "0.5.3" % "test"
-
-testFrameworks += new TestFramework("utest.runner.Framework")
diff --git a/homeworks/homework_8/homework_8.md b/homeworks/homework_8/homework_8.md
deleted file mode 100644
index 4e41675d..00000000
--- a/homeworks/homework_8/homework_8.md
+++ /dev/null
@@ -1,16 +0,0 @@
-# Домашнее задание №8 (курс Scala, Naumen)
-
-## Задание 1. *Read*
-Реализовать тайпкласс Read, который позволяет прочитать значение типа T, реализующего тайпкласс, из строки.
-Тайпкласс должен иметь метод read, который на вход принимает строку, а на выходе выдает Either[String, T],
-где в случае, если чтение было успешно, будет Right с нужным значением, если неуспешным, то Left со строкой,
-поясняющей ошибку.
-
-Реализовать для данного тайпкласса интерфейс с использованием неявных параметров и обогащающий класс.
-Должны работать следующие синтаксисы: Read.read[T]("...") и "...".read[T]
-
-Реализовать для данного тайпкласса инстансы для типов: String, Int и Option[T], где тип Т уже имеет инстанс Read.
-Для типа String операция чтения всегда успешна и возвращает саму строку.
-Для типа Int операция возвращает число, если поданная на вход строка является корректым представлением числа, или ошибку.
-Для типа Option[T] операция возвращает None, если на вход подана строка "None", Some(<результат чтения внутреннего выражения>),
-если на вход подана строка вида "Some(...)" и выражение в скобках было корректно прочитано в тип T, и ошибку во всех остальных случаях.
diff --git a/homeworks/homework_8/project/build.properties b/homeworks/homework_8/project/build.properties
deleted file mode 100644
index 010613d5..00000000
--- a/homeworks/homework_8/project/build.properties
+++ /dev/null
@@ -1 +0,0 @@
-sbt.version = 1.3.3
\ No newline at end of file
diff --git a/homeworks/homework_8/src/main/scala/Exercises.scala b/homeworks/homework_8/src/main/scala/Exercises.scala
deleted file mode 100644
index dc5d3ccf..00000000
--- a/homeworks/homework_8/src/main/scala/Exercises.scala
+++ /dev/null
@@ -1,3 +0,0 @@
-import scala.util.Try
-object Exercises {
-}
diff --git a/homeworks/homework_8/src/test/scala/Test.scala b/homeworks/homework_8/src/test/scala/Test.scala
deleted file mode 100644
index 394c5b40..00000000
--- a/homeworks/homework_8/src/test/scala/Test.scala
+++ /dev/null
@@ -1,45 +0,0 @@
-import utest._
-
-import Exercises._
-
-object Test extends TestSuite {
-
- val tests = Tests {
- 'string - {
- val success = Read.read[String]("test")
- assert(success == Right("test"))
- }
-
- 'int - {
- val success = "123".read[Int]
- assert(success == Right(123))
- val failure = "test".read[Int]
- assert(failure.isLeft)
- }
-
- 'option - {
- val none1 = "None".read[Option[String]]
- assert(none1 == Right(None))
- val someString = "Some(test)".read[Option[String]]
- assert(someString == Right(Some("test")))
-
- val none2 = "None".read[Option[Int]]
- assert(none2 == Right(None))
- val someInt = "Some(123)".read[Option[Int]]
- assert(someInt == Right(Some(123)))
-
- val failure = "test".read[Option[String]]
- assert(failure.isLeft)
- val someFailure = "Some(test)".read[Option[Int]]
- assert(someFailure.isLeft)
-
- val multipleSome =
- "Some(Some(Some(Some(123))))".read[Option[Option[Option[Option[Int]]]]]
- assert(multipleSome == Right(Some(Some(Some(Some(123))))))
- val multipleNone = "Some(Some(None))".read[Option[Option[Option[String]]]]
- assert(multipleNone == Right(Some(Some(None))))
- val lessNone = "Some(None)".read[Option[Option[Option[Int]]]]
- assert(lessNone == Right(Some(None)))
- }
- }
-}
diff --git a/homeworks/homework_9/.gitignore b/homeworks/homework_9/.gitignore
deleted file mode 100644
index 56b16317..00000000
--- a/homeworks/homework_9/.gitignore
+++ /dev/null
@@ -1,3 +0,0 @@
-/.idea
-/target
-project/target
\ No newline at end of file
diff --git a/homeworks/homework_9/build.sbt b/homeworks/homework_9/build.sbt
deleted file mode 100644
index d2f156c8..00000000
--- a/homeworks/homework_9/build.sbt
+++ /dev/null
@@ -1,7 +0,0 @@
-name := "FP"
-
-version := "0.1"
-
-scalaVersion := "2.13.7"
-
-libraryDependencies += "org.scalatest" %% "scalatest" % "3.2.10" % Test
diff --git a/homeworks/homework_9/homework_9.md b/homeworks/homework_9/homework_9.md
deleted file mode 100644
index c0e41cea..00000000
--- a/homeworks/homework_9/homework_9.md
+++ /dev/null
@@ -1,3 +0,0 @@
-# Домашнее задание №9 (курс Scala, Naumen)
-
-Необходимо реализовать объявления функций в файле "ListOps.scala" в соответствии с тестами (файл "Test.scala")
diff --git a/homeworks/homework_9/project/build.properties b/homeworks/homework_9/project/build.properties
deleted file mode 100644
index 302b6be1..00000000
--- a/homeworks/homework_9/project/build.properties
+++ /dev/null
@@ -1 +0,0 @@
-sbt.version = 1.3.13
\ No newline at end of file
diff --git a/homeworks/homework_9/src/main/scala/DataList.scala b/homeworks/homework_9/src/main/scala/DataList.scala
deleted file mode 100644
index 660993da..00000000
--- a/homeworks/homework_9/src/main/scala/DataList.scala
+++ /dev/null
@@ -1,11 +0,0 @@
-sealed trait DataList[+T]
-
-object DataList {
- final case class NonEmptyList[+T](head: T, tail: DataList[T]) extends DataList[T]
- case object EmptyList extends DataList[Nothing]
-
- def apply[T](x: T*): DataList[T] = x.toList match {
- case head :: tail => NonEmptyList(head, apply(tail: _*))
- case _ => EmptyList
- }
-}
diff --git a/homeworks/homework_9/src/main/scala/ListOps.scala b/homeworks/homework_9/src/main/scala/ListOps.scala
deleted file mode 100644
index 826c38f8..00000000
--- a/homeworks/homework_9/src/main/scala/ListOps.scala
+++ /dev/null
@@ -1,48 +0,0 @@
-import scala.annotation.tailrec
-
-object ListOps {
-
- /**
- * Функция fold "сворачивает" список из Т в один элемент типа Т.
- * Если в списке лишь один элемент, то он и вернётся, два - вернётся результат применения f к этим элементам,
- * больше двух - результат применения к f(f(f(...), a[i - 1]), a[i])
- * @param f функция свёртывания. Применяется попарно к предыдущему результату применения и i-ому элементу списка
- * @return None - если список пустой
- */
- def foldOption[T](f: (T, T) => T): DataList[T] => Option[T] = ???
-
-
- /**
- * Используя foldOption[T](f: (T, T) => T) реализуйте суммирование всех элементов списка.
- * @return Если список пустой, то 0
- */
- def sum[T : Numeric](list: DataList[T]): T = {
- /**
- * Используйте для суммирования двух чисел любого типа (Int, Long, Double, Float etc)
- */
- def sumT(a: T, b: T) = implicitly[Numeric[T]].plus(a, b)
-
- ???
- }
-
- /**
- * Фильтрация списка. Хвостовая рекурсия
- * @param f - фильтрующее правило (если f(a[i]) == true, то элемент остаётся в списке)
- */
- @tailrec
- private def filterImpl[T](f: T => Boolean)(buffer: DataList[T])(l: DataList[T]): DataList[T] = ???
-
- final def filter[T](f: T => Boolean): DataList[T] => DataList[T] = filterImpl(f)(DataList.EmptyList)
-
- final def map[A, B](f: A => B): DataList[A] => DataList[B] = {
- case DataList.EmptyList => DataList.EmptyList
- case DataList.NonEmptyList(head, tail) => DataList.NonEmptyList(f(head), map(f)(tail))
- }
-
- /**
- * Используя композицию функций реализуйте collect. Collect - комбинация filter и map.
- * В качестве фильтрующего правила нужно использовать f.isDefinedAt
- */
- def collect[A, B](f: PartialFunction[A, B]): DataList[A] => DataList[B] = ???
-
-}
\ No newline at end of file
diff --git a/homeworks/homework_9/src/test/scala/Test.scala b/homeworks/homework_9/src/test/scala/Test.scala
deleted file mode 100644
index 7bc561eb..00000000
--- a/homeworks/homework_9/src/test/scala/Test.scala
+++ /dev/null
@@ -1,29 +0,0 @@
-import org.scalatest._
-import flatspec._
-import matchers._
-
-class Test extends AnyFlatSpec with should.Matchers {
-
- "foldOption" should "return None on empty list" in {
- ListOps.foldOption[Any](_ == _)(DataList.EmptyList) should be (None)
- }
-
- "foldOption" should "work correct on non empty list" in {
- ListOps.foldOption[String](_ ++ _)(DataList("1", "2", "3")) should be (Some("123"))
- }
-
- "sum" should "work correctly" in {
- ListOps.sum[Int](DataList(1, 2, 3)) should be (6)
- }
-
- "filter" should "work correctly" in {
- ListOps.filter[Int](_ % 2 == 0)(DataList((0 to 4).toList: _*)) should be (DataList(0, 2, 4))
- }
-
- "collect" should "work correctly" in {
- ListOps.collect[Int, String] {
- case i: Int if i % 2 == 0 => i.toString
- }(DataList((0 to 4).toList: _*)) should be (DataList("0", "2", "4"))
- }
-
-}
diff --git a/index.md b/index.md
index e62b5070..6fbe6af9 100644
--- a/index.md
+++ b/index.md
@@ -1,13 +1,17 @@
---
layout: default
---
-# naumen.scala.course.2023.spring
+# naumen.scala.course.2023.autumn
### Лекции
* Лекция 1. [Что такое Scala?](lectures/scala_lecture_1.html)
+* Лекция 4. [Функциональное программирование. Концепция](PowerPoint)](lectures/scala_lecture_4.pptx)
### Домашние задания
* [Инструкция по предоставлению результатов](https://github.com/naumen-student/naumen.scala.course.2023.autumn#%D0%BF%D1%80%D0%B5%D0%B4%D0%BE%D1%81%D1%82%D0%B0%D0%B2%D0%BB%D0%B5%D0%BD%D0%B8%D0%B5-%D1%80%D0%B5%D0%B7%D1%83%D0%BB%D1%8C%D1%82%D0%B0%D1%82%D0%BE%D0%B2)
-* [Задание 1](homeworks/homework_1/homework_1.md) [папка в GitHub](https://github.com/naumen-student/naumen.scala.course.2023.spring/tree/master/homeworks/homework_1)
\ No newline at end of file
+* [Задание 1](homeworks/homework_1/homework_1.md) [папка в GitHub](https://github.com/naumen-student/naumen.scala.course.2023.autumn/tree/master/homeworks/homework_1)
+* [Задание 2](homeworks/homework_2/homework_2.md) [папка в GitHub](https://github.com/naumen-student/naumen.scala.course.2023.autumn/tree/master/homeworks/homework_2)
+* [Задание 3](homeworks/homework_3/homework_3.md) [папка в GitHub](https://github.com/naumen-student/naumen.scala.course.2023.autumn/tree/master/homeworks/homework_3)
+* [Задание 4](homeworks/homework_4/homework_4.md) [папка в GitHub](https://github.com/naumen-student/naumen.scala.course.2023.autumn/tree/master/homeworks/homework_4)
\ No newline at end of file
diff --git a/lectures/scala_lecture_4.pptx b/lectures/scala_lecture_4.pptx
new file mode 100644
index 00000000..4d3a3adc
Binary files /dev/null and b/lectures/scala_lecture_4.pptx differ