수강생 여러분,
모두 열심히 수업에 적극적으로 참여해 주셔서 대단히 고맙습니다.
한사람도 빠짐없이 과제를 제출해 주셨습니다. 그래서 과제에 대해서 해설을
하면서 이번 학기를 마무리 하려고 합니다. 이번에 제출된 과제를 보면서
다음과 같이 두가지 점에서 매우 놀랐습니다.
첫째, 기발한 아이디어로 박스그림을 포함하여 일반적인 함수를 만든
수강생이 있습니다.
둘째, rev 함수를 사용하여 엄청나게 간략한 코드를 만든 수강생도 있습니다.
그래서 내가 이것을 참고하여 일반적인 함수를 만들어 보았습니다.
# 1부터 25까지의 숫자를 5x5 행렬에 미리 넣어 놓고
# 짝수행을 찾아서 숫자를 반대로 뒤집는 함수를 썼습니다.
# 아이디어를 주신 수강생에게 감사를 드립니다.
out=matrix(1:25, 5,5,byrow=T)
for (i in 1:5) {
if (i %% 2 == 0) out[i,] = rev(out[i,])
}
print(out)
## [,1] [,2] [,3] [,4] [,5]
## [1,] 1 2 3 4 5
## [2,] 10 9 8 7 6
## [3,] 11 12 13 14 15
## [4,] 20 19 18 17 16
## [5,] 21 22 23 24 25
# 1부터 25까지의 알파벳 문자를 letters함수를 써서 5x5 행렬에 미리 넣어 놓고
# 짝수행을 찾아서 문문자를 반대로 뒤집는 함수를 썼습니다.
out=matrix(letters[-26],5,5,byrow=T)
for (i in 1:5) {
if (i %% 2 == 0) out[i,] = rev(out[i,])
}
print(out,quote=F)
## [,1] [,2] [,3] [,4] [,5]
## [1,] a b c d e
## [2,] j i h g f
## [3,] k l m n o
## [4,] t s r q p
## [5,] u v w x y
# 1부터 25까지의 숫자를 입력할 때, 홀수행은 그냥 입력하고,
# 짝수행은 반대로 입력하는 방법입니다.
out=matrix(nrow=5, ncol=5)
n = 1
for (i in 1:5) {
for (j in 1:5) {
if (i %% 2 != 0) {
out[i,j] = n # 홀수행은 열의 번호를 (1,2,3,4,5)로 입력
} else {
out[i, 6-j] = n # 짝수행은 열의 번호를 (5,4,3,2,1)로 입력
}
n = n + 1
}
}
print(out)
## [,1] [,2] [,3] [,4] [,5]
## [1,] 1 2 3 4 5
## [2,] 10 9 8 7 6
## [3,] 11 12 13 14 15
## [4,] 20 19 18 17 16
## [5,] 21 22 23 24 25
# n*n개의 숫자로 미리 숫자를 행렬에 입력해 놓고,
# 짝수행을 찾아서 숫자의 순서를 뒤집는다.
boxN = function(n) {
out = matrix(1:(n*n), n, n, byrow=T)
for (i in 1:n) {
if (i %% 2 == 0) out[i,] = rev(out[i,])
}
print(out)
}
boxN(5)
## [,1] [,2] [,3] [,4] [,5]
## [1,] 1 2 3 4 5
## [2,] 10 9 8 7 6
## [3,] 11 12 13 14 15
## [4,] 20 19 18 17 16
## [5,] 21 22 23 24 25
boxN(10)
## [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10]
## [1,] 1 2 3 4 5 6 7 8 9 10
## [2,] 20 19 18 17 16 15 14 13 12 11
## [3,] 21 22 23 24 25 26 27 28 29 30
## [4,] 40 39 38 37 36 35 34 33 32 31
## [5,] 41 42 43 44 45 46 47 48 49 50
## [6,] 60 59 58 57 56 55 54 53 52 51
## [7,] 61 62 63 64 65 66 67 68 69 70
## [8,] 80 79 78 77 76 75 74 73 72 71
## [9,] 81 82 83 84 85 86 87 88 89 90
## [10,] 100 99 98 97 96 95 94 93 92 91
# n*n개의 문자로 미리 문자를 행렬에 입력해 놓고,
# 짝수행을 찾아서 문자를 뒤집는다.
# 전체 문자의 수를 알파벳 26자를 이용하여 n*n개의 벡터를 만드는 것이 중요하다.
# 즉 10x10의 문자를 채우려면, 100 %/% 26 ==> 3 (몫), 100 %% 26 ==> 22 (나머지)를
# 이용하여 문자 vector를 만듬. c(rep(letters,3),letters(1:22))가 바로 우리가
# 원하는 문자 vector이다
boxC = function(n) {
nn=n*n
nn1 = nn %/% 26 # 몫
nn2 = nn %% 26 # 나머지
out = c(rep(letters,nn1),letters[1:nn2])
out = matrix(out,n,n,byrow=T)
for (i in 1:n) {
if (i %% 2 == 0) out[i,] = rev(out[i,])
}
print(out, quote=F)
}
boxC(5)
## [,1] [,2] [,3] [,4] [,5]
## [1,] a b c d e
## [2,] j i h g f
## [3,] k l m n o
## [4,] t s r q p
## [5,] u v w x y
boxC(10)
## [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10]
## [1,] a b c d e f g h i j
## [2,] t s r q p o n m l k
## [3,] u v w x y z a b c d
## [4,] n m l k j i h g f e
## [5,] o p q r s t u v w x
## [6,] h g f e d c b a z y
## [7,] i j k l m n o p q r
## [8,] b a z y x w v u t s
## [9,] c d e f g h i j k l
## [10,] v u t s r q p o n m
출력결과가 화면에서 깨져서 나오기는 하지만, 이렇게 과제를 완성하기 위해서 아이디어를 내고 특별한 방법을 사용하신 것에 박수를 보냅니다. 감사합니다.
# 2023.04.28
# aSSIST AI첨단대학원 과정 : "Statistics with R'
# 과제 (1)
# 매트릭스의 크기를 입력하면 출력하는 과제
# 단, 짝수행의 원소 숫자는 위치가 서로 치환되어 출력되어야 함
# 예를 들어 5를 입력하면 아래와 같이 출력됨
# decorateMatrix(size, position)
# 출력 형태가 보기 좋도록 특수기호를 이용해서 행렬의 외곽과 내부에 선을 긋는다.
# 이 함수를 통해 다음의 세 가지 라인이 출력된다. (두 자리 숫자까지만 출력이 잘 됨)
# decorateMatrix(5, START) : ┌────┬────┬────┬────┬────┐
# decorateMatrix(5, MIDDLE) : ├────┼────┼────┼────┼────┤
# decorateMatrix(5, END) : └────┴────┴────┴────┴────┘
#
#
# param size : Integer, : 매트릭스의 컬럼 수 (몇 번이나 반복되어야 할지 카운트)
# param position : Integer, : 선긋기를 적용할 매트릭스 내 위치, START / MIDDLE / END값을 갖는다
# no return
decorateMatrix<-function(size,position){
unit = rep('─',4) # 숫자가 채워질 매트릭스의 한 칸 크기
c_left = c('┌','├','└') # 좌측 외곽선을 표현할 decorator
c_middle = c('┬','┼','┴') # 가운데 외곽선/내부선을 표현할 decorator
c_right = c('┐','┤','┘') # 우측 외곽선을 표현할 decorator
cat(c_left[position],sep='') # 첫번째 모서리
for (i in 1:(size-1)){ # 열의 크기만큼 반복
cat(unit,c_middle[position],sep='') # 예) ───┬────┬────┬────┬────
}
cat(unit,c_right[position],'\n',sep='') # 마지막 한 칸과 모서리
}
# getNumericMatrix(row, col, reverse, printResult)
# (row,col) 크기를 매트릭스를 만들고 1부터 (row*col) 숫자만큼 채운다.
# reverse 인자값에 따라 짝수 행의 값은 서로 순서를 바꿀 수 있다.
# printResult 인자값을 활용하여 디버깅 목적으로 매트릭스를 출력해 볼 수 있다.
#
#
# param row : Integer, : 매트릭스의 행 크기
# param col : Integer, : 매트릭스의 열 크기, 행과 열의 크기가 정해지면 자동으로 1부터 숫자가 채워진다
# param reverse : Logical, : 짝수 행마다 원소의 위치를 바꿀 것인지를 지정한다.
# param printResult : Logical, : 만들어진 매트릭스를 출력할 지 여부를 지정한다.
# return Matrix : 만들어진 매트릭스를 반환한다
getNumericMatrix <- function(row,col,reverse,printResult = FALSE){
a = matrix(1:(row*col), row, col, byrow=T) # 1부터 정수가 채워지는 매트릭스를 생성
if(reverse) # 만약 reverse 옵션이 TRUE이면
a[seq(from=2,to=row, by=2),] <- a[seq(from=2, to=row, by=2),ncol(a):1] # 짝수 행마다 1:nol(a) 대신 ncol(a):1 값으로 치환. (R의 간편함.)
if (printResult) print(a) # 출력하고 싶으면 printResult = TRUE로 설정
return (a)
}
# printLine(mat, row_num)
# 인자로 입력받은 매트릭스의 지정된 행을 출력하되 매트릭스의 decoration을 위해서 특수 기호와 스페이스를 추가한다.
# 매트릭의 특정 행의 값이 6,7,8,9,10 일 경우, 이 함수를 거치면
# '│ 6 │ 7 │ 8 │ 9 │ 10 │' 형태로 decoration되어 출력된다. (숫자 앞 뒤로 bar와 space가 추가됨)
#
# param mat : Matrix, : 출력하고자 하는 매트릭스
# param row_num : Integer, : 출력하고자 하는 매트릭스의 행
# no return
printLine <- function(mat,row_num){
a=paste0("│ ", mat[row_num,],ifelse(mat[row_num,]<10,' ',' ')) # paste0함수를 이용해서 공란없이 연속으로 출력
# 한 자리 숫자이면 스페이스를 두 개 추가
# 두 자리 숫자이면 스페이스를 한 개 추가
# 3항 연산자 ifelse 를 써서 한 줄로 처리함.
cat(a,"│\n",sep='') # 매트릭스의 맨 우측 라인을 표시하기 위해추가
}
# printMatrix(size, reverse)
# size를 입력받으면 행과 열의 크기가 동일한 매트릭스를 구성한 후에 1부터 숫자를 채우는 메인함수
#
#
# param size : Integer, : 출력하고자 하는 매트릭스의 크기, n X n 사이즈의 행렬이 형성된다.
# param reverse : logical, : 매트릭스의 짝수 행의 원소 위치를 서로 맞바꿀 것인지 지정하는 인자
# no return
printMatrix <- function(size,reverse=TRUE) {
START = 1
MIDDLE = 2
END = 3
# STEP (1) : matrix를 구성하고 내부에 원소들을 채운다, reverse 인자값에 따라 짝수 행의 값이 변경될 수도 있다.
mat = getNumericMatrix(size,size,reverse,printResult = FALSE)
decorateMatrix(size,START) # STEP (2) 첫번째 외곽선을 그린다
for (i in 1:size){ # STEP (3) 행의 크기만큼 반복
printLine(mat,i) # STEP (4) 행 별로 한 줄씩 숫자를 출력
if (i<size) decorateMatrix(size,MIDDLE) # STEP (5) 마지막 행이 아니라면 행 사이를 구분하기 위한 선을 그린다
}
decorateMatrix(size,END) # STEP (6) 마지막 외곽선을 그린다
}
# 테스트 코드
# 5 X 5 사이즈의 매트릭스를 출력하되 짝수행의 원소 위치를 맞바꿈
printMatrix(5)
## ┌────┬────┬────┬────┬────┐
## │ 1 │ 2 │ 3 │ 4 │ 5 │
## ├────┼────┼────┼────┼────┤
## │ 10 │ 9 │ 8 │ 7 │ 6 │
## ├────┼────┼────┼────┼────┤
## │ 11 │ 12 │ 13 │ 14 │ 15 │
## ├────┼────┼────┼────┼────┤
## │ 20 │ 19 │ 18 │ 17 │ 16 │
## ├────┼────┼────┼────┼────┤
## │ 21 │ 22 │ 23 │ 24 │ 25 │
## └────┴────┴────┴────┴────┘
# 5 X 5 사이즈의 매트릭스를 출력하되, 항상 우측의 숫자가 그 행에서 가장 작은 숫자부터 출력되도록 함
printMatrix(5, reverse=FALSE)
## ┌────┬────┬────┬────┬────┐
## │ 1 │ 2 │ 3 │ 4 │ 5 │
## ├────┼────┼────┼────┼────┤
## │ 6 │ 7 │ 8 │ 9 │ 10 │
## ├────┼────┼────┼────┼────┤
## │ 11 │ 12 │ 13 │ 14 │ 15 │
## ├────┼────┼────┼────┼────┤
## │ 16 │ 17 │ 18 │ 19 │ 20 │
## ├────┼────┼────┼────┼────┤
## │ 21 │ 22 │ 23 │ 24 │ 25 │
## └────┴────┴────┴────┴────┘
# 행과 열의 크기에 따라 매트릭스 내 숫자 배열이 자동으로 이루어지고,
printMatrix(7)
## ┌────┬────┬────┬────┬────┬────┬────┐
## │ 1 │ 2 │ 3 │ 4 │ 5 │ 6 │ 7 │
## ├────┼────┼────┼────┼────┼────┼────┤
## │ 14 │ 13 │ 12 │ 11 │ 10 │ 9 │ 8 │
## ├────┼────┼────┼────┼────┼────┼────┤
## │ 15 │ 16 │ 17 │ 18 │ 19 │ 20 │ 21 │
## ├────┼────┼────┼────┼────┼────┼────┤
## │ 28 │ 27 │ 26 │ 25 │ 24 │ 23 │ 22 │
## ├────┼────┼────┼────┼────┼────┼────┤
## │ 29 │ 30 │ 31 │ 32 │ 33 │ 34 │ 35 │
## ├────┼────┼────┼────┼────┼────┼────┤
## │ 42 │ 41 │ 40 │ 39 │ 38 │ 37 │ 36 │
## ├────┼────┼────┼────┼────┼────┼────┤
## │ 43 │ 44 │ 45 │ 46 │ 47 │ 48 │ 49 │
## └────┴────┴────┴────┴────┴────┴────┘
# decoration도 알아서 행렬의 크기에 따라 조정됨
printMatrix(7, reverse=FALSE)
## ┌────┬────┬────┬────┬────┬────┬────┐
## │ 1 │ 2 │ 3 │ 4 │ 5 │ 6 │ 7 │
## ├────┼────┼────┼────┼────┼────┼────┤
## │ 8 │ 9 │ 10 │ 11 │ 12 │ 13 │ 14 │
## ├────┼────┼────┼────┼────┼────┼────┤
## │ 15 │ 16 │ 17 │ 18 │ 19 │ 20 │ 21 │
## ├────┼────┼────┼────┼────┼────┼────┤
## │ 22 │ 23 │ 24 │ 25 │ 26 │ 27 │ 28 │
## ├────┼────┼────┼────┼────┼────┼────┤
## │ 29 │ 30 │ 31 │ 32 │ 33 │ 34 │ 35 │
## ├────┼────┼────┼────┼────┼────┼────┤
## │ 36 │ 37 │ 38 │ 39 │ 40 │ 41 │ 42 │
## ├────┼────┼────┼────┼────┼────┼────┤
## │ 43 │ 44 │ 45 │ 46 │ 47 │ 48 │ 49 │
## └────┴────┴────┴────┴────┴────┴────┘