library(markovchain)
Warning: package ‘markovchain’ was built under R version 4.3.3
Package:  markovchain
Version:  0.9.5
Date:     2023-09-24 09:20:02 UTC
BugReport: https://github.com/spedygiorgio/markovchain/issues
library(formattable)
Warning: package ‘formattable’ was built under R version 4.3.3
Registered S3 method overwritten by 'htmlwidgets':
  method           from         
  print.htmlwidget tools:rstudio
#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,]
  1   2   3 
0.5 0.3 0.2 
#Obtener la calidad del aire para el dia siguiente
sample(estados, size = 1, prob = P[estado,])
[1] 1
#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
 [1] 1 3 3 3 2 1 1 3 1 2
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')



#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
[1] 84249.97
# Literal C. MonteCarlo ---------------------------------------------------
Warning message:
In normalizePath(path.expand(path), winslash, mustWork) :
  path[1]="": El sistema no puede encontrar la ruta especificada
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))
[1] "Inventario con simulación de MonteCarlo:  70.567"
#Valoresperado con analisis transitorio
print(paste('Valor esperado del inventario (literal b): ', round(vEsperadoInv[30],3)))
[1] "Valor esperado del inventario (literal b):  70.499"

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
[1] 86550
print(paste("Costo total de ordenar promedio utilizando simulación de Monte Carlo: ", currency(costo_promedio)))
[1] "Costo total de ordenar promedio utilizando simulación de Monte Carlo:  $86,550.00"
print(paste("Valor esperado del costo total de ordenar: ", currency(round(vEsperadoOrd,3))))
[1] "Valor esperado del costo total de ordenar:  $84,249.97"
LS0tDQp0aXRsZTogIlNpbXVsYWNpb24gZGUgTW9udGVjYXJsbyINCm91dHB1dDogaHRtbF9ub3RlYm9vaw0KLS0tDQoNCmBgYHtyfQ0KDQpsaWJyYXJ5KG1hcmtvdmNoYWluKQ0KDQpsaWJyYXJ5KGZvcm1hdHRhYmxlKQ0KDQojRGVmaW5pciBsYSBtYXRyaXogUA0KZXN0YWRvcyA9IGMoMTozKQ0KUCA9IG1hdHJpeChjKDAuNSwgMC4zLCAwLjIsDQogICAgICAgICAgICAgMC4zLCAwLjQsIDAuMywNCiAgICAgICAgICAgICAwLjIsIDAuMywgMC41KSwgbnJvdyA9IDMsIG5jb2wgPSAzLCBieXJvdyA9IFQpDQoNCmRpbW5hbWVzKFApID0gbGlzdChlc3RhZG9zLGVzdGFkb3MpDQoNCiNFc3RhZG8gYWN0dWFsDQplc3RhZG8gPSAxDQoNCiNEZWZpbmlyIGxhIGRpc3RyaWJ1Y2nDs24gZGUgcHJvYmFiaWxpZGFkIHBhcmEgZWwgZGlhIHNpZ3VpZW50ZSBkYWRvIGVsIGVzdGFkbyBhY3R1YWwNClBbZXN0YWRvLF0NCg0KI09idGVuZXIgbGEgY2FsaWRhZCBkZWwgYWlyZSBwYXJhIGVsIGRpYSBzaWd1aWVudGUNCnNhbXBsZShlc3RhZG9zLCBzaXplID0gMSwgcHJvYiA9IFBbZXN0YWRvLF0pDQoNCiNTaW11bGFyIDEwIGRpYXMgZGUgbGEgY2FsaWRhZCBkZWwgYWlyZQ0KZGlhcyA9IDEwDQpzZXQuc2VlZCgwKSNEZWZpbmllbmRvIGxhIHNlbWlsbGENCg0KI0RlZmluaXIgZWwgZXN0YWRvIGluaWNpYWwNCmVzdGFkbyA9IDENCg0KI0luaWNpbGl6YXIgdW5hIGxpc3RhIHF1ZSBjb250aWVuZSBsYSBjYWxpZGFkIGRlbCBhaXJlIGVuIGNhZGEgZGlhDQpsaXN0YV9lc3RhZG9zID0gYygpDQoNCmZvciAoaSBpbiAxOmRpYXMpIHsNCiAgI0d1YXJkYXIgZWwgZXN0YWRvIGFjdHVhbCBlbiBsYSBsaXN0YSBkZSBlc3RhZG9zDQogIGxpc3RhX2VzdGFkb3MgPSBjKGxpc3RhX2VzdGFkb3MsZXN0YWRvKQ0KICANCiAgI09CdGVuZXIgZWwgZXN0YWRvIGZ1dHVybw0KICBlc3RhZG8gPSBzYW1wbGUoZXN0YWRvcywgc2l6ZSA9IDEsIHByb2IgPSBQW2VzdGFkbyxdKQ0KfQ0KbGlzdGFfZXN0YWRvcw0KDQoNCnBsb3QobGlzdGFfZXN0YWRvcyx0eXBlID0gJ2wnLCB4bGFiID0gJ0RpYXMnLCB5bGFiID0gJ0NhbGlkYWQgZGVsIGFpcmUnLA0KICAgICBtYWluID0gJ0V2b2x1Y2nDs24gZGUgbGEgY2FsaWRhZCBkZWwgYWlyZScpDQoNCg0KIyBTaW11bGFjacOzbiBjb24gOCBlc2NlbmFyaW9zIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQ0KDQoNCmRpYXMgPSAxMA0KZXNjZW5hcmlvcyA9IDgNCnNldC5zZWVkKDApDQoNCm1hdHJpel9jYWxpZGFkID0gbWF0cml4KDAsbnJvdyA9IGRpYXMsIG5jb2wgPSBlc2NlbmFyaW9zKQ0KDQpmb3IgKGogaW4gMTplc2NlbmFyaW9zKSB7DQogIA0KICAjRGVmaW5pciBlbCBlc3RhZG8gYWN0dWFsDQogIGVzdGFkbyA9IDENCiAgDQogICNTaW11bGFyIGxvcyAxMCBkaWFzDQogIGZvciAoaSBpbiAxOmRpYXMpIHsNCiAgICANCiAgICAjR3VhcmRhciBlbCBlc3RhZG8gZW4gbGEgbWF0cml6IA0KICAgIG1hdHJpel9jYWxpZGFkW2ksal0gPSBlc3RhZG8NCiAgICANCiAgICBlc3RhZG8gPSBzYW1wbGUoZXN0YWRvcywgc2l6ZSA9IDEsIHByb2IgPSBQW2VzdGFkbyxdKQ0KICAgIA0KICB9DQp9DQoNCm1hdHBsb3QobWF0cml6X2NhbGlkYWQsIHR5cGUgPSAnbCcsIHhsYWIgPSAnRGlhcycsIHlsYWIgPSAnQ2FsaWRhZCBkZWwgYWlyZScsDQogICAgICAgIG1haW4gPSAnRXZvbHVjacOzbiBkZSBsYSBjYWxpZGFkIGRlbCBhaXJlJykNCg0KYGBgDQoNCmBgYHtyfQ0KDQoNCiNUYXNhIGRlIGxhIGRlbWFuZGENCmxhbWJkYTwtMTUNCg0KI01vZGVsYWNpw7NuIGRlbCBtYW5lam8gZGUgaW52ZW50YXJpb3MgZGUgV2F0dGVuc3BoYXJtYSBjb24gY2FkZW5hcyBkZSBNYXJrb3YNCiNDcmVhciBsb3MgZXN0YWRvcw0KZXN0YWRvczwtYygwOjEwMCkNCg0KIyoqKioqQ3JlYXIgeSBsbGVuYXIgbGEgbWF0cml6IFAgZGUgbGEgcG9sw610aWNhKioqKioNCm1hdHJpelA8LW1hdHJpeCgwLG5yb3cgPSBsZW5ndGgoZXN0YWRvcyksIG5jb2wgPSBsZW5ndGgoZXN0YWRvcykpDQpyb3duYW1lcyhtYXRyaXpQKTwtZXN0YWRvcw0KY29sbmFtZXMobWF0cml6UCk8LWVzdGFkb3MNCg0KI1BhcmEgbGEgUG9saXRpY2EgLT4gc2kgaTw9NzAgc29saWNpdGEgMzAgY2FqYXMNCmZvciAoaSBpbiBlc3RhZG9zKSB7DQogIGZvciAoaiBpbiBlc3RhZG9zKSB7DQogICAgaWYoaTw9NzAgJiBqPjApew0KICAgICAgbWF0cml6UFtpKzEsaisxXT0gZHBvaXMoMzAraS1qLGxhbWJkYT1sYW1iZGEpDQogICAgfWVsc2UgaWYoaTw9NzAgJiBqPT0wKXsNCiAgICAgIG1hdHJpelBbaSsxLGorMV09cHBvaXMoMzAraS0xLGxhbWJkYSA9IGxhbWJkYSwgbG93ZXIudGFpbCA9IEYpDQogICAgfWVsc2UgaWYoaT43MCAmIGo+MCl7DQogICAgICBtYXRyaXpQW2krMSxqKzFdPWRwb2lzKGktaixsYW1iZGE9bGFtYmRhKQ0KICAgIH1lbHNlIGlmKGk+NzAgJiBqPT0wKXsNCiAgICAgIG1hdHJpelBbaSsxLGorMV09cHBvaXMoaS0xLGxhbWJkYSA9IGxhbWJkYSwgbG93ZXIudGFpbCA9IEYpDQogICAgfQ0KICB9DQp9DQoNCiMgQ3JlYXIgbGEgY2FkZW5hIHVzYW5kbyBlbCBwYXF1ZXRlIG1hcmtvdmNoYWluDQpjbXRkPC1uZXcoIm1hcmtvdmNoYWluIiwgc3RhdGVzPWFzLmNoYXJhY3Rlcihlc3RhZG9zKSwgdHJhbnNpdGlvbk1hdHJpeD1tYXRyaXpQKQ0KDQoNCiMgTGl0ZXJhbCBCIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQ0KDQojIFZlY3RvciBwYXJhIGd1YXJkYXIgZWwgdmFsb3IgZXNwZXJhZG8gZGVsIGludmVudGFyaW8gZW4gY2FkYSBzZW1hbmENCnZFc3BlcmFkb0ludiA8LSBjKCkgICAgDQoNCiMgUmVjb3JyZXIgbGFzIHNlbWFuYXMNCmZvcihuIGluIDE6MzApew0KICBlc3RhZG9faW5pY2lhbCA8LSAiMCIgICAgICAgICAgICAjIERlZmluaXIgZWwgZXN0YWRvIGluaWNpYWwNCiAgUF90IDwtIGNtdGRebiAgICAgICAgICAgICAgICAgICAgIyBDYWxjdWxhciBsYSBtYXRyaXogZGUgcHJvYmFiaWxpZGFkZXMgZW4gZWwgdHJhbnNpdG9yaW8NCiAgcHJvYnMgPC0gUF90W2VzdGFkb19pbmljaWFsLF0gICAgIyBDYWxjdWxhciBwcm9iYWJpbGlkYWRlcyBlbiBlbCB0cmFuc2l0b3JpbyBkYWRvIGVsIGVzdGFkbyBpbmljaWFsDQogIHZFc3BlcmFkb0ludiA8LSBjKHZFc3BlcmFkb0ludiwgcHJvYnMlKiVlc3RhZG9zKSAgIyBDYWxjdWxhciB2YWxvciBlc3BlcmFkbyB5IGFncmVnYXIgYWwgdmVjdG9yDQp9DQoNCnBsb3QodkVzcGVyYWRvSW52LCB0eXBlID0gImwiLCB5bGFiPSJWYWxvciBlc3BlcmFkbyBkZWwgaW52ZW50YXJpbyIsIHhsYWI9IlNlbWFuYSIsIG1haW49IkludmVudGFyaW8gYWwgZmluYWwgZGUgbGEgc2VtYW5hIikNCg0KIyBDYWxjdWxhIGVsIHZhbG9yIGVzcGVyYWRvIGRlbCBjb3N0byBkZSBvcmRlbmFyIGRlIGxhcyBzaWd1aWVudGVzIDMwIHNlbWFuYXMNCmNPcmRlbmFyIDwtIDUwMDANCnZFc3BlcmFkb09yZCA8LSAwDQoNCmZvcihuIGluIDE6MzApew0KICBlc3RhZG9faW5pY2lhbCA8LSAiMCIgICAgICAgICAgICAjIERlZmluaXIgZWwgZXN0YWRvIGluaWNpYWwNCiAgUF90IDwtIGNtdGRebiAgICAgICAgICAgICAgICAgICAgIyBDYWxjdWxhciBsYSBtYXRyaXogZGUgcHJvYmFiaWxpZGFkZXMgZW4gZWwgdHJhbnNpdG9yaW8NCiAgcHJvYnMgPC0gUF90W2VzdGFkb19pbmljaWFsLF0gICAgIyBDYWxjdWxhciBwcm9iYWJpbGlkYWRlcyBlbiBlbCB0cmFuc2l0b3JpbyBkYWRvIGVsIGVzdGFkbyBpbmljaWFsDQogIA0KICAjIENhbGN1bGFyIGVsIHZhbG9yIGVzcGVyYWRvIGRlIG9yZGVuYXIgeSBzdW1hcmxvIGFsIGNvc3RvIGhhc3RhIGVsIG1vbWVudG8NCiAgdkVzcGVyYWRvT3JkIDwtIHZFc3BlcmFkb09yZCArIHN1bShwcm9ic1sxOjcxXSkqY09yZGVuYXINCn0NCnZFc3BlcmFkb09yZA0KYGBgDQoNCmBgYHtyfQ0KIyBMaXRlcmFsIEMuIE1vbnRlQ2FybG8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tDQplc2NlbmFyaW9zID0gOA0Kc2VtYW5hcyA9IDMwDQoNCmludmVudGFyaW8gPSBtYXRyaXgoMCxucm93ID0gc2VtYW5hcywgbmNvbCA9IGVzY2VuYXJpb3MpDQoNCg0KI1NpbXVsYXIgbGEgY2FkZW5hIGRlIG1hcmtvdg0Kc2V0LnNlZWQoMCkNCmZvciAoaiBpbiAxOmVzY2VuYXJpb3MpIHsNCiAgDQogICNEZXRlcm1pbmFyIGVsIGVzdGFkbyBpbmljaWFsDQogIGVzdGFkbyA9IDANCiAgDQogICNTSW11bGFyIGxhcyAzMCBzZW1hbmFzDQogIGZvciAoaSBpbiAxOnNlbWFuYXMpIHsNCiAgICANCiAgICAjR3VhcmRhciBlbCBpbnZlbnRhcmlvIGFjdHVhbA0KICAgIGludmVudGFyaW9baSxqXSA9IGVzdGFkbw0KICAgIA0KICAgIGVzdGFkbyA9IHNhbXBsZShlc3RhZG9zLCBzaXplID0gMSwgcHJvYiA9IG1hdHJpelBbYXMuY2hhcmFjdGVyKGVzdGFkbyksXSkNCiAgICANCiAgfQ0KfQ0KDQptYXRwbG90KGludmVudGFyaW8sIHR5cGUgPSAnbCcsIHhsYWIgPSAnU2VtYW5hcycsIHlsYWIgPSAnSW52ZW50YXJpbycpDQpgYGANCg0KTGl0ZXJhbCBEDQoNCmBgYHtyfQ0KZXNjZW5hcmlvcyA9IDEwMDANCnNlbWFuYXMgPSAzMA0KDQppbnZlbnRhcmlvID0gbWF0cml4KDAsbnJvdyA9IHNlbWFuYXMsIG5jb2wgPSBlc2NlbmFyaW9zKQ0KDQoNCiNTaW11bGFyIGxhIGNhZGVuYSBkZSBtYXJrb3YNCnNldC5zZWVkKDApDQpmb3IgKGogaW4gMTplc2NlbmFyaW9zKSB7DQogIA0KICAjRGV0ZXJtaW5hciBlbCBlc3RhZG8gaW5pY2lhbA0KICBlc3RhZG8gPSAwDQogIA0KICAjU0ltdWxhciBsYXMgMzAgc2VtYW5hcw0KICBmb3IgKGkgaW4gMTpzZW1hbmFzKSB7DQogICAgDQogICAgI0d1YXJkYXIgZWwgaW52ZW50YXJpbyBhY3R1YWwNCiAgICBpbnZlbnRhcmlvW2ksal0gPSBlc3RhZG8NCiAgICANCiAgICBlc3RhZG8gPSBzYW1wbGUoZXN0YWRvcywgc2l6ZSA9IDEsIHByb2IgPSBtYXRyaXpQW2FzLmNoYXJhY3Rlcihlc3RhZG8pLF0pDQogICAgDQogIH0NCn0NCg0KaGlzdChpbnZlbnRhcmlvWzMwLF0sIG1haW4gPSAnRGlzdHJpYnVjacOzbiBkZWwgaW52ZW50YXJpbyBlbiBsYSBzZW1hbmEgMzAnKQ0KDQojQ2FsY3VsYW5kbyBlbCBpbnZlbnRhcmlvIHByb21lZGlvIGNvbiBNb250ZUNhcmxvDQppbnZlbnRhcmlvX3Byb21lZGlvID0gbWVhbihpbnZlbnRhcmlvWzMwLF0pDQoNCnByaW50KHBhc3RlKCdJbnZlbnRhcmlvIGNvbiBzaW11bGFjacOzbiBkZSBNb250ZUNhcmxvOiAnLCBpbnZlbnRhcmlvX3Byb21lZGlvKSkNCg0KI1ZhbG9yZXNwZXJhZG8gY29uIGFuYWxpc2lzIHRyYW5zaXRvcmlvDQpwcmludChwYXN0ZSgnVmFsb3IgZXNwZXJhZG8gZGVsIGludmVudGFyaW8gKGxpdGVyYWwgYik6ICcsIHJvdW5kKHZFc3BlcmFkb0ludlszMF0sMykpKQ0KYGBgDQoNCiMgTGl0ZXJhbCBFIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQ0KDQpgYGB7cn0NCmVzY2VuYXJpb3MgPC0gMTAwMA0Kc2VtYW5hcyA8LSAzMA0KDQojIEluaWNpYWxpemFyIHZlY3RvciBwYXJhIGd1YXJkYXIgbG9zIGNvc3RvcyBkZSBvcmRlbmFyIGRlIGNhZGEgZXNjZW5hcmlvDQp2ZWN0b3JfY29zdG9zIDwtIGMoKQ0KDQojIFNpbXVsYXIgbGEgY2FkZW5hIGRlIE1hcmtvdg0Kc2V0LnNlZWQoMCkNCmZvcihqIGluIDE6ZXNjZW5hcmlvcyl7DQogIA0KICAjIERlZmluaXIgZWwgZXN0YWRvIGluaWNpYWwgKGludmVudGFyaW8gaW5pY2lhbCkNCiAgZXN0YWRvIDwtIDANCiAgIyBJbmljaWFsaXphciBjb3N0byBkZSBvcmRlbmFyDQogIGNvc3RvIDwtIDANCiAgDQogICMgU2ltdWxhciBsYXMgdHJhbnNpY2lvbmVzIHBvciAzMCBzZW1hbmFzDQogIGZvcihpIGluIDE6c2VtYW5hcyl7DQogICAgDQogICAgIyBTaSBlbCBpbnZlbnRhcmlvIGVzIG1lbm9yIGEgNzAsIHN1bWFyIGNvc3RvIGRlIG9yZGVuYXINCiAgICBpZihlc3RhZG88PTcwKXsNCiAgICAgIGNvc3RvID0gY29zdG8gKyBjT3JkZW5hcg0KICAgIH0NCiAgICBlc3RhZG8gPC0gc2FtcGxlKGVzdGFkb3MsIHNpemU9MSwgcHJvYj1tYXRyaXpQW2FzLmNoYXJhY3Rlcihlc3RhZG8pLF0pDQogIH0NCiAgDQogICMgR3VhcmRhciBlbCBjb3N0byBkZSBvcmRlbmFyDQogIHZlY3Rvcl9jb3N0b3MgPC0gYyh2ZWN0b3JfY29zdG9zLCBjb3N0bykNCn0NCmNvc3RvX3Byb21lZGlvID0gbWVhbih2ZWN0b3JfY29zdG9zKQ0KY29zdG9fcHJvbWVkaW8NCg0KcHJpbnQocGFzdGUoIkNvc3RvIHRvdGFsIGRlIG9yZGVuYXIgcHJvbWVkaW8gdXRpbGl6YW5kbyBzaW11bGFjacOzbiBkZSBNb250ZSBDYXJsbzogIiwgY3VycmVuY3koY29zdG9fcHJvbWVkaW8pKSkNCg0KcHJpbnQocGFzdGUoIlZhbG9yIGVzcGVyYWRvIGRlbCBjb3N0byB0b3RhbCBkZSBvcmRlbmFyOiAiLCBjdXJyZW5jeShyb3VuZCh2RXNwZXJhZG9PcmQsMykpKSkNCg0KYGBgDQo=