Ruby 프로그래밍 2 loop, 수열 함수 정의 및 호출 반복과 재귀 한국어 정보의 전산 처리 2017. 4. 26.
사용자로부터 입력받은 정수들의 합, 평균 3 정수들을 command line argument로 제공한 경우 sum = 0 ARGV.each do |i| # ARGV : command line argument로 제공된 문자열들의 Array sum += i.to_i # ARGV Array에 들어 있는 각 문자열 i를 정수로 변환하여 # sum에 더함. end print sum, "\t", sum.to_f / ARGV.length
구구단 출력하기 (1..9).each do |y| #1부터 9까지 (2..9).each do |x| #2단부터 9단까지 print x, "*", y, "=", x*y, "\t“ #이 라인은 8*9=72번 실행됨. end #작은 loop는 9번 반복 실행됨. print “\n“ #이 라인은 9번 반복 실행됨. end loop가 중첩(nesting)될 수 있음. 큰 loop 안에 작은 loop가 내포됨. 큰 loop의 변수의 하나의 값에 대해 작은 loop가 1번 돌아감. 작은 loop 안에 들어 있는 블록은 (큰 loop의 변수의 값의 개수 * 작 은 loop의 변수의 값의 개수)만큼 실행됨.
한글 완성형 2350자 출력하기 # -*- coding: cp949 -*- (0xb0..0xc8).each do |ap| #앞 바이트의 범위. 총 25개 (0xa1..0xfe).each do |dui| #뒤 바이트의 범위. 총94개 print ap.chr, dui.chr, "\n“ #ap, dui를 숫자가 아니라 문자(character)로 출력 #printf "%c%c\n", ap, dui 라고 해도 됨. #25*94=2350번 실행됨. end ruby script 파일의 인코딩을 cp949로 해서 저장해야 함. .chr 메소드는 정수를 (그 정수 값을 code point로 하는) 문자로 변환 .ord 메소드는 문자를 (그 문자의 code point에 해당하는) 정수로 변환
등차수열 출력하기 등차수열: 각 항과 다음 항 사이의 差(공차)가 일정한 수열 puts "등차수열을 출력해 드립니다. 초항, 공차, 상한선을 입력하세요." first = gets.chomp.to_i #초항 diff = gets.chomp.to_i #공차 max = gets.chomp.to_i #상한선 i = first #출력할 수를 나타내는 변수 i를 초항으로 설정 while i <= max do # i가 상한선보다 작거나 같으면 블록을 반복 실행 puts i # i를 출력 i += diff # i에 공차를 더함 end
등차수열 출력하기 command line argument 이용 first = ARGV[0].to_i # 첫째 인자: 초항 diff = ARGV[1].to_i # 둘째 인자: 공차 max = ARGV[2].to_i # 셋째 인자: 상한선 i = first while i <= max do puts i i += diff end
등차수열 출력하기: 유의사항 추가 사용자가 command line argument를 충분히 제공하지 않으면 앞의 code는 제대로 작동하지 않음. 또한 공차가 0이면 loop가 무한히 반복됨. 그럴 경우에는 경고 메시지를 출력하고 프로그램을 조기 종료. if ARGV.length < 3 print "초항, 공차, 상한선을 알려 주세요.“ #경고 메시지 exit # 프로그램 종료 end first = ARGV[0].to_i diff = ARGV[1].to_i if diff == 0 print "공차가 0이면 안 됩니다.“ # 경고 메시지
등차수열: 공차가 음수인 경우 공차가 음의 정수인 등비수열도 수학적으로 가능함. 공차가 음수인 경우에 대비해야 함 if diff > 0 # 공차가 양수 while i <= max do puts i i += diff end else # 공차가 음수 while i >= max do # i가 하한선(max)보다 크면 블록을 반복 실행
등비수열 출력 등비수열: 각 항과 다음 항 사이의 比(공비)가 일정한 수열 if ARGV.length < 3 등비수열: 각 항과 다음 항 사이의 比(공비)가 일정한 수열 if ARGV.length < 3 print "초항,공비,상한선 알려줘." exit end first = ARGV[0].to_i ratio = ARGV[1].to_i max = ARGV[2].to_i if ratio <= 1 print "공비가 1 이하이면 안돼." exit end i = first while i <= max do puts i i *= ratio
등비수열: 공비가 1보다 작은 경우 대비 if ARGV.length < 3 print "초항,공비,상한선 알려줘." exit end first = ARGV[0].to_f ratio = ARGV[1].to_f max = ARGV[2].to_f if ratio == 1.0 or ratio =< 0.0 print "공비가 1, 0, 음수이면 안돼.” i = first if ratio > 1.0 while i <= max do puts i i *= ratio end else # 0.0 < ratio < 1.0 while i >= max do
피보나치(Fibonacci) 수열 n항과 n+1항의 합이 n+2항이 되는 수열 if ARGV.length < 3 print "초항, 제2항, 상한선을 입력." exit end x = ARGV[0].to_i y = ARGV[1].to_i max= ARGV[2].to_i puts x puts y z = x+y while z <= max do puts z x, y = y, z end Ruby는 parallel assignment가 가능하다는 게 특징임. x, y = y, z # y의 값을 x에 할당하고, z의 값을 y에 할당함. (이 순서대 로)
factorial 구하기 1: iterative algorithm n!, factorial(n) : 1부터 n까지의 정수를 모두 곱한 수 if ARGV.length < 1 print "factorial을 구해 드립니다. n을 입력하세요." exit end n = ARGV[0].to_i result = 1 #결과값을 담을 변수를 일단 곱셈의 항등원인 1로 설정 (2..n).each do |i| # 1은 곱하나 마나이므로 2부터 n까지 result *= i # result = result * i와 같음. result에 i를 곱함 print result
factorial 구하기 2: 함수 이용 called code def factorial(n) #함수 정의 result = 1 (2..n).each do |i| result *= i end result #return value #함수의 마지막에 있는 expression을 #evaluate하여 그 값을 return함 calling code if ARGV.length < 1 print "factorial: n을 입력해." exit end require './factorial_func.rb‘ # factorial 함수가 정의된 파일을 불러옴. print factorial( ARGV[0].to_i ) # 첫째 인자를 factorial 함수에 적용
factorial 구하기 2: recursive algorithm n!은 얼마? n * (n-1)!임. (n-1)!은? (n-1) * (n-2)!임. …… 이 논리를 적용하여, factorial 함수 내에서 다시 factorial 함수를 호출 할 수 있음: 재귀 호출(recursive call) def factorial(n) return n if n <= 2 # 종결 조건: 재귀 호출을 중지, 함수를 종료함. n * factorial(n-1) # 재귀 호출: n! == n * (n-1)! end 무한 재귀 호출을 방지하기 위해 종결 조건 필요: n<=2인 경우 함수의 재귀 호출은 수학적 귀납법과 논리 구조가 같음. 수학적 귀납법의 예: 모든 자연수가 ~~의 속성을 가짐을 증명. 1은 ~~의 속성을 가짐. (초기 조건) n이 ~~의 속성을 가지면 n+1도 ~~의 속성을 가짐. (점화식)
순열(permutation), 조합(combination) 순열: n개의 요소 중 m개를 뽑아 일렬로 늘어놓는 방법의 수 nPm = n* (n-1) * (n-2) * …… = n! / (n-m)! └-------m개--------┘ 조합: n개의 요소 중 m개를 뽑는 방법의 수 nCm = n! / ( (n-m)! * m! ) = nPm / m! require './factorial_func.rb‘ # factorial 함수가 정의된 파일 불러옴 n = ARGV[0].to_i # n = 첫째 인자 m = ARGV[1].to_i # m = 둘째 인자 perm = factorial(n) / factorial(n-m) # 순열=n!/(n-m)! comb = perm / factorial(m) #조합=순열/m! print perm, “\t”, comb