1. R을 이용하여 다음을 계산하여라. (3점)

(a) $2^{-5}+2^{3}$

2**(-5) + 2**3
[1] 8.03125

(b) $\sqrt{33}$

sqrt(33)
[1] 5.744563

(c) $\sum_{k=1}^{100} \frac{1}{k^2+2k+1}=\sum_{k=1}^{100}(k+1)^{-2}$

for k in 100

(풀이)

- (c)만 풀겠습니다.

- 방법1: for문을 이용

ak <-c() 
for (k in 1:100) ak[k] <- 1/(k**2 + 2*k + 1) 
sum(ak)
[1] 0.6350819

- 방법2: 벡터의 연산을 이용한다.

k=1:100 
sum(1/(k**2 + 2*k + 1) )
[1] 0.6350819

- 수학을 좋아하는 사람?

k=1:100
sum((k+1)^(-2))
[1] 0.6350819

- 제 생각에는 방법2가 좋은것 같아요. (계산효율면에서 좋고 디버깅이 편해요)

1:100
  [1]   1   2   3   4   5   6   7   8   9  10  11  12  13  14  15  16  17  18
 [19]  19  20  21  22  23  24  25  26  27  28  29  30  31  32  33  34  35  36
 [37]  37  38  39  40  41  42  43  44  45  46  47  48  49  50  51  52  53  54
 [55]  55  56  57  58  59  60  61  62  63  64  65  66  67  68  69  70  71  72
 [73]  73  74  75  76  77  78  79  80  81  82  83  84  85  86  87  88  89  90
 [91]  91  92  93  94  95  96  97  98  99 100
(1:100)**2
  [1]     1     4     9    16    25    36    49    64    81   100   121   144
 [13]   169   196   225   256   289   324   361   400   441   484   529   576
 [25]   625   676   729   784   841   900   961  1024  1089  1156  1225  1296
 [37]  1369  1444  1521  1600  1681  1764  1849  1936  2025  2116  2209  2304
 [49]  2401  2500  2601  2704  2809  2916  3025  3136  3249  3364  3481  3600
 [61]  3721  3844  3969  4096  4225  4356  4489  4624  4761  4900  5041  5184
 [73]  5329  5476  5625  5776  5929  6084  6241  6400  6561  6724  6889  7056
 [85]  7225  7396  7569  7744  7921  8100  8281  8464  8649  8836  9025  9216
 [97]  9409  9604  9801 10000
(1:100)**2 + 2*(1:100)
  [1]     3     8    15    24    35    48    63    80    99   120   143   168
 [13]   195   224   255   288   323   360   399   440   483   528   575   624
 [25]   675   728   783   840   899   960  1023  1088  1155  1224  1295  1368
 [37]  1443  1520  1599  1680  1763  1848  1935  2024  2115  2208  2303  2400
 [49]  2499  2600  2703  2808  2915  3024  3135  3248  3363  3480  3599  3720
 [61]  3843  3968  4095  4224  4355  4488  4623  4760  4899  5040  5183  5328
 [73]  5475  5624  5775  5928  6083  6240  6399  6560  6723  6888  7055  7224
 [85]  7395  7568  7743  7920  8099  8280  8463  8648  8835  9024  9215  9408
 [97]  9603  9800  9999 10200
(1:100)**2 + 2*(1:100) +1
  [1]     4     9    16    25    36    49    64    81   100   121   144   169
 [13]   196   225   256   289   324   361   400   441   484   529   576   625
 [25]   676   729   784   841   900   961  1024  1089  1156  1225  1296  1369
 [37]  1444  1521  1600  1681  1764  1849  1936  2025  2116  2209  2304  2401
 [49]  2500  2601  2704  2809  2916  3025  3136  3249  3364  3481  3600  3721
 [61]  3844  3969  4096  4225  4356  4489  4624  4761  4900  5041  5184  5329
 [73]  5476  5625  5776  5929  6084  6241  6400  6561  6724  6889  7056  7225
 [85]  7396  7569  7744  7921  8100  8281  8464  8649  8836  9025  9216  9409
 [97]  9604  9801 10000 10201
