Un dado de \(k\) caras
En R podemos simular un dado de \(k\) caras fácilmente:
rDado<-function(n,k){
return(ceiling(k*runif(n)))
}
Por ejemplo, si queremos observar el lanzamiento de 10 dados de 20 caras, podemos invocar:
replicate(10,rDado(1,20))
[1] 4 1 13 20 16 4 18 7 20 14
o podríamos aprovechar la manera como escribimos la función para obtener un resultado similar…
rDado(10,20)
[1] 1 12 14 16 15 20 9 17 15 18
En los diversos experimentos que realizaremos hoy, vamos a trabajar con dados de seis caras.
Podemos escribir una función para simular un dado de seis caras, que sirva para encapsular la función anterior y nos permita trabajar con los diversos experimentos planteados.
d6<-function(n){
return(rDado(n,6))
}
Ahora podemos utilizar la función para hacer varios lanzamientos de dados de seis, por ejemplo siete dados de seis
d6(7)
[1] 4 5 2 2 1 1 1
Ahora vamos a atacar desde el punto de vista empírico los experimentos mencionados en clase.
Experimentos
La idea es repetir el experimento suficientes veces hasta tener una idea razonable de cuanto valen las diversas probabilidades y cual es el espacio de resultados.
Es conveniente determinar una buena forma de visualizar cada corrida de simulación para tener una idea de los diversos valores.
Evidentemente la visualización correcta para cada caso depende de una multiplicidad de factores, como son:
- El tipo de experimento y su espacio de resultados.
- La cantidad de veces que se repite el experimento.
E1: Un dado de seis
Este experimento es relativamente sencillo, el espacio de resultados consiste en el conjunto de los valores \(\{1,2,3,4,5,6\}\) y las probabilidades de cada valor son todas iguales a \(\frac{1}{6}\) ya que el dado es justo.
Para mostrar esto podemos hacer el experimento varias veces.
Pocas veces
E11<-d6(60)
table(E11)/length(E11)
E11
1 2 3 4 5 6
0.1000000 0.2333333 0.1666667 0.2166667 0.1833333 0.1000000
summary(E11)
Min. 1st Qu. Median Mean 3rd Qu. Max.
1.00 2.00 3.50 3.45 5.00 6.00
stripchart(E11,method="stack",pch=19)
abline(h=1-0.05)
points(mean(E11),1-0.1,pch=17,col="red")

hist(E11,col="lightgreen",breaks=1:7-0.5,prob=TRUE)

boxplot(E11,col="lightgreen")

Muchas veces
E12<-d6(60000)
table(E12)/length(E12)
E12
1 2 3 4 5 6
0.1665667 0.1660167 0.1642667 0.1670667 0.1681667 0.1679167
summary(E12)
Min. 1st Qu. Median Mean 3rd Qu. Max.
1.000 2.000 4.000 3.508 5.000 6.000
hist(E12,col="lightgreen",breaks=1:7-0.5,prob=TRUE)

boxplot(E12,col="lightgreen")

E2: Suma de tres dados de seis
rSumaDe3<-function(n){
replicate(n,sum(d6(3)))
}
Este experimento es un poco más complicado, el espacio de resultados consiste en el conjunto de los valores \(\{3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18\}\) y las probabilidades de cada valor se pueden calcular trabajando sobre el espacio equiprobable de las tripletas \((x_1,x_2,x_3)\) con \(x_i\in\{1,2,3,4,5,6\}\) para \(i\in\{1,2,3\}\).
Para estimar las probabilidades repetir el experimento varias veces.
Pocas veces
E21<-rSumaDe3(216)
table(E21)/length(E21)
E21
3 4 5 6 7
0.004629630 0.009259259 0.027777778 0.055555556 0.060185185
8 9 10 11 12
0.097222222 0.148148148 0.101851852 0.087962963 0.138888889
13 14 15 16 17
0.101851852 0.069444444 0.041666667 0.037037037 0.004629630
18
0.013888889
summary(E21)
Min. 1st Qu. Median Mean 3rd Qu. Max.
3.00 8.00 10.00 10.55 13.00 18.00
stripchart(E21,method="stack",pch=19,ylim=c(0.8,2),xlim=c(3,18))
abline(h=1-0.05)
points(mean(E21),1-0.1,pch=17,col="red")

hist(E21,col="lightgreen",breaks=3:19-0.5,prob=TRUE)

boxplot(E21,col="lightgreen")

Como se puede apreciar, ya el diagrama de puntos no es particularmente útil, pues en realidad nos da casi la misma información que el histograma. ### Muchas veces
E22<-rSumaDe3(60000)
table(E22)/length(E22)
E22
3 4 5 6 7
0.004250000 0.013966667 0.028566667 0.045333333 0.068816667
8 9 10 11 12
0.097333333 0.113816667 0.125983333 0.126266667 0.115866667
13 14 15 16 17
0.097016667 0.069133333 0.047916667 0.027783333 0.013716667
18
0.004233333
summary(E22)
Min. 1st Qu. Median Mean 3rd Qu. Max.
3.00 8.00 11.00 10.51 13.00 18.00
hist(E22,col="lightgreen",breaks=3:19-0.5,prob=TRUE)

boxplot(E22,col="lightgreen")

