Function Usage Example
matrix() Create matrix matrix(1:9, nrow=3)
cbind() Combine columns cbind(1:3, 4:6)
rbind() Combine rows rbind(1:3, 4:6)
dim() Get dimensions dim(matrix(1:6, 2, 3))
nrow() Number of rows nrow(matrix(1:6, 2, 3))
ncol() Number of columns ncol(matrix(1:6, 2, 3))
sum() Sum elements sum(1:5)
prod() Product elements prod(1:4)
mean() Arithmetic mean mean(c(1,2,3,4))
var() Variance var(c(1,2,3,4,5))
sd() Standard deviation sd(c(1,2,3,4,5))
max() Maximum value max(c(3,1,4,1,5))
min() Minimum value min(c(3,1,4,1,5))
sort() Sort vector sort(c(3,1,4,1,5))
order() Get sort order order(c(3,1,4))
rev() Reverse vector rev(1:5)
cumsum() Cumulative sum cumsum(1:5)
cumprod() Cumulative product cumprod(1:5)
abs() Absolute value abs(c(-1,2,-3))
sqrt() Square root sqrt(c(4,9,16))
acos() Arc cosine acos(0.5)
pi π constant pi
det() Determinant det(matrix(c(1,2,3,4),2))
solve() Solve/inverse solve(matrix(c(4,7,2,6),2))
t() Transpose t(matrix(1:6,2,3))
diag() Diagonal/extract diag(3)
identical() Exact equality identical(1,1.0)
sample() Random sample sample(1:10, 3)
seq() Generate sequence seq(1,10,2)
rep() Replicate values rep(5,3)
if() Conditional if(x>0) print("positive")
else() Alternative else print("negative")
for() Loop for(i in 1:5) print(i)
while() While loop while(x<10) x<-x+1
function() Define function f <- function(x) x^2
return() Return value return(x+y)
list() Create list list(a=1, b="text")
c() Combine values c(1,2,3)
numeric() Create numeric vector numeric(5)
colSums() Column sums colSums(matrix(1:9,3))
rowSums() Row sums rowSums(matrix(1:9,3))
colMeans() Column means colMeans(matrix(1:9,3))
rowMeans() Row means rowMeans(matrix(1:9,3))
%*% Matrix multiplication matrix(1:4,2) %*% matrix(5:8,2)
eigen() Eigenvalues/vectors eigen(matrix(c(4,1,1,3),2))

Here are all the vector functions:

# 1. Dot product
dot_product <- function(a, b) {
  sum(a * b)
}

# 2. Magnitude
magnitude <- function(a) {
  sqrt(sum(a^2))
}

# 3. Normalize
normalize <- function(a) {
  mag <- magnitude(a)
  if (mag == 0) stop("Zero vector cannot be normalized")
  a / mag
}

# 4. Cross product (3D)
cross_product <- function(a, b) {
  if (length(a) != 3 || length(b) != 3) stop("Vectors must be 3D")
  c(a[2]*b[3] - a[3]*b[2],
    a[3]*b[1] - a[1]*b[3],
    a[1]*b[2] - a[2]*b[1])
}

# 5. Check orthogonal
is_orthogonal <- function(a, b, tol = 1e-10) {
  abs(dot_product(a, b)) < tol
}

# 6. Check parallel
is_parallel <- function(a, b, tol = 1e-10) {
  mag_a <- magnitude(a)
  mag_b <- magnitude(b)
  if (mag_a == 0 || mag_b == 0) return(TRUE)
  abs(dot_product(a, b) / (mag_a * mag_b)) > 1 - tol
}

# 7. Angle in degrees
angle_degrees <- function(a, b) {
  mag_a <- magnitude(a)
  mag_b <- magnitude(b)
  if (mag_a == 0 || mag_b == 0) stop("Zero vector has no angle")
  acos(dot_product(a, b) / (mag_a * mag_b)) * 180 / pi
}

# 8. Projection of a onto b
projection <- function(a, b) {
  (dot_product(a, b) / dot_product(b, b)) * b
}

# 9. Scalar projection
scalar_projection <- function(a, b) {
  dot_product(a, b) / magnitude(b)
}

# 10. Add vectors
vector_add <- function(a, b) {
  a + b
}

# 11. Subtract vectors
vector_subtract <- function(a, b) {
  a - b
}

# 12. Multiply by scalar
vector_scale <- function(a, k) {
  a * k
}

# 13. Sum of elements
vector_sum <- function(a) {
  sum(a)
}

# 14. Product of elements
vector_prod <- function(a) {
  prod(a)
}

# 15. Maximum
vector_max <- function(a) {
  max(a)
}

# 16. Minimum
vector_min <- function(a) {
  min(a)
}

# 17. Mean
vector_mean <- function(a) {
  sum(a) / length(a)
}

# 18. Variance
vector_var <- function(a) {
  mean_val <- vector_mean(a)
  sum((a - mean_val)^2) / (length(a) - 1)
}

# 19. Standard deviation
vector_sd <- function(a) {
  sqrt(vector_var(a))
}

# 20. Reverse
vector_reverse <- function(a) {
  a[length(a):1]
}

# 21. Bubble sort
bubble_sort <- function(a) {
  n <- length(a)
  for (i in 1:(n-1)) {
    for (j in 1:(n-i)) {
      if (a[j] > a[j+1]) {
        temp <- a[j]
        a[j] <- a[j+1]
        a[j+1] <- temp
      }
    }
  }
  a
}

# 22. Index of max
which_max <- function(a) {
  which.max(a)
}

# 23. Index of min
which_min <- function(a) {
  which.min(a)
}

