Ejemplo 2.1

Datos

En primer lugar construimos los datos (realización de observar la variable aleatoria X/variable en los individuos de la muestra).

# Crear un vector vacío
v_individuos <- c()

# Añadir elementos al vector
for (i in 1:34) {
  v_individuos[i] <- i
}

# Crear un vector con los niveles
v_nivel <- c(10.6, 12.5, 11.1, 9.2, 11.5, 9.9, 11.9, 11.6, 14.9, 12.5,
             12.5, 12.3, 12.2, 10.8, 16.5, 15.0, 10.3, 12.4, 9.1, 7.8,
             11.3, 12.3, 9.7, 12.0, 11.8, 12.7, 11.4, 9.3, 8.6, 8.5,
             10.1, 12.4, 11.1, 10.2
             )

# Crear una estructura de data frame
df_2_1 <- data.frame(Individuo = v_individuos, 
                     Nivel = v_nivel
                     )

# Veamos la matriz de datos
df_2_1
NA

Población, individuos, muestra

El fenómeno aleatorio es el nivel de colinesterasa.

La población son todos los agricultores (de una zona geográfica, o edad, o cualquier otra premisa, indeterminada en cualquier caso) que usan colinesterasa.

El número de individuos en la población es desconocido. Normalmente no sabremos el número de individuos de una población.

El número de individuos en la muestra son 34 agricultores. Asumimos que la muestra es una muestra representativa, es decir, que representa la población de forma acertada. Si asumimos que la población es homogénea y que la selección de los individuos de la muestra se ha echo al azar, entonces podemos considerar que la muestra es representativa.

Variable aleatoria y modelo probabilístico

La variable aleatoria es el nivel de colinesterasa.

Los caracteres que observamos en este ejercicio son: el identificador del individuo (que realmente no tiene otro valor más que el de identificar al individuo de forma única) y el nivel de colinesterasa (que además es la variable aleatoria X).

El parámetro o parámetro poblacional (la característica) de la población que queremos determinar es el nivel de colinesterasa media. La variable, o variable aleatoria X, que utilizamos en este ejercicio es el nivel de colinesterasa en los individuos de la muestra.

El carácter “nivel de colinesterasa” es de tipo cuantitativo.

Conceptos fundamentales de la estadística descriptiva

Las modalidades del caracter no tienen mucho sentido en este caso. Los valores repetidos en este caso no tienen mucho sentido.

# Primero calculamos la frecuencia total. Para ello, en este ejercicio, 
# calculamos cuantos elementos tiene el vector con los individuos de la muestra.
n <- length(v_nivel)

# En este ejercicio las modalidades son los valores únicos de la variable, el 
# carácter "nivel".
# Además, (no es neceario pero) vamos a presentar las modalidades de forma 
# ordenada.
modalidades <- sort(unique(v_nivel))
numero_de_modalidades <- length(modalidades)
print(paste("La muestra tiene", n, "individuos y", numero_de_modalidades, "modalidades."))
[1] "La muestra tiene 34 individuos y 29 modalidades."
print("Las modalidades son:")
[1] "Las modalidades son:"
print(modalidades)
 [1]  7.8  8.5  8.6  9.1  9.2  9.3  9.7  9.9 10.1 10.2 10.3 10.6 10.8 11.1 11.3 11.4 11.5 11.6 11.8 11.9 12.0 12.2
[23] 12.3 12.4 12.5 12.7 14.9 15.0 16.5

La matriz de datos es esta:

df_2_1

En este ejercicio no hay clases de datos ya que los datos no se presentan agrupados. Las clases son agrupamientos de valores en intervalos.

Si quisieramos presentar los datos agrupados en intervalos/clases ¿En cuantos intervalos/clases separamos los datos? -> Aplicamos la forma de Sturges.

¿Y cuales serían los intervalos?

