Examen

Examen Pregunta 1

Una sucursal de Farmacias Similares quiere ver si su tiempo de espera (en minutos) es el adecuado, por lo que se le pide a usted que tome el tiempo a los siguientes 50 clientes que lleguen a la sucursal. No se sabe qué distribución tenga ésta información, pero su jefe le ha pedido a usted que le de un tiempo promedio de espera estimado para ver si están haciendo bien las cosas. En ese sentido se le pide que realice una simulación por medio de bootstrap con 5000 repeticiones (Utilice 888 como semilla para el ejercicio) para poder responder las siguientes preguntas:

library(boot)

# Datos originales de la base de datos Farmacias Similares
set.seed(888)
tiempos_espera <- round(runif(50, min = 2, max = 15), 1)
cat("Datos:", tiempos_espera, "\n\n")
## Datos: 2.3 6.5 2.8 10.9 12 3.4 7.1 5.5 2.6 13.7 7.2 2.5 2.2 7.6 11.4 14.7 11.6 5.9 13.2 12.1 10.1 14.2 13.9 11.2 12.8 9.7 10.5 4.6 6 13.1 3.6 4 13.5 3.3 7.5 5.4 2.2 14.7 6.8 7 8.2 3.6 7.1 9.2 5 12.7 12.2 6.3 7.4 2.3
bootstrap_media <- function(data, indices) {
  return(mean(data[indices]))  
}

1.-¿Cuál es el tiempo promedio de espera?

set.seed(888)
b1 <- boot(data = tiempos_espera, statistic = bootstrap_media, R = 5000)
cat("Media:", round(mean(b1$t), 2), "min | 95% CI: [", round(boot.ci(b1, type = "perc")$percent[4], 2), ", ", round(boot.ci(b1, type = "perc")$percent[5], 2), "]\n\n")
## Media: 8.05 min | 95% CI: [ 6.93 ,  9.15 ]

2.- ¿Cuál es el intervalo que se genera para esta estimación?

cat("El intervalo de confianza al 95% es: [", round(boot.ci(b1, type = "perc")$percent[4], 2), ", ", round(boot.ci(b1, type = "perc")$percent[5], 2), "] minutos\n\n")
## El intervalo de confianza al 95% es: [ 6.93 ,  9.15 ] minutos

3.- En sus palabras, ¿cómo aprecia el intervalo de confianza generado? (En términos de qué tanta incertidumbre hay). (El intervalo de confianza muestra el rango donde probablemente esté el promedio real de espera; si es amplio hay más incertidumbre y si es reducido, la estimación es más precisa. dame mejor repseuesta a esta pregunta)

4.- Si realiza un bootstrap adicional sobre los resultados del anterior pero ahora con 10,000 repeticiones, ¿cómo cambia el tiempo de atención promedio?

set.seed(888)
b2 <- boot(data = tiempos_espera, statistic = bootstrap_media, R = 10000)
cat("Media 10,000 rep:", round(mean(b2$t), 2), "min | 95% CI: [", round(boot.ci(b2, type = "perc")$percent[4], 2), ", ", round(boot.ci(b2, type = "perc")$percent[5], 2), "]\n")
## Media 10,000 rep: 8.06 min | 95% CI: [ 6.96 ,  9.16 ]
cat("Diferencia media:", round(mean(b2$t) - mean(b1$t), 3), "minutos\n\n")
## Diferencia media: 0.004 minutos

5.- Genere un nuevo intervalo de confianza con el nuevo bootstrap realizado y comparelo con el que resultó del punto 2.

cat("Comparación de intervalos:\n")
## Comparación de intervalos:
cat("Bootstrap 5000 rep: [", round(boot.ci(b1, type = "perc")$percent[4], 2), ", ", round(boot.ci(b1, type = "perc")$percent[5], 2), "] minutos\n")
## Bootstrap 5000 rep: [ 6.93 ,  9.15 ] minutos
cat("Bootstrap 10000 rep: [", round(boot.ci(b2, type = "perc")$percent[4], 2), ", ", round(boot.ci(b2, type = "perc")$percent[5], 2), "] minutos\n")
## Bootstrap 10000 rep: [ 6.96 ,  9.16 ] minutos

Examen Pregunta 2

Un centro de atención al cliente quiere analizar el tiempo promedio de espera de las llamadas para estimar un intervalo de confianza. Sin embargo, los tiempos de espera no son independientes, ya que:

Durante horas pico, los tiempos de espera suelen ser más largos. Si hay muchas llamadas seguidas, el tiempo de espera de un cliente puede verse afectado por la carga previa. En horas de baja demanda, los tiempos de espera son menores y más estables. En ese sentido, se le pide que realice un block bootstrap debido a que los tiempos en cada observación están correlacionados con la observación anterior y se quiere preservar la temporalidad.

La estructura de los datos es la siguiente:

En R

set.seed(888) n <- 300 #Número de llamadas analizadas tiempos_espera <- c(rep(4, 100), rep(2, 100), rep(6, 100)) + rnorm(n, mean = 0, sd = 0.5) #Tiempos de espera junto con ruido

Se le pide que el block bootstrap realice 5000 iteraciones y que el tamaño del bloque que se estará utilizando será de 30 llamadas.

library(boot)
set.seed(888)
n <- 300  
tiempos_espera <- c(rep(4, 100), rep(2, 100), rep(6, 100)) + rnorm(n, mean = 0, sd = 0.5)
db_tiempos <- data.frame(indices = seq(1:n), Tiempo_Espera = tiempos_espera)
bootstrap_mean <- function(data, indices) {
  return(mean(data))  # Extraer datos según los índices de bootstrap
}

Responda las siguientes preguntas.

1.-¿Cuál es el tiempo promedio de espera?

# Block Bootstrap con 5000 repeticiones y bloque 30
set.seed(888)
block_boot <- tsboot(db_tiempos$Tiempo_Espera, statistic = bootstrap_mean, R = 5000, l = 30, sim = "fixed")
ic_lower <- quantile(block_boot$t, 0.025)
ic_upper <- quantile(block_boot$t, 0.975)

# Resultados
cat("Media estimada del tiempo de espera:", round(mean(db_tiempos$Tiempo_Espera), 2), "minutos\n")
## Media estimada del tiempo de espera: 4.03 minutos
cat("Media bootstrap 5000 rep:", round(mean(block_boot$t), 2), "minutos\n")
## Media bootstrap 5000 rep: 4.02 minutos
cat("Intervalo de confianza del 95% con Block Bootstrap: [", round(ic_lower, 2), ",", round(ic_upper, 2), "]\n\n")
## Intervalo de confianza del 95% con Block Bootstrap: [ 3.1 , 4.92 ]

2.- ¿Cuál es el intervalo que se genera para esta estimación?

cat("El intervalo de confianza al 95% es: [", round(ic_lower, 2), ",", round(ic_upper, 2), "] minutos\n")
## El intervalo de confianza al 95% es: [ 3.1 , 4.92 ] minutos
cat("Esto significa que hay un 95% de confianza de que el verdadero tiempo promedio este en este rango")
## Esto significa que hay un 95% de confianza de que el verdadero tiempo promedio este en este rango

3.- En sus palabras, ¿cómo aprecia el intervalo de confianza generado? (En términos de qué tanta incertidumbre hay).

# El intervalo de confianza muestra el rango en el que es probable que esté el tiempo promedio real. Entre más amplio el intervalo, mayor incertidumbre; entre más cerrado, mayor precisión del mismo 
cat("La amplitud del intervalo es:", round(ic_upper - ic_lower, 2), "minutos\n")
## La amplitud del intervalo es: 1.83 minutos

4.- Si hiciera un bootstrap adicional sobre los resultados del anterior pero ahora con 10,000 repeticiones, ¿cómo cambia el tiempo de atención promedio?

set.seed(888)
block_boot2 <- tsboot(block_boot$t, statistic = bootstrap_mean, R = 10000, l = 30, sim = "fixed")
# Obtener intervalo de confianza del 95% 
ic_lower2 <- quantile(block_boot2$t, 0.025)
ic_upper2 <- quantile(block_boot2$t, 0.975)

# Resultados
cat("Media bootstrap 10,000 rep:", round(mean(block_boot2$t), 2), "minutos\n")
## Media bootstrap 10,000 rep: 4.02 minutos
cat("Intervalo de confianza del 95% con Block Bootstrap: [", round(ic_lower2, 2), ",", round(ic_upper2, 2), "]\n")
## Intervalo de confianza del 95% con Block Bootstrap: [ 4.01 , 4.03 ]
cat("Diferencia media:", round(mean(block_boot2$t) - mean(block_boot$t), 3), "minutos\n\n")
## Diferencia media: 0 minutos

5.- Genere un nuevo intervalo de confianza con el nuevo bootstrap realizado y comparelo con el que resultó del punto 2.

cat("Comparación de intervalos:\n")
## Comparación de intervalos:
cat("Block Bootstrap 5000 rep: [", round(ic_lower, 2), ",", round(ic_upper, 2), "] minutos\n")
## Block Bootstrap 5000 rep: [ 3.1 , 4.92 ] minutos
cat("Block Bootstrap 10000 rep: [", round(ic_lower2, 2), ",", round(ic_upper2, 2), "] minutos\n")
## Block Bootstrap 10000 rep: [ 4.01 , 4.03 ] minutos
cat("El intervalo con 10,000 repeticiones suele ser ligeramente más estable (menos variabilidad).\n")
## El intervalo con 10,000 repeticiones suele ser ligeramente más estable (menos variabilidad).
cat("NOTA: El block bootstrap preserva la estructura temporal de los datos.\n\n")
## NOTA: El block bootstrap preserva la estructura temporal de los datos.

Examen Pregunta 3

Toeria de Filas

Un centro de atención telefónica tiene una sola línea para atender a los clientes. Las llamadas llegan de manera aleatoria siguiendo un proceso de Poisson con una tasa de llegada de 83 llamadas por hora.

Cada llamada es atendida por un único operador, cuyo tiempo de servicio sigue una distribución exponencial con una tasa de 90 clientes por hora.

library(queueing)
lambda <- 83   # llamadas por hora
mu <- 90       # clientes por hora
c1 <- 1        # 1 línea
c2 <- 2  

Responda las siguientes preguntas:

1.- ¿Cuál es el nivel de saturación del sistema, el número de clientes en la fila, el número de clientes en el sistema, el tiempo promedio en la fila y el tiempo promedio en el sistema?