# 24. Cumulative sum
cumsum_vec <- function(a) {
  result <- numeric(length(a))
  result[1] <- a[1]
  for (i in 2:length(a)) {
    result[i] <- result[i-1] + a[i]
  }
  result
}

# 25. Cumulative product
cumprod_vec <- function(a) {
  result <- numeric(length(a))
  result[1] <- a[1]
  for (i in 2:length(a)) {
    result[i] <- result[i-1] * a[i]
  }
  result
}

# 26. Euclidean distance
euclidean_dist <- function(a, b) {
  sqrt(sum((a - b)^2))
}

# 27. Manhattan distance
manhattan_dist <- function(a, b) {
  sum(abs(a - b))
}

# 28. Check unit vector
is_unit_vector <- function(a, tol = 1e-10) {
  abs(magnitude(a) - 1) < tol
}

# 29. Median without median()
vector_median <- function(a) {
  sorted <- sort(a)
  n <- length(a)
  if (n %% 2 == 1) {
    sorted[(n+1)/2]
  } else {
    (sorted[n/2] + sorted[n/2 + 1]) / 2
  }
}

# 30. Check linear independence of 3 vectors
are_linearly_independent <- function(a, b, c) {
  if (length(a) != 3 || length(b) != 3 || length(c) != 3) {
    stop("Vectors must be 3D")
  }
  det(matrix(c(a, b, c), nrow = 3, byrow = TRUE)) != 0
}

Example usage:

a <- c(1, 2, 3)
b <- c(4, 5, 6)

dot_product(a, b)  # 32
magnitude(a)  # 3.741657
normalize(a)  # [0.267, 0.534, 0.801]
cross_product(a, b)  # [-3, 6, -3]
is_orthogonal(a, b)  # FALSE
angle_degrees(a, b)  # 12.933 degrees

Write a function to multiply two 2x2 matrices.

mul2by2 <- function(A,B){
  C <- matrix(NA, nrow=2, ncol=2)
  
  C[1,1] <- A[1,1]*B[1,1] + A[1,2]*B[2,1]
  C[1,2] <- A[1,1]*B[1,2] + A[1,2]*B[2,2]
  C[2,1] <- A[2,1]*B[1,1] + A[2,2]*B[2,1]
  C[2,2] <- A[2,1]*B[1,2] + A[2,2]*B[2,2]
  
  return(C)
}
A<-matrix(c(1,2,7,4),nrow=2)
B<-matrix(c(2,3,4,10),nrow=2)
mul2by2(A,B)
     [,1] [,2]
[1,]   23   74
[2,]   16   48

Write a function to multiply two matrices of compatible dimensions.

#2*3
#3*2

matrix_multiply <- function(A, B) {
  if (ncol(A) != nrow(B)) {
    stop("Incompatible dimensions: ncol(A) must equal nrow(B)")
  }
  result <- matrix(0, nrow = nrow(A), ncol = ncol(B))
  
  for (i in 1:nrow(A)) {
    for (j in 1:ncol(B)) {
      result[i, j] <- sum(A[i, ] * B[, j])
    }
  }
  
  result
}

ans=matrix_multiply(A,B)
print(ans)
     [,1] [,2]
[1,]   23   74
[2,]   16   48

Write a function to replace a row in a matrix with a vector.

row_replace <- function(A,r,vect){
  A[r,]<-vect
  return(A)
  }
ans<-row_replace(A,2,c(0,0))
print(ans)
     [,1] [,2]
[1,]    1    7
[2,]    0    0

Write a function to find the maximum element in a matrix.

max_ele<- function(A){
  maxi<-A[1,1]
  for (i in 1:nrow(A)){
    for (j in 1:ncol(A)){
      if (A[i,j]>maxi){
        maxi<-A[i,j]
      }
    }
  }
  return(maxi)
}
ans<-max_ele(A)
print(ans)
[1] 7

Write a function to compute row sums of a matrix.

A
     [,1] [,2]
[1,]    1    7
[2,]    2    4
row_sums<-function(A){
  result<-numeric(nrow(A))
  for (i in 1:nrow(A)){
    result[i]<-sum(A[i,])
  }
  return(result)
}

ans<-row_sums(A)
print(ans)
[1] 8 6

Write a function to check if a matrix is upper triangular.

uptrian <- function(A){
  for (i in 1:nrow(A)){
    for (j in 1:ncol(A)){
      if (i>j){
        A[i,j]!=0
        return(FALSE)
      }
    }
  }
  return(TRUE)
}
ans<-uptrian(A)
print(ans)
[1] FALSE
A<-c()
A<-append(A,2)
A<-append(A,4)

Write a function to check if a matrix is scalar (multiple of identity).

scaler_check <- function(A){
  for (i in 1:nrow(A)){
    for (j in 1:ncol(A)){
      if(i!=j & A[i,j]!=0){
        return(FALSE)
      } 
      else if(i==j & A[i,j]!=A[1,1]){
        return(FALSE)
      }
    }
  }
  return(TRUE)
  }

A<-matrix(c(1,2,7,4),nrow=2)
B<-matrix(c(1,0,0,1), nrow=2)
scaler_check(B)
[1] TRUE

Write a function to compute the row-wise maximum of a matrix.

rowmax<-function(A){
  maxs<-numeric(nrow(A))
  for (i in 1:nrow(A)){
    max=A[i,1]
    for (j in 1:ncol(A)){
      if (A[i,j]>max){
        max<-A[i,j]
      }
    }
    maxs[i]<-max 
  }
  return(maxs)
}
print(rowmax(A))
[1] 7 4
A
     [,1] [,2]