1 / ((1:100)**2 + 2*(1:100) +1)
  [1] 0.2500000000 0.1111111111 0.0625000000 0.0400000000 0.0277777778
  [6] 0.0204081633 0.0156250000 0.0123456790 0.0100000000 0.0082644628
 [11] 0.0069444444 0.0059171598 0.0051020408 0.0044444444 0.0039062500
 [16] 0.0034602076 0.0030864198 0.0027700831 0.0025000000 0.0022675737
 [21] 0.0020661157 0.0018903592 0.0017361111 0.0016000000 0.0014792899
 [26] 0.0013717421 0.0012755102 0.0011890606 0.0011111111 0.0010405827
 [31] 0.0009765625 0.0009182736 0.0008650519 0.0008163265 0.0007716049
 [36] 0.0007304602 0.0006925208 0.0006574622 0.0006250000 0.0005948840
 [41] 0.0005668934 0.0005408329 0.0005165289 0.0004938272 0.0004725898
 [46] 0.0004526935 0.0004340278 0.0004164931 0.0004000000 0.0003844675
 [51] 0.0003698225 0.0003559986 0.0003429355 0.0003305785 0.0003188776
 [56] 0.0003077870 0.0002972652 0.0002872738 0.0002777778 0.0002687450
 [61] 0.0002601457 0.0002519526 0.0002441406 0.0002366864 0.0002295684
 [66] 0.0002227668 0.0002162630 0.0002100399 0.0002040816 0.0001983733
 [71] 0.0001929012 0.0001876525 0.0001826150 0.0001777778 0.0001731302
 [76] 0.0001686625 0.0001643655 0.0001602307 0.0001562500 0.0001524158
 [81] 0.0001487210 0.0001451589 0.0001417234 0.0001384083 0.0001352082
 [86] 0.0001321178 0.0001291322 0.0001262467 0.0001234568 0.0001207584
 [91] 0.0001181474 0.0001156203 0.0001131734 0.0001108033 0.0001085069
 [96] 0.0001062812 0.0001041233 0.0001020304 0.0001000000 0.0000980296
sum(1 / ((1:100)**2 + 2*(1:100) +1))
[1] 0.6350819

2. 다음을 잘 읽고 물음에 답하라. (2점)

(a) 아래와 같은 수열을 생성하라.

$$x=(-10,-9.5,-9.0,...,9.0,9.5,10)$$

(b) 생성된 수열에 대하여 아래를 만족하는 $y$를 계산하라.

$$y=\begin{cases} x & |x|>5 \\ 0 & |x| \leq 2 \\ 5 & o.w. \end{cases}$$

(풀이)

- 그냥 예제문제

seq(-10,10,0.5)
 [1] -10.0  -9.5  -9.0  -8.5  -8.0  -7.5  -7.0  -6.5  -6.0  -5.5  -5.0  -4.5
[13]  -4.0  -3.5  -3.0  -2.5  -2.0  -1.5  -1.0  -0.5   0.0   0.5   1.0   1.5
[25]   2.0   2.5   3.0   3.5   4.0   4.5   5.0   5.5   6.0   6.5   7.0   7.5
[37]   8.0   8.5   9.0   9.5  10.0
x=seq(-10,10,0.5)
ifelse(abs(x)>5,x, ifelse(abs(x)<=2,0,5))
 [1] -10.0  -9.5  -9.0  -8.5  -8.0  -7.5  -7.0  -6.5  -6.0  -5.5   5.0   5.0
[13]   5.0   5.0   5.0   5.0   0.0   0.0   0.0   0.0   0.0   0.0   0.0   0.0
[25]   0.0   5.0   5.0   5.0   5.0   5.0   5.0   5.5   6.0   6.5   7.0   7.5
[37]   8.0   8.5   9.0   9.5  10.0

- 검산

cbind(x,ifelse(abs(x)>5,x, ifelse(abs(x)<=2,0,5)))
      x          
 [1,] -10.0 -10.0
 [2,]  -9.5  -9.5
 [3,]  -9.0  -9.0
 [4,]  -8.5  -8.5
 [5,]  -8.0  -8.0
 [6,]  -7.5  -7.5
 [7,]  -7.0  -7.0
 [8,]  -6.5  -6.5
 [9,]  -6.0  -6.0
