'2008/03'에 해당되는 글 12건

  1. 2008/03/31 annotated Alice 독후감 by sloth_chord (2)
  2. 2008/03/29 Ruby 걸음마의 코드 - 연속된 자연수의 범위 찾기 (또는 home on the range....) by sloth_chord
  3. 2008/03/27 Ruby 걸음마의 코드 - LCD display by sloth_chord

(이 전에 쓴 두개의 글을 합쳐서 정리한건데.. "나무늘보 색히 앨리스하나가지구 더럽게 우려먹네" 하는 생각이 들더라도 좀 참아주면 감사^^)

이 책.. 이 책의 부분적인 구절이나 여타 등등이 인용이 많이 되기도 하며, 많은 전산계의 유명인들이 추천하는 책 이기도 하다..

annotated Alice는 이상한 나라의 앨리스, 거울 나라의 앨리스 두편이 담겨있구, 거기에다
마틴 가드너 할아버지가 주해를 달아놓은 버젼이다.

늘 궁금했다.. 아동 동화책이랑 프로그래밍이랑 무슨 관계가 있길래 이렇게 유독 추천을 할까?
 

읽으면서 느낀 점을 적자면................

일단 처음엔..
땅 속 세상, 거울 속 세상 등으로의 여행을 가서 동물, 전설 속의 생명체, 카드, 좀 정신 나간 듯한 사람들 - 모험에 등장하는  인간들은 보통 좀 정신 나간 듯 한 인간들 밖에 없다 - , 체스 말, 달걀, 벌레, 꽃 등등이랑 심도 있는 대화를 나누는데.. 정말 하하;;

또, 등장 사물 - 이렇게 밖에 표현을 못하겠다 - 들에게 투영된 현실세계의 사람이 무엇일지 생각해 보는 것도 재미있으며.. 작품 속의 비꼬는 듯한 은유나 논리적 패러독스도 재미있다.

다만, 중간중간 나오는 시(대부분 유명시의 패러디)들은 썩 재미있게 와 닿지는 않은 것들이 많다.
 
다른 동화와 다른점이라면 주인공 앨리스를 비롯한 등장 사물이 평면적이지도 않구.. 권선징악을 강조하지 않는 그냥 엘리스의 모험이 주 내용이라는 특징 같다;;
그 모험이 딱히 무슨 대단한 목적이 있는 것도 아니구, 주인공 꼬마 아가씨의 상상 속 여행이란점도 그렇구.. 꼬마 아가씨의 상상이라 생각해버리기엔 비범한 삐딱한 시선이나 통찰(?)이 녹아 들어가 있는점도 참 특이하다,,

또한 상상 속의 세상에서 작품 중간중간에 등장하는 문학/수학/논리학/수사학/세계관등에 관한 여러 가지 숨어있는 재미들을 찾아볼 수 있도록 멍석을 깔아준다는.. 자꾸 생각해보며 파고 들어보게 하는 그러한 매력을 가진 소설 같다.

 
읽기전에 가졌던 궁금함에 대한 결론을 좀 내려보면..

좋은 프로그래머가 되는데에 도움이 되는 책이란 어떤책일까?
단지 전산학 이론, 요소기술 등을 다루는 책만 생각한다면 너무 좁은 생각일 것이다.

좋은 프로그래머라면 이론/기술적인면 뿐만 아니라, 논리력, 창의력, 문제발견, 문제해결 능력은 기본이다. 또, 찾아낸 답의 오류를 찾아내는 능력(프로그래머란 인간들은 매일 논리오류와 싸우며살아간다), 어떤 사실을 다른 관점에서 생각해 볼 수 있는 능력(좀 더 나은 해법을 찾게한다), 상상력(새로운 패러다임, 비전을 제시하려면 없어선 안 될 능력이다) 등 이 있겠다.

더 붙이자면 의사소통, 팀 플레이, 정보습득/학습능력 등 이 있겠지만, 이건 비교적 일반적으로 모두 요구되는 것 이니  프로그래머에게 "특히 더욱" 요구되는 능력은 위의 것 들이라할 수 있겠다.

자, 저런 능력이랑 이 소설이 뭐가 관계가 있단것일까..

일단 갖가지 수학적, 논리적, 수사적 패러독스가 녹아 들어가 있으며, 엘리스와 그 외 사물들은 이런 패러독스에 관해서 매우 자주 토론 (다르게 이야기하면 입씨름)을 한다.

계속 말장난(?)으로써 앨리스를 (혹은 독자) 멍하게 만들어가며, 과연 그 이야기들은 설득력이 있는지, 오류는 없는것인지 생각을 할 수 밖에 없게 한다.
프로그래머들은 매일 그럴듯하게 보이는 코드속에 숨어있는 논리적 오류와 싸우는 것이 생활이다.

