강의영상

- (1/6) 볼링공 문제풀이 (1)

- (2/6) 볼링공 문제풀이 (2)

- (3/6) 자료형

- (4/6) 형변환

- (5/6) 벡터, 매트릭스(1)

- (6/6) 매트릭스 (2)

볼링공문제 (2019 SW마에스트로 입학 테스트)

A,B 두 사람이 볼링을 치고 있습니다. 두 사람은 서로 무게가 다른 볼링공을 고르려고 합니다. 볼링공은 총 N개가 있으며 각 볼링공마다 무게가 적혀 있고, 공의 번호는 1번부터 순서대로 부여됩니다. 또한 같은 무게의 공이 여러개 있을 수 있지만, 서로 다른 공으로 간주합니다. 볼링공의 무게는 1부터 M까지의 자연수 형태로 존재합니다.

예를들어 N이 5이고, M이 3이며 각각의 무게가 차례대로 1,3,2,3,2일 때 각 공의 번호가 차례대로 1번부터 5번까지 부여됩니다. 이때 두 사람이 고를 수 있는 볼링공 번호의 조합을 구하면 다음과 같습니다.

(1번,2번), (1번,3번), (1번,4번), (1번,5번), (2번,3번), (2번,5번), (3번,4번), (4번,5번)

결과적으로 두 사람이 공을 고르는 경우의 수는 8가지입니다. N개의 공의 무게가 각각 주어질 때, 두 사람이 볼링공을 고르는 경우의 수를 구하는 프로그램을 작성하세요.

  • 입력예시
입력
5 3 
1 3 2 3 2 
출력
8

문제의 수학적표현

$N$개의 볼링공의 무게를 각각 $x_1,\dots,x_N$ 이라고 하자. (단, $x_1,\dots, x_N$은 $\{1,\dots, M\}$사의 자연수의 값을 가지며 서로 같은 값을 가질 수 있다)

예시 $(a_1,\dots, a_5)=(1,3,2,3,2)$ 일 경우 가능한 조합의 집합은 아래와 같다. $(a_1,a_2), (a_1,a_3), (a_1,a_4), (a_1,a_5), (a_2,a_3), (a_2,a_5), (a_3,a_4), (a_4,a_5)$

풀이7

a<-c(1,3,2,3,2)
a1<-a
a2<-a
dim(a1)<-c(5,1) 
dim(a2)<-c(1,5)
a1
     [,1]
[1,] 1   
[2,] 3   
[3,] 2   
[4,] 3   
[5,] 2   
a2
     [,1] [,2] [,3] [,4] [,5]
[1,] 1    3    2    3    2   
a1 %*% a2
     [,1] [,2] [,3] [,4] [,5]
[1,] 1    3    2    3    2   
[2,] 3    9    6    9    6   
[3,] 2    6    4    6    4   
[4,] 3    9    6    9    6   
[5,] 2    6    4    6    4   
  • %*% 연산자: 매트릭스의 곱셈을 가능하게 해준다. (중요함)
A = a1 %*% a2
A
     [,1] [,2] [,3] [,4] [,5]
[1,] 1    3    2    3    2   
[2,] 3    9    6    9    6   
[3,] 2    6    4    6    4   
[4,] 3    9    6    9    6   
[5,] 2    6    4    6    4   
upper.tri(A)
     [,1]  [,2]  [,3]  [,4]  [,5] 
[1,] FALSE  TRUE  TRUE  TRUE  TRUE
[2,] FALSE FALSE  TRUE  TRUE  TRUE
[3,] FALSE FALSE FALSE  TRUE  TRUE
[4,] FALSE FALSE FALSE FALSE  TRUE
[5,] FALSE FALSE FALSE FALSE FALSE
  • upper.tri(): 그렇게 중요하진 않음
A[upper.tri(A)]
 [1] 3 2 6 3 9 6 2 6 4 6
  • 매트릭스 인덱싱: 중요함
