R강의: 제3강 보충 + 구구단 + Prime Number 구하기

3-1. Vector/Matrix 보충

# repeat 명령
rep(1:3, times = 5)
##  [1] 1 2 3 1 2 3 1 2 3 1 2 3 1 2 3
rep(1:3, 5)
##  [1] 1 2 3 1 2 3 1 2 3 1 2 3 1 2 3
rep(TRUE, 5)
## [1] TRUE TRUE TRUE TRUE TRUE
xx = rep(TRUE, 5)
xx[3] = FALSE

# xx 가운데 TRUE의 위치 
which(xx)
## [1] 1 2 4 5
xx = rep(T, 10)

# 4부터 10까지 2의 배수를 선택
xx[seq(4, 10, 2)]
## [1] TRUE TRUE TRUE TRUE
# 4부터 10까지 2의 배수에 해당하는 것을 FALSE로 바꿈
xx[seq(4, 10, 2)] = FALSE

# xx 가운데 TRUE인 것의 위치를 표시
which(xx) 
## [1] 1 2 3 5 7 9
# xx 가운데 TRUE인 것의 갯수를 표시
length(which(xx))
## [1] 6
# 엑셀자료의 reading
library(openxlsx)
df = read.xlsx("regress.xlsx")

# colSds function (칼럼별 표준편차 구하기)
colSds = function(df) {
  return(apply(df,2,sd))
}
colSds(df)
## 근무만족도   대인관계   자아개념   근무평정    SES점수 
##   18.54835   20.13358   22.16604   12.08571   15.16742
# colNs function (칼럼별 사례수 구하기)
colNs = function(df) {
  return(colSums(!is.na(df)))
}
colNs(df)
## 근무만족도   대인관계   자아개념   근무평정    SES점수 
##         30         30         30         30         30

3-2. 구구단 과제 정리

# 구구단을 옆으로 늘어놓기

gugu1 = function(n)
{
  for (j in 1:9) {
    for ( i in 2:n){
      cat(i,"*", j, "=",i*j, "\t")
    }
    cat("\n")
  }
}

gugu1(7)
## 2 * 1 = 2    3 * 1 = 3   4 * 1 = 4   5 * 1 = 5   6 * 1 = 6   7 * 1 = 7   
## 2 * 2 = 4    3 * 2 = 6   4 * 2 = 8   5 * 2 = 10  6 * 2 = 12  7 * 2 = 14  
## 2 * 3 = 6    3 * 3 = 9   4 * 3 = 12  5 * 3 = 15  6 * 3 = 18  7 * 3 = 21  
## 2 * 4 = 8    3 * 4 = 12  4 * 4 = 16  5 * 4 = 20  6 * 4 = 24  7 * 4 = 28  
## 2 * 5 = 10   3 * 5 = 15  4 * 5 = 20  5 * 5 = 25  6 * 5 = 30  7 * 5 = 35  
## 2 * 6 = 12   3 * 6 = 18  4 * 6 = 24  5 * 6 = 30  6 * 6 = 36  7 * 6 = 42  
## 2 * 7 = 14   3 * 7 = 21  4 * 7 = 28  5 * 7 = 35  6 * 7 = 42  7 * 7 = 49  
## 2 * 8 = 16   3 * 8 = 24  4 * 8 = 32  5 * 8 = 40  6 * 8 = 48  7 * 8 = 56  
## 2 * 9 = 18   3 * 9 = 27  4 * 9 = 36  5 * 9 = 45  6 * 9 = 54  7 * 9 = 63  
# 2단부터 9단까지 출력하기: n은 한 줄에 들어가는 단수 

gugu2 = function(size){
    if (size > 8) {
        size = 8
        print("Maximum size is limited to 8.")
    }
        
    start = 2
    end = start+size-1
    for(k in 1: ceiling((9-2+1)/size)){
        for (i in 1:9){
            for(j in start:end){
                cat(j, " x ", i, " = ", j*i)
                if ((j==9) |(j-1)%%size == 0)
                    cat('\n')
                else
                    cat('\t|\t')
            }
        }
        start = end + 1
        next_end = start+size-1
        if (next_end > 9) end = 9   # 9단 이상은 출력할 필요없다
        else end = next_end
        
        cat("-----------------\n")
    }
}

