“Paradoja” del cumpleaños

Seguramente haz escuchado de la “paradoja” del cumpleaños donde se desea determinar la probabilidad de que dos personas en un salón cumplan el mismo día. Para fines de este ejercicio considera que se tienen n personas, los años bisiestos no son contados ni se admiten las personas gemelas; además de que los posibles 365 cumpleaños tienen la misma probabilidad de ocurrir.

\[\mathbb{P}=\left\{\begin{array}{ll}1-\frac{365 !}{365^{n}(365-n) !} & 1 \leq n \leq 365 \\ 1 & n>365\end{array} ; \quad \mathbb{P}=1-\left(\frac{364}{365}\right)^{n}\right.\]

En resumen, se tienen las siguientes expresiones para determinar la probabilidad, bajo las condiciones anteriores, de que dos personas cumplan el mismo día y de que otra persona cumpla el mismo día que tú. Seguramente haz escuchado de la “paradoja” del cumpleaños donde se desea determinar la probabilidad de que dos personas en un salón cumplan el mismo día. Para fines de este ejercicio considera que se tienen n personas, los años bisiestos no son contados ni se admiten las personas gemelas; además de que los posibles 365 cumpleaños tienen la misma probabilidad de ocurrir.

  1. Crea una función que, de acuerdo a una n válida, determine ambas probabilidades.
  2. Crea una gráfica donde se tengan la distribución de cada una de las probabilidades y determina si existe algún momento en el que hay la misma probabilidad, para una n, de que dos personas cumplan el mismo día y de que otra personas cumpla el mismo día que tú.
```r
Paradox1 <- function(n){
  p <- 1
  #Se realiza un ciclo for para calcular las probabilidades
  for(i in 1:n) {
    p = p * ((365 - i + 1) / 365) #Casos favorables entre casos totales
  }
  1 - p
}

<!-- rnb-source-end -->

<!-- rnb-chunk-end -->


<!-- rnb-text-begin -->

La función para la segunda probabilidad sería de la siguiente manera


<!-- rnb-text-end -->


<!-- rnb-chunk-begin -->


<!-- rnb-source-begin eyJkYXRhIjoiYGBgclxuYGBgclxuUGFyYWRveDIgPC0gZnVuY3Rpb24obil7XG4gIDEgLSAoKDM2NC8zNjUpXm4pXG59XG5cbmBgYFxuYGBgIn0= -->

```r
```r
Paradox2 <- function(n){
  1 - ((364/365)^n)
}

<!-- rnb-source-end -->

<!-- rnb-chunk-end -->


<!-- rnb-text-begin -->

Combinemos las funciones Paradox1 y Paradox2 en una sola función


<!-- rnb-text-end -->


<!-- rnb-chunk-begin -->


<!-- rnb-source-begin eyJkYXRhIjoiYGBgclxuYGBgclxuQmlydGhfUGFyYWRveCA8LSBmdW5jdGlvbihuKXtcbiAgdW5vIDwtIFBhcmFkb3gxKG4pXG4gIGRvcyA8LSBQYXJhZG94MihuKVxuICBcbiAgYSA8LSBwYXN0ZShcXEVuIHVuIGdydXBvIGNvblxcLG4sXFxwZXJzb25hczpcXClcbiAgYiA8LSBwYXN0ZShcXExhIHByb2JhYmlsaWRhZCBkZSBxdWUgZG9zIHBlcnNvbmFzIGN1bXBsYW4gYcODwrFvcyBlbCBtaXNtbyBkw4PCrWEgZXNcXCx1bm8pXG4gIGMgPC0gcGFzdGUoXFxMYSBwcm9iYWJpbGlkYWQgZGUgcXVlIGFsZ3VpZW4gY3VtcGxhIGHDg8Kxb3MgZWwgbWlzbW8gZGlhIHF1ZSB0w4PCuiBlc1xcLGRvcylcbiAgdG9kbyA8LSBjKGEsYixjKVxuICByZXR1cm4odG9kbylcbn1cbmBgYFxuYGBgIn0= -->

```r
```r
Birth_Paradox <- function(n){
  uno <- Paradox1(n)
  dos <- Paradox2(n)
  
  a <- paste(\En un grupo con\,n,\personas:\)
  b <- paste(\La probabilidad de que dos personas cumplan años el mismo día es\,uno)
  c <- paste(\La probabilidad de que alguien cumpla años el mismo dia que tú es\,dos)
  todo <- c(a,b,c)
  return(todo)
}

<!-- rnb-source-end -->

<!-- rnb-chunk-end -->


<!-- rnb-text-begin -->

Probemos la función Birth_Paradox para dos grupos de personas

<!-- rnb-text-end -->


<!-- rnb-chunk-begin -->


<!-- rnb-source-begin eyJkYXRhIjoiYGBgclxuYGBgclxuQmlydGhfUGFyYWRveCg3MCkgI1BhcmEgdW4gZ3J1cG8gZGUgNzAgcGVyc29uYXNcbmBgYFxuYGBgIn0= -->

```r
```r
Birth_Paradox(70) #Para un grupo de 70 personas

<!-- rnb-source-end -->

<!-- rnb-output-begin eyJkYXRhIjoiWzFdIFxcRW4gdW4gZ3J1cG8gY29uIDcwIHBlcnNvbmFzOlxcICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXG5bMl0gXFxMYSBwcm9iYWJpbGlkYWQgZGUgcXVlIGRvcyBwZXJzb25hcyBjdW1wbGFuIGHDg8Kxb3MgZWwgbWlzbW8gZMODwq1hIGVzIDAuOTk5MTU5NTc1OTY1MTU3XFxcblszXSBcXExhIHByb2JhYmlsaWRhZCBkZSBxdWUgYWxndWllbiBjdW1wbGEgYcODwrFvcyBlbCBtaXNtbyBkaWEgcXVlIHTDg8K6IGVzIDAuMTc0NzI5NDU3NTgzMTRcXFxuIn0= -->

[1] un grupo con 70 personas: 
[2] probabilidad de que dos personas cumplan años el mismo día es 0.999159575965157
[3] probabilidad de que alguien cumpla años el mismo dia que tú es 0.17472945758314




<!-- rnb-output-end -->

<!-- rnb-chunk-end -->


<!-- rnb-text-begin -->



<!-- rnb-text-end -->


<!-- rnb-chunk-begin -->


<!-- rnb-source-begin eyJkYXRhIjoiYGBgclxuYGBgclxuQmlydGhfUGFyYWRveCgyMDApICNQYXJhIHVuIGdydXBvIGRlIDIwMCBwZXJzb25hc1xuYGBgXG5gYGAifQ== -->

```r
```r
Birth_Paradox(200) #Para un grupo de 200 personas

<!-- rnb-source-end -->

<!-- rnb-output-begin eyJkYXRhIjoiWzFdIFxcRW4gdW4gZ3J1cG8gY29uIDIwMCBwZXJzb25hczpcXCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFxuWzJdIFxcTGEgcHJvYmFiaWxpZGFkIGRlIHF1ZSBkb3MgcGVyc29uYXMgY3VtcGxhbiBhw4PCsW9zIGVsIG1pc21vIGTDg8KtYSBlcyAxXFwgICAgICAgICAgICAgICAgIFxuWzNdIFxcTGEgcHJvYmFiaWxpZGFkIGRlIHF1ZSBhbGd1aWVuIGN1bXBsYSBhw4PCsW9zIGVsIG1pc21vIGRpYSBxdWUgdMODwrogZXMgMC40MjIyOTgwNDMzMDA5MzRcXFxuIn0= -->

[1] un grupo con 200 personas: 
[2] probabilidad de que dos personas cumplan años el mismo día es 1 
[3] probabilidad de que alguien cumpla años el mismo dia que tú es 0.422298043300934




<!-- rnb-output-end -->

<!-- rnb-chunk-end -->


<!-- rnb-text-begin -->

Ahora veamos si existe la posibilidad de que las funciones Paradox1 y Paradox2 converjan.

Para ello vamos a graficar ambas funciones para distintos grupos de personas

<!-- rnb-text-end -->


<!-- rnb-chunk-begin -->


<!-- rnb-source-begin eyJkYXRhIjoiYGBgclxuYGBgclxuI2NyZWFyZW1vcyBkb3MgdmVjdG9yZXMgdmFjaW9zIHF1ZSBhbG1hY2VuZW4gbGFzIHByb2JhYmlsaWRhZGVzIGNhbGN1bGFkYXNcbmRhdGExIDwtIGMoKVxuZGF0YTIgPC0gYygpXG5cbiNoYWdhbW9zIGVsIGNhbGN1bG8gZGUgYW1hYmFzIHByb2JhYmlsaWRhZGVzIHBhcmEgZGlmZXJlbnRlcyBncnVwb3MgKGRlIDEgYSAyMDAwKVxuZm9yKGkgaW4gMToyMDAwKXtcbiAgZGF0YTFbaV0gPC0gUGFyYWRveDEoaSlcbiAgZGF0YTJbaV0gPC0gUGFyYWRveDIoaSlcbn1cblxucGxvdChjKDAsIDIwMDApLCBjKDAsIDEpLCB0eXBlID0gXFxuXFwsIHhsYWIgPSBcXE7Dg8K6bWVybyBkZSBwZXJzb25hc1xcLFxuICAgICAgeWxhYiA9IFxcUHJvYmFiaWxpZGFkXFwsIG1haW4gPSBcXFBhcmFkb2phIGRlbCBjdW1wbGXDg8Kxb3NcXClcbmxpbmVzKGRhdGExLCBwY2ggPSAxOSwgY29sID0gXFxkYXJrb3JjaGlkMVxcKVxuYGBgXG5gYGByXG5saW5lcyhkYXRhMiwgcGNoID0gMTksIGNvbCA9IFxcZGFya29yY2hpZDRcXClcbmdyaWQoKVxuYGBgXG5gYGByXG5sZWdlbmQoXFxib3R0b21yaWdodFxcLCBsZWdlbmQgPSBjKFxcRnVuY2nDg8KzbiAxXFwsXFxGdW5jacODwrNuIDJcXCksIHBjaCA9IGMoMTksIDE5KSwgXG4gICAgICAgY29sID0gYyhcXGRhcmtvcmNoaWQxXFwsXFxkYXJrb3JjaGlkNFxcKSlcbmBgYFxuYGBgIn0= -->

```r
```r
#crearemos dos vectores vacios que almacenen las probabilidades calculadas
data1 <- c()
data2 <- c()

#hagamos el calculo de amabas probabilidades para diferentes grupos (de 1 a 2000)
for(i in 1:2000){
  data1[i] <- Paradox1(i)
  data2[i] <- Paradox2(i)
}

plot(c(0, 2000), c(0, 1), type = \n\, xlab = \Número de personas\,
      ylab = \Probabilidad\, main = \Paradoja del cumpleños\)
lines(data1, pch = 19, col = \darkorchid1\)
lines(data2, pch = 19, col = \darkorchid4\)
grid()
legend(\bottomright\, legend = c(\Función 1\,\Función 2\), pch = c(19, 19), 
       col = c(\darkorchid1\,\darkorchid4\))

<!-- rnb-source-end -->

<!-- rnb-plot-begin -->

<img src="data:image/png;base64,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" />

<!-- rnb-plot-end -->

<!-- rnb-chunk-end -->


<!-- rnb-text-begin -->



# Relación Fibonacci-Eigen (vectores/valores)
Existen aplicaciones muy interesantes donde se utilizan los conocidos eigen vectores/valores de una matriz. Una de ellas es la relación que tienen estos con los conocidos números de Fibonacci. Recuerda que los números de Fibonacci quedan representados por la ecuación recursiva $F_{n}=F_{n-1}+F_{n-2}$ y de una manera muy sencilla se puede ver 

$$\left(\begin{array}{c}F_{n} \\ F_{n-1}\end{array}\right)=\left(\begin{array}{cc}1 & 1 \\ 1 & 0\end{array}\right)\left(\begin{array}{c}F_{n-1} \\ F_{n_{2}}\end{array}\right)$$

0. Crea una función para obtener el n-ésimo número de Fibonacci.
1. Determina mediante el uso de R el eigen valor positivo correspondiente a dicha matriz (es decir, el famoso número áureo o número de oro).
2. Crea una gráfica, para un n que desees, donde cada punto corresponda a $(F_{n-1},F_{n-2})$ o $(F_{n},F_{n-1})$. Dichos puntos deben ser de color de negro.
3. En la misma gráfica coloca la recta sobre la que pasa el eigen vector correspondiente al eigen valor del punto 1.
4. Elige algún punto de los graficados en el punto dos y multiplícalo por el eigen valor del punto 1 y grafícalo en color rojo ¿Qué sucedió?
5. ¿Qué concluyes de todo esto?

La sucesión de Fibonacci es la sucesión de números:
0,   1,   1,   2,   3,   5,   8,   13,   21,   34, …

En donde cada número se calcula sumando los dos anteriores a él. Vamos a crear una función que calcule el los números de Fibonacci


<!-- rnb-text-end -->


<!-- rnb-chunk-begin -->


<!-- rnb-source-begin eyJkYXRhIjoiYGBgclxuYGBgclxuZmliX24gPC0gZnVuY3Rpb24obikge1xuICAgIGlmKG4gPT0gMCl7XG4gICAgICByZXR1cm4oMClcbiAgICB9ZWxzZSBpZihuID09IDEpe1xuICAgICAgcmV0dXJuKDEpXG4gICAgfWVsc2UgaWYgKG4gPT0gMikge1xuICAgIHJldHVybigxKVxuICAgIH1lbHNlIGlmKG4gPiAyKXtcbiAgICByZXR1cm4oZmliX24obiAtIDEpICsgZmliX24obiAtIDIpKVxuICAgIH1cbiAgfVxuYGBgXG5gYGAifQ== -->

```r
```r
fib_n <- function(n) {
    if(n == 0){
      return(0)
    }else if(n == 1){
      return(1)
    }else if (n == 2) {
    return(1)
    }else if(n > 2){
    return(fib_n(n - 1) + fib_n(n - 2))
    }
  }

<!-- rnb-source-end -->

<!-- rnb-chunk-end -->


<!-- rnb-text-begin -->

Debemos recordar que n representa la posición que el número tiene en la serie

<!-- rnb-text-end -->


<!-- rnb-chunk-begin -->


<!-- rnb-source-begin eyJkYXRhIjoiYGBgclxuYGBgclxuZmliX251bWJlciA8LSBmdW5jdGlvbihuKXtcbiAgeCA8LSBmaWJfbihuKVxuICBwYXN0ZShcXEVsIFxcLCBuLCBcXMOCwrAgbsODwrptZXJvIGRlIEZpYm9uYWNjaSBlcyBcXCwgeClcbn1cbmBgYFxuYGBgIn0= -->

```r
```r
fib_number <- function(n){
  x <- fib_n(n)
  paste(\El \, n, \° número de Fibonacci es \, x)
}

<!-- rnb-source-end -->

<!-- rnb-chunk-end -->


<!-- rnb-text-begin -->

Veamos si podemos obtener las primeras 7 posiciones de los números de Fibonacci

<!-- rnb-text-end -->


<!-- rnb-chunk-begin -->


<!-- rnb-source-begin eyJkYXRhIjoiYGBgclxuYGBgclxuZmliX251bWJlcigwKVxuXG5gYGBcbmBgYCJ9 -->

```r
```r
fib_number(0)

<!-- rnb-source-end -->

<!-- rnb-chunk-end -->


<!-- rnb-chunk-begin -->


<!-- rnb-source-begin eyJkYXRhIjoiYGBgclxuYGBgclxuZmliX251bWJlcigxKVxuXG5gYGBcbmBgYCJ9 -->

```r
```r
fib_number(1)

<!-- rnb-source-end -->

<!-- rnb-chunk-end -->


<!-- rnb-text-begin -->

Ahora calculemos el número áureo a partir de la siguiente matriz
A=(1110

<!-- rnb-text-end -->


<!-- rnb-chunk-begin -->


<!-- rnb-source-begin eyJkYXRhIjoiYGBgclxuYGBgclxuQSA8LSByYmluZChjKDEsMSksIGMoMSwwKSkgXG5cbmVpZ0EgPC0gZWlnZW4oQSkgI0xhIGZ1bmNpw4PCs24gZWlnZW4oKSBjYWxjdWxhIGxvcyBlaWdlbnZhbG9yZXMgeSBlaWdlbnZlY3RvcmVzXG5cbmVpZ0EkdmFsdWVzICNFaWdlbnZhbG9yZXMgZGUgQVxuYGBgXG5gYGAifQ== -->

```r
```r
A <- rbind(c(1,1), c(1,0)) 

eigA <- eigen(A) #La función eigen() calcula los eigenvalores y eigenvectores

eigA$values #Eigenvalores de A

<!-- rnb-source-end -->

<!-- rnb-chunk-end -->


<!-- rnb-text-begin -->



<!-- rnb-text-end -->


<!-- rnb-chunk-begin -->


<!-- rnb-source-begin eyJkYXRhIjoiYGBgclxuYGBgclxub3JvIDwtIGVpZ0EkdmFsdWVzWzFdXG5cbnBhc3RlKFxcRWwgbsODwrptZXJvIMODwqF1cmVvIGVzIGVsIGVpZ2VudmFsb3IgcG9zaXRpdm8gZGUgbGEgbWF0cml6IEFcbmBgYCJ9 -->

```r
```r
oro <- eigA$values[1]

paste(\El número áureo es el eigenvalor positivo de la matriz A

Ahora vamos a crear una función que grafique n elementos de la serie de Fibonacci, los puntos tendrán coordenadas (Fn, Fn−1) y deben graficarse a partir de n=1 puesto que el número F0−1=F−1 no existe.

Sobre esta misma gráfia agregaremos el eigenvector correspondiente al número de oro

```r
grafica_fib <- function(n){
  x <- c()
  y <- c()

  for(i in 1:n){
    x[i] <- fib_n(i)
    y[i] <- fib_n(i-1) 
  }
  
  plot(x, y, xlab = expression(\F\[n]), ylab = expression(\F\[n-1]), 
       main = paste( n, \Números de Fibonacci y el eigenvector\), pch = 19)
  abline(a =  0, b = eigA$vectors[2,1]/eigA$vectors[1,1], col = \firebrick2\)
  abline(v = (seq(0, 100, 2)), col=\lightgray\, lty=\dotted\)
  abline(h = (seq(0, 100, 2)), col=\lightgray\, lty=\dotted\)
}

<!-- rnb-source-end -->

<!-- rnb-chunk-end -->


<!-- rnb-text-begin -->

Para n=10 veamos como sería nuestra grafica

<!-- rnb-text-end -->


<!-- rnb-chunk-begin -->


<!-- rnb-source-begin eyJkYXRhIjoiYGBgclxuYGBgclxuZ3JhZmljYV9maWIoMTApXG5cbmBgYFxuYGBgIn0= -->

```r
```r
grafica_fib(10)

<!-- rnb-source-end -->

<!-- rnb-chunk-end -->


<!-- rnb-text-begin -->

Veamos que pasa cuando multiplicamos algún punto de los graficados anteriormente (m) por el número áureo

<!-- rnb-text-end -->


<!-- rnb-chunk-begin -->


<!-- rnb-source-begin eyJkYXRhIjoiYGBgclxuYGBgclxuIyBuIGVzIHBhcmEgbGEgY2FudGlkYWQgZGUgcHVudG9zIGEgZ3JhZmljYXJcbiMgbSBlcyBwYXJhIGVsIHB1bnRvIGEgbXVsdGlwbGljYXIgcG9yIGVsIG7Dg8K6bWVybyBkZSBvcm9cbmdyYWZfbmV3UG9pbnQgPC0gZnVuY3Rpb24obiwgbSl7IFxuICB4IDwtIGMoKVxuICB5IDwtIGMoKVxuICBcbiAgZm9yKGkgaW4gMTpuKXtcbiAgICB4W2ldIDwtIGZpYl9uKGkpXG4gICAgeVtpXSA8LSBmaWJfbihpLTEpXG4gIH1cbiAgXG4gIHBvaW50IDwtIGMoeFttXSwgeVttXSlcbiAgbmV3X3BvaW50IDwtIHBvaW50ICogb3JvXG4gIFxuICBwbG90KHgsIHksIHhsYWIgPSBleHByZXNzaW9uKFxcRlxcW25dKSwgeWxhYiA9IGV4cHJlc3Npb24oXFxGXFxbbi0xXSksIFxuICAgICAgbWFpbiA9IHBhc3RlKFxcRWwgbW92aW1pZW50byBkZWwgcHVudG9cXCwgbSksIHBjaCA9IDE5KVxuICBsaW5lcyhuZXdfcG9pbnRbMV0sIG5ld19wb2ludFsyXSwgdHlwZSA9IFxccFxcLCBwY2ggPSAxOCwgY29sID0gXFxyZWRcXClcbiAgYWJsaW5lKGEgPSAgMCwgYiA9IGVpZ0EkdmVjdG9yc1syLDFdL2VpZ0EkdmVjdG9yc1sxLDFdLCBjb2wgPSBcXGZpcmVicmljazJcXClcbiAgYWJsaW5lKHYgPSAoc2VxKDAsIDEwMCwgMikpLCBjb2w9XFxsaWdodGdyYXlcXCwgbHR5PVxcZG90dGVkXFwpXG4gIGFibGluZShoID0gKHNlcSgwLCAxMDAsIDIpKSwgY29sPVxcbGlnaHRncmF5XFwsIGx0eT1cXGRvdHRlZFxcKVxufVxuYGBgXG5gYGAifQ== -->

```r
```r
# n es para la cantidad de puntos a graficar
# m es para el punto a multiplicar por el número de oro
graf_newPoint <- function(n, m){ 
  x <- c()
  y <- c()
  
  for(i in 1:n){
    x[i] <- fib_n(i)
    y[i] <- fib_n(i-1)
  }
  
  point <- c(x[m], y[m])
  new_point <- point * oro
  
  plot(x, y, xlab = expression(\F\[n]), ylab = expression(\F\[n-1]), 
      main = paste(\El movimiento del punto\, m), pch = 19)
  lines(new_point[1], new_point[2], type = \p\, pch = 18, col = \red\)
  abline(a =  0, b = eigA$vectors[2,1]/eigA$vectors[1,1], col = \firebrick2\)
  abline(v = (seq(0, 100, 2)), col=\lightgray\, lty=\dotted\)
  abline(h = (seq(0, 100, 2)), col=\lightgray\, lty=\dotted\)
}

<!-- rnb-source-end -->

<!-- rnb-chunk-end -->


<!-- rnb-text-begin -->

En mi caso yo quiero graficar 10 puntos de la suceción de Fibonacci y quiero multiplicar el 9° elemento por el número de oro


<!-- rnb-text-end -->


<!-- rnb-chunk-begin -->


<!-- rnb-source-begin eyJkYXRhIjoiYGBgclxuYGBgclxuZ3JhZl9uZXdQb2ludCgxMCw5KVxuXG5gYGBcbmBgYCJ9 -->

```r
```r
graf_newPoint(10,9)

<!-- rnb-source-end -->

<!-- rnb-chunk-end -->


<!-- rnb-text-begin -->

De la grafica anterior podemos concluir que el número áureo es la razón de cambio de la sucesión de Fibonacci



# Iteraciones
En la mayoría de cursos que haz visto se ha tenido una gran cantidad de teoría sin ver algoritmos que te permitan comprobar dichas cosas. Vamos a arreglar un poco esto y crea alguna función o método iterativo para aproximar lo siguiente. En cada uno de los casos da un ejemplo para comprobar el funcionamiento de tu solución.

1. Derivada. Para comprobar determina si la derivada de $2x2$ en algún punto se aproxima con tu función.
2. Integral. Puedes usar funciones positivas para comprobar tu función utilizando la interpretación de la integral.
3. Perímetro de una circunferencia. Investiga un poco sobre la relación que existe entre el número de lados de un polígono regular y su perímetro, así como la longitud de los lados de un polígono inscrito en una circunferencia de radio r. Con esto tienes las bases para crear una función, que de acuerdo a un numero de lados n se vaya acercando al perímetro de una circunferencia. Al final puedes comprobar tus resultados con la formula ya conocida.

# Procesamiento de textos
La idea será sencilla aunque la implementación no lo se 🙈, por lo que podrías obtener más resultados de los que coloco aquí. De acuerdo a un archivo .txt que se te será proporcionado determinar lo siguiente:

1. Cantidad de letras.
2. Cantidad de vocales.
3. Cantidad de espacios.
4. Porcentaje que representa cada letra en el texto.

No importa si consideras a los caracteres especiales como letras o no, tampoco si haces distinción entre mayúsculas y minúsculas, ni tampoco las veces que tengas que cargar el archivo.

Para este ejercicio primero debemos cargar algunas librerias


<!-- rnb-text-end -->


<!-- rnb-chunk-begin -->


<!-- rnb-source-begin eyJkYXRhIjoiYGBgclxuYGBgclxubGlicmFyeSh0b2tlbml6ZXJzKVxubGlicmFyeShyZWFkcilcbmxpYnJhcnkod29yZGNsb3VkKVxubGlicmFyeShkcGx5cilcbmxpYnJhcnkocmVhZHIpXG5saWJyYXJ5KGdncGxvdDIpXG5saWJyYXJ5KHN0cmluZ3IpXG5saWJyYXJ5KGV4dHJhZm9udClcbmxpYnJhcnkodG0pXG5saWJyYXJ5KFJDb2xvckJyZXdlcilcbmBgYFxuYGBgIn0= -->

```r
```r
library(tokenizers)
library(readr)
library(wordcloud)
library(dplyr)
library(readr)
library(ggplot2)
library(stringr)
library(extrafont)
library(tm)
library(RColorBrewer)

<!-- rnb-source-end -->

<!-- rnb-chunk-end -->


<!-- rnb-text-begin -->


Primero debemos cargar nuestro documento, y hacerle una “limpieza” con el fin de facilitar nuestro análisis


<!-- rnb-text-end -->


<!-- rnb-chunk-begin -->


<!-- rnb-source-begin eyJkYXRhIjoiYGBgclxuYGBgclxuQ2FyZ2FfZG9jdW1lbnRvIDwtIGZ1bmN0aW9uKGRvY3VtZW50byl7XG5cbiAgI1V0aWxpemEgbGEgZnVuY2nDg8KzbiBmaWxlLCBjb24gZWwgcGFyw4PCoW1ldHJvIHIgKGRlIFxccmVhZFxcLCBsZWVyKVxuICBsZWVyX2RvY3VtZW50byA8LSBmaWxlKGRvY3VtZW50bywgb3BlbiA9IFxcclxcKVxuXG4gICNBcGxpY2EgbGEgZnVuY2nDg8KzbiByZWFkTGluZXMgcGFyYSBsZWVyIGxhcyBsw4PCrW5lYXMgZGVsIGFyY2hpdm8sIFxuICAjZsODwq1qYXRlIHF1ZSBlbCBlbmNvZGluZyBzZWEgVVRGLThcbiAgdGV4dG9fbGluZWFzIDwtIHJlYWRMaW5lcyhsZWVyX2RvY3VtZW50bywgZW5jb2RpbmcgPSBcXFVURi04XFwpXG5cbiAgI0p1bnRhIHRvZGFzIGxhcyBsaW5lYXMgKHDDg8KhcnJhZm9zKSBlbiB1bm8gc29sb1xuICB0ZXh0b19jb21wbGV0byA8LSBwYXN0ZSh0ZXh0b19saW5lYXMsIGNvbGxhcHNlID0gXFxcXG5cXClcbiAgXG4gICNSZXRpcmVtb3MgbG9zIHNpZ25vcyBkZSBwdW50dWFjacODwrNuXG4gIHRleHRvX3NpblNpZ25vcyA8LSByZW1vdmVQdW5jdHVhdGlvbih0ZXh0b19jb21wbGV0bylcblxuICAjVmFtb3MgYSBjYW1iaWFyIGxvcyBcXFxcblxcIHF1ZSByZXByZXNlbnRhbiBsb3Mgc2FsdG9zIGRlIGxpbmVhIHBvciBlc3BhY2lvcyBlbiBibGFuY29cbiAgdGV4dG9fU2luU2FsdG9zIDwtIHN0cl9yZXBsYWNlX2FsbCh0ZXh0b19zaW5TaWdub3MsIFxcXFxuXFwsIFxcIFxcKVxuXG4gICNWYW1vcyBhIGVsaW1pbmFyIGxvcyBlc3BhY2lvcyBlbiBibGFuY28gbcODwrpsdGlwbGVzXG4gIHRleHRvX1NpbkVzcGFjaW9zIDwtIHN0cl9yZXBsYWNlX2FsbCh0ZXh0b19TaW5TYWx0b3MsIFxcW1xcXFxzXStcXCwgXFwgXFwpXG59XG5cbmBgYFxuYGBgIn0= -->

```r
```r
Carga_documento <- function(documento){

  #Utiliza la función file, con el parámetro r (de \read\, leer)
  leer_documento <- file(documento, open = \r\)

  #Aplica la función readLines para leer las líneas del archivo, 
  #fíjate que el encoding sea UTF-8
  texto_lineas <- readLines(leer_documento, encoding = \UTF-8\)

  #Junta todas las lineas (párrafos) en uno solo
  texto_completo <- paste(texto_lineas, collapse = \\n\)
  
  #Retiremos los signos de puntuación
  texto_sinSignos <- removePunctuation(texto_completo)

  #Vamos a cambiar los \\n\ que representan los saltos de linea por espacios en blanco
  texto_SinSaltos <- str_replace_all(texto_sinSignos, \\n\, \ \)

  #Vamos a eliminar los espacios en blanco múltiples
  texto_SinEspacios <- str_replace_all(texto_SinSaltos, \[\\s]+\, \ \)
}

<!-- rnb-source-end -->

<!-- rnb-chunk-end -->


<!-- rnb-text-begin -->


documento <- "Romeo_and_Juliet.txt"

Carga_documento(documento)```{r}

Teorema central del límite

Es bien conocido el teorema que abordamos en este ejercicio y sólo para recordar, si \(X_{1},X_{2},…\) es una sucesión de variables aleatorias independientes e idénticamente distribuidas, con media \(μ\) y varianza finita \(σ2\), la función de distribución de la variable aleatoria \(Z\) descrita por \[Z=\frac{\left(X_{1}+\cdots+X_{n}\right)-n \mu}{\sqrt{n \sigma^{2}}}\] tiende a la función de distribución normal estándar cuando \(n→∞\). Entonces, tu objetivo será crear una función que, de acuerdo a una distribución (pueden ser tantas como conozcas) que sean adaptables a las condiciones del teorema, incluyendo como parámetros de la función la media y la varianza de dicha distribución y una n, se creen simulaciones de dicha distribución, al igual que la v.a. \(Z\). Finalmente se tiene que dar las gráficas de probabilidad acumulada y de densidad correspondiente (puedes guardar todo en una lista). Al final, con un n grande dado en la función, se debería poder ver una “comprobación visual de dicho teorema”.

Suerte! Ojala que no la necesites 🤭

LS0tDQp0aXRsZTogInBydWViYV8xIg0KYXV0aG9yOiAiQ1JVWiBNQVRFTyBEQVZJRCINCmRhdGU6ICIyOC85LzIwMjEiDQpvdXRwdXQ6DQogIGh0bWxfbm90ZWJvb2s6DQogICAgdG9jOiB0cnVlDQogIHBkZl9kb2N1bWVudDoNCiAgICB0b2M6IHRydWUNCiAgaHRtbF9kb2N1bWVudDoNCiAgICB0b2M6IHRydWUNCmxhbmc6IGVzLUVTDQotLS0NCiMg4oCcUGFyYWRvamHigJ0gZGVsIGN1bXBsZWHDsW9zDQoNClNlZ3VyYW1lbnRlIGhheiBlc2N1Y2hhZG8gZGUgbGEg4oCccGFyYWRvamHigJ0gZGVsIGN1bXBsZWHDsW9zIGRvbmRlIHNlIGRlc2VhIGRldGVybWluYXIgbGEgcHJvYmFiaWxpZGFkIGRlIHF1ZSBkb3MgcGVyc29uYXMgZW4gdW4gc2Fsw7NuIGN1bXBsYW4gZWwgbWlzbW8gZMOtYS4gUGFyYSBmaW5lcyBkZSBlc3RlIGVqZXJjaWNpbyBjb25zaWRlcmEgcXVlIHNlIHRpZW5lbiBuIHBlcnNvbmFzLCBsb3MgYcOxb3MgYmlzaWVzdG9zIG5vIHNvbiBjb250YWRvcyBuaSBzZSBhZG1pdGVuIGxhcyBwZXJzb25hcyBnZW1lbGFzOyBhZGVtw6FzIGRlIHF1ZSBsb3MgcG9zaWJsZXMgMzY1IGN1bXBsZWHDsW9zIHRpZW5lbiBsYSBtaXNtYSBwcm9iYWJpbGlkYWQgZGUgb2N1cnJpci4NCg0KJCRcbWF0aGJie1B9PVxsZWZ0XHtcYmVnaW57YXJyYXl9e2xsfTEtXGZyYWN7MzY1ICF9ezM2NV57bn0oMzY1LW4pICF9ICYgMSBcbGVxIG4gXGxlcSAzNjUgXFwgMSAmIG4+MzY1XGVuZHthcnJheX0gOyBccXVhZCBcbWF0aGJie1B9PTEtXGxlZnQoXGZyYWN7MzY0fXszNjV9XHJpZ2h0KV57bn1ccmlnaHQuJCQNCg0KRW4gcmVzdW1lbiwgc2UgdGllbmVuIGxhcyBzaWd1aWVudGVzIGV4cHJlc2lvbmVzIHBhcmEgZGV0ZXJtaW5hciBsYSBwcm9iYWJpbGlkYWQsIGJham8gbGFzIGNvbmRpY2lvbmVzIGFudGVyaW9yZXMsIGRlIHF1ZSBkb3MgcGVyc29uYXMgY3VtcGxhbiBlbCBtaXNtbyBkw61hIHkgZGUgcXVlIG90cmEgcGVyc29uYSBjdW1wbGEgZWwgbWlzbW8gZMOtYSBxdWUgdMO6Lg0KU2VndXJhbWVudGUgaGF6IGVzY3VjaGFkbyBkZSBsYSDigJxwYXJhZG9qYeKAnSBkZWwgY3VtcGxlYcOxb3MgZG9uZGUgc2UgZGVzZWEgZGV0ZXJtaW5hciBsYSBwcm9iYWJpbGlkYWQgZGUgcXVlIGRvcyBwZXJzb25hcyBlbiB1biBzYWzDs24gY3VtcGxhbiBlbCBtaXNtbyBkw61hLiBQYXJhIGZpbmVzIGRlIGVzdGUgZWplcmNpY2lvIGNvbnNpZGVyYSBxdWUgc2UgdGllbmVuIG4gcGVyc29uYXMsIGxvcyBhw7FvcyBiaXNpZXN0b3Mgbm8gc29uIGNvbnRhZG9zIG5pIHNlIGFkbWl0ZW4gbGFzIHBlcnNvbmFzIGdlbWVsYXM7IGFkZW3DoXMgZGUgcXVlIGxvcyBwb3NpYmxlcyAzNjUgY3VtcGxlYcOxb3MgdGllbmVuIGxhIG1pc21hIHByb2JhYmlsaWRhZCBkZSBvY3VycmlyLg0KDQoxLiBDcmVhIHVuYSBmdW5jacOzbiBxdWUsIGRlIGFjdWVyZG8gYSB1bmEgbiB2w6FsaWRhLCBkZXRlcm1pbmUgYW1iYXMgcHJvYmFiaWxpZGFkZXMuDQoyLiBDcmVhIHVuYSBncsOhZmljYSBkb25kZSBzZSB0ZW5nYW4gbGEgZGlzdHJpYnVjacOzbiBkZSBjYWRhIHVuYSBkZSBsYXMgcHJvYmFiaWxpZGFkZXMgeSBkZXRlcm1pbmEgc2kgZXhpc3RlIGFsZ8O6biBtb21lbnRvIGVuIGVsIHF1ZSBoYXkgbGEgbWlzbWEgcHJvYmFiaWxpZGFkLCBwYXJhIHVuYSBuLCBkZSBxdWUgZG9zIHBlcnNvbmFzIGN1bXBsYW4gZWwgbWlzbW8gZMOtYSB5IGRlIHF1ZSBvdHJhIHBlcnNvbmFzIGN1bXBsYSBlbCBtaXNtbyBkw61hIHF1ZSB0w7ouDQoNCmBgYHtyfQ0KUGFyYWRveDEgPC0gZnVuY3Rpb24obil7DQogIHAgPC0gMQ0KICAjU2UgcmVhbGl6YSB1biBjaWNsbyBmb3IgcGFyYSBjYWxjdWxhciBsYXMgcHJvYmFiaWxpZGFkZXMNCiAgZm9yKGkgaW4gMTpuKSB7DQogICAgcCA9IHAgKiAoKDM2NSAtIGkgKyAxKSAvIDM2NSkgI0Nhc29zIGZhdm9yYWJsZXMgZW50cmUgY2Fzb3MgdG90YWxlcw0KICB9DQogIDEgLSBwDQp9DQoNCmBgYA0KTGEgZnVuY2nDs24gcGFyYSBsYSBzZWd1bmRhIHByb2JhYmlsaWRhZCBzZXLDrWEgZGUgbGEgc2lndWllbnRlIG1hbmVyYQ0KDQpgYGB7cn0NClBhcmFkb3gyIDwtIGZ1bmN0aW9uKG4pew0KICAxIC0gKCgzNjQvMzY1KV5uKQ0KfQ0KDQpgYGANCkNvbWJpbmVtb3MgbGFzIGZ1bmNpb25lcyBQYXJhZG94MSB5IFBhcmFkb3gyIGVuIHVuYSBzb2xhIGZ1bmNpw7NuDQoNCmBgYHtyfQ0KQmlydGhfUGFyYWRveCA8LSBmdW5jdGlvbihuKXsNCiAgdW5vIDwtIFBhcmFkb3gxKG4pDQogIGRvcyA8LSBQYXJhZG94MihuKQ0KICANCiAgYSA8LSBwYXN0ZSgiRW4gdW4gZ3J1cG8gY29uIixuLCJwZXJzb25hczoiKQ0KICBiIDwtIHBhc3RlKCJMYSBwcm9iYWJpbGlkYWQgZGUgcXVlIGRvcyBwZXJzb25hcyBjdW1wbGFuIGHDsW9zIGVsIG1pc21vIGTDrWEgZXMiLHVubykNCiAgYyA8LSBwYXN0ZSgiTGEgcHJvYmFiaWxpZGFkIGRlIHF1ZSBhbGd1aWVuIGN1bXBsYSBhw7FvcyBlbCBtaXNtbyBkaWEgcXVlIHTDuiBlcyIsZG9zKQ0KICB0b2RvIDwtIGMoYSxiLGMpDQogIHJldHVybih0b2RvKQ0KfQ0KYGBgDQpQcm9iZW1vcyBsYSBmdW5jacOzbiBCaXJ0aF9QYXJhZG94IHBhcmEgZG9zIGdydXBvcyBkZSBwZXJzb25hcw0KYGBge3J9DQpCaXJ0aF9QYXJhZG94KDcwKSAjUGFyYSB1biBncnVwbyBkZSA3MCBwZXJzb25hcw0KDQpgYGANCg0KYGBge3J9DQpCaXJ0aF9QYXJhZG94KDIwMCkgI1BhcmEgdW4gZ3J1cG8gZGUgMjAwIHBlcnNvbmFzDQoNCmBgYA0KQWhvcmEgdmVhbW9zIHNpIGV4aXN0ZSBsYSBwb3NpYmlsaWRhZCBkZSBxdWUgbGFzIGZ1bmNpb25lcyBQYXJhZG94MSB5IFBhcmFkb3gyIGNvbnZlcmphbi4NCg0KUGFyYSBlbGxvIHZhbW9zIGEgZ3JhZmljYXIgYW1iYXMgZnVuY2lvbmVzIHBhcmEgZGlzdGludG9zIGdydXBvcyBkZSBwZXJzb25hcw0KYGBge3J9DQojY3JlYXJlbW9zIGRvcyB2ZWN0b3JlcyB2YWNpb3MgcXVlIGFsbWFjZW5lbiBsYXMgcHJvYmFiaWxpZGFkZXMgY2FsY3VsYWRhcw0KZGF0YTEgPC0gYygpDQpkYXRhMiA8LSBjKCkNCg0KI2hhZ2Ftb3MgZWwgY2FsY3VsbyBkZSBhbWFiYXMgcHJvYmFiaWxpZGFkZXMgcGFyYSBkaWZlcmVudGVzIGdydXBvcyAoZGUgMSBhIDIwMDApDQpmb3IoaSBpbiAxOjIwMDApew0KICBkYXRhMVtpXSA8LSBQYXJhZG94MShpKQ0KICBkYXRhMltpXSA8LSBQYXJhZG94MihpKQ0KfQ0KDQpwbG90KGMoMCwgMjAwMCksIGMoMCwgMSksIHR5cGUgPSAibiIsIHhsYWIgPSAiTsO6bWVybyBkZSBwZXJzb25hcyIsDQogICAgICB5bGFiID0gIlByb2JhYmlsaWRhZCIsIG1haW4gPSAiUGFyYWRvamEgZGVsIGN1bXBsZcOxb3MiKQ0KbGluZXMoZGF0YTEsIHBjaCA9IDE5LCBjb2wgPSAiZGFya29yY2hpZDEiKQ0KbGluZXMoZGF0YTIsIHBjaCA9IDE5LCBjb2wgPSAiZGFya29yY2hpZDQiKQ0KZ3JpZCgpDQpsZWdlbmQoImJvdHRvbXJpZ2h0IiwgbGVnZW5kID0gYygiRnVuY2nDs24gMSIsIkZ1bmNpw7NuIDIiKSwgcGNoID0gYygxOSwgMTkpLCANCiAgICAgICBjb2wgPSBjKCJkYXJrb3JjaGlkMSIsImRhcmtvcmNoaWQ0IikpDQpgYGANCg0KDQojIFJlbGFjacOzbiBGaWJvbmFjY2ktRWlnZW4gKHZlY3RvcmVzL3ZhbG9yZXMpDQpFeGlzdGVuIGFwbGljYWNpb25lcyBtdXkgaW50ZXJlc2FudGVzIGRvbmRlIHNlIHV0aWxpemFuIGxvcyBjb25vY2lkb3MgZWlnZW4gdmVjdG9yZXMvdmFsb3JlcyBkZSB1bmEgbWF0cml6LiBVbmEgZGUgZWxsYXMgZXMgbGEgcmVsYWNpw7NuIHF1ZSB0aWVuZW4gZXN0b3MgY29uIGxvcyBjb25vY2lkb3MgbsO6bWVyb3MgZGUgRmlib25hY2NpLiBSZWN1ZXJkYSBxdWUgbG9zIG7Dum1lcm9zIGRlIEZpYm9uYWNjaSBxdWVkYW4gcmVwcmVzZW50YWRvcyBwb3IgbGEgZWN1YWNpw7NuIHJlY3Vyc2l2YSAkRl97bn09Rl97bi0xfStGX3tuLTJ9JCB5IGRlIHVuYSBtYW5lcmEgbXV5IHNlbmNpbGxhIHNlIHB1ZWRlIHZlciANCg0KJCRcbGVmdChcYmVnaW57YXJyYXl9e2N9Rl97bn0gXFwgRl97bi0xfVxlbmR7YXJyYXl9XHJpZ2h0KT1cbGVmdChcYmVnaW57YXJyYXl9e2NjfTEgJiAxIFxcIDEgJiAwXGVuZHthcnJheX1ccmlnaHQpXGxlZnQoXGJlZ2lue2FycmF5fXtjfUZfe24tMX0gXFwgRl97bl97Mn19XGVuZHthcnJheX1ccmlnaHQpJCQNCg0KMC4gQ3JlYSB1bmEgZnVuY2nDs24gcGFyYSBvYnRlbmVyIGVsIG4tw6lzaW1vIG7Dum1lcm8gZGUgRmlib25hY2NpLg0KMS4gRGV0ZXJtaW5hIG1lZGlhbnRlIGVsIHVzbyBkZSBSIGVsIGVpZ2VuIHZhbG9yIHBvc2l0aXZvIGNvcnJlc3BvbmRpZW50ZSBhIGRpY2hhIG1hdHJpeiAoZXMgZGVjaXIsIGVsIGZhbW9zbyBuw7ptZXJvIMOhdXJlbyBvIG7Dum1lcm8gZGUgb3JvKS4NCjIuIENyZWEgdW5hIGdyw6FmaWNhLCBwYXJhIHVuIG4gcXVlIGRlc2VlcywgZG9uZGUgY2FkYSBwdW50byBjb3JyZXNwb25kYSBhICQoRl97bi0xfSxGX3tuLTJ9KSQgbyAkKEZfe259LEZfe24tMX0pJC4gRGljaG9zIHB1bnRvcyBkZWJlbiBzZXIgZGUgY29sb3IgZGUgbmVncm8uDQozLiBFbiBsYSBtaXNtYSBncsOhZmljYSBjb2xvY2EgbGEgcmVjdGEgc29icmUgbGEgcXVlIHBhc2EgZWwgZWlnZW4gdmVjdG9yIGNvcnJlc3BvbmRpZW50ZSBhbCBlaWdlbiB2YWxvciBkZWwgcHVudG8gMS4NCjQuIEVsaWdlIGFsZ8O6biBwdW50byBkZSBsb3MgZ3JhZmljYWRvcyBlbiBlbCBwdW50byBkb3MgeSBtdWx0aXBsw61jYWxvIHBvciBlbCBlaWdlbiB2YWxvciBkZWwgcHVudG8gMSB5IGdyYWbDrWNhbG8gZW4gY29sb3Igcm9qbyDCv1F1w6kgc3VjZWRpw7M/DQo1LiDCv1F1w6kgY29uY2x1eWVzIGRlIHRvZG8gZXN0bz8NCg0KTGEgc3VjZXNpw7NuIGRlIEZpYm9uYWNjaSBlcyBsYSBzdWNlc2nDs24gZGUgbsO6bWVyb3M6DQowLCAgIDEsICAgMSwgICAyLCAgIDMsICAgNSwgICA4LCAgIDEzLCAgIDIxLCAgIDM0LCDigKYNCg0KRW4gZG9uZGUgY2FkYSBuw7ptZXJvIHNlIGNhbGN1bGEgc3VtYW5kbyBsb3MgZG9zIGFudGVyaW9yZXMgYSDDqWwuIFZhbW9zIGEgY3JlYXIgdW5hIGZ1bmNpw7NuIHF1ZSBjYWxjdWxlIGVsIGxvcyBuw7ptZXJvcyBkZSBGaWJvbmFjY2kNCg0KYGBge3J9DQpmaWJfbiA8LSBmdW5jdGlvbihuKSB7DQogICAgaWYobiA9PSAwKXsNCiAgICAgIHJldHVybigwKQ0KICAgIH1lbHNlIGlmKG4gPT0gMSl7DQogICAgICByZXR1cm4oMSkNCiAgICB9ZWxzZSBpZiAobiA9PSAyKSB7DQogICAgcmV0dXJuKDEpDQogICAgfWVsc2UgaWYobiA+IDIpew0KICAgIHJldHVybihmaWJfbihuIC0gMSkgKyBmaWJfbihuIC0gMikpDQogICAgfQ0KICB9DQpgYGANCkRlYmVtb3MgcmVjb3JkYXIgcXVlIG4gcmVwcmVzZW50YSBsYSBwb3NpY2nDs24gcXVlIGVsIG7Dum1lcm8gdGllbmUgZW4gbGEgc2VyaWUNCmBgYHtyfQ0KZmliX251bWJlciA8LSBmdW5jdGlvbihuKXsNCiAgeCA8LSBmaWJfbihuKQ0KICBwYXN0ZSgiRWwgIiwgbiwgIsKwIG7Dum1lcm8gZGUgRmlib25hY2NpIGVzICIsIHgpDQp9DQpgYGANClZlYW1vcyBzaSBwb2RlbW9zIG9idGVuZXIgbGFzIHByaW1lcmFzIDcgcG9zaWNpb25lcyBkZSBsb3MgbsO6bWVyb3MgZGUgRmlib25hY2NpDQpgYGB7cn0NCmZpYl9udW1iZXIoMCkNCg0KYGBgDQpgYGB7cn0NCmZpYl9udW1iZXIoMSkNCg0KYGBgDQpBaG9yYSBjYWxjdWxlbW9zIGVsIG7Dum1lcm8gw6F1cmVvIGEgcGFydGlyIGRlIGxhIHNpZ3VpZW50ZSBtYXRyaXoNCkE9KDExMTANCmBgYHtyfQ0KQSA8LSByYmluZChjKDEsMSksIGMoMSwwKSkgDQoNCmVpZ0EgPC0gZWlnZW4oQSkgI0xhIGZ1bmNpw7NuIGVpZ2VuKCkgY2FsY3VsYSBsb3MgZWlnZW52YWxvcmVzIHkgZWlnZW52ZWN0b3Jlcw0KDQplaWdBJHZhbHVlcyAjRWlnZW52YWxvcmVzIGRlIEENCmBgYA0KDQpgYGB7cn0NCm9ybyA8LSBlaWdBJHZhbHVlc1sxXQ0KDQpwYXN0ZSgiRWwgbsO6bWVybyDDoXVyZW8gZXMgZWwgZWlnZW52YWxvciBwb3NpdGl2byBkZSBsYSBtYXRyaXogQSwgZXMgZGVjaXIiLCBvcm8pDQoNCmBgYA0KQWhvcmEgdmFtb3MgYSBjcmVhciB1bmEgZnVuY2nDs24gcXVlIGdyYWZpcXVlIG4gZWxlbWVudG9zIGRlIGxhIHNlcmllIGRlIEZpYm9uYWNjaSwgbG9zIHB1bnRvcyB0ZW5kcsOhbiBjb29yZGVuYWRhcyAoRm4sIEZu4oiSMSkgeSBkZWJlbiBncmFmaWNhcnNlIGEgcGFydGlyIGRlIG49MSBwdWVzdG8gcXVlIGVsIG7Dum1lcm8gRjDiiJIxPUbiiJIxIG5vIGV4aXN0ZS4NCg0KU29icmUgZXN0YSBtaXNtYSBncsOhZmlhIGFncmVnYXJlbW9zIGVsIGVpZ2VudmVjdG9yIGNvcnJlc3BvbmRpZW50ZSBhbCBuw7ptZXJvIGRlIG9ybw0KYGBge3J9DQpncmFmaWNhX2ZpYiA8LSBmdW5jdGlvbihuKXsNCiAgeCA8LSBjKCkNCiAgeSA8LSBjKCkNCg0KICBmb3IoaSBpbiAxOm4pew0KICAgIHhbaV0gPC0gZmliX24oaSkNCiAgICB5W2ldIDwtIGZpYl9uKGktMSkgDQogIH0NCiAgDQogIHBsb3QoeCwgeSwgeGxhYiA9IGV4cHJlc3Npb24oIkYiW25dKSwgeWxhYiA9IGV4cHJlc3Npb24oIkYiW24tMV0pLCANCiAgICAgICBtYWluID0gcGFzdGUoIG4sICJOw7ptZXJvcyBkZSBGaWJvbmFjY2kgeSBlbCBlaWdlbnZlY3RvciIpLCBwY2ggPSAxOSkNCiAgYWJsaW5lKGEgPSAgMCwgYiA9IGVpZ0EkdmVjdG9yc1syLDFdL2VpZ0EkdmVjdG9yc1sxLDFdLCBjb2wgPSAiZmlyZWJyaWNrMiIpDQogIGFibGluZSh2ID0gKHNlcSgwLCAxMDAsIDIpKSwgY29sPSJsaWdodGdyYXkiLCBsdHk9ImRvdHRlZCIpDQogIGFibGluZShoID0gKHNlcSgwLCAxMDAsIDIpKSwgY29sPSJsaWdodGdyYXkiLCBsdHk9ImRvdHRlZCIpDQp9DQpgYGANClBhcmEgbj0xMCB2ZWFtb3MgY29tbyBzZXLDrWEgbnVlc3RyYSBncmFmaWNhDQpgYGB7cn0NCmdyYWZpY2FfZmliKDEwKQ0KDQpgYGANClZlYW1vcyBxdWUgcGFzYSBjdWFuZG8gbXVsdGlwbGljYW1vcyBhbGfDum4gcHVudG8gZGUgbG9zIGdyYWZpY2Fkb3MgYW50ZXJpb3JtZW50ZSAobSkgcG9yIGVsIG7Dum1lcm8gw6F1cmVvDQpgYGB7cn0NCiMgbiBlcyBwYXJhIGxhIGNhbnRpZGFkIGRlIHB1bnRvcyBhIGdyYWZpY2FyDQojIG0gZXMgcGFyYSBlbCBwdW50byBhIG11bHRpcGxpY2FyIHBvciBlbCBuw7ptZXJvIGRlIG9ybw0KZ3JhZl9uZXdQb2ludCA8LSBmdW5jdGlvbihuLCBtKXsgDQogIHggPC0gYygpDQogIHkgPC0gYygpDQogIA0KICBmb3IoaSBpbiAxOm4pew0KICAgIHhbaV0gPC0gZmliX24oaSkNCiAgICB5W2ldIDwtIGZpYl9uKGktMSkNCiAgfQ0KICANCiAgcG9pbnQgPC0gYyh4W21dLCB5W21dKQ0KICBuZXdfcG9pbnQgPC0gcG9pbnQgKiBvcm8NCiAgDQogIHBsb3QoeCwgeSwgeGxhYiA9IGV4cHJlc3Npb24oIkYiW25dKSwgeWxhYiA9IGV4cHJlc3Npb24oIkYiW24tMV0pLCANCiAgICAgIG1haW4gPSBwYXN0ZSgiRWwgbW92aW1pZW50byBkZWwgcHVudG8iLCBtKSwgcGNoID0gMTkpDQogIGxpbmVzKG5ld19wb2ludFsxXSwgbmV3X3BvaW50WzJdLCB0eXBlID0gInAiLCBwY2ggPSAxOCwgY29sID0gInJlZCIpDQogIGFibGluZShhID0gIDAsIGIgPSBlaWdBJHZlY3RvcnNbMiwxXS9laWdBJHZlY3RvcnNbMSwxXSwgY29sID0gImZpcmVicmljazIiKQ0KICBhYmxpbmUodiA9IChzZXEoMCwgMTAwLCAyKSksIGNvbD0ibGlnaHRncmF5IiwgbHR5PSJkb3R0ZWQiKQ0KICBhYmxpbmUoaCA9IChzZXEoMCwgMTAwLCAyKSksIGNvbD0ibGlnaHRncmF5IiwgbHR5PSJkb3R0ZWQiKQ0KfQ0KYGBgDQpFbiBtaSBjYXNvIHlvIHF1aWVybyBncmFmaWNhciAxMCBwdW50b3MgZGUgbGEgc3VjZWNpw7NuIGRlIEZpYm9uYWNjaSB5IHF1aWVybyBtdWx0aXBsaWNhciBlbCA5wrAgZWxlbWVudG8gcG9yIGVsIG7Dum1lcm8gZGUgb3JvDQoNCmBgYHtyfQ0KZ3JhZl9uZXdQb2ludCgxMCw5KQ0KDQpgYGANCkRlIGxhIGdyYWZpY2EgYW50ZXJpb3IgcG9kZW1vcyBjb25jbHVpciBxdWUgZWwgbsO6bWVybyDDoXVyZW8gZXMgbGEgcmF6w7NuIGRlIGNhbWJpbyBkZSBsYSBzdWNlc2nDs24gZGUgRmlib25hY2NpDQoNCg0KDQojIEl0ZXJhY2lvbmVzDQpFbiBsYSBtYXlvcsOtYSBkZSBjdXJzb3MgcXVlIGhheiB2aXN0byBzZSBoYSB0ZW5pZG8gdW5hIGdyYW4gY2FudGlkYWQgZGUgdGVvcsOtYSBzaW4gdmVyIGFsZ29yaXRtb3MgcXVlIHRlIHBlcm1pdGFuIGNvbXByb2JhciBkaWNoYXMgY29zYXMuIFZhbW9zIGEgYXJyZWdsYXIgdW4gcG9jbyBlc3RvIHkgY3JlYSBhbGd1bmEgZnVuY2nDs24gbyBtw6l0b2RvIGl0ZXJhdGl2byBwYXJhIGFwcm94aW1hciBsbyBzaWd1aWVudGUuIEVuIGNhZGEgdW5vIGRlIGxvcyBjYXNvcyBkYSB1biBlamVtcGxvIHBhcmEgY29tcHJvYmFyIGVsIGZ1bmNpb25hbWllbnRvIGRlIHR1IHNvbHVjacOzbi4NCg0KMS4gRGVyaXZhZGEuIFBhcmEgY29tcHJvYmFyIGRldGVybWluYSBzaSBsYSBkZXJpdmFkYSBkZSAkMngyJCBlbiBhbGfDum4gcHVudG8gc2UgYXByb3hpbWEgY29uIHR1IGZ1bmNpw7NuLg0KMi4gSW50ZWdyYWwuIFB1ZWRlcyB1c2FyIGZ1bmNpb25lcyBwb3NpdGl2YXMgcGFyYSBjb21wcm9iYXIgdHUgZnVuY2nDs24gdXRpbGl6YW5kbyBsYSBpbnRlcnByZXRhY2nDs24gZGUgbGEgaW50ZWdyYWwuDQozLiBQZXLDrW1ldHJvIGRlIHVuYSBjaXJjdW5mZXJlbmNpYS4gSW52ZXN0aWdhIHVuIHBvY28gc29icmUgbGEgcmVsYWNpw7NuIHF1ZSBleGlzdGUgZW50cmUgZWwgbsO6bWVybyBkZSBsYWRvcyBkZSB1biBwb2zDrWdvbm8gcmVndWxhciB5IHN1IHBlcsOtbWV0cm8sIGFzw60gY29tbyBsYSBsb25naXR1ZCBkZSBsb3MgbGFkb3MgZGUgdW4gcG9sw61nb25vIGluc2NyaXRvIGVuIHVuYSBjaXJjdW5mZXJlbmNpYSBkZSByYWRpbyByLiBDb24gZXN0byB0aWVuZXMgbGFzIGJhc2VzIHBhcmEgY3JlYXIgdW5hIGZ1bmNpw7NuLCBxdWUgZGUgYWN1ZXJkbyBhIHVuIG51bWVybyBkZSBsYWRvcyBuIHNlIHZheWEgYWNlcmNhbmRvIGFsIHBlcsOtbWV0cm8gZGUgdW5hIGNpcmN1bmZlcmVuY2lhLiBBbCBmaW5hbCBwdWVkZXMgY29tcHJvYmFyIHR1cyByZXN1bHRhZG9zIGNvbiBsYSBmb3JtdWxhIHlhIGNvbm9jaWRhLg0KDQojIFByb2Nlc2FtaWVudG8gZGUgdGV4dG9zDQpMYSBpZGVhIHNlcsOhIHNlbmNpbGxhIGF1bnF1ZSBsYSBpbXBsZW1lbnRhY2nDs24gbm8gbG8gc2Ug8J+ZiCwgcG9yIGxvIHF1ZSBwb2Ryw61hcyBvYnRlbmVyIG3DoXMgcmVzdWx0YWRvcyBkZSBsb3MgcXVlIGNvbG9jbyBhcXXDrS4gRGUgYWN1ZXJkbyBhIHVuIGFyY2hpdm8gLnR4dCBxdWUgc2UgdGUgc2Vyw6EgcHJvcG9yY2lvbmFkbyBkZXRlcm1pbmFyIGxvIHNpZ3VpZW50ZToNCg0KMS4gQ2FudGlkYWQgZGUgbGV0cmFzLg0KMi4gQ2FudGlkYWQgZGUgdm9jYWxlcy4NCjMuIENhbnRpZGFkIGRlIGVzcGFjaW9zLg0KNC4gUG9yY2VudGFqZSBxdWUgcmVwcmVzZW50YSBjYWRhIGxldHJhIGVuIGVsIHRleHRvLg0KDQpObyBpbXBvcnRhIHNpIGNvbnNpZGVyYXMgYSBsb3MgY2FyYWN0ZXJlcyBlc3BlY2lhbGVzIGNvbW8gbGV0cmFzIG8gbm8sIHRhbXBvY28gc2kgaGFjZXMgZGlzdGluY2nDs24gZW50cmUgbWF5w7pzY3VsYXMgeSBtaW7DunNjdWxhcywgbmkgdGFtcG9jbyBsYXMgdmVjZXMgcXVlIHRlbmdhcyBxdWUgY2FyZ2FyIGVsIGFyY2hpdm8uDQoNClBhcmEgZXN0ZSBlamVyY2ljaW8gcHJpbWVybyBkZWJlbW9zIGNhcmdhciBhbGd1bmFzIGxpYnJlcmlhcw0KDQpgYGB7cn0NCmxpYnJhcnkodG9rZW5pemVycykNCmxpYnJhcnkocmVhZHIpDQpsaWJyYXJ5KHdvcmRjbG91ZCkNCmxpYnJhcnkoZHBseXIpDQpsaWJyYXJ5KHJlYWRyKQ0KbGlicmFyeShnZ3Bsb3QyKQ0KbGlicmFyeShzdHJpbmdyKQ0KbGlicmFyeShleHRyYWZvbnQpDQpsaWJyYXJ5KHRtKQ0KbGlicmFyeShSQ29sb3JCcmV3ZXIpDQpgYGANCg0KUHJpbWVybyBkZWJlbW9zIGNhcmdhciBudWVzdHJvIGRvY3VtZW50bywgeSBoYWNlcmxlIHVuYSDigJxsaW1waWV6YeKAnSBjb24gZWwgZmluIGRlIGZhY2lsaXRhciBudWVzdHJvIGFuw6FsaXNpcw0KDQpgYGB7cn0NCkNhcmdhX2RvY3VtZW50byA8LSBmdW5jdGlvbihkb2N1bWVudG8pew0KDQogICNVdGlsaXphIGxhIGZ1bmNpw7NuIGZpbGUsIGNvbiBlbCBwYXLDoW1ldHJvIHIgKGRlICJyZWFkIiwgbGVlcikNCiAgbGVlcl9kb2N1bWVudG8gPC0gZmlsZShkb2N1bWVudG8sIG9wZW4gPSAiciIpDQoNCiAgI0FwbGljYSBsYSBmdW5jacOzbiByZWFkTGluZXMgcGFyYSBsZWVyIGxhcyBsw61uZWFzIGRlbCBhcmNoaXZvLCANCiAgI2bDrWphdGUgcXVlIGVsIGVuY29kaW5nIHNlYSBVVEYtOA0KICB0ZXh0b19saW5lYXMgPC0gcmVhZExpbmVzKGxlZXJfZG9jdW1lbnRvLCBlbmNvZGluZyA9ICJVVEYtOCIpDQoNCiAgI0p1bnRhIHRvZGFzIGxhcyBsaW5lYXMgKHDDoXJyYWZvcykgZW4gdW5vIHNvbG8NCiAgdGV4dG9fY29tcGxldG8gPC0gcGFzdGUodGV4dG9fbGluZWFzLCBjb2xsYXBzZSA9ICJcbiIpDQogIA0KICAjUmV0aXJlbW9zIGxvcyBzaWdub3MgZGUgcHVudHVhY2nDs24NCiAgdGV4dG9fc2luU2lnbm9zIDwtIHJlbW92ZVB1bmN0dWF0aW9uKHRleHRvX2NvbXBsZXRvKQ0KDQogICNWYW1vcyBhIGNhbWJpYXIgbG9zICJcbiIgcXVlIHJlcHJlc2VudGFuIGxvcyBzYWx0b3MgZGUgbGluZWEgcG9yIGVzcGFjaW9zIGVuIGJsYW5jbw0KICB0ZXh0b19TaW5TYWx0b3MgPC0gc3RyX3JlcGxhY2VfYWxsKHRleHRvX3NpblNpZ25vcywgIlxuIiwgIiAiKQ0KDQogICNWYW1vcyBhIGVsaW1pbmFyIGxvcyBlc3BhY2lvcyBlbiBibGFuY28gbcO6bHRpcGxlcw0KICB0ZXh0b19TaW5Fc3BhY2lvcyA8LSBzdHJfcmVwbGFjZV9hbGwodGV4dG9fU2luU2FsdG9zLCAiW1xcc10rIiwgIiAiKQ0KfQ0KDQpgYGANCg0KZG9jdW1lbnRvIDwtICJSb21lb19hbmRfSnVsaWV0LnR4dCINCg0KQ2FyZ2FfZG9jdW1lbnRvKGRvY3VtZW50bylgYGB7cn0NCg0KYGBgDQoNCiMgVGVvcmVtYSBjZW50cmFsIGRlbCBsw61taXRlDQpFcyBiaWVuIGNvbm9jaWRvIGVsIHRlb3JlbWEgcXVlIGFib3JkYW1vcyBlbiBlc3RlIGVqZXJjaWNpbyB5IHPDs2xvIHBhcmEgcmVjb3JkYXIsIHNpICRYX3sxfSxYX3syfSzigKYkIGVzIHVuYSBzdWNlc2nDs24gZGUgdmFyaWFibGVzIGFsZWF0b3JpYXMgaW5kZXBlbmRpZW50ZXMgZSBpZMOpbnRpY2FtZW50ZSBkaXN0cmlidWlkYXMsIGNvbiBtZWRpYSAkzrwkIHkgdmFyaWFuemEgZmluaXRhICTPgzIkLCBsYSBmdW5jacOzbiBkZSBkaXN0cmlidWNpw7NuIGRlIGxhIHZhcmlhYmxlIGFsZWF0b3JpYSAkWiQgZGVzY3JpdGEgcG9yDQokJFo9XGZyYWN7XGxlZnQoWF97MX0rXGNkb3RzK1hfe259XHJpZ2h0KS1uIFxtdX17XHNxcnR7biBcc2lnbWFeezJ9fX0kJA0KdGllbmRlIGEgbGEgZnVuY2nDs24gZGUgZGlzdHJpYnVjacOzbiBub3JtYWwgZXN0w6FuZGFyIGN1YW5kbyAkbuKGkuKIniQuIEVudG9uY2VzLCB0dSBvYmpldGl2byBzZXLDoSBjcmVhciB1bmEgZnVuY2nDs24gcXVlLCBkZSBhY3VlcmRvIGEgdW5hIGRpc3RyaWJ1Y2nDs24gKHB1ZWRlbiBzZXIgdGFudGFzIGNvbW8gY29ub3pjYXMpIHF1ZSBzZWFuIGFkYXB0YWJsZXMgYSBsYXMgY29uZGljaW9uZXMgZGVsIHRlb3JlbWEsIGluY2x1eWVuZG8gY29tbyBwYXLDoW1ldHJvcyBkZSBsYSBmdW5jacOzbiBsYSBtZWRpYSB5IGxhIHZhcmlhbnphIGRlIGRpY2hhIGRpc3RyaWJ1Y2nDs24geSB1bmEgbiwgc2UgY3JlZW4gc2ltdWxhY2lvbmVzIGRlIGRpY2hhIGRpc3RyaWJ1Y2nDs24sIGFsIGlndWFsIHF1ZSBsYSB2LmEuICRaJC4gRmluYWxtZW50ZSBzZSB0aWVuZSBxdWUgZGFyIGxhcyBncsOhZmljYXMgZGUgcHJvYmFiaWxpZGFkIGFjdW11bGFkYSB5IGRlIGRlbnNpZGFkIGNvcnJlc3BvbmRpZW50ZSAocHVlZGVzIGd1YXJkYXIgdG9kbyBlbiB1bmEgbGlzdGEpLiBBbCBmaW5hbCwgY29uIHVuIG4gZ3JhbmRlIGRhZG8gZW4gbGEgZnVuY2nDs24sIHNlIGRlYmVyw61hIHBvZGVyIHZlciB1bmEg4oCcY29tcHJvYmFjacOzbiB2aXN1YWwgZGUgZGljaG8gdGVvcmVtYeKAnS4NCg0KU3VlcnRlISBPamFsYSBxdWUgbm8gbGEgbmVjZXNpdGVzIPCfpK0NCg==