A[upper.tri(A)] %in% c(4,9)
 [1] FALSE FALSE FALSE FALSE  TRUE FALSE FALSE FALSE  TRUE FALSE
  • %in%연산자: 중요함
sum(!(A[upper.tri(A)] %in% c(4,9)))
[1] 8

--

보총학습 %in% 연산자

a_ = c(1,2,3,4,4,4,5,6,7,8,9,9,9)
a_ %in% c(4,5,9) # _a의 모든원소를 조사하여, 그 원소가 4 혹은 9 이면 True, 아니면 False
 [1] FALSE FALSE FALSE  TRUE  TRUE  TRUE  TRUE FALSE FALSE FALSE  TRUE  TRUE
[13]  TRUE

풀이8

a<-c(1,3,2,3,2)
A=outer(a,a)
A
     [,1] [,2] [,3] [,4] [,5]
[1,] 1    3    2    3    2   
[2,] 3    9    6    9    6   
[3,] 2    6    4    6    4   
[4,] 3    9    6    9    6   
[5,] 2    6    4    6    4   
sum(!(A[upper.tri(A)] %in% c(4,9) ))
[1] 8
sum(!(outer(a,a)[upper.tri(outer(a,a))] %in% a**2 ))
[1] 32

풀이 6,7,8

- 풀이6: 데이터프레임 활용 $\to$ 사용하기 쉽고 확장성이 좋음

- 풀이7,8: 코드가 간결함 / 에러가 발생할 수 있음

데이터형

- R에서 데이터를 구성하는 세가지 기본형

- 수치형(numeric): 정수, 실수, 지수등을 나타내며 실수가 기본형

a=345
mode(a)
[1] "numeric"
a=34.4455
mode(a)
[1] "numeric"

- 논리형(logical): 논리적 참과 거짓을 나타낸다.

a=T
mode(a)
[1] "logical"
a=TRUE
mode(a)
[1] "logical"
a=F
mode(a)
[1] "logical"
a=FALSE
mode(a)
[1] "logical"

- 문자형

a='asdf'
mode(a)
[1] "character"
a='TRUE'
mode(a)
[1] "character"
a='1'
mode(a)
[1] "character"

- 참고: storgae.mode()

a=pi
a
[1] 3.141593
mode(a)
[1] "numeric"
storage.mode(a)
[1] "double"
a=1:2
a
[1] 1 2
storage.mode(a)
[1] "integer"

형 변환

방법1

a="331"
mode(a)
[1] "character"

- 이것을 수치형으로 바꾸고 싶다.

mode(a)
[1] "character"

결과가 "character"이 아니라 "numeric"으로 나오면 좋겠다.

mode(a)<-"numeric"
mode(a)
[1] "numeric"
a
[1] 331

방법2

a="331"
mode(a)
[1] "character"
a
[1] 331
as.numeric(a)
[1] 331
a=as.numeric(a)
a
[1] 331

예제1: logical -> numeric

a=F
as.numeric(a)
[1] 0

예제2: numeric -> logical

a=1
as.logical(a)
[1] TRUE
a=0
as.logical(a)
[1] FALSE

- 그런데 0,1 이외의 숫자를 바꾸면 어떻게 되는가?

a= -1
as.logical(a)
[1] TRUE
a= 2
as.logical(a)
[1] TRUE
a= 2.222
as.logical(a)
[1] TRUE

예제3

a='asdfasdfasdf'
a=as.numeric(a)
Warning message in eval(expr, envir, enclos):
“NAs introduced by coercion”
mode(a)
[1] "numeric"
a='asdfasdfasdf'
a=as.logical(a)
mode(a)
[1] "logical"

mode가 서로 다른 원소로 이루어진 벡터가 있다면, 이 벡터의 mode는 무엇일까?

- 예시1

a<-c(1,T,'1')
a
[1] "1"    "TRUE" "1"   
mode(a)
[1] "character"

