mirror of
https://github.com/VyunSergey/tinkoff-interview.git
synced 2025-12-06 03:26:55 +03:00
Initial Commit
This commit is contained in:
7
.gitignore
vendored
Normal file
7
.gitignore
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
# Project exclude paths
|
||||
/.bsp
|
||||
/.idea
|
||||
/project/target/
|
||||
/project/project/target/
|
||||
/target/
|
||||
/target/scala-2.13/classes/
|
||||
5
build.sbt
Normal file
5
build.sbt
Normal file
@@ -0,0 +1,5 @@
|
||||
name := "tinkoff-pr"
|
||||
|
||||
version := "0.1"
|
||||
|
||||
scalaVersion := "2.13.6"
|
||||
1
project/build.properties
Normal file
1
project/build.properties
Normal file
@@ -0,0 +1 @@
|
||||
sbt.version = 1.4.7
|
||||
31
src/main/scala/test1.scala
Normal file
31
src/main/scala/test1.scala
Normal file
@@ -0,0 +1,31 @@
|
||||
object test1 extends App {
|
||||
/**
|
||||
* 1) Сжать последовательность целых чисел
|
||||
* Seq(1, 2, 2, 3, 4, 3, 3, 3) => Seq((1, 1), (2, 2), (3, 1), (4, 1), (3, 3))
|
||||
* Ответ выдать в виде Seq[(Int, Int)] (число из последовательности и число последовательных повторений)
|
||||
* 2) восстановить исходную последовательность из сжатой
|
||||
*/
|
||||
|
||||
def collectP(seq: Seq[Int]): Seq[(Int, Int)] =
|
||||
seq.foldLeft(Seq.empty[(Int, Int)]) {
|
||||
case ((elm, cnt) :: tail, int) if elm == int =>
|
||||
(int, cnt + 1) +: tail
|
||||
case (acc, int) =>
|
||||
(int, 1) +: acc
|
||||
case (Nil, int) => Seq((int, 1))
|
||||
}
|
||||
|
||||
def explodeP(seq: Seq[(Int, Int)]): Seq[Int] = {
|
||||
seq.flatMap { case (i, cnt) => Seq.fill(cnt)(i) }
|
||||
}
|
||||
|
||||
val seq = Seq(1, 2, 2, 3, 4, 3, 3, 3)
|
||||
val res = collectP(seq).reverse
|
||||
val res2 = explodeP(res)
|
||||
|
||||
println(res)
|
||||
assert(res == Seq((1, 1), (2, 2), (3, 1), (4, 1), (3, 3)))
|
||||
|
||||
println(res2)
|
||||
assert(res2 == seq)
|
||||
}
|
||||
53
src/main/scala/test2.scala
Normal file
53
src/main/scala/test2.scala
Normal file
@@ -0,0 +1,53 @@
|
||||
import scala.concurrent.{Await, ExecutionContext, Future}
|
||||
import scala.concurrent.duration._
|
||||
import scala.util.control.NonFatal
|
||||
|
||||
object test2 extends App {
|
||||
/**
|
||||
* На входе получаем последовательность асинхронных вызовов
|
||||
* с сигнатурой Seq[Future[String]]
|
||||
* Получить Future[(Seq[String], Seq[Throwable]) - результат агрегации
|
||||
* выполненных Future и исключений
|
||||
*/
|
||||
def sequenceF(seq: Seq[Future[String]])
|
||||
(implicit ec: ExecutionContext): Future[(Seq[String], Seq[Throwable])] = {
|
||||
Future.sequence(
|
||||
seq.map { ftr =>
|
||||
ftr.map(Right(_)).recover { case NonFatal(e) => Left(e) }
|
||||
}
|
||||
).map { seq =>
|
||||
seq.foldLeft((Seq.empty[String], Seq.empty[Throwable])) {
|
||||
case ((res, errs), Left(e)) => (res, errs :+ e)
|
||||
case ((res, errs), Right(str)) => (res :+ str, errs)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
import scala.concurrent.ExecutionContext.Implicits.global
|
||||
|
||||
val (exp1, exp2, exp3) = (
|
||||
new RuntimeException("exception1"),
|
||||
new RuntimeException("exception2"),
|
||||
new RuntimeException("exception3")
|
||||
)
|
||||
val talk = Seq(
|
||||
Future {
|
||||
Thread.sleep(1000)
|
||||
"red"
|
||||
},
|
||||
Future.failed(exp1),
|
||||
Future.successful("blue"),
|
||||
Future.failed(exp2),
|
||||
Future.successful("green"),
|
||||
Future.failed(exp3)
|
||||
)
|
||||
|
||||
val resF = sequenceF(talk)
|
||||
val (res, errs) = Await.result(resF, 1.minute)
|
||||
|
||||
println(res)
|
||||
assert(res == Seq("red", "blue", "green"))
|
||||
|
||||
println(errs)
|
||||
assert(errs == Seq(exp1, exp2, exp3))
|
||||
}
|
||||
36
src/main/scala/test3.scala
Normal file
36
src/main/scala/test3.scala
Normal file
@@ -0,0 +1,36 @@
|
||||
object test3 extends App {
|
||||
/**
|
||||
* Transformation Chain
|
||||
* Дан набор возможных трансформаций: type Transformation[T] = T => Option[T]
|
||||
* Написать функцию преобразования последовательности трансформаций в возможную трансформацию.
|
||||
* Новая трансформация это результат работы всей цепочки трансформаций, которые не вернули None.
|
||||
* Если все вернули None, то общий результат None.
|
||||
*/
|
||||
|
||||
type Transformation[T] = T => Option[T]
|
||||
|
||||
def transformationChain[T](chain: Seq[Transformation[T]]): Transformation[T] =
|
||||
(t: T) => {
|
||||
chain.foldLeft(Option.empty[T]) { (acc, trm) =>
|
||||
acc.flatMap { t =>
|
||||
trm(t) match {
|
||||
case s: Some[T] => s
|
||||
case None => Some(t)
|
||||
}
|
||||
}.orElse(trm(t))
|
||||
}
|
||||
}
|
||||
|
||||
val t1: Transformation[Int] = t => Some(t + t)
|
||||
val t2: Transformation[Int] = _ => None
|
||||
val t3: Transformation[Int] = t => if(t > 2) Some(t * t) else None
|
||||
|
||||
val tc1 = transformationChain(Seq(t1,t2,t3))
|
||||
val tc2 = transformationChain(Seq(t2,t3))
|
||||
|
||||
println(tc1(2), tc1(1), tc2(1))
|
||||
|
||||
assert(tc1(2).contains(16))
|
||||
assert(tc1(1).contains(2))
|
||||
assert(tc2(1).isEmpty)
|
||||
}
|
||||
Reference in New Issue
Block a user