Skip to content

Commit

Permalink
Solutions from Scalania 8
Browse files Browse the repository at this point in the history
  • Loading branch information
jaceklaskowski committed Nov 30, 2013
1 parent ad2f08c commit d63535f
Show file tree
Hide file tree
Showing 11 changed files with 159 additions and 20 deletions.
2 changes: 1 addition & 1 deletion build.sbt
Expand Up @@ -14,7 +14,7 @@ libraryDependencies in Global += "org.specs2" %% "specs2" % "2.4-SNAPSHOT" % "te

resolvers in Global ++= Seq("snapshots", "releases").map(Resolver.sonatypeRepo)

lazy val scalania = project.in(file(".")).aggregate(exercises)
lazy val scalania = project in file(".") aggregate exercises

lazy val exercises = project

Expand Down
8 changes: 8 additions & 0 deletions exercises/src/main/scala/pl/japila/scalania/package.scala
@@ -0,0 +1,8 @@
package pl.japila

package object scalania {

def solutionName(s: Any) =
s.getClass.getSimpleName.split("\\$").drop(1).dropRight(1).mkString("_")

}
24 changes: 23 additions & 1 deletion exercises/src/main/scala/pl/japila/scalania/s99/S99_P20.scala
@@ -1,5 +1,27 @@
package pl.japila.scalania.s99

object S99_P20 {
def removeAt[T](n: Int, ts: Seq[T]): (Seq[T], T) = ???

val solutions = Seq[(Int, Seq[Any]) => (Seq[Any], Any)](
removeAt,
removeAt_jacekkolodziejski,
removeAt_ajozwik
)

def removeAt[T] = (n: Int, ts: Seq[T]) => ???

def removeAt_jacekkolodziejski[T] = (n: Int, ts: Seq[T]) =>
(ts.take(n) ++ ts.drop(n + 1), ts(n))

def removeAt_ajozwik[T] = (n: Int, ts: Seq[T]) => {
val (l, _, t) = ts.foldLeft[(Seq[T], Int, Option[T])]((Seq[T](), n, None))((acc, el) => {
if (acc._2 == 0) {
(acc._1, acc._2 - 1, Some(el))
} else {
(el +: acc._1, acc._2 - 1, acc._3)
}
}
)
(l.reverse, t.get)
}
}
47 changes: 46 additions & 1 deletion exercises/src/main/scala/pl/japila/scalania/s99/S99_P21.scala
@@ -1,5 +1,50 @@
package pl.japila.scalania.s99

object S99_P21 {
def insertAt[T](toAdd: T, position: Int, ts: Seq[T]): Seq[T] = ???

val solutions = Seq[(Any, Int, Seq[Any]) => Seq[Any]](
insertAt,
insertAt_tboloo,
insertAt_7680700,
insertAt_PawelPanasewicz,
insertAt_ajozwik
)

def insertAt[T] = (toAdd: T, position: Int, ts: Seq[T]) => ???

def insertAt_tboloo[T]: (T, Int, Seq[T]) => Seq[T] =
(toAdd: T, position: Int, ts: Seq[T]) => {
(position, ts) match {
case (0, h :: t) => Seq(toAdd) ++ t
case (position, h :: t) => Seq(h) ++ insertAt_tboloo(toAdd, position - 1, t)
}
}

def insertAt_7680700[T] = (toAdd: T, position: Int, ts: Seq[T]) => {
@annotation.tailrec
def go(n: Int, l: List[T], r: List[T]): List[T] = {
if (n == 0) l.reverse ::: toAdd :: r
else go(n - 1, r.head :: l, r.tail)
}
go(position, Nil, ts.toList)
}

def insertAt_PawelPanasewicz[T] = (toAdd: T, position: Int, ts: Seq[T]) =>
ts.patch(position, Seq(toAdd), 0)

def insertAt_ajozwik[T] = (toAdd: T, position: Int, ts: Seq[T]) => {
def insertToAcc: ((Seq[T], Int), T) => (Seq[T], Int) = {
(acc, current) =>
{
val (seq, index) = acc
if (index == 0) {
(current +: toAdd +: seq, index - 1)
} else {
(current +: seq, index - 1)
}
}
}
val (l, _) = ts.foldLeft[(Seq[T], Int)]((Seq[T](), position))(insertToAcc)
l.reverse
}
}
45 changes: 44 additions & 1 deletion exercises/src/main/scala/pl/japila/scalania/s99/S99_P22.scala
@@ -1,5 +1,48 @@
package pl.japila.scalania.s99