- 예시2

a<-c(1,T)
a
[1] 1 1
mode(a)
[1] "numeric"

- 결국 mode가 서로 다른 원소로 이루어진 벡터는 없다.

- 서로 다른 기본형을 가지는 원소로 벡터를 만들게 된다면 한가지 형으로 자동 형 변환이 된다.

행렬

- 행렬도 벡터와 같이 동일한 형의 원소로 구성된다.

- 행렬의 속성

A=cbind(c(1,2,3,4),c(4,5,6,7),c(2,3,4,1))
A
     [,1] [,2] [,3]
[1,] 1    4    2   
[2,] 2    5    3   
[3,] 3    6    4   
[4,] 4    7    1   
length(A)
[1] 12
mode(A)
[1] "numeric"
dim(A)
[1] 4 3
dimnames(A)
NULL

- 지금은 이름이 없지만 아래와 같이 이름이 있는 경우도 있다.

x=c(1,2,3,4)
y=c(2,2,3,4)
z=c(3,2,3,4)
A=cbind(x,y,z)
A
     x y z
[1,] 1 2 3
[2,] 2 2 2
[3,] 3 3 3
[4,] 4 4 4
a=T
mode(a)<-"character"
dimnames(A)
[[1]]
NULL

[[2]]
[1] "x" "y" "z"
A=rbind(x,y,z)
A
  [,1] [,2] [,3] [,4]
x 1    2    3    4   
y 2    2    3    4   
z 3    2    3    4   
dimnames(A)
[[1]]
[1] "x" "y" "z"

[[2]]
NULL

매트릭스를 만드는 방법1: matrix 함수를 이용하는 방법

- 예제1

matrix(1:12,ncol=2)
     [,1] [,2]
[1,] 1     7  
[2,] 2     8  
[3,] 3     9  
[4,] 4    10  
[5,] 5    11  
[6,] 6    12  

- 예제2

matrix(1:12,ncol=3)
     [,1] [,2] [,3]
[1,] 1    5     9  
[2,] 2    6    10  
[3,] 3    7    11  
[4,] 4    8    12  

- 예제3

matrix(1:12,nrow=1)
     [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10] [,11] [,12]
[1,] 1    2    3    4    5    6    7    8    9    10    11    12   

- 예제4

matrix(1:12,nrow=2)
     [,1] [,2] [,3] [,4] [,5] [,6]
[1,] 1    3    5    7     9   11  
[2,] 2    4    6    8    10   12  

- 예제5

matrix(1:12,ncol=2,byrow=T)
     [,1] [,2]
[1,]  1    2  
[2,]  3    4  
[3,]  5    6  
[4,]  7    8  
[5,]  9   10  
[6,] 11   12  

- 예제6

matrix(1:12)
      [,1]
 [1,]  1  
 [2,]  2  
 [3,]  3  
 [4,]  4  
 [5,]  5  
 [6,]  6  
 [7,]  7  
 [8,]  8  
 [9,]  9  
[10,] 10  
[11,] 11  
[12,] 12  

매트릭스를 만드는 방법2: rbind 함수를 이용하는 방법

- 예제1

rbind(1:6,rep(c(1,2),3))
     [,1] [,2] [,3] [,4] [,5] [,6]
[1,] 1    2    3    4    5    6   
[2,] 1    2    1    2    1    2   

- 예제2

rbind(1:5,5:1,1:3)
Warning message in rbind(1:5, 5:1, 1:3):
“number of columns of result is not a multiple of vector length (arg 3)”
     [,1] [,2] [,3] [,4] [,5]
[1,] 1    2    3    4    5   
[2,] 5    4    3    2    1   
[3,] 1    2    3    1    2   

- 예제3

rbind(1:4,4:1,1:2)
     [,1] [,2] [,3] [,4]
