Initial Commit
This commit is contained in:
99
3.b. doomsday-fuel (failed)/Fractions.py
Normal file
99
3.b. doomsday-fuel (failed)/Fractions.py
Normal file
@@ -0,0 +1,99 @@
|
||||
class Fraction:
|
||||
def __init__(self, num, den):
|
||||
if num < 1 and num > 0:
|
||||
self.num = num*100
|
||||
self.den = 100
|
||||
else:
|
||||
self.num = num
|
||||
self.den = den
|
||||
self._simplify()
|
||||
|
||||
def __str__(self):
|
||||
return str(self.num) + "/" + str(self.den)
|
||||
|
||||
def __radd__(self, other):
|
||||
return self.__add__(other)
|
||||
|
||||
def __rsub__(self, other):
|
||||
return self.__sub__(other)
|
||||
|
||||
def __rmul__(self, other):
|
||||
return self.__mul__(other)
|
||||
|
||||
def __rdiv__(self, other):
|
||||
return self.__div__(other)
|
||||
|
||||
def __add__(self, other):
|
||||
if isinstance(other, self.__class__):
|
||||
if self.den == other.den:
|
||||
return Fraction(self.num + other.num, self.den)
|
||||
else:
|
||||
num = self.num * other.den + other.num * self.den
|
||||
den = self.den * other.den
|
||||
return Fraction(num, den)
|
||||
elif isinstance(other, int):
|
||||
return Fraction(self.num + (other * self.den), self.den)
|
||||
|
||||
def __sub__(self, other):
|
||||
if isinstance(other, self.__class__):
|
||||
if self.den == other.den:
|
||||
return Fraction(self.num - other.num, self.den)
|
||||
else:
|
||||
return Fraction(((self.num * other.den)-(other.num*self.den)),self.den * other.den )
|
||||
elif isinstance(other, int):
|
||||
if other == 0:
|
||||
return Fraction(-self.num, self.den)
|
||||
else:
|
||||
return Fraction(self.num - (other * self.den), self.den)
|
||||
|
||||
def __mul__(self, other):
|
||||
if isinstance(other, self.__class__):
|
||||
num = self.num * other.num
|
||||
den = self.den * other.den
|
||||
return Fraction(num, den)
|
||||
elif isinstance(other, int):
|
||||
return self * Fraction(other, 1)
|
||||
|
||||
def __div__(self, other):
|
||||
if isinstance(other, self.__class__):
|
||||
num = self.num * other.den
|
||||
den = self.den * other.num
|
||||
return Fraction(num, den)
|
||||
elif isinstance(other, int):
|
||||
return self / Fraction(other, 1)
|
||||
|
||||
def getNum(self):
|
||||
return self.num
|
||||
|
||||
def getDen(self):
|
||||
return self.den
|
||||
|
||||
def _gcf(self, first, second):
|
||||
while second:
|
||||
first, second = second, first % second
|
||||
return first
|
||||
|
||||
def _simplify(self):
|
||||
if self.den == 0:
|
||||
return
|
||||
gcf = self._gcf(self.num, self.den)
|
||||
self.num = self.num / gcf
|
||||
self.den = self.den / gcf
|
||||
|
||||
|
||||
print Fraction(1, 3) + Fraction(1, 6)
|
||||
print Fraction(1, 3) - Fraction(1, 6)
|
||||
print Fraction(1, 3) * Fraction(1, 6)
|
||||
print Fraction(1, 3) / Fraction(1, 6)
|
||||
|
||||
print Fraction(1,3) + 2
|
||||
print Fraction(1,3) - 2
|
||||
print Fraction(1,3) * 2
|
||||
print Fraction(1,3) / 2
|
||||
|
||||
print 2 + Fraction(1,3)
|
||||
print 2 - Fraction(1,3)
|
||||
print 2 * Fraction(1,3)
|
||||
print 2 / Fraction(1,3)
|
||||
|
||||
print Fraction(3, 12)
|
||||
199
3.b. doomsday-fuel (failed)/Matrix.py
Normal file
199
3.b. doomsday-fuel (failed)/Matrix.py
Normal file
@@ -0,0 +1,199 @@
|
||||
class Matrix:
|
||||
def __init__(self, m):
|
||||
self.matrix = [[0 for i in range(len(m[0]))] for j in range(len(m))]
|
||||
for i, row in enumerate(m):
|
||||
for j, col in enumerate(row):
|
||||
self.matrix[i][j] = m[i][j]
|
||||
|
||||
self.I = []
|
||||
self.R = []
|
||||
self.Q = []
|
||||
|
||||
def __str__(self):
|
||||
textArr = ""
|
||||
for row in self.matrix:
|
||||
for col in row:
|
||||
if type(col) == int:
|
||||
textArr += " " + str(col) + " "
|
||||
else:
|
||||
textArr += str(col) + " "
|
||||
textArr += "\n"
|
||||
return textArr
|
||||
|
||||
def __len__(self):
|
||||
return len(self.matrix)
|
||||
|
||||
def __getitem__(self, i):
|
||||
return self.matrix[i]
|
||||
|
||||
def __radd__(self, other):
|
||||
return self.__add__(other)
|
||||
|
||||
def __rsub__(self, other):
|
||||
return self.__sub__(other)
|
||||
|
||||
def __rmul__(self, other):
|
||||
return self.__mul__(other)
|
||||
|
||||
def __add__(self, other):
|
||||
result = [[0 for i in range(len(other.matrix[0]))] for j in range(len(other.matrix[0]))]
|
||||
if isinstance(other, self.__class__):
|
||||
for i in range(len(self.matrix)):
|
||||
for j in range(len(other.matrix[0])):
|
||||
result[i][j] = other.matrix[i][j] + other.matrix[i][j]
|
||||
elif isinstance(other, int):
|
||||
return "TODO: Matrix Add Function w/ Int"
|
||||
return result
|
||||
|
||||
def __sub__(self, other):
|
||||
if isinstance(other, self.__class__):
|
||||
if len(self.matrix) < len(other.matrix):
|
||||
short = self
|
||||
else:
|
||||
short = other
|
||||
result = [[0 for i in range(len(short.matrix[0]))] for j in range(len(short.matrix[0]))]
|
||||
for i in range(len(short.matrix)):
|
||||
for j in range(len(short.matrix[0])):
|
||||
result[i][j] = self.matrix[i][j] - other.matrix[i][j]
|
||||
elif isinstance(other, int):
|
||||
return "TODO: Matrix Sub Function w/ Int"
|
||||
return result
|
||||
|
||||
def __mul__(self, other):
|
||||
A = self
|
||||
B = other
|
||||
result = [[sum(a * b for a, b in zip(A_row, B_col))
|
||||
for B_col in zip(*B)]
|
||||
for A_row in A]
|
||||
return result
|
||||
|
||||
def getI(self):
|
||||
return self.I
|
||||
|
||||
def getR(self):
|
||||
return self.R
|
||||
|
||||
def getQ(self):
|
||||
return self.Q
|
||||
|
||||
def makeRegAndSTD(self):
|
||||
m = self.matrix
|
||||
shift = 0
|
||||
# Point Terminal states to themselves and move to top of 2d array
|
||||
for i, row in enumerate(m):
|
||||
void = True
|
||||
for col in row:
|
||||
if col != 0:
|
||||
void = False
|
||||
if void == True:
|
||||
row[i] = 1
|
||||
m.insert(shift, row)
|
||||
m.pop(i+1)
|
||||
shift += 1
|
||||
|
||||
# Shift all elements relative to the nmber of terminal states found
|
||||
for i, row in enumerate(m):
|
||||
m[i] = m[i][-shift:] + m[i][:-shift]
|
||||
|
||||
# Extract sections of the matrix for use in calculating F
|
||||
top = m[:shift]
|
||||
bottom = m[shift:]
|
||||
I = [[0 for i in range(len(m))] for j in range(shift)]
|
||||
R = [[0 for i in range(len(m))] for j in range(len(m)-shift)]
|
||||
Q = [[0 for i in range(len(m))] for j in range(len(m)-shift)]
|
||||
|
||||
for i, col in enumerate(top):
|
||||
I[i] = col[:shift]
|
||||
|
||||
for i, col in enumerate(bottom):
|
||||
R[i] = col[:shift]
|
||||
Q[i] = col[shift:]
|
||||
|
||||
self.I = Matrix(I)
|
||||
self.R = Matrix(R)
|
||||
self.Q = Matrix(Q)
|
||||
|
||||
|
||||
def transposeMatrix(m):
|
||||
return map(list,zip(*m))
|
||||
|
||||
def getMatrixMinor(m,i,j):
|
||||
return [row[:j] + row[j+1:] for row in (m[:i]+m[i+1:])]
|
||||
|
||||
def getMatrixDeternminant(m):
|
||||
#base case for 2x2 matrix
|
||||
if len(m) == 2:
|
||||
return m[0][0]*m[1][1]-m[0][1]*m[1][0]
|
||||
|
||||
determinant = 0
|
||||
for c in range(len(m)):
|
||||
determinant += ((-1)**c)*m[0][c]*getMatrixDeternminant(getMatrixMinor(m,0,c))
|
||||
return determinant
|
||||
|
||||
def getMatrixInverse(m):
|
||||
determinant = getMatrixDeternminant(m)
|
||||
#special case for 2x2 matrix:
|
||||
if len(m) == 2:
|
||||
return [[m[1][1]/determinant, -1*m[0][1]/determinant],
|
||||
[-1*m[1][0]/determinant, m[0][0]/determinant]]
|
||||
|
||||
#find matrix of cofactors
|
||||
cofactors = []
|
||||
for r in range(len(m)):
|
||||
cofactorRow = []
|
||||
for c in range(len(m)):
|
||||
minor = getMatrixMinor(m,r,c)
|
||||
cofactorRow.append(((-1)**(r+c)) * getMatrixDeternminant(minor))
|
||||
cofactors.append(cofactorRow)
|
||||
cofactors = transposeMatrix(cofactors)
|
||||
for r in range(len(cofactors)):
|
||||
for c in range(len(cofactors)):
|
||||
cofactors[r][c] = cofactors[r][c]/determinant
|
||||
return cofactors
|
||||
|
||||
def print2D(array):
|
||||
for arr in array:
|
||||
print arr
|
||||
return ""
|
||||
|
||||
# ---------------------------------------------------------
|
||||
|
||||
m1 = Matrix([
|
||||
[1,0],
|
||||
[0,1]])
|
||||
m2 = Matrix([
|
||||
[.8, .1],
|
||||
[.4, .4]])
|
||||
m3 = Matrix([
|
||||
[12, 7, 3],
|
||||
[4, 5, 6],
|
||||
[7, 8, 9]])
|
||||
m4 = Matrix([
|
||||
[5, 8, 1, 2],
|
||||
[6, 7, 3, 0],
|
||||
[4, 5, 9, 1]
|
||||
,[2, 3, 7,3]])
|
||||
m5 = Matrix([
|
||||
[0, 1, 0, 0, 0, 1],
|
||||
[4, 0, 0, 3, 2, 0],
|
||||
[0, 0, 0, 0, 0, 0],
|
||||
[0, 0, 0, 0, 0, 0],
|
||||
[0, 0, 0, 0, 0, 0],
|
||||
[0, 0, 0, 0, 0, 0]])
|
||||
m6 = Matrix([
|
||||
[.1,0,.8,.1],
|
||||
[.1,.1,.4,.4],
|
||||
[0,0,0,0],
|
||||
[0,0,0,0],])
|
||||
|
||||
# ----------------------------------------------------------
|
||||
|
||||
print "Subtract"
|
||||
print2D(m3 - m4)
|
||||
print ""
|
||||
print2D(m4 - m3)
|
||||
|
||||
# print "Subtract Whole Number"
|
||||
# print2D(1 - m3)
|
||||
|
||||
|
||||
121
3.b. doomsday-fuel (failed)/inverse.py
Normal file
121
3.b. doomsday-fuel (failed)/inverse.py
Normal file
@@ -0,0 +1,121 @@
|
||||
def getInverse(self):
|
||||
n = len(self.matrix)
|
||||
AM = copy_matrix(self.getMatrix)
|
||||
I = self.I
|
||||
IM = copy_matrix(self.I)
|
||||
|
||||
indices = list(range(n))
|
||||
for fd in range(n):
|
||||
fdScaler = 1.0 / AM[fd][fd]
|
||||
for j in range(n):
|
||||
AM[fd][j] *= fdScaler
|
||||
IM[fd][j] *= fdScaler
|
||||
for i in indices[0:fd] + indices[fd+1:]:
|
||||
crScaler = AM[i][fd]
|
||||
for j in range(n):
|
||||
AM[i][j] = AM[i][j] - crScaler * AM[fd][j]
|
||||
IM[i][j] = IM[i][j] - crScaler * IM[fd][j]
|
||||
return IM
|
||||
|
||||
# -----------------------------------------------
|
||||
|
||||
def eliminate(r1, r2, col, target=0):
|
||||
fac = (r2[col]-target) / r1[col]
|
||||
for i in range(len(r2)):
|
||||
r2[i] -= fac * r1[i]
|
||||
|
||||
def gauss(a):
|
||||
for i in range(len(a)):
|
||||
if a[i][i] == 0:
|
||||
for j in range(i+1, len(a)):
|
||||
if a[i][j] != 0:
|
||||
a[i], a[j] = a[j], a[i]
|
||||
break
|
||||
else:
|
||||
print("MATRIX NOT INVERTIBLE")
|
||||
return -1
|
||||
for j in range(i+1, len(a)):
|
||||
eliminate(a[i], a[j], i)
|
||||
for i in range(len(a)-1, -1, -1):
|
||||
for j in range(i-1, -1, -1):
|
||||
eliminate(a[i], a[j], i)
|
||||
for i in range(len(a)):
|
||||
eliminate(a[i], a[i], i, target=1)
|
||||
return a
|
||||
|
||||
def inverse(a):
|
||||
tmp = [[] for _ in a]
|
||||
for i,row in enumerate(a):
|
||||
assert len(row) == len(a)
|
||||
tmp[i].extend(row + [0]*i + [1] + [0]*(len(a)-i-1))
|
||||
gauss(tmp)
|
||||
ret = []
|
||||
for i in range(len(tmp)):
|
||||
ret.append(tmp[i][len(tmp[i])//2:])
|
||||
return ret
|
||||
|
||||
# -----------------------------------------------
|
||||
|
||||
def invert_matrix(AM, IM):
|
||||
for fd in range(len(AM)):
|
||||
fdScaler = 1.0 / AM[fd][fd]
|
||||
for j in range(len(AM)):
|
||||
AM[fd][j] *= fdScaler
|
||||
IM[fd][j] *= fdScaler
|
||||
for i in list(range(len(AM)))[0:fd] + list(range(len(AM)))[fd+1:]:
|
||||
crScaler = AM[i][fd]
|
||||
for j in range(len(AM)):
|
||||
AM[i][j] = AM[i][j] - crScaler * AM[fd][j]
|
||||
IM[i][j] = IM[i][j] - crScaler * IM[fd][j]
|
||||
return IM
|
||||
|
||||
def identity_matrix(n):
|
||||
I = zeros_matrix(n, n)
|
||||
for i in range(n):
|
||||
I[i][i] = 1.0
|
||||
|
||||
return I
|
||||
|
||||
def copy_matrix(m):
|
||||
print m
|
||||
rows = len(m)
|
||||
cols = len(m[0])
|
||||
mc = []
|
||||
while len(mc) < rows:
|
||||
mc.append([])
|
||||
while len(mc[-1]) < cols:
|
||||
mc[-1].append(0.0)
|
||||
|
||||
for i in range(rows):
|
||||
for j in range(rows):
|
||||
mc[i][j] = m[i][j]
|
||||
return mc
|
||||
|
||||
def zeros_matrix(rows, cols):
|
||||
"""
|
||||
Creates a matrix filled with zeros.
|
||||
:param rows: the number of rows the matrix should have
|
||||
:param cols: the number of columns the matrix should have
|
||||
:returns: list of lists that form the matrix.
|
||||
"""
|
||||
M = []
|
||||
while len(M) < rows:
|
||||
M.append([])
|
||||
while len(M[-1]) < cols:
|
||||
M[-1].append(0.0)
|
||||
|
||||
return M
|
||||
|
||||
|
||||
m = [
|
||||
[1,.5],
|
||||
[-0.44444,1]
|
||||
]
|
||||
|
||||
def print2D(array):
|
||||
for arr in array:
|
||||
print arr
|
||||
return ""
|
||||
|
||||
print2D(inverse(m))
|
||||
print2D(invert_matrix(m, identity_matrix(2)))
|
||||
213
3.b. doomsday-fuel (failed)/prod-test.py
Normal file
213
3.b. doomsday-fuel (failed)/prod-test.py
Normal file
@@ -0,0 +1,213 @@
|
||||
from fractions import Fraction
|
||||
import unittest
|
||||
|
||||
def mAdd(left, right):
|
||||
if len(left[0]) < len(right[0]):
|
||||
short = left
|
||||
else:
|
||||
short = right
|
||||
result = [[0 for i in range(len(short))] for j in range(len(short[0]))]
|
||||
for i in range(len(result)):
|
||||
for j in range(len(result[0])):
|
||||
result[i][j] = left[i][j] + right[i][j]
|
||||
return result
|
||||
|
||||
def mSub(left, right):
|
||||
if len(left[0]) < len(right[0]):
|
||||
short = left
|
||||
else:
|
||||
short = right
|
||||
result = [[0 for i in range(len(short))] for j in range(len(short[0]))]
|
||||
for i in range(len(result)):
|
||||
for j in range(len(result[0])):
|
||||
result[i][j] = left[i][j] - right[i][j]
|
||||
return result
|
||||
|
||||
def mMul(left, right):
|
||||
result = [[sum(a * b for a, b in zip(left_row, right_col))
|
||||
for right_col in zip(*right)]
|
||||
for left_row in left]
|
||||
return result
|
||||
|
||||
def makeIdentityM(s):
|
||||
result = [[0 for i in range(s)] for j in range(s)]
|
||||
for i, row in enumerate(result):
|
||||
for j, col in enumerate(row):
|
||||
if i == j:
|
||||
result[i][j] = 1
|
||||
return result
|
||||
|
||||
def makeRegAndSTD(m):
|
||||
shift = 0
|
||||
# Point Terminal states to themselves and move to top of 2d array
|
||||
for i, row in enumerate(m):
|
||||
void = True
|
||||
for col in row:
|
||||
if col != 0:
|
||||
void = False
|
||||
if void == True:
|
||||
row[i] = 1
|
||||
m.insert(shift, row)
|
||||
m.pop(i+1)
|
||||
shift += 1
|
||||
# Shift all elements relative to the nmber of terminal states found
|
||||
for i, row in enumerate(m):
|
||||
m[i] = m[i][-shift:] + m[i][:-shift]
|
||||
|
||||
# Extract sections of the matrix for use in calculating F
|
||||
top = m[:shift]
|
||||
bottom = m[shift:]
|
||||
I = [[0 for i in range(len(m))] for j in range(shift)]
|
||||
R = [[0 for i in range(len(m))] for j in range(len(m)-shift)]
|
||||
Q = [[0 for i in range(len(m))] for j in range(len(m)-shift)]
|
||||
for i, col in enumerate(top):
|
||||
I[i] = col[:shift]
|
||||
for i, col in enumerate(bottom):
|
||||
R[i] = col[:shift]
|
||||
Q[i] = col[shift:]
|
||||
return [m, I, R, Q]
|
||||
|
||||
def invertMatrix(AM, IM):
|
||||
for fd in range(len(AM)):
|
||||
fdScaler = 1.0 / AM[fd][fd]
|
||||
for j in range(len(AM)):
|
||||
AM[fd][j] *= fdScaler
|
||||
IM[fd][j] *= fdScaler
|
||||
for i in list(range(len(AM)))[0:fd] + list(range(len(AM)))[fd+1:]:
|
||||
crScaler = AM[i][fd]
|
||||
for j in range(len(AM)):
|
||||
AM[i][j] = AM[i][j] - crScaler * AM[fd][j]
|
||||
IM[i][j] = IM[i][j] - crScaler * IM[fd][j]
|
||||
return IM
|
||||
|
||||
def gcd(x, y):
|
||||
while y:
|
||||
x, y = y, x % y
|
||||
return x
|
||||
|
||||
def transformProbabilities(m):
|
||||
result = [0 for i in range(len(m))]
|
||||
numerators = [0 for i in range(len(m))]
|
||||
denomenators = [0 for i in range(len(m))]
|
||||
|
||||
for i, prob in enumerate(m):
|
||||
x = Fraction(prob).limit_denominator(1000)
|
||||
if str(x).find('/') != -1:
|
||||
y = str(x).split('/')
|
||||
numerators[i] = int(y[0])
|
||||
denomenators[i] = int(y[1])
|
||||
else:
|
||||
numerators[i] = int(x)
|
||||
|
||||
lcm = denomenators[0]
|
||||
# Protect by divide 0
|
||||
if lcm == 0:
|
||||
lcm = 1
|
||||
for i in denomenators[1:]:
|
||||
lcm = lcm*i/gcd(lcm, i)
|
||||
# Make sure lcm is not 0
|
||||
if lcm == 0:
|
||||
lcm = 1
|
||||
|
||||
for i, num in enumerate(numerators):
|
||||
if denomenators[i] != 0 and denomenators[i] != lcm:
|
||||
result[i] = num * (lcm / denomenators[i])
|
||||
else:
|
||||
result[i] = num
|
||||
|
||||
result.append(lcm)
|
||||
return result
|
||||
|
||||
def solution(m):
|
||||
# Check if our matrix is 1 x 1
|
||||
try:
|
||||
m[0][1]
|
||||
except IndexError:
|
||||
return [1,1]
|
||||
|
||||
# Check if S0 is Terminal State
|
||||
isTerminal = True
|
||||
for item in m[0][1:]:
|
||||
if item != 0:
|
||||
isTerminal = False
|
||||
if isTerminal == True:
|
||||
result = [1]
|
||||
for i, row in enumerate(m[1:]):
|
||||
void = True
|
||||
for col in row:
|
||||
if col != 0:
|
||||
void = False
|
||||
if void == True:
|
||||
result.append(0)
|
||||
result.append(1)
|
||||
return result
|
||||
|
||||
# Write fractions to matrix (for help with math)
|
||||
for i, row in enumerate(m):
|
||||
den = 0
|
||||
for j, col in enumerate(row):
|
||||
den += m[i][j]
|
||||
for j, col in enumerate(row):
|
||||
if m[i][j] != 0 and den != 0:
|
||||
m[i][j] = Fraction(m[i][j], den)
|
||||
|
||||
# Returns [m, I, R, Q]
|
||||
helpers = makeRegAndSTD(m)
|
||||
iq = mSub(helpers[1], helpers[3])
|
||||
F = invertMatrix(iq, makeIdentityM(len(iq)))
|
||||
FR = mMul(F, helpers[2])
|
||||
return transformProbabilities(FR[0])
|
||||
|
||||
|
||||
class TestDoomsdayFuel(unittest.TestCase):
|
||||
def test1(self):
|
||||
test_input = [
|
||||
[0, 2, 1, 0, 0],
|
||||
[0, 0, 0, 3, 4],
|
||||
[0, 0, 0, 0, 0],
|
||||
[0, 0, 0, 0, 0],
|
||||
[0, 0, 0, 0, 0]
|
||||
]
|
||||
self.assertEqual(solution(test_input),
|
||||
[7, 6, 8, 21])
|
||||
|
||||
def test2(self):
|
||||
test_input = [
|
||||
[0, 1, 0, 0, 0, 1],
|
||||
[4, 0, 0, 3, 2, 0],
|
||||
[0, 0, 0, 0, 0, 0],
|
||||
[0, 0, 0, 0, 0, 0],
|
||||
[0, 0, 0, 0, 0, 0],
|
||||
[0, 0, 0, 0, 0, 0]
|
||||
]
|
||||
self.assertEqual(solution(test_input), [0, 3, 2, 9, 14])
|
||||
|
||||
def test3(self):
|
||||
test_input = [
|
||||
[0, 1, 0, 0, 0, 1],
|
||||
[1, 0, 0, 1, 1, 0],
|
||||
[0, 0, 0, 0, 0, 0],
|
||||
[0, 0, 0, 0, 0, 0],
|
||||
[0, 0, 0, 0, 0, 0],
|
||||
[0, 0, 0, 0, 0, 0]
|
||||
]
|
||||
self.assertEqual(solution(test_input), [0, 1, 1, 3, 5])
|
||||
|
||||
def test4(self):
|
||||
test_input = [
|
||||
[1, 1, 0, 1],
|
||||
[1, 1, 0, 0],
|
||||
[0, 0, 0, 0],
|
||||
[0, 0, 0, 0],
|
||||
]
|
||||
self.assertEqual(solution(test_input), [0, 1, 1])
|
||||
|
||||
def test5(self):
|
||||
test_input = [
|
||||
[0, 1, 0],
|
||||
[1, 1, 1],
|
||||
[0, 0, 0]
|
||||
]
|
||||
self.assertEqual(solution(test_input), [1, 0, 1])
|
||||
|
||||
unittest.main()
|
||||
65
3.b. doomsday-fuel (failed)/readme.txt
Normal file
65
3.b. doomsday-fuel (failed)/readme.txt
Normal file
@@ -0,0 +1,65 @@
|
||||
Doomsday Fuel
|
||||
=============
|
||||
|
||||
Making fuel for the LAMBCHOP's reactor core is a tricky process because of the exotic matter involved. It starts as raw ore, then during processing, begins randomly changing between forms, eventually reaching a stable form. There may be multiple stable forms that a sample could ultimately reach, not all of which are useful as fuel.
|
||||
|
||||
Commander Lambda has tasked you to help the scientists increase fuel creation efficiency by predicting the end state of a given ore sample. You have carefully studied the different structures that the ore can take and which transitions it undergoes. It appears that, while random, the probability of each structure transforming is fixed. That is, each time the ore is in 1 state, it has the same probabilities of entering the next state (which might be the same state). You have recorded the observed transitions in a matrix. The others in the lab have hypothesized more exotic forms that the ore can become, but you haven't seen all of them.
|
||||
|
||||
Write a function solution(m) that takes an array of array of nonnegative ints representing how many times that state has gone to the next state and return an array of ints for each terminal state giving the exact probabilities of each terminal state, represented as the numerator for each state, then the denominator for all of them at the end and in simplest form. The matrix is at most 10 by 10. It is guaranteed that no matter which state the ore is in, there is a path from that state to a terminal state. That is, the processing will always eventually end in a stable state. The ore starts in state 0. The denominator will fit within a signed 32-bit integer during the calculation, as long as the fraction is simplified regularly.
|
||||
|
||||
For example, consider the matrix m:
|
||||
[
|
||||
[0,1,0,0,0,1], # s0, the initial state, goes to s1 and s5 with equal probability
|
||||
[4,0,0,3,2,0], # s1 can become s0, s3, or s4, but with different probabilities
|
||||
[0,0,0,0,0,0], # s2 is terminal, and unreachable (never observed in practice)
|
||||
[0,0,0,0,0,0], # s3 is terminal
|
||||
[0,0,0,0,0,0], # s4 is terminal
|
||||
[0,0,0,0,0,0], # s5 is terminal
|
||||
]
|
||||
So, we can consider different paths to terminal states, such as:
|
||||
s0 -> s1 -> s3
|
||||
s0 -> s1 -> s0 -> s1 -> s0 -> s1 -> s4
|
||||
s0 -> s1 -> s0 -> s5
|
||||
Tracing the probabilities of each, we find that
|
||||
s2 has probability 0
|
||||
s3 has probability 3/14
|
||||
s4 has probability 1/7
|
||||
s5 has probability 9/14
|
||||
So, putting that together, and making a common denominator, gives an answer in the form of
|
||||
[s2.numerator, s3.numerator, s4.numerator, s5.numerator, denominator] which is
|
||||
[0, 3, 2, 9, 14].
|
||||
|
||||
Languages
|
||||
=========
|
||||
|
||||
To provide a Java solution, edit Solution.java
|
||||
To provide a Python solution, edit solution.py
|
||||
|
||||
Test cases
|
||||
==========
|
||||
Your code should pass the following test cases.
|
||||
Note that it may also be run against hidden test cases not shown here.
|
||||
|
||||
-- Java cases --
|
||||
Input:
|
||||
Solution.solution({{0, 2, 1, 0, 0}, {0, 0, 0, 3, 4}, {0, 0, 0, 0, 0}, {0, 0, 0, 0,0}, {0, 0, 0, 0, 0}})
|
||||
Output:
|
||||
[7, 6, 8, 21]
|
||||
|
||||
Input:
|
||||
Solution.solution({{0, 1, 0, 0, 0, 1}, {4, 0, 0, 3, 2, 0}, {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0}})
|
||||
Output:
|
||||
[0, 3, 2, 9, 14]
|
||||
|
||||
-- Python cases --
|
||||
Input:
|
||||
solution.solution([[0, 2, 1, 0, 0], [0, 0, 0, 3, 4], [0, 0, 0, 0, 0], [0, 0, 0, 0,0], [0, 0, 0, 0, 0]])
|
||||
Output:
|
||||
[7, 6, 8, 21]
|
||||
|
||||
Input:
|
||||
solution.solution([[0, 1, 0, 0, 0, 1], [4, 0, 0, 3, 2, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0]])
|
||||
Output:
|
||||
[0, 3, 2, 9, 14]
|
||||
|
||||
Use verify [file] to test your solution and see how it does. When you are finished editing your code, use submit [file] to submit your answer. If your solution passes the test cases, it will be removed from your home folder.
|
||||
326
3.b. doomsday-fuel (failed)/solution-soClose.py
Normal file
326
3.b. doomsday-fuel (failed)/solution-soClose.py
Normal file
@@ -0,0 +1,326 @@
|
||||
class Fraction:
|
||||
def __init__(self, num, den):
|
||||
if num < 1 and num > 0:
|
||||
self.num = num*100
|
||||
self.den = 100
|
||||
else:
|
||||
self.num = num
|
||||
self.den = den
|
||||
self._simplify()
|
||||
|
||||
def __str__(self):
|
||||
return str(self.num) + "/" + str(self.den)
|
||||
|
||||
def __radd__(self, other):
|
||||
return self.__add__(other)
|
||||
|
||||
def __rsub__(self, other):
|
||||
return self.__sub__(other)
|
||||
|
||||
def __rmul__(self, other):
|
||||
return self.__mul__(other)
|
||||
|
||||
def __rdiv__(self, other):
|
||||
return self.__div__(other)
|
||||
|
||||
def __add__(self, other):
|
||||
if isinstance(other, self.__class__):
|
||||
if self.den == other.den:
|
||||
return Fraction(self.num + other.num, self.den)
|
||||
else:
|
||||
num = self.num * other.den + other.num * self.den
|
||||
den = self.den * other.den
|
||||
return Fraction(num, den)
|
||||
elif isinstance(other, int):
|
||||
return Fraction(self.num + (other * self.den), self.den)
|
||||
|
||||
def __sub__(self, other):
|
||||
if isinstance(other, self.__class__):
|
||||
if self.den == other.den:
|
||||
return Fraction(self.num - other.num, self.den)
|
||||
else:
|
||||
return Fraction(((self.num * other.den)-(other.num*self.den)),self.den * other.den)
|
||||
elif isinstance(other, int):
|
||||
if other == 0:
|
||||
return Fraction(-self.num, self.den)
|
||||
else:
|
||||
return Fraction(self.num - (other * self.den), self.den)
|
||||
elif isinstance(other, float):
|
||||
if other == 0:
|
||||
return Fraction(-self.num, self.den)
|
||||
else:
|
||||
return Fraction(self.num - (other * self.den), self.den)
|
||||
|
||||
def __mul__(self, other):
|
||||
if isinstance(other, self.__class__):
|
||||
num = self.num * other.num
|
||||
den = self.den * other.den
|
||||
return Fraction(num, den)
|
||||
elif isinstance(other, int):
|
||||
return self * Fraction(other, 1)
|
||||
elif isinstance(other, float):
|
||||
return self * Fraction(other, 1)
|
||||
|
||||
def __div__(self, other):
|
||||
if isinstance(other, self.__class__):
|
||||
num = self.num * other.den
|
||||
den = self.den * other.num
|
||||
return Fraction(num, den)
|
||||
elif isinstance(other, int):
|
||||
return self / Fraction(other, 1)
|
||||
|
||||
def getNum(self):
|
||||
return self.num
|
||||
|
||||
def getDen(self):
|
||||
return self.den
|
||||
|
||||
def _gcf(self, first, second):
|
||||
while second:
|
||||
first, second = second, first % second
|
||||
return first
|
||||
|
||||
def _simplify(self):
|
||||
if self.den == 0:
|
||||
return
|
||||
gcf = self._gcf(self.num, self.den)
|
||||
self.num = self.num / gcf
|
||||
self.den = self.den / gcf
|
||||
|
||||
class Matrix:
|
||||
def __init__(self, m):
|
||||
self.matrix = [[0 for i in range(len(m[0]))] for j in range(len(m))]
|
||||
for i, row in enumerate(m):
|
||||
for j, col in enumerate(row):
|
||||
self.matrix[i][j] = m[i][j]
|
||||
self.I = []
|
||||
self.R = []
|
||||
self.Q = []
|
||||
|
||||
def __str__(self):
|
||||
textArr = ""
|
||||
for row in self.matrix:
|
||||
for col in row:
|
||||
if type(col) == int:
|
||||
textArr += " " + str(col) + " "
|
||||
else:
|
||||
textArr += str(col) + " "
|
||||
textArr += "\n"
|
||||
return textArr
|
||||
|
||||
def __len__(self):
|
||||
return len(self.matrix)
|
||||
|
||||
def __getitem__(self, i):
|
||||
return self.matrix[i]
|
||||
|
||||
def __radd__(self, other):
|
||||
return self.__add__(other)
|
||||
|
||||
def __rsub__(self, other):
|
||||
return self.__sub__(other)
|
||||
|
||||
def __rmul__(self, other):
|
||||
return self.__mul__(other)
|
||||
|
||||
def __add__(self, other):
|
||||
result = [[0 for i in range(len(other.matrix[0]))] for j in range(len(other.matrix[0]))]
|
||||
if isinstance(other, self.__class__):
|
||||
for i in range(len(self.matrix)):
|
||||
for j in range(len(other.matrix[0])):
|
||||
result[i][j] = other.matrix[i][j] + other.matrix[i][j]
|
||||
elif isinstance(other, int):
|
||||
return "TODO: Matrix Add Function w/ Int"
|
||||
return result
|
||||
|
||||
def __sub__(self, other):
|
||||
if isinstance(other, self.__class__):
|
||||
if len(self.matrix) < len(other.matrix):
|
||||
short = self
|
||||
else:
|
||||
short = other
|
||||
result = [[0 for i in range(len(short.matrix[0]))] for j in range(len(short.matrix[0]))]
|
||||
for i in range(len(short.matrix)):
|
||||
for j in range(len(short.matrix[0])):
|
||||
result[i][j] = self.matrix[i][j] - other.matrix[i][j]
|
||||
elif isinstance(other, int):
|
||||
return "TODO: Matrix Sub Function w/ Int"
|
||||
return result
|
||||
|
||||
def __mul__(self, other):
|
||||
A = self
|
||||
B = other
|
||||
result = [[sum(a * b for a, b in zip(A_row, B_col))
|
||||
for B_col in zip(*B)]
|
||||
for A_row in A]
|
||||
return result
|
||||
|
||||
def getMatrix(self):
|
||||
return self.matrix
|
||||
|
||||
def getI(self):
|
||||
return self.I
|
||||
|
||||
def getR(self):
|
||||
return self.R
|
||||
|
||||
def getQ(self):
|
||||
return self.Q
|
||||
|
||||
def makeRegAndSTD(self):
|
||||
m = self.matrix
|
||||
shift = 0
|
||||
# Point Terminal states to themselves and move to top of 2d array
|
||||
for i, row in enumerate(m):
|
||||
void = True
|
||||
for col in row:
|
||||
if col != 0:
|
||||
void = False
|
||||
if void == True:
|
||||
row[i] = 1
|
||||
m.insert(shift, row)
|
||||
m.pop(i+1)
|
||||
shift += 1
|
||||
|
||||
# Shift all elements relative to the nmber of terminal states found
|
||||
for i, row in enumerate(m):
|
||||
m[i] = m[i][-shift:] + m[i][:-shift]
|
||||
|
||||
# Extract sections of the matrix for use in calculating F
|
||||
top = m[:shift]
|
||||
bottom = m[shift:]
|
||||
I = [[0 for i in range(len(m))] for j in range(shift)]
|
||||
R = [[0 for i in range(len(m))] for j in range(len(m)-shift)]
|
||||
Q = [[0 for i in range(len(m))] for j in range(len(m)-shift)]
|
||||
|
||||
for i, col in enumerate(top):
|
||||
I[i] = col[:shift]
|
||||
|
||||
for i, col in enumerate(bottom):
|
||||
R[i] = col[:shift]
|
||||
Q[i] = col[shift:]
|
||||
|
||||
self.I = Matrix(I)
|
||||
self.R = Matrix(R)
|
||||
self.Q = Matrix(Q)
|
||||
|
||||
def invertMatrix(AM, IM):
|
||||
for fd in range(len(AM)):
|
||||
fdScaler = 1.0 / AM[fd][fd]
|
||||
for j in range(len(AM)):
|
||||
AM[fd][j] *= fdScaler
|
||||
IM[fd][j] *= fdScaler
|
||||
for i in list(range(len(AM)))[0:fd] + list(range(len(AM)))[fd+1:]:
|
||||
crScaler = AM[i][fd]
|
||||
for j in range(len(AM)):
|
||||
AM[i][j] = AM[i][j] - crScaler * AM[fd][j]
|
||||
IM[i][j] = IM[i][j] - crScaler * IM[fd][j]
|
||||
return IM
|
||||
|
||||
def fetchProbabilities(m):
|
||||
nums = [0]*len(m[0])
|
||||
dens = [0]*len(m[0])
|
||||
results = [0]*len(m[0])
|
||||
for i, col in enumerate(m[0]):
|
||||
nums[i] = col.getNum()
|
||||
dens[i] = col.getDen()
|
||||
|
||||
# RISK: both denominators might need to get changed (not just go into the biggest)
|
||||
commonDen = dens[0]
|
||||
for col in dens[1:]:
|
||||
if col > commonDen:
|
||||
commonDen = col
|
||||
|
||||
for i, col in enumerate(nums):
|
||||
if dens[i] != commonDen:
|
||||
results[i] = nums[i] * (commonDen / dens[i])
|
||||
|
||||
results.append(commonDen)
|
||||
|
||||
return results
|
||||
|
||||
def solution(m):
|
||||
# Change probabilities to Fractions' for easy working
|
||||
for i, row in enumerate(m):
|
||||
den = 0
|
||||
for j, col in enumerate(row):
|
||||
den += m[i][j]
|
||||
for j, col in enumerate(row):
|
||||
if m[i][j] != 0 and den != 0:
|
||||
m[i][j] = Fraction(m[i][j], den)
|
||||
|
||||
m = Matrix(m)
|
||||
print "Input: \n" + m.__str__()
|
||||
|
||||
m.makeRegAndSTD()
|
||||
print "STD: \n" + m.__str__()
|
||||
|
||||
iq = Matrix(m.getI() - m.getQ())
|
||||
print "I-Q: \n" + iq.__str__()
|
||||
|
||||
F = invertMatrix(iq.getMatrix(), [[1,0],[0,1]])
|
||||
print "F: \n" + F.__str__()
|
||||
|
||||
FR = Matrix(F * m.getR())
|
||||
print "FR: \n" + FR.__str__()
|
||||
|
||||
return fetchProbabilities(FR)
|
||||
|
||||
|
||||
|
||||
|
||||
# set1 = [
|
||||
# [0, 2, 1, 0, 0],
|
||||
# [0, 0, 0, 3, 4],
|
||||
# [0, 0, 0, 0, 0],
|
||||
# [0, 0, 0, 0,0],
|
||||
# [0, 0, 0, 0, 0]
|
||||
# ]
|
||||
# set1Out = [7, 6, 8, 21]
|
||||
|
||||
|
||||
set2 = [
|
||||
[0, 1, 0, 0, 0, 1],
|
||||
[4, 0, 0, 3, 2, 0],
|
||||
[0, 0, 0, 0, 0, 0],
|
||||
[0, 0, 0, 0, 0, 0],
|
||||
[0, 0, 0, 0, 0, 0],
|
||||
[0, 0, 0, 0, 0, 0]
|
||||
]
|
||||
set2Out = [0, 3, 2, 9, 14]
|
||||
|
||||
# set3 = [
|
||||
# [1,0,0,0],
|
||||
# [0,1,0,0],
|
||||
# [0,0,1,0],
|
||||
# [0,0,0,1]
|
||||
# ]
|
||||
# set3Out = [1, 1]
|
||||
|
||||
# case1 = solution(set1)
|
||||
# if case1 == set1Out:
|
||||
# print "Test 1: Passed"
|
||||
# else:
|
||||
# print "Test 1: Failed"
|
||||
# print "Recieved " + str(case1)
|
||||
|
||||
|
||||
case2 = solution(set2)
|
||||
if case2 == set2Out:
|
||||
print "Test 2: Passed"
|
||||
else:
|
||||
print "Test 2: Failed"
|
||||
print "Recieved " + str(case2)
|
||||
|
||||
# case3 = solution(set3)
|
||||
# if case3 == set3Out:
|
||||
# print "Test 3: Passed"
|
||||
# else:
|
||||
# print "Test 3: Failed"
|
||||
# print "Recieved " + str(case3)
|
||||
|
||||
|
||||
def print2D(array):
|
||||
for arr in array:
|
||||
print arr
|
||||
return ""
|
||||
206
3.b. doomsday-fuel (failed)/solution.py
Normal file
206
3.b. doomsday-fuel (failed)/solution.py
Normal file
@@ -0,0 +1,206 @@
|
||||
from fractions import Fraction
|
||||
|
||||
def mAdd(left, right):
|
||||
if len(left[0]) < len(right[0]):
|
||||
short = left
|
||||
else:
|
||||
short = right
|
||||
result = [[0 for i in range(len(short))] for j in range(len(short[0]))]
|
||||
for i in range(len(result)):
|
||||
for j in range(len(result[0])):
|
||||
result[i][j] = left[i][j] + right[i][j]
|
||||
return result
|
||||
|
||||
def mSub(left, right):
|
||||
if len(left[0]) < len(right[0]):
|
||||
short = left
|
||||
else:
|
||||
short = right
|
||||
result = [[0 for i in range(len(short))] for j in range(len(short[0]))]
|
||||
for i in range(len(result)):
|
||||
for j in range(len(result[0])):
|
||||
result[i][j] = left[i][j] - right[i][j]
|
||||
return result
|
||||
|
||||
def mMul(left, right):
|
||||
result = [[sum(a * b for a, b in zip(left_row, right_col))
|
||||
for right_col in zip(*right)]
|
||||
for left_row in left]
|
||||
return result
|
||||
|
||||
def makeIdentityM(s):
|
||||
result = [[0 for i in range(s)] for j in range(s)]
|
||||
for i, row in enumerate(result):
|
||||
for j, col in enumerate(row):
|
||||
if i == j:
|
||||
result[i][j] = 1
|
||||
return result
|
||||
|
||||
def makeRegAndSTD(m):
|
||||
shiftU = 0
|
||||
# Point Terminal states to themselves and move to top of 2d array
|
||||
for i, row in enumerate(m):
|
||||
void = True
|
||||
for col in row:
|
||||
if col != 0:
|
||||
void = False
|
||||
if void == True:
|
||||
m[i][i] = 1
|
||||
m.insert(shiftU, row)
|
||||
m.pop(i+1)
|
||||
shiftU += 1
|
||||
print "Void -----"
|
||||
print2D(m)
|
||||
# Shift all elements relative to the nmber of terminal states found
|
||||
shiftR = shiftU
|
||||
if len(m[0]) % 2 != 0:
|
||||
shiftR = shiftU + 1
|
||||
print "ShiftR: " + str(shiftR)
|
||||
for i, row in enumerate(m):
|
||||
print "Shift -----"
|
||||
print2D(m)
|
||||
m[i] = m[i][-shiftR:] + m[i][:-shiftR]
|
||||
|
||||
# Extract sections of the matrix for use in calculating F
|
||||
top = m[:shiftU]
|
||||
bottom = m[shiftU:]
|
||||
|
||||
I = [[0 for i in range(len(top))] for j in range(len(top[0])-shiftR)]
|
||||
for i, row in enumerate(I):
|
||||
for j, col in enumerate(row):
|
||||
I[i][j] = m[i][j]
|
||||
print "NEW I"
|
||||
print2D(I)
|
||||
|
||||
R = [[0 for i in range(ShiftU)] for j in range(len(m)-shiftR)]
|
||||
Q = [[0 for i in range(ShiftU)] for j in range(len(shiftU)-shiftR)]
|
||||
|
||||
|
||||
for i, col in enumerate(bottom):
|
||||
R[i] = col[:shiftR]
|
||||
Q[i] = col[shiftR:]
|
||||
|
||||
return [m, I, R, Q]
|
||||
|
||||
def invertMatrix(AM, IM):
|
||||
for fd in range(len(AM)):
|
||||
fdScaler = 1.0 / AM[fd][fd]
|
||||
for j in range(len(AM)):
|
||||
AM[fd][j] *= fdScaler
|
||||
IM[fd][j] *= fdScaler
|
||||
for i in list(range(len(AM)))[0:fd] + list(range(len(AM)))[fd+1:]:
|
||||
crScaler = AM[i][fd]
|
||||
for j in range(len(AM)):
|
||||
AM[i][j] = AM[i][j] - crScaler * AM[fd][j]
|
||||
IM[i][j] = IM[i][j] - crScaler * IM[fd][j]
|
||||
return IM
|
||||
|
||||
def gcd(x, y):
|
||||
while y:
|
||||
x, y = y, x % y
|
||||
return x
|
||||
|
||||
def transformProbabilities(m):
|
||||
result = [0 for i in range(len(m))]
|
||||
numerators = [0 for i in range(len(m))]
|
||||
denomenators = [0 for i in range(len(m))]
|
||||
|
||||
for i, prob in enumerate(m):
|
||||
x = Fraction(prob).limit_denominator(1000)
|
||||
if str(x).find('/') != -1:
|
||||
y = str(x).split('/')
|
||||
numerators[i] = int(y[0])
|
||||
denomenators[i] = int(y[1])
|
||||
else:
|
||||
numerators[i] = int(x)
|
||||
|
||||
lcm = denomenators[0]
|
||||
# Protect by divide 0
|
||||
if lcm == 0:
|
||||
lcm = 1
|
||||
for i in denomenators[1:]:
|
||||
lcm = lcm*i/gcd(lcm, i)
|
||||
# Make sure lcm is not 0
|
||||
if lcm == 0:
|
||||
lcm = 1
|
||||
|
||||
for i, num in enumerate(numerators):
|
||||
if denomenators[i] != 0 and denomenators[i] != lcm:
|
||||
result[i] = num * (lcm / denomenators[i])
|
||||
else:
|
||||
result[i] = num
|
||||
|
||||
result.append(lcm)
|
||||
return result
|
||||
|
||||
def solution(m):
|
||||
# Check if our matrix is 1 x 1
|
||||
try:
|
||||
m[0][1]
|
||||
except IndexError:
|
||||
return [1,1]
|
||||
|
||||
# Check if S0 is Terminal State
|
||||
isTerminal = True
|
||||
for item in m[0][1:]:
|
||||
if item != 0:
|
||||
isTerminal = False
|
||||
if isTerminal == True:
|
||||
result = [1]
|
||||
for i, row in enumerate(m[1:]):
|
||||
void = True
|
||||
for col in row:
|
||||
if col != 0:
|
||||
void = False
|
||||
if void == True:
|
||||
result.append(0)
|
||||
result.append(1)
|
||||
return result
|
||||
|
||||
# Write fractions to matrix (for help with math)
|
||||
# for i, row in enumerate(m):
|
||||
# den = 0
|
||||
# for j, col in enumerate(row):
|
||||
# den += m[i][j]
|
||||
# for j, col in enumerate(row):
|
||||
# if m[i][j] != 0 and den != 0:
|
||||
# m[i][j] = Fraction(m[i][j], den)
|
||||
|
||||
# Returns [m, I, R, Q]
|
||||
helpers = makeRegAndSTD(m)
|
||||
iq = mSub(helpers[1], helpers[3])
|
||||
print "m"
|
||||
print2D(helpers[0])
|
||||
print "I"
|
||||
print2D(helpers[1])
|
||||
print "R"
|
||||
print2D(helpers[2])
|
||||
print "Q"
|
||||
print2D(helpers[3])
|
||||
print2D(iq)
|
||||
F = invertMatrix(iq, makeIdentityM(len(iq)))
|
||||
FR = mMul(F, helpers[2])
|
||||
return transformProbabilities(FR[0])
|
||||
|
||||
|
||||
|
||||
def print2D(array):
|
||||
for arr in array:
|
||||
print arr
|
||||
return ""
|
||||
|
||||
test_input = [
|
||||
[0, 0, 1],
|
||||
[0, 0, 0],
|
||||
[1, 1, 1]
|
||||
]
|
||||
print2D(test_input)
|
||||
print solution(test_input)
|
||||
|
||||
# test_input = [
|
||||
# [0,1,0],
|
||||
# [0,1,0],
|
||||
# [0,0,1]
|
||||
# ]
|
||||
# print2D(test_input)
|
||||
# print solution(test_input)
|
||||
Reference in New Issue
Block a user