[10,]  -5.5  -5.5
[11,]  -5.0   5.0
[12,]  -4.5   5.0
[13,]  -4.0   5.0
[14,]  -3.5   5.0
[15,]  -3.0   5.0
[16,]  -2.5   5.0
[17,]  -2.0   0.0
[18,]  -1.5   0.0
[19,]  -1.0   0.0
[20,]  -0.5   0.0
[21,]   0.0   0.0
[22,]   0.5   0.0
[23,]   1.0   0.0
[24,]   1.5   0.0
[25,]   2.0   0.0
[26,]   2.5   5.0
[27,]   3.0   5.0
[28,]   3.5   5.0
[29,]   4.0   5.0
[30,]   4.5   5.0
[31,]   5.0   5.0
[32,]   5.5   5.5
[33,]   6.0   6.0
[34,]   6.5   6.5
[35,]   7.0   7.0
[36,]   7.5   7.5
[37,]   8.0   8.0
[38,]   8.5   8.5
[39,]   9.0   9.0
[40,]   9.5   9.5
[41,]  10.0  10.0

3. $x=(-10,-9,-8,\dots,8,9,10)$의 각 원소에 대하여 $h(g(f(x)))$의 계산결과를 구하는 코드를 작성하라. (10점)

단, $f(x)$,$g(x)$, $h(x)$의 정의는 각각 아래와 같다.

  • $f(x)=2x+3 $
  • $g(x)=\frac{e^x}{1+e^x}$
  • $h(x)=max(x,0)$

(풀이)

- 문제 의도가 좀 왜곡되었어요.. $x=(-10,-9,-8, \dots, 8,9,10)$의 각 원소에 대하여! 로 바꿔야합니다.

library(tidyverse)
f = function(x) 2*x +3 
g = function(x) exp(x) / (1+exp(x)) 
h = function(x) max(x,0) 
-10:10 %>% f %>% g %>% h
[1] 1

- 원래 의도는 이거였습니다.

f = function(x) 2*x +3 
g = function(x) exp(x) / (1+exp(x)) 
h = function(x) ifelse(y>0,y,0)  
-10:10 %>% f %>% g %>% h
 [1] 4.139938e-08 3.059022e-07 2.260324e-06 1.670142e-05 1.233946e-04
 [6] 9.110512e-04 6.692851e-03 4.742587e-02 2.689414e-01 7.310586e-01
[11] 9.525741e-01 9.933071e-01 9.990889e-01 9.998766e-01 9.999833e-01
[16] 9.999977e-01 9.999997e-01 1.000000e+00 1.000000e+00 1.000000e+00
[21] 1.000000e+00

4. 아래중 옳은것은? (O / X 로 답안지를 쓰고 답의 근거가 되는 코드를 작성할것) (10점)

(a) $1= \frac{1}{2}+\frac{1}{4} +\frac{1}{8} \dots $

(b) $e^x= 1+x+x^2+x^3+\dots $

(풀이)

sum=0 
for (i in 1:10){
    sum=sum+(1/2)**i 
    print(sum)
}
[1] 0.5
[1] 0.75
[1] 0.875
[1] 0.9375
[1] 0.96875
[1] 0.984375
[1] 0.9921875
[1] 0.9960938
[1] 0.9980469
[1] 0.9990234
  • 1에 점점 가까워짐

5. 다음을 읽고 물음에 답하라. (10점)

다음은 어느 회사의 연봉에 대한 규정이다.

(가) 입사 첫째 해 연봉은 $a$원이고, 입사 19년째 해까지의 연봉은 해마다 직전 연봉에서 8%씩 인상된다.

(나) 입사 20년째 해부터의 연봉은 입사 19년째 해 연봉의 75%로 한다.

이 회사에 입사한 사람이 28년동안 근무하여 받는 연봉의 총합은?

6. 다음 문장을 읽고 참거짓을 판단하시오. (10점)

(a) _a는 변수이름으로 가능하다.

(b) 벡터의 원소는 수치형(numeric)만 가능하다.

(c) 논리형(logical)변수는 수치형 변수로 변환할 수 없다.

(d) R에서 {}는 ()로 바꿀 수 있다.

7. 100개의 라커 (15점)

복도에 100개의 라커가 있다. 복도를 어떤 남자가 100개의 라커 문을 전부 연다. 그리고 나서 짝수 번호의 라커를 전부 닫는다. 그 다음에는 번호가 3의 배수인 라커를 순서대로 찾아다니며 열려 있으면 닫고, 닫혀 있으면 연다. 그 다음에는 번호가 4의 배수인 라커를 순서대로 찾아다니며 열려있으면 닫고, 닫혀있으면 연다. 이후에 5의 배수, 6의 배수 .. 인 라커를 순서대로 찾아다니며 행동을 반복한다. 이런식으로 복도를 100번 지나가면 열린 라커의 문은 몇개가 되겠는가?

(풀이1)

- 문을 모두 닫은 상태로 둔다.

