====== Curs 6. Aplicatii cu liste ====== /* Avem un sir, care contine numere si whitespace. "12 4 560 3" Vrem sa realizam un split dupa whitespace al acestui sir: "12", "4", "560", "3" */ type Sir = List[Char] /* Haide sa parsam un CSV. a,b,c d,e,f g,h,i */ val csvContents: Sir = """a,b,c |d,e,f |g,h,i |""".stripMargin.toList type Table = List[List[Sir]] //split('\n')(csvContents) //split('\n')(csvContents) // .map(split(',')) def readCSV(content: Sir): Table = { def split(delim: Char)(s: Sir): List[Sir] = { def op (c: Char, acc: List[Sir]): List[Sir] = acc match { case Nil => if (c == delim) Nil else List(List(c)) case x :: xs => if (c == delim) Nil :: acc else (c :: x) :: xs } s.foldRight(Nil: List[Sir])(op) } split('\n')(content) .map(split(',')) } readCSV(csvContents) def writeCSV(t: Table): Sir = { def op(delim: Char)(e: Sir, acc: Sir): Sir = acc match { case Nil => e case _ => e ++ List(delim)++acc } t.foldRight(Nil:Sir)((line, acc) => line.foldRight(Nil:Sir)(op(',')) ++ List('\n') ++ acc ) // t.map(line => line.foldRight(Nil:Sir)(op(','))) // .foldRight(Nil:Sir)(op('\n')) } val f: (Int,Int) => Int = (x, y) => x + y val g: (Int,Int) => Int = _ + _ /* Vrem sa citim, in loc de un fisier CSV, o matrice de Int */ type Matrix = List[List[Int]] type Tabular[A] = List[List[A]] def readTabular[A](read:Sir => A)(content: Sir): Tabular[A] = { def split(delim: Char)(s: Sir): List[Sir] = { def op (c: Char, acc: List[Sir]): List[Sir] = acc match { case Nil => if (c == delim) Nil else List(List(c)) case x :: xs => if (c == delim) Nil :: acc else (c :: x) :: xs } s.foldRight(Nil: List[Sir])(op) } split('\n')(content) .map((split(',')(_)).andThen(_.map(read(_)))) } val m = """1,2,3 |4,5,6 |7,8,9 |""".stripMargin.toList val m1: Tabular[Int] = readTabular(_.foldRight("")(_ + _).toInt)(m) m1.map(_.map(_*2)) def transpose(m: Matrix): Matrix = m match{ case Nil :: _ => Nil case _ => m.map(_.head) :: transpose(m.map(_.tail)) } List(1,2,3).zip(List(1,0,0)) .map(pair => pair._1 * pair._2) .foldRight(0)(_ + _) /* 1 2 3 1 0 0 (deja transpusa) 4 5 6 1 1 0 7 8 9 0 1 0 vreau sa calculez prima linie din matricea produs: */ List(List(1,0,0),List(1,1,0),List(0,1,0)) .map(List(1,2,3).zip(_).map(pair => pair._1 * pair._2).sum) /* daca vreau sa construiesc matricea produs: */ val transposed = List(List(1,0,0),List(1,1,0),List(0,1,0)) List(List(1,2,3),List(4,5,6),List(7,8,9)). map(line => transposed.map(line.zip(_).map(pair => pair._1 * pair._2).sum)) def product(m1: Matrix, m2: Matrix): Matrix = m1.map( line => transpose(m2).map( col => line.zip(col).map(pair => pair._1 * pair._2).foldRight(0)(_ + _))) val m1 = List(List(1,2,3),List(4,5,6),List(7,8,9)) val m2 = List(List(1,0,0),List(0,1,0),List(0,0,1)) product(m1,m2)