Header

  1. View current page

    딥뿔이 자라나는 노트

Profile_image?t=1225424611&type=big
나를 바꾼 똑똑한 생활 습관, 스프링노트 - 여러분도 지금 시작해보세요!
38

컬렉션 활용한 바코드 체크섬과 할인 가격 문제

오늘도 Factor를 조금 공부해본다. 직접 뭔가를 만들려고 보니 자꾸만 뭔가 컬렉션(Collection)을 정의하고 이 컬렉션을 잘 다루는 부분이 꼭 필요하겠구나 싶다. 그래서 이번엔 그 부분을 집중적으로 연습했다.

 

시퀀스(sequence)

Factor의 시퀀스는 크기가 정해져있고, 선형적으로 순서가 정해진 요소들의 집합이다. 이 말은 정의이고, 시스템적으로 보면 '시퀀스 프로토콜'을 준수하는 모든 것은 다 시퀀스로 간주한다. 마치 루비의 duck typing 처럼 유연하다. 그래서 f 객체나 숫자도 시퀀스다.

 

  1. ( scratchpad ) f length .
    0
  2. ( scratchpad ) f empty? .
    t

 

숫자는 마치 Range처럼 동작한다.

 

  1. ( scratchpad ) 5 [ 2 * ] map .
    { 0 2 4 6 8 }

 

시퀀스를 구현하고 있는 것들을 한번 살펴보자.

 

  • Arrays

    • 사이즈가 고정됨.
  • Vectors

    • 가변 사이즈
  • Bit arrays

    • 구성 요소가 t나 f
  • Byte arrays

    • 구성 요소가 1-255
  • Strings

    • 사이즈가 고정됨
  • String buffers

    • 가변 사이즈
  • Quotations

 

연관 매핑(Associative mappings)

줄여서 assoc이라고 표현하는데, 키/값의 쌍이로 구성되어 효과적인 찾기 연산을 제공한다. 루비의 해시와 동일하다. 종류는  해시 테이블과 연관리스트(alist)가 있다. 해시 테이블과 달리 alist는 순서가 있다.

 

바코드 체크섬

여기까지 예습을 마친 다음, 바코드 체크섬을 구하는 문제를 풀어보았다. 문자열을 입력받아 숫자를 담은 배열로 변환하고 가중치합을 더해 체크섬을 확인하는 방식이다. 크게 어렵지 않았다.

 

  1. ! barcode checksum
    : >digit-array ( seq -- seq )   >array [ digit> ] map ;
    : barcode-checksum ( seq -- x ) >digit-array "1313131313131" >digit-array weighted_sum ;
    : valid-barcode? ( seq -- x )   barcode-checksum 10 mod 0 = ;

  2. [ t ] [ "8809010665009" valid-barcode? ] unit-test
    [ f ] [ "8809010665008" valid-barcode? ] unit-test

 

할인 가격

이번엔 할인가격 문제다. 먼저 사려는 양과 현재 범위(룰)을 넣으면 남은 양과 현재 룰이 적용되는 양을 구하는 워드 (quantity)를 구현하고, alist로 정의된 룰을 keys와 values로 나눈 다음 keys 부분에 적절하게 (quantity)를 적용해 양을 룰에 따라 나누고 그 결과를 가중치합하면 된다.

 

  1. ! 할인가격
    : (quantity) ( initial quantity -- remain quantity )
        2dup * zero? [
            drop 0 swap
        ] [
            2dup >= [ 2dup - ] [ 0 ] if -rot min
        ] if ;

  2. [ 15 20 ] [ 35 20 (quantity) ] unit-test
    [  0 15 ] [ 15 20 (quantity) ] unit-test
    [  0 15 ] [ 15  0 (quantity) ] unit-test
    [  0  0 ] [ 0  20 (quantity) ] unit-test

    : (split-rule) ( rule -- values keys ) [ values ] keep keys ;
    : (distribute-quantity) ( rule quantity -- seq ) [ (quantity) ] map nip ;

    : price ( rule quantity -- price )
        swap (split-rule) swapd (distribute-quantity) weighted_sum ;

    [  9.0 ] [ { { 20 0.90 } { 40 0.80 } { 0 0.75 } } 10 price ] unit-test
    [ 30.0 ] [ { { 20 0.90 } { 40 0.80 } { 0 0.75 } } 35 price ] unit-test
    [ 57.5 ] [ { { 20 0.90 } { 40 0.80 } { 0 0.75 } } 70 price ] unit-test

 

if문 사용법도 알게되고, 시퀀스에 대해서도 조금 익숙해져서 좋은 연습이었다. 하지만 아직도 코드가 읽기 쉬워보이지는 않는다. 더 연습이 필요하겠다. 다음에는 좀 더 유용하 프로그램을 만들 수 있도록 GUI 만들기에 도전할 생각이다.

 

 

History

Last edited on 12/23/2007 10:40 by deepblue

Comments (0)

You must log in to leave a comment. Please sign in.