[1,]    1    7
[2,]    2    4

Write a function to compute cumulative sum of each row.

cumsumrow <- function(A){
  mat<-matrix(NA,nrow=nrow(A),ncol=ncol(A))
  for (i in 1:nrow(A)){
    cumsum<-numeric(ncol(A))
    cumsum[1]<-A[i,1]
    for (j in 2:ncol(A)){
      cumsum[j]<-A[i,j]+cumsum[j-1]
    }
    mat[i,]<-cumsum
  }
  return(mat)
}

print(cumsumrow(A))
     [,1] [,2]
[1,]    1    8
[2,]    2    6
A
     [,1] [,2]
[1,]    1    7
[2,]    2    4

25. Cumulative product

cumprod_vec <- function(a) { result <- numeric(length(a)) result[1] <- a[1] for (i in 2:length(a)) { result[i] <- result[i-1] * a[i] } result }



vecx<-c(10,20,188,348)
sum(vecx^2)
[1] 156948
A<-c(1,2,3,4)
B<-c(2,4,6,8)
all(A/B==A[1]/B[1])
[1] TRUE
# 21. Bubble sort
bubble_sort <- function(a) {
  n <- length(a)
  for (i in 1:(n-1)) {
    for (j in 1:(n-i)) {
      if (a[j] > a[j+1]) {
        temp <- a[j]
        a[j] <- a[j+1]
        a[j+1] <- temp
      }
    }
  }
  a
}
LS0tDQp0aXRsZTogIlIgTm90ZWJvb2siDQpvdXRwdXQ6IGh0bWxfbm90ZWJvb2sNCi0tLQ0KDQoNCnwgRnVuY3Rpb24gfCBVc2FnZSB8IEV4YW1wbGUgfA0KfC0tLS0tLS0tLS18LS0tLS0tLXwtLS0tLS0tLS18DQp8IGBtYXRyaXgoKWAgfCBDcmVhdGUgbWF0cml4IHwgYG1hdHJpeCgxOjksIG5yb3c9MylgIHwNCnwgYGNiaW5kKClgIHwgQ29tYmluZSBjb2x1bW5zIHwgYGNiaW5kKDE6MywgNDo2KWAgfA0KfCBgcmJpbmQoKWAgfCBDb21iaW5lIHJvd3MgfCBgcmJpbmQoMTozLCA0OjYpYCB8DQp8IGBkaW0oKWAgfCBHZXQgZGltZW5zaW9ucyB8IGBkaW0obWF0cml4KDE6NiwgMiwgMykpYCB8DQp8IGBucm93KClgIHwgTnVtYmVyIG9mIHJvd3MgfCBgbnJvdyhtYXRyaXgoMTo2LCAyLCAzKSlgIHwNCnwgYG5jb2woKWAgfCBOdW1iZXIgb2YgY29sdW1ucyB8IGBuY29sKG1hdHJpeCgxOjYsIDIsIDMpKWAgfA0KfCBgc3VtKClgIHwgU3VtIGVsZW1lbnRzIHwgYHN1bSgxOjUpYCB8DQp8IGBwcm9kKClgIHwgUHJvZHVjdCBlbGVtZW50cyB8IGBwcm9kKDE6NClgIHwNCnwgYG1lYW4oKWAgfCBBcml0aG1ldGljIG1lYW4gfCBgbWVhbihjKDEsMiwzLDQpKWAgfA0KfCBgdmFyKClgIHwgVmFyaWFuY2UgfCBgdmFyKGMoMSwyLDMsNCw1KSlgIHwNCnwgYHNkKClgIHwgU3RhbmRhcmQgZGV2aWF0aW9uIHwgYHNkKGMoMSwyLDMsNCw1KSlgIHwNCnwgYG1heCgpYCB8IE1heGltdW0gdmFsdWUgfCBgbWF4KGMoMywxLDQsMSw1KSlgIHwNCnwgYG1pbigpYCB8IE1pbmltdW0gdmFsdWUgfCBgbWluKGMoMywxLDQsMSw1KSlgIHwNCnwgYHNvcnQoKWAgfCBTb3J0IHZlY3RvciB8IGBzb3J0KGMoMywxLDQsMSw1KSlgIHwNCnwgYG9yZGVyKClgIHwgR2V0IHNvcnQgb3JkZXIgfCBgb3JkZXIoYygzLDEsNCkpYCB8DQp8IGByZXYoKWAgfCBSZXZlcnNlIHZlY3RvciB8IGByZXYoMTo1KWAgfA0KfCBgY3Vtc3VtKClgIHwgQ3VtdWxhdGl2ZSBzdW0gfCBgY3Vtc3VtKDE6NSlgIHwNCnwgYGN1bXByb2QoKWAgfCBDdW11bGF0aXZlIHByb2R1Y3QgfCBgY3VtcHJvZCgxOjUpYCB8DQp8IGBhYnMoKWAgfCBBYnNvbHV0ZSB2YWx1ZSB8IGBhYnMoYygtMSwyLC0zKSlgIHwNCnwgYHNxcnQoKWAgfCBTcXVhcmUgcm9vdCB8IGBzcXJ0KGMoNCw5LDE2KSlgIHwNCnwgYGFjb3MoKWAgfCBBcmMgY29zaW5lIHwgYGFjb3MoMC41KWAgfA0KfCBgcGlgIHwgz4AgY29uc3RhbnQgfCBgcGlgIHwNCnwgYGRldCgpYCB8IERldGVybWluYW50IHwgYGRldChtYXRyaXgoYygxLDIsMyw0KSwyKSlgIHwNCnwgYHNvbHZlKClgIHwgU29sdmUvaW52ZXJzZSB8IGBzb2x2ZShtYXRyaXgoYyg0LDcsMiw2KSwyKSlgIHwNCnwgYHQoKWAgfCBUcmFuc3Bvc2UgfCBgdChtYXRyaXgoMTo2LDIsMykpYCB8DQp8IGBkaWFnKClgIHwgRGlhZ29uYWwvZXh0cmFjdCB8IGBkaWFnKDMpYCB8DQp8IGBpZGVudGljYWwoKWAgfCBFeGFjdCBlcXVhbGl0eSB8IGBpZGVudGljYWwoMSwxLjApYCB8DQp8IGBzYW1wbGUoKWAgfCBSYW5kb20gc2FtcGxlIHwgYHNhbXBsZSgxOjEwLCAzKWAgfA0KfCBgc2VxKClgIHwgR2VuZXJhdGUgc2VxdWVuY2UgfCBgc2VxKDEsMTAsMilgIHwNCnwgYHJlcCgpYCB8IFJlcGxpY2F0ZSB2YWx1ZXMgfCBgcmVwKDUsMylgIHwNCnwgYGlmKClgIHwgQ29uZGl0aW9uYWwgfCBgaWYoeD4wKSBwcmludCgicG9zaXRpdmUiKWAgfA0KfCBgZWxzZSgpYCB8IEFsdGVybmF0aXZlIHwgYGVsc2UgcHJpbnQoIm5lZ2F0aXZlIilgIHwNCnwgYGZvcigpYCB8IExvb3AgfCBgZm9yKGkgaW4gMTo1KSBwcmludChpKWAgfA0KfCBgd2hpbGUoKWAgfCBXaGlsZSBsb29wIHwgYHdoaWxlKHg8MTApIHg8LXgrMWAgfA0KfCBgZnVuY3Rpb24oKWAgfCBEZWZpbmUgZnVuY3Rpb24gfCBgZiA8LSBmdW5jdGlvbih4KSB4XjJgIHwNCnwgYHJldHVybigpYCB8IFJldHVybiB2YWx1ZSB8IGByZXR1cm4oeCt5KWAgfA0KfCBgbGlzdCgpYCB8IENyZWF0ZSBsaXN0IHwgYGxpc3QoYT0xLCBiPSJ0ZXh0IilgIHwNCnwgYGMoKWAgfCBDb21iaW5lIHZhbHVlcyB8IGBjKDEsMiwzKWAgfA0KfCBgbnVtZXJpYygpYCB8IENyZWF0ZSBudW1lcmljIHZlY3RvciB8IGBudW1lcmljKDUpYCB8DQp8IGBjb2xTdW1zKClgIHwgQ29sdW1uIHN1bXMgfCBgY29sU3VtcyhtYXRyaXgoMTo5LDMpKWAgfA0KfCBgcm93U3VtcygpYCB8IFJvdyBzdW1zIHwgYHJvd1N1bXMobWF0cml4KDE6OSwzKSlgIHwNCnwgYGNvbE1lYW5zKClgIHwgQ29sdW1uIG1lYW5zIHwgYGNvbE1lYW5zKG1hdHJpeCgxOjksMykpYCB8DQp8IGByb3dNZWFucygpYCB8IFJvdyBtZWFucyB8IGByb3dNZWFucyhtYXRyaXgoMTo5LDMpKWAgfA0KfCBgJSolYCB8IE1hdHJpeCBtdWx0aXBsaWNhdGlvbiB8IGBtYXRyaXgoMTo0LDIpICUqJSBtYXRyaXgoNTo4LDIpYCB8DQp8IGBlaWdlbigpYCB8IEVpZ2VudmFsdWVzL3ZlY3RvcnMgfCBgZWlnZW4obWF0cml4KGMoNCwxLDEsMyksMikpYCB8DQoNCg0KDQoNCg0KSGVyZSBhcmUgYWxsIHRoZSB2ZWN0b3IgZnVuY3Rpb25zOg0KDQpgYGByDQojIDEuIERvdCBwcm9kdWN0DQpkb3RfcHJvZHVjdCA8LSBmdW5jdGlvbihhLCBiKSB7DQogIHN1bShhICogYikNCn0NCg0KIyAyLiBNYWduaXR1ZGUNCm1hZ25pdHVkZSA8LSBmdW5jdGlvbihhKSB7DQogIHNxcnQoc3VtKGFeMikpDQp9DQoNCiMgMy4gTm9ybWFsaXplDQpub3JtYWxpemUgPC0gZnVuY3Rpb24oYSkgew0KICBtYWcgPC0gbWFnbml0dWRlKGEpDQogIGlmIChtYWcgPT0gMCkgc3RvcCgiWmVybyB2ZWN0b3IgY2Fubm90IGJlIG5vcm1hbGl6ZWQiKQ0KICBhIC8gbWFnDQp9DQoNCiMgNC4gQ3Jvc3MgcHJvZHVjdCAoM0QpDQpjcm9zc19wcm9kdWN0IDwtIGZ1bmN0aW9uKGEsIGIpIHsNCiAgaWYgKGxlbmd0aChhKSAhPSAzIHx8IGxlbmd0aChiKSAhPSAzKSBzdG9wKCJWZWN0b3JzIG11c3QgYmUgM0QiKQ0KICBjKGFbMl0qYlszXSAtIGFbM10qYlsyXSwNCiAgICBhWzNdKmJbMV0gLSBhWzFdKmJbM10sDQogICAgYVsxXSpiWzJdIC0gYVsyXSpiWzFdKQ0KfQ0KDQojIDUuIENoZWNrIG9ydGhvZ29uYWwNCmlzX29ydGhvZ29uYWwgPC0gZnVuY3Rpb24oYSwgYiwgdG9sID0gMWUtMTApIHsNCiAgYWJzKGRvdF9wcm9kdWN0KGEsIGIpKSA8IHRvbA0KfQ0KDQojIDYuIENoZWNrIHBhcmFsbGVsDQppc19wYXJhbGxlbCA8LSBmdW5jdGlvbihhLCBiLCB0b2wgPSAxZS0xMCkgew0KICBtYWdfYSA8LSBtYWduaXR1ZGUoYSkNCiAgbWFnX2IgPC0gbWFnbml0dWRlKGIpDQogIGlmIChtYWdfYSA9PSAwIHx8IG1hZ19iID09IDApIHJldHVybihUUlVFKQ0KICBhYnMoZG90X3Byb2R1Y3QoYSwgYikgLyAobWFnX2EgKiBtYWdfYikpID4gMSAtIHRvbA0KfQ0KDQojIDcuIEFuZ2xlIGluIGRlZ3JlZXMNCmFuZ2xlX2RlZ3JlZXMgPC0gZnVuY3Rpb24oYSwgYikgew0KICBtYWdfYSA8LSBtYWduaXR1ZGUoYSkNCiAgbWFnX2IgPC0gbWFnbml0dWRlKGIpDQogIGlmIChtYWdfYSA9PSAwIHx8IG1hZ19iID09IDApIHN0b3AoIlplcm8gdmVjdG9yIGhhcyBubyBhbmdsZSIpDQogIGFjb3MoZG90X3Byb2R1Y3QoYSwgYikgLyAobWFnX2EgKiBtYWdfYikpICogMTgwIC8gcGkNCn0NCg0KIyA4LiBQcm9qZWN0aW9uIG9mIGEgb250byBiDQpwcm9qZWN0aW9uIDwtIGZ1bmN0aW9uKGEsIGIpIHsNCiAgKGRvdF9wcm9kdWN0KGEsIGIpIC8gZG90X3Byb2R1Y3QoYiwgYikpICogYg0KfQ0KDQojIDkuIFNjYWxhciBwcm9qZWN0aW9uDQpzY2FsYXJfcHJvamVjdGlvbiA8LSBmdW5jdGlvbihhLCBiKSB7DQogIGRvdF9wcm9kdWN0KGEsIGIpIC8gbWFnbml0dWRlKGIpDQp9DQoNCiMgMTAuIEFkZCB2ZWN0b3JzDQp2ZWN0b3JfYWRkIDwtIGZ1bmN0aW9uKGEsIGIpIHsNCiAgYSArIGINCn0NCg0KIyAxMS4gU3VidHJhY3QgdmVjdG9ycw0KdmVjdG9yX3N1YnRyYWN0IDwtIGZ1bmN0aW9uKGEsIGIpIHsNCiAgYSAtIGINCn0NCg0KIyAxMi4gTXVsdGlwbHkgYnkgc2NhbGFyDQp2ZWN0b3Jfc2NhbGUgPC0gZnVuY3Rpb24oYSwgaykgew0KICBhICogaw0KfQ0KDQojIDEzLiBTdW0gb2YgZWxlbWVudHMNCnZlY3Rvcl9zdW0gPC0gZnVuY3Rpb24oYSkgew0KICBzdW0oYSkNCn0NCg0KIyAxNC4gUHJvZHVjdCBvZiBlbGVtZW50cw0KdmVjdG9yX3Byb2QgPC0gZnVuY3Rpb24oYSkgew0KICBwcm9kKGEpDQp9DQoNCiMgMTUuIE1heGltdW0NCnZlY3Rvcl9tYXggPC0gZnVuY3Rpb24oYSkgew0KICBtYXgoYSkNCn0NCg0KIyAxNi4gTWluaW11bQ0KdmVjdG9yX21pbiA8LSBmdW5jdGlvbihhKSB7DQogIG1pbihhKQ0KfQ0KDQojIDE3LiBNZWFuDQp2ZWN0b3JfbWVhbiA8LSBmdW5jdGlvbihhKSB7DQogIHN1bShhKSAvIGxlbmd0aChhKQ0KfQ0KDQojIDE4LiBWYXJpYW5jZQ0KdmVjdG9yX3ZhciA8LSBmdW5jdGlvbihhKSB7DQogIG1lYW5fdmFsIDwtIHZlY3Rvcl9tZWFuKGEpDQogIHN1bSgoYSAtIG1lYW5fdmFsKV4yKSAvIChsZW5ndGgoYSkgLSAxKQ0KfQ0KDQojIDE5LiBTdGFuZGFyZCBkZXZpYXRpb24NCnZlY3Rvcl9zZCA8LSBmdW5jdGlvbihhKSB7DQogIHNxcnQodmVjdG9yX3ZhcihhKSkNCn0NCg0KIyAyMC4gUmV2ZXJzZQ0KdmVjdG9yX3JldmVyc2UgPC0gZnVuY3Rpb24oYSkgew0KICBhW2xlbmd0aChhKToxXQ0KfQ0KDQojIDIxLiBCdWJibGUgc29ydA0KYnViYmxlX3NvcnQgPC0gZnVuY3Rpb24oYSkgew0KICBuIDwtIGxlbmd0aChhKQ0KICBmb3IgKGkgaW4gMToobi0xKSkgew0KICAgIGZvciAoaiBpbiAxOihuLWkpKSB7DQogICAgICBpZiAoYVtqXSA+IGFbaisxXSkgew0KICAgICAgICB0ZW1wIDwtIGFbal0NCiAgICAgICAgYVtqXSA8LSBhW2orMV0NCiAgICAgICAgYVtqKzFdIDwtIHRlbXANCiAgICAgIH0NCiAgICB9DQogIH0NCiAgYQ0KfQ0KDQojIDIyLiBJbmRleCBvZiBtYXgNCndoaWNoX21heCA8LSBmdW5jdGlvbihhKSB7DQogIHdoaWNoLm1heChhKQ0KfQ0KDQojIDIzLiBJbmRleCBvZiBtaW4NCndoaWNoX21pbiA8LSBmdW5jdGlvbihhKSB7DQogIHdoaWNoLm1pbihhKQ0KfQ0KDQojIDI0LiBDdW11bGF0aXZlIHN1bQ0KY3Vtc3VtX3ZlYyA8LSBmdW5jdGlvbihhKSB7DQogIHJlc3VsdCA8LSBudW1lcmljKGxlbmd0aChhKSkNCiAgcmVzdWx0WzFdIDwtIGFbMV0NCiAgZm9yIChpIGluIDI6bGVuZ3RoKGEpKSB7DQogICAgcmVzdWx0W2ldIDwtIHJlc3VsdFtpLTFdICsgYVtpXQ0KICB9DQogIHJlc3VsdA0KfQ0KDQojIDI1LiBDdW11bGF0aXZlIHByb2R1Y3QNCmN1bXByb2RfdmVjIDwtIGZ1bmN0aW9uKGEpIHsNCiAgcmVzdWx0IDwtIG51bWVyaWMobGVuZ3RoKGEpKQ0KICByZXN1bHRbMV0gPC0gYVsxXQ0KICBmb3IgKGkgaW4gMjpsZW5ndGgoYSkpIHsNCiAgICByZXN1bHRbaV0gPC0gcmVzdWx0W2ktMV0gKiBhW2ldDQogIH0NCiAgcmVzdWx0DQp9DQoNCiMgMjYuIEV1Y2xpZGVhbiBkaXN0YW5jZQ0KZXVjbGlkZWFuX2Rpc3QgPC0gZnVuY3Rpb24oYSwgYikgew0KICBzcXJ0KHN1bSgoYSAtIGIpXjIpKQ0KfQ0KDQojIDI3LiBNYW5oYXR0YW4gZGlzdGFuY2UNCm1hbmhhdHRhbl9kaXN0IDwtIGZ1bmN0aW9uKGEsIGIpIHsNCiAgc3VtKGFicyhhIC0gYikpDQp9DQoNCiMgMjguIENoZWNrIHVuaXQgdmVjdG9yDQppc191bml0X3ZlY3RvciA8LSBmdW5jdGlvbihhLCB0b2wgPSAxZS0xMCkgew0KICBhYnMobWFnbml0dWRlKGEpIC0gMSkgPCB0b2wNCn0NCg0KIyAyOS4gTWVkaWFuIHdpdGhvdXQgbWVkaWFuKCkNCnZlY3Rvcl9tZWRpYW4gPC0gZnVuY3Rpb24oYSkgew0KICBzb3J0ZWQgPC0gc29ydChhKQ0KICBuIDwtIGxlbmd0aChhKQ0KICBpZiAobiAlJSAyID09IDEpIHsNCiAgICBzb3J0ZWRbKG4rMSkvMl0NCiAgfSBlbHNlIHsNCiAgICAoc29ydGVkW24vMl0gKyBzb3J0ZWRbbi8yICsgMV0pIC8gMg0KICB9DQp9DQoNCiMgMzAuIENoZWNrIGxpbmVhciBpbmRlcGVuZGVuY2Ugb2YgMyB2ZWN0b3JzDQphcmVfbGluZWFybHlfaW5kZXBlbmRlbnQgPC0gZnVuY3Rpb24oYSwgYiwgYykgew0KICBpZiAobGVuZ3RoKGEpICE9IDMgfHwgbGVuZ3RoKGIpICE9IDMgfHwgbGVuZ3RoKGMpICE9IDMpIHsNCiAgICBzdG9wKCJWZWN0b3JzIG11c3QgYmUgM0QiKQ0KICB9DQogIGRldChtYXRyaXgoYyhhLCBiLCBjKSwgbnJvdyA9IDMsIGJ5cm93ID0gVFJVRSkpICE9IDANCn0NCmBgYA0KDQoqKkV4YW1wbGUgdXNhZ2U6KioNCmBgYHINCmEgPC0gYygxLCAyLCAzKQ0KYiA8LSBjKDQsIDUsIDYpDQoNCmRvdF9wcm9kdWN0KGEsIGIpICAjIDMyDQptYWduaXR1ZGUoYSkgICMgMy43NDE2NTcNCm5vcm1hbGl6ZShhKSAgIyBbMC4yNjcsIDAuNTM0LCAwLjgwMV0NCmNyb3NzX3Byb2R1Y3QoYSwgYikgICMgWy0zLCA2LCAtM10NCmlzX29ydGhvZ29uYWwoYSwgYikgICMgRkFMU0UNCmFuZ2xlX2RlZ3JlZXMoYSwgYikgICMgMTIuOTMzIGRlZ3JlZXMNCmBgYA0KDQoNCg0KDQoNCiMjIyBXcml0ZSBhIGZ1bmN0aW9uIHRvIG11bHRpcGx5IHR3byAyeDIgbWF0cmljZXMuDQpgYGB7cn0NCm11bDJieTIgPC0gZnVuY3Rpb24oQSxCKXsNCiAgQyA8LSBtYXRyaXgoTkEsIG5yb3c9MiwgbmNvbD0yKQ0KICANCiAgQ1sxLDFdIDwtIEFbMSwxXSpCWzEsMV0gKyBBWzEsMl0qQlsyLDFdDQogIENbMSwyXSA8LSBBWzEsMV0qQlsxLDJdICsgQVsxLDJdKkJbMiwyXQ0KICBDWzIsMV0gPC0gQVsyLDFdKkJbMSwxXSArIEFbMiwyXSpCWzIsMV0NCiAgQ1syLDJdIDwtIEFbMiwxXSpCWzEsMl0gKyBBWzIsMl0qQlsyLDJdDQogIA0KICByZXR1cm4oQykNCn0NCkE8LW1hdHJpeChjKDEsMiw3LDQpLG5yb3c9MikNCkI8LW1hdHJpeChjKDIsMyw0LDEwKSxucm93PTIpDQptdWwyYnkyKEEsQikNCmBgYA0KIyMjIFdyaXRlIGEgZnVuY3Rpb24gdG8gbXVsdGlwbHkgdHdvIG1hdHJpY2VzIG9mIGNvbXBhdGlibGUgZGltZW5zaW9ucy4NCmBgYHtyfQ0KIzIqMw0KIzMqMg0KDQptYXRyaXhfbXVsdGlwbHkgPC0gZnVuY3Rpb24oQSwgQikgew0KICBpZiAobmNvbChBKSAhPSBucm93KEIpKSB7DQogICAgc3RvcCgiSW5jb21wYXRpYmxlIGRpbWVuc2lvbnM6IG5jb2woQSkgbXVzdCBlcXVhbCBucm93KEIpIikNCiAgfQ0KICByZXN1bHQgPC0gbWF0cml4KDAsIG5yb3cgPSBucm93KEEpLCBuY29sID0gbmNvbChCKSkNCiAgDQogIGZvciAoaSBpbiAxOm5yb3coQSkpIHsNCiAgICBmb3IgKGogaW4gMTpuY29sKEIpKSB7DQogICAgICByZXN1bHRbaSwgal0gPC0gc3VtKEFbaSwgXSAqIEJbLCBqXSkNCiAgICB9DQogIH0NCiAgDQogIHJlc3VsdA0KfQ0KDQphbnM9bWF0cml4X211bHRpcGx5KEEsQikNCnByaW50KGFucykNCg0KYGBgDQojIyMgV3JpdGUgYSBmdW5jdGlvbiB0byByZXBsYWNlIGEgcm93IGluIGEgbWF0cml4IHdpdGggYSB2ZWN0b3IuDQpgYGB7cn0NCnJvd19yZXBsYWNlIDwtIGZ1bmN0aW9uKEEscix2ZWN0KXsNCiAgQVtyLF08LXZlY3QNCiAgcmV0dXJuKEEpDQogIH0NCmFuczwtcm93X3JlcGxhY2UoQSwyLGMoMCwwKSkNCnByaW50KGFucykNCmBgYA0KIyMjIFdyaXRlIGEgZnVuY3Rpb24gdG8gZmluZCB0aGUgbWF4aW11bSBlbGVtZW50IGluIGEgbWF0cml4Lg0KYGBge3J9DQptYXhfZWxlPC0gZnVuY3Rpb24oQSl7DQogIG1heGk8LUFbMSwxXQ0KICBmb3IgKGkgaW4gMTpucm93KEEpKXsNCiAgICBmb3IgKGogaW4gMTpuY29sKEEpKXsNCiAgICAgIGlmIChBW2ksal0+bWF4aSl7DQogICAgICAgIG1heGk8LUFbaSxqXQ0KICAgICAgfQ0KICAgIH0NCiAgfQ0KICByZXR1cm4obWF4aSkNCn0NCmFuczwtbWF4X2VsZShBKQ0KcHJpbnQoYW5zKQ0KYGBgDQojIyMgV3JpdGUgYSBmdW5jdGlvbiB0byBjb21wdXRlIHJvdyBzdW1zIG9mIGEgbWF0cml4Lg0KYGBge3J9DQpBDQpyb3dfc3VtczwtZnVuY3Rpb24oQSl7DQogIHJlc3VsdDwtbnVtZXJpYyhucm93KEEpKQ0KICBmb3IgKGkgaW4gMTpucm93KEEpKXsNCiAgICByZXN1bHRbaV08LXN1bShBW2ksXSkNCiAgfQ0KICByZXR1cm4ocmVzdWx0KQ0KfQ0KDQphbnM8LXJvd19zdW1zKEEpDQpwcmludChhbnMpDQpgYGANCiMjIyBXcml0ZSBhIGZ1bmN0aW9uIHRvIGNoZWNrIGlmIGEgbWF0cml4IGlzIHVwcGVyIHRyaWFuZ3VsYXIuDQpgYGB7cn0NCnVwdHJpYW4gPC0gZnVuY3Rpb24oQSl7DQogIGZvciAoaSBpbiAxOm5yb3coQSkpew0KICAgIGZvciAoaiBpbiAxOm5jb2woQSkpew0KICAgICAgaWYgKGk+ail7DQogICAgICAgIEFbaSxqXSE9MA0KICAgICAgICByZXR1cm4oRkFMU0UpDQogICAgICB9DQogICAgfQ0KICB9DQogIHJldHVybihUUlVFKQ0KfQ0KYW5zPC11cHRyaWFuKEEpDQpwcmludChhbnMpDQpgYGANCmBgYHtyfQ0KQTwtYygpDQpBPC1hcHBlbmQoQSwyKQ0KQTwtYXBwZW5kKEEsNCkNCg0KYGBgDQoNCiMjIyBXcml0ZSBhIGZ1bmN0aW9uIHRvIGNoZWNrIGlmIGEgbWF0cml4IGlzIHNjYWxhciAobXVsdGlwbGUgb2YgaWRlbnRpdHkpLg0KYGBge3J9DQpzY2FsZXJfY2hlY2sgPC0gZnVuY3Rpb24oQSl7DQogIGZvciAoaSBpbiAxOm5yb3coQSkpew0KICAgIGZvciAoaiBpbiAxOm5jb2woQSkpew0KICAgICAgaWYoaSE9aiAmIEFbaSxqXSE9MCl7DQogICAgICAgIHJldHVybihGQUxTRSkNCiAgICAgIH0gDQogICAgICBlbHNlIGlmKGk9PWogJiBBW2ksal0hPUFbMSwxXSl7DQogICAgICAgIHJldHVybihGQUxTRSkNCiAgICAgIH0NCiAgICB9DQogIH0NCiAgcmV0dXJuKFRSVUUpDQogIH0NCg0KQTwtbWF0cml4KGMoMSwyLDcsNCksbnJvdz0yKQ0KQjwtbWF0cml4KGMoMSwwLDAsMSksIG5yb3c9MikNCnNjYWxlcl9jaGVjayhCKQ0KYGBgDQojIyMgV3JpdGUgYSBmdW5jdGlvbiB0byBjb21wdXRlIHRoZSByb3ctd2lzZSBtYXhpbXVtIG9mIGEgbWF0cml4Lg0KYGBge3J9DQpyb3dtYXg8LWZ1bmN0aW9uKEEpew0KICBtYXhzPC1udW1lcmljKG5yb3coQSkpDQogIGZvciAoaSBpbiAxOm5yb3coQSkpew0KICAgIG1heD1BW2ksMV0NCiAgICBmb3IgKGogaW4gMTpuY29sKEEpKXsNCiAgICAgIGlmIChBW2ksal0+bWF4KXsNCiAgICAgICAgbWF4PC1BW2ksal0NCiAgICAgIH0NCiAgICB9DQogICAgbWF4c1tpXTwtbWF4IA0KICB9DQogIHJldHVybihtYXhzKQ0KfQ0KcHJpbnQocm93bWF4KEEpKQ0KQQ0KYGBgDQojIyMgV3JpdGUgYSBmdW5jdGlvbiB0byBjb21wdXRlIGN1bXVsYXRpdmUgc3VtIG9mIGVhY2ggcm93Lg0KYGBge3J9DQpjdW1zdW1yb3cgPC0gZnVuY3Rpb24oQSl7DQogIG1hdDwtbWF0cml4KE5BLG5yb3c9bnJvdyhBKSxuY29sPW5jb2woQSkpDQogIGZvciAoaSBpbiAxOm5yb3coQSkpew0KICAgIGN1bXN1bTwtbnVtZXJpYyhuY29sKEEpKQ0KICAgIGN1bXN1bVsxXTwtQVtpLDFdDQogICAgZm9yIChqIGluIDI6bmNvbChBKSl7DQogICAgICBjdW1zdW1bal08LUFbaSxqXStjdW1zdW1bai0xXQ0KICAgIH0NCiAgICBtYXRbaSxdPC1jdW1zdW0NCiAgfQ0KICByZXR1cm4obWF0KQ0KfQ0KDQpwcmludChjdW1zdW1yb3coQSkpDQpBDQpgYGANCiMgMjUuIEN1bXVsYXRpdmUgcHJvZHVjdA0KY3VtcHJvZF92ZWMgPC0gZnVuY3Rpb24oYSkgew0KICByZXN1bHQgPC0gbnVtZXJpYyhsZW5ndGgoYSkpDQogIHJlc3VsdFsxXSA8LSBhWzFdDQogIGZvciAoaSBpbiAyOmxlbmd0aChhKSkgew0KICAgIHJlc3VsdFtpXSA8LSByZXN1bHRbaS0xXSAqIGFbaV0NCiAgfQ0KICByZXN1bHQNCn0NCg0KYGBge3J9DQoNCg0KdmVjeDwtYygxMCwyMCwxODgsMzQ4KQ0Kc3VtKHZlY3heMikNCg0KDQpgYGANCg0KDQoNCmBgYHtyfQ0KQTwtYygxLDIsMyw0KQ0KQjwtYygyLDQsNiw4KQ0KYWxsKEEvQj09QVsxXS9CWzFdKQ0KYGBgDQoNCmBgYHtyfQ0KIyAyMS4gQnViYmxlIHNvcnQNCmJ1YmJsZV9zb3J0IDwtIGZ1bmN0aW9uKGEpIHsNCiAgbiA8LSBsZW5ndGgoYSkNCiAgZm9yIChpIGluIDE6KG4tMSkpIHsNCiAgICBmb3IgKGogaW4gMToobi1pKSkgew0KICAgICAgaWYgKGFbal0gPiBhW2orMV0pIHsNCiAgICAgICAgdGVtcCA8LSBhW2pdDQogICAgICAgIGFbal0gPC0gYVtqKzFdDQogICAgICAgIGFbaisxXSA8LSB0ZW1wDQogICAgICB9DQogICAgfQ0KICB9DQogIGENCn0NCmBgYA0KDQoNCg0K