또한, 어떤 등장 사물들은 사실에 대한 전혀 상식적이지 않은 관점과 거기에 대한 해석을 계속해서 떠들어댄다. 이렇게 생각하면 어떨까? 또 저렇게 생각해본다면?

게다가, 상상력을 빼 놓구서는 이 소설을 이야기하기가 힘들 것 이다.
하지만, 허무맹랑한 세계가 아니라 현실세계를 잘 비꽈서 abstraction 해 놓은 말 그대로의 이상한세계이다.

CS는 abstraction의 학문이 아니었던가,, (이 이야긴 우리 은사님의 말씀이다.)

또, 무엇보다 한 작품을 이렇게 방대한 분야에서 다양한 해석을 "만들어 낼 수 있도록 소재를 제공하는" 작품도 드물것이다. 비록 꿈보다 해몽이되더라도 이런저런 관계를 유추하며, 무엇보다 "생각" 하게 만들어주는 그러한 소설이다.

음식, 음악, 독서도 편식은 좋지 않다.
뭐, 누군가처럼 훈민정음해제 같은걸 추천하는 건 오히려 오버라구 생각하지만 어쨌든 우리에게는 기술 자체 외에도 참 많은 능력이 요구가 된다.

0/1로 구분되는 단순한 세계에서 빠져있지만 말구, 그 외의 중요한 요소들에 대해서 생각을 해보게 하는 비타민 같은 존재라구 생각이 된다.

 

크리에이티브 커먼즈 라이선스
Creative Commons License
Posted by sloth_chord
TAG 서평
# Ruby 1.8에서테스트
def continued?(arr, a, b)
  return ( (arr[a].to_i + 1) == arr[b].to_i )
end


def beginning?(arr, i)
  return ( (i == 0) or (!continued?(arr, i - 1, i)) )
end

def mark_append(result, arr, i)

  if continued?(arr, i, i + 1)
    ((result << arr[i] << '-') if (beginning?(arr, i)))
  else
    result << arr[i] << ', '
  end

end

# 오름차순으로 정렬된 자연수의 리스트에서
# 연속으로 이어진 부분들은 범위를 나타내는 표시로 바꾸는 문제

# 예를 들면은 "1 2 3" => "1-3."
# "1 2 3 5 7 8" => "1-3, 5, 7-8.";  "1 3 4 5 7" => "1, 3-5, 7."

# 입력은 정수리스트나 문자열, 숫자들은 스페이스 한 칸으로 구분
# 출력은 문자열로 범위는 '-'를 이용하여 "시작-끝"과 같은 형식으로 표현

# ', '는 범위의 끝, '.'는 입력의 끝

def home_on_the_range(num_str)

  arr = num_str.split(' ').uniq
  result = String.new

  # 루프에서는 맨 마지막 숫자바로앞 까지만 진행시킴

  last_idx = arr.length - 1
  last_idx.times do |i| mark_append(result, arr, i) end

  result << arr[last_idx] << '.'

  return result

end

require 'test/unit'

class TestClass < Test::Unit::TestCase

  def test_cont
    assert_equal('1-3.', home_on_the_range('1 2 3'))
  end

  def test_repeted
    assert_equal('1-2, 450, 500.', home_on_the_range('1 1 2 450 450 500 500'))
  end

  def test_one_elem
    assert_equal('1.', home_on_the_range('1'))
  end

  def test_left_cont
    assert_equal('1-2, 500.', home_on_the_range('1 2 500'))
  end

  def test_side_cont
    assert_equal('1-3, 5, 7-9.', home_on_the_range('1 2 3 5 7 8 9'))
  end

  def test_mid_cont
    assert_equal('1, 3-5, 7.', home_on_the_range('1 3 4 5 7'))
  end

  def test_not_cont
    assert_equal('1, 100, 500.', home_on_the_range('1 100 500'))
  end

end

크리에이티브 커먼즈 라이선스
Creative Commons License
Posted by sloth_chord
TAG program, ruby
# Ruby 1.8에서테스트
# LCD display 문제
# 숫자와 크기를입력받아서 lcd display 식으로 표시해줌

# EasyEclipse for Ruby and Rails에서 테스트할땐 숫자모양이  제대로 나오는데
# SciTE에서 테스트하면 삐뚤빼뚤함

# 문자열로 된 숫자를 각각 한 자리씩 쪼개내서 integer 배열에다가 담은
# 예를들어서 num_str이 "12345"면은  [1, 2, 3, 4, 5] 를 리턴

