EJEMPLO


library(markovchain)

library(formattable)

#Definir la matriz P
estados = c(1:3)
P = matrix(c(0.5, 0.3, 0.2,
             0.3, 0.4, 0.3,
             0.2, 0.3, 0.5), nrow = 3, ncol = 3, byrow = T)

dimnames(P) = list(estados,estados)

#Estado actual
estado = 1

#Definir la distribución de probabilidad para el dia siguiente dado el estado actual
P[estado,]

#Obtener la calidad del aire para el dia siguiente
sample(estados, size = 1, prob = P[estado,])

#Simular 10 dias de la calidad del aire
dias = 10
set.seed(0)#Definiendo la semilla

#Definir el estado inicial
estado = 1

#Inicilizar una lista que contiene la calidad del aire en cada dia
lista_estados = c()

for (i in 1:dias) {
  #Guardar el estado actual en la lista de estados
  lista_estados = c(lista_estados,estado)
  
  #OBtener el estado futuro
  estado = sample(estados, size = 1, prob = P[estado,])
}
lista_estados


plot(lista_estados,type = 'l', xlab = 'Dias', ylab = 'Calidad del aire',
     main = 'Evolución de la calidad del aire')


# Simulación con 8 escenarios ---------------------------------------------


dias = 10
escenarios = 8
set.seed(0)

matriz_calidad = matrix(0,nrow = dias, ncol = escenarios)

for (j in 1:escenarios) {
  
  #Definir el estado actual
  estado = 1
  
  #Simular los 10 dias
  for (i in 1:dias) {
    
    #Guardar el estado en la matriz 
    matriz_calidad[i,j] = estado
    
    estado = sample(estados, size = 1, prob = P[estado,])
    
  }
}

matplot(matriz_calidad, type = 'l', xlab = 'Dias', ylab = 'Calidad del aire',
        main = 'Evolución de la calidad del aire')

EJERCICIO



#Tasa de la demanda
lambda<-15

#Modelación del manejo de inventarios de Wattenspharma con cadenas de Markov
#Crear los estados
estados<-c(0:100)

#*****Crear y llenar la matriz P de la política*****
matrizP<-matrix(0,nrow = length(estados), ncol = length(estados))
rownames(matrizP)<-estados
colnames(matrizP)<-estados

#Para la Politica -> si i<=70 solicita 30 cajas
for (i in estados) {
  for (j in estados) {
    if(i<=70 & j>0){
      matrizP[i+1,j+1]= dpois(30+i-j,lambda=lambda)
    }else if(i<=70 & j==0){
      matrizP[i+1,j+1]=ppois(30+i-1,lambda = lambda, lower.tail = F)
    }else if(i>70 & j>0){
      matrizP[i+1,j+1]=dpois(i-j,lambda=lambda)
    }else if(i>70 & j==0){
      matrizP[i+1,j+1]=ppois(i-1,lambda = lambda, lower.tail = F)
    }
  }
}

# Crear la cadena usando el paquete markovchain
cmtd<-new("markovchain", states=as.character(estados), transitionMatrix=matrizP)


# Literal B ---------------------------------------------------------------

# Vector para guardar el valor esperado del inventario en cada semana
vEsperadoInv <- c()    

# Recorrer las semanas
for(n in 1:30){
  estado_inicial <- "0"            # Definir el estado inicial
  P_t <- cmtd^n                    # Calcular la matriz de probabilidades en el transitorio
  probs <- P_t[estado_inicial,]    # Calcular probabilidades en el transitorio dado el estado inicial
  vEsperadoInv <- c(vEsperadoInv, probs%*%estados)  # Calcular valor esperado y agregar al vector
}

plot(vEsperadoInv, type = "l", ylab="Valor esperado del inventario", xlab="Semana", main="Inventario al final de la semana")

# Calcula el valor esperado del costo de ordenar de las siguientes 30 semanas
cOrdenar <- 5000
vEsperadoOrd <- 0