gugu2(3)
## 2  x  1  =  2    |   3  x  1  =  3   |   4  x  1  =  4
## 2  x  2  =  4    |   3  x  2  =  6   |   4  x  2  =  8
## 2  x  3  =  6    |   3  x  3  =  9   |   4  x  3  =  12
## 2  x  4  =  8    |   3  x  4  =  12  |   4  x  4  =  16
## 2  x  5  =  10   |   3  x  5  =  15  |   4  x  5  =  20
## 2  x  6  =  12   |   3  x  6  =  18  |   4  x  6  =  24
## 2  x  7  =  14   |   3  x  7  =  21  |   4  x  7  =  28
## 2  x  8  =  16   |   3  x  8  =  24  |   4  x  8  =  32
## 2  x  9  =  18   |   3  x  9  =  27  |   4  x  9  =  36
## -----------------
## 5  x  1  =  5    |   6  x  1  =  6   |   7  x  1  =  7
## 5  x  2  =  10   |   6  x  2  =  12  |   7  x  2  =  14
## 5  x  3  =  15   |   6  x  3  =  18  |   7  x  3  =  21
## 5  x  4  =  20   |   6  x  4  =  24  |   7  x  4  =  28
## 5  x  5  =  25   |   6  x  5  =  30  |   7  x  5  =  35
## 5  x  6  =  30   |   6  x  6  =  36  |   7  x  6  =  42
## 5  x  7  =  35   |   6  x  7  =  42  |   7  x  7  =  49
## 5  x  8  =  40   |   6  x  8  =  48  |   7  x  8  =  56
## 5  x  9  =  45   |   6  x  9  =  54  |   7  x  9  =  63
## -----------------
## 8  x  1  =  8    |   9  x  1  =  9
## 8  x  2  =  16   |   9  x  2  =  18
## 8  x  3  =  24   |   9  x  3  =  27
## 8  x  4  =  32   |   9  x  4  =  36
## 8  x  5  =  40   |   9  x  5  =  45
## 8  x  6  =  48   |   9  x  6  =  54
## 8  x  7  =  56   |   9  x  7  =  63
## 8  x  8  =  64   |   9  x  8  =  72
## 8  x  9  =  72   |   9  x  9  =  81
## -----------------
# 구구단 출력하기: dan-출력하고 싶은 단,  num-한 줄에 넣고 싶은 곱셈
gugu3 = function(dan,num){
for(i in 1:9) {
  cat(dan, "*", i, "=", dan*i, "\t")
  if(i %% num == 0) {
    cat("\n")
  }
 }
}

gugu3(5,3)
## 5 * 1 = 5    5 * 2 = 10  5 * 3 = 15  
## 5 * 4 = 20   5 * 5 = 25  5 * 6 = 30  
## 5 * 7 = 35   5 * 8 = 40  5 * 9 = 45  
# k: 각 단의 시작 위치 (1단, 4단, 9단)
# i: 1~9 까지의 숫자
# 단 이름 ([* 단])을 추가

