En RStudio se puede reconocer 4 secciones, el editor de R, la consola, las variables de ambiente, y los archivos y ayuda de R. En la consola es posible ejecutar código; realizar operaciones aritméticas, correr funciones y evaluar variables, sin embargo no es posible almacenar el código que se escribe en la consola, por esta razón se utiliza el script de R.

En el script se escribe el código que se quiere almacenar para volver a ejecutar en el futuro. Al guardar, el archivo resultante es un script de R que tiene extensión “.R”.

Las variables globales que sean definidas en el código aparecerán en las variables de ambiente y en la pestaña de ayuda de R se encontrará la información de paquetes, funciones y gráficas que sean generadas

Primero, vamos a definir las variables, hay dos operadores para dfinirlas

a = 1
b <- 2

Existen diferentes clases de objetos en R

Caracteres Numeros (reales) Enteros Complejos Logicos (True/False)

VECTORES

Tambien podemos crear vectores de diferentes clases de objetos

#Vector con numeros enteros
vectorA = c(1,5)

#Vector con caracteres
vectorB = c('hola', 'bien','modelos')

#Vector con diferentes calses de objetos
vectorDiverso = c(1.4, 'dos', TRUE)
class(vectorDiverso)

vectorExplicito = 0:7
class(vectorExplicito)

as.character(vectorExplicito)

as.logical(vectorExplicito)

Como instalar paquetes de R?

# install.packages("Nombre del paquete")
# library('Nombre del paquete')

install.packages('markovchain')
library('markovchain')

Funciones en R

#------------------------------------Funciones en R-------------------------#

#estructura de codigo de una funciC3n
funcion1 = function(arg1,arg2){
  statements
  return(object)
}

Ejemplo. Vamos a crear una funcion como parametro un numero y calcule su raiz cubica y suma 10

funcion2 = function(n){
  valor = (n^(1/3))+10
  return(valor)
}
funcion2(4)

Una función, no necesariamente debe retornar un valor numerico, puede retornar graficas

funcion3 = function(x){
  y <- seq(from = 1, to = length(x), by = 1)
  plot(y,x, type = 'c', col = 'red')
}
vector1 = c(5,4,7,6,10)
funcion3(vector1)

Recorridos en R

funcion4 = function(v1,v2){
  vectorResultado = rep(0,times = length(v1))
  
  for(i in 1:length(v1)){
    vectorResultado[i] = max(v1[i],v2[i])
   }
  return(vectorResultado)
}

vectorp = c(2,3,4,5,6)
vectorp2 = c(3,1,9,8,2)

funcion4(vectorp,vectorp2)

ESTRUCTURAS DE CONTROL O CONDIONALES

x = 4
if (x <= 10) {
  print('x es menor a 10')
} else {
  print('x es mayor a 10')
} 

x = 10
if (x > 1 & x < 7) {
  print('X es un numero entre 1 y 7')
} else if (x > 8 & x < 15) {
  print(('X es un numero entre 8 y 15'))
}

Poniendo en practica lo aprendido, vamos a elaborar una funciC3n que retorne TRUE si un numero especifico esta dentro de un vector

funcion5 = function(vector,n){
  for (i in 1:length(vector)) {
    if (vector[i] == n) {
      return(TRUE)
    } 
  }
  return(FALSE)
}


vectorE = c(3,4,7,9,10,18,23,78,95)
y = 18
funcion5(vectorE,y)
#Graficas en R
#Vamos a crear un grafico de lineas usando dos vectores

vectorC = c(1,3,4,7,8,4,2)
vectorD = c(1,2,3,4,5,6,7)

grafica = plot(vectorD, vectorC, type = 'l', col = 'blue')

COMPLEMENTARIA 2

El objetivo de esta complementaria es definir y manejar matrices en R. Ya qué estas son las las matrices que usaremos para definir las cadenas de Markov.

Primero vamos a hacer una matri< que nos diga algunas estadisticas importantes de equipos de futbol colombiano.

Para esto usaremos la funcion matrix

¿Cuales son los pricnipales argumentos de la función matrix?. Set de datos, número de filas y numero de columnas