for(n in 1:30){
  estado_inicial <- "0"            # Definir el estado inicial
  P_t <- cmtd^n                    # Calcular la matriz de probabilidades en el transitorio
  probs <- P_t[estado_inicial,]    # Calcular probabilidades en el transitorio dado el estado inicial
  
  # Calcular el valor esperado de ordenar y sumarlo al costo hasta el momento
  vEsperadoOrd <- vEsperadoOrd + sum(probs[1:71])*cOrdenar
}
vEsperadoOrd



# Literal C. MonteCarlo ---------------------------------------------------
escenarios = 8
semanas = 30

inventario = matrix(0,nrow = semanas, ncol = escenarios)


#Simular la cadena de markov
set.seed(0)
for (j in 1:escenarios) {
  
  #Determinar el estado inicial
  estado = 0
  
  #SImular las 30 semanas
  for (i in 1:semanas) {
    
    #Guardar el inventario actual
    inventario[i,j] = estado
    
    estado = sample(estados, size = 1, prob = matrizP[as.character(estado),])
    
  }
}

matplot(inventario, type = 'l', xlab = 'Semanas', ylab = 'Inventario')


# Literal D ---------------------------------------------------------------


escenarios = 1000
semanas = 30

inventario = matrix(0,nrow = semanas, ncol = escenarios)


#Simular la cadena de markov
set.seed(0)
for (j in 1:escenarios) {
  
  #Determinar el estado inicial
  estado = 0
  
  #SImular las 30 semanas
  for (i in 1:semanas) {
    
    #Guardar el inventario actual
    inventario[i,j] = estado
    
    estado = sample(estados, size = 1, prob = matrizP[as.character(estado),])
    
  }
}

hist(inventario[30,], main = 'Distribución del inventario en la semana 30')

#Calculando el inventario promedio con MonteCarlo
inventario_promedio = mean(inventario[30,])

print(paste('Inventario con simulación de MonteCarlo: ', inventario_promedio))

#Valoresperado con analisis transitorio
print(paste('Valor esperado del inventario (literal b): ', round(vEsperadoInv[30],3)))



# Literal E ---------------------------------------------------------------


escenarios <- 1000
semanas <- 30

# Inicializar vector para guardar los costos de ordenar de cada escenario
vector_costos <- c()

# Simular la cadena de Markov
set.seed(0)
for(j in 1:escenarios){
  
  # Definir el estado inicial (inventario inicial)
  estado <- 0
  # Inicializar costo de ordenar
  costo <- 0
  
  # Simular las transiciones por 30 semanas
  for(i in 1:semanas){
    
    # Si el inventario es menor a 70, sumar costo de ordenar
    if(estado<=70){
      costo = costo + cOrdenar
    }
    estado <- sample(estados, size=1, prob=matrizP[as.character(estado),])
  }
  
  # Guardar el costo de ordenar
  vector_costos <- c(vector_costos, costo)
}
costo_promedio = mean(vector_costos)
costo_promedio

print(paste("Costo total de ordenar promedio utilizando simulación de Monte Carlo: ", currency(costo_promedio)))