for(k in c(1,4,7)) {
    cat("[",k,"단 ]\t","[",k+1,"단 ]\t [",k+2,"단 ]\n")
    for(i in 1:9) {
    for(j in k:(k+2)) {
      cat(paste0(j, " x ", i, " = ", i*j, "\t"))
    }
    cat("\n")
  }
  cat("\n")
}
## [ 1 단 ]   [ 2 단 ]     [ 3 단 ]
## 1 x 1 = 1    2 x 1 = 2   3 x 1 = 3   
## 1 x 2 = 2    2 x 2 = 4   3 x 2 = 6   
## 1 x 3 = 3    2 x 3 = 6   3 x 3 = 9   
## 1 x 4 = 4    2 x 4 = 8   3 x 4 = 12  
## 1 x 5 = 5    2 x 5 = 10  3 x 5 = 15  
## 1 x 6 = 6    2 x 6 = 12  3 x 6 = 18  
## 1 x 7 = 7    2 x 7 = 14  3 x 7 = 21  
## 1 x 8 = 8    2 x 8 = 16  3 x 8 = 24  
## 1 x 9 = 9    2 x 9 = 18  3 x 9 = 27  
## 
## [ 4 단 ]   [ 5 단 ]     [ 6 단 ]
## 4 x 1 = 4    5 x 1 = 5   6 x 1 = 6   
## 4 x 2 = 8    5 x 2 = 10  6 x 2 = 12  
## 4 x 3 = 12   5 x 3 = 15  6 x 3 = 18  
## 4 x 4 = 16   5 x 4 = 20  6 x 4 = 24  
## 4 x 5 = 20   5 x 5 = 25  6 x 5 = 30  
## 4 x 6 = 24   5 x 6 = 30  6 x 6 = 36  
## 4 x 7 = 28   5 x 7 = 35  6 x 7 = 42  
## 4 x 8 = 32   5 x 8 = 40  6 x 8 = 48  
## 4 x 9 = 36   5 x 9 = 45  6 x 9 = 54  
## 
## [ 7 단 ]   [ 8 단 ]     [ 9 단 ]
## 7 x 1 = 7    8 x 1 = 8   9 x 1 = 9   
## 7 x 2 = 14   8 x 2 = 16  9 x 2 = 18  
## 7 x 3 = 21   8 x 3 = 24  9 x 3 = 27  
## 7 x 4 = 28   8 x 4 = 32  9 x 4 = 36  
## 7 x 5 = 35   8 x 5 = 40  9 x 5 = 45  
## 7 x 6 = 42   8 x 6 = 48  9 x 6 = 54  
## 7 x 7 = 49   8 x 7 = 56  9 x 7 = 63  
## 7 x 8 = 56   8 x 8 = 64  9 x 8 = 72  
## 7 x 9 = 63   8 x 9 = 72  9 x 9 = 81  
# num1: 단
# num2: 구구단의 수

gugu5 = function(num1,num2) {
i = 1  
j = 1  
for (i in 1:num1 ) {
  for (j in 1:num2 ) {
    cat("\n", paste(i , "*", j, " =", i*j))
  }
 }
}

gugu5(3,9)
## 
##  1 * 1  = 1
##  1 * 2  = 2
##  1 * 3  = 3
##  1 * 4  = 4
##  1 * 5  = 5
##  1 * 6  = 6
##  1 * 7  = 7
##  1 * 8  = 8
##  1 * 9  = 9
##  2 * 1  = 2
##  2 * 2  = 4
##  2 * 3  = 6
##  2 * 4  = 8
##  2 * 5  = 10
##  2 * 6  = 12
##  2 * 7  = 14
##  2 * 8  = 16
##  2 * 9  = 18
##  3 * 1  = 3
##  3 * 2  = 6
##  3 * 3  = 9
##  3 * 4  = 12
##  3 * 5  = 15
##  3 * 6  = 18
##  3 * 7  = 21
##  3 * 8  = 24
##  3 * 9  = 27
#***********************************<9단 코드>*********************************
# 1단부터 9단까지 한번에 3칼럼씩 출력해 주는 프로그램

out = matrix("",(9+1)*3,3)
pos = matrix(0,9,2)
lineGap=9
colGap =3

for (i in 1:9) {
    pos[i,1] = ((i-1) %/% colGap) * lineGap + ((i+(colGap-1)) %/% colGap)
    pos[i,2] = ((i-1) %%  colGap) + 1
}

for (i in 1:9)   {out[pos[i,1], pos[i,2]]  = paste0("[",i,"]단")
  for (j in 1:9) {out[pos[i,1]+j,pos[i,2]] = paste0(i, " x ", j, " = ",i*j)
  }
}

