2009년 1월 30일 금요일

블라블라 forge 류 소프트웨어들

http://en.wikipedia.org/wiki/Forge_(software)

간만에 mercurial 위키를 구경하다가  InDefero 링크를 보게되서 좀 구경해보다가 아예 위키피디아 링크도 걸어둔다. 저쪽엔 언급이 없지만 네이버의 nFORGE (GForge 기반)란게 있다는것도 기억해두고..

forge 류 소프트웨어들을 하나쯤 돌리면 개발이 편해질것 같은 느낌이 들기도 하지만.. 설치와 관리를 생각하면 우울해진다. 저걸 돌릴정도로 참여자가 많은 상태도 아니고..



PS.

음 hg 위키를 찾아간게 1.1 부터 추가된 북마크 기능때문이었는데.. git 에서 정말 맘에 드는 기능인 로컬브랜치를 구현한거라 꼭 써보고 싶었지만 현재 우분투 intrepid 가 mercurial 1.1 패키지를 제공하지 않아서 그냥 구경만 했다.

https://launchpad.net/~maxb/+archive/ppa 를 통해서 1.1 을 한번 깔아는 봤는데.. hgview 등 다른 패키지들이랑 충돌이 있는듯 해서 바로 다시 원복했다. 뭐 mercurial 은 아직 혼자만 쓰고 회사에선 svn 을 쓰니 굳이 미리 삽질을 할필요야 없지.

XP-Dev.com 무료 서브버전 호스팅을 해주는곳

http://xp-dev.com/

물론 svn 호스팅만을 위한곳이 아니고 다른 여러 기능들이 있지만 아무래도 이게 제일먼저 눈에 보이네. 유저당 1.5기가 정도의 용량을 주니까.. dot 파일들 저장하는데는 충분할듯하다.

그런데 예전에 어셈블라 가 무료일때도 가입만 해두고 막상 쓰질 않았으니.. 이 곳도 내가 쓰지는 않을것 같은데.. 집에 PC 를 꺼야하는 상황이 닥치면 그때 다시 둘러보자...

2009년 1월 29일 목요일

프로젝트 오일러 30 haskell 풀이





import Data.Char(digitToInt)

main = print $ sum solve

sumOfPowers :: Int -> Int -> Int
sumOfPowers n = sum . mapDigits (^n)

sumOfFifthPowers = sumOfPowers 5

-- 음.. 어퍼바운드가 역시나 산술적으로 나오는 모양인데.. 난 그냥 적절히
-- 큰수로 박았다. 쩝
solve = filter surprise candidates
where surprise n = sumOfFifthPowers n == n
candidates = [2..999999]

-- 전에 만들어둔 함수. 역시나 오일러에서는 자주쓰이네
mapDigits f n = map (f.digitToInt) (show n)

2009년 1월 26일 월요일

프로젝트 오일러 20 haskell 풀이

이전에는 fold 안썼는데 이번에 답 옮기면서 fold 로 짜봤다.

아직 어색해서 그런건지.. 가독성이 더 안좋아 보이는데...
반복로직을 fold 가 가져가서 읽기 편하다고 주장들을 하던데
뭐 틀린말은 아닌거 같지만 아직 fold 를 보는순간 머리에서 루프가
안그려져서 읽는게 좀 곤혹스럽다.



import Data.Char(digitToInt)

fac n = product [1..n]
sumOfDigits = foldr (\x acc -> (digitToInt x)+acc) 0 . show

main = print $ sumOfDigits $ fac 100



프로젝트 오일러 48 haskell 풀이

haskell 로는 거저먹는 문제.
쉬운문제 찾다보니.. 낄낄.

-- 흠. fold 의 묘미를 아직 잘 모르겠지만 쉽게 풀긴 했다. foldr 을
-- 쓰기에 적당한 상황이었는지 모르겠네.
f n = foldr (\x acc->acc+(x^x)) 0 [1..n]
solve = f 1000 `mod` 10^10

main = print solve

프로젝트 오일러 34 haskell 풀이

블로그스팟에 적던건데 그냥 이쪽으로 죄다 적어야겠다. 구글갓댐.

이건 정리된 버전...

import Data.Char(digitToInt)

main = print solve

fac n = foldr (*) 1 [1..n] -- 팩토리얼
mapDigits f n = map (f.digitToInt) (show n) -- 각 디짓 별로 map
curious n = n == sumOfDigitFact n -- 34 번 문제의 조건에 맞는지 판단
sumOfDigitFact = sum . mapDigits fac -- 각 디짓의 팩토리얼의 합
solve = filter curious [3..100000] -- 이거.. 어퍼바운드 결정을 그냥 때려 맞춘것


아래는 풀이하면서 이것저것 해본 코드. foldl/foldl'/foldr 차이점은 아직 느낌이 잘 안오네..

펼쳐두기..

2009년 1월 23일 금요일