# Si "n" es la frecuencia total, el número de intervalos según la fórmula de
# Sturges es:
k <- 1 + 3.322*log10(n)
print(paste("El número de intervalos según la fórmula de Sturges es", k))
[1] "El número de intervalos según la fórmula de Sturges es 6.08757296241437"
k_int <- round(k, digits = 0)
k_int <- ceiling(k)
print(paste("que redondeamos a", k_int, "intervalos."))
[1] "que redondeamos a 7 intervalos."
cat("\n")
# Veamos los intervalos
# calculamos las modalidades mínima y máxima
mod_min <- min(v_nivel)
mod_max <- max(v_nivel)
# y las redondeamos
mod_min_int <- floor(mod_min)
mod_max_int <- ceiling(mod_max)
print(paste("Para cubrir las modalidades desde", mod_min, "hasta", mod_max))
[1] "Para cubrir las modalidades desde 7.8 hasta 16.5"
print(paste("primero las redondeamos. La mímina hacia abajo", mod_min_int, "y la máxima hacia arriva", mod_max_int))
[1] "primero las redondeamos. La mímina hacia abajo 7 y la máxima hacia arriva 17"
cat("\n")
print(paste("Ahora calculamos la amplitud de los intervalos."))
[1] "Ahora calculamos la amplitud de los intervalos."
amplitud_intervalos <- (mod_max - mod_min)/k_int
amplitud_intervalos_int <- (mod_max_int - mod_min_int)/k_int
# edondear hacia arriva en intervalos de 0.5
amplitud_intervalos_int <- ceiling(amplitud_intervalos) - 0.5
#amplitud_intervalos_int <- amplitud_intervalos
print(paste("Entonces la amplitud de los intervalos es:", amplitud_intervalos, ", que redondeamos a", amplitud_intervalos_int))
[1] "Entonces la amplitud de los intervalos es: 1.24285714285714 , que redondeamos a 1.5"
cat("\n")
# Veamos los intervalos
print(paste("Finalmente, veamos los intervalos"))
[1] "Finalmente, veamos los intervalos"
intervalo_valor_inicial <- mod_min_int
for (i in 1:k_int) {
  intervalo_valor_final <- intervalo_valor_inicial + amplitud_intervalos_int
  print(paste("El intervalo", i, "va desde", intervalo_valor_inicial, "hasta", intervalo_valor_final))
  intervalo_valor_inicial <- intervalo_valor_final
}
[1] "El intervalo 1 va desde 7 hasta 8.5"
[1] "El intervalo 2 va desde 8.5 hasta 10"
[1] "El intervalo 3 va desde 10 hasta 11.5"
[1] "El intervalo 4 va desde 11.5 hasta 13"
[1] "El intervalo 5 va desde 13 hasta 14.5"
[1] "El intervalo 6 va desde 14.5 hasta 16"
[1] "El intervalo 7 va desde 16 hasta 17.5"

Distribuciones unidimensionales

Vamos a construir las distribuciones de frecuencias absoluta, relativa, absoluta acumulada y relativa acumulada.

# Distribución de frecuencias absolutas
# Tomamos SOLO la columna de los Niveles e instruimos a R que nos de la table de
# los valores únicos en ella y el número de instancias de cada una (frecuencias
# absolutas)
df_dd <- as.data.frame(table(df_2_1$Nivel))

# a la columna de las modalidades la llamamos "X_i" porque las modalidades son
# del tipo cuantitativo.
colnames(df_dd) <- c("X_i", "n_i")



# Distribución de frecuencias relativas
f_i <- c()
for (i in 1:length(df_dd$modalidad)) {
  f_i[i] <- df_dd$n_i[i]/n
  print(f_i[i])
}
df_dd$f_i <- f_i
# validar que la suma de todos los elementos es 1

# Distribución de frecuencias absolutas acumuladas
seed <- 0
N_i <- c()
for (i in 1:length(df_dd$modalidad)) {
  N_i[i] <- df_dd$n_i[i] + seed
  seed <- N_i[i]
}
df_dd$N_i <- N_i


# Distribución de frecuencias relativas acumuladas
seed <- 0
F_i <- c()
for (i in 1:length(df_dd$modalidad)) {
  F_i[i] <- df_dd$f_i[i] + seed
  seed <- F_i[i]
}
df_dd$F_i <- F_i

# Veamos todas las distribuciones de frecuencias
df_dd

Medidas de tendencia central de caracteres cuantitativos

# función nativa
a <- mean(df_2_1$Nivel)

sumatorio <- as.numeric(0)
for (i in 1:length(df_dd$modalidad)) {
  mod_by_n_i <- as.numeric(df_dd$modalidad[i]) * as.numeric(df_dd$n_i[i])
  sumatorio <- sumatorio + mod_by_n_i 
}
media <- sumatorio/n

suma <- as.numeric(0)
for (i in 1:length(df_2_1$Individuo)) {
  suma <- suma + df_2_1$Nivel
}
media <- suma/n

print(paste("La media aritmética es", a))
[1] "La media aritmética es 11.3529411764706"
print(paste("La media aritmética es", media))
 [1] "La media aritmética es 10.6"            
 [2] "La media aritmética es 12.5"            
 [3] "La media aritmética es 11.1"            
 [4] "La media aritmética es 9.19999999999999"
 [5] "La media aritmética es 11.5"            
 [6] "La media aritmética es 9.9"             
 [7] "La media aritmética es 11.9"            
 [8] "La media aritmética es 11.6"            
 [9] "La media aritmética es 14.9"            
[10] "La media aritmética es 12.5"            
[11] "La media aritmética es 12.5"            
[12] "La media aritmética es 12.3"            
[13] "La media aritmética es 12.2"            
[14] "La media aritmética es 10.8"            
[15] "La media aritmética es 16.5"            
[16] "La media aritmética es 15"              
[17] "La media aritmética es 10.3"            
[18] "La media aritmética es 12.4"            
[19] "La media aritmética es 9.1"             
[20] "La media aritmética es 7.8"             
[21] "La media aritmética es 11.3"            
[22] "La media aritmética es 12.3"            
[23] "La media aritmética es 9.69999999999999"
[24] "La media aritmética es 12"              
[25] "La media aritmética es 11.8"            
[26] "La media aritmética es 12.7"            
[27] "La media aritmética es 11.4"            
[28] "La media aritmética es 9.30000000000001"
[29] "La media aritmética es 8.6"             
[30] "La media aritmética es 8.5"             
[31] "La media aritmética es 10.1"            
[32] "La media aritmética es 12.4"            
[33] "La media aritmética es 11.1"            
[34] "La media aritmética es 10.2"            