mat = matrix(c(1,4,1,3,2,4,4,0,3,2,1,1,4,2,2,0), nrow = 4, ncol = 4)

Es importante tener en cuenta que la matriz se genera por columna por defecto, a menos que utilizemos el comendo byrow

mat = matrix(c(1,4,1,3,2,4,4,0,3,2,1,1,4,2,2,0), nrow = 4, ncol = 4, byrow = TRUE)

Tambien podemos incorporar nombres a las filas y a las columnas de nuestra matriz. Utilizando el comando dimnames

dimnames(mat) = list(c('America', 'Alianza','Santafe','Fortaleza'),
                     c('Pos','Goles marcados', 'Goles recibidos', 'Diferencia'))

Ahora, digamos que queremos añadir las estadisticas de otro equipo a nuestra matriz. Esto lo podemos hacer con ayuda de la funcion rbind

Millonarios = c(5,0,3,-5)
mat = rbind(mat, Millonarios)

Como podemos acceder a las filas o a las columnas de la matriz?

mat['America',]
mat[,'Goles recibidos']
#Otro ejemplo
mat[1,]
mat[,3]

Es importante verificar que el conjunto de datos o matriz que estemos creando sea efectivamente de tipo matrix

Para evaluar si un conjunto de datos es de tipo matrix

is.matrix(mat)

Para convertir un set de datos a matriz

as.matrix(mat)

Porque es importante esto, por las operacionesque podemos hacer entre matrices. Aqui hay algunos ejemplos

Vamos a crear dos matrices cutos valores van a seguir una dsirtribución normal, esto es para efectos de generara rapidamente valores aleatorios.

A = matrix(rnorm(n=36, mean = 20, sd = 8), nrow = 6, ncol = 6)
B = matrix(rnorm(n=36, mean = 10, sd = 3), nrow = 6, ncol = 6)

Operaciones entre matrices

#transpuesta de una matriz
t(A)

#Suma de matrices
A + B

#Producto matricial
A%*%B

#Producto elemento a elemento
A*B

#Inversa de una matriz
solve(A)

#determinante de una matriz
det(A)

#diagonal de la matriz
diag(A)

#Suma de columnas y filas
rowSums(A)
colSums(B)

Ahora veremos como reflejar una cadena de markov a R, entonces vamos a hacer el primer problema de de la complementaria 2

estados = c(1:5)

mat1 = matrix(0, nrow = 5, ncol = 5, dimnames = list(estados,estados))

filas = estados
columnas = estados