자바 스크립트 게임 모음

http://www.webresourcesdepot.com/25-amazing-javascript-games-some-fun-and-inspiration/

헐.. 놀랍군

haskell 숫자들로만 이루어진 파일(문자열) 을 [[Int]] 로 읽기

음 뭐 별건 아니고 reading file to list 를 잠깐 구경하다가 만들어본거. 핵심은 아래 f 함수 한줄. 이제 reading file to list 를 좀 읽어봐야겠군..

음.. 그런데 이걸 정말 써먹을 일이 있다면 아마도 ByteString 으로 읽을텐데 그럴경우엔 어떻게 코딩해야 할지 모르겠네. ByteString 을 String 으로 변환해서 처리하는건 삽질일테고. ByteString 에 lines/words 등이 있으려나? read 는 어케되나?
뭐 이런건 나중에 더...

-- 테스트할 문자열
contents = "3 10 2\n4 1\n11 18\n"

-- 토크닝 해주는 함수
f :: String -> [[Int]]
f = map (map read.words).lines

-- 테스트
t = f contents

-- 파일에서 읽으려면 readFile 을 쓰면 간단하겠지
t2 = readFile "/tmp/nums.txt" >>= return.f

2009년 1월 22일 목요일

MinUnit: C 에서 유닛 테스트 간단하게.


cmake테스트를 주로 쓰는 편이라 테스트를 위해서 작은 바이너리들을 여러개 만드는 편인데 이 바이너리 코드들은 대부분 정형화 되어있다.

테스트할 함수 불러보고 리턴이 맘에 들면 조용히 지나가고 리턴이 맘에 안들면 뭐라뭐라 찍어주고 main 이 실패값을 리턴하도록 되어있는데 너무 뻔한 작업이다 보니 매크로를 쓰게 되고.. 그런데 이걸 그냥 즉흥적으로 하다보니 나중에 보면 매번 조금씩 다른 매크로를 만들었더라.

그러던 참에 List of unit testing frameworks 에서 MinUnit 을 구경하게 됐고 매크로만으로 이루어진게 내가 평소 하던 짓이랑 똑같아서 앞으로 이놈을 쓰기로 했다.

아예 minunit.h 파일을 새로 만들때마다 위 코드(의 수정버전)을 채워버리도록 emacs 에서 세팅하고 사용중.


2009년 1월 21일 수요일

haskell 로 바이너리 패킷을 다루는 간단한 예제

지금 테스트툴을 haskell 로 작성중인데 바이너리 프로토콜을 써야 하는 상황이 왔네.

제일 먼저..네트웍 통신에 String 을 그냥 쓰는건 너무 효율이 안좋을것 같아서 바이트스트링을 쓰기로 하고 Bits 모듈의 시프트를 가져다가 Int -> (Word8,Word8) 등등의 무식한 로우레벨 함수로 바이트를 쪼개 만들어서 cons 로 이어 붙여서 패킷을 만들고, 또 이걸 읽어서 index, take, drop 등 아주 생기초 함수들(그외는 잘 모르니까)을 이용해서 파싱을 했다.

짜고 나니 이게 패킷구조가 좀더 복잡해지면 답이 안나오겠더라.. 결국 좀 뒤져보니 바이너리 모듈이란게 존재하네. 모나드 덩어리라 아직 이해할수는 없지만! 대강 써먹는데는 별문제가 없길래 이놈으로 갈아타서 작성을 해봤다.

그런데 맘에 안드는게... 아래 주석에도 적었지만 바이트스트링이 워드/캐릭터 에 따라서 또 스트릭트/레이지 에 따라서 나뉜다는게 거참... 이런 구조는 정말 납득이 안되는데.

뭐 아직 쌩초짜니까 그냥 선입견이지만 haskell 의 모듈시스템은 쓰는건 편한데 모듈을 만들어 제공하려면 정말 더러울것 같다.



{-
바이너리 패킷이 있다고 가정을 하고 이걸 읽고 써보자.
바이너리 패킷의 모양은

먼저 매직넘버 두바이트
[0] 0xAB
[1] 0xCD
그리고 두바이트 짜리 값 하나. 뭐.. packet id 정도?
[2]
[3]
다시 두바이트 짜리 값 하나. 뒤에 나올 payload 길이
[4]
[5]
이제 payload len 만큼 바이트가 나온다.
[6]
...

http://www.haskell.org/haskellwiki/DealingWithBinaryData
문서를 참고하자

아직 개념이 없어서 바이트스트링은 다 비슷한 부류로 느껴지는데 Word8
이냐 Char 에 따라 갈리고 다시 Strict 와 Lazy 에 의해 갈리는건 정말
부조리하게 느껴지는데... 결국 비슷한 일을 하는놈들인데 모듈이 그만큼
생긴 거니까..

네트웍쪽 모듈만 해도 바이트스트링용 모듈이 따로 존재하고 이 바이너리
모듈도 스트릭트 버전이 따로 있는등.. 이건 정말 이해할수가 없군.

더 공부하다 보면 알게 되려나.
-}