Medidas de dispersión

recorrido <- (mod_max - mod_min)
print(paste("El recorrido es", recorrido))
[1] "El recorrido es 8.7"
S_sqr <- var(df_2_1$Nivel)
print(paste("La cuasivarianza es", S_sqr))
[1] "La cuasivarianza es 3.51408199643494"
s_sqr <- S_sqr * (n -1)/n
print(paste("La varianza es", s_sqr))
[1] "La varianza es 3.41072664359862"
S <- sqrt(S_sqr)
print(paste("La cuasidesviación típica es", S))
[1] "La cuasidesviación típica es 1.87458848722458"
s <- sqrt(s_sqr)
print(paste("La desviación típica es", s))
[1] "La desviación típica es 1.84681527056677"
boxplot(df_2_1$Nivel)


summary(df_2_1$Nivel)
   Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
   7.80   10.12   11.45   11.35   12.38   16.50 

Ejemplo 2.9

# Crear vectores con los individuos y las observaciones de la característica/
# variable estadística
v_horas <- c(21, 32, 15, 40, 27, 
             18, 26, 50, 33, 51, 
             36, 16, 19, 22, 16, 
             39, 56, 29, 45, 25)
v_marcas <- c(13.2, 12.6, 13, 12.2, 15,
             14.8, 14.8, 12.2, 13.6, 12.6,
             13.1, 14.9, 13.9, 13.2, 15.1,
             14.1, 13, 13.5, 12.7, 14.2)

# Crear una estructura del tipo data frame
df_2_9 <- data.frame(horas = v_horas,
                     marcas = v_marcas)

# Veamos la matriz de datos
df_2_9
# Gráfica de los datos en forma de nube de puntos
plot(df_2_9$horas, df_2_9$marcas,
     xlab = "horas de entrenamiento",
     ylab = "marca",
     main = "nube de puntos")

ajus <- lm(df_2_9$marcas~df_2_9$horas)
ajus

Call:
lm(formula = df_2_9$marcas ~ df_2_9$horas)

Coefficients:
 (Intercept)  df_2_9$horas  
    15.05908      -0.04786  
# añade la recta de regresión a la nube de puntos
abline(ajus)

# añade un rótulo
legend(42, 14, 
       c("línea de regresión"),
       lty = c(1))

# El coeficiente de correlación de Pearson 
r <- cor(df_2_9$horas, df_2_9$marcas)
r_r <- round(r, digits = 2)