x= rep(FALSE, 100)
x
  [1] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
 [13] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
 [25] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
 [37] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
 [49] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
 [61] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
 [73] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
 [85] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
 [97] FALSE FALSE FALSE FALSE

- 문을 여는 함수를 만든다. (닫혀있으면 열고, 열려있으면 닫는함수)

f<- function(x) !x
  • 10월7일강의 논리연산자 예제1
x %>% f
  [1] TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE
 [16] TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE
 [31] TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE
 [46] TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE
 [61] TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE
 [76] TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE
 [91] TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE
  • 문이 잘 열린다.

- 2,3,4,5 ... 의 배수를 찾아서 문을 열자.

  • Step1: 2,3,4,5의 배수에 해당하는 원소를 뽑는 코드를 작성한다.
  • Step2: Step1에서 나온 원소에 한정하여 문을 열거나 닫는다.

- 2의 배수 구현예시

(1:100) %% 2 == 0
  [1] FALSE  TRUE FALSE  TRUE FALSE  TRUE FALSE  TRUE FALSE  TRUE FALSE  TRUE
 [13] FALSE  TRUE FALSE  TRUE FALSE  TRUE FALSE  TRUE FALSE  TRUE FALSE  TRUE
 [25] FALSE  TRUE FALSE  TRUE FALSE  TRUE FALSE  TRUE FALSE  TRUE FALSE  TRUE
 [37] FALSE  TRUE FALSE  TRUE FALSE  TRUE FALSE  TRUE FALSE  TRUE FALSE  TRUE
 [49] FALSE  TRUE FALSE  TRUE FALSE  TRUE FALSE  TRUE FALSE  TRUE FALSE  TRUE
 [61] FALSE  TRUE FALSE  TRUE FALSE  TRUE FALSE  TRUE FALSE  TRUE FALSE  TRUE
 [73] FALSE  TRUE FALSE  TRUE FALSE  TRUE FALSE  TRUE FALSE  TRUE FALSE  TRUE
 [85] FALSE  TRUE FALSE  TRUE FALSE  TRUE FALSE  TRUE FALSE  TRUE FALSE  TRUE
 [97] FALSE  TRUE FALSE  TRUE
  • 짝이면 TRUE, 홀이면 FALSE 인 벡터
x[(1:100) %% 2 == 0 ]
 [1] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
[13] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
[25] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
[37] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
[49] FALSE FALSE
  • 1~100까지의 라커중 짝수에 해당하는 라커만 추출
x[(1:100) %% 2 == 0 ] %>% f
 [1] TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE
[16] TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE
[31] TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE
[46] TRUE TRUE TRUE TRUE TRUE
  • 1~100까지의 라커중 짝수에 해당하는 라커만 추출 $\to$ 그 라커들은 문을 열었음
x[(1:100) %% 2 == 0 ] <- x[(1:100) %% 2 == 0 ] %>% f 
x
  [1] FALSE  TRUE FALSE  TRUE FALSE  TRUE FALSE  TRUE FALSE  TRUE FALSE  TRUE
 [13] FALSE  TRUE FALSE  TRUE FALSE  TRUE FALSE  TRUE FALSE  TRUE FALSE  TRUE
 [25] FALSE  TRUE FALSE  TRUE FALSE  TRUE FALSE  TRUE FALSE  TRUE FALSE  TRUE
 [37] FALSE  TRUE FALSE  TRUE FALSE  TRUE FALSE  TRUE FALSE  TRUE FALSE  TRUE
 [49] FALSE  TRUE FALSE  TRUE FALSE  TRUE FALSE  TRUE FALSE  TRUE FALSE  TRUE
 [61] FALSE  TRUE FALSE  TRUE FALSE  TRUE FALSE  TRUE FALSE  TRUE FALSE  TRUE
 [73] FALSE  TRUE FALSE  TRUE FALSE  TRUE FALSE  TRUE FALSE  TRUE FALSE  TRUE
 [85] FALSE  TRUE FALSE  TRUE FALSE  TRUE FALSE  TRUE FALSE  TRUE FALSE  TRUE
 [97] FALSE  TRUE FALSE  TRUE
  • 결과를 저장

- 3의 배수 구현예시

x[(1:100) %% 3 == 0 ] <- x[(1:100) %% 3 == 0 ] %>% f

- 4의 배수.. 5의 배수.. $\to$ 함수를 만들자.

