Ejercicio 1 — Listas de
vectores
1. Crear una lista llamada acciones con
los precios de cierre de tres días consecutivos para Apple (120, 125,
130), Google (1800, 1850, 1900) y Amazon (3200, 3300, 3400), nombrando
cada elemento según la empresa.
acciones <- list(
apple = c(120, 125, 130),
google = c(1800, 1850, 1900),
amazon = c(3200, 3300, 3400)
)
str(acciones)
#> List of 3
#> $ apple : num [1:3] 120 125 130
#> $ google: num [1:3] 1800 1850 1900
#> $ amazon: num [1:3] 3200 3300 3400
La lista se puede ver también en formato tabular, ya que todos los
vectores tienen la misma longitud:
tabla(
as.data.frame(do.call(rbind, acciones)),
col.names = c("Día 1", "Día 2", "Día 3"),
caption = "Precios de cierre (USD)"
)
Precios de cierre (USD)
|
|
Día 1
|
Día 2
|
Día 3
|
|
apple
|
120
|
125
|
130
|
|
google
|
1800
|
1850
|
1900
|
|
amazon
|
3200
|
3300
|
3400
|
2. Añadir a la lista un vector con los precios de
cierre de Microsoft (210, 215, 220) para los mismos tres días.
acciones$microsoft <- c(210, 215, 220)
tabla(
as.data.frame(do.call(rbind, acciones)),
col.names = c("Día 1", "Día 2", "Día 3"),
caption = "Precios de cierre tras incorporar Microsoft"
)
Precios de cierre tras incorporar Microsoft
|
|
Día 1
|
Día 2
|
Día 3
|
|
apple
|
120
|
125
|
130
|
|
google
|
1800
|
1850
|
1900
|
|
amazon
|
3200
|
3300
|
3400
|
|
microsoft
|
210
|
215
|
220
|
3. Extraer el segundo elemento del vector
google dentro de la lista acciones.
#> [1] 1850
Ejercicio 2 — Listas
con objetos heterogéneos
1. Crear una lista indicadores con el
PIB (30000), la inflación (2.5, 3.0, 3.5), el desempleo (5.0, 5.5, 6.0,
4.5, 4.0, 3.5) en una matriz de dos filas, y la deuda desagregada en
pública (60) y privada (40).
gdp <- 30000
inf <- c(2.5, 3.0, 3.5)
# matrix() LLENA POR COLUMNAS; byrow = TRUE RESPETA EL ORDEN DEL ENUNCIADO
un_emp <- matrix(
c(5.0, 5.5, 6.0, 4.5, 4.0, 3.5),
nrow = 2,
byrow = TRUE,
dimnames = list(c("Semestre I", "Semestre II"),
c("T1", "T2", "T3"))
)
# DEUDA DESAGREGADA (SUBLISTA)
debt <- list(pb_debt = 60, pvt_debt = 40)
indicadores <- list(
pib = gdp,
inflacion = inf,
desempleo = un_emp,
deuda = debt
)
str(indicadores)
#> List of 4
#> $ pib : num 30000
#> $ inflacion: num [1:3] 2.5 3 3.5
#> $ desempleo: num [1:2, 1:3] 5 4.5 5.5 4 6 3.5
#> ..- attr(*, "dimnames")=List of 2
#> .. ..$ : chr [1:2] "Semestre I" "Semestre II"
#> .. ..$ : chr [1:3] "T1" "T2" "T3"
#> $ deuda :List of 2
#> ..$ pb_debt : num 60
#> ..$ pvt_debt: num 40
tabla(un_emp, caption = "Tasa de desempleo (%)")
Tasa de desempleo (%)
|
|
T1
|
T2
|
T3
|
|
Semestre I
|
5.0
|
5.5
|
6.0
|
|
Semestre II
|
4.5
|
4.0
|
3.5
|
2. Calcular el promedio de los elementos del tercer
elemento de la lista y aumentar la deuda pública en un 20 %
adicional.
# EL RESULTADO SE GUARDA EN UN OBJETO NUEVO PARA NO DESTRUIR LA MATRIZ
prom_desempleo <- mean(indicadores[[3]])
prom_desempleo
#> [1] 4.75
# LA MATRIZ SIGUE INTACTA DENTRO DE LA LISTA
indicadores$desempleo
#> T1 T2 T3
#> Semestre I 5.0 5.5 6.0
#> Semestre II 4.5 4.0 3.5
deuda_previa <- indicadores$deuda$pb_debt
indicadores$deuda$pb_debt <- indicadores$deuda$pb_debt * 1.20
tabla(
data.frame(
Concepto = c("Deuda pública", "Deuda privada"),
Antes = c(deuda_previa, indicadores$deuda$pvt_debt),
Después = c(indicadores$deuda$pb_debt, indicadores$deuda$pvt_debt)
),
row.names = FALSE,
caption = "Deuda antes y después del ajuste del 20 %"
)
Deuda antes y después del ajuste del 20 %
|
Concepto
|
Antes
|
Después
|
|
Deuda pública
|
60
|
72
|
|
Deuda privada
|
40
|
40
|
El promedio se asigna a un objeto separado
(prom_desempleo). Si se escribiera
indicadores$desempleo <- mean(...), la matriz original
quedaría reemplazada por un escalar y se perdería la estructura de la
lista.
Ejercicio 3 — Listas
anidadas
1. Crear una lista estudiantes con los
nombres (Ana, Luis, Pedro), las edades (18, 19, 20) y las notas de
matemáticas (8, 7, 9), historia (6, 8, 7) e inglés (9, 10, 8).
name <- c("Ana", "Luis", "Pedro")
age <- c(18, 19, 20)
# NOTAS POR MATERIA (SUBLISTA)
notes <- list(
matematicas = c(8, 7, 9),
historia = c(6, 8, 7),
ingles = c(9, 10, 8)
)
estudiantes <- list(
nombre = name,
edad = age,
notas = notes
)
str(estudiantes)
#> List of 3
#> $ nombre: chr [1:3] "Ana" "Luis" "Pedro"
#> $ edad : num [1:3] 18 19 20
#> $ notas :List of 3
#> ..$ matematicas: num [1:3] 8 7 9
#> ..$ historia : num [1:3] 6 8 7
#> ..$ ingles : num [1:3] 9 10 8
2. Modificar el nombre del primer estudiante por
“Elena”. 3. Añadir un vector con los géneros de los
estudiantes (F, M, NB). 4. Cambiar la nota de inglés
del tercer estudiante por nueve (9).
estudiantes$nombre[1] <- "Elena"
estudiantes$genero <- c("F", "M", "NB")
estudiantes$notas$ingles[3] <- 9
tabla(
data.frame(
Nombre = estudiantes$nombre,
Edad = estudiantes$edad,
Género = estudiantes$genero,
Matemáticas = estudiantes$notas$matematicas,
Historia = estudiantes$notas$historia,
Inglés = estudiantes$notas$ingles
),
row.names = FALSE,
caption = "Registro de estudiantes tras las modificaciones"
)
Registro de estudiantes tras las modificaciones
|
Nombre
|
Edad
|
Género
|
Matemáticas
|
Historia
|
Inglés
|
|
Elena
|
18
|
F
|
8
|
6
|
9
|
|
Luis
|
19
|
M
|
7
|
8
|
10
|
|
Pedro
|
20
|
NB
|
9
|
7
|
9
|
Ejercicio 4 — Data
frames
1. Crear un data frame ventas_tienda de
\(5\times5\), donde las filas
representen cinco tiendas distintas y las columnas cinco días.
ventas_tienda <- data.frame(
dia_1 = c(12, 10, 22, 16, 30),
dia_2 = c(15, 11, 24, 17, 32),
dia_3 = c(14, 13, 21, 19, 31),
dia_4 = c(18, 12, 25, 20, 35),
dia_5 = c(20, 15, 23, 18, 33),
row.names = c("Tienda A", "Tienda B", "Tienda C", "Tienda D", "Tienda E")
)
tabla(ventas_tienda, caption = "Ventas iniciales por tienda y día")
Ventas iniciales por tienda y día
|
|
dia_1
|
dia_2
|
dia_3
|
dia_4
|
dia_5
|
|
Tienda A
|
12
|
15
|
14
|
18
|
20
|
|
Tienda B
|
10
|
11
|
13
|
12
|
15
|
|
Tienda C
|
22
|
24
|
21
|
25
|
23
|
|
Tienda D
|
16
|
17
|
19
|
20
|
18
|
|
Tienda E
|
30
|
32
|
31
|
35
|
33
|
2. Mostrar el valor ubicado en la fila 3, columna 4.
3. Mostrar los valores de todas las tiendas para los
días dos y cinco.
#> [1] 25
tabla(
ventas_tienda[, c("dia_2", "dia_5")],
col.names = c("Día 2", "Día 5"),
caption = "Ventas de los días 2 y 5"
)
Ventas de los días 2 y 5
|
|
Día 2
|
Día 5
|
|
Tienda A
|
15
|
20
|
|
Tienda B
|
11
|
15
|
|
Tienda C
|
24
|
23
|
|
Tienda D
|
17
|
18
|
|
Tienda E
|
32
|
33
|
4. Cambiar las ventas de la “Tienda B” en el
dia_1 por un valor de 14.
# INDEXACIÓN POR NOMBRE PARA EVITAR ERRORES DE POSICIÓN
ventas_tienda["Tienda B", "dia_1"] <- 14
tabla(ventas_tienda, caption = "Ventas tras corregir la Tienda B")
Ventas tras corregir la Tienda B
|
|
dia_1
|
dia_2
|
dia_3
|
dia_4
|
dia_5
|
|
Tienda A
|
12
|
15
|
14
|
18
|
20
|
|
Tienda B
|
14
|
11
|
13
|
12
|
15
|
|
Tienda C
|
22
|
24
|
21
|
25
|
23
|
|
Tienda D
|
16
|
17
|
19
|
20
|
18
|
|
Tienda E
|
30
|
32
|
31
|
35
|
33
|
5. Incrementar en un 15 % todos los valores
registrados en la fila de la “Tienda E”. 6. Reemplazar
toda la columna dia_3 multiplicando sus valores por
dos.
ventas_tienda["Tienda E", ] <- round(ventas_tienda["Tienda E", ] * 1.15, 2)
ventas_tienda[, "dia_3"] <- ventas_tienda[, "dia_3"] * 2
tabla(ventas_tienda, caption = "Ventas finales tras ambas transformaciones")
Ventas finales tras ambas transformaciones
|
|
dia_1
|
dia_2
|
dia_3
|
dia_4
|
dia_5
|
|
Tienda A
|
12.0
|
15.0
|
28.0
|
18.00
|
20.00
|
|
Tienda B
|
14.0
|
11.0
|
26.0
|
12.00
|
15.00
|
|
Tienda C
|
22.0
|
24.0
|
42.0
|
25.00
|
23.00
|
|
Tienda D
|
16.0
|
17.0
|
38.0
|
20.00
|
18.00
|
|
Tienda E
|
34.5
|
36.8
|
71.3
|
40.25
|
37.95
|
El orden de las operaciones importa: la Tienda E se ajusta primero en
un 15 % y luego su valor de dia_3 se duplica, de modo que
esa celda acumula ambas transformaciones (\(1.15 \times 2\)).
LS0tCnRpdGxlOiAiTWFuZWpvIGRlIGVzdHJ1Y3R1cmFzIGRlIGRhdG9zIGLDoXNpY2FzIGVuIFIiCnN1YnRpdGxlOiAiQWN0aXZpZGFkIEEyMiDigJQgVGFyZWEgMiAoTE0yMzAyNykiCmF1dGhvcjogIkhhcm9sZCBTLiBMLiBNb250YW5vIgpkYXRlOiAiMjAyNi0wNy0yNCIKb3V0cHV0OgogIGh0bWxfZG9jdW1lbnQ6CiAgICB0b2M6IHRydWUKICAgIHRvY19mbG9hdDoKICAgICAgY29sbGFwc2VkOiBmYWxzZQogICAgICBzbW9vdGhfc2Nyb2xsOiB0cnVlCiAgICB0b2NfZGVwdGg6IDMKICAgIG51bWJlcl9zZWN0aW9uczogdHJ1ZQogICAgdGhlbWU6IGZsYXRseQogICAgaGlnaGxpZ2h0OiB0YW5nbwogICAgZGZfcHJpbnQ6IHBhZ2VkCiAgICBjb2RlX2ZvbGRpbmc6IHNob3cKICAgIGNvZGVfZG93bmxvYWQ6IHRydWUKLS0tCgpgYGB7ciBzZXR1cCwgaW5jbHVkZT1GQUxTRX0Ka25pdHI6Om9wdHNfY2h1bmskc2V0KAogIGVjaG8gICAgPSBUUlVFLAogIG1lc3NhZ2UgPSBGQUxTRSwKICB3YXJuaW5nID0gRkFMU0UsCiAgY29tbWVudCA9ICIjPiIKKQoKIyBUQUJMQVMgSFRNTCBDT05TSVNURU5URVMgU0lOIERFUEVOREVOQ0lBUyBFWFRFUk5BUwp0YWJsYSA8LSBmdW5jdGlvbih4LCAuLi4pIHsKICBrbml0cjo6a2FibGUoeCwgZm9ybWF0ID0gImh0bWwiLCB0YWJsZS5hdHRyID0gJ2NsYXNzPSJ0YWJsYSInLCAuLi4pCn0KYGBgCgpgYGB7Y3NzLCBlY2hvPUZBTFNFfQpib2R5IHsKICBmb250LXNpemU6IDE1cHg7CiAgbGluZS1oZWlnaHQ6IDEuNjU7Cn0KCmgxLnRpdGxlIHsgZm9udC13ZWlnaHQ6IDYwMDsgfQoKaDEgewogIGJvcmRlci1ib3R0b206IDJweCBzb2xpZCAjMmMzZTUwOwogIHBhZGRpbmctYm90dG9tOiAuM2VtOwogIG1hcmdpbi10b3A6IDEuOGVtOwp9CgouZW51bmNpYWRvIHsKICBiYWNrZ3JvdW5kLWNvbG9yOiAjZjRmN2Y5OwogIGJvcmRlci1sZWZ0OiA0cHggc29saWQgIzJjM2U1MDsKICBwYWRkaW5nOiAuOWVtIDEuMWVtOwogIG1hcmdpbjogMS4yZW0gMDsKICBib3JkZXItcmFkaXVzOiAwIDRweCA0cHggMDsKfQoKLmVudW5jaWFkbyBwOmxhc3QtY2hpbGQgeyBtYXJnaW4tYm90dG9tOiAwOyB9Cgoubm90YSB7CiAgYmFja2dyb3VuZC1jb2xvcjogI2ZkZjZlMzsKICBib3JkZXItbGVmdDogNHB4IHNvbGlkICNiNTg5MDA7CiAgcGFkZGluZzogLjhlbSAxLjFlbTsKICBtYXJnaW46IDEuMmVtIDA7CiAgZm9udC1zaXplOiAuOTNlbTsKICBib3JkZXItcmFkaXVzOiAwIDRweCA0cHggMDsKfQoKdGFibGUudGFibGEgewogIGJvcmRlci1jb2xsYXBzZTogY29sbGFwc2U7CiAgbWFyZ2luOiAxZW0gMDsKICBmb250LXNpemU6IC45M2VtOwp9Cgp0YWJsZS50YWJsYSB0aCB7CiAgYmFja2dyb3VuZC1jb2xvcjogIzJjM2U1MDsKICBjb2xvcjogI2ZmZjsKICBwYWRkaW5nOiAuNWVtIC45ZW07CiAgdGV4dC1hbGlnbjogcmlnaHQ7Cn0KCnRhYmxlLnRhYmxhIHRoOmZpcnN0LWNoaWxkIHsgdGV4dC1hbGlnbjogbGVmdDsgfQoKdGFibGUudGFibGEgdGQgewogIHBhZGRpbmc6IC40NWVtIC45ZW07CiAgYm9yZGVyLWJvdHRvbTogMXB4IHNvbGlkICNlMWU1ZWE7CiAgdGV4dC1hbGlnbjogcmlnaHQ7Cn0KCnRhYmxlLnRhYmxhIHRkOmZpcnN0LWNoaWxkIHsKICB0ZXh0LWFsaWduOiBsZWZ0OwogIGZvbnQtd2VpZ2h0OiA1MDA7Cn0KCnRhYmxlLnRhYmxhIHRyOmhvdmVyIHRkIHsgYmFja2dyb3VuZC1jb2xvcjogI2Y0ZjdmOTsgfQoKcHJlIHsgYm9yZGVyLXJhZGl1czogNHB4OyB9CmBgYAoKIyBFamVyY2ljaW8gMSDigJQgTGlzdGFzIGRlIHZlY3RvcmVzIHsjZWoxfQoKOjo6IHsuZW51bmNpYWRvfQoqKjEuKiogQ3JlYXIgdW5hIGxpc3RhIGxsYW1hZGEgYGFjY2lvbmVzYCBjb24gbG9zIHByZWNpb3MgZGUgY2llcnJlIGRlIHRyZXMgZMOtYXMgY29uc2VjdXRpdm9zIHBhcmEgQXBwbGUgKDEyMCwgMTI1LCAxMzApLCBHb29nbGUgKDE4MDAsIDE4NTAsIDE5MDApIHkgQW1hem9uICgzMjAwLCAzMzAwLCAzNDAwKSwgbm9tYnJhbmRvIGNhZGEgZWxlbWVudG8gc2Vnw7puIGxhIGVtcHJlc2EuCjo6OgoKYGBge3IgYWNjaW9uZXMtbGlzdGF9CmFjY2lvbmVzIDwtIGxpc3QoCiAgYXBwbGUgID0gYygxMjAsIDEyNSwgMTMwKSwKICBnb29nbGUgPSBjKDE4MDAsIDE4NTAsIDE5MDApLAogIGFtYXpvbiA9IGMoMzIwMCwgMzMwMCwgMzQwMCkKKQoKc3RyKGFjY2lvbmVzKQpgYGAKCkxhIGxpc3RhIHNlIHB1ZWRlIHZlciB0YW1iacOpbiBlbiBmb3JtYXRvIHRhYnVsYXIsIHlhIHF1ZSB0b2RvcyBsb3MgdmVjdG9yZXMgdGllbmVuIGxhIG1pc21hIGxvbmdpdHVkOgoKYGBge3IgYWNjaW9uZXMtdGFibGF9CnRhYmxhKAogIGFzLmRhdGEuZnJhbWUoZG8uY2FsbChyYmluZCwgYWNjaW9uZXMpKSwKICBjb2wubmFtZXMgPSBjKCJEw61hIDEiLCAiRMOtYSAyIiwgIkTDrWEgMyIpLAogIGNhcHRpb24gICA9ICJQcmVjaW9zIGRlIGNpZXJyZSAoVVNEKSIKKQpgYGAKCjo6OiB7LmVudW5jaWFkb30KKioyLioqIEHDsWFkaXIgYSBsYSBsaXN0YSB1biB2ZWN0b3IgY29uIGxvcyBwcmVjaW9zIGRlIGNpZXJyZSBkZSBNaWNyb3NvZnQgKDIxMCwgMjE1LCAyMjApIHBhcmEgbG9zIG1pc21vcyB0cmVzIGTDrWFzLgo6OjoKCmBgYHtyIGFjY2lvbmVzLW1pY3Jvc29mdH0KYWNjaW9uZXMkbWljcm9zb2Z0IDwtIGMoMjEwLCAyMTUsIDIyMCkKCnRhYmxhKAogIGFzLmRhdGEuZnJhbWUoZG8uY2FsbChyYmluZCwgYWNjaW9uZXMpKSwKICBjb2wubmFtZXMgPSBjKCJEw61hIDEiLCAiRMOtYSAyIiwgIkTDrWEgMyIpLAogIGNhcHRpb24gICA9ICJQcmVjaW9zIGRlIGNpZXJyZSB0cmFzIGluY29ycG9yYXIgTWljcm9zb2Z0IgopCmBgYAoKOjo6IHsuZW51bmNpYWRvfQoqKjMuKiogRXh0cmFlciBlbCBzZWd1bmRvIGVsZW1lbnRvIGRlbCB2ZWN0b3IgYGdvb2dsZWAgZGVudHJvIGRlIGxhIGxpc3RhIGBhY2Npb25lc2AuCjo6OgoKYGBge3IgYWNjaW9uZXMtZ29vZ2xlLTJ9CmFjY2lvbmVzJGdvb2dsZVsyXQpgYGAKCiMgRWplcmNpY2lvIDIg4oCUIExpc3RhcyBjb24gb2JqZXRvcyBoZXRlcm9nw6luZW9zIHsjZWoyfQoKOjo6IHsuZW51bmNpYWRvfQoqKjEuKiogQ3JlYXIgdW5hIGxpc3RhIGBpbmRpY2Fkb3Jlc2AgY29uIGVsIFBJQiAoMzAwMDApLCBsYSBpbmZsYWNpw7NuICgyLjUsIDMuMCwgMy41KSwgZWwgZGVzZW1wbGVvICg1LjAsIDUuNSwgNi4wLCA0LjUsIDQuMCwgMy41KSBlbiB1bmEgbWF0cml6IGRlIGRvcyBmaWxhcywgeSBsYSBkZXVkYSBkZXNhZ3JlZ2FkYSBlbiBww7pibGljYSAoNjApIHkgcHJpdmFkYSAoNDApLgo6OjoKCmBgYHtyIGluZGljYWRvcmVzLWxpc3RhfQpnZHAgPC0gMzAwMDAKaW5mIDwtIGMoMi41LCAzLjAsIDMuNSkKCiMgbWF0cml4KCkgTExFTkEgUE9SIENPTFVNTkFTOyBieXJvdyA9IFRSVUUgUkVTUEVUQSBFTCBPUkRFTiBERUwgRU5VTkNJQURPCnVuX2VtcCA8LSBtYXRyaXgoCiAgYyg1LjAsIDUuNSwgNi4wLCA0LjUsIDQuMCwgMy41KSwKICBucm93ICA9IDIsCiAgYnlyb3cgPSBUUlVFLAogIGRpbW5hbWVzID0gbGlzdChjKCJTZW1lc3RyZSBJIiwgIlNlbWVzdHJlIElJIiksCiAgICAgICAgICAgICAgICAgIGMoIlQxIiwgIlQyIiwgIlQzIikpCikKCiMgREVVREEgREVTQUdSRUdBREEgKFNVQkxJU1RBKQpkZWJ0IDwtIGxpc3QocGJfZGVidCA9IDYwLCBwdnRfZGVidCA9IDQwKQoKaW5kaWNhZG9yZXMgPC0gbGlzdCgKICBwaWIgICAgICAgPSBnZHAsCiAgaW5mbGFjaW9uID0gaW5mLAogIGRlc2VtcGxlbyA9IHVuX2VtcCwKICBkZXVkYSAgICAgPSBkZWJ0CikKCnN0cihpbmRpY2Fkb3JlcykKYGBgCgpgYGB7ciBpbmRpY2Fkb3Jlcy1kZXNlbXBsZW8tdGFibGF9CnRhYmxhKHVuX2VtcCwgY2FwdGlvbiA9ICJUYXNhIGRlIGRlc2VtcGxlbyAoJSkiKQpgYGAKCjo6OiB7LmVudW5jaWFkb30KKioyLioqIENhbGN1bGFyIGVsIHByb21lZGlvIGRlIGxvcyBlbGVtZW50b3MgZGVsIHRlcmNlciBlbGVtZW50byBkZSBsYSBsaXN0YSB5IGF1bWVudGFyIGxhIGRldWRhIHDDumJsaWNhIGVuIHVuIDIwICUgYWRpY2lvbmFsLgo6OjoKCmBgYHtyIGluZGljYWRvcmVzLXByb21lZGlvfQojIEVMIFJFU1VMVEFETyBTRSBHVUFSREEgRU4gVU4gT0JKRVRPIE5VRVZPIFBBUkEgTk8gREVTVFJVSVIgTEEgTUFUUklaCnByb21fZGVzZW1wbGVvIDwtIG1lYW4oaW5kaWNhZG9yZXNbWzNdXSkKcHJvbV9kZXNlbXBsZW8KCiMgTEEgTUFUUklaIFNJR1VFIElOVEFDVEEgREVOVFJPIERFIExBIExJU1RBCmluZGljYWRvcmVzJGRlc2VtcGxlbwpgYGAKCmBgYHtyIGluZGljYWRvcmVzLWRldWRhfQpkZXVkYV9wcmV2aWEgPC0gaW5kaWNhZG9yZXMkZGV1ZGEkcGJfZGVidAppbmRpY2Fkb3JlcyRkZXVkYSRwYl9kZWJ0IDwtIGluZGljYWRvcmVzJGRldWRhJHBiX2RlYnQgKiAxLjIwCgp0YWJsYSgKICBkYXRhLmZyYW1lKAogICAgQ29uY2VwdG8gPSBjKCJEZXVkYSBww7pibGljYSIsICJEZXVkYSBwcml2YWRhIiksCiAgICBBbnRlcyAgICA9IGMoZGV1ZGFfcHJldmlhLCBpbmRpY2Fkb3JlcyRkZXVkYSRwdnRfZGVidCksCiAgICBEZXNwdcOpcyAgPSBjKGluZGljYWRvcmVzJGRldWRhJHBiX2RlYnQsIGluZGljYWRvcmVzJGRldWRhJHB2dF9kZWJ0KQogICksCiAgcm93Lm5hbWVzID0gRkFMU0UsCiAgY2FwdGlvbiAgID0gIkRldWRhIGFudGVzIHkgZGVzcHXDqXMgZGVsIGFqdXN0ZSBkZWwgMjAgJSIKKQpgYGAKCjo6OiB7Lm5vdGF9CkVsIHByb21lZGlvIHNlIGFzaWduYSBhIHVuIG9iamV0byBzZXBhcmFkbyAoYHByb21fZGVzZW1wbGVvYCkuIFNpIHNlIGVzY3JpYmllcmEgYGluZGljYWRvcmVzJGRlc2VtcGxlbyA8LSBtZWFuKC4uLilgLCBsYSBtYXRyaXogb3JpZ2luYWwgcXVlZGFyw61hIHJlZW1wbGF6YWRhIHBvciB1biBlc2NhbGFyIHkgc2UgcGVyZGVyw61hIGxhIGVzdHJ1Y3R1cmEgZGUgbGEgbGlzdGEuCjo6OgoKIyBFamVyY2ljaW8gMyDigJQgTGlzdGFzIGFuaWRhZGFzIHsjZWozfQoKOjo6IHsuZW51bmNpYWRvfQoqKjEuKiogQ3JlYXIgdW5hIGxpc3RhIGBlc3R1ZGlhbnRlc2AgY29uIGxvcyBub21icmVzIChBbmEsIEx1aXMsIFBlZHJvKSwgbGFzIGVkYWRlcyAoMTgsIDE5LCAyMCkgeSBsYXMgbm90YXMgZGUgbWF0ZW3DoXRpY2FzICg4LCA3LCA5KSwgaGlzdG9yaWEgKDYsIDgsIDcpIGUgaW5nbMOpcyAoOSwgMTAsIDgpLgo6OjoKCmBgYHtyIGVzdHVkaWFudGVzLWxpc3RhfQpuYW1lIDwtIGMoIkFuYSIsICJMdWlzIiwgIlBlZHJvIikKYWdlICA8LSBjKDE4LCAxOSwgMjApCgojIE5PVEFTIFBPUiBNQVRFUklBIChTVUJMSVNUQSkKbm90ZXMgPC0gbGlzdCgKICBtYXRlbWF0aWNhcyA9IGMoOCwgNywgOSksCiAgaGlzdG9yaWEgICAgPSBjKDYsIDgsIDcpLAogIGluZ2xlcyAgICAgID0gYyg5LCAxMCwgOCkKKQoKZXN0dWRpYW50ZXMgPC0gbGlzdCgKICBub21icmUgPSBuYW1lLAogIGVkYWQgICA9IGFnZSwKICBub3RhcyAgPSBub3RlcwopCgpzdHIoZXN0dWRpYW50ZXMpCmBgYAoKOjo6IHsuZW51bmNpYWRvfQoqKjIuKiogTW9kaWZpY2FyIGVsIG5vbWJyZSBkZWwgcHJpbWVyIGVzdHVkaWFudGUgcG9yICJFbGVuYSIuCioqMy4qKiBBw7FhZGlyIHVuIHZlY3RvciBjb24gbG9zIGfDqW5lcm9zIGRlIGxvcyBlc3R1ZGlhbnRlcyAoRiwgTSwgTkIpLgoqKjQuKiogQ2FtYmlhciBsYSBub3RhIGRlIGluZ2zDqXMgZGVsIHRlcmNlciBlc3R1ZGlhbnRlIHBvciBudWV2ZSAoOSkuCjo6OgoKYGBge3IgZXN0dWRpYW50ZXMtbW9kaWZpY2FjaW9uZXN9CmVzdHVkaWFudGVzJG5vbWJyZVsxXSAgICAgICAgPC0gIkVsZW5hIgplc3R1ZGlhbnRlcyRnZW5lcm8gICAgICAgICAgIDwtIGMoIkYiLCAiTSIsICJOQiIpCmVzdHVkaWFudGVzJG5vdGFzJGluZ2xlc1szXSAgPC0gOQpgYGAKCmBgYHtyIGVzdHVkaWFudGVzLXRhYmxhfQp0YWJsYSgKICBkYXRhLmZyYW1lKAogICAgTm9tYnJlICAgICAgPSBlc3R1ZGlhbnRlcyRub21icmUsCiAgICBFZGFkICAgICAgICA9IGVzdHVkaWFudGVzJGVkYWQsCiAgICBHw6luZXJvICAgICAgPSBlc3R1ZGlhbnRlcyRnZW5lcm8sCiAgICBNYXRlbcOhdGljYXMgPSBlc3R1ZGlhbnRlcyRub3RhcyRtYXRlbWF0aWNhcywKICAgIEhpc3RvcmlhICAgID0gZXN0dWRpYW50ZXMkbm90YXMkaGlzdG9yaWEsCiAgICBJbmdsw6lzICAgICAgPSBlc3R1ZGlhbnRlcyRub3RhcyRpbmdsZXMKICApLAogIHJvdy5uYW1lcyA9IEZBTFNFLAogIGNhcHRpb24gICA9ICJSZWdpc3RybyBkZSBlc3R1ZGlhbnRlcyB0cmFzIGxhcyBtb2RpZmljYWNpb25lcyIKKQpgYGAKCiMgRWplcmNpY2lvIDQg4oCUIERhdGEgZnJhbWVzIHsjZWo0fQoKOjo6IHsuZW51bmNpYWRvfQoqKjEuKiogQ3JlYXIgdW4gZGF0YSBmcmFtZSBgdmVudGFzX3RpZW5kYWAgZGUgJDVcdGltZXM1JCwgZG9uZGUgbGFzIGZpbGFzIHJlcHJlc2VudGVuIGNpbmNvIHRpZW5kYXMgZGlzdGludGFzIHkgbGFzIGNvbHVtbmFzIGNpbmNvIGTDrWFzLgo6OjoKCmBgYHtyIHZlbnRhcy1kZn0KdmVudGFzX3RpZW5kYSA8LSBkYXRhLmZyYW1lKAogIGRpYV8xID0gYygxMiwgMTAsIDIyLCAxNiwgMzApLAogIGRpYV8yID0gYygxNSwgMTEsIDI0LCAxNywgMzIpLAogIGRpYV8zID0gYygxNCwgMTMsIDIxLCAxOSwgMzEpLAogIGRpYV80ID0gYygxOCwgMTIsIDI1LCAyMCwgMzUpLAogIGRpYV81ID0gYygyMCwgMTUsIDIzLCAxOCwgMzMpLAogIHJvdy5uYW1lcyA9IGMoIlRpZW5kYSBBIiwgIlRpZW5kYSBCIiwgIlRpZW5kYSBDIiwgIlRpZW5kYSBEIiwgIlRpZW5kYSBFIikKKQoKdGFibGEodmVudGFzX3RpZW5kYSwgY2FwdGlvbiA9ICJWZW50YXMgaW5pY2lhbGVzIHBvciB0aWVuZGEgeSBkw61hIikKYGBgCgo6Ojogey5lbnVuY2lhZG99CioqMi4qKiBNb3N0cmFyIGVsIHZhbG9yIHViaWNhZG8gZW4gbGEgZmlsYSAzLCBjb2x1bW5hIDQuCioqMy4qKiBNb3N0cmFyIGxvcyB2YWxvcmVzIGRlIHRvZGFzIGxhcyB0aWVuZGFzIHBhcmEgbG9zIGTDrWFzIGRvcyB5IGNpbmNvLgo6OjoKCmBgYHtyIHZlbnRhcy1jb25zdWx0YXN9CnZlbnRhc190aWVuZGFbMywgNF0KYGBgCgpgYGB7ciB2ZW50YXMtZGlhcy0yLTV9CnRhYmxhKAogIHZlbnRhc190aWVuZGFbLCBjKCJkaWFfMiIsICJkaWFfNSIpXSwKICBjb2wubmFtZXMgPSBjKCJEw61hIDIiLCAiRMOtYSA1IiksCiAgY2FwdGlvbiAgID0gIlZlbnRhcyBkZSBsb3MgZMOtYXMgMiB5IDUiCikKYGBgCgo6Ojogey5lbnVuY2lhZG99CioqNC4qKiBDYW1iaWFyIGxhcyB2ZW50YXMgZGUgbGEgIlRpZW5kYSBCIiBlbiBlbCBgZGlhXzFgIHBvciB1biB2YWxvciBkZSAxNC4KOjo6CgpgYGB7ciB2ZW50YXMtdGllbmRhYi1kaWExfQojIElOREVYQUNJw5NOIFBPUiBOT01CUkUgUEFSQSBFVklUQVIgRVJST1JFUyBERSBQT1NJQ0nDk04KdmVudGFzX3RpZW5kYVsiVGllbmRhIEIiLCAiZGlhXzEiXSA8LSAxNAoKdGFibGEodmVudGFzX3RpZW5kYSwgY2FwdGlvbiA9ICJWZW50YXMgdHJhcyBjb3JyZWdpciBsYSBUaWVuZGEgQiIpCmBgYAoKOjo6IHsuZW51bmNpYWRvfQoqKjUuKiogSW5jcmVtZW50YXIgZW4gdW4gMTUgJSB0b2RvcyBsb3MgdmFsb3JlcyByZWdpc3RyYWRvcyBlbiBsYSBmaWxhIGRlIGxhICJUaWVuZGEgRSIuCioqNi4qKiBSZWVtcGxhemFyIHRvZGEgbGEgY29sdW1uYSBgZGlhXzNgIG11bHRpcGxpY2FuZG8gc3VzIHZhbG9yZXMgcG9yIGRvcy4KOjo6CgpgYGB7ciB2ZW50YXMtdHJhbnNmb3JtYWNpb25lc30KdmVudGFzX3RpZW5kYVsiVGllbmRhIEUiLCBdIDwtIHJvdW5kKHZlbnRhc190aWVuZGFbIlRpZW5kYSBFIiwgXSAqIDEuMTUsIDIpCnZlbnRhc190aWVuZGFbLCAiZGlhXzMiXSAgICA8LSB2ZW50YXNfdGllbmRhWywgImRpYV8zIl0gKiAyCgp0YWJsYSh2ZW50YXNfdGllbmRhLCBjYXB0aW9uID0gIlZlbnRhcyBmaW5hbGVzIHRyYXMgYW1iYXMgdHJhbnNmb3JtYWNpb25lcyIpCmBgYAoKOjo6IHsubm90YX0KRWwgb3JkZW4gZGUgbGFzIG9wZXJhY2lvbmVzIGltcG9ydGE6IGxhIFRpZW5kYSBFIHNlIGFqdXN0YSBwcmltZXJvIGVuIHVuIDE1ICUgeSBsdWVnbyBzdSB2YWxvciBkZSBgZGlhXzNgIHNlIGR1cGxpY2EsIGRlIG1vZG8gcXVlIGVzYSBjZWxkYSBhY3VtdWxhIGFtYmFzIHRyYW5zZm9ybWFjaW9uZXMgKCQxLjE1IFx0aW1lcyAyJCkuCjo6Ogo=