modelo1_linea <- NewInput.MMC(lambda = lambda, mu = mu, c = c1, n = 0, method = 0)
resultado1 <- QueueingModel(modelo1_linea)
# Mostrar resultados
cat("Factor de utilización (rho):", round(resultado1$RO, 4), "\n")
## Factor de utilización (rho): 0.9222
cat("Número promedio de clientes en la fila (Lq):", round(resultado1$Lq, 4), "\n")
## Número promedio de clientes en la fila (Lq): 10.9349
cat("Número promedio de clientes en el sistema (L):", round(resultado1$L, 4), "\n")
## Número promedio de clientes en el sistema (L): 11.8571
cat("Tiempo promedio en la fila (Wq):", round(resultado1$Wq * 60, 2), "minutos\n")
## Tiempo promedio en la fila (Wq): 7.9 minutos
cat("Tiempo promedio en el sistema (W):", round(resultado1$W * 60, 2), "minutos\n")
## Tiempo promedio en el sistema (W): 8.57 minutos

R: Los restulado arrojan que el sistema está sobresaturado al 92.22%. Los clientes esperan casi 8 minutos en la fila, con más de 10 personas esperando constantemente.

2.- Suponga que el gerente del centro revisó el análisis que usted realizó y decidió abrir una línea más teniendo 2 en total, ¿cómo cambia su análisis anterior agregando ésta línea telefónica adicional (vuelva a calcular, reporte las variables solicitadas en la pregunta 1 y compare los resultados con los de la pregunta 1)?

modelo2_lineas <- NewInput.MMC(lambda = lambda, mu = mu, c = c2, n = 0, method = 0)

# Resolver el modelo
resultado2 <- QueueingModel(modelo2_lineas)

# Mostrar resultados
cat("Factor de utilización (rho):", round(resultado2$RO, 4), "\n")
## Factor de utilización (rho): 0.4611
cat("Número promedio de clientes en la fila (Lq):", round(resultado2$Lq, 4), "\n")
## Número promedio de clientes en la fila (Lq): 0.249
cat("Número promedio de clientes en el sistema (L):", round(resultado2$L, 4), "\n")
## Número promedio de clientes en el sistema (L): 1.1713
cat("Tiempo promedio en la fila (Wq):", round(resultado2$Wq * 60, 2), "minutos\n")
## Tiempo promedio en la fila (Wq): 0.18 minutos
cat("Tiempo promedio en el sistema (W):", round(resultado2$W * 60, 2), "minutos\n")
## Tiempo promedio en el sistema (W): 0.85 minutos

R: Ahora con este cambio de agregar dos líneas, el sistema es muy distinto. Los clientes esperan solo 18 segundos en lugar de 7.71 minutos.

Examen Pregunta 4

Los negocios de Acme Steel Fabricators han sido muy prósperos en los últimos cinco años. La compañía fabrica una amplia gama de productos de acero, como barandales, escaleras y marcos de acero estructural ligero. El método manual vigente para manejo de materiales ocasiona un exceso de inventario y congestionamientos. Acme está considerando si debe comprar un sistema de transporte que pende de un riel (monoriel), o un vehículo montacargas, para incrementar su capacidad y mejorar su eficiencia manufacturera.

Los resultados anuales del sistema, antes de impuestos, dependen de la demanda futura. Si la demanda se mantiene en el nivel actual, lo cual tiene una probabilidad de 0.50, el ahorro anual que producirá el transportador elevado (monoriel) será de $10,000. Si la demanda aumenta permitirá ahorrar $25,000 al año por la eficiencia operativa, además de las nuevas ventas. Finalmente, si la demanda cae, provocará una pérdida anual estimada en $65,000.

Se estima una probabilidad de 0.30 de que la demanda sea alta y de 0.20 de que sea baja. Si se compra, el montacargas, los resultados anuales serán de $5,000 si la demanda no cambia, $10,000 si la demanda aumenta y –$25,000 si la demanda cae.

# Librerias
library(DiagrammeR)
library(tidyverse)
## ── Attaching core tidyverse packages ──────────────────────── tidyverse 2.0.0 ──
## ✔ dplyr     1.1.4     ✔ readr     2.1.5
## ✔ forcats   1.0.0     ✔ stringr   1.5.1
## ✔ ggplot2   3.5.2     ✔ tibble    3.3.0
## ✔ lubridate 1.9.3     ✔ tidyr     1.3.1
## ✔ purrr     1.1.0     
## ── Conflicts ────────────────────────────────────────── tidyverse_conflicts() ──
## ✖ dplyr::filter() masks stats::filter()
## ✖ dplyr::lag()    masks stats::lag()
## ℹ Use the conflicted package (<http://conflicted.r-lib.org/>) to force all conflicts to become errors
# Definir probabilidades y parámetros
p_alta  <- 0.30
p_igual <- 0.50
p_baja  <- 0.20

ah_mono_alta  <- 25000
ah_mono_igual <- 10000
ah_mono_baja  <- -65000

ah_mont_alta  <- 10000
ah_mont_igual <-  5000
ah_mont_baja  <- -25000

# Calcular valores esperados (VE)
ve_monoriel   <- p_alta*ah_mono_alta + p_igual*ah_mono_igual + p_baja*ah_mono_baja
ve_montacargas<- p_alta*ah_mont_alta + p_igual*ah_mont_igual + p_baja*ah_mont_baja

cat("VE Monoriel:   $", format(round(ve_monoriel, 2), big.mark=","), "\n", sep = "")
## VE Monoriel:   $-500
cat("VE Montacargas:$", format(round(ve_montacargas, 2), big.mark=","), "\n", sep = "")
## VE Montacargas:$500
mejor_opcion <- ifelse(ve_montacargas > ve_monoriel, "Montacargas", "Monoriel")
cat("Mejor alternativa:", mejor_opcion, "\n")
## Mejor alternativa: Montacargas
# Tabla resumen de escenarios
resumen <- tribble(
  ~Alternativa, ~Demanda, ~Prob, ~Ahorro_USD,
  "Monoriel",    "Alta",   p_alta,  ah_mono_alta,
  "Monoriel",    "Igual",  p_igual, ah_mono_igual,
  "Monoriel",    "Baja",   p_baja,  ah_mono_baja,
  "Montacargas", "Alta",   p_alta,  ah_mont_alta,
  "Montacargas", "Igual",  p_igual, ah_mont_igual,
  "Montacargas", "Baja",   p_baja,  ah_mont_baja
) %>%
  mutate(Prob = scales::percent(Prob, accuracy = 1),
         Ahorro_USD = scales::dollar(Ahorro_USD))