g=function(x,a){
    n=length(x) 
    x[(1:n) %% a == 0 ] <- x[(1:n) %% a == 0 ] %>% f ## 연산 
    x ## 결과를 리턴
}

- 검산을 해보자. (검산을 쉽게하기 위해서 10개정도의 라커만 고려하자.)

x=rep(FALSE, 10) 
x
 [1] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
x %>% f
 [1] TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE
x %>% f %>% g(2)
 [1]  TRUE FALSE  TRUE FALSE  TRUE FALSE  TRUE FALSE  TRUE FALSE
x %>% f %>% g(2) %>% g(3)
 [1]  TRUE FALSE FALSE FALSE  TRUE  TRUE  TRUE FALSE FALSE FALSE

- 잘 되는것 같습니다. 이제 일반화해서 답을 구해보면

x=rep(FALSE, 100) # x를 선언, FALSE의 의미는 문이 닫혀있다. 
x=f(x) # 1회 복도를 지나가면서 모든 문을 열어요 
for (i in 2:100){ # 2회부터 100회까지 지나가면서 
    x=g(x,i) # (1) 2,3,4,5 ... , 100의 배수에 해당하는 문을 선택 (2) 문이 열려있으면 닫고, 닫혀있으면 열어요 
}

- 결과는 아래와 같다.

x
  [1]  TRUE FALSE FALSE  TRUE FALSE FALSE FALSE FALSE  TRUE FALSE FALSE FALSE
 [13] FALSE FALSE FALSE  TRUE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
 [25]  TRUE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE  TRUE
 [37] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
 [49]  TRUE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
 [61] FALSE FALSE FALSE  TRUE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
 [73] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE  TRUE FALSE FALSE FALSE
 [85] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
 [97] FALSE FALSE FALSE  TRUE
sum(x)
[1] 10

(풀이2)

x=rep(TRUE,100) 
for (i in 2:100) x[(1:100) %% i ==0] = !( x[(1:100) %% i ==0] ) 
sum(x)
[1] 10
  • 시험제출용 코드입니다. 공부용은 아니에요
  • 차근차근 디버깅을 하고 코드를 확인해가면서 혹시 모를 실수를 방지할 수 있는 풀이 1이 좋아요.
  • 코드 중간결과를 시각화해서 내가 잘 구현하고 있는지 끊임없이 확인해야 합니다.
  • 그 다음에 코드를 효율적으로 정리합니다.

8. 무궁화 꽃이 피었습니다. (25점)

총 456명의 참가자가 '무궁화 꽃이 피었습니다' 게임에 참가한다. 기본적인 게임의 규칙은 아래와 같다.

  • 술래는 총 10회간 벽을 보고 '무궁화 꽃이 피었습니다' 를 외친다.

  • 참가자는 술래가 있는 곳 까지 이동해야 살 수 있다.

  • 술래는 벽을 보고 '무궁화 꽃이 피었습니다'를 외치다가 구호가 끝남과 동시에 뒤를 돌아본다. 이때 움직이는 사람은 죽는다

따라서 참가자는 술래가 벽을 보고 '무궁화 꽃이 피었습니다'를 외치는 동안만 이동할 수 있다. 욕심을 부려 더 이동하고자 하면 죽을 수 있다. 반대로 죽는 것을 지나치게 두려워한 나머지 매턴마다 조금씩만 이동한다면 10회의 제한횟수 내에 술래에게 도달하지 못하여 죽는다.

게임환경과 관련된 세부적인 설정은 아래와 같다.

  • 술래와 참가자의 거리는 35이다.

  • 술래는 처음 벽을 보고 $x$초간 무궁화 꽃이 피었습니다를 외친다.

  • 모든 참가자는 1초에 거리1이상 움직일 수 없다고 가정한다. (예를들어 2.4초 동안은 최대 2.4의 거리를 이동할 수 있다. 반면 이동을 원치않으면 0의 거리만큼 움직이므로 0~2.4사이의 거리를 움직일 수 있다)

술래와 참가자에 대한 설정값은 아래와 같다.

술래에 대한 설정값

  • 처음에는 술래가 10초간 무궁화 꽃이 피었습니다를 외친다.

  • 그 다음에는 술래가 9.5초간 무궁화 꽃이 피었습니다를 외친다.

  • 그 다음에도 0.5초씩 구호를 외치는 시간을 줄인다. 이것을 10회 반복한다.

