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