resumen
## # A tibble: 6 × 4
##   Alternativa Demanda Prob  Ahorro_USD
##   <chr>       <chr>   <chr> <chr>     
## 1 Monoriel    Alta    30%   $25,000   
## 2 Monoriel    Igual   50%   $10,000   
## 3 Monoriel    Baja    20%   -$65,000  
## 4 Montacargas Alta    30%   $10,000   
## 5 Montacargas Igual   50%   $5,000    
## 6 Montacargas Baja    20%   -$25,000
# Visualizando el árbol de decisión
DiagrammeR::grViz("
digraph decision_tree {
  graph [rankdir=LR]
  node [shape=box, style=filled, fillcolor=lightblue];

  Inicio [label='Decisión: Sistema de manejo de materiales'];

  Monoriel    [label='Monoriel'];
  Montacargas [label='Montacargas'];

  Mono_Alta   [label='Alta (0.30)\\nAhorro = $25,000'];
  Mono_Igual  [label='Igual (0.50)\\nAhorro = $10,000'];
  Mono_Baja   [label='Baja (0.20)\\nAhorro = -$65,000'];

  Mont_Alta   [label='Alta (0.30)\\nAhorro = $10,000'];
  Mont_Igual  [label='Igual (0.50)\\nAhorro = $5,000'];
  Mont_Baja   [label='Baja (0.20)\\nAhorro = -$25,000'];

  Inicio -> Monoriel
  Inicio -> Montacargas

  Monoriel -> Mono_Alta  [label='0.30']
  Monoriel -> Mono_Igual [label='0.50']
  Monoriel -> Mono_Baja  [label='0.20']

  Montacargas -> Mont_Alta  [label='0.30']
  Montacargas -> Mont_Igual [label='0.50']
  Montacargas -> Mont_Baja  [label='0.20']
}
")

Responda las siguientes preguntas:

1.- ¿Cuál es la mejor alternativa para ACME? La mejor alternativa para ACME es Montacargas, porque su valor esperado es mayor y su riesgo de pérdida es menor que el del Monorriel.

2.- ¿Cuál sería el ahorro esperado en el largo plazo? El ahorro esperado a largo plazo sería de 500 dólares por año, basado en el valor esperado del Montacargas.

Examen Pregunta 5

Se tienen dos dados de 20 lados cada uno. Esos dados se lanzan de manera simultánea para ver cuánto cae en ambos.

set.seed(520)  
num_simulations_10k <- 10000   # Primera simulación
num_simulations_50k <- 50000   # Segunda simulación
# Simulacion con 10,000 iteraciones
dice1_10k <- sample(1:20, num_simulations_10k, replace = TRUE)
dice2_10k <- sample(1:20, num_simulations_10k, replace = TRUE)

sum_dices_10k <- dice1_10k + dice2_10k
mult_dices_10k <- dice1_10k * dice2_10k

# Estimamos las 3 probabilidades
prob_suma_30_10k <- mean(sum_dices_10k >= 30)
prob_suma_27_10k <- mean(sum_dices_10k == 27)
prob_mult_300_10k <- mean(mult_dices_10k >= 300)

# Mostramos los resultados
print(paste("1. Probabilidad suma >= 30:", round(prob_suma_30_10k * 100, 2), "%"))
## [1] "1. Probabilidad suma >= 30: 16.47 %"
print(paste("2. Probabilidad suma = 27:", round(prob_suma_27_10k * 100, 2), "%"))
## [1] "2. Probabilidad suma = 27: 3.68 %"
print(paste("3. Probabilidad multiplicación >= 300:", round(prob_mult_300_10k * 100, 2), "%"))
## [1] "3. Probabilidad multiplicación >= 300: 5.22 %"

A usted se le pide que realice una simulación de montecarlo para calcular lo siguiente:

1.- ¿Cuál es la probabilidad de que la suma de los resultados sea mayor o igual a 30? R: 16.47 %

2.- ¿Cuál es la probabilidad de que la suma de los resultados sea igual a 27? R: 3.68 %

3.- ¿Cuál es la probabilidad de que la multiplicación de sus resultados sea mayor o igual a 300? R: 5.22%

Para realizar este ejercicio por favor haga uso del seed 520 y realice el ejercicio para 10,000 iteraciones

Una vez que realizó lo anterior, vuelva a realizar los tres ejercicios (preguntas) pero ahora con un total de 50,000 iteraciones y compare los resultados de ambos ejercicios con los valores reales de que ocurran éstos escenarios. Es decir, cuál fue más cercano a la realidad.

# Generamos los lanzamientos de los dos dados de 20 lados
dice1_50k <- sample(1:20, num_simulations_50k, replace = TRUE)
dice2_50k <- sample(1:20, num_simulations_50k, replace = TRUE)

# Calculamos la suma de los dos dados
sum_dices_50k <- dice1_50k + dice2_50k

# Calculamos la multiplicación de los dos dados
mult_dices_50k <- dice1_50k * dice2_50k

# Estimamos las probabilidades
prob_suma_30_50k <- mean(sum_dices_50k >= 30)
prob_suma_27_50k <- mean(sum_dices_50k == 27)
prob_mult_300_50k <- mean(mult_dices_50k >= 300)

# Mostramos los resultados
print(paste("1. Probabilidad suma >= 30:", round(prob_suma_30_50k * 100, 2), "%"))
## [1] "1. Probabilidad suma >= 30: 16.53 %"
print(paste("2. Probabilidad suma = 27:", round(prob_suma_27_50k * 100, 2), "%"))
## [1] "2. Probabilidad suma = 27: 3.48 %"
print(paste("3. Probabilidad multiplicación >= 300:", round(prob_mult_300_50k * 100, 2), "%"))
## [1] "3. Probabilidad multiplicación >= 300: 5.33 %"
# Valores reales proporcionados
prob_real_suma_30 <- 16.5
prob_real_suma_27 <- 3.5
prob_real_mult_300 <- 5.25

# Suma >= 30
error_10k_suma30 <- abs(prob_suma_30_10k * 100 - prob_real_suma_30)
error_50k_suma30 <- abs(prob_suma_30_50k * 100 - prob_real_suma_30)
cat("Suma>=30  |", prob_real_suma_30, "% |", round(prob_suma_30_10k * 100, 2), "% |", 
    round(prob_suma_30_50k * 100, 2), "% |", round(error_10k_suma30, 2), "% |", 
    round(error_50k_suma30, 2), "%\n")
## Suma>=30  | 16.5 % | 16.47 % | 16.53 % | 0.03 % | 0.03 %
# Suma = 27
error_10k_suma27 <- abs(prob_suma_27_10k * 100 - prob_real_suma_27)
error_50k_suma27 <- abs(prob_suma_27_50k * 100 - prob_real_suma_27)
cat("Suma=27   |", prob_real_suma_27, "% |", round(prob_suma_27_10k * 100, 2), "% |", 
    round(prob_suma_27_50k * 100, 2), "% |", round(error_10k_suma27, 2), "% |", 
    round(error_50k_suma27, 2), "%\n")
## Suma=27   | 3.5 % | 3.68 % | 3.48 % | 0.18 % | 0.02 %
# Multiplicación >= 300
error_10k_mult300 <- abs(prob_mult_300_10k * 100 - prob_real_mult_300)
error_50k_mult300 <- abs(prob_mult_300_50k * 100 - prob_real_mult_300)
cat("Mult>=300 |", prob_real_mult_300, "% |", round(prob_mult_300_10k * 100, 2), "% |", 
    round(prob_mult_300_50k * 100, 2), "% |", round(error_10k_mult300, 2), "% |", 
    round(error_50k_mult300, 2), "%\n")
## Mult>=300 | 5.25 % | 5.22 % | 5.33 % | 0.03 % | 0.08 %
# Determinar cuál es más precisa 
error_total_10k <- error_10k_suma30 + error_10k_suma27 + error_10k_mult300
error_total_50k <- error_50k_suma30 + error_50k_suma27 + error_50k_mult300

cat("Error total simulación 10k:", round(error_total_10k, 2), "%\n")
## Error total simulación 10k: 0.24 %
cat("Error total simulación 50k:", round(error_total_50k, 2), "%\n")
## Error total simulación 50k: 0.12 %
if (error_total_50k < error_total_10k) {
  cat("RESULTADO: La simulación con 50,000 iteraciones es MÁS PRECISA\n")
} else {
  cat("RESULTADO: La simulación con 10,000 iteraciones es MÁS PRECISA\n")
}
## RESULTADO: La simulación con 50,000 iteraciones es MÁS PRECISA

1.- En el primer caso la probabilidad real es de 16.5%

2.- En el segundo caso la probabilidad real es de 3.5%

3.- En el tercer caso la probabilidad es de 5.25%

R:La simulación de Monte Carlo con 10,000 iteraciones fue muy cercana a la realidad. Los resultados mostraron que la probabilidad de suma ≥ 30 fue 16.47% vs. 16.5% real, suma = 27 fue 3.68% vs. 3.5% real, y multiplicación ≥ 300 fue 5.22% vs. 5.25% real. El error total fue solo 0.24%, demostrando que 10,000 iteraciones fue excepcionalmente preciso para este ejercicio.

LS0tCnRpdGxlOiAiRXhhbWVuIE1vZHVsbyAyIgphdXRob3I6ICJTZWJhc3RpYW4gRXNwaW5vemEgQTAwODMzNzA0IgpkYXRlOiAiMjAyNS0wOC0yNSIKb3V0cHV0OiAKIGh0bWxfZG9jdW1lbnQ6IAogIHRvYzogVFJVRQogIHRvY19mbG9hdDogVFJVRQogIGNvZGVfZG93bmxvYWQ6IFRSVUUKICB0aGVtZTogeWV0aQotLS0KIyA8c3BhbiBzdHlsZT0nY29sb3I6cmVkOyc+ICBFeGFtZW4gPC9zcGFuPiAKCiMjIDxzcGFuIHN0eWxlPSdjb2xvcjpyZWQ7Jz4gIEV4YW1lbiBQcmVndW50YSAxIDwvc3Bhbj4gCgpVbmEgc3VjdXJzYWwgZGUgRmFybWFjaWFzIFNpbWlsYXJlcyBxdWllcmUgdmVyIHNpIHN1IHRpZW1wbyBkZSBlc3BlcmEgKGVuIG1pbnV0b3MpIGVzIGVsIGFkZWN1YWRvLCBwb3IgbG8gcXVlIHNlIGxlIHBpZGUgYSB1c3RlZCBxdWUgdG9tZSBlbCB0aWVtcG8gYSBsb3Mgc2lndWllbnRlcyA1MCBjbGllbnRlcyBxdWUgbGxlZ3VlbiBhIGxhIHN1Y3Vyc2FsLiBObyBzZSBzYWJlIHF1w6kgZGlzdHJpYnVjacOzbiB0ZW5nYSDDqXN0YSBpbmZvcm1hY2nDs24sIHBlcm8gc3UgamVmZSBsZSBoYSBwZWRpZG8gYSB1c3RlZCBxdWUgbGUgZGUgdW4gdGllbXBvIHByb21lZGlvIGRlIGVzcGVyYSBlc3RpbWFkbyBwYXJhIHZlciBzaSBlc3TDoW4gaGFjaWVuZG8gYmllbiBsYXMgY29zYXMuIEVuIGVzZSBzZW50aWRvIHNlIGxlIHBpZGUgcXVlIHJlYWxpY2UgdW5hIHNpbXVsYWNpw7NuIHBvciBtZWRpbyBkZSBib290c3RyYXAgY29uIDUwMDAgcmVwZXRpY2lvbmVzIChVdGlsaWNlIDg4OCBjb21vIHNlbWlsbGEgcGFyYSBlbCBlamVyY2ljaW8pIHBhcmEgcG9kZXIgcmVzcG9uZGVyIGxhcyBzaWd1aWVudGVzIHByZWd1bnRhczoKCmBgYHtyfQpsaWJyYXJ5KGJvb3QpCgojIERhdG9zIG9yaWdpbmFsZXMgZGUgbGEgYmFzZSBkZSBkYXRvcyBGYXJtYWNpYXMgU2ltaWxhcmVzCnNldC5zZWVkKDg4OCkKdGllbXBvc19lc3BlcmEgPC0gcm91bmQocnVuaWYoNTAsIG1pbiA9IDIsIG1heCA9IDE1KSwgMSkKY2F0KCJEYXRvczoiLCB0aWVtcG9zX2VzcGVyYSwgIlxuXG4iKQpib290c3RyYXBfbWVkaWEgPC0gZnVuY3Rpb24oZGF0YSwgaW5kaWNlcykgewogIHJldHVybihtZWFuKGRhdGFbaW5kaWNlc10pKSAgCn0KYGBgCgoxLi3Cv0N1w6FsIGVzIGVsIHRpZW1wbyBwcm9tZWRpbyBkZSBlc3BlcmE/CmBgYHtyfQpzZXQuc2VlZCg4ODgpCmIxIDwtIGJvb3QoZGF0YSA9IHRpZW1wb3NfZXNwZXJhLCBzdGF0aXN0aWMgPSBib290c3RyYXBfbWVkaWEsIFIgPSA1MDAwKQpjYXQoIk1lZGlhOiIsIHJvdW5kKG1lYW4oYjEkdCksIDIpLCAibWluIHwgOTUlIENJOiBbIiwgcm91bmQoYm9vdC5jaShiMSwgdHlwZSA9ICJwZXJjIikkcGVyY2VudFs0XSwgMiksICIsICIsIHJvdW5kKGJvb3QuY2koYjEsIHR5cGUgPSAicGVyYyIpJHBlcmNlbnRbNV0sIDIpLCAiXVxuXG4iKQpgYGAKCjIuLSDCv0N1w6FsIGVzIGVsIGludGVydmFsbyBxdWUgc2UgZ2VuZXJhIHBhcmEgZXN0YSBlc3RpbWFjacOzbj8KYGBge3J9CmNhdCgiRWwgaW50ZXJ2YWxvIGRlIGNvbmZpYW56YSBhbCA5NSUgZXM6IFsiLCByb3VuZChib290LmNpKGIxLCB0eXBlID0gInBlcmMiKSRwZXJjZW50WzRdLCAyKSwgIiwgIiwgcm91bmQoYm9vdC5jaShiMSwgdHlwZSA9ICJwZXJjIikkcGVyY2VudFs1XSwgMiksICJdIG1pbnV0b3NcblxuIikKYGBgCgoKMy4tIEVuIHN1cyBwYWxhYnJhcywgwr9jw7NtbyBhcHJlY2lhIGVsIGludGVydmFsbyBkZSBjb25maWFuemEgZ2VuZXJhZG8/IChFbiB0w6lybWlub3MgZGUgcXXDqSB0YW50YSBpbmNlcnRpZHVtYnJlIGhheSkuCihFbCBpbnRlcnZhbG8gZGUgY29uZmlhbnphIG11ZXN0cmEgZWwgcmFuZ28gZG9uZGUgcHJvYmFibGVtZW50ZSBlc3TDqSBlbCBwcm9tZWRpbyByZWFsIGRlIGVzcGVyYTsgc2kgZXMgYW1wbGlvIGhheSBtw6FzIGluY2VydGlkdW1icmUgeSBzaSBlcyByZWR1Y2lkbywgbGEgZXN0aW1hY2nDs24gZXMgbcOhcyBwcmVjaXNhLiBkYW1lIG1lam9yIHJlcHNldWVzdGEgYSBlc3RhIHByZWd1bnRhKQoKNC4tIFNpIHJlYWxpemEgdW4gYm9vdHN0cmFwIGFkaWNpb25hbCBzb2JyZSBsb3MgcmVzdWx0YWRvcyBkZWwgYW50ZXJpb3IgcGVybyBhaG9yYSBjb24gMTAsMDAwIHJlcGV0aWNpb25lcywgwr9jw7NtbyBjYW1iaWEgZWwgdGllbXBvIGRlIGF0ZW5jacOzbiBwcm9tZWRpbz8KYGBge3J9CnNldC5zZWVkKDg4OCkKYjIgPC0gYm9vdChkYXRhID0gdGllbXBvc19lc3BlcmEsIHN0YXRpc3RpYyA9IGJvb3RzdHJhcF9tZWRpYSwgUiA9IDEwMDAwKQpjYXQoIk1lZGlhIDEwLDAwMCByZXA6Iiwgcm91bmQobWVhbihiMiR0KSwgMiksICJtaW4gfCA5NSUgQ0k6IFsiLCByb3VuZChib290LmNpKGIyLCB0eXBlID0gInBlcmMiKSRwZXJjZW50WzRdLCAyKSwgIiwgIiwgcm91bmQoYm9vdC5jaShiMiwgdHlwZSA9ICJwZXJjIikkcGVyY2VudFs1XSwgMiksICJdXG4iKQpjYXQoIkRpZmVyZW5jaWEgbWVkaWE6Iiwgcm91bmQobWVhbihiMiR0KSAtIG1lYW4oYjEkdCksIDMpLCAibWludXRvc1xuXG4iKQoKYGBgCgoKCjUuLSBHZW5lcmUgdW4gbnVldm8gaW50ZXJ2YWxvIGRlIGNvbmZpYW56YSBjb24gZWwgbnVldm8gYm9vdHN0cmFwIHJlYWxpemFkbyB5IGNvbXBhcmVsbyBjb24gZWwgcXVlIHJlc3VsdMOzIGRlbCBwdW50byAyLgoKYGBge3J9CmNhdCgiQ29tcGFyYWNpw7NuIGRlIGludGVydmFsb3M6XG4iKQpjYXQoIkJvb3RzdHJhcCA1MDAwIHJlcDogWyIsIHJvdW5kKGJvb3QuY2koYjEsIHR5cGUgPSAicGVyYyIpJHBlcmNlbnRbNF0sIDIpLCAiLCAiLCByb3VuZChib290LmNpKGIxLCB0eXBlID0gInBlcmMiKSRwZXJjZW50WzVdLCAyKSwgIl0gbWludXRvc1xuIikKY2F0KCJCb290c3RyYXAgMTAwMDAgcmVwOiBbIiwgcm91bmQoYm9vdC5jaShiMiwgdHlwZSA9ICJwZXJjIikkcGVyY2VudFs0XSwgMiksICIsICIsIHJvdW5kKGJvb3QuY2koYjIsIHR5cGUgPSAicGVyYyIpJHBlcmNlbnRbNV0sIDIpLCAiXSBtaW51dG9zXG4iKQpgYGAKCgojIyA8c3BhbiBzdHlsZT0nY29sb3I6cmVkOyc+ICBFeGFtZW4gUHJlZ3VudGEgMiA8L3NwYW4+IAoKVW4gY2VudHJvIGRlIGF0ZW5jacOzbiBhbCBjbGllbnRlIHF1aWVyZSBhbmFsaXphciBlbCB0aWVtcG8gcHJvbWVkaW8gZGUgZXNwZXJhIGRlIGxhcyBsbGFtYWRhcyBwYXJhIGVzdGltYXIgdW4gaW50ZXJ2YWxvIGRlIGNvbmZpYW56YS4gU2luIGVtYmFyZ28sIGxvcyB0aWVtcG9zIGRlIGVzcGVyYSBubyBzb24gaW5kZXBlbmRpZW50ZXMsIHlhIHF1ZToKCkR1cmFudGUgaG9yYXMgcGljbywgbG9zIHRpZW1wb3MgZGUgZXNwZXJhIHN1ZWxlbiBzZXIgbcOhcyBsYXJnb3MuClNpIGhheSBtdWNoYXMgbGxhbWFkYXMgc2VndWlkYXMsIGVsIHRpZW1wbyBkZSBlc3BlcmEgZGUgdW4gY2xpZW50ZSBwdWVkZSB2ZXJzZSBhZmVjdGFkbyBwb3IgbGEgY2FyZ2EgcHJldmlhLiBFbiBob3JhcyBkZSBiYWphIGRlbWFuZGEsIGxvcyB0aWVtcG9zIGRlIGVzcGVyYSBzb24gbWVub3JlcyB5IG3DoXMgZXN0YWJsZXMuIEVuIGVzZSBzZW50aWRvLCBzZSBsZSBwaWRlIHF1ZSByZWFsaWNlIHVuIGJsb2NrIGJvb3RzdHJhcCBkZWJpZG8gYSBxdWUgbG9zIHRpZW1wb3MgZW4gY2FkYSBvYnNlcnZhY2nDs24gZXN0w6FuIGNvcnJlbGFjaW9uYWRvcyBjb24gbGEgb2JzZXJ2YWNpw7NuIGFudGVyaW9yIHkgc2UgcXVpZXJlIHByZXNlcnZhciBsYSB0ZW1wb3JhbGlkYWQuCgpMYSBlc3RydWN0dXJhIGRlIGxvcyBkYXRvcyBlcyBsYSBzaWd1aWVudGU6CgoKRW4gUgoKc2V0LnNlZWQoODg4KQpuIDwtIDMwMCAgI07Dum1lcm8gZGUgbGxhbWFkYXMgYW5hbGl6YWRhcwp0aWVtcG9zX2VzcGVyYSA8LSBjKHJlcCg0LCAxMDApLCByZXAoMiwgMTAwKSwgcmVwKDYsIDEwMCkpICsgcm5vcm0obiwgbWVhbiA9IDAsIHNkID0gMC41KSAjVGllbXBvcyBkZSBlc3BlcmEganVudG8gY29uIHJ1aWRvCiAKClNlIGxlIHBpZGUgcXVlIGVsIGJsb2NrIGJvb3RzdHJhcCByZWFsaWNlIDUwMDAgaXRlcmFjaW9uZXMgeSBxdWUgZWwgdGFtYcOxbyBkZWwgYmxvcXVlIHF1ZSBzZSBlc3RhcsOhIHV0aWxpemFuZG8gc2Vyw6EgZGUgMzAgbGxhbWFkYXMuCgpgYGB7cn0KbGlicmFyeShib290KQpzZXQuc2VlZCg4ODgpCm4gPC0gMzAwICAKdGllbXBvc19lc3BlcmEgPC0gYyhyZXAoNCwgMTAwKSwgcmVwKDIsIDEwMCksIHJlcCg2LCAxMDApKSArIHJub3JtKG4sIG1lYW4gPSAwLCBzZCA9IDAuNSkKZGJfdGllbXBvcyA8LSBkYXRhLmZyYW1lKGluZGljZXMgPSBzZXEoMTpuKSwgVGllbXBvX0VzcGVyYSA9IHRpZW1wb3NfZXNwZXJhKQpib290c3RyYXBfbWVhbiA8LSBmdW5jdGlvbihkYXRhLCBpbmRpY2VzKSB7CiAgcmV0dXJuKG1lYW4oZGF0YSkpICAjIEV4dHJhZXIgZGF0b3Mgc2Vnw7puIGxvcyDDrW5kaWNlcyBkZSBib290c3RyYXAKfQoKYGBgCgpSZXNwb25kYSBsYXMgc2lndWllbnRlcyBwcmVndW50YXMuCgoxLi3Cv0N1w6FsIGVzIGVsIHRpZW1wbyBwcm9tZWRpbyBkZSBlc3BlcmE/CmBgYHtyfQojIEJsb2NrIEJvb3RzdHJhcCBjb24gNTAwMCByZXBldGljaW9uZXMgeSBibG9xdWUgMzAKc2V0LnNlZWQoODg4KQpibG9ja19ib290IDwtIHRzYm9vdChkYl90aWVtcG9zJFRpZW1wb19Fc3BlcmEsIHN0YXRpc3RpYyA9IGJvb3RzdHJhcF9tZWFuLCBSID0gNTAwMCwgbCA9IDMwLCBzaW0gPSAiZml4ZWQiKQppY19sb3dlciA8LSBxdWFudGlsZShibG9ja19ib290JHQsIDAuMDI1KQppY191cHBlciA8LSBxdWFudGlsZShibG9ja19ib290JHQsIDAuOTc1KQoKIyBSZXN1bHRhZG9zCmNhdCgiTWVkaWEgZXN0aW1hZGEgZGVsIHRpZW1wbyBkZSBlc3BlcmE6Iiwgcm91bmQobWVhbihkYl90aWVtcG9zJFRpZW1wb19Fc3BlcmEpLCAyKSwgIm1pbnV0b3NcbiIpCmNhdCgiTWVkaWEgYm9vdHN0cmFwIDUwMDAgcmVwOiIsIHJvdW5kKG1lYW4oYmxvY2tfYm9vdCR0KSwgMiksICJtaW51dG9zXG4iKQpjYXQoIkludGVydmFsbyBkZSBjb25maWFuemEgZGVsIDk1JSBjb24gQmxvY2sgQm9vdHN0cmFwOiBbIiwgcm91bmQoaWNfbG93ZXIsIDIpLCAiLCIsIHJvdW5kKGljX3VwcGVyLCAyKSwgIl1cblxuIikKYGBgCgoyLi0gwr9DdcOhbCBlcyBlbCBpbnRlcnZhbG8gcXVlIHNlIGdlbmVyYSBwYXJhIGVzdGEgZXN0aW1hY2nDs24/CmBgYHtyfQpjYXQoIkVsIGludGVydmFsbyBkZSBjb25maWFuemEgYWwgOTUlIGVzOiBbIiwgcm91bmQoaWNfbG93ZXIsIDIpLCAiLCIsIHJvdW5kKGljX3VwcGVyLCAyKSwgIl0gbWludXRvc1xuIikKY2F0KCJFc3RvIHNpZ25pZmljYSBxdWUgaGF5IHVuIDk1JSBkZSBjb25maWFuemEgZGUgcXVlIGVsIHZlcmRhZGVybyB0aWVtcG8gcHJvbWVkaW8gZXN0ZSBlbiBlc3RlIHJhbmdvIikKYGBgCgozLi0gRW4gc3VzIHBhbGFicmFzLCDCv2PDs21vIGFwcmVjaWEgZWwgaW50ZXJ2YWxvIGRlIGNvbmZpYW56YSBnZW5lcmFkbz8gKEVuIHTDqXJtaW5vcyBkZSBxdcOpIHRhbnRhIGluY2VydGlkdW1icmUgaGF5KS4KYGBge3J9CiMgRWwgaW50ZXJ2YWxvIGRlIGNvbmZpYW56YSBtdWVzdHJhIGVsIHJhbmdvIGVuIGVsIHF1ZSBlcyBwcm9iYWJsZSBxdWUgZXN0w6kgZWwgdGllbXBvIHByb21lZGlvIHJlYWwuIEVudHJlIG3DoXMgYW1wbGlvIGVsIGludGVydmFsbywgbWF5b3IgaW5jZXJ0aWR1bWJyZTsgZW50cmUgbcOhcyBjZXJyYWRvLCBtYXlvciBwcmVjaXNpw7NuIGRlbCBtaXNtbyAKY2F0KCJMYSBhbXBsaXR1ZCBkZWwgaW50ZXJ2YWxvIGVzOiIsIHJvdW5kKGljX3VwcGVyIC0gaWNfbG93ZXIsIDIpLCAibWludXRvc1xuIikKCgpgYGAKCjQuLSBTaSBoaWNpZXJhIHVuIGJvb3RzdHJhcCBhZGljaW9uYWwgc29icmUgbG9zIHJlc3VsdGFkb3MgZGVsIGFudGVyaW9yIHBlcm8gYWhvcmEgY29uIDEwLDAwMCByZXBldGljaW9uZXMsIMK/Y8OzbW8gY2FtYmlhIGVsIHRpZW1wbyBkZSBhdGVuY2nDs24gcHJvbWVkaW8/CmBgYHtyfQpzZXQuc2VlZCg4ODgpCmJsb2NrX2Jvb3QyIDwtIHRzYm9vdChibG9ja19ib290JHQsIHN0YXRpc3RpYyA9IGJvb3RzdHJhcF9tZWFuLCBSID0gMTAwMDAsIGwgPSAzMCwgc2ltID0gImZpeGVkIikKIyBPYnRlbmVyIGludGVydmFsbyBkZSBjb25maWFuemEgZGVsIDk1JSAKaWNfbG93ZXIyIDwtIHF1YW50aWxlKGJsb2NrX2Jvb3QyJHQsIDAuMDI1KQppY191cHBlcjIgPC0gcXVhbnRpbGUoYmxvY2tfYm9vdDIkdCwgMC45NzUpCgojIFJlc3VsdGFkb3MKY2F0KCJNZWRpYSBib290c3RyYXAgMTAsMDAwIHJlcDoiLCByb3VuZChtZWFuKGJsb2NrX2Jvb3QyJHQpLCAyKSwgIm1pbnV0b3NcbiIpCmNhdCgiSW50ZXJ2YWxvIGRlIGNvbmZpYW56YSBkZWwgOTUlIGNvbiBCbG9jayBCb290c3RyYXA6IFsiLCByb3VuZChpY19sb3dlcjIsIDIpLCAiLCIsIHJvdW5kKGljX3VwcGVyMiwgMiksICJdXG4iKQpjYXQoIkRpZmVyZW5jaWEgbWVkaWE6Iiwgcm91bmQobWVhbihibG9ja19ib290MiR0KSAtIG1lYW4oYmxvY2tfYm9vdCR0KSwgMyksICJtaW51dG9zXG5cbiIpCmBgYAoKNS4tIEdlbmVyZSB1biBudWV2byBpbnRlcnZhbG8gZGUgY29uZmlhbnphIGNvbiBlbCBudWV2byBib290c3RyYXAgcmVhbGl6YWRvIHkgY29tcGFyZWxvIGNvbiBlbCBxdWUgcmVzdWx0w7MgZGVsIHB1bnRvIDIuCmBgYHtyfQpjYXQoIkNvbXBhcmFjacOzbiBkZSBpbnRlcnZhbG9zOlxuIikKY2F0KCJCbG9jayBCb290c3RyYXAgNTAwMCByZXA6IFsiLCByb3VuZChpY19sb3dlciwgMiksICIsIiwgcm91bmQoaWNfdXBwZXIsIDIpLCAiXSBtaW51dG9zXG4iKQpjYXQoIkJsb2NrIEJvb3RzdHJhcCAxMDAwMCByZXA6IFsiLCByb3VuZChpY19sb3dlcjIsIDIpLCAiLCIsIHJvdW5kKGljX3VwcGVyMiwgMiksICJdIG1pbnV0b3NcbiIpCmNhdCgiRWwgaW50ZXJ2YWxvIGNvbiAxMCwwMDAgcmVwZXRpY2lvbmVzIHN1ZWxlIHNlciBsaWdlcmFtZW50ZSBtw6FzIGVzdGFibGUgKG1lbm9zIHZhcmlhYmlsaWRhZCkuXG4iKQpjYXQoIk5PVEE6IEVsIGJsb2NrIGJvb3RzdHJhcCBwcmVzZXJ2YSBsYSBlc3RydWN0dXJhIHRlbXBvcmFsIGRlIGxvcyBkYXRvcy5cblxuIikKYGBgCgoKIyMgPHNwYW4gc3R5bGU9J2NvbG9yOnJlZDsnPiAgRXhhbWVuIFByZWd1bnRhIDMgPC9zcGFuPgojIyMgPHNwYW4gc3R5bGU9J2NvbG9yOnJlZDsnPiAgVG9lcmlhIGRlIEZpbGFzPC9zcGFuPgoKVW4gY2VudHJvIGRlIGF0ZW5jacOzbiB0ZWxlZsOzbmljYSB0aWVuZSB1bmEgc29sYSBsw61uZWEgcGFyYSBhdGVuZGVyIGEgbG9zIGNsaWVudGVzLiBMYXMgbGxhbWFkYXMgbGxlZ2FuIGRlIG1hbmVyYSBhbGVhdG9yaWEgc2lndWllbmRvIHVuIHByb2Nlc28gZGUgUG9pc3NvbiBjb24gdW5hIHRhc2EgZGUgbGxlZ2FkYSBkZSA4MyBsbGFtYWRhcyBwb3IgaG9yYS4KCkNhZGEgbGxhbWFkYSBlcyBhdGVuZGlkYSBwb3IgdW4gw7puaWNvIG9wZXJhZG9yLCBjdXlvIHRpZW1wbyBkZSBzZXJ2aWNpbyBzaWd1ZSB1bmEgZGlzdHJpYnVjacOzbiBleHBvbmVuY2lhbCBjb24gdW5hIHRhc2EgZGUgOTAgY2xpZW50ZXMgcG9yIGhvcmEuCgpgYGB7cn0KbGlicmFyeShxdWV1ZWluZykKbGFtYmRhIDwtIDgzICAgIyBsbGFtYWRhcyBwb3IgaG9yYQptdSA8LSA5MCAgICAgICAjIGNsaWVudGVzIHBvciBob3JhCmMxIDwtIDEgICAgICAgICMgMSBsw61uZWEKYzIgPC0gMiAgCmBgYAoKUmVzcG9uZGEgbGFzIHNpZ3VpZW50ZXMgcHJlZ3VudGFzOgoKMS4tIMK/Q3XDoWwgZXMgZWwgbml2ZWwgZGUgc2F0dXJhY2nDs24gZGVsIHNpc3RlbWEsIGVsIG7Dum1lcm8gZGUgY2xpZW50ZXMgZW4gbGEgZmlsYSwgZWwgbsO6bWVybyBkZSBjbGllbnRlcyBlbiBlbCBzaXN0ZW1hLCBlbCB0aWVtcG8gcHJvbWVkaW8gZW4gbGEgZmlsYSB5IGVsIHRpZW1wbyBwcm9tZWRpbyBlbiBlbCBzaXN0ZW1hPwoKYGBge3J9Cm1vZGVsbzFfbGluZWEgPC0gTmV3SW5wdXQuTU1DKGxhbWJkYSA9IGxhbWJkYSwgbXUgPSBtdSwgYyA9IGMxLCBuID0gMCwgbWV0aG9kID0gMCkKcmVzdWx0YWRvMSA8LSBRdWV1ZWluZ01vZGVsKG1vZGVsbzFfbGluZWEpCiMgTW9zdHJhciByZXN1bHRhZG9zCmNhdCgiRmFjdG9yIGRlIHV0aWxpemFjacOzbiAocmhvKToiLCByb3VuZChyZXN1bHRhZG8xJFJPLCA0KSwgIlxuIikKY2F0KCJOw7ptZXJvIHByb21lZGlvIGRlIGNsaWVudGVzIGVuIGxhIGZpbGEgKExxKToiLCByb3VuZChyZXN1bHRhZG8xJExxLCA0KSwgIlxuIikKY2F0KCJOw7ptZXJvIHByb21lZGlvIGRlIGNsaWVudGVzIGVuIGVsIHNpc3RlbWEgKEwpOiIsIHJvdW5kKHJlc3VsdGFkbzEkTCwgNCksICJcbiIpCmNhdCgiVGllbXBvIHByb21lZGlvIGVuIGxhIGZpbGEgKFdxKToiLCByb3VuZChyZXN1bHRhZG8xJFdxICogNjAsIDIpLCAibWludXRvc1xuIikKY2F0KCJUaWVtcG8gcHJvbWVkaW8gZW4gZWwgc2lzdGVtYSAoVyk6Iiwgcm91bmQocmVzdWx0YWRvMSRXICogNjAsIDIpLCAibWludXRvc1xuIikKCmBgYAoqKlIqKjogTG9zIHJlc3R1bGFkbyBhcnJvamFuIHF1ZSBlbCBzaXN0ZW1hIGVzdMOhIHNvYnJlc2F0dXJhZG8gYWwgOTIuMjIlLiBMb3MgY2xpZW50ZXMgZXNwZXJhbiBjYXNpIDggbWludXRvcyBlbiBsYSBmaWxhLCBjb24gbcOhcyBkZSAxMCBwZXJzb25hcyBlc3BlcmFuZG8gY29uc3RhbnRlbWVudGUuCgoqKjIuLSBTdXBvbmdhIHF1ZSBlbCBnZXJlbnRlIGRlbCBjZW50cm8gcmV2aXPDsyBlbCBhbsOhbGlzaXMgcXVlIHVzdGVkIHJlYWxpesOzIHkgZGVjaWRpw7MgYWJyaXIgdW5hIGzDrW5lYSBtw6FzIHRlbmllbmRvIDIgZW4gdG90YWwsIMK/Y8OzbW8gY2FtYmlhIHN1IGFuw6FsaXNpcyBhbnRlcmlvciBhZ3JlZ2FuZG8gw6lzdGEgbMOtbmVhIHRlbGVmw7NuaWNhIGFkaWNpb25hbCAodnVlbHZhIGEgY2FsY3VsYXIsIHJlcG9ydGUgbGFzIHZhcmlhYmxlcyBzb2xpY2l0YWRhcyBlbiBsYSBwcmVndW50YSAxIHkgY29tcGFyZSBsb3MgcmVzdWx0YWRvcyBjb24gbG9zIGRlIGxhIHByZWd1bnRhIDEpPyoqCgpgYGB7cn0KbW9kZWxvMl9saW5lYXMgPC0gTmV3SW5wdXQuTU1DKGxhbWJkYSA9IGxhbWJkYSwgbXUgPSBtdSwgYyA9IGMyLCBuID0gMCwgbWV0aG9kID0gMCkKCiMgUmVzb2x2ZXIgZWwgbW9kZWxvCnJlc3VsdGFkbzIgPC0gUXVldWVpbmdNb2RlbChtb2RlbG8yX2xpbmVhcykKCiMgTW9zdHJhciByZXN1bHRhZG9zCmNhdCgiRmFjdG9yIGRlIHV0aWxpemFjacOzbiAocmhvKToiLCByb3VuZChyZXN1bHRhZG8yJFJPLCA0KSwgIlxuIikKY2F0KCJOw7ptZXJvIHByb21lZGlvIGRlIGNsaWVudGVzIGVuIGxhIGZpbGEgKExxKToiLCByb3VuZChyZXN1bHRhZG8yJExxLCA0KSwgIlxuIikKY2F0KCJOw7ptZXJvIHByb21lZGlvIGRlIGNsaWVudGVzIGVuIGVsIHNpc3RlbWEgKEwpOiIsIHJvdW5kKHJlc3VsdGFkbzIkTCwgNCksICJcbiIpCmNhdCgiVGllbXBvIHByb21lZGlvIGVuIGxhIGZpbGEgKFdxKToiLCByb3VuZChyZXN1bHRhZG8yJFdxICogNjAsIDIpLCAibWludXRvc1xuIikKY2F0KCJUaWVtcG8gcHJvbWVkaW8gZW4gZWwgc2lzdGVtYSAoVyk6Iiwgcm91bmQocmVzdWx0YWRvMiRXICogNjAsIDIpLCAibWludXRvc1xuIikKCmBgYAoqKlIqKjogQWhvcmEgY29uIGVzdGUgY2FtYmlvIGRlIGFncmVnYXIgZG9zIGzDrW5lYXMsIGVsIHNpc3RlbWEgZXMgbXV5IGRpc3RpbnRvLiBMb3MgY2xpZW50ZXMgZXNwZXJhbiBzb2xvIDE4IHNlZ3VuZG9zIGVuIGx1Z2FyIGRlIDcuNzEgbWludXRvcy4KCgojIyA8c3BhbiBzdHlsZT0nY29sb3I6cmVkOyc+ICBFeGFtZW4gUHJlZ3VudGEgNCA8L3NwYW4+IAoKTG9zIG5lZ29jaW9zIGRlIEFjbWUgU3RlZWwgRmFicmljYXRvcnMgaGFuIHNpZG8gbXV5IHByw7NzcGVyb3MgZW4gbG9zIMO6bHRpbW9zIGNpbmNvIGHDsW9zLiBMYSBjb21wYcOxw61hIGZhYnJpY2EgdW5hIGFtcGxpYSBnYW1hIGRlIHByb2R1Y3RvcyBkZSBhY2VybywgY29tbyBiYXJhbmRhbGVzLCBlc2NhbGVyYXMgeSBtYXJjb3MgZGUgYWNlcm8gZXN0cnVjdHVyYWwgbGlnZXJvLiBFbCBtw6l0b2RvIG1hbnVhbCB2aWdlbnRlIHBhcmEgbWFuZWpvIGRlIG1hdGVyaWFsZXMgb2Nhc2lvbmEgdW4gZXhjZXNvIGRlIGludmVudGFyaW8geSBjb25nZXN0aW9uYW1pZW50b3MuIEFjbWUgZXN0w6EgY29uc2lkZXJhbmRvIHNpIGRlYmUgY29tcHJhciB1biBzaXN0ZW1hIGRlIHRyYW5zcG9ydGUgcXVlIHBlbmRlIGRlIHVuIHJpZWwgKG1vbm9yaWVsKSwgbyB1biB2ZWjDrWN1bG8gbW9udGFjYXJnYXMsIHBhcmEgaW5jcmVtZW50YXIgc3UgY2FwYWNpZGFkIHkgbWVqb3JhciBzdSBlZmljaWVuY2lhIG1hbnVmYWN0dXJlcmEuCgpMb3MgcmVzdWx0YWRvcyBhbnVhbGVzIGRlbCBzaXN0ZW1hLCBhbnRlcyBkZSBpbXB1ZXN0b3MsIGRlcGVuZGVuIGRlIGxhIGRlbWFuZGEgZnV0dXJhLiBTaSBsYSBkZW1hbmRhIHNlIG1hbnRpZW5lIGVuIGVsIG5pdmVsIGFjdHVhbCwgbG8gY3VhbCB0aWVuZSB1bmEgcHJvYmFiaWxpZGFkIGRlIDAuNTAsIGVsIGFob3JybyBhbnVhbCBxdWUgcHJvZHVjaXLDoSBlbCB0cmFuc3BvcnRhZG9yIGVsZXZhZG8gKG1vbm9yaWVsKSBzZXLDoSBkZSAkMTAsMDAwLiBTaSBsYSBkZW1hbmRhIGF1bWVudGEgcGVybWl0aXLDoSBhaG9ycmFyICQyNSwwMDAgYWwgYcOxbyBwb3IgbGEgZWZpY2llbmNpYSBvcGVyYXRpdmEsIGFkZW3DoXMgZGUgbGFzIG51ZXZhcyB2ZW50YXMuIEZpbmFsbWVudGUsIHNpIGxhIGRlbWFuZGEgY2FlLCBwcm92b2NhcsOhIHVuYSBww6lyZGlkYSBhbnVhbCBlc3RpbWFkYSBlbiAkNjUsMDAwLgoKU2UgZXN0aW1hIHVuYSBwcm9iYWJpbGlkYWQgZGUgMC4zMCBkZSBxdWUgbGEgZGVtYW5kYSBzZWEgYWx0YSB5IGRlIDAuMjAgZGUgcXVlIHNlYSBiYWphLiBTaSBzZSBjb21wcmEsIGVsIG1vbnRhY2FyZ2FzLCBsb3MgcmVzdWx0YWRvcyBhbnVhbGVzIHNlcsOhbiBkZSAkNSwwMDAgc2kgbGEgZGVtYW5kYSBubyBjYW1iaWEsICQxMCwwMDAgc2kgbGEgZGVtYW5kYSBhdW1lbnRhIHkg4oCTJDI1LDAwMCBzaSBsYSBkZW1hbmRhIGNhZS4KCmBgYHtyfQojIExpYnJlcmlhcwpsaWJyYXJ5KERpYWdyYW1tZVIpCmxpYnJhcnkodGlkeXZlcnNlKQoKIyBEZWZpbmlyIHByb2JhYmlsaWRhZGVzIHkgcGFyw6FtZXRyb3MKcF9hbHRhICA8LSAwLjMwCnBfaWd1YWwgPC0gMC41MApwX2JhamEgIDwtIDAuMjAKCmFoX21vbm9fYWx0YSAgPC0gMjUwMDAKYWhfbW9ub19pZ3VhbCA8LSAxMDAwMAphaF9tb25vX2JhamEgIDwtIC02NTAwMAoKYWhfbW9udF9hbHRhICA8LSAxMDAwMAphaF9tb250X2lndWFsIDwtICA1MDAwCmFoX21vbnRfYmFqYSAgPC0gLTI1MDAwCgojIENhbGN1bGFyIHZhbG9yZXMgZXNwZXJhZG9zIChWRSkKdmVfbW9ub3JpZWwgICA8LSBwX2FsdGEqYWhfbW9ub19hbHRhICsgcF9pZ3VhbCphaF9tb25vX2lndWFsICsgcF9iYWphKmFoX21vbm9fYmFqYQp2ZV9tb250YWNhcmdhczwtIHBfYWx0YSphaF9tb250X2FsdGEgKyBwX2lndWFsKmFoX21vbnRfaWd1YWwgKyBwX2JhamEqYWhfbW9udF9iYWphCgpjYXQoIlZFIE1vbm9yaWVsOiAgICQiLCBmb3JtYXQocm91bmQodmVfbW9ub3JpZWwsIDIpLCBiaWcubWFyaz0iLCIpLCAiXG4iLCBzZXAgPSAiIikKY2F0KCJWRSBNb250YWNhcmdhczokIiwgZm9ybWF0KHJvdW5kKHZlX21vbnRhY2FyZ2FzLCAyKSwgYmlnLm1hcms9IiwiKSwgIlxuIiwgc2VwID0gIiIpCgptZWpvcl9vcGNpb24gPC0gaWZlbHNlKHZlX21vbnRhY2FyZ2FzID4gdmVfbW9ub3JpZWwsICJNb250YWNhcmdhcyIsICJNb25vcmllbCIpCmNhdCgiTWVqb3IgYWx0ZXJuYXRpdmE6IiwgbWVqb3Jfb3BjaW9uLCAiXG4iKQoKIyBUYWJsYSByZXN1bWVuIGRlIGVzY2VuYXJpb3MKcmVzdW1lbiA8LSB0cmliYmxlKAogIH5BbHRlcm5hdGl2YSwgfkRlbWFuZGEsIH5Qcm9iLCB+QWhvcnJvX1VTRCwKICAiTW9ub3JpZWwiLCAgICAiQWx0YSIsICAgcF9hbHRhLCAgYWhfbW9ub19hbHRhLAogICJNb25vcmllbCIsICAgICJJZ3VhbCIsICBwX2lndWFsLCBhaF9tb25vX2lndWFsLAogICJNb25vcmllbCIsICAgICJCYWphIiwgICBwX2JhamEsICBhaF9tb25vX2JhamEsCiAgIk1vbnRhY2FyZ2FzIiwgIkFsdGEiLCAgIHBfYWx0YSwgIGFoX21vbnRfYWx0YSwKICAiTW9udGFjYXJnYXMiLCAiSWd1YWwiLCAgcF9pZ3VhbCwgYWhfbW9udF9pZ3VhbCwKICAiTW9udGFjYXJnYXMiLCAiQmFqYSIsICAgcF9iYWphLCAgYWhfbW9udF9iYWphCikgJT4lCiAgbXV0YXRlKFByb2IgPSBzY2FsZXM6OnBlcmNlbnQoUHJvYiwgYWNjdXJhY3kgPSAxKSwKICAgICAgICAgQWhvcnJvX1VTRCA9IHNjYWxlczo6ZG9sbGFyKEFob3Jyb19VU0QpKQoKcmVzdW1lbgoKIyBWaXN1YWxpemFuZG8gZWwgw6FyYm9sIGRlIGRlY2lzacOzbgpEaWFncmFtbWVSOjpnclZpeigiCmRpZ3JhcGggZGVjaXNpb25fdHJlZSB7CiAgZ3JhcGggW3JhbmtkaXI9TFJdCiAgbm9kZSBbc2hhcGU9Ym94LCBzdHlsZT1maWxsZWQsIGZpbGxjb2xvcj1saWdodGJsdWVdOwoKICBJbmljaW8gW2xhYmVsPSdEZWNpc2nDs246IFNpc3RlbWEgZGUgbWFuZWpvIGRlIG1hdGVyaWFsZXMnXTsKCiAgTW9ub3JpZWwgICAgW2xhYmVsPSdNb25vcmllbCddOwogIE1vbnRhY2FyZ2FzIFtsYWJlbD0nTW9udGFjYXJnYXMnXTsKCiAgTW9ub19BbHRhICAgW2xhYmVsPSdBbHRhICgwLjMwKVxcbkFob3JybyA9ICQyNSwwMDAnXTsKICBNb25vX0lndWFsICBbbGFiZWw9J0lndWFsICgwLjUwKVxcbkFob3JybyA9ICQxMCwwMDAnXTsKICBNb25vX0JhamEgICBbbGFiZWw9J0JhamEgKDAuMjApXFxuQWhvcnJvID0gLSQ2NSwwMDAnXTsKCiAgTW9udF9BbHRhICAgW2xhYmVsPSdBbHRhICgwLjMwKVxcbkFob3JybyA9ICQxMCwwMDAnXTsKICBNb250X0lndWFsICBbbGFiZWw9J0lndWFsICgwLjUwKVxcbkFob3JybyA9ICQ1LDAwMCddOwogIE1vbnRfQmFqYSAgIFtsYWJlbD0nQmFqYSAoMC4yMClcXG5BaG9ycm8gPSAtJDI1LDAwMCddOwoKICBJbmljaW8gLT4gTW9ub3JpZWwKICBJbmljaW8gLT4gTW9udGFjYXJnYXMKCiAgTW9ub3JpZWwgLT4gTW9ub19BbHRhICBbbGFiZWw9JzAuMzAnXQogIE1vbm9yaWVsIC0+IE1vbm9fSWd1YWwgW2xhYmVsPScwLjUwJ10KICBNb25vcmllbCAtPiBNb25vX0JhamEgIFtsYWJlbD0nMC4yMCddCgogIE1vbnRhY2FyZ2FzIC0+IE1vbnRfQWx0YSAgW2xhYmVsPScwLjMwJ10KICBNb250YWNhcmdhcyAtPiBNb250X0lndWFsIFtsYWJlbD0nMC41MCddCiAgTW9udGFjYXJnYXMgLT4gTW9udF9CYWphICBbbGFiZWw9JzAuMjAnXQp9CiIpCmBgYAoKUmVzcG9uZGEgbGFzIHNpZ3VpZW50ZXMgcHJlZ3VudGFzOgoKMS4tIMK/Q3XDoWwgZXMgbGEgbWVqb3IgYWx0ZXJuYXRpdmEgcGFyYSBBQ01FPwogIExhIG1lam9yIGFsdGVybmF0aXZhIHBhcmEgQUNNRSBlcyBNb250YWNhcmdhcywgcG9ycXVlIHN1IHZhbG9yIGVzcGVyYWRvIGVzIG1heW9yIHkgc3Ugcmllc2dvIGRlIHDDqXJkaWRhIGVzIG1lbm9yIHF1ZSBlbCBkZWwgTW9ub3JyaWVsLgoKMi4tIMK/Q3XDoWwgc2Vyw61hIGVsIGFob3JybyBlc3BlcmFkbyBlbiBlbCBsYXJnbyBwbGF6bz8KICBFbCBhaG9ycm8gZXNwZXJhZG8gYSBsYXJnbyBwbGF6byBzZXLDrWEgZGUgNTAwIGTDs2xhcmVzIHBvciBhw7FvLCBiYXNhZG8gZW4gZWwgdmFsb3IgZXNwZXJhZG8gZGVsIE1vbnRhY2FyZ2FzLgoKIyMgPHNwYW4gc3R5bGU9J2NvbG9yOnJlZDsnPiAgRXhhbWVuIFByZWd1bnRhIDUgPC9zcGFuPiAKCioqU2UgdGllbmVuIGRvcyBkYWRvcyBkZSAyMCBsYWRvcyBjYWRhIHVuby4gRXNvcyBkYWRvcyBzZSBsYW56YW4gZGUgbWFuZXJhIHNpbXVsdMOhbmVhIHBhcmEgdmVyIGN1w6FudG8gY2FlIGVuIGFtYm9zLioqCgpgYGB7cn0Kc2V0LnNlZWQoNTIwKSAgCm51bV9zaW11bGF0aW9uc18xMGsgPC0gMTAwMDAgICAjIFByaW1lcmEgc2ltdWxhY2nDs24KbnVtX3NpbXVsYXRpb25zXzUwayA8LSA1MDAwMCAgICMgU2VndW5kYSBzaW11bGFjacOzbgpgYGAKIApgYGB7cn0KIyBTaW11bGFjaW9uIGNvbiAxMCwwMDAgaXRlcmFjaW9uZXMKZGljZTFfMTBrIDwtIHNhbXBsZSgxOjIwLCBudW1fc2ltdWxhdGlvbnNfMTBrLCByZXBsYWNlID0gVFJVRSkKZGljZTJfMTBrIDwtIHNhbXBsZSgxOjIwLCBudW1fc2ltdWxhdGlvbnNfMTBrLCByZXBsYWNlID0gVFJVRSkKCnN1bV9kaWNlc18xMGsgPC0gZGljZTFfMTBrICsgZGljZTJfMTBrCm11bHRfZGljZXNfMTBrIDwtIGRpY2UxXzEwayAqIGRpY2UyXzEwawoKIyBFc3RpbWFtb3MgbGFzIDMgcHJvYmFiaWxpZGFkZXMKcHJvYl9zdW1hXzMwXzEwayA8LSBtZWFuKHN1bV9kaWNlc18xMGsgPj0gMzApCnByb2Jfc3VtYV8yN18xMGsgPC0gbWVhbihzdW1fZGljZXNfMTBrID09IDI3KQpwcm9iX211bHRfMzAwXzEwayA8LSBtZWFuKG11bHRfZGljZXNfMTBrID49IDMwMCkKCiMgTW9zdHJhbW9zIGxvcyByZXN1bHRhZG9zCnByaW50KHBhc3RlKCIxLiBQcm9iYWJpbGlkYWQgc3VtYSA+PSAzMDoiLCByb3VuZChwcm9iX3N1bWFfMzBfMTBrICogMTAwLCAyKSwgIiUiKSkKcHJpbnQocGFzdGUoIjIuIFByb2JhYmlsaWRhZCBzdW1hID0gMjc6Iiwgcm91bmQocHJvYl9zdW1hXzI3XzEwayAqIDEwMCwgMiksICIlIikpCnByaW50KHBhc3RlKCIzLiBQcm9iYWJpbGlkYWQgbXVsdGlwbGljYWNpw7NuID49IDMwMDoiLCByb3VuZChwcm9iX211bHRfMzAwXzEwayAqIDEwMCwgMiksICIlIikpCmBgYAogQSB1c3RlZCBzZSBsZSBwaWRlIHF1ZSByZWFsaWNlIHVuYSBzaW11bGFjacOzbiBkZSBtb250ZWNhcmxvIHBhcmEgY2FsY3VsYXIgbG8gc2lndWllbnRlOgoKMS4tIMK/Q3XDoWwgZXMgbGEgcHJvYmFiaWxpZGFkIGRlIHF1ZSBsYSBzdW1hIGRlIGxvcyByZXN1bHRhZG9zIHNlYSBtYXlvciBvIGlndWFsIGEgMzA/IFI6IDE2LjQ3ICUKCjIuLSDCv0N1w6FsIGVzIGxhIHByb2JhYmlsaWRhZCBkZSBxdWUgbGEgc3VtYSBkZSBsb3MgcmVzdWx0YWRvcyBzZWEgaWd1YWwgYSAyNz8gICBSOiAzLjY4ICUKCjMuLSDCv0N1w6FsIGVzIGxhIHByb2JhYmlsaWRhZCBkZSBxdWUgbGEgbXVsdGlwbGljYWNpw7NuIGRlIHN1cyByZXN1bHRhZG9zIHNlYSBtYXlvciBvIGlndWFsIGEgMzAwPyBSOiA1LjIyJQoKClBhcmEgcmVhbGl6YXIgZXN0ZSBlamVyY2ljaW8gcG9yIGZhdm9yIGhhZ2EgdXNvIGRlbCBzZWVkIDUyMCB5IHJlYWxpY2UgZWwgZWplcmNpY2lvIHBhcmEgMTAsMDAwIGl0ZXJhY2lvbmVzCiAKKipVbmEgdmV6IHF1ZSByZWFsaXrDsyBsbyBhbnRlcmlvciwgdnVlbHZhIGEgcmVhbGl6YXIgbG9zIHRyZXMgZWplcmNpY2lvcyAocHJlZ3VudGFzKSBwZXJvIGFob3JhIGNvbiB1biB0b3RhbCBkZSA1MCwwMDAgaXRlcmFjaW9uZXMgeSBjb21wYXJlIGxvcyByZXN1bHRhZG9zIGRlIGFtYm9zIGVqZXJjaWNpb3MgY29uIGxvcyB2YWxvcmVzIHJlYWxlcyBkZSBxdWUgb2N1cnJhbiDDqXN0b3MgZXNjZW5hcmlvcy4gRXMgZGVjaXIsIGN1w6FsIGZ1ZSBtw6FzIGNlcmNhbm8gYSBsYSByZWFsaWRhZC4qKgoKYGBge3J9CiMgR2VuZXJhbW9zIGxvcyBsYW56YW1pZW50b3MgZGUgbG9zIGRvcyBkYWRvcyBkZSAyMCBsYWRvcwpkaWNlMV81MGsgPC0gc2FtcGxlKDE6MjAsIG51bV9zaW11bGF0aW9uc181MGssIHJlcGxhY2UgPSBUUlVFKQpkaWNlMl81MGsgPC0gc2FtcGxlKDE6MjAsIG51bV9zaW11bGF0aW9uc181MGssIHJlcGxhY2UgPSBUUlVFKQoKIyBDYWxjdWxhbW9zIGxhIHN1bWEgZGUgbG9zIGRvcyBkYWRvcwpzdW1fZGljZXNfNTBrIDwtIGRpY2UxXzUwayArIGRpY2UyXzUwawoKIyBDYWxjdWxhbW9zIGxhIG11bHRpcGxpY2FjacOzbiBkZSBsb3MgZG9zIGRhZG9zCm11bHRfZGljZXNfNTBrIDwtIGRpY2UxXzUwayAqIGRpY2UyXzUwawoKIyBFc3RpbWFtb3MgbGFzIHByb2JhYmlsaWRhZGVzCnByb2Jfc3VtYV8zMF81MGsgPC0gbWVhbihzdW1fZGljZXNfNTBrID49IDMwKQpwcm9iX3N1bWFfMjdfNTBrIDwtIG1lYW4oc3VtX2RpY2VzXzUwayA9PSAyNykKcHJvYl9tdWx0XzMwMF81MGsgPC0gbWVhbihtdWx0X2RpY2VzXzUwayA+PSAzMDApCgojIE1vc3RyYW1vcyBsb3MgcmVzdWx0YWRvcwpwcmludChwYXN0ZSgiMS4gUHJvYmFiaWxpZGFkIHN1bWEgPj0gMzA6Iiwgcm91bmQocHJvYl9zdW1hXzMwXzUwayAqIDEwMCwgMiksICIlIikpCnByaW50KHBhc3RlKCIyLiBQcm9iYWJpbGlkYWQgc3VtYSA9IDI3OiIsIHJvdW5kKHByb2Jfc3VtYV8yN181MGsgKiAxMDAsIDIpLCAiJSIpKQpwcmludChwYXN0ZSgiMy4gUHJvYmFiaWxpZGFkIG11bHRpcGxpY2FjacOzbiA+PSAzMDA6Iiwgcm91bmQocHJvYl9tdWx0XzMwMF81MGsgKiAxMDAsIDIpLCAiJSIpKQpgYGAKCmBgYHtyfQojIFZhbG9yZXMgcmVhbGVzIHByb3BvcmNpb25hZG9zCnByb2JfcmVhbF9zdW1hXzMwIDwtIDE2LjUKcHJvYl9yZWFsX3N1bWFfMjcgPC0gMy41CnByb2JfcmVhbF9tdWx0XzMwMCA8LSA1LjI1CgojIFN1bWEgPj0gMzAKZXJyb3JfMTBrX3N1bWEzMCA8LSBhYnMocHJvYl9zdW1hXzMwXzEwayAqIDEwMCAtIHByb2JfcmVhbF9zdW1hXzMwKQplcnJvcl81MGtfc3VtYTMwIDwtIGFicyhwcm9iX3N1bWFfMzBfNTBrICogMTAwIC0gcHJvYl9yZWFsX3N1bWFfMzApCmNhdCgiU3VtYT49MzAgIHwiLCBwcm9iX3JlYWxfc3VtYV8zMCwgIiUgfCIsIHJvdW5kKHByb2Jfc3VtYV8zMF8xMGsgKiAxMDAsIDIpLCAiJSB8IiwgCiAgICByb3VuZChwcm9iX3N1bWFfMzBfNTBrICogMTAwLCAyKSwgIiUgfCIsIHJvdW5kKGVycm9yXzEwa19zdW1hMzAsIDIpLCAiJSB8IiwgCiAgICByb3VuZChlcnJvcl81MGtfc3VtYTMwLCAyKSwgIiVcbiIpCgojIFN1bWEgPSAyNwplcnJvcl8xMGtfc3VtYTI3IDwtIGFicyhwcm9iX3N1bWFfMjdfMTBrICogMTAwIC0gcHJvYl9yZWFsX3N1bWFfMjcpCmVycm9yXzUwa19zdW1hMjcgPC0gYWJzKHByb2Jfc3VtYV8yN181MGsgKiAxMDAgLSBwcm9iX3JlYWxfc3VtYV8yNykKY2F0KCJTdW1hPTI3ICAgfCIsIHByb2JfcmVhbF9zdW1hXzI3LCAiJSB8Iiwgcm91bmQocHJvYl9zdW1hXzI3XzEwayAqIDEwMCwgMiksICIlIHwiLCAKICAgIHJvdW5kKHByb2Jfc3VtYV8yN181MGsgKiAxMDAsIDIpLCAiJSB8Iiwgcm91bmQoZXJyb3JfMTBrX3N1bWEyNywgMiksICIlIHwiLCAKICAgIHJvdW5kKGVycm9yXzUwa19zdW1hMjcsIDIpLCAiJVxuIikKCiMgTXVsdGlwbGljYWNpw7NuID49IDMwMAplcnJvcl8xMGtfbXVsdDMwMCA8LSBhYnMocHJvYl9tdWx0XzMwMF8xMGsgKiAxMDAgLSBwcm9iX3JlYWxfbXVsdF8zMDApCmVycm9yXzUwa19tdWx0MzAwIDwtIGFicyhwcm9iX211bHRfMzAwXzUwayAqIDEwMCAtIHByb2JfcmVhbF9tdWx0XzMwMCkKY2F0KCJNdWx0Pj0zMDAgfCIsIHByb2JfcmVhbF9tdWx0XzMwMCwgIiUgfCIsIHJvdW5kKHByb2JfbXVsdF8zMDBfMTBrICogMTAwLCAyKSwgIiUgfCIsIAogICAgcm91bmQocHJvYl9tdWx0XzMwMF81MGsgKiAxMDAsIDIpLCAiJSB8Iiwgcm91bmQoZXJyb3JfMTBrX211bHQzMDAsIDIpLCAiJSB8IiwgCiAgICByb3VuZChlcnJvcl81MGtfbXVsdDMwMCwgMiksICIlXG4iKQoKIyBEZXRlcm1pbmFyIGN1w6FsIGVzIG3DoXMgcHJlY2lzYSAKZXJyb3JfdG90YWxfMTBrIDwtIGVycm9yXzEwa19zdW1hMzAgKyBlcnJvcl8xMGtfc3VtYTI3ICsgZXJyb3JfMTBrX211bHQzMDAKZXJyb3JfdG90YWxfNTBrIDwtIGVycm9yXzUwa19zdW1hMzAgKyBlcnJvcl81MGtfc3VtYTI3ICsgZXJyb3JfNTBrX211bHQzMDAKCmNhdCgiRXJyb3IgdG90YWwgc2ltdWxhY2nDs24gMTBrOiIsIHJvdW5kKGVycm9yX3RvdGFsXzEwaywgMiksICIlXG4iKQpjYXQoIkVycm9yIHRvdGFsIHNpbXVsYWNpw7NuIDUwazoiLCByb3VuZChlcnJvcl90b3RhbF81MGssIDIpLCAiJVxuIikKCmlmIChlcnJvcl90b3RhbF81MGsgPCBlcnJvcl90b3RhbF8xMGspIHsKICBjYXQoIlJFU1VMVEFETzogTGEgc2ltdWxhY2nDs24gY29uIDUwLDAwMCBpdGVyYWNpb25lcyBlcyBNw4FTIFBSRUNJU0FcbiIpCn0gZWxzZSB7CiAgY2F0KCJSRVNVTFRBRE86IExhIHNpbXVsYWNpw7NuIGNvbiAxMCwwMDAgaXRlcmFjaW9uZXMgZXMgTcOBUyBQUkVDSVNBXG4iKQp9CmBgYAoKMS4tIEVuIGVsIHByaW1lciBjYXNvIGxhIHByb2JhYmlsaWRhZCByZWFsIGVzIGRlIDE2LjUlCgoyLi0gRW4gZWwgc2VndW5kbyBjYXNvIGxhIHByb2JhYmlsaWRhZCByZWFsIGVzIGRlIDMuNSUKCjMuLSBFbiBlbCB0ZXJjZXIgY2FzbyBsYSBwcm9iYWJpbGlkYWQgZXMgZGUgNS4yNSUKCioqUioqOkxhIHNpbXVsYWNpw7NuIGRlIE1vbnRlIENhcmxvIGNvbiAxMCwwMDAgaXRlcmFjaW9uZXMgZnVlIG11eSBjZXJjYW5hIGEgbGEgcmVhbGlkYWQuIExvcyByZXN1bHRhZG9zIG1vc3RyYXJvbiBxdWUgbGEgcHJvYmFiaWxpZGFkIGRlIHN1bWEg4omlIDMwIGZ1ZSAxNi40NyUgdnMuIDE2LjUlIHJlYWwsIHN1bWEgPSAyNyBmdWUgMy42OCUgdnMuIDMuNSUgcmVhbCwgeSBtdWx0aXBsaWNhY2nDs24g4omlIDMwMCBmdWUgNS4yMiUgdnMuIDUuMjUlIHJlYWwuIEVsIGVycm9yIHRvdGFsIGZ1ZSBzb2xvIDAuMjQlLCBkZW1vc3RyYW5kbyBxdWUgMTAsMDAwIGl0ZXJhY2lvbmVzIGZ1ZSBleGNlcGNpb25hbG1lbnRlIHByZWNpc28gcGFyYSBlc3RlIGVqZXJjaWNpby4KCgoKCgoKCgoKCgoK