참가자에 대한 설정값

  • 처음에는 참가자가 "본인의번호/100"을 계산하여 나온 숫자만큼 움직인다. 즉 10번 참가자는 0.1의 거리를 움직이고 456번 참가자는 4.56의 거리를 움직인다.

  • 그 다음은 처음에 본인이 이동했던 거리에 1씩 더하여 움직인다. 즉 10번 참가자는 1.1의 거리를 움직이고 456번 참가자는 5.56의 거리를 움직인다.

- 예시1

300번 참가자의 경우 아래와 같이 이동하므로

1회 2회 3회 4회 5회 6회
술래의 외침시간 10 9.5 9.0 8.5 8.0 7.5
참가자의 이동폭 3 4 5 6 7 7.5
참가자의 총 이동거리 3 7 12 18 25 32.5

생존할 수 없다. (6회에서 32.5까지 이동후 사망)

- 예시2

350번 참가자의 경우 아래와 같이 이동하므로

1회 2회 3회 4회 5회 6회
술래의 외침시간 10 9.5 9.0 8.5 8.0 7.5
참가자의 이동폭 3.5 4.5 5.5 6.5 7.5 7.5
참가자의 총 이동거리 3.5 8 13.5 20 27.5 35

생존 할 수 있다. (6회에서 정확하게 7.5초간 이동하고 살아남는다)

- 예시3

400번 참가자의 경우 아래와 같이 이동하므로

1회 2회 3회 4회 5회 6회
술래의 외침시간 10 9.5 9.0 8.5 8.0 7.5
참가자의 이동폭 4 5 6 7 8 5
참가자의 총 이동거리 4 9 15 22 30 35

생존 할 수 있다. (6회에서 5초간만 이동하면 35만큼 이동하므로 살아남는다)

(a) 1번, 67번, 218번, 456번 참가자의 생존여부를 확인하는 함수를 작성하라.

b <- 1/100
c <- 0
for(i in 1:10){
    a <- 10 - 0.5 * i
    c <- c + b
    if(c>=35|a<=b){
        print("탈락")
        break
    }
    b <- b + 1
        if(a<=b){
            b <- a
        if(c >= 35){
           b <- 35 - c
           }
                          }}
[1] "탈락"
1회 2회 3회 4회 5회 6회 7회 8회
술래의 외침시간 10 9.5 9.0 8.5 8.0 7.5 7 6.5
참가자의 이동폭 0.01 1.01 2.01 3.01 4.01 5.01 6.01 6.5
참가자의 총 이동거리 0.01 1.02 3.02 6.03 10.04 15.05 21.06 27.56
b <- 67/100
c <- 0
for(i in 1:10){
    a <- 10 - 0.5 * i
    c <- c + b
    if(c>=35|a<=b){
        print("탈락")
        break
    }
    b <- b + 1
        if(a<=b){
            b <- a
        if(c >= 35){
           b <- 35 - c
           }
                          }}
[1] "탈락"
1회 2회 3회 4회 5회 6회 7회 8회 9회
술래의 외침시간 10 9.5 9.0 8.5 8.0 7.5 7 6.5 6
참가자의 이동폭 0.67 1.67 2.67 3.67 4.67 5.67 6.67 6.5 2.81
참가자의 총 이동거리 0.67 2.34 5.01 8.68 13.35 19.02 25.69 32.19 35
b <- 218/100
c <- 0
for(i in 1:10){
    a <- 10 - 0.5 * i
    if(c<35){
        c <- c + b
        
    }
    if(c>=35|a<=b){
        print("탈락")
        break
    }
    b <- b + 1
        if(a<=b){
            b <- a
        if(c >= 35){
           b <- 35 - c
           }
                          }}
[1] "탈락"
1회 2회 3회 4회 5회 6회 7회
술래의 외침시간 10 9.5 9.0 8.5 8.0 7.5 7
참가자의 이동폭 2.18 3.18 4.18 5.18 6.18 7.18 6.92
참가자의 총 이동거리 2.18 5.36 9.54 14.72 20.90 28.08 35
b <- 456/100
c <- 0
for(i in 1:10){
    a <- 10 - 0.5 * i
    c <- c + b
    if(c>=35&a<=b){
        print("생존")
        break
    }
    b <- b + 1
        if(a<=b){
            b <- a
        if(c >= 35){
           b <- 35 - c
           }
                          }}