print(out, quote=F)
##       [,1]       [,2]       [,3]      
##  [1,] [1]단      [2]단      [3]단     
##  [2,] 1 x 1 = 1  2 x 1 = 2  3 x 1 = 3 
##  [3,] 1 x 2 = 2  2 x 2 = 4  3 x 2 = 6 
##  [4,] 1 x 3 = 3  2 x 3 = 6  3 x 3 = 9 
##  [5,] 1 x 4 = 4  2 x 4 = 8  3 x 4 = 12
##  [6,] 1 x 5 = 5  2 x 5 = 10 3 x 5 = 15
##  [7,] 1 x 6 = 6  2 x 6 = 12 3 x 6 = 18
##  [8,] 1 x 7 = 7  2 x 7 = 14 3 x 7 = 21
##  [9,] 1 x 8 = 8  2 x 8 = 16 3 x 8 = 24
## [10,] 1 x 9 = 9  2 x 9 = 18 3 x 9 = 27
## [11,] [4]단      [5]단      [6]단     
## [12,] 4 x 1 = 4  5 x 1 = 5  6 x 1 = 6 
## [13,] 4 x 2 = 8  5 x 2 = 10 6 x 2 = 12
## [14,] 4 x 3 = 12 5 x 3 = 15 6 x 3 = 18
## [15,] 4 x 4 = 16 5 x 4 = 20 6 x 4 = 24
## [16,] 4 x 5 = 20 5 x 5 = 25 6 x 5 = 30
## [17,] 4 x 6 = 24 5 x 6 = 30 6 x 6 = 36
## [18,] 4 x 7 = 28 5 x 7 = 35 6 x 7 = 42
## [19,] 4 x 8 = 32 5 x 8 = 40 6 x 8 = 48
## [20,] 4 x 9 = 36 5 x 9 = 45 6 x 9 = 54
## [21,] [7]단      [8]단      [9]단     
## [22,] 7 x 1 = 7  8 x 1 = 8  9 x 1 = 9 
## [23,] 7 x 2 = 14 8 x 2 = 16 9 x 2 = 18
## [24,] 7 x 3 = 21 8 x 3 = 24 9 x 3 = 27
## [25,] 7 x 4 = 28 8 x 4 = 32 9 x 4 = 36
## [26,] 7 x 5 = 35 8 x 5 = 40 9 x 5 = 45
## [27,] 7 x 6 = 42 8 x 6 = 48 9 x 6 = 54
## [28,] 7 x 7 = 49 8 x 7 = 56 9 x 7 = 63
## [29,] 7 x 8 = 56 8 x 8 = 64 9 x 8 = 72
## [30,] 7 x 9 = 63 8 x 9 = 72 9 x 9 = 81
#***********************************<일반 코드>*********************************
# 단수와 칼럼수를 선택하면 무엇이든지 출력해 주는 구구단 General Program
# default는 9단까지 한번 3칼럼씩 출력해 주는 프로그램

gugudan <- function(dan=9,col=3) {
  out = matrix("",(dan+1)*ceiling(dan/col),col)
  pos = matrix(0,dan,2)
  
  for (i in 1:dan) {
    pos[i,1] = ((i-1) %/% col) * dan + ((i+col-1) %/% col)
    pos[i,2] = ((i-1) %%  col) + 1
  }
  for (i in 1:dan) {out[pos[i,1], pos[i,2]]  = paste0("[",i,"]단")
    for (j in 1:dan) {out[pos[i,1]+j,pos[i,2]] = paste0(i, " x ", j, " = ",i*j)}
  }

  require('readr')
  library(readr)
  print(out,quote=F)
  write_excel_csv(as.data.frame(out),"gugudan.csv")
}

gugudan(10,4)
## 필요한 패키지를 로딩중입니다: readr
##       [,1]        [,2]          [,3]        [,4]       
##  [1,] [1]단       [2]단         [3]단       [4]단      
##  [2,] 1 x 1 = 1   2 x 1 = 2     3 x 1 = 3   4 x 1 = 4  
##  [3,] 1 x 2 = 2   2 x 2 = 4     3 x 2 = 6   4 x 2 = 8  
##  [4,] 1 x 3 = 3   2 x 3 = 6     3 x 3 = 9   4 x 3 = 12 
##  [5,] 1 x 4 = 4   2 x 4 = 8     3 x 4 = 12  4 x 4 = 16 
##  [6,] 1 x 5 = 5   2 x 5 = 10    3 x 5 = 15  4 x 5 = 20 
##  [7,] 1 x 6 = 6   2 x 6 = 12    3 x 6 = 18  4 x 6 = 24 
##  [8,] 1 x 7 = 7   2 x 7 = 14    3 x 7 = 21  4 x 7 = 28 
##  [9,] 1 x 8 = 8   2 x 8 = 16    3 x 8 = 24  4 x 8 = 32 
## [10,] 1 x 9 = 9   2 x 9 = 18    3 x 9 = 27  4 x 9 = 36 
## [11,] 1 x 10 = 10 2 x 10 = 20   3 x 10 = 30 4 x 10 = 40
## [12,] [5]단       [6]단         [7]단       [8]단      
## [13,] 5 x 1 = 5   6 x 1 = 6     7 x 1 = 7   8 x 1 = 8  
## [14,] 5 x 2 = 10  6 x 2 = 12    7 x 2 = 14  8 x 2 = 16 
## [15,] 5 x 3 = 15  6 x 3 = 18    7 x 3 = 21  8 x 3 = 24 
## [16,] 5 x 4 = 20  6 x 4 = 24    7 x 4 = 28  8 x 4 = 32 
## [17,] 5 x 5 = 25  6 x 5 = 30    7 x 5 = 35  8 x 5 = 40 
## [18,] 5 x 6 = 30  6 x 6 = 36    7 x 6 = 42  8 x 6 = 48 
## [19,] 5 x 7 = 35  6 x 7 = 42    7 x 7 = 49  8 x 7 = 56 
## [20,] 5 x 8 = 40  6 x 8 = 48    7 x 8 = 56  8 x 8 = 64 
## [21,] 5 x 9 = 45  6 x 9 = 54    7 x 9 = 63  8 x 9 = 72 
## [22,] 5 x 10 = 50 6 x 10 = 60   7 x 10 = 70 8 x 10 = 80
## [23,] [9]단       [10]단                               
## [24,] 9 x 1 = 9   10 x 1 = 10                          
## [25,] 9 x 2 = 18  10 x 2 = 20                          
## [26,] 9 x 3 = 27  10 x 3 = 30                          
## [27,] 9 x 4 = 36  10 x 4 = 40                          
## [28,] 9 x 5 = 45  10 x 5 = 50                          
## [29,] 9 x 6 = 54  10 x 6 = 60                          
## [30,] 9 x 7 = 63  10 x 7 = 70                          
## [31,] 9 x 8 = 72  10 x 8 = 80                          
## [32,] 9 x 9 = 81  10 x 9 = 90                          
## [33,] 9 x 10 = 90 10 x 10 = 100