E3: Número de veces que sale el seis en veinte lanzamientos
De nuevo, el experimento es más complicado que el anterior. Debería estar claro que el espacio de resultados es el conjunto de los números \(\{0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20\}\) pero ahora deberíamos notar que incluso una cantidad enorme de réplicas del experimento, no revela el espacio de resultados completo, por lo que para estimar de manera razonable las probabilidades de manera empírica, tenemos que irnos a números verdaderamente grandes.
rTotalDe6En20<-function(n){
replicate(n,sum(d6(20)==6))
}
m<-600000
ti<-proc.time()
E32<-rTotalDe6En20(m)
tf<-proc.time()
t<-(tf-ti)[3]
tiempolargo<-((6^20/m)*t)/(3600*24*365.25)
table(E32)/length(E32)
E32
0 1 2 3 4
2.587667e-02 1.039450e-01 1.987567e-01 2.384750e-01 2.018067e-01
5 6 7 8 9
1.296633e-01 6.480167e-02 2.557833e-02 8.296667e-03 2.258333e-03
10 11 12 13
4.583333e-04 7.000000e-05 1.166667e-05 1.666667e-06
summary(E32)
Min. 1st Qu. Median Mean 3rd Qu. Max.
0.000 2.000 3.000 3.332 4.000 13.000
hist(E32,col="lightgreen",breaks=0:21-0.5,prob=TRUE)

boxplot(E32,col="lightgreen")

De hecho, para esperar observar una vez el resultado \(20\), debemos repetir el experimento \(6^{20}=\) 3,656,158,440,062,976 veces. Esto ya resulta impráctico ya que el resultado observado se tardó 34.05 segundos, por lo que la simulación larga se tardaría aproximadamente 6574.9 años.
E4: Número de lanzamientos hasta que sale seis por primera vez
El experimento ahora es genuinamente complicado (bueno, no realmente) y requiere entender el uso de la instrución while. Como R es un lenguaje de programación podemos utilizarlo para simular el experimento 4 de manera directa.
El espacio de resultados ahora es \(\{1,2,3,\ldots\}=\mathbb{N}\). Como este espacio de resultados es infinito, la idea de la tabla de valores ya no es factible, por lo que obtener aproximaciones a las probabilidades de manera empírica solo es práctico para valores relativamente pequeños de el número de lanzamientos hasta observar el primer seis.
rNHP6<-function(){
listo<-FALSE
i<-0
while(!listo){
i<-i+1
listo<-(d6(1)==6)
}
return(i)
}
rNumeroHastaPrimer6<-function(n){
return(replicate(n,rNHP6()))
}
E42<-rNumeroHastaPrimer6(1000)
table(E42)/length(E42)
E42
1 2 3 4 5 6 7 8 9 10 11
0.173 0.147 0.119 0.101 0.069 0.075 0.047 0.039 0.043 0.033 0.024
12 13 14 15 16 17 18 19 20 21 22
0.021 0.015 0.012 0.018 0.006 0.005 0.008 0.005 0.014 0.003 0.004
23 24 25 26 27 30 31 32 35
0.003 0.003 0.005 0.002 0.001 0.002 0.001 0.001 0.001
summary(E42)
Min. 1st Qu. Median Mean 3rd Qu. Max.
1.000 2.000 4.000 5.884 8.000 35.000
hist(E42,col="lightgreen",breaks=0:(max(E42)+1)-0.5,prob=TRUE)

boxplot(E42,col="lightgreen")

