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