Google Code Jam을 하기 위한 기반 클래스Google Code Jam을 하기 위한 기반 클래스

Posted at 2008. 12. 27. 16:39 | Posted in 프로그래밍 언어/Ruby
일단 Google Code Jam은 인풋파일의 형태가 보통

[처리해야 할 인풋 개수]
[인풋 1]
[인풋 2]
...

이런 식이고 출력형태는

Case #1: [값]
Case #2: [값]
...

이런 식이다.

어떤 문제를 풀던간에 파일 처리는 기본적으로 해야 하는 부분이기 때문에
이 부분을 처리해 주는 클래스를 하나 만들었다.

file_reader.rb
class FileReader
def initialize(&algorithm)
@fin = File.open("input/" + $0.split(".")[0] + ".txt")
@fout = File.new("input/" + $0.split(".")[0] + "_out.txt", "w")
@num_of_inputs = @fin.gets # read value meaning # of inputs
@algorithm = algorithm
end
def process_per_line
line_cnt = 1
@fin.each_line do |line|
result = @algorithm.call(line)
@fout.print "Case ##{line_cnt}: #{result}\n"
print "Case ##{line_cnt}: #{result}\n"
line_cnt += 1
end
end
def destroy
@fin.close
@fout.close
end
end

인풋, 아웃풋 파일 이름은 이 클래스가 사용되는 파일 이름을 사용한다.
예를 들어 이 클래스가 test.rb 에 include/require로 불려진다면 input/output file은
input/test.txt, input/test_out.txt 가 될 것이다.
그리고 문제를 풀 파일을 하나 생성하여 다음과 같이 위 클래스를 사용한다.
아래는 제대로 문제를 푼 것이 아니다;;

Round1A_numbers.rb
require 'file_reader.rb'

file_reader = FileReader.new do |line|
inner_val = (3 + Math.sqrt(5))**line.to_i
inner_val = inner_val.floor % 1000
result = ""
case inner_val
when (0..9)
result += "00"
when (10..99)
result += "0"
end
result + inner_val.to_s
end
file_reader.process_per_line
file_reader.destroy

FileReader.new 뒤의 do-end 블록이 FileReader 클래스의 @algorithm이 되고,
process_per_line 메서드를 호출하면 @algorithm 에 구현된? 메서드의 블록으로 파일의 each line을 파라미터로 넘긴다.
즉 FileReader.new 뒤의 블록에 파일 한 줄을 읽어 문제를 처리하는 알고리즘을 구현하면 된다.
그리고 블록의 마지막에 결과를 위치시킨다.

저런 FileReader.new do - end 가 FileReader의 initialize(&algorithm) 의 algorithm으로 넘겨져 쓰이는 것을
뭐라고 부르는 지는 잘 모르겠다.
이게 closure인가-_-?;;

루비는 시작한지 며칠 안 돼서 루비의 특징을 살린 코드라고는 절대 할 수 없는 코드지만;
C++에서는 경험하지 못했던 것들이라 언어 자체가 흥미롭고 재밌다.
//