[1] "생존"
1회 2회 3회 4회 5회 6회
술래의 외침시간 10 9.5 9.0 8.5 8.0 7.5
참가자의 이동폭 4.56 5.56 6.56 7.56 8 2.76
참가자의 총 이동거리 4.56 10.12 16.68 24.24 32.24 35

(b) 전체 생존자중 몇명이 살아남는지 계산하라.

(풀이)

- 전략: 각 플레이어별로 죽느냐 사느냐를 판단하는 로직을 구현하고 for문을 돌리면 된다.

- 죽느냐 사느냐를 판단하는 방법: 살아있는 동안 이동한 총거리 >= 35

- 살아있는 동안 이동한 총거리를 계산하는 방법:

  • 죽을위험이 없는 횟수에서 이동한 총거리 + 죽을위험이 있는 횟수에서 술래의 외침시간 동안 이동한 거리

a = 10-0.5*(0:9)
a
 [1] 10.0  9.5  9.0  8.5  8.0  7.5  7.0  6.5  6.0  5.5
b = 400/100 + (0:9)
b
 [1]  4  5  6  7  8  9 10 11 12 13
a>=b
 [1]  TRUE  TRUE  TRUE  TRUE  TRUE FALSE FALSE FALSE FALSE FALSE
which(a<b)[1]
[1] 6
sum(b[a>=b]) + a[which(a<b)[1]]
[1] 37.5
(sum(b[a>=b]) + a[which(a<b)[1]])>=35
[1] TRUE
if((sum(b[a>=b]) + a[which(a<b)[1]]>=35)){print("생존")}
[1] "생존"
num <- 0
for(i in 1:456){
    a = 10-0.5*(0:9)
    b = i/100 + (0:9)
    if((sum(b[a>=b]) + a[which(a<b)[1]]>=35)){
        num <- num + 1
    }    }
print(num)
[1] 85

- 죽을위험이 없는 횟수에서 이동한 총거리

num=350 
x= seq(10,5.5,by=-.5) ## 술래의 외침시간 
steps = num/100 + 0:9 ## 참가자가 이동하려는 거리
x>=steps
 [1]  TRUE  TRUE  TRUE  TRUE  TRUE FALSE FALSE FALSE FALSE FALSE
sum(steps[x>=steps])
[1] 27.5

- 죽을 위험이 있는 횟수에서 이동한 거리

x[x<steps][1]
[1] 7.5

- 더하면?

sum(steps[x>=steps]) + x[x<steps][1] ## 총이동거리
[1] 35

- 총이동거리 >= 35 이면 살아남을 수 있음

sum(steps[x>=steps]) + x[x<steps][1] >= 35
[1] TRUE

- 정리하면

x=seq(10,5.5,by= -0.5) 
surv<-c() 
for (num in 1:456){
    steps = num/100 + 0:9 
    surv[num] <- sum(steps[x>=steps]) + x[x<steps][1] >= 35
}
sum(surv)
[1] 85

9. 다음을 잘 읽고 시각화 하라. (15점)

다음은 인터넷에서 어떠한 자료를 다운받아 매트릭스로 저장하는 코드이다.

df=read.csv("https://raw.githubusercontent.com/miruetoto/yechan/master/_notebooks/round2.csv")
mat=as.matrix(df)

매트릭스는 mat이라는 변수에 저장되어 있다.

df=read.csv("https://raw.githubusercontent.com/miruetoto/yechan/master/_notebooks/round2.csv")
mat=as.matrix(df)
Warning message in file(file, "rt"):
“cannot open URL 'https://raw.githubusercontent.com/miruetoto/yechan/master/_notebooks/round2.csv': HTTP status was '404 Not Found'”
Error in file(file, "rt"): cannot open the connection to 'https://raw.githubusercontent.com/miruetoto/yechan/master/_notebooks/round2.csv'
Traceback:

1. read.csv("https://raw.githubusercontent.com/miruetoto/yechan/master/_notebooks/round2.csv")
2. read.table(file = file, header = header, sep = sep, quote = quote, 
 .     dec = dec, fill = fill, comment.char = comment.char, ...)
3. file(file, "rt")

(a) mat의 첫번째 열을 $x$, 두번째열을 $y$로 생각하고 plot함수를 통하여 아래와 같은 산점도를 그려라.

plot(mat[,1],mat[,2])
plot(mat)
  • R은 알아서 해석해서 해주는 것이 좀 많아요..
  • 이것은 프로그램 만든 사람이 편의성을 위해 "만들어준" 기능입니다.
  • 이러한 기능을 이용한 풀이는 좋은 풀이가 아닌데 그 이유는 프로그램을 만든 사람의 마음에 따라서 시각화가 가능하기도 하고 불가능하기도 합니다.