print(paste("El coeficiente de correlación lineal de Pearson es:", r_r))
[1] "El coeficiente de correlación lineal de Pearson es: -0.63"
LS0tCnRpdGxlOiAiQ2Fww610dWxvIDIuIEVzdGFkw61zdGljYSBkZXNjcmlwdGl2YSIKb3V0cHV0OiBodG1sX25vdGVib29rCi0tLQoKIyBFamVtcGxvIDIuMQoKIyMgRGF0b3MKRW4gcHJpbWVyIGx1Z2FyIGNvbnN0cnVpbW9zIGxvcyAqZGF0b3MqIChyZWFsaXphY2nDs24gZGUgb2JzZXJ2YXIgbGEgKnZhcmlhYmxlIAphbGVhdG9yaWEgWCovKnZhcmlhYmxlKiBlbiBsb3MgaW5kaXZpZHVvcyBkZSBsYSBtdWVzdHJhKS4KCmBgYHtyfQojIENyZWFyIHVuIHZlY3RvciB2YWPDrW8Kdl9pbmRpdmlkdW9zIDwtIGMoKQoKIyBBw7FhZGlyIGVsZW1lbnRvcyBhbCB2ZWN0b3IKZm9yIChpIGluIDE6MzQpIHsKICB2X2luZGl2aWR1b3NbaV0gPC0gaQp9CgojIENyZWFyIHVuIHZlY3RvciBjb24gbG9zIG5pdmVsZXMKdl9uaXZlbCA8LSBjKDEwLjYsIDEyLjUsIDExLjEsIDkuMiwgMTEuNSwgOS45LCAxMS45LCAxMS42LCAxNC45LCAxMi41LAogICAgICAgICAgICAgMTIuNSwgMTIuMywgMTIuMiwgMTAuOCwgMTYuNSwgMTUuMCwgMTAuMywgMTIuNCwgOS4xLCA3LjgsCiAgICAgICAgICAgICAxMS4zLCAxMi4zLCA5LjcsIDEyLjAsIDExLjgsIDEyLjcsIDExLjQsIDkuMywgOC42LCA4LjUsCiAgICAgICAgICAgICAxMC4xLCAxMi40LCAxMS4xLCAxMC4yCiAgICAgICAgICAgICApCgojIENyZWFyIHVuYSBlc3RydWN0dXJhIGRlbCB0aXBvIGRhdGEgZnJhbWUKZGZfMl8xIDwtIGRhdGEuZnJhbWUoSW5kaXZpZHVvID0gdl9pbmRpdmlkdW9zLCAKICAgICAgICAgICAgICAgICAgICAgTml2ZWwgPSB2X25pdmVsCiAgICAgICAgICAgICAgICAgICAgICkKCiMgVmVhbW9zIGxhIG1hdHJpeiBkZSBkYXRvcwpkZl8yXzEKYGBgCiMjIFBvYmxhY2nDs24sIGluZGl2aWR1b3MsIG11ZXN0cmEKCkVsICpmZW7Ds21lbm8gYWxlYXRvcmlvKiBlcyBlbCBuaXZlbCBkZSBjb2xpbmVzdGVyYXNhLgoKTGEgKnBvYmxhY2nDs24qIHNvbiB0b2RvcyBsb3MgYWdyaWN1bHRvcmVzIChkZSB1bmEgem9uYSBnZW9ncsOhZmljYSwgbyBlZGFkLCBvCmN1YWxxdWllciBvdHJhIHByZW1pc2EsIGluZGV0ZXJtaW5hZGEgZW4gY3VhbHF1aWVyIGNhc28pIHF1ZSB1c2FuIGNvbGluZXN0ZXJhc2EuCgpFbCBuw7ptZXJvIGRlICppbmRpdmlkdW9zKiBlbiBsYSBwb2JsYWNpw7NuIGVzIGRlc2Nvbm9jaWRvLiBOb3JtYWxtZW50ZSBubwpzYWJyZW1vcyBlbCBuw7ptZXJvIGRlIGluZGl2aWR1b3MgZGUgdW5hIHBvYmxhY2nDs24uCgpFbCBuw7ptZXJvIGRlIGluZGl2aWR1b3MgZW4gbGEgKm11ZXN0cmEqIHNvbiAzNCBhZ3JpY3VsdG9yZXMuIEFzdW1pbW9zIHF1ZSBsYSAKbXVlc3RyYSBlcyB1bmEgKm11ZXN0cmEgcmVwcmVzZW50YXRpdmEqLCBlcyBkZWNpciwgcXVlIHJlcHJlc2VudGEgbGEgcG9ibGFjacOzbiAKZGUgZm9ybWEgYWNlcnRhZGEuIFNpIGFzdW1pbW9zIHF1ZSBsYSBwb2JsYWNpw7NuIGVzIGhvbW9nw6luZWEgeSBxdWUgbGEgc2VsZWNjacOzbiAKZGUgbG9zIGluZGl2aWR1b3MgZGUgbGEgbXVlc3RyYSBzZSBoYSBlY2hvIGFsIGF6YXIsIGVudG9uY2VzIHBvZGVtb3MgY29uc2lkZXJhciAKcXVlIGxhIG11ZXN0cmEgZXMgcmVwcmVzZW50YXRpdmEuCgoKIyMgVmFyaWFibGUgYWxlYXRvcmlhIHkgbW9kZWxvIHByb2JhYmlsw61zdGljbwpMYSAqdmFyaWFibGUgYWxlYXRvcmlhKiBlcyBlbCBuaXZlbCBkZSBjb2xpbmVzdGVyYXNhLiAKCkxvcyAqY2FyYWN0ZXJlcyogcXVlIG9ic2VydmFtb3MgZW4gZXN0ZSBlamVyY2ljaW8gc29uOiBlbCBpZGVudGlmaWNhZG9yIGRlbCAKaW5kaXZpZHVvIChxdWUgcmVhbG1lbnRlIG5vIHRpZW5lIG90cm8gdmFsb3IgbcOhcyBxdWUgZWwgZGUgaWRlbnRpZmljYXIgYWwgCmluZGl2aWR1byBkZSBmb3JtYSDDum5pY2EpIHkgZWwgbml2ZWwgZGUgY29saW5lc3RlcmFzYSAocXVlIGFkZW3DoXMgZXMgbGEgCnZhcmlhYmxlIGFsZWF0b3JpYSBYKS4KCkVsICpwYXLDoW1ldHJvKiBvICpwYXLDoW1ldHJvIHBvYmxhY2lvbmFsKiAobGEgY2FyYWN0ZXLDrXN0aWNhKSBkZSBsYSBwb2JsYWNpw7NuIHF1ZQpxdWVyZW1vcyBkZXRlcm1pbmFyIGVzIGVsIG5pdmVsIGRlIGNvbGluZXN0ZXJhc2EgbWVkaWEuIExhICp2YXJpYWJsZSosIG8gCip2YXJpYWJsZSBhbGVhdG9yaWEgWCosIHF1ZSB1dGlsaXphbW9zIGVuIGVzdGUgZWplcmNpY2lvIGVzIGVsIG5pdmVsIGRlIApjb2xpbmVzdGVyYXNhIGVuIGxvcyBpbmRpdmlkdW9zIGRlIGxhIG11ZXN0cmEuCgpFbCBjYXLDoWN0ZXIgIm5pdmVsIGRlIGNvbGluZXN0ZXJhc2EiIGVzIGRlIHRpcG8gKmN1YW50aXRhdGl2byouCgoKIyMgQ29uY2VwdG9zIGZ1bmRhbWVudGFsZXMgZGUgbGEgZXN0YWTDrXN0aWNhIGRlc2NyaXB0aXZhCgpMYXMgKm1vZGFsaWRhZGVzKiBkZWwgY2FyYWN0ZXIgbm8gdGllbmVuIG11Y2hvIHNlbnRpZG8gZW4gZXN0ZSBjYXNvLiBMb3MgdmFsb3JlcwogcmVwZXRpZG9zIGVuIGVzdGUgY2FzbyBubyB0aWVuZW4gbXVjaG8gc2VudGlkby4KYGBge3J9CiMgUHJpbWVybyBjYWxjdWxhbW9zIGxhIGZyZWN1ZW5jaWEgdG90YWwuIFBhcmEgZWxsbywgZW4gZXN0ZSBlamVyY2ljaW8sIAojIGNhbGN1bGFtb3MgY3VhbnRvcyBlbGVtZW50b3MgdGllbmUgZWwgdmVjdG9yIGNvbiBsb3MgaW5kaXZpZHVvcyBkZSBsYSBtdWVzdHJhLgpuIDwtIGxlbmd0aCh2X25pdmVsKQoKIyBFbiBlc3RlIGVqZXJjaWNpbyBsYXMgbW9kYWxpZGFkZXMgc29uIGxvcyB2YWxvcmVzIMO6bmljb3MgZGUgbGEgdmFyaWFibGUsIGVsIAojIGNhcsOhY3RlciAibml2ZWwiLgojIEFkZW3DoXMsIChubyBlcyBuZWNlYXJpbyBwZXJvKSB2YW1vcyBhIHByZXNlbnRhciBsYXMgbW9kYWxpZGFkZXMgZGUgZm9ybWEgCiMgb3JkZW5hZGEuCm1vZGFsaWRhZGVzIDwtIHNvcnQodW5pcXVlKHZfbml2ZWwpKQpudW1lcm9fZGVfbW9kYWxpZGFkZXMgPC0gbGVuZ3RoKG1vZGFsaWRhZGVzKQpwcmludChwYXN0ZSgiTGEgbXVlc3RyYSB0aWVuZSIsIG4sICJpbmRpdmlkdW9zIHkiLCBudW1lcm9fZGVfbW9kYWxpZGFkZXMsICJtb2RhbGlkYWRlcy4iKSkKcHJpbnQoIkxhcyBtb2RhbGlkYWRlcyBzb246IikKcHJpbnQobW9kYWxpZGFkZXMpCmBgYAoKTGEgbWF0cml6IGRlIGRhdG9zIGVzIGVzdGE6CmBgYHtyfQpkZl8yXzEKYGBgCgpFbiBlc3RlIGVqZXJjaWNpbyBubyBoYXkgKmNsYXNlcyBkZSBkYXRvcyogeWEgcXVlIGxvcyBkYXRvcyBubyBzZSBwcmVzZW50YW4KYWdydXBhZG9zLiBMYXMgY2xhc2VzIHNvbiBhZ3J1cGFtaWVudG9zIGRlIHZhbG9yZXMgZW4gaW50ZXJ2YWxvcy4gCgpTaSBxdWlzaWVyYW1vcyBwcmVzZW50YXIgbG9zIGRhdG9zIGFncnVwYWRvcyBlbiBpbnRlcnZhbG9zL2NsYXNlcyDCv0VuIGN1YW50b3MgCmludGVydmFsb3MvY2xhc2VzIHNlcGFyYW1vcyBsb3MgZGF0b3M/IC0+IEFwbGljYW1vcyBsYSBmb3JtYSBkZSBTdHVyZ2VzLgoKwr9ZIGN1YWxlcyBzZXLDrWFuIGxvcyBpbnRlcnZhbG9zPwoKYGBge3J9CiMgU2kgIm4iIGVzIGxhIGZyZWN1ZW5jaWEgdG90YWwsIGVsIG7Dum1lcm8gZGUgaW50ZXJ2YWxvcyBzZWfDum4gbGEgZsOzcm11bGEgZGUKIyBTdHVyZ2VzIGVzOgprIDwtIDEgKyAzLjMyMipsb2cxMChuKQpwcmludChwYXN0ZSgiRWwgbsO6bWVybyBkZSBpbnRlcnZhbG9zIHNlZ8O6biBsYSBmw7NybXVsYSBkZSBTdHVyZ2VzIGVzIiwgaykpCmtfaW50IDwtIHJvdW5kKGssIGRpZ2l0cyA9IDApCmtfaW50IDwtIGNlaWxpbmcoaykKcHJpbnQocGFzdGUoInF1ZSByZWRvbmRlYW1vcyBhIiwga19pbnQsICJpbnRlcnZhbG9zLiIpKQpjYXQoIlxuIikKCiMgVmVhbW9zIGxvcyBpbnRlcnZhbG9zCiMgY2FsY3VsYW1vcyBsYXMgbW9kYWxpZGFkZXMgbcOtbmltYSB5IG3DoXhpbWEKbW9kX21pbiA8LSBtaW4odl9uaXZlbCkKbW9kX21heCA8LSBtYXgodl9uaXZlbCkKIyB5IGxhcyByZWRvbmRlYW1vcwptb2RfbWluX2ludCA8LSBmbG9vcihtb2RfbWluKQptb2RfbWF4X2ludCA8LSBjZWlsaW5nKG1vZF9tYXgpCnByaW50KHBhc3RlKCJQYXJhIGN1YnJpciBsYXMgbW9kYWxpZGFkZXMgZGVzZGUiLCBtb2RfbWluLCAiaGFzdGEiLCBtb2RfbWF4KSkKcHJpbnQocGFzdGUoInByaW1lcm8gbGFzIHJlZG9uZGVhbW9zLiBMYSBtw61taW5hIGhhY2lhIGFiYWpvIiwgbW9kX21pbl9pbnQsICJ5IGxhIG3DoXhpbWEgaGFjaWEgYXJyaXZhIiwgbW9kX21heF9pbnQpKQpjYXQoIlxuIikKCgpwcmludChwYXN0ZSgiQWhvcmEgY2FsY3VsYW1vcyBsYSBhbXBsaXR1ZCBkZSBsb3MgaW50ZXJ2YWxvcy4iKSkKYW1wbGl0dWRfaW50ZXJ2YWxvcyA8LSAobW9kX21heCAtIG1vZF9taW4pL2tfaW50CmFtcGxpdHVkX2ludGVydmFsb3NfaW50IDwtIChtb2RfbWF4X2ludCAtIG1vZF9taW5faW50KS9rX2ludAojIGVkb25kZWFyIGhhY2lhIGFycml2YSBlbiBpbnRlcnZhbG9zIGRlIDAuNQphbXBsaXR1ZF9pbnRlcnZhbG9zX2ludCA8LSBjZWlsaW5nKGFtcGxpdHVkX2ludGVydmFsb3MpIC0gMC41CiNhbXBsaXR1ZF9pbnRlcnZhbG9zX2ludCA8LSBhbXBsaXR1ZF9pbnRlcnZhbG9zCnByaW50KHBhc3RlKCJFbnRvbmNlcyBsYSBhbXBsaXR1ZCBkZSBsb3MgaW50ZXJ2YWxvcyBlczoiLCBhbXBsaXR1ZF9pbnRlcnZhbG9zLCAiLCBxdWUgcmVkb25kZWFtb3MgYSIsIGFtcGxpdHVkX2ludGVydmFsb3NfaW50KSkKY2F0KCJcbiIpCgojIFZlYW1vcyBsb3MgaW50ZXJ2YWxvcwpwcmludChwYXN0ZSgiRmluYWxtZW50ZSwgdmVhbW9zIGxvcyBpbnRlcnZhbG9zIikpCmludGVydmFsb192YWxvcl9pbmljaWFsIDwtIG1vZF9taW5faW50CmZvciAoaSBpbiAxOmtfaW50KSB7CiAgaW50ZXJ2YWxvX3ZhbG9yX2ZpbmFsIDwtIGludGVydmFsb192YWxvcl9pbmljaWFsICsgYW1wbGl0dWRfaW50ZXJ2YWxvc19pbnQKICBwcmludChwYXN0ZSgiRWwgaW50ZXJ2YWxvIiwgaSwgInZhIGRlc2RlIiwgaW50ZXJ2YWxvX3ZhbG9yX2luaWNpYWwsICJoYXN0YSIsIGludGVydmFsb192YWxvcl9maW5hbCkpCiAgaW50ZXJ2YWxvX3ZhbG9yX2luaWNpYWwgPC0gaW50ZXJ2YWxvX3ZhbG9yX2ZpbmFsCn0KYGBgCgojIyBEaXN0cmlidWNpb25lcyB1bmlkaW1lbnNpb25hbGVzClZhbW9zIGEgY29uc3RydWlyIGxhcyBkaXN0cmlidWNpb25lcyBkZSBmcmVjdWVuY2lhcyBhYnNvbHV0YSwgcmVsYXRpdmEsIAphYnNvbHV0YSBhY3VtdWxhZGEgeSByZWxhdGl2YSBhY3VtdWxhZGEuCmBgYHtyfQojIERpc3RyaWJ1Y2nDs24gZGUgZnJlY3VlbmNpYXMgYWJzb2x1dGFzCiMgVG9tYW1vcyBTT0xPIGxhIGNvbHVtbmEgZGUgbG9zIE5pdmVsZXMgZSBpbnN0cnVpbW9zIGEgUiBxdWUgbm9zIGRlIGxhIHRhYmxlIGRlCiMgbG9zIHZhbG9yZXMgw7puaWNvcyBlbiBlbGxhIHkgZWwgbsO6bWVybyBkZSBpbnN0YW5jaWFzIGRlIGNhZGEgdW5hIChmcmVjdWVuY2lhcwojIGFic29sdXRhcykKZGZfZGQgPC0gYXMuZGF0YS5mcmFtZSh0YWJsZShkZl8yXzEkTml2ZWwpKQoKIyBhIGxhIGNvbHVtbmEgZGUgbGFzIG1vZGFsaWRhZGVzIGxhIGxsYW1hbW9zICJYX2kiIHBvcnF1ZSBsYXMgbW9kYWxpZGFkZXMgc29uCiMgZGVsIHRpcG8gY3VhbnRpdGF0aXZvLgpjb2xuYW1lcyhkZl9kZCkgPC0gYygiWF9pIiwgIm5faSIpCgoKCiMgRGlzdHJpYnVjacOzbiBkZSBmcmVjdWVuY2lhcyByZWxhdGl2YXMKZl9pIDwtIGMoKQpmb3IgKGkgaW4gMTpsZW5ndGgoZGZfZGQkbW9kYWxpZGFkKSkgewogIGZfaVtpXSA8LSBkZl9kZCRuX2lbaV0vbgogIHByaW50KGZfaVtpXSkKfQpkZl9kZCRmX2kgPC0gZl9pCiMgdmFsaWRhciBxdWUgbGEgc3VtYSBkZSB0b2RvcyBsb3MgZWxlbWVudG9zIGVzIDEKCiMgRGlzdHJpYnVjacOzbiBkZSBmcmVjdWVuY2lhcyBhYnNvbHV0YXMgYWN1bXVsYWRhcwpzZWVkIDwtIDAKTl9pIDwtIGMoKQpmb3IgKGkgaW4gMTpsZW5ndGgoZGZfZGQkbW9kYWxpZGFkKSkgewogIE5faVtpXSA8LSBkZl9kZCRuX2lbaV0gKyBzZWVkCiAgc2VlZCA8LSBOX2lbaV0KfQpkZl9kZCROX2kgPC0gTl9pCgoKIyBEaXN0cmlidWNpw7NuIGRlIGZyZWN1ZW5jaWFzIHJlbGF0aXZhcyBhY3VtdWxhZGFzCnNlZWQgPC0gMApGX2kgPC0gYygpCmZvciAoaSBpbiAxOmxlbmd0aChkZl9kZCRtb2RhbGlkYWQpKSB7CiAgRl9pW2ldIDwtIGRmX2RkJGZfaVtpXSArIHNlZWQKICBzZWVkIDwtIEZfaVtpXQp9CmRmX2RkJEZfaSA8LSBGX2kKCiMgVmVhbW9zIHRvZGFzIGxhcyBkaXN0cmlidWNpb25lcyBkZSBmcmVjdWVuY2lhcwpkZl9kZApgYGAKCgojIyBNZWRpZGFzIGRlIHRlbmRlbmNpYSBjZW50cmFsIGRlIGNhcmFjdGVyZXMgY3VhbnRpdGF0aXZvcwpgYGB7cn0KIyBmdW5jacOzbiBuYXRpdmEKYSA8LSBtZWFuKGRmXzJfMSROaXZlbCkKCnN1bWF0b3JpbyA8LSBhcy5udW1lcmljKDApCmZvciAoaSBpbiAxOmxlbmd0aChkZl9kZCRtb2RhbGlkYWQpKSB7CiAgbW9kX2J5X25faSA8LSBhcy5udW1lcmljKGRmX2RkJG1vZGFsaWRhZFtpXSkgKiBhcy5udW1lcmljKGRmX2RkJG5faVtpXSkKICBzdW1hdG9yaW8gPC0gc3VtYXRvcmlvICsgbW9kX2J5X25faSAKfQptZWRpYSA8LSBzdW1hdG9yaW8vbgoKc3VtYSA8LSBhcy5udW1lcmljKDApCmZvciAoaSBpbiAxOmxlbmd0aChkZl8yXzEkSW5kaXZpZHVvKSkgewogIHN1bWEgPC0gc3VtYSArIGRmXzJfMSROaXZlbAp9Cm1lZGlhIDwtIHN1bWEvbgoKYGBgCgoKIyMgTWVkaWRhcyBkZSBkaXNwZXJzacOzbgpgYGB7cn0KcmVjb3JyaWRvIDwtIChtb2RfbWF4IC0gbW9kX21pbikKcHJpbnQocGFzdGUoIkVsIHJlY29ycmlkbyBlcyIsIHJlY29ycmlkbykpCgpTX3NxciA8LSB2YXIoZGZfMl8xJE5pdmVsKQpwcmludChwYXN0ZSgiTGEgY3Vhc2l2YXJpYW56YSBlcyIsIFNfc3FyKSkKCnNfc3FyIDwtIFNfc3FyICogKG4gLTEpL24KcHJpbnQocGFzdGUoIkxhIHZhcmlhbnphIGVzIiwgc19zcXIpKQoKUyA8LSBzcXJ0KFNfc3FyKQpwcmludChwYXN0ZSgiTGEgY3Vhc2lkZXN2aWFjacOzbiB0w61waWNhIGVzIiwgUykpCnMgPC0gc3FydChzX3NxcikKcHJpbnQocGFzdGUoIkxhIGRlc3ZpYWNpw7NuIHTDrXBpY2EgZXMiLCBzKSkKCmJveHBsb3QoZGZfMl8xJE5pdmVsKQoKc3VtbWFyeShkZl8yXzEkTml2ZWwpCmBgYAoKCiMgRWplbXBsbyAyLjkKCmBgYHtyfQojIEVqZW1wbG8gMi45CiMgQ3JlYXIgdmVjdG9yZXMgY29uIGxvcyBpbmRpdmlkdW9zIHkgbGFzIG9ic2VydmFjaW9uZXMgZGUgbGEgY2FyYWN0ZXLDrXN0aWNhLwojIHZhcmlhYmxlIGVzdGFkw61zdGljYQp2X2hvcmFzIDwtIGMoMjEsIDMyLCAxNSwgNDAsIDI3LCAKICAgICAgICAgICAgIDE4LCAyNiwgNTAsIDMzLCA1MSwgCiAgICAgICAgICAgICAzNiwgMTYsIDE5LCAyMiwgMTYsIAogICAgICAgICAgICAgMzksIDU2LCAyOSwgNDUsIDI1KQp2X21hcmNhcyA8LSBjKDEzLjIsIDEyLjYsIDEzLCAxMi4yLCAxNSwKICAgICAgICAgICAgIDE0LjgsIDE0LjgsIDEyLjIsIDEzLjYsIDEyLjYsCiAgICAgICAgICAgICAxMy4xLCAxNC45LCAxMy45LCAxMy4yLCAxNS4xLAogICAgICAgICAgICAgMTQuMSwgMTMsIDEzLjUsIDEyLjcsIDE0LjIpCgojIENyZWFyIHVuYSBlc3RydWN0dXJhIGRlbCB0aXBvIGRhdGEgZnJhbWUKZGZfMl85IDwtIGRhdGEuZnJhbWUoaG9yYXMgPSB2X2hvcmFzLAogICAgICAgICAgICAgICAgICAgICBtYXJjYXMgPSB2X21hcmNhcykKCiMgVmVhbW9zIGxhIG1hdHJpeiBkZSBkYXRvcwpkZl8yXzkKYGBgCgpgYGB7cn0KIyBHcsOhZmljYSBkZSBsb3MgZGF0b3MgZW4gZm9ybWEgZGUgbnViZSBkZSBwdW50b3MKcGxvdChkZl8yXzkkaG9yYXMsIGRmXzJfOSRtYXJjYXMsCiAgICAgeGxhYiA9ICJob3JhcyBkZSBlbnRyZW5hbWllbnRvIiwKICAgICB5bGFiID0gIm1hcmNhIiwKICAgICBtYWluID0gIm51YmUgZGUgcHVudG9zIHkgcmVjdGEgZGUgYWp1c3RlIikKCiMgY2FsY3VsYSBsYSByZWN0YSBkZSBhanVzdGUKYWp1cyA8LSBsbShkZl8yXzkkbWFyY2FzfmRmXzJfOSRob3JhcykKIyBtdWVzdHJhIGN1YWwgZXMgbGEgcmVjdGEgZGUgYWp1c3RlCmFqdXMKCiMgYcOxYWRlIGxhIHJlY3RhIGRlIHJlZ3Jlc2nDs24gYSBsYSBudWJlIGRlIHB1bnRvcwphYmxpbmUoYWp1cykKCiMgYcOxYWRlIHVuIHLDs3R1bG8KbGVnZW5kKDQyLCAxNCwgCiAgICAgICBjKCJsw61uZWEgZGUgcmVncmVzacOzbiIpLAogICAgICAgbHR5ID0gYygxKSkKYGBgCgpgYGB7cn0KIyBFbCBjb2VmaWNpZW50ZSBkZSBjb3JyZWxhY2nDs24gZGUgUGVhcnNvbiAKciA8LSBjb3IoZGZfMl85JGhvcmFzLCBkZl8yXzkkbWFyY2FzKQpyX3IgPC0gcm91bmQociwgZGlnaXRzID0gMikKCnByaW50KHBhc3RlKCJFbCBjb2VmaWNpZW50ZSBkZSBjb3JyZWxhY2nDs24gbGluZWFsIGRlIFBlYXJzb24gZXM6Iiwgcl9yKSkKYGBgCgoK