def str_to_int_arr(num_str)
  return num_str.split(//).map! {|x| x.to_i}
end

# 맨 위쪽 가로막대를 그림

def draw_top(part, bar, tab)
  idx = 0
  part << ' ' << bar[tab[idx]] << ' '
end

# 윗쪽의 좌, 우 세로막대를 그림

def draw_up_vert(part, blank, bar, tab)
  left_idx, right_idx = 1, 2
  part << bar[tab[left_idx]] << blank << bar[tab[right_idx]]
end

# 중간의 가로막대

def draw_mid_hori(part, bar, tab)
  idx = 3
  part  << ' ' << bar[tab[idx]] << ' '
end

# 아래쪽의 좌, 우 세로막대 그림

def draw_down_vert(part, blank, bar, tab)
  left_idx, right_idx = 4, 5
  part << bar[tab[left_idx]] << blank << bar[tab[right_idx]]
end

# 제일 밑의 가로막대

def draw_bottom(part, bar, tab)
  idx = 6
  part << ' ' <<  bar[tab[idx]] << ' '
end

def hori_var_idx?(idx)
  return (idx % 2 == 0)
end

def print_lcd(lcd, each_size)

  # 가로바는 each_size 길이만큼 만들어져서 들어가있지만은 세로바는
  # 그냥 '|' 아니면 ' '로만 있기 때문에 루프로 찍어야함

  lcd.each_index {|i| n = (hori_var_idx?(i) ? 1 : each_size)
    n.times do
      puts lcd[i]
    end }

end

def draw_one_num(lcd, hori_bar, vert_bar, tab)

    draw_top(lcd[0], hori_bar, tab)
    draw_up_vert(lcd[1], hori_bar[0], vert_bar, tab)
    draw_mid_hori(lcd[2], hori_bar, tab)
    draw_down_vert(lcd[3], hori_bar[0], vert_bar, tab)
    draw_bottom(lcd[4], hori_bar, tab)

end

def make_lcd(num_str, each_size)

  # 가로바, 세로바인데 0번 인덱스엔 공백, 1번 인덱스엔 바를 넣음
  # 가로바같은 경우 그냥 글자 크기만큼 공백, '-'를 길게 만들면 된다

  hori_bar = [Array.new(each_size , ' ').to_s, Array.new(each_size, '-').to_s]

  vert_bar = [' ', '|']

  num_arr = str_to_int_arr(num_str)

  # tab에는 0 ~ 9까지의 숫자가 인덱스로 쓰여갖구
  # 각 숫자의 7 세그먼트에 선이 그려지면 1, 안그려지면 0을 가지구 있음
  # 순서는 맨 위 가로바, 왼쪽 위 세로, 오른쪽 위 세로, 중간 가로,
  # 왼쪽 아래 세로, 오른쪽 아래 세로, 맨 밑 가로 순서
  # 예를 들면 0은 중간의 가로바만 없구 나머지는 다 있으니까 [1, 1, 1, 0, 1, 1, 1] 이다
  # 종이에 그려보면 이해가 좀 더 쉬움

  tab = [ [1, 1, 1, 0, 1, 1, 1], [0, 0, 1, 0, 0, 1, 0], [1, 0, 1, 1, 1, 0, 1],
          [1, 0, 1, 1, 0, 1, 1], [0, 1, 1, 1, 0, 1, 1], [1, 1, 0, 1, 0, 1, 1],
          [1, 1, 0, 1, 1, 1, 1], [1, 1, 1, 0, 0, 1, 0], [1, 1, 1, 1, 1, 1, 1],
          [1, 1, 1, 1, 0, 1, 1] ]

  # lcd display방식은 결국 맨 위 가로바, 중간에서 윗부분의 좌, 우 세로바,
  # 중간에 있는가로바, 중간에서 아랫부분의 좌, 우 세로바,
  # 맨 아래의 가로바 이렇게 7부분으로 구성된다.

  # 문자열 배열인데 요소갯수는 5개 (세로바는 좌, 우 세로바 둘다 한 문자열에 나타낼것임

  lcd = ['', '', '', '', '']

  # 숫자사이는 적당히 띄워준다

  blank_inter = '  '

  (num_arr.length).times do |i|
    ( lcd.each {|x| x << blank_inter} if (i > 0) )
    draw_one_num(lcd, hori_bar, vert_bar, tab[num_arr[i]])
  end

  return lcd

end


def lcd_display(num_str, each_size)
  print_lcd(make_lcd(num_str, each_size), each_size)
end

lcd_display('0123456789', 5)
크리에이티브 커먼즈 라이선스
Creative Commons License
Posted by sloth_chord