E5: Número de lanzamientos hasta que salen dos seis consecutivos
Para simular el experimento 5, deben modificar la función que simula el experimento 4 de manera cuidadosa.
El espacio de resultados es \(\{2,3,\ldots\}=\mathbb{N}\setminus\{1\}\). Estimar las probabilidades por simulación es difícil si no se tiene una idea clara de cuán grande debe ser el número de réplicas.
Una dificultad adicional en este problema es que, a diferencia de los experimentos anteriores, saber si el próximo lanzamiento concluye el experimento es algo que depende del lanzamiento actual, si no fue seis sabemos que el experimento no puede terminar en el próximo lanzamiento, mientras que si el lanzamiento actual fue un seis entonces el experimento termina en el próximo lanzamiento con probabilidad \(\frac{1}{6}\).
E6: Número de lanzamientos hasta que sale el octavo seis
Para simular el experimento 6, deben modificar la función que simula el experimento 4 de manera cuidadosa.
E7: Número de valores distintos que se observan en 6 lanzamientos
E8: Número de valores distintos que se observan en 30 lanzamientos
E9: Número de lanzamientos hasta que se repite un valor de manera consecutiva
E10: Número de veces hasta que se observan todos los valores del dado
Proyecto de laboratorio
Reportar los diversos descriptores numéricos mencionados en clase para cada experimento. Puede ser interesante leer las ayudas de summary, quantile,median, mean, sd, var, min y max entre otras. Para el coeficiente de variación y el rango intercuartil deben escribir funciones cdv y ric que dada una muestra cualquiera, determinen sus valores de acuerdo a la definición. NO deben usar las funciones prefabricadas de R.
Realizar una visualización informativa donde se comparen los resultados teóricos y los resultados empíricos para cada experimento. Para poder hacer esto es fundamental entender el espacio de resultados de cada experimento y poder encontrar la probabilidad teórica de cada resultado.
Especificar, cuando sea posible, que variable aleatoria sirve para modelar cada uno de los experimentos.
Reportar los valores esperados teóricos de todos los experimentos.
La entrega debe ser un documento .Rmd que siga el formato de este documento (de hecho, podrían simplemente rellenar los espacios vacíos de este documento).
El tiempo de ejecución debe ser razonable, es decir, el número de réplicas debe ser suficientemente grande para que las visualizaciones sean informativas pero suficientemente pequeño para no tardarse una eternidad a la hora de revisarlo. Nota: La diversidad de visualizaciones y las subsecciones de Pocas veces y Muchas veces son solo para dar una idea de lo que se puede hacer y no deben considerarse como una propuesta de visualización informativa, en particular, ni los ejes, ni los títulos fueron etiquetados apropiadamente por tratarse este documento de una guía de laboratorio con la que deben practicar. Entre los otros documentos que ya han visto pueden ver ejemplos de como etiquetar apropiadamente los gráficos y como decidir que presentación es pertinente. En cualquier caso, recuerden que tienen un libro de texto. Advertencia: Los experimentos 9 y 10 son difíciles de resolver desde el punto de vista teórico.
TF<-proc.time()
tT<-(TF-TI)[3]
Este documento tardó 57.32 segundos en ser generado.
LS0tDQp0aXRsZTogIkN1YWRlcm5vIGRlIHRyYWJham8gZGUgcHJvYmFiaWxpZGFkZXMiDQpvdXRwdXQ6IGh0bWxfbm90ZWJvb2sNCi0tLQ0KDQpgYGB7cn0NClRJPC1wcm9jLnRpbWUoKQ0KYGBgDQoNCiMgVW4gZGFkbyBkZSAkayQgY2FyYXMNCkVuICoqUioqIHBvZGVtb3Mgc2ltdWxhciB1biBkYWRvIGRlICRrJCBjYXJhcyBmw6FjaWxtZW50ZToNCg0KYGBge3J9DQpyRGFkbzwtZnVuY3Rpb24obixrKXsNCiAgcmV0dXJuKGNlaWxpbmcoaypydW5pZihuKSkpDQp9DQpgYGANCg0KUG9yIGVqZW1wbG8sIHNpIHF1ZXJlbW9zIG9ic2VydmFyIGVsIGxhbnphbWllbnRvIGRlIDEwIGRhZG9zIGRlIDIwIGNhcmFzLCBwb2RlbW9zIGludm9jYXI6DQpgYGB7cn0NCnJlcGxpY2F0ZSgxMCxyRGFkbygxLDIwKSkNCmBgYA0KDQpvIHBvZHLDrWFtb3MgYXByb3ZlY2hhciBsYSBtYW5lcmEgY29tbyBlc2NyaWJpbW9zIGxhIGZ1bmNpw7NuIHBhcmEgb2J0ZW5lciB1biByZXN1bHRhZG8gc2ltaWxhci4uLg0KYGBge3J9DQpyRGFkbygxMCwyMCkNCmBgYA0KDQpFbiBsb3MgZGl2ZXJzb3MgZXhwZXJpbWVudG9zIHF1ZSByZWFsaXphcmVtb3MgaG95LCB2YW1vcyBhIHRyYWJhamFyIGNvbiBkYWRvcyBkZSBzZWlzIGNhcmFzLg0KDQpQb2RlbW9zIGVzY3JpYmlyIHVuYSBmdW5jacOzbiBwYXJhIHNpbXVsYXIgdW4gZGFkbyBkZSBzZWlzIGNhcmFzLCBxdWUgc2lydmEgcGFyYSBlbmNhcHN1bGFyIGxhIGZ1bmNpw7NuIGFudGVyaW9yIHkgbm9zIHBlcm1pdGEgdHJhYmFqYXIgY29uIGxvcyBkaXZlcnNvcyBleHBlcmltZW50b3MgcGxhbnRlYWRvcy4NCg0KYGBge3J9DQpkNjwtZnVuY3Rpb24obil7DQogIHJldHVybihyRGFkbyhuLDYpKQ0KfQ0KYGBgDQoNCkFob3JhIHBvZGVtb3MgdXRpbGl6YXIgbGEgZnVuY2nDs24gcGFyYSBoYWNlciB2YXJpb3MgbGFuemFtaWVudG9zIGRlIGRhZG9zIGRlIHNlaXMsIHBvciBlamVtcGxvIHNpZXRlIGRhZG9zIGRlIHNlaXMNCg0KYGBge3J9DQpkNig3KQ0KYGBgDQoNCkFob3JhIHZhbW9zIGEgYXRhY2FyIGRlc2RlIGVsIHB1bnRvIGRlIHZpc3RhIGVtcMOtcmljbyBsb3MgZXhwZXJpbWVudG9zIG1lbmNpb25hZG9zIGVuIGNsYXNlLg0KDQojIEV4cGVyaW1lbnRvcw0KDQpMYSBpZGVhIGVzIHJlcGV0aXIgZWwgZXhwZXJpbWVudG8gc3VmaWNpZW50ZXMgdmVjZXMgaGFzdGEgdGVuZXIgdW5hIGlkZWEgcmF6b25hYmxlIGRlIGN1YW50byB2YWxlbiBsYXMgZGl2ZXJzYXMgcHJvYmFiaWxpZGFkZXMgeSBjdWFsIGVzIGVsIGVzcGFjaW8gZGUgcmVzdWx0YWRvcy4NCg0KRXMgY29udmVuaWVudGUgZGV0ZXJtaW5hciB1bmEgYnVlbmEgZm9ybWEgZGUgdmlzdWFsaXphciBjYWRhIGNvcnJpZGEgZGUgc2ltdWxhY2nDs24gcGFyYSB0ZW5lciB1bmEgaWRlYSBkZSBsb3MgZGl2ZXJzb3MgdmFsb3Jlcy4NCg0KRXZpZGVudGVtZW50ZSBsYSB2aXN1YWxpemFjacOzbiBjb3JyZWN0YSBwYXJhIGNhZGEgY2FzbyBkZXBlbmRlIGRlIHVuYSBtdWx0aXBsaWNpZGFkIGRlIGZhY3RvcmVzLCBjb21vIHNvbjoNCg0KKyBFbCB0aXBvIGRlIGV4cGVyaW1lbnRvIHkgc3UgZXNwYWNpbyBkZSByZXN1bHRhZG9zLg0KKyBMYSBjYW50aWRhZCBkZSB2ZWNlcyBxdWUgc2UgcmVwaXRlIGVsIGV4cGVyaW1lbnRvLg0KDQojIyBFMTogVW4gZGFkbyBkZSBzZWlzDQpFc3RlIGV4cGVyaW1lbnRvIGVzIHJlbGF0aXZhbWVudGUgc2VuY2lsbG8sIGVsIGVzcGFjaW8gZGUgcmVzdWx0YWRvcyBjb25zaXN0ZSBlbiBlbCBjb25qdW50byBkZSBsb3MgdmFsb3JlcyAkXHsxLDIsMyw0LDUsNlx9JCB5IGxhcyBwcm9iYWJpbGlkYWRlcyBkZSBjYWRhIHZhbG9yIHNvbiB0b2RhcyBpZ3VhbGVzIGEgJFxmcmFjezF9ezZ9JCB5YSBxdWUgZWwgZGFkbyBlcyBqdXN0by4NCg0KUGFyYSBtb3N0cmFyIGVzdG8gcG9kZW1vcyBoYWNlciBlbCBleHBlcmltZW50byB2YXJpYXMgdmVjZXMuDQoNCiMjIyBQb2NhcyB2ZWNlcw0KDQpgYGB7cn0NCkUxMTwtZDYoNjApDQp0YWJsZShFMTEpL2xlbmd0aChFMTEpDQpzdW1tYXJ5KEUxMSkNCnN0cmlwY2hhcnQoRTExLG1ldGhvZD0ic3RhY2siLHBjaD0xOSkNCmFibGluZShoPTEtMC4wNSkNCnBvaW50cyhtZWFuKEUxMSksMS0wLjEscGNoPTE3LGNvbD0icmVkIikNCmhpc3QoRTExLGNvbD0ibGlnaHRncmVlbiIsYnJlYWtzPTE6Ny0wLjUscHJvYj1UUlVFKQ0KYm94cGxvdChFMTEsY29sPSJsaWdodGdyZWVuIikNCmBgYA0KDQojIyMgTXVjaGFzIHZlY2VzDQoNCmBgYHtyfQ0KRTEyPC1kNig2MDAwMCkNCnRhYmxlKEUxMikvbGVuZ3RoKEUxMikNCnN1bW1hcnkoRTEyKQ0KaGlzdChFMTIsY29sPSJsaWdodGdyZWVuIixicmVha3M9MTo3LTAuNSxwcm9iPVRSVUUpDQpib3hwbG90KEUxMixjb2w9ImxpZ2h0Z3JlZW4iKQ0KYGBgDQoNCiMjIEUyOiBTdW1hIGRlIHRyZXMgZGFkb3MgZGUgc2Vpcw0KDQpgYGB7cn0NCnJTdW1hRGUzPC1mdW5jdGlvbihuKXsNCiAgcmVwbGljYXRlKG4sc3VtKGQ2KDMpKSkNCn0NCmBgYA0KRXN0ZSBleHBlcmltZW50byBlcyB1biBwb2NvIG3DoXMgY29tcGxpY2FkbywgZWwgZXNwYWNpbyBkZSByZXN1bHRhZG9zIGNvbnNpc3RlIGVuIGVsIGNvbmp1bnRvIGRlIGxvcyB2YWxvcmVzICRcezMsNCw1LDYsNyw4LDksMTAsMTEsMTIsMTMsMTQsMTUsMTYsMTcsMThcfSQgeSBsYXMgcHJvYmFiaWxpZGFkZXMgZGUgY2FkYSB2YWxvciBzZSBwdWVkZW4gY2FsY3VsYXIgdHJhYmFqYW5kbyBzb2JyZSBlbCBlc3BhY2lvIGVxdWlwcm9iYWJsZSBkZSBsYXMgdHJpcGxldGFzICQoeF8xLHhfMix4XzMpJCBjb24gJHhfaVxpblx7MSwyLDMsNCw1LDZcfSQgcGFyYSAkaVxpblx7MSwyLDNcfSQuDQoNClBhcmEgZXN0aW1hciBsYXMgcHJvYmFiaWxpZGFkZXMgcmVwZXRpciBlbCBleHBlcmltZW50byB2YXJpYXMgdmVjZXMuDQoNCiMjIyBQb2NhcyB2ZWNlcw0KDQpgYGB7cn0NCkUyMTwtclN1bWFEZTMoMjE2KQ0KdGFibGUoRTIxKS9sZW5ndGgoRTIxKQ0Kc3VtbWFyeShFMjEpDQpzdHJpcGNoYXJ0KEUyMSxtZXRob2Q9InN0YWNrIixwY2g9MTkseWxpbT1jKDAuOCwyKSx4bGltPWMoMywxOCkpDQphYmxpbmUoaD0xLTAuMDUpDQpwb2ludHMobWVhbihFMjEpLDEtMC4xLHBjaD0xNyxjb2w9InJlZCIpDQpoaXN0KEUyMSxjb2w9ImxpZ2h0Z3JlZW4iLGJyZWFrcz0zOjE5LTAuNSxwcm9iPVRSVUUpDQpib3hwbG90KEUyMSxjb2w9ImxpZ2h0Z3JlZW4iKQ0KYGBgDQpDb21vIHNlIHB1ZWRlIGFwcmVjaWFyLCB5YSBlbCBkaWFncmFtYSBkZSBwdW50b3Mgbm8gZXMgcGFydGljdWxhcm1lbnRlIMO6dGlsLCBwdWVzIGVuIHJlYWxpZGFkIG5vcyBkYSBjYXNpIGxhIG1pc21hIGluZm9ybWFjacOzbiBxdWUgZWwgaGlzdG9ncmFtYS4NCiMjIyBNdWNoYXMgdmVjZXMNCg0KYGBge3J9DQpFMjI8LXJTdW1hRGUzKDYwMDAwKQ0KdGFibGUoRTIyKS9sZW5ndGgoRTIyKQ0Kc3VtbWFyeShFMjIpDQpoaXN0KEUyMixjb2w9ImxpZ2h0Z3JlZW4iLGJyZWFrcz0zOjE5LTAuNSxwcm9iPVRSVUUpDQpib3hwbG90KEUyMixjb2w9ImxpZ2h0Z3JlZW4iKQ0KYGBgDQoNCiMjIEUzOiBOw7ptZXJvIGRlIHZlY2VzIHF1ZSBzYWxlIGVsIHNlaXMgZW4gdmVpbnRlIGxhbnphbWllbnRvcw0KDQpEZSBudWV2bywgZWwgZXhwZXJpbWVudG8gZXMgbcOhcyBjb21wbGljYWRvIHF1ZSBlbCBhbnRlcmlvci4gRGViZXLDrWEgZXN0YXIgY2xhcm8gcXVlIGVsIGVzcGFjaW8gZGUgcmVzdWx0YWRvcyBlcyBlbCBjb25qdW50byBkZSBsb3MgbsO6bWVyb3MgJFx7MCwxLDIsMyw0LDUsNiw3LDgsOSwxMCwxMSwxMiwxMywxNCwxNSwxNiwxNywxOCwxOSwyMFx9JCBwZXJvIGFob3JhIGRlYmVyw61hbW9zIG5vdGFyIHF1ZSBpbmNsdXNvIHVuYSBjYW50aWRhZCBlbm9ybWUgZGUgcsOpcGxpY2FzIGRlbCBleHBlcmltZW50bywgbm8gcmV2ZWxhIGVsIGVzcGFjaW8gZGUgcmVzdWx0YWRvcyBjb21wbGV0bywgcG9yIGxvIHF1ZSBwYXJhIGVzdGltYXIgZGUgbWFuZXJhIHJhem9uYWJsZSBsYXMgcHJvYmFiaWxpZGFkZXMgZGUgbWFuZXJhIGVtcMOtcmljYSwgdGVuZW1vcyBxdWUgaXJub3MgYSBuw7ptZXJvcyB2ZXJkYWRlcmFtZW50ZSBncmFuZGVzLiANCg0KYGBge3J9DQpyVG90YWxEZTZFbjIwPC1mdW5jdGlvbihuKXsNCiAgcmVwbGljYXRlKG4sc3VtKGQ2KDIwKT09NikpDQp9DQpgYGANCg0KYGBge3J9DQptPC02MDAwMDANCnRpPC1wcm9jLnRpbWUoKQ0KRTMyPC1yVG90YWxEZTZFbjIwKG0pDQp0ZjwtcHJvYy50aW1lKCkNCnQ8LSh0Zi10aSlbM10NCnRpZW1wb2xhcmdvPC0oKDZeMjAvbSkqdCkvKDM2MDAqMjQqMzY1LjI1KQ0KdGFibGUoRTMyKS9sZW5ndGgoRTMyKQ0Kc3VtbWFyeShFMzIpDQpoaXN0KEUzMixjb2w9ImxpZ2h0Z3JlZW4iLGJyZWFrcz0wOjIxLTAuNSxwcm9iPVRSVUUpDQpib3hwbG90KEUzMixjb2w9ImxpZ2h0Z3JlZW4iKQ0KYGBgDQoNCkRlIGhlY2hvLCBwYXJhIGVzcGVyYXIgb2JzZXJ2YXIgdW5hIHZleiBlbCByZXN1bHRhZG8gJDIwJCwgZGViZW1vcyByZXBldGlyIGVsIGV4cGVyaW1lbnRvICQ2XnsyMH09JCBgciBmb3JtYXQoNl4yMCxkaWdpdHM9Y2VpbGluZyhsb2coNl4yMCxiYXNlPTEwKSkrMSxiaWcubWFyayA9IiwiKWAgdmVjZXMuIEVzdG8geWEgcmVzdWx0YSBpbXByw6FjdGljbyB5YSBxdWUgZWwgcmVzdWx0YWRvIG9ic2VydmFkbyBzZSB0YXJkw7MgYHIgdGAgc2VndW5kb3MsIHBvciBsbyBxdWUgbGEgc2ltdWxhY2nDs24gKmxhcmdhKiBzZSB0YXJkYXLDrWEgYXByb3hpbWFkYW1lbnRlIGByIGZvcm1hdCh0aWVtcG9sYXJnbyxkaWdpdHM9Y2VpbGluZyhsb2codGllbXBvbGFyZ28sYmFzZT0xMCkpKzEpYCBhw7Fvcy4gDQoNCiMjIEU0OiBOw7ptZXJvIGRlIGxhbnphbWllbnRvcyBoYXN0YSBxdWUgc2FsZSBzZWlzIHBvciBwcmltZXJhIHZleg0KDQpFbCBleHBlcmltZW50byBhaG9yYSBlcyBnZW51aW5hbWVudGUgY29tcGxpY2FkbyAoKmJ1ZW5vLCBubyByZWFsbWVudGUqKSB5IHJlcXVpZXJlIGVudGVuZGVyIGVsIHVzbyBkZSBsYSBpbnN0cnVjacOzbiBgd2hpbGVgLiBDb21vICoqUioqIGVzIHVuIGxlbmd1YWplIGRlIHByb2dyYW1hY2nDs24gcG9kZW1vcyB1dGlsaXphcmxvIHBhcmEgc2ltdWxhciBlbCBleHBlcmltZW50byA0IGRlIG1hbmVyYSBkaXJlY3RhLg0KDQpFbCBlc3BhY2lvIGRlIHJlc3VsdGFkb3MgYWhvcmEgZXMgJFx7MSwyLDMsXGxkb3RzXH09XG1hdGhiYntOfSQuIENvbW8gZXN0ZSBlc3BhY2lvIGRlIHJlc3VsdGFkb3MgZXMgaW5maW5pdG8sIGxhIGlkZWEgZGUgbGEgdGFibGEgZGUgdmFsb3JlcyB5YSBubyBlcyBmYWN0aWJsZSwgcG9yIGxvIHF1ZSBvYnRlbmVyIGFwcm94aW1hY2lvbmVzIGEgbGFzIHByb2JhYmlsaWRhZGVzIGRlIG1hbmVyYSBlbXDDrXJpY2Egc29sbyBlcyBwcsOhY3RpY28gcGFyYSB2YWxvcmVzIHJlbGF0aXZhbWVudGUgcGVxdWXDsW9zIGRlIGVsIG7Dum1lcm8gZGUgbGFuemFtaWVudG9zIGhhc3RhIG9ic2VydmFyIGVsIHByaW1lciBzZWlzLg0KDQoNCmBgYHtyfQ0Kck5IUDY8LWZ1bmN0aW9uKCl7DQogIGxpc3RvPC1GQUxTRQ0KICBpPC0wDQogIHdoaWxlKCFsaXN0byl7DQogICAgaTwtaSsxDQogICAgbGlzdG88LShkNigxKT09NikNCiAgfQ0KICByZXR1cm4oaSkNCn0NCg0Kck51bWVyb0hhc3RhUHJpbWVyNjwtZnVuY3Rpb24obil7DQogIHJldHVybihyZXBsaWNhdGUobixyTkhQNigpKSkNCn0NCmBgYA0KDQpgYGB7cn0NCkU0Mjwtck51bWVyb0hhc3RhUHJpbWVyNigxMDAwKQ0KdGFibGUoRTQyKS9sZW5ndGgoRTQyKQ0Kc3VtbWFyeShFNDIpDQpoaXN0KEU0Mixjb2w9ImxpZ2h0Z3JlZW4iLGJyZWFrcz0wOihtYXgoRTQyKSsxKS0wLjUscHJvYj1UUlVFKQ0KYm94cGxvdChFNDIsY29sPSJsaWdodGdyZWVuIikNCmBgYA0KDQoNCg0KIyMgRTU6IE7Dum1lcm8gZGUgbGFuemFtaWVudG9zIGhhc3RhIHF1ZSBzYWxlbiBkb3Mgc2VpcyBjb25zZWN1dGl2b3MNCg0KUGFyYSBzaW11bGFyIGVsIGV4cGVyaW1lbnRvIDUsIGRlYmVuIG1vZGlmaWNhciBsYSBmdW5jacOzbiBxdWUgc2ltdWxhIGVsIGV4cGVyaW1lbnRvIDQgZGUgbWFuZXJhIGN1aWRhZG9zYS4NCg0KRWwgZXNwYWNpbyBkZSByZXN1bHRhZG9zIGVzICRcezIsMyxcbGRvdHNcfT1cbWF0aGJie059XHNldG1pbnVzXHsxXH0kLiBFc3RpbWFyIGxhcyBwcm9iYWJpbGlkYWRlcyBwb3Igc2ltdWxhY2nDs24gZXMgZGlmw61jaWwgc2kgbm8gc2UgdGllbmUgdW5hIGlkZWEgY2xhcmEgZGUgY3XDoW4gZ3JhbmRlIGRlYmUgc2VyIGVsIG7Dum1lcm8gZGUgcsOpcGxpY2FzLg0KDQpVbmEgZGlmaWN1bHRhZCBhZGljaW9uYWwgZW4gZXN0ZSBwcm9ibGVtYSBlcyBxdWUsIGEgZGlmZXJlbmNpYSBkZSBsb3MgZXhwZXJpbWVudG9zIGFudGVyaW9yZXMsIHNhYmVyIHNpIGVsIHByw7N4aW1vIGxhbnphbWllbnRvIGNvbmNsdXllIGVsIGV4cGVyaW1lbnRvIGVzIGFsZ28gcXVlIGRlcGVuZGUgZGVsIGxhbnphbWllbnRvIGFjdHVhbCwgc2kgbm8gZnVlICpzZWlzKiBzYWJlbW9zIHF1ZSBlbCBleHBlcmltZW50byBubyBwdWVkZSB0ZXJtaW5hciBlbiBlbCBwcsOzeGltbyBsYW56YW1pZW50bywgbWllbnRyYXMgcXVlIHNpIGVsIGxhbnphbWllbnRvIGFjdHVhbCBmdWUgdW4gKnNlaXMqIGVudG9uY2VzIGVsIGV4cGVyaW1lbnRvIHRlcm1pbmEgZW4gZWwgcHLDs3hpbW8gbGFuemFtaWVudG8gY29uIHByb2JhYmlsaWRhZCAkXGZyYWN7MX17Nn0kLg0KDQoNCiMjIEU2OiBOw7ptZXJvIGRlIGxhbnphbWllbnRvcyBoYXN0YSBxdWUgc2FsZSBlbCBvY3Rhdm8gc2Vpcw0KDQpQYXJhIHNpbXVsYXIgZWwgZXhwZXJpbWVudG8gNiwgZGViZW4gbW9kaWZpY2FyIGxhIGZ1bmNpw7NuIHF1ZSBzaW11bGEgZWwgZXhwZXJpbWVudG8gNCBkZSBtYW5lcmEgY3VpZGFkb3NhLg0KDQojIyBFNzogTsO6bWVybyBkZSB2YWxvcmVzIGRpc3RpbnRvcyBxdWUgc2Ugb2JzZXJ2YW4gZW4gNiBsYW56YW1pZW50b3MNCg0KIyMgRTg6IE7Dum1lcm8gZGUgdmFsb3JlcyBkaXN0aW50b3MgcXVlIHNlIG9ic2VydmFuIGVuIDMwIGxhbnphbWllbnRvcw0KDQojIyBFOTogTsO6bWVybyBkZSBsYW56YW1pZW50b3MgaGFzdGEgcXVlIHNlIHJlcGl0ZSB1biB2YWxvciBkZSBtYW5lcmEgY29uc2VjdXRpdmENCg0KIyMgRTEwOiBOw7ptZXJvIGRlIHZlY2VzIGhhc3RhIHF1ZSBzZSBvYnNlcnZhbiB0b2RvcyBsb3MgdmFsb3JlcyBkZWwgZGFkbw0KDQojIFByb3llY3RvIGRlIGxhYm9yYXRvcmlvDQoNCjEuIFJlcG9ydGFyIGxvcyBkaXZlcnNvcyBkZXNjcmlwdG9yZXMgbnVtw6lyaWNvcyBtZW5jaW9uYWRvcyBlbiBjbGFzZSBwYXJhIGNhZGEgZXhwZXJpbWVudG8uIFB1ZWRlIHNlciBpbnRlcmVzYW50ZSBsZWVyIGxhcyBheXVkYXMgZGUgYHN1bW1hcnlgLCBgcXVhbnRpbGVgLGBtZWRpYW5gLCBgbWVhbmAsIGBzZGAsIGB2YXJgLCBgbWluYCB5IGBtYXhgIGVudHJlIG90cmFzLiBQYXJhIGVsICoqY29lZmljaWVudGUgZGUgdmFyaWFjacOzbioqIHkgZWwgKipyYW5nbyBpbnRlcmN1YXJ0aWwqKiBkZWJlbiBlc2NyaWJpciBmdW5jaW9uZXMgYGNkdmAgeSBgcmljYCBxdWUgZGFkYSB1bmEgbXVlc3RyYSBjdWFscXVpZXJhLCBkZXRlcm1pbmVuIHN1cyB2YWxvcmVzIGRlIGFjdWVyZG8gYSBsYSBkZWZpbmljacOzbi4gKipOTyoqIGRlYmVuIHVzYXIgbGFzIGZ1bmNpb25lcyBwcmVmYWJyaWNhZGFzIGRlICoqUioqLg0KDQoyLiBSZWFsaXphciAqKnVuYSB2aXN1YWxpemFjacOzbiBpbmZvcm1hdGl2YSoqIGRvbmRlIHNlIGNvbXBhcmVuIGxvcyByZXN1bHRhZG9zIHRlw7NyaWNvcyB5IGxvcyByZXN1bHRhZG9zIGVtcMOtcmljb3MgcGFyYSBjYWRhIGV4cGVyaW1lbnRvLiBQYXJhIHBvZGVyIGhhY2VyIGVzdG8gZXMgZnVuZGFtZW50YWwgZW50ZW5kZXIgZWwgZXNwYWNpbyBkZSByZXN1bHRhZG9zIGRlIGNhZGEgZXhwZXJpbWVudG8geSBwb2RlciBlbmNvbnRyYXIgbGEgcHJvYmFiaWxpZGFkIHRlw7NyaWNhIGRlIGNhZGEgcmVzdWx0YWRvLg0KDQozLiBFc3BlY2lmaWNhciwgY3VhbmRvIHNlYSBwb3NpYmxlLCBxdWUgdmFyaWFibGUgYWxlYXRvcmlhIHNpcnZlIHBhcmEgbW9kZWxhciBjYWRhIHVubyBkZSBsb3MgZXhwZXJpbWVudG9zLg0KDQo0LiBSZXBvcnRhciBsb3MgdmFsb3JlcyBlc3BlcmFkb3MgdGXDs3JpY29zIGRlIHRvZG9zIGxvcyBleHBlcmltZW50b3MuDQoNCkxhIGVudHJlZ2EgZGViZSBzZXIgdW4gZG9jdW1lbnRvIGAuUm1kYCBxdWUgc2lnYSBlbCBmb3JtYXRvIGRlIGVzdGUgZG9jdW1lbnRvIChkZSBoZWNobywgcG9kcsOtYW4gc2ltcGxlbWVudGUgcmVsbGVuYXIgbG9zIGVzcGFjaW9zIHZhY8Otb3MgZGUgZXN0ZSBkb2N1bWVudG8pLg0KDQpFbCB0aWVtcG8gZGUgZWplY3VjacOzbiBkZWJlIHNlciByYXpvbmFibGUsIGVzIGRlY2lyLCBlbCBuw7ptZXJvIGRlIHLDqXBsaWNhcyBkZWJlIHNlciBzdWZpY2llbnRlbWVudGUgZ3JhbmRlIHBhcmEgcXVlIGxhcyB2aXN1YWxpemFjaW9uZXMgc2VhbiAqaW5mb3JtYXRpdmFzKiBwZXJvIHN1ZmljaWVudGVtZW50ZSBwZXF1ZcOxbyBwYXJhIG5vIHRhcmRhcnNlIHVuYSBldGVybmlkYWQgYSBsYSBob3JhIGRlIHJldmlzYXJsby4NCipOb3RhKjogTGEgZGl2ZXJzaWRhZCBkZSB2aXN1YWxpemFjaW9uZXMgeSBsYXMgc3Vic2VjY2lvbmVzIGRlICoqUG9jYXMgdmVjZXMqKiB5ICoqTXVjaGFzIHZlY2VzKiogc29uIHNvbG8gcGFyYSBkYXIgdW5hIGlkZWEgZGUgbG8gcXVlIHNlIHB1ZWRlIGhhY2VyIHkgbm8gZGViZW4gY29uc2lkZXJhcnNlIGNvbW8gdW5hIHByb3B1ZXN0YSBkZSAqdmlzdWFsaXphY2nDs24gaW5mb3JtYXRpdmEqLCBlbiBwYXJ0aWN1bGFyLCBuaSBsb3MgZWplcywgbmkgbG9zIHTDrXR1bG9zIGZ1ZXJvbiBldGlxdWV0YWRvcyBhcHJvcGlhZGFtZW50ZSBwb3IgdHJhdGFyc2UgZXN0ZSBkb2N1bWVudG8gZGUgdW5hIGd1w61hIGRlIGxhYm9yYXRvcmlvIGNvbiBsYSBxdWUgZGViZW4gcHJhY3RpY2FyLiBFbnRyZSBsb3Mgb3Ryb3MgZG9jdW1lbnRvcyBxdWUgeWEgaGFuIHZpc3RvIHB1ZWRlbiB2ZXIgZWplbXBsb3MgZGUgY29tbyBldGlxdWV0YXIgYXByb3BpYWRhbWVudGUgbG9zIGdyw6FmaWNvcyB5IGNvbW8gZGVjaWRpciBxdWUgcHJlc2VudGFjacOzbiBlcyBwZXJ0aW5lbnRlLiBFbiBjdWFscXVpZXIgY2FzbywgcmVjdWVyZGVuIHF1ZSB0aWVuZW4gdW4gbGlicm8gZGUgdGV4dG8uDQoqQWR2ZXJ0ZW5jaWEqOiBMb3MgZXhwZXJpbWVudG9zIDkgeSAxMCBzb24gZGlmw61jaWxlcyBkZSByZXNvbHZlciBkZXNkZSBlbCBwdW50byBkZSB2aXN0YSB0ZcOzcmljby4NCg0KYGBge3J9DQpURjwtcHJvYy50aW1lKCkNCnRUPC0oVEYtVEkpWzNdDQpgYGANCg0KRXN0ZSBkb2N1bWVudG8gdGFyZMOzIGByIHRUYCBzZWd1bmRvcyBlbiBzZXIgZ2VuZXJhZG8u