(7주차) 10월26일
볼링공문제, 벡터만 사용한 풀이, 매트릭스를 이용한 풀이, 데이터프레임을 활용한 풀이
-
(1/5) 볼링공 문제풀이 (1)
-
(2/5) 볼링공 문제풀이 (2)
-
(3/5) 볼링공 문제풀이 (3)
-
(4/5) 볼링공 문제풀이 (4)
-
(5/5) 과제설명
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)$
a=c(1,3,2,3,2)
a
count=0
for (i in 1:5){
for (j in 1:5){
if(a[i]!=a[j]) count=count+1
}
}
count
- 중복이 계산이 되어서 16이라는 값이 나왔다. (원래는 8이 나와야 한다.)
-
아래와 같이 수정하면 된다.
count=0
for (i in 1:5){
for (j in 1:5){
if ((a[i]!=a[j]) & (j>i)) count=count+1
}
}
count
-
((a[i]!=a[j]) & (j>i)) 에서 (j>i) 는 for문 선언부에서 처리할 수 있다.
count=0
for (i in 1:5){
for (j in i:5){
if (a[i]!=a[j]) count=count+1
}
}
count
a=c(1,3,2,3,2)
A=rep(0,25*2)
dim(A)=c(25,2)
A
k=1
for (i in 1:5){
for (j in 1:5){
A[k,]<- c(a[i],a[j])
k=k+1
}
}
A
-
(1) 무게가 같은 것을 뽑지 않고 (2) 중복되는 경우를 제외
- 중복되는 경우를 제외한다는 말은 1번공-2번공 뽑는 경우와 2번공-1번공을 뽑는경우중 하나만 고려한다는 것을 의미
vec1<-c()
vec2<-c()
for(i in 1:25){
vec1[i] <- A[i,1] != A[i,2]
vec2[i] <- A[i,1] > A[i,2]
}
vec1
vec2
sum(vec1 & vec2)
-
vec1, vec2를 굳이 for문으로 구할필요가 없을것 같다.
a=c(1,3,2,3,2)
A=rep(0,25*2)
dim(A)=c(25,2)
k=1
for (i in 1:5){
for (j in 1:5){
A[k,]<- c(a[i],a[j])
k=k+1
}
}
A
vec1<- A[,1]!=A[,2]
vec2<- A[,1]>A[,2]
sum(vec1&vec2)
-
생각해보니까 단순히 첫번째 열이 두번쨰 열보다 큰지만 체크해도 된다.
a=c(1,3,2,3,2)
A=rep(0,25*2)
dim(A)=c(25,2)
k=1
for (i in 1:5){
for (j in 1:5){
A[k,]<- c(a[i],a[j])
k=k+1
}
}
sum(A[,1]>A[,2])
-
풀이1-2: 매트릭스를 사용하지 않음.
-
풀이3-5: 매트릭스를 사용함.
-
현재까지는 풀이2가 가장 간결하고 루프도 적게돌아간다. 하지만 가장 중요한 일은 틀리지 않는 것인데 풀이2는 틀리기 쉬움
-
하지만 풀이2와 같은 접근법은 디버깅이 어렵다. $\to$ 예외사항을 처리하기 어려움.
-
특히 삼성에서 실시하는 코딩테스트 문제의 경우 예외사항을 잘 처리해야 하는 문제가 주로 출제된다고 한다.
-
사실 A를 구해주는 함수가 R에 존재함.
a=c(1,3,2,3,2)
A=expand.grid(a,a)
A
- expand.grid(): 벡터를 입렵으로 받아서 그 벡터의 원소가 만들어내는 순서쌍 조합을 데이터프레임 형태로 리턴함
- 데이터프레임
library(tidyverse)
A %>% mutate(C= Var1> Var2)
- mutate(): 데이터프레임에서 새로운 column을 추가하는 기능 (기존의 컬럼을 활용하여 새로운 파생되는 칼럼을 쉽게 만들 수 있다)
A %>% mutate(C= Var1> Var2) %>% filter(C == TRUE)
- filter(): 데이터프레임에서 특정조건을 만족하는 행을 필터링 하는 기능
A %>% mutate(C= Var1> Var2) %>% filter(C == TRUE) %>% count
- count(): 데이터프레임의 행의 숫자를 세어주는 기능
-
결과가 데이터프레임으로 나옴 $\to$ 숫자가 하나인데 굳이 데이터프레임이 자료형일 이유는 없음 (다루기 불편)
A %>% mutate(C= Var1> Var2) %>% filter(C == TRUE) %>% count -> rslt
rslt+20
1:8
1:rslt
-
숫자로 만들기 위해서 as.numeric() 함수를 사용하면 된다.
as.numeric(rslt)
A %>% mutate(C= Var1> Var2) %>% filter(C == TRUE) %>% count %>% as.numeric
A %>% mutate(C= Var1 -Var2)