object S99_P22 {
def range(from: Int, to: Int): Seq[Int] = ???

val solutions = Seq[(Int, Int) => Seq[Int]](
range,
range_7680926,
range_mprowaznik,
range_tboloo,
range_ajozwik,
range_7681054
)

def range = (from: Int, to: Int) => ???

def range_7680926: (Int, Int) => Seq[Int] = (from, to) => {
if (to < from) {
throw new IllegalArgumentException("Invalid range")
}
from match {
case `to` => List(from)
case x => List(from) ++ range_7680926(from + 1, to)
}
}

def range_mprowaznik = (from: Int, to: Int) =>
(from to to).toList

def range_tboloo: (Int, Int) => Seq[Int] = (from, to) =>
(from, to) match {
case (from, to) if from != to => Seq(from) ++ range_tboloo(from + 1, to)
case _ => Nil
}

def range_ajozwik = (from: Int, to: Int) => {
def fromN(n: Int): Stream[Int] = n #:: fromN(n + 1)
fromN(from).take(to - from + 1).toList
}

def range_7681054 = (from: Int, to: Int) => {
@annotation.tailrec
def go(i: Int, acc: Seq[Int]): Seq[Int] = {
if (i > to) acc.reverse
else go(i + 1, i +: acc)
}
go(from, Seq())
}
}
@@ -1,6 +1,7 @@
package pl.japila.scalania.euler

import org.specs2.mutable._
import pl.japila.scalania._
import Euler_P01._

class P01Spec extends Specification with ExamplesBlock {
Expand All @@ -12,6 +13,4 @@ class P01Spec extends Specification with ExamplesBlock {
}
}
}

def solutionName(s: Any) = s.getClass.getSimpleName.split("\\$").drop(1).dropRight(1).mkString("_")
}
16 changes: 11 additions & 5 deletions exercises/src/test/scala/pl/japila/scalania/s99/P20Spec.scala
@@ -1,14 +1,20 @@
package pl.japila.scalania.s99

import org.specs2.mutable._
import S99_P20.removeAt
import pl.japila.scalania._

class P20Spec extends Specification {
class P20Spec extends Specification with ExamplesBlock {
"P20 solution" should {
"Remove the Kth element from a list." in {
val (ts, t) = removeAt(1, List('a, 'b, 'c, 'd))
ts === List('a, 'c, 'd)
t === 'b
import S99_P20.solutions
solutions.map(s => (s"${solutionName(s)} solution", s)).foreach {
case (solution, s) =>
solution >> {
val (ts, t) = s(1, Seq('a, 'b, 'c, 'd))
ts === Seq('a, 'c, 'd)
t must_== 'b
}
}
}
}
}
14 changes: 11 additions & 3 deletions exercises/src/test/scala/pl/japila/scalania/s99/P21Spec.scala
@@ -1,12 +1,20 @@
package pl.japila.scalania.s99

import org.specs2.mutable._
import S99_P21.insertAt
import pl.japila.scalania._

class P21Spec extends Specification {
class P21Spec extends Specification with ExamplesBlock {
"P21 solution" should {
"Insert an element at a given position into a list." in {
insertAt('new, 1, List('a, 'b, 'c, 'd)) === List('a, 'new, 'b, 'c, 'd)
import S99_P21.solutions
solutions.map(s => (s"${solutionName(s)} solution", s)).foreach {
case (solution, s) =>
solution >> {
val actual = s('new, 1, Seq('a, 'b, 'c, 'd))
val expected = Seq('a, 'new, 'b, 'c, 'd)
actual === expected
}
}
}
}
}
16 changes: 12 additions & 4 deletions exercises/src/test/scala/pl/japila/scalania/s99/P22Spec.scala
@@ -1,12 +1,20 @@
package pl.japila.scalania.s99

import org.specs2.mutable._
import S99_P22.range
import pl.japila.scalania._

class P22Spec extends Specification {
class P22Spec extends Specification with ExamplesBlock {
"P22 solution" should {
" Create a list containing all integers within a given range." in {
range(4, 9) === List(4, 5, 6, 7, 8, 9)
"Create a list containing all integers within a given range." in {
import S99_P22.solutions
solutions.map(s => (s"${solutionName(s)} solution", s)).foreach {
case (solution, s) =>
solution >> {
val actual = s(4, 9)
val expected = Seq(4, 5, 6, 7, 8, 9)
actual must_== expected
}
}
}
}
}
Expand Up @@ -5,7 +5,7 @@ import S99_P24.lotto

class P24Spec extends Specification {
"P24 solution" should {
" Lotto: Draw N different random numbers from the set 1..M." in {
"Lotto: Draw N different random numbers from the set 1..M." in {
val randomrange = lotto(6, 49)
randomrange.distinct.size === 6
randomrange.forall(e => 1 <= e && e <= 49) === true
Expand Down
Expand Up @@ -6,7 +6,7 @@ import S99_P28.lsortFreq

class P28Spec extends Specification {
"P28a solution" should {
" Sort a list of lists according to length of sublists." in {
"Sort a list of lists according to length of sublists." in {
lsort(List(List('a, 'b, 'c), List('d, 'e), List('f, 'g, 'h), List('d, 'e), List('i, 'j, 'k, 'l), List('m, 'n), List('o))) === List(List('o), List('d, 'e), List('d, 'e), List('m, 'n), List('a, 'b, 'c), List('f, 'g, 'h), List('i, 'j, 'k, 'l))
}
}
Expand Down

0 comments on commit d63535f

Please sign in to comment.