Linear Equation Solve
1) Write a function to solve a system of 2 linear equations in 2
variables (2x2 system).
cat("The equations are:\n a1x + b1y = c1\n a2x + b2y = c2\n\n")
The equations are:
a1x + b1y = c1
a2x + b2y = c2
a1 <- as.numeric(readline(prompt = "a1 = "))
4
b1 <- as.numeric(readline(prompt = "b1 = "))
3
c1 <- as.numeric(readline(prompt = "c1 = "))
1
a2 <- as.numeric(readline(prompt = "a2 = "))
5
b2 <- as.numeric(readline(prompt = "b2 = "))
7
c2 <- as.numeric(readline(prompt = "c2 = "))
8
values <- c(a1,b1,c1,a2,b2,c2)
eqn_2by2_solver <- function(a1, b1, c1, a2, b2, c2){
# Solving the system
denominator <- (a1*b2 - a2*b1)
if (denominator == 0) {
cat("No unique solution exists.\n")
} else {
y <- (a1*c2 - a2*c1) / denominator
x <- (c1 - b1*y) / a1
cat(sprintf("Solution:\nx = %.4f \ny = %.4f\n", x, y))
}
}
eqn_2by2_solver(a1,b1,c1,a2,b2,c2)
Solution:
x = -1.3077
y = 2.0769
do.call(eqn_2by2_solver, as.list(values))
Solution:
x = -1.3077
y = 2.0769
2) Write a function to solve a 3x3 system using Cramer’s rule.
cramer3by3 <- function(eqn1,eqn2,eqn3){
D <- rbind(
eqn1[1:3],
eqn2[1:3],
eqn3[1:3]
)
b <- c(eqn1[4],eqn2[4],eqn3[4])
vars <- c("x","y","z")
for (i in 1:3){
E <- D
E[,i] <- b
cat(vars[i],"=",det(E)/det(D),"\n")
}
}
eqn1 <- c(a1=2, b1=3, c1=-1, d1=8)
eqn2 <- c(a2=1, b2=-1, c2=4, d2=11)
eqn3 <- c(a3=3, b3=1, c3=2, d3=7)
cramer3by3(eqn1,eqn2,eqn3)
x = -3.428571
y = 6.714286
z = 5.285714
3) Write a function to find the determinant of a 2x2 matrix.
det2by2 <- function(A){
(A[1,1]*A[2,2])-(A[1,2]*A[2,1])
}
A <- matrix(c(2,9,4,5), nrow=2)
det2by2(A)
[1] -26
4) Write a function to find the determinant of a 3x3 matrix
det3by3 <- function(A){
result <- A[1,1]*(A[2,2]*A[3,3]-A[3,2]*A[2,3])-A[1,2]*(A[2,1]*A[3,3]-A[3,1]*A[2,3])+A[1,3]*(A[2,1]*A[3,2]-A[3,1]*A[2,2])
return(result)
}
A=matrix(c(1:8,11), nrow=3)
det3by3(A)
[1] -6
A
[,1] [,2] [,3]
[1,] 1 4 7
[2,] 2 5 8
[3,] 3 6 11
5) Write a function to find the inverse of a 2x2 matrix using the
determinant and adjugate.
inv2by2 <- function(A){
det_A <- (A[1,1]*A[2,2]-A[2,1]*A[1,2])
if (det_A!=0){
inv_A <- matrix(c(A[2,2], -A[1,2], -A[2,1], A[1,1]), nrow=2)/det_A
return(inv_A)
}
else{
return("Inverse not possible")
}
}
A <- matrix(c(1, 2, 2, 3), ncol = 2, byrow = TRUE)
inv2by2(A)
[,1] [,2]
[1,] -3 2
[2,] 2 -1
6) Write a function to solve a 2x2 system by finding the inverse
matrix and multiplying.
solver2by2 <- function(A, b){
sol <- inv2by2(A) %*% b
cat("x = ",sol[1,],"\ny = ", sol[2,])
}
A <- matrix(c(2,3,4,-1), byrow=TRUE, nrow=2)
b <- matrix(c(8,2), nrow=2)
b
[,1]
[1,] 8
[2,] 2
solver2by2(A,b)
x = 1.142857
y = 1.428571
7) Write a function to check if a 2x2 system has a unique solution,
no solution, or infinitely many solutions.
For the system
a₁x + b₁y = c₁
a₂x + b₂y = c₂
Compute
D = a₁b₂ − a₂b₁
• If D ≠ 0 → unique solution
• If D = 0 and a₁/a₂ = b₁/b₂ = c₁/c₂ → infinitely many
solutions
• If D = 0 and a₁/a₂ = b₁/b₂ ≠ c₁/c₂ → no solution
sol_type_2by2 <- function(A,b){
D <- A[1,1]*A[2,2]-A[2,1]*A[1,2]
if (D!=0){
return ("Unique")
}
else{
if (A[1,1]/A[2,1]==A[1,2]*A[2,2] & b[1,]/b[2,]==A[1,1]/A[2,1]){
return("Infinitely many")
} else{
return("No Solution")
}
}
}
A <- matrix(c(2,3,4,-1), byrow=TRUE, nrow=2)
b <- matrix(c(8,2), nrow=2)
sol_type_2by2(A,b)
[1] "Unique"
8) Check the nature of roots of a quadratic equation
quadric_root_nature <- function(a,b,c){
D <- b^2 - 4*a*c
if (D > 0) {
cat("Two distinct real roots")
} else if (D == 0) {
cat("Two equal real roots")
} else {
cat("No real roots")
}
}
a <- 1
b <- -3
c <- 2
quadric_root_nature(a,b,c)
Two distinct real roots
9) Write a function to check if a 3x3 system has a unique solution
(by checking determinant).
sol_type_3by3 <- function(A,b){
if (det(A)!=0){
cat("Unique Solution")
} else{
cat("Infinitely many or No solution")
}
}
sol_type_3by3(A,b)
Unique Solution
10) Write a function to find the trace of a square matrix (2x2,
3x3).
trace_finder <- function(A){
if (nrow(A)==ncol(A)){
t <- 0
for (i in 1:nrow(A)){
t <- t+A[i,i]
}
cat("Trace:",t)
}
else {
cat("Give Square Matrix")
}
}
A <- matrix(1:9, nrow = 3, ncol = 3)
trace_finder(A)
Trace: 15
matrix is singular when determinant = 0
LS0tDQp0aXRsZTogIlIgcXVlc3Rpb24gc29sdmUiDQpvdXRwdXQ6IGh0bWxfbm90ZWJvb2sNCi0tLQ0KIyBMaW5lYXIgRXF1YXRpb24gU29sdmUNCg0KIyMjIDEpIFdyaXRlIGEgZnVuY3Rpb24gdG8gc29sdmUgYSBzeXN0ZW0gb2YgMiBsaW5lYXIgZXF1YXRpb25zIGluIDIgdmFyaWFibGVzICgyeDIgc3lzdGVtKS4NCmBgYHtyfQ0KY2F0KCJUaGUgZXF1YXRpb25zIGFyZTpcbiBhMXggKyBiMXkgPSBjMVxuIGEyeCArIGIyeSA9IGMyXG5cbiIpDQoNCmExIDwtIGFzLm51bWVyaWMocmVhZGxpbmUocHJvbXB0ID0gImExID0gIikpDQpiMSA8LSBhcy5udW1lcmljKHJlYWRsaW5lKHByb21wdCA9ICJiMSA9ICIpKQ0KYzEgPC0gYXMubnVtZXJpYyhyZWFkbGluZShwcm9tcHQgPSAiYzEgPSAiKSkNCg0KYTIgPC0gYXMubnVtZXJpYyhyZWFkbGluZShwcm9tcHQgPSAiYTIgPSAiKSkNCmIyIDwtIGFzLm51bWVyaWMocmVhZGxpbmUocHJvbXB0ID0gImIyID0gIikpDQpjMiA8LSBhcy5udW1lcmljKHJlYWRsaW5lKHByb21wdCA9ICJjMiA9ICIpKQ0KDQoNCnZhbHVlcyA8LSBjKGExLGIxLGMxLGEyLGIyLGMyKQ0KZXFuXzJieTJfc29sdmVyIDwtIGZ1bmN0aW9uKGExLCBiMSwgYzEsIGEyLCBiMiwgYzIpew0KICAjIFNvbHZpbmcgdGhlIHN5c3RlbQ0KICBkZW5vbWluYXRvciA8LSAoYTEqYjIgLSBhMipiMSkNCiAgDQogIGlmIChkZW5vbWluYXRvciA9PSAwKSB7DQogICAgY2F0KCJObyB1bmlxdWUgc29sdXRpb24gZXhpc3RzLlxuIikNCiAgfSBlbHNlIHsNCiAgICB5IDwtIChhMSpjMiAtIGEyKmMxKSAvIGRlbm9taW5hdG9yDQogICAgeCA8LSAoYzEgLSBiMSp5KSAvIGExDQogICAgY2F0KHNwcmludGYoIlNvbHV0aW9uOlxueCA9ICUuNGYgXG55ID0gJS40ZlxuIiwgeCwgeSkpDQogIH0NCn0NCmVxbl8yYnkyX3NvbHZlcihhMSxiMSxjMSxhMixiMixjMikNCmRvLmNhbGwoZXFuXzJieTJfc29sdmVyLCBhcy5saXN0KHZhbHVlcykpDQoNCmBgYA0KIyMjIDIpIFdyaXRlIGEgZnVuY3Rpb24gdG8gc29sdmUgYSAzeDMgc3lzdGVtIHVzaW5nIENyYW1lcidzIHJ1bGUuDQpgYGB7cn0NCmNyYW1lcjNieTMgPC0gZnVuY3Rpb24oZXFuMSxlcW4yLGVxbjMpew0KICBEIDwtIHJiaW5kKA0KICAgIGVxbjFbMTozXSwNCiAgICBlcW4yWzE6M10sDQogICAgZXFuM1sxOjNdDQogICkNCiAgYiA8LSBjKGVxbjFbNF0sZXFuMls0XSxlcW4zWzRdKQ0KICB2YXJzIDwtIGMoIngiLCJ5IiwieiIpDQogIGZvciAoaSBpbiAxOjMpew0KICAgIEUgPC0gRA0KICAgIEVbLGldIDwtIGINCiAgICBjYXQodmFyc1tpXSwiPSIsZGV0KEUpL2RldChEKSwiXG4iKQ0KICB9DQogIA0KfQ0KDQplcW4xIDwtIGMoYTE9MiwgYjE9MywgYzE9LTEsIGQxPTgpDQplcW4yIDwtIGMoYTI9MSwgYjI9LTEsIGMyPTQsIGQyPTExKQ0KZXFuMyA8LSBjKGEzPTMsIGIzPTEsIGMzPTIsIGQzPTcpDQoNCmNyYW1lcjNieTMoZXFuMSxlcW4yLGVxbjMpDQoNCmBgYA0KIyMjIDMpIFdyaXRlIGEgZnVuY3Rpb24gdG8gZmluZCB0aGUgZGV0ZXJtaW5hbnQgb2YgYSAyeDIgbWF0cml4Lg0KYGBge3J9DQpkZXQyYnkyIDwtIGZ1bmN0aW9uKEEpew0KICAoQVsxLDFdKkFbMiwyXSktKEFbMSwyXSpBWzIsMV0pDQp9DQpBIDwtIG1hdHJpeChjKDIsOSw0LDUpLCBucm93PTIpDQpkZXQyYnkyKEEpDQpgYGANCiMjIyA0KSBXcml0ZSBhIGZ1bmN0aW9uIHRvIGZpbmQgdGhlIGRldGVybWluYW50IG9mIGEgM3gzIG1hdHJpeA0KYGBge3J9DQpkZXQzYnkzIDwtIGZ1bmN0aW9uKEEpew0KICByZXN1bHQgPC0gQVsxLDFdKihBWzIsMl0qQVszLDNdLUFbMywyXSpBWzIsM10pLUFbMSwyXSooQVsyLDFdKkFbMywzXS1BWzMsMV0qQVsyLDNdKStBWzEsM10qKEFbMiwxXSpBWzMsMl0tQVszLDFdKkFbMiwyXSkNCiAgcmV0dXJuKHJlc3VsdCkNCn0NCg0KQT1tYXRyaXgoYygxOjgsMTEpLCBucm93PTMpDQpkZXQzYnkzKEEpDQpBDQpgYGANCiMjIyA1KSBXcml0ZSBhIGZ1bmN0aW9uIHRvIGZpbmQgdGhlIGludmVyc2Ugb2YgYSAyeDIgbWF0cml4IHVzaW5nIHRoZSBkZXRlcm1pbmFudCBhbmQgYWRqdWdhdGUuDQpgYGB7cn0NCmludjJieTIgPC0gZnVuY3Rpb24oQSl7DQogIGRldF9BIDwtIChBWzEsMV0qQVsyLDJdLUFbMiwxXSpBWzEsMl0pDQogIGlmIChkZXRfQSE9MCl7DQogIGludl9BIDwtIG1hdHJpeChjKEFbMiwyXSwgLUFbMSwyXSwgLUFbMiwxXSwgQVsxLDFdKSwgbnJvdz0yKS9kZXRfQQ0KICByZXR1cm4oaW52X0EpDQogIH0NCiAgZWxzZXsNCiAgICByZXR1cm4oIkludmVyc2Ugbm90IHBvc3NpYmxlIikNCiAgfQ0KfQ0KDQpBIDwtIG1hdHJpeChjKDEsIDIsIDIsIDMpLCBuY29sID0gMiwgYnlyb3cgPSBUUlVFKQ0KaW52MmJ5MihBKQ0KYGBgDQojIyMgNikgV3JpdGUgYSBmdW5jdGlvbiB0byBzb2x2ZSBhIDJ4MiBzeXN0ZW0gYnkgZmluZGluZyB0aGUgaW52ZXJzZSBtYXRyaXggYW5kIG11bHRpcGx5aW5nLg0KYGBge3J9DQpzb2x2ZXIyYnkyIDwtIGZ1bmN0aW9uKEEsIGIpew0KICBzb2wgPC0gaW52MmJ5MihBKSAlKiUgYg0KICBjYXQoInggPSAiLHNvbFsxLF0sIlxueSA9ICIsIHNvbFsyLF0pDQp9DQoNCkEgPC0gbWF0cml4KGMoMiwzLDQsLTEpLCBieXJvdz1UUlVFLCBucm93PTIpDQoNCmIgPC0gbWF0cml4KGMoOCwyKSwgbnJvdz0yKQ0KYg0Kc29sdmVyMmJ5MihBLGIpDQpgYGANCiMjIyA3KSBXcml0ZSBhIGZ1bmN0aW9uIHRvIGNoZWNrIGlmIGEgMngyIHN5c3RlbSBoYXMgYSB1bmlxdWUgc29sdXRpb24sIG5vIHNvbHV0aW9uLCBvciBpbmZpbml0ZWx5IG1hbnkgc29sdXRpb25zLg0KDQpGb3IgdGhlIHN5c3RlbSAgDQph4oKBeCArIGLigoF5ID0gY+KCgSAgDQph4oKCeCArIGLigoJ5ID0gY+KCgiAgDQoNCkNvbXB1dGUgIA0KRCA9IGHigoFi4oKCIOKIkiBh4oKCYuKCgSAgDQoNCuKAoiBJZiBEIOKJoCAwIOKGkiAqKnVuaXF1ZSBzb2x1dGlvbioqICANCuKAoiBJZiBEID0gMCBhbmQgYeKCgS9h4oKCID0gYuKCgS9i4oKCID0gY+KCgS9j4oKCIOKGkiAqKmluZmluaXRlbHkgbWFueSBzb2x1dGlvbnMqKiAgDQrigKIgSWYgRCA9IDAgYW5kIGHigoEvYeKCgiA9IGLigoEvYuKCgiDiiaAgY+KCgS9j4oKCIOKGkiAqKm5vIHNvbHV0aW9uKioNCmBgYHtyfQ0Kc29sX3R5cGVfMmJ5MiA8LSBmdW5jdGlvbihBLGIpew0KICBEIDwtIEFbMSwxXSpBWzIsMl0tQVsyLDFdKkFbMSwyXQ0KICBpZiAoRCE9MCl7DQogICAgcmV0dXJuICgiVW5pcXVlIikNCiAgfQ0KICBlbHNlew0KICAgIGlmIChBWzEsMV0vQVsyLDFdPT1BWzEsMl0qQVsyLDJdICYgYlsxLF0vYlsyLF09PUFbMSwxXS9BWzIsMV0pew0KICAgICAgcmV0dXJuKCJJbmZpbml0ZWx5IG1hbnkiKQ0KICAgIH0gZWxzZXsNCiAgICAgIHJldHVybigiTm8gU29sdXRpb24iKQ0KICAgIH0NCiAgfQ0KfQ0KDQpBIDwtIG1hdHJpeChjKDIsMyw0LC0xKSwgYnlyb3c9VFJVRSwgbnJvdz0yKQ0KYiA8LSBtYXRyaXgoYyg4LDIpLCBucm93PTIpDQpzb2xfdHlwZV8yYnkyKEEsYikNCmBgYA0KIyMjIDgpIENoZWNrIHRoZSBuYXR1cmUgb2Ygcm9vdHMgb2YgYSBxdWFkcmF0aWMgZXF1YXRpb24NCmBgYHtyfQ0KcXVhZHJpY19yb290X25hdHVyZSA8LSBmdW5jdGlvbihhLGIsYyl7DQogIEQgPC0gYl4yIC0gNCphKmMgDQogICAgaWYgKEQgPiAwKSB7DQogICAgY2F0KCJUd28gZGlzdGluY3QgcmVhbCByb290cyIpDQogIH0gZWxzZSBpZiAoRCA9PSAwKSB7DQogICAgY2F0KCJUd28gZXF1YWwgcmVhbCByb290cyIpDQogIH0gZWxzZSB7DQogICAgY2F0KCJObyByZWFsIHJvb3RzIikNCiAgfQ0KfQ0KDQphIDwtIDENCmIgPC0gLTMNCmMgPC0gMg0KDQpxdWFkcmljX3Jvb3RfbmF0dXJlKGEsYixjKQ0KYGBgDQojIyMgOSkgV3JpdGUgYSBmdW5jdGlvbiB0byBjaGVjayBpZiBhIDN4MyBzeXN0ZW0gaGFzIGEgdW5pcXVlIHNvbHV0aW9uIChieSBjaGVja2luZyBkZXRlcm1pbmFudCkuDQpgYGB7cn0NCnNvbF90eXBlXzNieTMgPC0gZnVuY3Rpb24oQSxiKXsNCiAgaWYgKGRldChBKSE9MCl7DQogICAgY2F0KCJVbmlxdWUgU29sdXRpb24iKQ0KICB9IGVsc2V7DQogICAgY2F0KCJJbmZpbml0ZWx5IG1hbnkgb3IgTm8gc29sdXRpb24iKQ0KICB9DQp9DQpzb2xfdHlwZV8zYnkzKEEsYikNCmBgYA0KIyMjIDEwKSBXcml0ZSBhIGZ1bmN0aW9uIHRvIGZpbmQgdGhlIHRyYWNlIG9mIGEgc3F1YXJlIG1hdHJpeCAoMngyLCAzeDMpLg0KYGBge3J9DQp0cmFjZV9maW5kZXIgPC0gZnVuY3Rpb24oQSl7DQogIGlmIChucm93KEEpPT1uY29sKEEpKXsNCiAgICB0IDwtIDANCiAgICBmb3IgKGkgaW4gMTpucm93KEEpKXsNCiAgICAgIHQgPC0gdCtBW2ksaV0NCiAgICB9DQogICAgY2F0KCJUcmFjZToiLHQpDQogIH0NCiAgZWxzZSB7DQogICAgY2F0KCJHaXZlIFNxdWFyZSBNYXRyaXgiKQ0KICB9DQp9DQoNCkEgPC0gbWF0cml4KDE6OSwgbnJvdyA9IDMsIG5jb2wgPSAzKQ0KdHJhY2VfZmluZGVyKEEpDQpgYGANCm1hdHJpeCBpcyBzaW5ndWxhciB3aGVuIGRldGVybWluYW50ID0gMA0KDQoNCg0KLS0tDQoNCiMgTGluZWFyIEFsZ2VicmEgZm9yIENvZGVyczogRXNzZW50aWFsIENvbmNlcHRzIGFuZCBBbGdvcml0aG1zDQoNCiMjIDEuICoqUm93IEVjaGVsb24gRm9ybSAoUkVGKSoqDQoNCiMjIyBEZWZpbml0aW9uDQoNCkEgbWF0cml4IGlzIGluIFJvdyBFY2hlbG9uIEZvcm0gd2hlbjoNCg0KKiBBbGwgbm9uemVybyByb3dzIGFyZSBhYm92ZSByb3dzIG9mIGFsbCB6ZXJvcw0KKiBFYWNoIGxlYWRpbmcgY29lZmZpY2llbnQgKHBpdm90KSBvZiBhIHJvdyBpcyBpbiBhIGNvbHVtbiB0byB0aGUgcmlnaHQgb2YgdGhlIGxlYWRpbmcgY29lZmZpY2llbnQgb2YgdGhlIHJvdyBhYm92ZSBpdA0KKiBBbGwgZW50cmllcyBpbiBhIGNvbHVtbiBiZWxvdyBhIGxlYWRpbmcgY29lZmZpY2llbnQgYXJlIHplcm9zDQoNCiMjIyBFeGFtcGxlDQoNCmBgYA0KWyAxICAyICAzICA0IF0NClsgMCAgMSAgNSAgNiBdICAg4pyTIFJFRg0KWyAwICAwICAwICAxIF0NCmBgYA0KDQpgYGANClsgMCAgMSAgMiBdICAgICAg4pyXIE5vdCBSRUYgKHplcm8gcm93IGFib3ZlIG5vbi16ZXJvKQ0KWyAxICAwICAzIF0NCmBgYA0KDQojIyMgQWxnb3JpdGhtIHRvIGFjaGlldmUgUkVGDQoNCmBgYHINCnJvd19lY2hlbG9uX2Zvcm0gPC0gZnVuY3Rpb24obWF0KSB7DQogIHJvd3MgPC0gbnJvdyhtYXQpDQogIGNvbHMgPC0gbmNvbChtYXQpDQogIHBpdm90X3JvdyA8LSAxDQogIA0KICBmb3IgKGNvbCBpbiAxOmNvbHMpIHsNCiAgICAjIEZpbmQgcGl2b3QgaW4gY3VycmVudCBjb2x1bW4NCiAgICBwaXZvdCA8LSBmaW5kX3Bpdm90KG1hdCwgcGl2b3Rfcm93LCBjb2wpDQogICAgaWYgKGlzLm51bGwocGl2b3QpKSB7DQogICAgICBuZXh0DQogICAgfQ0KICAgIA0KICAgICMgU3dhcCBwaXZvdCByb3cgd2l0aCBjdXJyZW50IHJvdw0KICAgIG1hdCA8LSBzd2FwX3Jvd3MobWF0LCBwaXZvdCwgcGl2b3Rfcm93KQ0KICAgIA0KICAgICMgTWFrZSBhbGwgZW50cmllcyBiZWxvdyBwaXZvdCB6ZXJvDQogICAgZm9yIChyb3cgaW4gKHBpdm90X3JvdyArIDEpOnJvd3MpIHsNCiAgICAgIGZhY3RvciA8LSBtYXRbcm93LCBjb2xdIC8gbWF0W3Bpdm90X3JvdywgY29sXQ0KICAgICAgbWF0W3JvdywgXSA8LSBtYXRbcm93LCBdIC0gZmFjdG9yICogbWF0W3Bpdm90X3JvdywgXQ0KICAgIH0NCiAgICANCiAgICBwaXZvdF9yb3cgPC0gcGl2b3Rfcm93ICsgMQ0KICAgIGlmIChwaXZvdF9yb3cgPiByb3dzKSB7DQogICAgICBicmVhaw0KICAgIH0NCiAgfQ0KICByZXR1cm4obWF0KQ0KfQ0KYGBgDQoNCi0tLQ0KDQojIyAyLiAqKkZvcndhcmQgRWxpbWluYXRpb24qKg0KDQojIyMgUHVycG9zZQ0KDQpDb252ZXJ0IGEgc3lzdGVtIG9mIGxpbmVhciBlcXVhdGlvbnMgdG8gdXBwZXIgdHJpYW5ndWxhciBmb3JtLg0KDQojIyMgUHJvY2Vzcw0KDQoxLiBTdGFydCB3aXRoIGZpcnN0IGVxdWF0aW9uDQoyLiBVc2UgaXQgdG8gZWxpbWluYXRlIGZpcnN0IHZhcmlhYmxlIGZyb20gc3Vic2VxdWVudCBlcXVhdGlvbnMNCjMuIE1vdmUgdG8gbmV4dCBlcXVhdGlvbiwgcmVwZWF0DQoNCiMjIyBFeGFtcGxlIFN5c3RlbQ0KDQpgYGANCjJ4ICsgIHkgKyAgeiA9ICA4DQo0eCArIDN5ICsgMnogPSAxOA0KLTJ4ICsgIHkgKyAgeiA9ICAyDQpgYGANCg0KIyMjIEFmdGVyIEZvcndhcmQgRWxpbWluYXRpb24NCg0KYGBgDQoyeCArICB5ICsgIHogPSA4DQoweCArICB5ICsgMHogPSAyICAoU2Vjb25kIGVxdWF0aW9uIG1pbnVzIDLDl2ZpcnN0KQ0KMHggKyAyeSArIDJ6ID0gMTAgKFRoaXJkIGVxdWF0aW9uIHBsdXMgZmlyc3QpDQpgYGANCg0KLS0tDQoNCiMjIDMuICoqR2F1c3NpYW4gRWxpbWluYXRpb24qKg0KDQojIyMgQ29tcGxldGUgQWxnb3JpdGhtDQoNCjEuICoqRm9yd2FyZCBFbGltaW5hdGlvbioqOiBDb252ZXJ0IHRvIHVwcGVyIHRyaWFuZ3VsYXIgbWF0cml4DQoyLiAqKkJhY2sgU3Vic3RpdHV0aW9uKio6IFNvbHZlIGZyb20gYm90dG9tIHRvIHRvcA0KDQojIyMgSW1wbGVtZW50YXRpb24gU3RlcHMNCg0KYGBgcg0KZ2F1c3NpYW5fZWxpbWluYXRpb24gPC0gZnVuY3Rpb24oQSwgYikgew0KICBuIDwtIG5yb3coQSkNCiAgDQogICMgQXVnbWVudCBtYXRyaXggW0F8Yl0NCiAgQWIgPC0gY2JpbmQoQSwgYikNCiAgDQogICMgRm9yd2FyZCBlbGltaW5hdGlvbg0KICBmb3IgKGkgaW4gMTpuKSB7DQogICAgIyBQYXJ0aWFsIHBpdm90aW5nIGZvciBzdGFiaWxpdHkNCiAgICBtYXhfcm93IDwtIHdoaWNoLm1heChhYnMoQWJbaTpuLCBpXSkpICsgaSAtIDENCiAgICBpZiAoaSAhPSBtYXhfcm93KSB7DQogICAgICBBYltjKGksIG1heF9yb3cpLCBdIDwtIEFiW2MobWF4X3JvdywgaSksIF0NCiAgICB9DQogICAgDQogICAgIyBFbGltaW5hdGUgYmVsb3cgcGl2b3QNCiAgICBmb3IgKGogaW4gKGkgKyAxKTpuKSB7DQogICAgICBmYWN0b3IgPC0gQWJbaiwgaV0gLyBBYltpLCBpXQ0KICAgICAgQWJbaiwgXSA8LSBBYltqLCBdIC0gZmFjdG9yICogQWJbaSwgXQ0KICAgIH0NCiAgfQ0KICANCiAgIyBCYWNrIHN1YnN0aXR1dGlvbg0KICB4IDwtIG51bWVyaWMobikNCiAgZm9yIChpIGluIG46MSkgew0KICAgIHhbaV0gPC0gQWJbaSwgbiArIDFdIC8gQWJbaSwgaV0NCiAgICBmb3IgKGogaW4gKGkgLSAxKToxKSB7DQogICAgICBBYltqLCBuICsgMV0gPC0gQWJbaiwgbiArIDFdIC0gQWJbaiwgaV0gKiB4W2ldDQogICAgfQ0KICB9DQogIA0KICByZXR1cm4oeCkNCn0NCmBgYA0KDQotLS0NCg0KDQoNCi0tLQ0KDQojIyA0LiAqKlJhbmsgQ2hlY2sqKg0KDQojIyMgRGVmaW5pdGlvbg0KDQpUaGUgcmFuayBvZiBhIG1hdHJpeCBpcyB0aGUgbWF4aW11bSBudW1iZXIgb2YgbGluZWFybHkgaW5kZXBlbmRlbnQgcm93cyAob3IgY29sdW1ucykuDQoNCiMjIyBQcm9wZXJ0aWVzDQoNCiogcmFuayhBKSDiiaQgbWluKG0sIG4pIGZvciBtw5duIG1hdHJpeA0KKiBGdWxsIHJhbms6IHJhbmsgPSBtaW4obSwgbikNCiogU2luZ3VsYXIgbWF0cml4OiByYW5rIDwgbiBmb3IgbsOXbiBtYXRyaXgNCg0KIyMjIEFsZ29yaXRobSB0byBDb21wdXRlIFJhbmsNCg0KYGBgcg0KbWF0cml4X3JhbmsgPC0gZnVuY3Rpb24obWF0LCBhdWdtZW50ZWQgPSBGQUxTRSkgew0KICByZWZfbWF0IDwtIHJvd19lY2hlbG9uX2Zvcm0obWF0KQ0KICByYW5rIDwtIDANCiAgY29scyA8LSBpZmVsc2UoYXVnbWVudGVkLCBuY29sKHJlZl9tYXQpIC0gMSwgbmNvbChyZWZfbWF0KSkNCiAgDQogIGZvciAoaSBpbiAxOm5yb3cocmVmX21hdCkpIHsNCiAgICBpZiAoYW55KGFicyhyZWZfbWF0W2ksIDE6Y29sc10pID4gMWUtMTApKSB7DQogICAgICByYW5rIDwtIHJhbmsgKyAxDQogICAgfQ0KICB9DQogIHJldHVybihyYW5rKQ0KfQ0KYGBgDQoNCiMjIyBTaWduaWZpY2FuY2UNCg0KKiAqKlVuaXF1ZSBzb2x1dGlvbioqOiByYW5rKEEpID0gcmFuayhbQXxiXSkgPSBuDQoqICoqSW5maW5pdGUgc29sdXRpb25zKio6IHJhbmsoQSkgPSByYW5rKFtBfGJdKSA8IG4NCiogKipObyBzb2x1dGlvbioqOiByYW5rKEEpIDwgcmFuayhbQXxiXSkNCg0KLS0tDQoNCiMjIDUuICoqQXVnbWVudGVkIE1hdHJpeCoqDQoNCiMjIyBEZWZpbml0aW9uDQoNCkNvbWJpbmVzIGNvZWZmaWNpZW50IG1hdHJpeCBBIGFuZCBjb25zdGFudCB2ZWN0b3IgYiBpbnRvIFtBfGJdDQoNCiMjIyBQdXJwb3NlDQoNCkFsbG93cyBzaW11bHRhbmVvdXMgb3BlcmF0aW9ucyBvbiBib3RoIHNpZGVzIGR1cmluZyBlbGltaW5hdGlvbi4NCg0KIyMjIEV4YW1wbGUNCg0KU3lzdGVtOg0KDQpgYGANCjJ4ICsgM3kgPSA4DQo0eCAtIHkgPSAyDQpgYGANCg0KQXVnbWVudGVkIE1hdHJpeDoNCg0KYGBgDQpbIDIgIDMgfCA4IF0NClsgNCAtMSB8IDIgXQ0KYGBgDQoNCiMjIyBJbXBsZW1lbnRhdGlvbg0KDQpgYGByDQphdWdtZW50X21hdHJpeCA8LSBmdW5jdGlvbihBLCBiKSB7DQogIGNiaW5kKEEsIGIpDQp9DQpgYGANCg0KLS0tDQoNCiMjIDYuICoqU29sdXRpb24gVHlwZXMgZm9yIExpbmVhciBTeXN0ZW1zKioNCg0KIyMjIDYuMSAqKlVuaXF1ZSBTb2x1dGlvbioqDQoNCiogQ29uZGl0aW9uOiByYW5rKEEpID0gcmFuayhbQXxiXSkgPSBuDQoqIERldGVybWluYW50OiBkZXQoQSkg4omgIDANCiogSW50ZXJwcmV0YXRpb246IFN5c3RlbSBoYXMgZXhhY3RseSBvbmUgc29sdXRpb24NCiogRXhhbXBsZTogSW50ZXJzZWN0aW9uIG9mIHR3byBub24tcGFyYWxsZWwgbGluZXMNCg0KIyMjIDYuMiAqKkluY29uc2lzdGVudCBTeXN0ZW0gKE5vIFNvbHV0aW9uKSoqDQoNCiogQ29uZGl0aW9uOiByYW5rKEEpIDwgcmFuayhbQXxiXSkNCiogSW50ZXJwcmV0YXRpb246IEVxdWF0aW9ucyBjb250cmFkaWN0IGVhY2ggb3RoZXINCiogRXhhbXBsZTogUGFyYWxsZWwgbGluZXMgdGhhdCBkb24ndCBpbnRlcnNlY3QNCg0KYGBgDQp4ICsgeSA9IDMNCnggKyB5ID0gNSAgIyBDb250cmFkaWN0aW9uIQ0KYGBgDQoNCiMjIyA2LjMgKipJbmZpbml0ZSBTb2x1dGlvbnMqKg0KDQoqIENvbmRpdGlvbjogcmFuayhBKSA9IHJhbmsoW0F8Yl0pIDwgbg0KKiBGcmVlIHZhcmlhYmxlczogbiAtIHJhbmsoQSkNCiogSW50ZXJwcmV0YXRpb246IFN5c3RlbSBoYXMgaW5maW5pdGVseSBtYW55IHNvbHV0aW9ucw0KKiBFeGFtcGxlOiBUd28gZXF1YXRpb25zIHJlcHJlc2VudGluZyB0aGUgc2FtZSBsaW5lDQoNCi0tLQ0KDQojIyA3LiAqKkdhdXNzLUpvcmRhbiBFbGltaW5hdGlvbioqDQoNCiMjIyBEaWZmZXJlbmNlIGZyb20gR2F1c3NpYW4gRWxpbWluYXRpb24NCg0KKiBDcmVhdGVzIFJlZHVjZWQgUm93IEVjaGVsb24gRm9ybSAoUlJFRikNCiogQm90aCBmb3J3YXJkIGVsaW1pbmF0aW9uIEFORCBiYWNrd2FyZCBlbGltaW5hdGlvbg0KKiBQaXZvdCBlbGVtZW50cyBiZWNvbWUgMQ0KKiBBbGwgZWxlbWVudHMgYWJvdmUgYW5kIGJlbG93IHBpdm90cyBiZWNvbWUgMA0KDQojIyMgUlJFRiBDb25kaXRpb25zDQoNCjEuIEluIFJFRg0KMi4gQWxsIHBpdm90IGVsZW1lbnRzID0gMQ0KMy4gRWFjaCBwaXZvdCBpcyB0aGUgb25seSBub24temVybyBlbnRyeSBpbiBpdHMgY29sdW1uDQoNCiMjIyBBbGdvcml0aG0NCg0KYGBgcg0KZ2F1c3Nfam9yZGFuIDwtIGZ1bmN0aW9uKEEsIGIpIHsNCiAgbiA8LSBucm93KEEpDQogIEFiIDwtIGNiaW5kKEEsIGIpDQogIA0KICBmb3IgKGkgaW4gMTpuKSB7DQogICAgcGl2b3QgPC0gQWJbaSwgaV0NCiAgICBmb3IgKGogaW4gaToobiArIDEpKSB7DQogICAgICBBYltpLCBqXSA8LSBBYltpLCBqXSAvIHBpdm90DQogICAgfQ0KICAgIA0KICAgIGZvciAoayBpbiAxOm4pIHsNCiAgICAgIGlmIChrICE9IGkpIHsNCiAgICAgICAgZmFjdG9yIDwtIEFiW2ssIGldDQogICAgICAgIGZvciAoaiBpbiBpOihuICsgMSkpIHsNCiAgICAgICAgICBBYltrLCBqXSA8LSBBYltrLCBqXSAtIGZhY3RvciAqIEFiW2ksIGpdDQogICAgICAgIH0NCiAgICAgIH0NCiAgICB9DQogIH0NCiAgDQogIHJldHVybihBYlssIG4gKyAxXSkNCn0NCmBgYA0KDQotLS0NCg0KDQotLS0NCg0KIyDwn46vIEdhdXNzaWFuIFNvbHZlcjogQ29tcGxldGUgVmlzdWFsIFdvcmtmbG93DQoNCiFbR2F1c3NpYW4gV29ya2Zsb3ddKEM6L1VzZXJzL0RlbGwvRG93bmxvYWRzL2dhdXNzaWFuX3dvcmtmbG93LnBuZykNCg0KDQoNCiMjIPCfk4sgUHJvYmxlbSBPdmVydmlldw0KDQpTb2x2ZSAqKkF4ID0gYioqIHVzaW5nIEdhdXNzaWFuIGVsaW1pbmF0aW9uLCBkZXRlcm1pbmluZyBzb2x1dGlvbiB0eXBlIHdpdGhvdXQgYnVpbHQtaW4gZnVuY3Rpb25zLg0KDQpgYGByDQojIFN5c3RlbSB0byBzb2x2ZToNCiMgMnjigoEgKyB44oKCID0gNQ0KIyB44oKBICsgM3jigoIgPSA2DQoNCkEgPC0gbWF0cml4KGMoMiwgMSwgMSwgMyksIG5yb3cgPSAyLCBieXJvdyA9IFRSVUUpDQpiIDwtIGMoNSwgNikNCmBgYA0KDQotLS0NCg0KIyMg8J+Pl++4jyBTeXN0ZW0gUmVwcmVzZW50YXRpb24NCg0KYGBgDQpPcmlnaW5hbCBTeXN0ZW06DQrilIwgICAgICAgICAgICAgICDilJANCuKUgiAgMiAgIDEgIHwgIDUgIOKUgiAgRXF1YXRpb24gMTogMnjigoEgKyB44oKCID0gNQ0K4pSCICAxICAgMyAgfCAgNiAg4pSCICBFcXVhdGlvbiAyOiB44oKBICsgM3jigoIgPSA2DQrilJQgICAgICAgICAgICAgICDilJgNCmBgYA0KDQotLS0NCg0KDQotLS0NCg0KIyMg8J+nriBGaW5hbCBJbXBsZW1lbnRhdGlvbiB3aXRoIENvbW1lbnRzDQoNCmBgYHINCmdhdXNzaWFuX3NvbHZlciA8LSBmdW5jdGlvbihBLCBiKSB7DQogIG4gPC0gbnJvdyhBKQ0KICANCiAgIyBDcmVhdGUgYXVnbWVudGVkIG1hdHJpeCBtYW51YWxseSAod2l0aG91dCBjYmluZCkNCiAgYXVnIDwtIG1hdHJpeCgwLCBucm93ID0gbiwgbmNvbCA9IG4gKyAxKQ0KICBmb3IgKGkgaW4gMTpuKSB7DQogICAgZm9yIChqIGluIDE6bikgew0KICAgICAgYXVnW2ksIGpdIDwtIEFbaSwgal0NCiAgICB9DQogICAgYXVnW2ksIG4gKyAxXSA8LSBiW2ldDQogIH0NCiAgDQogICMgRm9yd2FyZCBlbGltaW5hdGlvbiAobm8gcGl2b3RpbmcgZm9yIHNpbXBsaWNpdHkpDQogIGZvciAoaSBpbiAxOm4pIHsNCiAgICBpZiAoYWJzKGF1Z1tpLCBpXSkgPCAxZS0xMCkgew0KICAgICAgbmV4dA0KICAgIH0NCiAgICANCiAgICBmb3IgKGogaW4gKGkgKyAxKTpuKSB7DQogICAgICBmYWN0b3IgPC0gYXVnW2osIGldIC8gYXVnW2ksIGldDQogICAgICBmb3IgKGsgaW4gaToobiArIDEpKSB7DQogICAgICAgIGF1Z1tqLCBrXSA8LSBhdWdbaiwga10gLSBmYWN0b3IgKiBhdWdbaSwga10NCiAgICAgIH0NCiAgICB9DQogIH0NCiAgDQogICMgQ2hlY2sgc29sdXRpb24gdHlwZQ0KICBoYXNfemVyb19yb3cgPC0gRkFMU0UNCiAgaGFzX2luY29uc2lzdGVudCA8LSBGQUxTRQ0KICANCiAgZm9yIChpIGluIDE6bikgew0KICAgIGFsbF96ZXJvIDwtIGFsbChhYnMoYXVnW2ksIDE6bl0pIDwgMWUtMTApDQogICAgaWYgKGFsbF96ZXJvKSB7DQogICAgICBoYXNfemVyb19yb3cgPC0gVFJVRQ0KICAgICAgaWYgKGFicyhhdWdbaSwgbiArIDFdKSA+IDFlLTEwKSB7DQogICAgICAgIGhhc19pbmNvbnNpc3RlbnQgPC0gVFJVRQ0KICAgICAgfQ0KICAgIH0NCiAgfQ0KICANCiAgaWYgKGhhc19pbmNvbnNpc3RlbnQpIHsNCiAgICByZXR1cm4obGlzdChzdGF0dXMgPSAiTm8gc29sdXRpb24iLCBzb2x1dGlvbiA9IE5VTEwpKQ0KICB9DQogIA0KICBpZiAoaGFzX3plcm9fcm93KSB7DQogICAgcmV0dXJuKGxpc3Qoc3RhdHVzID0gIkluZmluaXRlIHNvbHV0aW9ucyIsIHNvbHV0aW9uID0gTlVMTCkpDQogIH0NCiAgDQogICMgQmFjayBzdWJzdGl0dXRpb24NCiAgeCA8LSBudW1lcmljKG4pDQogIGZvciAoaSBpbiBuOjEpIHsNCiAgICBzdW1fdmFsIDwtIGF1Z1tpLCBuICsgMV0NCiAgICBmb3IgKGogaW4gKGkgKyAxKTpuKSB7DQogICAgICBzdW1fdmFsIDwtIHN1bV92YWwgLSBhdWdbaSwgal0gKiB4W2pdDQogICAgfQ0KICAgIHhbaV0gPC0gc3VtX3ZhbCAvIGF1Z1tpLCBpXQ0KICB9DQogIA0KICBuYW1lcyh4KSA8LSBwYXN0ZTAoIngiLCAxOm4pDQogIHJldHVybihsaXN0KHN0YXR1cyA9ICJVbmlxdWUgc29sdXRpb24iLCBzb2x1dGlvbiA9IHgpKQ0KfQ0KDQojIFRlc3QgdGhlIGZ1bmN0aW9uDQpBIDwtIG1hdHJpeChjKDIsIDEsIDEsIDMpLCBucm93ID0gMiwgYnlyb3cgPSBUUlVFKQ0KYiA8LSBjKDUsIDYpDQpyZXN1bHQgPC0gZ2F1c3NpYW5fc29sdmVyKEEsIGIpDQpyZXN1bHQkc3RhdHVzDQpyZXN1bHQkc29sdXRpb24NCmBgYA0KDQotLS0NCg0KIyMg8J+OryBLZXkgTGVhcm5pbmcgUG9pbnRzDQoNCjEuICoqQXVnbWVudGVkIE1hdHJpeCoqOiBDb21iaW5lIEEgYW5kIGIgZm9yIHNpbXVsdGFuZW91cyBvcGVyYXRpb25zDQoyLiAqKlBhcnRpYWwgUGl2b3RpbmcqKjogUHJldmVudHMgZGl2aXNpb24gYnkgemVybyBhbmQgaW1wcm92ZXMgbnVtZXJpY2FsIHN0YWJpbGl0eQ0KMy4gKipGb3J3YXJkIEVsaW1pbmF0aW9uKio6IENyZWF0ZXMgdXBwZXIgdHJpYW5ndWxhciBmb3JtDQo0LiAqKlNvbHV0aW9uIEFuYWx5c2lzKio6DQoNCiAgICogSW5jb25zaXN0ZW50IGlmIGBbMCAwIC4uLiAwIHwgY11gIHdpdGggYGMg4omgIDBgDQogICAqIEluZmluaXRlIGlmIHJhbmsoQSkgPCBuDQogICAqIFVuaXF1ZSBpZiByYW5rKEEpID0gbiBhbmQgY29uc2lzdGVudA0KNS4gKipCYWNrIFN1YnN0aXR1dGlvbioqOiBTb2x2ZSBmcm9tIGJvdHRvbSB0byB0b3ANCg0KLS0tDQoNCmBgYHtyfQ0KDQpgYGANCg0KDQoNCg==