[1,] 1    2    3    4   
[2,] 4    3    2    1   
[3,] 1    2    1    2   

- 예제4

rbind("row1"=1:4,"row2"=4:1,"row3"=1:2)
     [,1] [,2] [,3] [,4]
row1 1    2    3    4   
row2 4    3    2    1   
row3 1    2    1    2   

매트릭스를 만드는 방법3: cbind 함수를 이용하는 방법

- 예제1

cbind(1:5,5:1,1:3)
Warning message in cbind(1:5, 5:1, 1:3):
“number of rows of result is not a multiple of vector length (arg 3)”
     [,1] [,2] [,3]
[1,] 1    5    1   
[2,] 2    4    2   
[3,] 3    3    3   
[4,] 4    2    1   
[5,] 5    1    2   

- 예제2

cbind("col1"=1:6,"col2"=6:1,"col3"=1:3)
     col1 col2 col3
[1,] 1    6    1   
[2,] 2    5    2   
[3,] 3    4    3   
[4,] 4    3    1   
[5,] 5    2    2   
[6,] 6    1    3   

매트릭스를 만드는 방법4: dim 함수를 이용하는 방법

- 예시1

mat= 1:6
dim(mat)
NULL
dim(mat)<-c(2,3)
dim(mat)
[1] 2 3
mat
     [,1] [,2] [,3]
[1,] 1    3    5   
[2,] 2    4    6   

- 참고: 동일한 문법논리를 사용해서 이미 만들어진 매트릭스를 벡터로 바꾸는 것도 가능하다.

dim(mat)<- NULL
dim(mat)
NULL
mat
[1] 1 2 3 4 5 6

매트릭스를 만드는 방법5: array함수를 이용하는 방법

- 예시1

array(1:12,dim=c(6,2))
     [,1] [,2]
[1,] 1     7  
[2,] 2     8  
[3,] 3     9  
[4,] 4    10  
[5,] 5    11  
[6,] 6    12  

- 예시2

array(1:12,dim=c(3,4))
     [,1] [,2] [,3] [,4]
[1,] 1    4    7    10  
[2,] 2    5    8    11  
[3,] 3    6    9    12  

- 예시3

array(1:2,dim=c(3,4))
     [,1] [,2] [,3] [,4]
[1,] 1    2    1    2   
[2,] 2    1    2    1   
[3,] 1    2    1    2   

- 예시4 (이건 매트릭스가 아니다!)

array(1:2,dim=c(3,4,2))
, , 1

     [,1] [,2] [,3] [,4]
[1,]    1    2    1    2
[2,]    2    1    2    1
[3,]    1    2    1    2

, , 2

     [,1] [,2] [,3] [,4]
[1,]    1    2    1    2
[2,]    2    1    2    1
[3,]    1    2    1    2

- 예시5 (이건 매트릭스가 아니다!)

array(1:2,dim=6)
[1] 1 2 1 2 1 2

배열 (array)

- 배열은 동일한 형의 원소를 p개의 차원으로 구성한 데이터 객체이다.

- 행렬은 2차원배열의 일종이다. $p=2$

- 배열을 선언하는 예시

array(1:2,dim=c(3,4,2))
, , 1

     [,1] [,2] [,3] [,4]
[1,]    1    2    1    2
[2,]    2    1    2    1
[3,]    1    2    1    2

, , 2

     [,1] [,2] [,3] [,4]
[1,]    1    2    1    2
[2,]    2    1    2    1
[3,]    1    2    1    2

숙제

아래와 같은 메트릭스를 만들고

$A=\begin{bmatrix} 1 & 2 & 3 \\ 4 & 5 & 6 \\ 7 & 8& 9 \end{bmatrix}$

$B=\begin{bmatrix} -1 & -2 & -3 \\ -4 & -5 & -6 \\ -7 & -8 & -10 \end{bmatrix}$

$A+B$를 계산하라.

A=asdf
B=asdf 
A+B