├── Quiz ├── 20160504 │ └── solution.scala ├── 20160726 │ └── QuizDecimal.scala ├── 2016-05-09 │ └── woo-kil.scala ├── 2016-06-07 │ └── maxsum.scala ├── 2016-06-14 │ └── Quiz160614.scala ├── 2017-03-07 │ ├── lazysoul_lookAndSay.kt │ └── lazysoul_lookAndSay2 ├── Factorial.scala ├── Gcd.scala ├── HotSummer.scala ├── StringJoin.scala ├── codingtest │ ├── maxDays.scala │ └── maxnum.scala ├── fibonacci.scala ├── insertionSort.scala ├── mergeSort.scala ├── spiral.scala └── trait_base1.scala ├── README.md ├── covariance ├── sample01.scala ├── sample02.scala └── sample03.scala ├── fpinscala ├── datastructure_exam.scala └── fp_datasturucture.scala └── images ├── 4-1.png ├── 스크린샷 2016-10-02 오후 6.06.50.png ├── 스크린샷 2016-10-02 오후 6.06.50.png └── 폴더설명 /Quiz/2016-05-09/woo-kil.scala: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by myeongin on 2016. 5. 9.. 3 | */ 4 | import java.io.PrintWriter 5 | import java.io._ 6 | import scala.util.control.Breaks._ 7 | import scala.io.Source 8 | 9 | object Main { 10 | 11 | def main(args: Array[String]) { 12 | val line = Source.fromFile("files/A-large-practice.in").getLines.toList 13 | 14 | val inputs = line.tail 15 | var count = 1 16 | 17 | //파일로드 18 | val writer = new PrintWriter(new File("files/A-large-practice.out")) 19 | 20 | inputs.foreach(input => { 21 | val result = s"Case #$count: ${largeSolution(input.split(" "))}\n" 22 | writer.write(result) 23 | count +=1 24 | }) 25 | 26 | writer.close() 27 | } 28 | 29 | //라지 케이스를 풀면서 개선한 알고리즘 시간복잡도가 많이 단축 됬다 30 | def largeSolution(inputList : Array[String]): Long ={ 31 | val month = inputList(0).toLong 32 | val days = inputList(1).toInt 33 | val weeks = inputList(2).toInt 34 | 35 | var sum = 0 :Long 36 | var remaind = 0 37 | 38 | val map = scala.collection.mutable.Map.empty[Long, Long] 39 | 40 | var count = 0 41 | breakable{ 42 | while(remaind != 0||map.size != -1){ 43 | sum += getSum(remaind, days, weeks) 44 | remaind = getRemaind(remaind, days, weeks) 45 | 46 | map(count) = sum 47 | 48 | if(remaind == 0) 49 | break() 50 | 51 | count += 1 52 | } 53 | } 54 | 55 | if(map.nonEmpty){ 56 | val sumOfCycle = map(map.size-1) 57 | sum = sumOfCycle * (month / map.size) 58 | 59 | val a = month % map.size 60 | 61 | if(a != 0) 62 | sum += map(a-1) 63 | } else{ 64 | sum = month*(days/weeks) 65 | } 66 | sum 67 | } 68 | 69 | //스몰 케이스 값을 구했을 때 했던 시간 복잡도가 높았던 알고리즘 70 | def smallSolution(inputList : Array[String]): Int ={ 71 | 72 | val month = inputList(0).toLong 73 | val days = inputList(1).toInt 74 | val weeks = inputList(2).toInt 75 | 76 | 77 | var sum = 0 78 | var remaind = 0 79 | 80 | for(i <- 0L until month){ 81 | sum+= getSum(remaind, days, weeks) 82 | remaind = getRemaind(remaind, days, weeks) 83 | } 84 | sum 85 | } 86 | 87 | //이전 달의 나머지값과 현재 달의 일수를 더해서 달력의 줄을 계산한다 88 | def getSum(value : Int, days : Int, weeks : Int) :Int = if((days+value)%weeks == 0 ) (days+value)/weeks else (days+value)/weeks +1 89 | 90 | //이번 달의 마지막 줄의 나머지 값을 구한다 91 | def getRemaind(remaind :Int, days : Int , weeks:Int): Int = (days+remaind)%weeks 92 | 93 | 94 | } 95 | -------------------------------------------------------------------------------- /Quiz/2016-06-07/maxsum.scala: -------------------------------------------------------------------------------- 1 | object Main { 2 | 3 | def getMaxSum(maxSum : Int, currentSum : Int, input: List[Int]): Int = input match { 4 | case x :: xs => if( currentSum + x > 0 ) getMaxSum(Math.max(maxSum, currentSum + x), currentSum + x, xs) else getMaxSum(maxSum, 0, xs) 5 | case Nil => maxSum 6 | 7 | } 8 | 9 | def main(args: Array[String]) { 10 | 11 | val num = scala.io.StdIn.readLine().toInt 12 | for (i <- 0 until num) { 13 | val value = scala.io.StdIn.readLine 14 | val input = scala.io.StdIn.readLine.split(" ").map(_.toInt).toList 15 | println(getMaxSum(0, 0, input)) 16 | } 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /Quiz/2016-06-14/Quiz160614.scala: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by com on 2016-07-27. 3 | */ 4 | 5 | object main { 6 | 7 | var primeList = List[Int]() 8 | 9 | def main(args: Array[String]) { 10 | val min = scala.io.StdIn.readLine().toInt 11 | val max = scala.io.StdIn.readLine().toInt 12 | println("================================") 13 | println(s">> min : $min") 14 | println(s">> max : $max") 15 | println(s">> result : ${getPrimes((2 to max).toList, min)}") 16 | } 17 | 18 | def getPrimes(sus: List[Int], min: Int): List[Int] = { 19 | sus.filter(isPrime).filter(min < _) 20 | } 21 | 22 | def isPrime(su: Int): Boolean = su match { 23 | case 2 => 24 | primeList = List(2) 25 | true 26 | case _ => 27 | if (primeList.find(su % _ == 0).size == 1) { 28 | false 29 | } else { 30 | primeList = su +: primeList 31 | true 32 | } 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /Quiz/20160504/solution.scala: -------------------------------------------------------------------------------- 1 | /** 2 | * > soultion1 3 | * input : I am a boy 4 | * output : boy a am I 5 | * 6 | * > soultion2 7 | * input : I am a boy 8 | * output : yob a ma I 9 | */ 10 | object solution12 { 11 | def main(args: Array[String]): Unit = { 12 | val inputString = scala.io.StdIn.readLine 13 | println("input : " + inputString) 14 | 15 | println("solution1 : " + solution1(inputString)) 16 | println("solution2 : " + solution2(inputString)) 17 | } 18 | 19 | def solution1(inputString: String) = { 20 | inputString.split(" ").reverse.mkString(" ") 21 | } 22 | 23 | def solution2(inputString: String): String = { 24 | val result = for (s <- inputString.split(" ").reverse) 25 | yield s.reverse 26 | result.mkString(" ") 27 | } 28 | } 29 | 30 | /** 31 | * > 교집합 32 | * input : [A, B, C, D], [C, D, E, F] 33 | * output : [C, D] 34 | */ 35 | object solution3 { 36 | def main(args: Array[String]) { 37 | val a = List("A", "B", "C", "D") 38 | val b = List("C", "D", "E", "F") 39 | 40 | var map = scala.collection.mutable.Map.empty[String, Int] 41 | for(s <- a) { 42 | map(s) = 1 43 | } 44 | for(s <- b) { 45 | if(map.contains(s)) 46 | map(s) += 1; 47 | } 48 | 49 | println(map.filter(_._2 > 1).keys.mkString(" ")) 50 | } 51 | } 52 | 53 | /** 54 | * [23, 32, 3, 9 , 40] 원소의 값을 조합해서 가장 큰 정수를 리턴하시오. 55 | * output : 94033223 56 | */ 57 | 58 | 59 | -------------------------------------------------------------------------------- /Quiz/20160726/QuizDecimal.scala: -------------------------------------------------------------------------------- 1 | object QuizDecimal { 2 | 3 | var primeList = List[Int]() 4 | 5 | def main(args: Array[String]) { 6 | val min = scala.io.StdIn.readLine().toInt 7 | val max = scala.io.StdIn.readLine().toInt 8 | println("================================") 9 | println(">> min : " + min) 10 | println(">> max : " + max) 11 | println(">> result : " + getPrimes((2 to max).toList, min)) 12 | } 13 | 14 | def getPrimes(sus: List[Int], min: Int): List[Int] = { 15 | sus.filter(isPrime(_)).filter(min <= _) 16 | } 17 | 18 | def isPrime(su: Int): Boolean = { 19 | if (primeList.find(su % _ == 0).size == 1) { 20 | false 21 | } else { 22 | primeList = su +: primeList 23 | true 24 | } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /Quiz/2017-03-07/lazysoul_lookAndSay.kt: -------------------------------------------------------------------------------- 1 | object LookAndSay { 2 | @JvmStatic 3 | fun main(args: Array) { 4 | println(lookAndSay(10)) 5 | } 6 | 7 | fun lookAndSay(value: Int): String { 8 | fun getValue(curr: Int, limit: Int, acc: String = "1"): String { 9 | return if (curr == limit) { 10 | acc 11 | } else { 12 | getValue(curr + 1, limit, acc.parse()) 13 | } 14 | } 15 | return getValue(1, value) 16 | } 17 | 18 | fun String.parse(): String { 19 | return if (this.isEmpty()) { 20 | "" 21 | } else { 22 | val header = this.takeWhile { this[0] == it } 23 | "${header[0]}${header.length}${this.drop(header.length).parse()}" 24 | } 25 | } 26 | 27 | } 28 | -------------------------------------------------------------------------------- /Quiz/2017-03-07/lazysoul_lookAndSay2: -------------------------------------------------------------------------------- 1 | object LookAndSay { 2 | @JvmStatic 3 | fun main(args: Array) { 4 | generateSequence(listOf(1)) { getValue(it) } 5 | .take(100) 6 | } 7 | 8 | fun getValue(list: List): List { 9 | val size = list.takeWhile { it == list.first() }.count() 10 | if (list.size == size) { 11 | return listOf(list.first(), size) 12 | } else { 13 | return listOf(list.first(), size) 14 | .plus(getValue(list.drop(size))) 15 | } 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /Quiz/Factorial.scala: -------------------------------------------------------------------------------- 1 | object Factorial { 2 | def main(args: Array[String]): Unit = { 3 | // 인자를 받는다 4 | val input = Integer.parseInt(readLine()) 5 | println("result = " + factorial(input, input)) 6 | } 7 | 8 | def factorial(v: Int, sum: Int): Int = { 9 | println("v : " + v + ", sum : " + sum) 10 | if (v > 1) { 11 | factorial(v - 1, sum * (v - 1)); 12 | } else { 13 | sum 14 | } 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /Quiz/Gcd.scala: -------------------------------------------------------------------------------- 1 | object gcd { 2 | def main(args: Array[String]): Unit = { 3 | // 인자를 받는다 4 | val input = readLine() 5 | val array = input.split(",") 6 | println(gcd(array(0).toInt, array(1).toInt)) 7 | } 8 | 9 | def gcd(n: Int, n2: Int): Int = { 10 | println(s"$n $n2") 11 | if (n2 == 0) { 12 | n 13 | } 14 | else { 15 | gcd(n2, n % n2) 16 | } 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /Quiz/HotSummer.scala: -------------------------------------------------------------------------------- 1 | object Main { 2 | def main(args: Array[String]): Unit = { 3 | val maxPower = scala.io.StdIn.readLine.toInt 4 | val powers = scala.io.StdIn.readLine.split(" ") 5 | 6 | println(checkPower(maxPower, powers)) 7 | } 8 | 9 | def checkPower(maxPower: Int, powers: Array[String]): Boolean = { 10 | // var sum = 0 11 | // for (i <- powers) { 12 | // sum += i.toInt 13 | // } 14 | maxPower > powers.foldLeft(0)((m: Int, n: String) => m + n.toInt) 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /Quiz/StringJoin.scala: -------------------------------------------------------------------------------- 1 | import scala.annotation.tailrec 2 | 3 | object Main { 4 | 5 | def main(args: Array[String]) { 6 | // val line = Source.fromFile("files/A-large-practice.in").getLines 7 | val inputNum = scala.io.StdIn.readLine().toInt 8 | 9 | for (i <- 0 until inputNum) { 10 | val num = scala.io.StdIn.readLine().toInt 11 | val numList = createNumList() 12 | println(solution(numList.sorted, 0)) 13 | } 14 | } 15 | 16 | def createNumList(): List[Int] = { 17 | scala.io.StdIn.readLine().split(" ") 18 | .toList 19 | .map(_.toInt) 20 | } 21 | 22 | @tailrec 23 | def solution(numList: List[Int], accm: Int): Int = numList match { 24 | case head :: List() => { 25 | accm 26 | } 27 | case head :: tail => { 28 | val newList = head + tail.head :: tail.tail 29 | solution(newList.sorted, accm + head + tail.head) 30 | } 31 | } 32 | 33 | } 34 | -------------------------------------------------------------------------------- /Quiz/codingtest/maxDays.scala: -------------------------------------------------------------------------------- 1 | import scala.annotation.tailrec 2 | 3 | object Main { 4 | 5 | val days = List(31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31) 6 | val weeks = List("Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday") 7 | 8 | def main(args: Array[String]): Unit = { 9 | val num = scala.io.StdIn.readLine.toInt 10 | for (i <- 0 until num) { 11 | val value = scala.io.StdIn.readLine 12 | solve(value) 13 | } 14 | } 15 | 16 | def solve(value : String): Unit ={ 17 | val values = value.split(" ") 18 | val m = values(0).toInt 19 | val d = values(1).toInt 20 | val w = values(2) 21 | println(parse(m, d, w)) 22 | } 23 | 24 | def parse(month : Int, day : Int, week : String) : String = { 25 | val preMaxDay = days(if(month-2 < 0) 11 else month-2) 26 | val maxDay = days(month-1) 27 | val pos = weeks.indexOf(week) 28 | val result1 = leftSolve(List(), day-1, pos-1, preMaxDay) 29 | val result2 = rightSolve(List(), day+1, pos+1, maxDay) 30 | 31 | val result = result1 ::: (day :: result2.reverse) 32 | 33 | result.mkString(" ") 34 | } 35 | 36 | @tailrec 37 | def leftSolve(result : List[Int], curr : Int, pos : Int, preMax : Int) : List[Int]= { 38 | pos match { 39 | case -1 => result 40 | case _ => 41 | val value = if(curr <= 0) preMax else curr 42 | leftSolve(value :: result , value -1, pos -1, preMax) 43 | } 44 | } 45 | 46 | @tailrec 47 | def rightSolve(result : List[Int], currDay : Int, pos : Int, max : Int) : List[Int]= { 48 | pos match { 49 | case 7 => result 50 | case _ => 51 | val value = if(currDay > max) 1 else currDay 52 | rightSolve(value :: result , value +1, pos +1, max) 53 | } 54 | } 55 | 56 | 57 | } 58 | -------------------------------------------------------------------------------- /Quiz/codingtest/maxnum.scala: -------------------------------------------------------------------------------- 1 | import scala.annotation.tailrec 2 | import scala.collection.immutable.ListMap 3 | import scala.collection.mutable 4 | 5 | /** 6 | * Created by n3956 on 2016-05-25. 7 | */ 8 | object Hello { 9 | def main(args: Array[String]) { 10 | 11 | val inputList = List(23, 3, 32, 38, 392, 382, 2, 9, 92, 263, 4, 2138) 12 | val result = getResult(inputList) 13 | println(result.mkString("")) 14 | } 15 | 16 | def getResult(inputList: List[Int]) = { 17 | val group = createGroup(inputList) 18 | val result = ListMap(group.toSeq.sortWith(_._1 > _._1):_*).flatMap( _._2) 19 | println(result) 20 | result 21 | } 22 | 23 | def isBigger(num: Int, head: Int): Boolean = { 24 | val numLength = getNumberLength(num) 25 | val headLength = getNumberLength(head) 26 | 27 | if(numLength == headLength){ 28 | if(num >= head) 29 | true 30 | else 31 | false 32 | } else { 33 | if(numLength > headLength){ 34 | isBigger(num, createBasNumber(head, getKeyOfNum(head), numLength-headLength)) 35 | } else { 36 | isBigger(createBasNumber(num, getKeyOfNum(num), headLength-numLength), head) 37 | } 38 | } 39 | } 40 | 41 | def sortList(num: Int, list: List[Int]): List[Int] = list match { 42 | case Nil => num :: Nil 43 | case x :: xs => { 44 | if (isBigger(num, x)) { 45 | num :: list 46 | } else { 47 | x :: sortList(num, xs) 48 | } 49 | } 50 | } 51 | 52 | def insertMap(num: Int, map: mutable.Map[Int, List[Int]]) = { 53 | val key: Int = getKeyOfNum(num) 54 | if (map.contains(key)) { 55 | map(key) = sortList(num, map(key)) 56 | } else { 57 | map(key) = num :: Nil 58 | } 59 | } 60 | 61 | def createGroup(input: List[Int]): mutable.Map[Int, List[Int]] = { 62 | val map = scala.collection.mutable.Map.empty[Int, List[Int]] 63 | 64 | input.foreach(num => { 65 | insertMap(num, map) 66 | }) 67 | map 68 | } 69 | 70 | @tailrec 71 | def getKeyOfNum(num: Int): Int = { 72 | num / 10 match { 73 | case 0 => num % 10 74 | case _ => getKeyOfNum(num / 10) 75 | } 76 | } 77 | 78 | def getNumberLength(num : Int): Int ={ 79 | var count =1 80 | var baseNumber = num 81 | while (baseNumber/10 !=0 ){ 82 | baseNumber /=10 83 | count+=1 84 | } 85 | count 86 | } 87 | 88 | def createBasNumber(num : Int, key : Int, length : Int) : Int = { 89 | var result = num 90 | var count = length 91 | while (count > 0) { 92 | result = result * 10 + key 93 | count -= 1 94 | } 95 | result 96 | } 97 | 98 | } 99 | -------------------------------------------------------------------------------- /Quiz/fibonacci.scala: -------------------------------------------------------------------------------- 1 | object Main { 2 | 3 | val baseArr : List[Int] = List(0,1) 4 | 5 | def main(args: Array[String]): Unit = { 6 | val num = scala.io.StdIn.readLine.toInt 7 | 8 | println(solve(num)) 9 | } 10 | 11 | //노가다 12 | def solve(value : Int) : Int = value match { 13 | case 1 => 0 14 | case 2 => 1 15 | case _ => fibonach(baseArr, value).last 16 | 17 | } 18 | 19 | def fibonach(arr : List[Int], num : Int) : List[Int] = { 20 | 21 | val preNum1 = arr(arr.length-2) 22 | val preNum2 = arr(arr.length-1) 23 | val result : List[Int] = arr ::: preNum1 + preNum2 :: Nil 24 | 25 | println(result) 26 | 27 | if(result.length == num) 28 | result 29 | else 30 | fibonach(result, num) 31 | } 32 | 33 | //좋은 해답 34 | def fib1( n : Int) : Int = n match { 35 | case 0 | 1 => n 36 | case _ => fib1( n-1 ) + fib1( n-2 ) 37 | } 38 | 39 | /** 40 | * 41 | * int fibo(int num) { 42 | if(num == 0) return 0; 43 | else if(num == 1) return 1; 44 | else return fibo(num-1) + fibo(num-2); 45 | } 46 | * / 47 | } 48 | -------------------------------------------------------------------------------- /Quiz/insertionSort.scala: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by kgkim on 2016. 4. 24.. 3 | */ 4 | object insertion { 5 | def isort(xs: List[Int]): List[Int] = 6 | if (xs.isEmpty) Nil 7 | else insert(xs.head, isort(xs.tail)) 8 | 9 | def insert(x: Int, xs: List[Int]): List[Int] = 10 | if (xs.isEmpty || x <= xs.head) x :: xs 11 | else xs.head :: insert(x, xs.tail) 12 | 13 | // 리스트 패턴 매칭 14 | def isort2(xs: List[Int]): List[Int] = xs match { 15 | case List() => List() 16 | case x :: xs1 => insert2(x, isort2(xs1)) 17 | } 18 | 19 | def insert2(x: Int, xs: List[Int]): List[Int] = xs match { 20 | case List() => List(x) 21 | case y :: ys => if (x <= y) x :: xs 22 | else y :: insert2(x, ys) 23 | } 24 | 25 | def main(args: Array[String]) { 26 | println(isort(List(8, 10, 2, 4, 1, 9, 6, 3, 7, 5))) 27 | println(isort2(List(8, 10, 2, 4, 1, 9, 6, 3, 7, 5))) 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /Quiz/mergeSort.scala: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by kgkim on 2016. 4. 25.. 3 | */ 4 | object merge { 5 | def msort[T](less: (T, T) => Boolean)(xs: List[T]): List[T] = { 6 | def merge(xs: List[T], ys: List[T]): List[T] = 7 | (xs, ys) match { 8 | case (Nil, _) => ys 9 | case (_, Nil) => xs 10 | case (x :: xs1, y :: ys1) => 11 | if (less(x, y)) x :: merge(xs1, ys) 12 | else y :: merge(xs, ys1) 13 | } 14 | val n = xs.length / 2 15 | 16 | if (n == 0) xs 17 | else { 18 | val (ys, zs) = xs splitAt n 19 | merge(msort(less)(ys), msort(less)(zs)) 20 | } 21 | } 22 | 23 | def msortSwapped[T](xs: List[T])(less: (T, T) => Boolean): List[T] = { 24 | def merge(xs: List[T], ys: List[T]): List[T] = 25 | (xs, ys) match { 26 | case (Nil, _) => ys 27 | case (_, Nil) => xs 28 | case (x :: xs1, y :: ys1) => 29 | if (less(x, y)) x :: merge(xs1, ys) 30 | else y :: merge(xs, ys1) 31 | } 32 | val n = xs.length / 2 33 | 34 | if (n == 0) xs 35 | else { 36 | val (ys, zs) = xs splitAt n 37 | merge(msort(less)(ys), msort(less)(zs)) 38 | } 39 | } 40 | 41 | def main(args: Array[String]) { 42 | val mixedInts = List(4, 1, 9, 10, 5, 8, 3, 6, 2, 7) 43 | val intSort = msort((x: Int, y: Int) => x < y) _ 44 | val reverseIntSort = msort((x: Int, y: Int) => x > y) _ 45 | 46 | println(msort((x: Int, y: Int) => x < y)(mixedInts)) 47 | println(intSort(mixedInts)) 48 | println(reverseIntSort(mixedInts)) 49 | println(msort[Int](_ < _)(mixedInts)) 50 | println(msortSwapped(mixedInts)(_ < _)) 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /Quiz/spiral.scala: -------------------------------------------------------------------------------- 1 | object Element { 2 | def elem(contents: Array[String]): Element = 3 | new ArrayElement(contents) 4 | def elem(chr: Char, width: Int, height: Int): Element = 5 | new UniformElement(chr, width, height) 6 | def elem(line: String): Element = 7 | new LineElement(line) 8 | } 9 | 10 | class ArrayElement( 11 | val contents: Array[String] 12 | ) extends Element 13 | 14 | class LineElement(s: String) extends Element { 15 | val contents = Array(s) 16 | override def width = s.length 17 | override def height = 1 18 | } 19 | 20 | class UniformElement( 21 | ch: Char, 22 | override val width: Int, 23 | override val height: Int 24 | ) extends Element { 25 | private val line = ch.toString * width 26 | def contents = Array.fill(height)(line) 27 | } 28 | 29 | import Element.elem 30 | abstract class Element { 31 | def contents: Array[String] 32 | 33 | def width: Int = contents(0).length 34 | def height: Int = contents.length 35 | 36 | def above(that: Element): Element = { 37 | val this1 = this widen that.width 38 | val that1 = that widen this.width 39 | elem(this1.contents ++ that1.contents) 40 | } 41 | 42 | def beside(that: Element): Element = { 43 | val this1 = this heighten that.height 44 | val that1 = that heighten this.height 45 | elem( 46 | for ((line1, line2) <- this1.contents zip that1.contents) 47 | yield line1 + line2) 48 | } 49 | 50 | def widen(w: Int): Element = 51 | if (w <= width) this 52 | else { 53 | val left = elem(' ', (w - width) / 2, height) 54 | var right = elem(' ', w - width - left.width, height) 55 | left beside this beside right 56 | } 57 | 58 | def heighten(h: Int): Element = 59 | if (h <= height) this 60 | else { 61 | val top = elem(' ', width, (h - height) / 2) 62 | var bot = elem(' ', width, h - height - top.height) 63 | top above this above bot 64 | } 65 | 66 | override def toString = contents mkString "\n" 67 | } 68 | 69 | object Spiral { 70 | val space = elem(" ") 71 | val corner = elem("+") 72 | def spiral(nEdges: Int, direction: Int): Element = { 73 | if (nEdges == 1) 74 | elem("+") 75 | else { 76 | val sp = spiral(nEdges - 1, (direction + 3) % 4) 77 | def verticalBar = elem('|', 1, sp.height) 78 | def horizontalBar = elem('-', sp.width, 1) 79 | if (direction == 0) 80 | (corner beside horizontalBar) above (sp beside space) 81 | else if (direction == 1) 82 | (sp above space) beside (corner above verticalBar) 83 | else if (direction == 2) 84 | (space beside sp) above (horizontalBar beside corner) 85 | else 86 | (verticalBar above corner) beside (space above sp) 87 | } 88 | } 89 | 90 | def main(args: Array[String]) { 91 | val nSides = scala.io.StdIn.readLine.toInt 92 | println(spiral(nSides, 0)) 93 | } 94 | } 95 | -------------------------------------------------------------------------------- /Quiz/trait_base1.scala: -------------------------------------------------------------------------------- 1 | trait Philosophical { 2 | def philosophize() { 3 | println("I consume memory, therefore I am!") 4 | } 5 | } 6 | 7 | //class Frog extends Philosophical { 8 | // override def toString = "green" 9 | //} 10 | 11 | class Frog extends Animal with Philosophical { 12 | override def toString = "green" 13 | override def philosophize() { 14 | println("It ain't easy being "+ toString +"!") 15 | } 16 | } 17 | 18 | 19 | object trait_base1 { 20 | def main(args: Array[String]) { 21 | // 일반적인 사용 22 | val f = new Frog 23 | println(f) 24 | f.philosophize() 25 | 26 | // trait 형으로 형변환 27 | val phrog: Philosophical = new Frog 28 | phrog.philosophize() 29 | 30 | // 간단하게 응용해서 사용 31 | val x = new AnyRef with Philosophical 32 | x.philosophize() 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # FunctionalPrograming Study 2 | ## 목적 3 | * 기존 oop 관점에서 벗어나 functional 패러다임 경험 및 공부. 4 | * 다양한 Functional 언어의 특성들을 경험하고 이해. 5 | * pair programming을 통한 협업능력 향상 및 사고력 향상 6 | 7 | ## 방식 8 | * 다양한 분야의 사람들과 pair programming을 통해 혼자문제를 해결하기 보다는 같이 토론하고 이해를 목표로 한다. 9 | * 목적없이 따라하거나 복사 붙여넣기 보다는 이해를 우선으로 한다. 10 | * 토즈 등 스터디 공간을 위한 비용은 각출. 11 | * 한 가지 주제를 정하고 그 주제에 대해 스터디를 진행 후 스터디가 마무리되면 다른 주제를 선정하여 진행. 12 | * 기간은 주제에 따라 다름 (1주가 될 수도 있고 4주가 될수도 있다.) 13 | * 주기적으로 알고리즘 등 코드를 풀어서 실습(페어 프로그래밍 ). 14 | 15 | ## 시간 및 장소 16 | * 매주 요일 (8시 반 ~ 10시 반)스터디를 기본으로 함. 17 | * 장소는 코로나로 인해 온라인으로 진행 18 | 19 | ## 스터디 신청 및 연락처 20 | * wtower123@gmail.com 21 | * myeonginwoo@gmail.com 22 | 23 | ## 진행상황 24 | * [위키페이지](https://github.com/funfunStudy/study/wiki) 25 | * [FacebookGroup](https://www.facebook.com/groups/1189616354467814) 26 | -------------------------------------------------------------------------------- /covariance/sample01.scala: -------------------------------------------------------------------------------- 1 | class Flower() {} 2 | class Rose() extends Flower() {} 3 | 4 | class Covariant[-T] 5 | 6 | object VariancesTest extends App { 7 | // def addFlower(flower: Array[Flower]) 8 | def addFlower[T <: Flower](flower: Array[T]) {} 9 | 10 | val r = Array(new Rose()) 11 | addFlower(r) 12 | 13 | 14 | //val cv1: Covariant[AnyRef] = new Covariant[String] 15 | // Error 16 | val cv2: Covariant[String] = new Covariant[AnyRef] 17 | } 18 | -------------------------------------------------------------------------------- /covariance/sample02.scala: -------------------------------------------------------------------------------- 1 | 2 | class Stack[+A] { 3 | def push[B >: A](elem: B): Stack[B] = new Stack[B] { 4 | override def top: B = elem 5 | 6 | override def pop: Stack[B] = Stack.this 7 | 8 | override def toString() = elem.toString() + " " + 9 | Stack.this.toString() 10 | } 11 | 12 | def top: A = sys.error("no element on stack") 13 | 14 | def pop: Stack[A] = sys.error("no element on stack") 15 | 16 | override def toString() = "" 17 | } 18 | 19 | object VariancesTest extends App { 20 | var s: Stack[Any] = new Stack().push("hello"); 21 | s = s.push(new Object()) 22 | s = s.push(7) 23 | println(s) 24 | } 25 | -------------------------------------------------------------------------------- /covariance/sample03.scala: -------------------------------------------------------------------------------- 1 | // List[Nothing] <: List[Something] 공변성 [+T] 2 | // List[Something] <: List[Nothing] 반공변성 [-T] 3 | 4 | trait List[+T] { 5 | def isEmpty: Boolean 6 | def head: T 7 | def tail: List[T] 8 | } 9 | 10 | class Cons[T](val head: T, val tail: List[T]) extends List[T] { 11 | def isEmpty = false 12 | } 13 | 14 | object Nil extends List[Nothing] { 15 | def isEmpty = true 16 | def head = throw new NoSuchElementException("Nil.head") 17 | def tail = throw new NoSuchElementException("Nil.tail") 18 | } 19 | -------------------------------------------------------------------------------- /fpinscala/datastructure_exam.scala: -------------------------------------------------------------------------------- 1 | object Main { 2 | def main(args: Array[String]) { 3 | 4 | val list = List(1, 2, 3, 4, 5) 5 | val list2 = List(1.0, 2.0, 3.0, 4.0, 5.0) 6 | val list3 = List(6, 7, 8, 9, 10) 7 | 8 | println(s"tail : ${List.getTail(list)}") 9 | println(s"head : ${List.setHead(9, list)}") 10 | println(s"drop : ${List.drop(2, list)}") 11 | println(s"dropWhile1 : ${List.dropWhile1(list, (x: Int) => x < 3)}") 12 | println(s"dropWhile2 : ${List.dropWhile2(list)(x => x < 3)}") 13 | println(s"init : ${List.init(list)}") 14 | println(s"length : ${List.length(list)}") 15 | println(s"sum2 : ${List.sum2(list)}") 16 | println(s"sum3 : ${List.sum3(list)}") 17 | println(s"product2 : ${List.product2(list2)}") 18 | println(s"product3 : ${List.product3(list2)}") 19 | println(s"plus1 : ${List.plus1(list)}") 20 | 21 | println(s"map1 : ${List.map(list)((x: Int) => x + 1)}") 22 | println(s"map2 : ${List.map(list2)((x: Double) => x.toString)}") 23 | 24 | println(s"filter : ${List.filter(list)((x: Int) => x % 2 == 0)}") 25 | println(s"foldRight : ${List.foldRight(List(1, 2, 3), List[Int]())(Cons(_, _))}") 26 | println(s"foldLeft : ${List.foldLeft(List[Int](), List(1, 2, 3))((x, y) => Cons(y, x))}") 27 | println(s"foldRightViaLeft : ${List.foldRightViaFoldLeft(List(1, 2, 3), List[Int]())(Cons(_, _))}") 28 | println(s"foldRightViaFoldLeft_1 : ${List.foldRightViaFoldLeft_1(List(1, 2, 3), List[Int]())(Cons(_, _))}") 29 | println(s"appendViaFoldRight : ${List.appendViaFoldRight(List(1, 2, 3), List(4, 5, 6))}") 30 | 31 | println(s"plus1ViaFoldRight : ${List.plus1ViaFoldRight(list)}") 32 | println(s"plus1ViaFoldLeft : ${List.plus1ViaFoldLeft(list)}") 33 | 34 | println(s"floatMap : ${List.flatMap(list)(x => Cons(x, Cons(x, Nil)))}") 35 | 36 | println(s"filterViaFlatMap : ${List.filterViaFlatMap(list)(_ % 2 == 1)}") 37 | 38 | println(s"zip : ${List.zip(list, list3)}") 39 | println(s"zipWidth : ${List.zipWidth(list, list3)((x, y) => x+ y)}") 40 | 41 | val subA = List(1,2) 42 | val subB = List(1,3) 43 | val subC = List(3,4,5) 44 | val subD = List(1,4,5) 45 | 46 | println(s"hasSubsequenceA : ${List.hasSubsequence(list, subA)}") 47 | println(s"hasSubsequenceB : ${List.hasSubsequence(list, subB)}") 48 | println(s"hasSubsequenceC : ${List.hasSubsequence(list, subC)}") 49 | println(s"hasSubsequenceD : ${List.hasSubsequence(list, subD)}") 50 | } 51 | 52 | sealed trait List[+A] 53 | 54 | // `List` data type, parameterized on a type, `A` 55 | case object Nil extends List[Nothing] 56 | 57 | // A `List` data constructor representing the empty list 58 | /* Another data constructor, representing nonempty lists. Note that `tail` is another `List[A]`, 59 | which may be `Nil` or another `Cons`. 60 | */ 61 | case class Cons[+A](head: A, tail: List[A]) extends List[A] 62 | 63 | object List { 64 | // `List` companion object. Contains functions for creating and working with lists. 65 | def sum(ints: List[Int]): Int = ints match { 66 | // A function that uses pattern matching to add up a list of integers 67 | case Nil => 0 // The sum of the empty list is 0. 68 | case Cons(x, xs) => x + sum(xs) // The sum of a list starting with `x` is `x` plus the sum of the rest of the list. 69 | } 70 | 71 | def product(ds: List[Double]): Double = ds match { 72 | case Nil => 1.0 73 | case Cons(0.0, _) => 0.0 74 | case Cons(x, xs) => x * product(xs) 75 | } 76 | 77 | def apply[A](as: A*): List[A] = // Variadic function syntax 78 | if (as.isEmpty) Nil 79 | else Cons(as.head, apply(as.tail: _*)) 80 | 81 | def getTail[A](list: List[A]): List[A] = list match { 82 | // Todo : List의 첫 원소를 제외한 나머지 List를 반환 83 | } 84 | 85 | def setHead[A](head: A, list: List[A]): List[A] = list match { 86 | // Todo : List의 첫 원소를 다른 값으로 교체 87 | } 88 | 89 | def drop[A](n: Int, list: List[A]): List[A] = list match { 90 | // Todo : List의 앞부분 부터 n 번째 까지를 제외한 리스트 반환 91 | } 92 | 93 | def dropWhile1[A](list: List[A], f: A => Boolean): List[A] = list match { 94 | // Todo : 함수 f에 부합하는 List의 앞 요소들을 제거하는 함수 95 | } 96 | 97 | def dropWhile2[A](list: List[A])(f: A => Boolean): List[A] = list match { 98 | // Todo : 함수 f에 부합하는 List의 앞 요소들을 제거하는 함수( 커링 사용 ) 99 | } 100 | 101 | def init[A](list: List[A]): List[A] = list match { 102 | // Todo : List의 마지막 요소를 제외한 모든 요소를 반환하는 List 103 | } 104 | 105 | def foldRight[A, B](as: List[A], z: B)(f: (A, B) => B): B = as match { 106 | // Todo : foldRight를 구현 107 | } 108 | 109 | def sum2(ns: List[Int]) = { 110 | // Todo : foldRight를 이용해 sum을 재 구현 111 | } 112 | 113 | def product2(ns: List[Double]) = { 114 | // Todo : foldRight를 이용해 product를 재 구현 115 | } 116 | 117 | def length[A](as: List[A]): Int = { 118 | // Todo : foldRight를 이용해 List의 Length를 가져오는 함수 구현 119 | } 120 | 121 | def foldLeft[A, B](as: List[A], z: B)(f: (B, A) => B): B = as match { 122 | // Todo : foldLeft를 구현 123 | } 124 | 125 | def sum3(ns: List[Int]) = { 126 | // Todo : foldLeft를 이용한 sum 구현 127 | } 128 | 129 | def product3(ns: List[Double]) = { 130 | // Todo : foldLeft를 이용한 product를 구현 131 | } 132 | 133 | def plus1 ... { 134 | // Todo : List의 각 요소값에 1을 더하는함수 135 | } 136 | 137 | def doubleToString ... { 138 | // Todo : List의 각 요소를 String으로 변환하는 함수 139 | } 140 | 141 | def reverse ... { 142 | // Todo : List를 역으로 반환하는 함수 (List(1,2,3) = List(3,2,1) ) 143 | } 144 | 145 | def foldRightViaFoldLeft ... = { 146 | // Todo : foldLeft를 이용한 foldRight 147 | } 148 | 149 | def foldLeftViaFoldRight ... = { 150 | // Todo : foldRight를 이용한 foldLeft 151 | } 152 | 153 | def appendViaFoldRight ... = { 154 | // Todo : List 2개를 입력받아 이어주는 함수 (List(1,2,3) + List(4,5,6) = List(1,2,3,4,5,6) ) 155 | } 156 | 157 | def concat ... = { 158 | // Todo : List의 List를 하나의 List로 반환하는 함수 ( List(LIst(1), List(2), List(3,4)) = List(1,2,3,4) ) 159 | } 160 | 161 | def map[A, B](as: List[A])(f: A => B): List[B] = as match { 162 | // Todo : A를 B로 변환하는 함수 구현 163 | } 164 | 165 | def filter[A](as: List[A])(f: A => Boolean): List[A] = as match { 166 | // Todo : List 에서 f를 만족시키지 않는 요소를 제외한 List 를 반환하는 함수 167 | } 168 | 169 | def flatMap[A, B](as: List[A])(f: A => List[B]): List[B] = { 170 | // Todo : List A의 요소 하나하나를 List[B] 로 만들고 전체를 하나의 리스트로 만드는 함수 171 | } 172 | 173 | def filterViaFlatMap ... = { 174 | // Todo : flatMap 을 이용한 filter 함수 175 | } 176 | 177 | def zip ... { 178 | // Todo : ListA 와 ListB를 입력받아 각 요소의 Index끼리의 합을 만드는 함수. 길이가 다를 경우 짧은 List를 기준. 179 | // List(1,2,3) List(4,5,6) = List(5,7,9) 180 | } 181 | 182 | @tailrec 183 | def zipWidth ... { 184 | //Todo : Zip 을 일반화한 함수. 185 | } 186 | 187 | @tailrec 188 | def hasSubsequence ... { 189 | // Todo : List B가 ListA 의 서브 시퀀스인지 검사하는 함수. 190 | } 191 | 192 | } 193 | 194 | 195 | } 196 | 197 | -------------------------------------------------------------------------------- /fpinscala/fp_datasturucture.scala: -------------------------------------------------------------------------------- 1 | object Main { 2 | def main(args: Array[String]) { 3 | 4 | val list = List(1, 2, 3, 4, 5) 5 | val list2 = List(1.0, 2.0, 3.0, 4.0, 5.0) 6 | val list3 = List(6, 7, 8, 9, 10) 7 | 8 | println(s"tail : ${List.getTail(list)}") 9 | println(s"head : ${List.setHead(9, list)}") 10 | println(s"drop : ${List.drop(2, list)}") 11 | println(s"dropWhile1 : ${List.dropWhile1(list, (x: Int) => x < 3)}") 12 | println(s"dropWhile2 : ${List.dropWhile2(list)(x => x < 3)}") 13 | println(s"init : ${List.init(list)}") 14 | println(s"length : ${List.length(list)}") 15 | println(s"sum2 : ${List.sum2(list)}") 16 | println(s"sum3 : ${List.sum3(list)}") 17 | println(s"product2 : ${List.product2(list2)}") 18 | println(s"product3 : ${List.product3(list2)}") 19 | println(s"plus1 : ${List.plus1(list)}") 20 | 21 | println(s"map1 : ${List.map(list)((x: Int) => x + 1)}") 22 | println(s"map2 : ${List.map(list2)((x: Double) => x.toString)}") 23 | 24 | println(s"filter : ${List.filter(list)((x: Int) => x % 2 == 0)}") 25 | println(s"foldRight : ${List.foldRight(List(1, 2, 3), List[Int]())(Cons(_, _))}") 26 | println(s"foldLeft : ${List.foldLeft(List[Int](), List(1, 2, 3))((x, y) => Cons(y, x))}") 27 | println(s"foldRightViaLeft : ${List.foldRightViaFoldLeft(List(1, 2, 3), List[Int]())(Cons(_, _))}") 28 | println(s"foldRightViaFoldLeft_1 : ${List.foldRightViaFoldLeft_1(List(1, 2, 3), List[Int]())(Cons(_, _))}") 29 | println(s"appendViaFoldRight : ${List.appendViaFoldRight(List(1, 2, 3), List(4, 5, 6))}") 30 | 31 | println(s"plus1ViaFoldRight : ${List.plus1ViaFoldRight(list)}") 32 | println(s"plus1ViaFoldLeft : ${List.plus1ViaFoldLeft(list)}") 33 | 34 | println(s"floatMap : ${List.flatMap(list)(x => Cons(x, Cons(x, Nil)))}") 35 | 36 | println(s"filterViaFlatMap : ${List.filterViaFlatMap(list)(_ % 2 == 1)}") 37 | 38 | println(s"zip : ${List.zip(list, list3)}") 39 | println(s"zipWidth : ${List.zipWidth(list, list3)((x, y) => x+ y)}") 40 | 41 | val subA = List(1,2) 42 | val subB = List(1,3) 43 | val subC = List(3,4,5) 44 | val subD = List(1,4,5) 45 | 46 | println(s"hasSubsequenceA : ${List.hasSubsequence(list, subA)}") 47 | println(s"hasSubsequenceB : ${List.hasSubsequence(list, subB)}") 48 | println(s"hasSubsequenceC : ${List.hasSubsequence(list, subC)}") 49 | println(s"hasSubsequenceD : ${List.hasSubsequence(list, subD)}") 50 | 51 | 52 | } 53 | 54 | sealed trait List[+A] 55 | 56 | // `List` data type, parameterized on a type, `A` 57 | case object Nil extends List[Nothing] 58 | 59 | // A `List` data constructor representing the empty list 60 | /* Another data constructor, representing nonempty lists. Note that `tail` is another `List[A]`, 61 | which may be `Nil` or another `Cons`. 62 | */ 63 | case class Cons[+A](head: A, tail: List[A]) extends List[A] 64 | 65 | object List { 66 | // `List` companion object. Contains functions for creating and working with lists. 67 | def sum(ints: List[Int]): Int = ints match { 68 | // A function that uses pattern matching to add up a list of integers 69 | case Nil => 0 // The sum of the empty list is 0. 70 | case Cons(x, xs) => x + sum(xs) // The sum of a list starting with `x` is `x` plus the sum of the rest of the list. 71 | } 72 | 73 | def product(ds: List[Double]): Double = ds match { 74 | case Nil => 1.0 75 | case Cons(0.0, _) => 0.0 76 | case Cons(x, xs) => x * product(xs) 77 | } 78 | 79 | def apply[A](as: A*): List[A] = // Variadic function syntax 80 | if (as.isEmpty) Nil 81 | else Cons(as.head, apply(as.tail: _*)) 82 | 83 | def getTail[A](list: List[A]): List[A] = list match { 84 | case Nil => Nil 85 | case Cons(x, xs) => xs 86 | } 87 | 88 | def setHead[A](head: A, list: List[A]): List[A] = list match { 89 | case Nil => Nil 90 | case Cons(x, xs) => Cons(head, xs) 91 | } 92 | 93 | def drop[A](n: Int, list: List[A]): List[A] = list match { 94 | case Nil => Nil 95 | case Cons(x, xs) => drop(n - 1, List.getTail(list)) 96 | } 97 | 98 | def dropWhile1[A](list: List[A], f: A => Boolean): List[A] = list match { 99 | case Cons(x, xs) if f(x) => dropWhile1(xs, f) 100 | case _ => list 101 | } 102 | 103 | def dropWhile2[A](list: List[A])(f: A => Boolean): List[A] = list match { 104 | case Cons(x, xs) if f(x) => dropWhile2(xs)(f) 105 | case _ => list 106 | } 107 | 108 | def init[A](list: List[A]): List[A] = list match { 109 | case Cons(x, Nil) => Nil 110 | case Cons(x, xs) => Cons(x, init(xs)) 111 | } 112 | 113 | def foldRight[A, B](as: List[A], z: B)(f: (A, B) => B): B = as match { 114 | case Nil => z 115 | case Cons(x, xs) => f(x, foldRight(xs, z)(f)) 116 | } 117 | 118 | def foldRightViaFoldLeft[A, B](as: List[A], z: B)(f: (A, B) => B): B = 119 | foldLeft(reverse(as), z)((b, a) => f(a, b)) 120 | 121 | def foldRightViaFoldLeft_1[A, B](l: List[A], z: B)(f: (A, B) => B): B = 122 | foldLeft(l, (b: B) => b)((g, a) => b => g(f(a, b)))(z) 123 | 124 | def sum2(ns: List[Int]) = 125 | foldRight(ns, 0)((x, y) => x + y) 126 | 127 | def product2(ns: List[Double]) = 128 | foldRight(ns, 1.0)(_ * _) 129 | 130 | def length[A](as: List[A]): Int = 131 | foldRight(as, 0)((x, y) => 1 + y) 132 | 133 | def foldLeft[A, B](as: List[A], z: B)(f: (B, A) => B): B = as match { 134 | case Nil => z 135 | case Cons(x, xs) => foldLeft(xs, f(z, x))(f) 136 | } 137 | 138 | def foldLeftViaFoldRight[A, B](as: List[A], z: B)(f: (B, A) => B): B = 139 | foldRight(as, (b: B) => b)((a, g) => b => g(f(b, a)))(z) 140 | 141 | def sum3(ns: List[Int]) = 142 | foldLeft(ns, 0)((y, x) => x + y) 143 | 144 | def product3(ns: List[Double]) = 145 | foldLeft(ns, 1.0)(_ * _) 146 | 147 | def reverse[A](ns: List[A]) = 148 | foldLeft(ns, List[A]())((list, head) => Cons(head, list)) 149 | 150 | def appendViaFoldRight[A](listA: List[A], listB: List[A]) = 151 | foldRight(listA, listB)((x, y) => Cons(x, y)) 152 | 153 | def plus1(ns: List[Int]): List[Int] = ns match { 154 | case Nil => Nil 155 | case Cons(x, xs) => Cons(x + 1, plus1(xs)) 156 | } 157 | 158 | def plus1ViaFoldRight(ns: List[Int]): List[Int] = 159 | foldRight(ns, Nil: List[Int])((x, y) => Cons(x + 1, y)) 160 | 161 | def plus1ViaFoldLeft(ns: List[Int]): List[Int] = 162 | foldLeft(ns, Nil: List[Int])((y, x) => Cons(x + 1, y)) 163 | 164 | def doubleToString(ns: List[Double]): List[String] = ns match { 165 | case Nil => Nil 166 | case Cons(x, xs) => Cons(x.toString, doubleToString(xs)) 167 | } 168 | 169 | def map[A, B](as: List[A])(f: A => B): List[B] = as match { 170 | case Nil => Nil 171 | case Cons(x, xs) => Cons(f(x), map(xs)(f)) 172 | } 173 | 174 | def filter[A](as: List[A])(f: A => Boolean): List[A] = as match { 175 | case Nil => Nil 176 | case Cons(x, xs) => if (f(x)) Cons(x, filter(xs)(f)) else filter(xs)(f) 177 | } 178 | 179 | def flatMap[A, B](as: List[A])(f: A => List[B]): List[B] = 180 | foldRight(map(as)(f), List[B]())((listA, listB) => appendViaFoldRight(listA, listB)) 181 | 182 | def filterViaFlatMap[A](as: List[A])(f: A => Boolean): List[A] = 183 | flatMap(as)(a => if (f(a)) List(a) else Nil) 184 | 185 | def zip(listA: List[Int], listB: List[Int]): List[Int] = (listA, listB) match { 186 | case (_, Nil) => Nil 187 | case (Nil, _) => Nil 188 | case (Cons(aHead, aTail), Cons(bHead, bTail)) => Cons(aHead + bHead, zip(aTail, bTail)) 189 | } 190 | 191 | def zipWidth[A](listA: List[A], listB: List[A])(f:(A, A) => A): List[A] = (listA, listB) match { 192 | case (_, Nil) => Nil 193 | case (Nil, _) => Nil 194 | case (Cons(aHead, aTail), Cons(bHead, bTail)) => Cons(f(aHead, bHead), zipWidth(aTail, bTail)(f)) 195 | } 196 | 197 | def hasSubsequence[A](sup: List[A], sub: List[A], hasFirst : Boolean = false) : Boolean = (sup, sub, hasFirst) match { 198 | case (Nil, Nil, true) => true 199 | case (Nil, _, _) => false 200 | case (_, Nil, true) => true 201 | case (Cons(supHead, supTail), Cons(subHead, subTail), true) => 202 | if(supHead == subHead) hasSubsequence(supTail, subTail, true) 203 | else false 204 | case (Cons(supHead, supTail), Cons(subHead, subTail), false) => { 205 | if(supHead == subHead) hasSubsequence(supTail, subTail, true) 206 | else hasSubsequence(supTail, Cons(subHead, subTail), false) 207 | } 208 | } 209 | 210 | } 211 | 212 | 213 | } 214 | -------------------------------------------------------------------------------- /images/4-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/funfunStudy/study/20f31fb4ee0278f967c9c5cc5f29a96617c4b7c3/images/4-1.png -------------------------------------------------------------------------------- /images/스크린샷 2016-10-02 오후 6.06.50.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/funfunStudy/study/20f31fb4ee0278f967c9c5cc5f29a96617c4b7c3/images/스크린샷 2016-10-02 오후 6.06.50.png -------------------------------------------------------------------------------- /images/스크린샷 2016-10-02 오후 6.06.50.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/funfunStudy/study/20f31fb4ee0278f967c9c5cc5f29a96617c4b7c3/images/스크린샷 2016-10-02 오후 6.06.50.png -------------------------------------------------------------------------------- /images/폴더설명: -------------------------------------------------------------------------------- 1 | 위키 이미지들 2 | --------------------------------------------------------------------------------