루빅스 큐브 기본

완전 초짜들을 위한 가이드 에 의하면 루빅스 큐브는 가운데에 고정되어 있는 1개의 면을 가지는 6큐브를 중심으로 2개의 면을 가지는 에지 큐브가 12개와 3개의 면을 가지는 모서리 큐브 8개가 모여서 이루어진다. 결국 주사위와 마찬가지로 축을 이루는 색깔간의 관계는 바뀌지 않고 에지와 모서리 큐브의 위치에 따라 상태(state)가 결정되는 셈이다. 어쩌면 큐브를 푸는 프로그램을 만들어 볼 수 있을것 같다.

scala에서 processing 사용하기

Scala에서 processing을 사용하는 예제들이 있는데 시험해 보면 size 명령이 제대로 동작하지 않는 경우가 있다. 보통 첫번째 방법을 많이 사용하는데 setup에서 size 명령이 제대로 먹히지 않는 반면 두번째 방법을 사용하니 제대로 동작한다. Windows 시스템에 한정된 일인지는 명확하지 않다. import processing.core._ object Test extends PApplet { private var test:Test = _ def main(args: Array[String]) = { test = new Test val frame = new javax.swing.JFrame("Test") frame.getContentPane().add(test) test.init frame.pack frame.setVisible(true) } } class Test extends PApplet { override def setup() = { } override def draw() = { } } import processing.core._ object Test { def main(args: Array[String]) = PApplet.main(Array[String]("Test")) } class Test extends PApplet { override def setup() = { } override def draw() = { } }

순열 만들기

Scala에서 순열을 만드는 2가지 방식을 생각해 볼 수 있겠습니다. 물론 더 여러가지가 있을 수 있겠지만... 1. 한번에 숫자 하나씩 처리하기 인자로 받은 리스트의 항목을 하나씩 가지고 결과물을 만들어 나가는 방법입니다. 매번 리스트 항목에서 하나를 선택해서 이미 만들어진 리스트의 앞, 중간, 뒤에 그 항목을 끼워넣습니다. List(1, 2, 3), List() -> List(2, 3), List(List(1)) -> List(3), List(List(2, 1), List(1, 2)) -> List(), List(List(3, 2, 1), List(2, 3, 1), List(2, 1, 3), List(3, 1, 2), List(1, 3, 2), List(1, 2, 3)) def permutation[A](xs:List[A]):List[List[A]] = { def mutate(x:A, ys:List[A]):List[List[A]] = { // ys의 앞, 중간, 뒤에 x를 끼워넣은 리스트를 반환 def helper(zs:List[A], prev:List[A], acc:List[List[A]]):List[List[A]] = zs match { case Nil => (ys :+ x)::acc case z::zs1 => helper(zs1, prev :+ z, (prev ++ (x::zs))::acc) } helper(ys, List(), List()) } def helper(ys:List[A], acc:List[List[A]]):List[List[A]] = ys match { case Nil => acc case y::ys1 => helper(ys1, acc.flatMap(mutate(y, _))) } helper(xs, List(Nil)) } ...

Structural subtyping, Upper bounds, Implicite Parameter & View bounds

Scala에서 insertion sort는 다음과 같이 구현할 수 있습니다. def isort[T](less:(T,T)=>Boolean)(xs:List[T]):List[T] = { def insert(x:T, xs:List[T]):List[T] = xs match { case Nil => List(x) case x1::xs1 => if (less(x, x1)) x::xs else x1::insert(x, xs1) } xs match { case Nil => Nil case x::xs1 => insert(x, isort(less)(xs1)) } } println(isort((x:Int, y:Int)=> x x Int형이라면 < 연산자를 사용하고 비교하기 위해 less 연산자를 사용하지 않겠지만 Double이나 Char를 정렬하고 싶은 경우도 생기기 때문에 일반적인 형 T에 대해 사용할 수 있도록 적은 것입니다. 하지만 Double, Char 모두 < 연산자를 제공하고 있는데 반복적인 less를 사용하는 것이 불편합니다. Programming Scala 책에는 structural subtype 에 대해 클래스 이름이 아니라 특정한 메소드를 가지는 것으로 subtype을 결정하는 것이라고 나와 있습니다. 다음과 같이 시도해 봅니다. def isort2[T List(x) case x1::xs1 => if (x Nil case x::xs1 => insert(x, isort(xs1)) } } 위에서 의미하고자 하는 것은 같은 형과 비교하는 연산자 <를 가지는 클래스 T를 말하는 것입니다만, structural subtype에서는 아직 정의되지 않은 T를 사용할 수 없다며 컴파일 오류가 발생합니다. 다른 형의 메소드라면 이 방법으로 해결할 수 있었겠지만 같은 형을 비교해서 Boolean을 반환하는 함수형은 이 방법을 사용할 수 없습...

소수 계산

val primeStream:Stream[Int] = 2 #:: Stream.from(3, 2).filter(i => primeStream.takeWhile(j => j*j i%k != 0)) stackoverflow 에 올라와 있는 scala의 소수(prime) stream 예제 위 코드를 한글로 번역하면 2와 3 이상의 홀수 중에서 제곱해서 자신보다 작은 이미 찾아낸 소수들 모두로 나누어지지 않는 수가 된다. val로 정의되어 있으므로 이미 찾아낸 값을 다시 계산하지 않는다. 2 3 - 2*2 5 - takeWhile에서 선택되는 소수는 2. 2는 5%2!=0을 만족하므로 채택 7 - takeWhile에서 선택되는 소수는 2. 2는 7%2!=0을 만족하므로 채택 9 - takeWhile에서 선택되는 소수는 2,3. 9%3 == 0이므로 채택되지 않음 11 - takeWhile에서 선택되는 소수는 2,3. 2,3 모두 11 나누면 나머지가 있으므로 채택 위의 방식으로 계속 찾아내게 된다.

OSX에서 Octave 설치

brew가 설치된 상태에서 % brew install octave # octave 받고 필요한 패키지들을 설치함. terminal에서 octave 실행시키고 명령어 내려볼 수 있다. graph 함수 실행시키면 동작하지 않는다. XQuartz 받아서 설치하고 다음의 명령어들을 실행 % brew install gnuplot # gnuplot과 필요 패키지들 설치 % cat ~/.octaverc # 홈 디렉토리에 .octaverc 파일을 만들고 내용을 다음과 같이 설정 setenv GNUTERM x11 이후 plot 명령 실행시키면 화면에 그래프 표시된다.

Scala에서 Tuple의 zipped

Scala 2.10.1 val a = List.range(1, 4) // List(1,2,3) val b = List.range(10, 40, 10) // List(10,20,30) a zip b // List((1, 10), (2, 20), (3, 30)) a zip b map ((x,y) => x+y) // ERROR : wrong number of parameters, expected 1 a zip b map (((x, y)) => x+y) // ERROR : not a legal formal parameter a zip b map (Tuple2(x,y) => x+y) // ERROR : not a legal formal parameter (a, b).zipped.map(_+_) // List(11, 22, 33) val c = List.range(100, 400, 100) // List(100, 200, 300) a zip b zip c // List(((1,10), 100), ((2, 20), 200), ((3, 30), 300)) a.zip(b, c) // ERROR : too many arguments (a, b, c).zipped.toList // List((1, 10, 100), (2, 20, 200), (3, 30, 300)) (a, b, c).zipped.map(_+_+_) // List(111, 222, 333)