import Data.Binary
import Data.Binary.Get
import Data.Binary.Put
import Data.ByteString.Internal(c2w,w2c)
import qualified Data.ByteString as B
import qualified Data.ByteString.Lazy as L

-- String 하고 ByteString 간의 전환은 정말 어색하네. 이렇게 번거롭게
-- 해야 할것 같지는 않은데... 다른 방법을 찾아봐야 겠다. IsString 이란
-- 클래스가 있긴 헌데.. 이걸 쓰려면 뭐 ghc 옵션을 줘야 하고 (확장) 영
-- 복잡하네. IsString 은 배워두면 쓸모 많을것 같으니 빨리 공부해야 할것
-- 같다.
toByteString :: String -> B.ByteString
toByteString x = B.pack $ map c2w x

fromByteString :: B.ByteString -> String
fromByteString x = map w2c (B.unpack x)


-- 음 Put 모나드를 리턴을 하고.. runPut 으로 그걸 실행하나 보네? 모나드
-- 공부를 아직 안했으니 뭐가뭔지 모르겠다. writer 모나드라고 문서엔
-- 나와있는데..
makePacket :: Int -> String -> Put
makePacket id payload = do
putWord8 0xAB
putWord8 0xCD
putWord16be $ fromIntegral id
putWord16be $ fromIntegral bodylen
putByteString body
where
body = toByteString payload
bodylen = B.length body

-- 실행은 요렇게. runPut 이 결국 ByteString.Lazy 를 주는데 이건 좀 맘에
-- 안드네. lazy 가 정말 좋은 스타일일까
test_makePacket = runPut $ makePacket 100 "hahaha"
-- 그냥 저장한번 해봤다.
test_store = L.writeFile "/tmp/hahaha" test_makePacket

-- 이건 Get 모나드.. 어떻게 돌아가는지는 몰라도 쓰는데는 문제 없다.
-- Word 와 Int 간의 캐스팅은 다른 언어에서라면 그냥 해주는건데 여기선
-- 그걸 안해주니 좀 답답하다. 뭐 장점도 많지만.
readPacket :: Get (Int, String)
readPacket = do
magic0 <- getWord8
magic1 <- getWord8
id <- getWord16be
len <- getWord16be
body <- getByteString (fromIntegral len)
return ((fromIntegral id), (fromByteString body))

-- 위에서 만든 test_makePacket 의 결과를 읽어봤다.
test_readPacket = runGet readPacket test_makePacket


2009년 1월 14일 수요일

C 에서 한바이트를 비트단위로 찍어보기

한동안 자주 쓸것같은 함수네.
여기 적어둔다.
버퍼포인터 주고받기 구찮아서 그냥 2진수 모양의 10진수를 리턴하도록 했다.


#include <stdint.h>
#include <stdio.h>

/* 어쩌다 보니 비트값까지 찍어야 할 판이네. 그냥 간단히 찍기 위해서
* 스트링버퍼에 담아주는 방식이 아니고 0 하고 1 로 이루어진 십진수로
* 리턴을 받아서 이걸 %08d 등으로 찍을수 있게 했다. */

int foo(uint8_t b)
{
int i,r = 0;
int base = 1;
for(i = 0; i < 8; ++i)
{
r += base * ((b>>i) & 0x01);
base *= 10;
}
return r;
}


int main()
{
int i;
for(i = 0; i < 256; ++i)
printf("%3d: %08d 0x%02x\n",
i,
foo(i), /* %08d 로 찍자 */
i);

/* 4bit 단위로 끊어봤어 */
for(i=0; i<256; ++i)
printf("%3d: %04d %04d\n",
i,
foo(i)/10000,
foo(i)%10000);
}









2009년 1월 8일 목요일

xmonad 잠깐 써봤는데 생각만큼 편하질 않네.

글쎄.. 타일링 윈도매니저는 꼭 써보고 싶긴 했는데 막상 써보니 그다지 편하질 않네. 메신저를 트레이(xmobar) 위에 올리는것도 상당히 삽질이고. 결국 그냥 다시 메타시티로 돌아오고 대신 emacs 에 풀스크린을 쓰도록 해줬다.


아 그리고 dwm 도 써봤는데.. xmonad 가 바이너리가 상당히 큰것에 비해 사이즈가 작아서 맘에 들더라. C 기반이니 당연한거지만. 그냥 구경만 해본 수준이라 더 할말은 없군.


awesome도 깔아보려고 했는데 이건 빌드가 짱나더라. 의존성이 너무 심하더군. 하드가 아까워 빌드안했다.



...

emacs 풀스크린도 좀 요상하게 도는데.. 다른 어플이 팝업을 띄운게 가려져서 안보이네.

흠. 쒯.