(b) 매트릭스의 첫번째 행(first row)를 출력하는 코드를 작성하라.

- 힌트: 출력결과는 (12,313)이 나와야 한다.

mat[1,]
  x   y 
 12 313 

(c) (b)의 결과에 아래의 연산을 수행하는 코드를 작성하라.

$$ \begin{bmatrix} 0 & -1 \\ -1 & 0 \end{bmatrix} \begin{bmatrix} 12 \\ 313 \end{bmatrix} $$
f = function(X){
    dim(X)=c(2,1)
    X
}
rbind(c(0,-1),c(-1,0)) %*% f(mat[1,])
     [,1]
[1,] -313
[2,]  -12

(d) (b)-(c) 과정을 mat의 모든행에 반복하여 새로운 매트릭스를 만들어라.

- 힌트: 아래의 과정을 따른다.

  • (i) mat와 동일한 dim을 가진 mat2를 만든다.
  • (ii) mat의 첫번째 행에 (b)-(c)의 과정을 적용하여 길이가 2인 벡터를 얻는다.
  • (iii) (ii)의 과정에서 얻은 벡터를 새로운 매트릭스의 첫번째 행에 넣는다.
  • (iv) mat의 두번째 행에 대하여 (ii)-(iii)의 과정을 반복한다. 이후 세번째, 네번째 행에 대하여 (ii)-(iii)의 과정을 반복한다.
g = function(X){
    dim(X)=c(1,2)
    X  
}
dim(mat2)
[1] 5513    2
mat2 = mat*0  
for (i in 1:5513) mat2[i,] = rbind(c(0,-1),c(-1,0)) %*% f(mat[i,]) %>% g

(e) (d)의 결과로 생성되 매트릭스의 첫번째 열을 x, 두번째 열을 y로 하고 산점도를 그려라. (점의 색은 붉은색으로 하라)

- 힌트: 아래와 같은 그림이 나와야 한다.

plot(mat2[,1],mat2[,2],col='red')

(풀이)

- 사실 아래는 같음

rbind(c(0,-1),c(-1,0)) %*% c(12,312) ## c(12,313) 벡터
     [,1]
[1,] -312
[2,]  -12
rbind(c(0,-1),c(-1,0)) %*% matrix(c(12,312),nrow=2)
     [,1]
[1,] -312
[2,]  -12

- 그리고 아래도 같음

c(12,313) %*% rbind(c(0,-1),c(-1,0))
     [,1] [,2]
[1,] -313 -12 
matrix(c(12,313),nrow=1) %*% rbind(c(0,-1),c(-1,0))
     [,1] [,2]
[1,] -313 -12 

- c(12,313)이 때로는 벡터로, 때로는 $n\times 1$인 매트릭스로 생각할 수 있고, 때로는 $1\times n$ 매트릭스로 해석할 수도 있음.

- 따라서 아래와 같이 풀어도 가능함.

mat2 = mat*0  
for (i in 1:5513) mat2[i,] = rbind(c(0,-1),c(-1,0)) %*% mat[i,]
plot(mat2,col='red')

(풀이3)

- 매트릭스의 곱셈을 잘 이해했다면?

head(mat)
     x  y  
[1,] 12 313
[2,] 12 314
[3,] 13 279
[4,] 13 311
[5,] 13 312
[6,] 13 313
rbind(c(0,-1),c(-1,0)) %*% c(12,313)
     [,1]
[1,] -313
[2,]  -12
rbind(c(0,-1),c(-1,0)) %*% c(12,314)
     [,1]
[1,] -314
[2,]  -12
cbind(c(12,313),c(12,314))
     [,1] [,2]
[1,]  12   12 
[2,] 313  314 
rbind(c(0,-1),c(-1,0)) %*% cbind(c(12,313),c(12,314))
     [,1] [,2]
[1,] -313 -314
[2,]  -12  -12

- 응용하면

rbind(c(0,-1),c(-1,0)) %*% t(mat) %>% t %>% plot(col='red')

- 매트릭스 A,B의 곱에서 뒷부분을 임의의 칼럼으로 쪼개서 각각 연산한뒤 합쳐도 성립한다.

- 매트릭스 A,B의 곱에서 앞부분을 임의의 로우로 쪼개서 각각 연산한뒤 합쳐도 성립한다.