for (i in filas) {
  for (j in columnas) {
    
    if (j == i & i >= 2 & i <= 4) {
      mat1[i,j] = 0.3
    }
    if (j == i - 1 & i >= 2) {
      mat1[i,j] = 0.2
    }
    if (j == i + 1 & i <= 4) {
      mat1[i,j] = 0.5
    }
    if (j == i & i == 1 ) {
      mat1[i,j] = 0.5
    }
    if (j == i & i == 5) {
      mat1[i,j] = 0.8
    }
  }
}
View(mat1)
rowSums(mat1)
LS0tDQp0aXRsZTogIkNvbXBsZW1lbnRhcmlhIDIiDQpvdXRwdXQ6DQogIGh0bWxfbm90ZWJvb2s6IGRlZmF1bHQNCiAgaHRtbF9kb2N1bWVudDoNCiAgICBkZl9wcmludDogcGFnZWQNCiAgcGRmX2RvY3VtZW50OiBkZWZhdWx0DQotLS0NCg0KRW4gUlN0dWRpbyBzZSBwdWVkZSByZWNvbm9jZXIgNCBzZWNjaW9uZXMsIGVsIGVkaXRvciBkZSBSLCBsYSBjb25zb2xhLCBsYXMgdmFyaWFibGVzIGRlIGFtYmllbnRlLCB5IGxvcyBhcmNoaXZvcyB5IGF5dWRhIGRlIFIuIEVuIGxhIGNvbnNvbGEgZXMgcG9zaWJsZSBlamVjdXRhciBjw7NkaWdvOyByZWFsaXphciBvcGVyYWNpb25lcyBhcml0bcOpdGljYXMsIGNvcnJlciBmdW5jaW9uZXMgeSBldmFsdWFyIHZhcmlhYmxlcywgc2luIGVtYmFyZ28gbm8gZXMgcG9zaWJsZSBhbG1hY2VuYXIgZWwgY8OzZGlnbyBxdWUgc2UgZXNjcmliZSBlbiBsYSBjb25zb2xhLCBwb3IgZXN0YSByYXrDs24gc2UgdXRpbGl6YSBlbCBzY3JpcHQgZGUgUi4gDQoNCg0KRW4gZWwgc2NyaXB0IHNlIGVzY3JpYmUgZWwgY8OzZGlnbyBxdWUgc2UgcXVpZXJlIGFsbWFjZW5hciBwYXJhIHZvbHZlciBhIGVqZWN1dGFyIGVuIGVsIGZ1dHVyby4gQWwgZ3VhcmRhciwgZWwgYXJjaGl2byByZXN1bHRhbnRlIGVzIHVuIHNjcmlwdCBkZSBSIHF1ZSB0aWVuZSBleHRlbnNpw7NuIOKAnC5S4oCdLiANCg0KDQpMYXMgdmFyaWFibGVzIGdsb2JhbGVzIHF1ZSBzZWFuIGRlZmluaWRhcyBlbiBlbCBjw7NkaWdvIGFwYXJlY2Vyw6FuIGVuIGxhcyB2YXJpYWJsZXMgZGUgYW1iaWVudGUgeSBlbiBsYSBwZXN0YcOxYSBkZSBheXVkYSBkZSBSIHNlIGVuY29udHJhcsOhIGxhIGluZm9ybWFjacOzbiBkZSBwYXF1ZXRlcywgZnVuY2lvbmVzIHkgZ3LDoWZpY2FzIHF1ZSBzZWFuIGdlbmVyYWRhcw0KDQpQcmltZXJvLCB2YW1vcyBhIGRlZmluaXIgbGFzIHZhcmlhYmxlcywgaGF5IGRvcyBvcGVyYWRvcmVzIHBhcmEgZGZpbmlybGFzDQpgYGB7cn0NCmEgPSAxDQpiIDwtIDINCg0KYGBgDQoNCkV4aXN0ZW4gZGlmZXJlbnRlcyBjbGFzZXMgZGUgb2JqZXRvcyBlbiBSDQoNCkNhcmFjdGVyZXMNCk51bWVyb3MgKHJlYWxlcykNCkVudGVyb3MNCkNvbXBsZWpvcw0KTG9naWNvcyAoVHJ1ZS9GYWxzZSkNCg0KVkVDVE9SRVMNCg0KVGFtYmllbiBwb2RlbW9zIGNyZWFyIHZlY3RvcmVzIGRlIGRpZmVyZW50ZXMgY2xhc2VzIGRlIG9iamV0b3MNCg0KYGBge3J9DQojVmVjdG9yIGNvbiBudW1lcm9zIGVudGVyb3MNCnZlY3RvckEgPSBjKDEsNSkNCg0KI1ZlY3RvciBjb24gY2FyYWN0ZXJlcw0KdmVjdG9yQiA9IGMoJ2hvbGEnLCAnYmllbicsJ21vZGVsb3MnKQ0KDQojVmVjdG9yIGNvbiBkaWZlcmVudGVzIGNhbHNlcyBkZSBvYmpldG9zDQp2ZWN0b3JEaXZlcnNvID0gYygxLjQsICdkb3MnLCBUUlVFKQ0KY2xhc3ModmVjdG9yRGl2ZXJzbykNCg0KdmVjdG9yRXhwbGljaXRvID0gMDo3DQpjbGFzcyh2ZWN0b3JFeHBsaWNpdG8pDQoNCmFzLmNoYXJhY3Rlcih2ZWN0b3JFeHBsaWNpdG8pDQoNCmFzLmxvZ2ljYWwodmVjdG9yRXhwbGljaXRvKQ0KDQpgYGANCg0KQ29tbyBpbnN0YWxhciBwYXF1ZXRlcyBkZSBSPw0KDQpgYGB7cn0NCiMgaW5zdGFsbC5wYWNrYWdlcygiTm9tYnJlIGRlbCBwYXF1ZXRlIikNCiMgbGlicmFyeSgnTm9tYnJlIGRlbCBwYXF1ZXRlJykNCg0KaW5zdGFsbC5wYWNrYWdlcygnbWFya292Y2hhaW4nKQ0KbGlicmFyeSgnbWFya292Y2hhaW4nKQ0KYGBgDQoNCkZ1bmNpb25lcyBlbiBSDQoNCmBgYHtyfQ0KIy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLUZ1bmNpb25lcyBlbiBSLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSMNCg0KI2VzdHJ1Y3R1cmEgZGUgY29kaWdvIGRlIHVuYSBmdW5jaUMzbg0KZnVuY2lvbjEgPSBmdW5jdGlvbihhcmcxLGFyZzIpew0KICBzdGF0ZW1lbnRzDQogIHJldHVybihvYmplY3QpDQp9DQpgYGANCkVqZW1wbG8uIFZhbW9zIGEgY3JlYXIgdW5hIGZ1bmNpb24gY29tbyBwYXJhbWV0cm8gdW4gbnVtZXJvIHkgY2FsY3VsZSBzdSByYWl6IGN1YmljYSB5IHN1bWEgMTANCg0KYGBge3J9DQpmdW5jaW9uMiA9IGZ1bmN0aW9uKG4pew0KICB2YWxvciA9IChuXigxLzMpKSsxMA0KICByZXR1cm4odmFsb3IpDQp9DQpmdW5jaW9uMig0KQ0KYGBgDQoNClVuYSBmdW5jacOzbiwgbm8gbmVjZXNhcmlhbWVudGUgZGViZSByZXRvcm5hciB1biB2YWxvciBudW1lcmljbywgcHVlZGUgcmV0b3JuYXIgZ3JhZmljYXMNCmBgYHtyfQ0KZnVuY2lvbjMgPSBmdW5jdGlvbih4KXsNCiAgeSA8LSBzZXEoZnJvbSA9IDEsIHRvID0gbGVuZ3RoKHgpLCBieSA9IDEpDQogIHBsb3QoeSx4LCB0eXBlID0gJ2MnLCBjb2wgPSAncmVkJykNCn0NCnZlY3RvcjEgPSBjKDUsNCw3LDYsMTApDQpmdW5jaW9uMyh2ZWN0b3IxKQ0KYGBgDQoNClJlY29ycmlkb3MgZW4gUg0KDQpgYGB7cn0NCmZ1bmNpb240ID0gZnVuY3Rpb24odjEsdjIpew0KICB2ZWN0b3JSZXN1bHRhZG8gPSByZXAoMCx0aW1lcyA9IGxlbmd0aCh2MSkpDQogIA0KICBmb3IoaSBpbiAxOmxlbmd0aCh2MSkpew0KICAgIHZlY3RvclJlc3VsdGFkb1tpXSA9IG1heCh2MVtpXSx2MltpXSkNCiAgIH0NCiAgcmV0dXJuKHZlY3RvclJlc3VsdGFkbykNCn0NCg0KdmVjdG9ycCA9IGMoMiwzLDQsNSw2KQ0KdmVjdG9ycDIgPSBjKDMsMSw5LDgsMikNCg0KZnVuY2lvbjQodmVjdG9ycCx2ZWN0b3JwMikNCmBgYA0KDQpFU1RSVUNUVVJBUyBERSBDT05UUk9MIE8gQ09ORElPTkFMRVMNCg0KYGBge3J9DQp4ID0gNA0KaWYgKHggPD0gMTApIHsNCiAgcHJpbnQoJ3ggZXMgbWVub3IgYSAxMCcpDQp9IGVsc2Ugew0KICBwcmludCgneCBlcyBtYXlvciBhIDEwJykNCn0gDQoNCnggPSAxMA0KaWYgKHggPiAxICYgeCA8IDcpIHsNCiAgcHJpbnQoJ1ggZXMgdW4gbnVtZXJvIGVudHJlIDEgeSA3JykNCn0gZWxzZSBpZiAoeCA+IDggJiB4IDwgMTUpIHsNCiAgcHJpbnQoKCdYIGVzIHVuIG51bWVybyBlbnRyZSA4IHkgMTUnKSkNCn0NCmBgYA0KDQoNClBvbmllbmRvIGVuIHByYWN0aWNhIGxvIGFwcmVuZGlkbywgdmFtb3MgYSBlbGFib3JhciB1bmEgZnVuY2lDM24gcXVlIHJldG9ybmUgVFJVRSBzaSB1biBudW1lcm8gZXNwZWNpZmljbyBlc3RhIGRlbnRybyBkZSB1biB2ZWN0b3INCg0KYGBge3J9DQpmdW5jaW9uNSA9IGZ1bmN0aW9uKHZlY3RvcixuKXsNCiAgZm9yIChpIGluIDE6bGVuZ3RoKHZlY3RvcikpIHsNCiAgICBpZiAodmVjdG9yW2ldID09IG4pIHsNCiAgICAgIHJldHVybihUUlVFKQ0KICAgIH0gDQogIH0NCiAgcmV0dXJuKEZBTFNFKQ0KfQ0KDQoNCnZlY3RvckUgPSBjKDMsNCw3LDksMTAsMTgsMjMsNzgsOTUpDQp5ID0gMTgNCmZ1bmNpb241KHZlY3RvckUseSkNCmBgYA0KDQpgYGB7cn0NCiNHcmFmaWNhcyBlbiBSDQojVmFtb3MgYSBjcmVhciB1biBncmFmaWNvIGRlIGxpbmVhcyB1c2FuZG8gZG9zIHZlY3RvcmVzDQoNCnZlY3RvckMgPSBjKDEsMyw0LDcsOCw0LDIpDQp2ZWN0b3JEID0gYygxLDIsMyw0LDUsNiw3KQ0KDQpncmFmaWNhID0gcGxvdCh2ZWN0b3JELCB2ZWN0b3JDLCB0eXBlID0gJ2wnLCBjb2wgPSAnYmx1ZScpDQoNCmBgYA0KDQoNCkNPTVBMRU1FTlRBUklBIDINCg0KRWwgb2JqZXRpdm8gZGUgZXN0YSBjb21wbGVtZW50YXJpYSBlcyBkZWZpbmlyIHkgbWFuZWphciBtYXRyaWNlcyBlbiBSLiBZYSBxdcOpIGVzdGFzIHNvbiBsYXMgbGFzIG1hdHJpY2VzIHF1ZSB1c2FyZW1vcyBwYXJhIGRlZmluaXIgbGFzIGNhZGVuYXMgZGUgTWFya292Lg0KDQpQcmltZXJvIHZhbW9zIGEgaGFjZXIgdW5hIG1hdHJpPCBxdWUgbm9zIGRpZ2EgYWxndW5hcyBlc3RhZGlzdGljYXMgaW1wb3J0YW50ZXMgZGUgZXF1aXBvcyBkZSBmdXRib2wgY29sb21iaWFuby4NCg0KUGFyYSBlc3RvIHVzYXJlbW9zIGxhIGZ1bmNpb24gbWF0cml4DQoNCsK/Q3VhbGVzIHNvbiBsb3MgcHJpY25pcGFsZXMgYXJndW1lbnRvcyBkZSBsYSBmdW5jacOzbiBtYXRyaXg/LiBTZXQgZGUgZGF0b3MsIG7Dum1lcm8gZGUgZmlsYXMgeSBudW1lcm8gZGUgY29sdW1uYXMNCg0KYGBge3J9DQptYXQgPSBtYXRyaXgoYygxLDQsMSwzLDIsNCw0LDAsMywyLDEsMSw0LDIsMiwwKSwgbnJvdyA9IDQsIG5jb2wgPSA0KQ0KYGBgDQoNCkVzIGltcG9ydGFudGUgdGVuZXIgZW4gY3VlbnRhIHF1ZSBsYSBtYXRyaXogc2UgZ2VuZXJhIHBvciBjb2x1bW5hIHBvciBkZWZlY3RvLCBhIG1lbm9zIHF1ZSB1dGlsaXplbW9zIGVsIGNvbWVuZG8gYnlyb3cNCg0KYGBge3J9DQptYXQgPSBtYXRyaXgoYygxLDQsMSwzLDIsNCw0LDAsMywyLDEsMSw0LDIsMiwwKSwgbnJvdyA9IDQsIG5jb2wgPSA0LCBieXJvdyA9IFRSVUUpDQoNCmBgYA0KDQpUYW1iaWVuIHBvZGVtb3MgaW5jb3Jwb3JhciBub21icmVzIGEgbGFzIGZpbGFzIHkgYSBsYXMgY29sdW1uYXMgZGUgbnVlc3RyYSBtYXRyaXouIFV0aWxpemFuZG8gZWwgY29tYW5kbyBkaW1uYW1lcw0KDQpgYGB7cn0NCmRpbW5hbWVzKG1hdCkgPSBsaXN0KGMoJ0FtZXJpY2EnLCAnQWxpYW56YScsJ1NhbnRhZmUnLCdGb3J0YWxlemEnKSwNCiAgICAgICAgICAgICAgICAgICAgIGMoJ1BvcycsJ0dvbGVzIG1hcmNhZG9zJywgJ0dvbGVzIHJlY2liaWRvcycsICdEaWZlcmVuY2lhJykpDQoNCmBgYA0KDQpBaG9yYSwgZGlnYW1vcyBxdWUgcXVlcmVtb3MgYcOxYWRpciBsYXMgZXN0YWRpc3RpY2FzIGRlIG90cm8gZXF1aXBvIGEgbnVlc3RyYSBtYXRyaXouIEVzdG8gbG8gcG9kZW1vcyBoYWNlciBjb24gYXl1ZGEgZGUgbGEgZnVuY2lvbiByYmluZA0KDQpgYGB7cn0NCk1pbGxvbmFyaW9zID0gYyg1LDAsMywtNSkNCm1hdCA9IHJiaW5kKG1hdCwgTWlsbG9uYXJpb3MpDQoNCmBgYA0KDQpDb21vIHBvZGVtb3MgYWNjZWRlciBhIGxhcyBmaWxhcyBvIGEgbGFzIGNvbHVtbmFzIGRlIGxhIG1hdHJpej8NCg0KYGBge3J9DQptYXRbJ0FtZXJpY2EnLF0NCm1hdFssJ0dvbGVzIHJlY2liaWRvcyddDQojT3RybyBlamVtcGxvDQptYXRbMSxdDQptYXRbLDNdDQoNCmBgYA0KDQpFcyBpbXBvcnRhbnRlIHZlcmlmaWNhciBxdWUgZWwgY29uanVudG8gZGUgZGF0b3MgbyBtYXRyaXogcXVlIGVzdGVtb3MgY3JlYW5kbyBzZWEgZWZlY3RpdmFtZW50ZSBkZSB0aXBvIG1hdHJpeA0KDQpQYXJhIGV2YWx1YXIgc2kgdW4gY29uanVudG8gZGUgZGF0b3MgZXMgZGUgdGlwbyBtYXRyaXgNCg0KYGBge3J9DQppcy5tYXRyaXgobWF0KQ0KDQpgYGANCg0KUGFyYSBjb252ZXJ0aXIgdW4gc2V0IGRlIGRhdG9zIGEgbWF0cml6DQoNCmBgYHtyfQ0KYXMubWF0cml4KG1hdCkNCg0KYGBgDQoNClBvcnF1ZSBlcyBpbXBvcnRhbnRlIGVzdG8sIHBvciBsYXMgb3BlcmFjaW9uZXNxdWUgcG9kZW1vcyBoYWNlciBlbnRyZSBtYXRyaWNlcy4gQXF1aSBoYXkgYWxndW5vcyBlamVtcGxvcw0KDQpWYW1vcyBhIGNyZWFyIGRvcyBtYXRyaWNlcyBjdXRvcyB2YWxvcmVzIHZhbiBhIHNlZ3VpciB1bmEgZHNpcnRyaWJ1Y2nDs24gbm9ybWFsLCBlc3RvIGVzIHBhcmEgZWZlY3RvcyBkZSBnZW5lcmFyYSByYXBpZGFtZW50ZSB2YWxvcmVzIGFsZWF0b3Jpb3MuDQoNCmBgYHtyfQ0KQSA9IG1hdHJpeChybm9ybShuPTM2LCBtZWFuID0gMjAsIHNkID0gOCksIG5yb3cgPSA2LCBuY29sID0gNikNCkIgPSBtYXRyaXgocm5vcm0obj0zNiwgbWVhbiA9IDEwLCBzZCA9IDMpLCBucm93ID0gNiwgbmNvbCA9IDYpDQpgYGANCg0KT3BlcmFjaW9uZXMgZW50cmUgbWF0cmljZXMNCg0KDQpgYGB7cn0NCiN0cmFuc3B1ZXN0YSBkZSB1bmEgbWF0cml6DQp0KEEpDQoNCiNTdW1hIGRlIG1hdHJpY2VzDQpBICsgQg0KDQojUHJvZHVjdG8gbWF0cmljaWFsDQpBJSolQg0KDQojUHJvZHVjdG8gZWxlbWVudG8gYSBlbGVtZW50bw0KQSpCDQoNCiNJbnZlcnNhIGRlIHVuYSBtYXRyaXoNCnNvbHZlKEEpDQoNCiNkZXRlcm1pbmFudGUgZGUgdW5hIG1hdHJpeg0KZGV0KEEpDQoNCiNkaWFnb25hbCBkZSBsYSBtYXRyaXoNCmRpYWcoQSkNCg0KI1N1bWEgZGUgY29sdW1uYXMgeSBmaWxhcw0Kcm93U3VtcyhBKQ0KY29sU3VtcyhCKQ0KDQpgYGANCg0KQWhvcmEgdmVyZW1vcyBjb21vIHJlZmxlamFyIHVuYSBjYWRlbmEgZGUgbWFya292IGEgUiwgZW50b25jZXMgdmFtb3MgYSBoYWNlciBlbCBwcmltZXIgcHJvYmxlbWEgZGUgZGUgbGEgY29tcGxlbWVudGFyaWEgMg0KDQpgYGB7cn0NCmVzdGFkb3MgPSBjKDE6NSkNCg0KbWF0MSA9IG1hdHJpeCgwLCBucm93ID0gNSwgbmNvbCA9IDUsIGRpbW5hbWVzID0gbGlzdChlc3RhZG9zLGVzdGFkb3MpKQ0KDQpmaWxhcyA9IGVzdGFkb3MNCmNvbHVtbmFzID0gZXN0YWRvcw0KDQpmb3IgKGkgaW4gZmlsYXMpIHsNCiAgZm9yIChqIGluIGNvbHVtbmFzKSB7DQogICAgDQogICAgaWYgKGogPT0gaSAmIGkgPj0gMiAmIGkgPD0gNCkgew0KICAgICAgbWF0MVtpLGpdID0gMC4zDQogICAgfQ0KICAgIGlmIChqID09IGkgLSAxICYgaSA+PSAyKSB7DQogICAgICBtYXQxW2ksal0gPSAwLjINCiAgICB9DQogICAgaWYgKGogPT0gaSArIDEgJiBpIDw9IDQpIHsNCiAgICAgIG1hdDFbaSxqXSA9IDAuNQ0KICAgIH0NCiAgICBpZiAoaiA9PSBpICYgaSA9PSAxICkgew0KICAgICAgbWF0MVtpLGpdID0gMC41DQogICAgfQ0KICAgIGlmIChqID09IGkgJiBpID09IDUpIHsNCiAgICAgIG1hdDFbaSxqXSA9IDAuOA0KICAgIH0NCiAgfQ0KfQ0KVmlldyhtYXQxKQ0Kcm93U3VtcyhtYXQxKQ0KDQpgYGANCg0KDQoNCg==