print(paste("Valor esperado del costo total de ordenar: ", currency(round(vEsperadoOrd,3))))
LS0tDQp0aXRsZTogIlNpbXVsYWNpb24gZGUgTW9udGVjYXJsbyINCm91dHB1dDogaHRtbF9ub3RlYm9vaw0KLS0tDQoNCkVKRU1QTE8NCg0KYGBge3J9DQoNCmxpYnJhcnkobWFya292Y2hhaW4pDQoNCmxpYnJhcnkoZm9ybWF0dGFibGUpDQoNCiNEZWZpbmlyIGxhIG1hdHJpeiBQDQplc3RhZG9zID0gYygxOjMpDQpQID0gbWF0cml4KGMoMC41LCAwLjMsIDAuMiwNCiAgICAgICAgICAgICAwLjMsIDAuNCwgMC4zLA0KICAgICAgICAgICAgIDAuMiwgMC4zLCAwLjUpLCBucm93ID0gMywgbmNvbCA9IDMsIGJ5cm93ID0gVCkNCg0KZGltbmFtZXMoUCkgPSBsaXN0KGVzdGFkb3MsZXN0YWRvcykNCg0KI0VzdGFkbyBhY3R1YWwNCmVzdGFkbyA9IDENCg0KI0RlZmluaXIgbGEgZGlzdHJpYnVjacOzbiBkZSBwcm9iYWJpbGlkYWQgcGFyYSBlbCBkaWEgc2lndWllbnRlIGRhZG8gZWwgZXN0YWRvIGFjdHVhbA0KUFtlc3RhZG8sXQ0KDQojT2J0ZW5lciBsYSBjYWxpZGFkIGRlbCBhaXJlIHBhcmEgZWwgZGlhIHNpZ3VpZW50ZQ0Kc2FtcGxlKGVzdGFkb3MsIHNpemUgPSAxLCBwcm9iID0gUFtlc3RhZG8sXSkNCg0KI1NpbXVsYXIgMTAgZGlhcyBkZSBsYSBjYWxpZGFkIGRlbCBhaXJlDQpkaWFzID0gMTANCnNldC5zZWVkKDApI0RlZmluaWVuZG8gbGEgc2VtaWxsYQ0KDQojRGVmaW5pciBlbCBlc3RhZG8gaW5pY2lhbA0KZXN0YWRvID0gMQ0KDQojSW5pY2lsaXphciB1bmEgbGlzdGEgcXVlIGNvbnRpZW5lIGxhIGNhbGlkYWQgZGVsIGFpcmUgZW4gY2FkYSBkaWENCmxpc3RhX2VzdGFkb3MgPSBjKCkNCg0KZm9yIChpIGluIDE6ZGlhcykgew0KICAjR3VhcmRhciBlbCBlc3RhZG8gYWN0dWFsIGVuIGxhIGxpc3RhIGRlIGVzdGFkb3MNCiAgbGlzdGFfZXN0YWRvcyA9IGMobGlzdGFfZXN0YWRvcyxlc3RhZG8pDQogIA0KICAjT0J0ZW5lciBlbCBlc3RhZG8gZnV0dXJvDQogIGVzdGFkbyA9IHNhbXBsZShlc3RhZG9zLCBzaXplID0gMSwgcHJvYiA9IFBbZXN0YWRvLF0pDQp9DQpsaXN0YV9lc3RhZG9zDQoNCg0KcGxvdChsaXN0YV9lc3RhZG9zLHR5cGUgPSAnbCcsIHhsYWIgPSAnRGlhcycsIHlsYWIgPSAnQ2FsaWRhZCBkZWwgYWlyZScsDQogICAgIG1haW4gPSAnRXZvbHVjacOzbiBkZSBsYSBjYWxpZGFkIGRlbCBhaXJlJykNCg0KDQojIFNpbXVsYWNpw7NuIGNvbiA4IGVzY2VuYXJpb3MgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tDQoNCg0KZGlhcyA9IDEwDQplc2NlbmFyaW9zID0gOA0Kc2V0LnNlZWQoMCkNCg0KbWF0cml6X2NhbGlkYWQgPSBtYXRyaXgoMCxucm93ID0gZGlhcywgbmNvbCA9IGVzY2VuYXJpb3MpDQoNCmZvciAoaiBpbiAxOmVzY2VuYXJpb3MpIHsNCiAgDQogICNEZWZpbmlyIGVsIGVzdGFkbyBhY3R1YWwNCiAgZXN0YWRvID0gMQ0KICANCiAgI1NpbXVsYXIgbG9zIDEwIGRpYXMNCiAgZm9yIChpIGluIDE6ZGlhcykgew0KICAgIA0KICAgICNHdWFyZGFyIGVsIGVzdGFkbyBlbiBsYSBtYXRyaXogDQogICAgbWF0cml6X2NhbGlkYWRbaSxqXSA9IGVzdGFkbw0KICAgIA0KICAgIGVzdGFkbyA9IHNhbXBsZShlc3RhZG9zLCBzaXplID0gMSwgcHJvYiA9IFBbZXN0YWRvLF0pDQogICAgDQogIH0NCn0NCg0KbWF0cGxvdChtYXRyaXpfY2FsaWRhZCwgdHlwZSA9ICdsJywgeGxhYiA9ICdEaWFzJywgeWxhYiA9ICdDYWxpZGFkIGRlbCBhaXJlJywNCiAgICAgICAgbWFpbiA9ICdFdm9sdWNpw7NuIGRlIGxhIGNhbGlkYWQgZGVsIGFpcmUnKQ0KDQpgYGANCg0KDQpFSkVSQ0lDSU8NCmBgYHtyfQ0KDQoNCiNUYXNhIGRlIGxhIGRlbWFuZGENCmxhbWJkYTwtMTUNCg0KI01vZGVsYWNpw7NuIGRlbCBtYW5lam8gZGUgaW52ZW50YXJpb3MgZGUgV2F0dGVuc3BoYXJtYSBjb24gY2FkZW5hcyBkZSBNYXJrb3YNCiNDcmVhciBsb3MgZXN0YWRvcw0KZXN0YWRvczwtYygwOjEwMCkNCg0KIyoqKioqQ3JlYXIgeSBsbGVuYXIgbGEgbWF0cml6IFAgZGUgbGEgcG9sw610aWNhKioqKioNCm1hdHJpelA8LW1hdHJpeCgwLG5yb3cgPSBsZW5ndGgoZXN0YWRvcyksIG5jb2wgPSBsZW5ndGgoZXN0YWRvcykpDQpyb3duYW1lcyhtYXRyaXpQKTwtZXN0YWRvcw0KY29sbmFtZXMobWF0cml6UCk8LWVzdGFkb3MNCg0KI1BhcmEgbGEgUG9saXRpY2EgLT4gc2kgaTw9NzAgc29saWNpdGEgMzAgY2FqYXMNCmZvciAoaSBpbiBlc3RhZG9zKSB7DQogIGZvciAoaiBpbiBlc3RhZG9zKSB7DQogICAgaWYoaTw9NzAgJiBqPjApew0KICAgICAgbWF0cml6UFtpKzEsaisxXT0gZHBvaXMoMzAraS1qLGxhbWJkYT1sYW1iZGEpDQogICAgfWVsc2UgaWYoaTw9NzAgJiBqPT0wKXsNCiAgICAgIG1hdHJpelBbaSsxLGorMV09cHBvaXMoMzAraS0xLGxhbWJkYSA9IGxhbWJkYSwgbG93ZXIudGFpbCA9IEYpDQogICAgfWVsc2UgaWYoaT43MCAmIGo+MCl7DQogICAgICBtYXRyaXpQW2krMSxqKzFdPWRwb2lzKGktaixsYW1iZGE9bGFtYmRhKQ0KICAgIH1lbHNlIGlmKGk+NzAgJiBqPT0wKXsNCiAgICAgIG1hdHJpelBbaSsxLGorMV09cHBvaXMoaS0xLGxhbWJkYSA9IGxhbWJkYSwgbG93ZXIudGFpbCA9IEYpDQogICAgfQ0KICB9DQp9DQoNCiMgQ3JlYXIgbGEgY2FkZW5hIHVzYW5kbyBlbCBwYXF1ZXRlIG1hcmtvdmNoYWluDQpjbXRkPC1uZXcoIm1hcmtvdmNoYWluIiwgc3RhdGVzPWFzLmNoYXJhY3Rlcihlc3RhZG9zKSwgdHJhbnNpdGlvbk1hdHJpeD1tYXRyaXpQKQ0KDQoNCiMgTGl0ZXJhbCBCIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQ0KDQojIFZlY3RvciBwYXJhIGd1YXJkYXIgZWwgdmFsb3IgZXNwZXJhZG8gZGVsIGludmVudGFyaW8gZW4gY2FkYSBzZW1hbmENCnZFc3BlcmFkb0ludiA8LSBjKCkgICAgDQoNCiMgUmVjb3JyZXIgbGFzIHNlbWFuYXMNCmZvcihuIGluIDE6MzApew0KICBlc3RhZG9faW5pY2lhbCA8LSAiMCIgICAgICAgICAgICAjIERlZmluaXIgZWwgZXN0YWRvIGluaWNpYWwNCiAgUF90IDwtIGNtdGRebiAgICAgICAgICAgICAgICAgICAgIyBDYWxjdWxhciBsYSBtYXRyaXogZGUgcHJvYmFiaWxpZGFkZXMgZW4gZWwgdHJhbnNpdG9yaW8NCiAgcHJvYnMgPC0gUF90W2VzdGFkb19pbmljaWFsLF0gICAgIyBDYWxjdWxhciBwcm9iYWJpbGlkYWRlcyBlbiBlbCB0cmFuc2l0b3JpbyBkYWRvIGVsIGVzdGFkbyBpbmljaWFsDQogIHZFc3BlcmFkb0ludiA8LSBjKHZFc3BlcmFkb0ludiwgcHJvYnMlKiVlc3RhZG9zKSAgIyBDYWxjdWxhciB2YWxvciBlc3BlcmFkbyB5IGFncmVnYXIgYWwgdmVjdG9yDQp9DQoNCnBsb3QodkVzcGVyYWRvSW52LCB0eXBlID0gImwiLCB5bGFiPSJWYWxvciBlc3BlcmFkbyBkZWwgaW52ZW50YXJpbyIsIHhsYWI9IlNlbWFuYSIsIG1haW49IkludmVudGFyaW8gYWwgZmluYWwgZGUgbGEgc2VtYW5hIikNCg0KIyBDYWxjdWxhIGVsIHZhbG9yIGVzcGVyYWRvIGRlbCBjb3N0byBkZSBvcmRlbmFyIGRlIGxhcyBzaWd1aWVudGVzIDMwIHNlbWFuYXMNCmNPcmRlbmFyIDwtIDUwMDANCnZFc3BlcmFkb09yZCA8LSAwDQoNCmZvcihuIGluIDE6MzApew0KICBlc3RhZG9faW5pY2lhbCA8LSAiMCIgICAgICAgICAgICAjIERlZmluaXIgZWwgZXN0YWRvIGluaWNpYWwNCiAgUF90IDwtIGNtdGRebiAgICAgICAgICAgICAgICAgICAgIyBDYWxjdWxhciBsYSBtYXRyaXogZGUgcHJvYmFiaWxpZGFkZXMgZW4gZWwgdHJhbnNpdG9yaW8NCiAgcHJvYnMgPC0gUF90W2VzdGFkb19pbmljaWFsLF0gICAgIyBDYWxjdWxhciBwcm9iYWJpbGlkYWRlcyBlbiBlbCB0cmFuc2l0b3JpbyBkYWRvIGVsIGVzdGFkbyBpbmljaWFsDQogIA0KICAjIENhbGN1bGFyIGVsIHZhbG9yIGVzcGVyYWRvIGRlIG9yZGVuYXIgeSBzdW1hcmxvIGFsIGNvc3RvIGhhc3RhIGVsIG1vbWVudG8NCiAgdkVzcGVyYWRvT3JkIDwtIHZFc3BlcmFkb09yZCArIHN1bShwcm9ic1sxOjcxXSkqY09yZGVuYXINCn0NCnZFc3BlcmFkb09yZA0KDQoNCg0KIyBMaXRlcmFsIEMuIE1vbnRlQ2FybG8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tDQplc2NlbmFyaW9zID0gOA0Kc2VtYW5hcyA9IDMwDQoNCmludmVudGFyaW8gPSBtYXRyaXgoMCxucm93ID0gc2VtYW5hcywgbmNvbCA9IGVzY2VuYXJpb3MpDQoNCg0KI1NpbXVsYXIgbGEgY2FkZW5hIGRlIG1hcmtvdg0Kc2V0LnNlZWQoMCkNCmZvciAoaiBpbiAxOmVzY2VuYXJpb3MpIHsNCiAgDQogICNEZXRlcm1pbmFyIGVsIGVzdGFkbyBpbmljaWFsDQogIGVzdGFkbyA9IDANCiAgDQogICNTSW11bGFyIGxhcyAzMCBzZW1hbmFzDQogIGZvciAoaSBpbiAxOnNlbWFuYXMpIHsNCiAgICANCiAgICAjR3VhcmRhciBlbCBpbnZlbnRhcmlvIGFjdHVhbA0KICAgIGludmVudGFyaW9baSxqXSA9IGVzdGFkbw0KICAgIA0KICAgIGVzdGFkbyA9IHNhbXBsZShlc3RhZG9zLCBzaXplID0gMSwgcHJvYiA9IG1hdHJpelBbYXMuY2hhcmFjdGVyKGVzdGFkbyksXSkNCiAgICANCiAgfQ0KfQ0KDQptYXRwbG90KGludmVudGFyaW8sIHR5cGUgPSAnbCcsIHhsYWIgPSAnU2VtYW5hcycsIHlsYWIgPSAnSW52ZW50YXJpbycpDQoNCg0KIyBMaXRlcmFsIEQgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tDQoNCg0KZXNjZW5hcmlvcyA9IDEwMDANCnNlbWFuYXMgPSAzMA0KDQppbnZlbnRhcmlvID0gbWF0cml4KDAsbnJvdyA9IHNlbWFuYXMsIG5jb2wgPSBlc2NlbmFyaW9zKQ0KDQoNCiNTaW11bGFyIGxhIGNhZGVuYSBkZSBtYXJrb3YNCnNldC5zZWVkKDApDQpmb3IgKGogaW4gMTplc2NlbmFyaW9zKSB7DQogIA0KICAjRGV0ZXJtaW5hciBlbCBlc3RhZG8gaW5pY2lhbA0KICBlc3RhZG8gPSAwDQogIA0KICAjU0ltdWxhciBsYXMgMzAgc2VtYW5hcw0KICBmb3IgKGkgaW4gMTpzZW1hbmFzKSB7DQogICAgDQogICAgI0d1YXJkYXIgZWwgaW52ZW50YXJpbyBhY3R1YWwNCiAgICBpbnZlbnRhcmlvW2ksal0gPSBlc3RhZG8NCiAgICANCiAgICBlc3RhZG8gPSBzYW1wbGUoZXN0YWRvcywgc2l6ZSA9IDEsIHByb2IgPSBtYXRyaXpQW2FzLmNoYXJhY3Rlcihlc3RhZG8pLF0pDQogICAgDQogIH0NCn0NCg0KaGlzdChpbnZlbnRhcmlvWzMwLF0sIG1haW4gPSAnRGlzdHJpYnVjacOzbiBkZWwgaW52ZW50YXJpbyBlbiBsYSBzZW1hbmEgMzAnKQ0KDQojQ2FsY3VsYW5kbyBlbCBpbnZlbnRhcmlvIHByb21lZGlvIGNvbiBNb250ZUNhcmxvDQppbnZlbnRhcmlvX3Byb21lZGlvID0gbWVhbihpbnZlbnRhcmlvWzMwLF0pDQoNCnByaW50KHBhc3RlKCdJbnZlbnRhcmlvIGNvbiBzaW11bGFjacOzbiBkZSBNb250ZUNhcmxvOiAnLCBpbnZlbnRhcmlvX3Byb21lZGlvKSkNCg0KI1ZhbG9yZXNwZXJhZG8gY29uIGFuYWxpc2lzIHRyYW5zaXRvcmlvDQpwcmludChwYXN0ZSgnVmFsb3IgZXNwZXJhZG8gZGVsIGludmVudGFyaW8gKGxpdGVyYWwgYik6ICcsIHJvdW5kKHZFc3BlcmFkb0ludlszMF0sMykpKQ0KDQoNCg0KIyBMaXRlcmFsIEUgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tDQoNCg0KZXNjZW5hcmlvcyA8LSAxMDAwDQpzZW1hbmFzIDwtIDMwDQoNCiMgSW5pY2lhbGl6YXIgdmVjdG9yIHBhcmEgZ3VhcmRhciBsb3MgY29zdG9zIGRlIG9yZGVuYXIgZGUgY2FkYSBlc2NlbmFyaW8NCnZlY3Rvcl9jb3N0b3MgPC0gYygpDQoNCiMgU2ltdWxhciBsYSBjYWRlbmEgZGUgTWFya292DQpzZXQuc2VlZCgwKQ0KZm9yKGogaW4gMTplc2NlbmFyaW9zKXsNCiAgDQogICMgRGVmaW5pciBlbCBlc3RhZG8gaW5pY2lhbCAoaW52ZW50YXJpbyBpbmljaWFsKQ0KICBlc3RhZG8gPC0gMA0KICAjIEluaWNpYWxpemFyIGNvc3RvIGRlIG9yZGVuYXINCiAgY29zdG8gPC0gMA0KICANCiAgIyBTaW11bGFyIGxhcyB0cmFuc2ljaW9uZXMgcG9yIDMwIHNlbWFuYXMNCiAgZm9yKGkgaW4gMTpzZW1hbmFzKXsNCiAgICANCiAgICAjIFNpIGVsIGludmVudGFyaW8gZXMgbWVub3IgYSA3MCwgc3VtYXIgY29zdG8gZGUgb3JkZW5hcg0KICAgIGlmKGVzdGFkbzw9NzApew0KICAgICAgY29zdG8gPSBjb3N0byArIGNPcmRlbmFyDQogICAgfQ0KICAgIGVzdGFkbyA8LSBzYW1wbGUoZXN0YWRvcywgc2l6ZT0xLCBwcm9iPW1hdHJpelBbYXMuY2hhcmFjdGVyKGVzdGFkbyksXSkNCiAgfQ0KICANCiAgIyBHdWFyZGFyIGVsIGNvc3RvIGRlIG9yZGVuYXINCiAgdmVjdG9yX2Nvc3RvcyA8LSBjKHZlY3Rvcl9jb3N0b3MsIGNvc3RvKQ0KfQ0KY29zdG9fcHJvbWVkaW8gPSBtZWFuKHZlY3Rvcl9jb3N0b3MpDQpjb3N0b19wcm9tZWRpbw0KDQpwcmludChwYXN0ZSgiQ29zdG8gdG90YWwgZGUgb3JkZW5hciBwcm9tZWRpbyB1dGlsaXphbmRvIHNpbXVsYWNpw7NuIGRlIE1vbnRlIENhcmxvOiAiLCBjdXJyZW5jeShjb3N0b19wcm9tZWRpbykpKQ0KDQpwcmludChwYXN0ZSgiVmFsb3IgZXNwZXJhZG8gZGVsIGNvc3RvIHRvdGFsIGRlIG9yZGVuYXI6ICIsIGN1cnJlbmN5KHJvdW5kKHZFc3BlcmFkb09yZCwzKSkpKQ0KDQpgYGANCg0K