3-3. Prime Number 구하기 과제 정리

# 에라토스테네스의 체(Eratosthenes' sieve)로 Prime Number 구하기
# 1부터 n까지의 숫자를 입력한다. 
# 2부터 n의 제곱근까지, 숫자가 0이 아닐 경우에 {pSet[seq(i+i, n, by=i)] = 0}
# 을 활용하여 그 숫자의 배수를 모두 0으로 바꾼다.

prime1 = function(n) {
  pSet = c(1:n)                           
  pSet[1] = 0
  
  for (i in 2:sqrt(n)){
    if(pSet[i]) {pSet[seq(i+i, n, by=i)] = 0} 
  }
  
  return(pSet[pSet!=0])
}
# prime1(10000000)
length(prime1(10000000))
## [1] 664579
# 에라토스테네스의 체(Eratosthenes' sieve)로 Prime Number 구하기
# n개의 TRUE값으로 시작한다. 
# 2부터 n의 제곱근까지, 숫자가 0이 아닐 경우에 {pSet[seq(i+i, n, by=i)] = FALSE}
# 을 활용하여 그 숫자의 배수를 모두 FALSE으로 바꾼다.

prime2 = function(n){
    print("Starting [Sieve of Eratosthenes]")
    
    isPrime = rep(TRUE,n)      # 초기화, 1부터 n까지의 모든 수를 소수라고 가정함
    isPrime[1] = FALSE         # 1은 소수가 아니므로
    
    # 2부터 n까지의 수 중에서 sqrt(n)까지만 확인하면 됨.
    
    for (i in 2:floor(sqrt(n))){
        if (isPrime[i]) isPrime[seq(from=2*i, to=n, by=i)] = F
        }

    # 소수인 인덱스들만 모아서 벡터를 구성.
    x = which(isPrime)
  
    cat("\n소수의 갯수는 ", length(x),"\n")
}

prime2(10000000)
## [1] "Starting [Sieve of Eratosthenes]"
## 
## 소수의 갯수는  664579
# prime2와 알고리즘은 같고, running time을 기록함.

prime3 <- function(n) {
  start_time <- Sys.time()
  sieve <- rep(TRUE, n)
  sieve[1] <- FALSE
  
  for (i in 2:ceiling(sqrt(n))) {
    if (sieve[i]) {
      sieve[seq(i+i, n, i)] <- FALSE
    }
  }
  
  primes <- which(sieve)
  end_time <- Sys.time()
  cat("Execution Time: ", end_time - start_time, "seconds\n")
  cat("Number of primes: ", length(primes), "\n")
}

prime3(100000000)
## Execution Time:  8.172507 seconds
## Number of primes:  5761455