title: Google Foobar Doomsday Fuel Challenge IndexError
body: <p>I was working on a small python challenge where the code was working fine on my laptop but showing index error on line 18 in the online console.
  Question is</p>
  
  <pre><code>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 answer(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 -&gt; s1 -&gt; s3
  s0 -&gt; s1 -&gt; s0 -&gt; s1 -&gt; s0 -&gt; s1 -&gt; s4
  s0 -&gt; s1 -&gt; s0 -&gt; 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 Python solution, edit solution.py
  To provide a Java solution, edit solution.java
  
  Test cases
  ==========
  
  Inputs:
      (int) m = [[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:
      (int list) [7, 6, 8, 21]
  
  Inputs:
      (int) m = [[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:
      (int list) [0, 3, 2, 9, 14]
  </code></pre>
  
  <p>And the code is</p>
  
  <pre><code>from itertools import product 
  from fractions import Fraction
  from functools import reduce
  #this is for matrix inversion
  def invert(matrix):
      n = len(matrix)
      inverse = [[Fraction(0) for col in range(n)] for row in range(n)]
      for i in range(n):
          inverse[i][i] = Fraction(1)
      for i in range(n):
          for j in range(n):
              if i != j:
                  if matrix[i][i] == 0:
                      return False
                  ratio = matrix[j][i] / matrix[i][i]
                  for k in range(n):
                      inverse[j][k] = inverse[j][k] - ratio * inverse[i][k]
                      matrix[j][k] = matrix[j][k] - ratio * matrix[i][k]
      for i in range(n):
          a = matrix[i][i]
          if a == 0:
              return False
          for j in range(n):
              inverse[i][j] = inverse[i][j] / a
      return inverse
  #finding sum of a row in matrix
  def sumRow(m, r):
      return sum(m[r])
  #subtracting two matrices
  def substract(matr_a, matr_b):
      output = []
      for i in range(len(matr_a)):
          tmp = []
          for valA, valB in zip(matr_a[i], matr_b[i]):
              tmp.append(valA - valB)
          output.append(tmp[:])
      return output[:]
  #matrix multiplication
  def matrixmult(matr_a, matr_b):
      #cols = len(matr_b[0])
      rows = len(matr_b)
      if rows is not 0:
          cols = len(matr_b[0])
      else:
          cols = 0
      resRows = range(len(matr_a))
      rMatrix = [[0] * cols for _ in resRows]
      for idx in resRows:
          for j, k in product(range(cols), range(rows)):
              rMatrix[idx][j] += matr_a[idx][k] * matr_b[k][j]
      if cols is not 0:
          return rMatrix
      else:
          return 0
      # return rMatrix
  #gcd to find lcm
  def gcd(a, b):
      while b:      
          a, b = b, a % b
      return a
  #lcm to find last value of the output
  def lcm(a,n):
      ans = a[0]
      for i in range(1,n):
          ans = (a[i]*ans)//gcd(a[i],ans)
      return ans
  #main function
  def answer(m):
      num = len(m)
      f=[]
      #finding zero rows
      for i in range(0,num):
          j=[]
          j.append(sumRow(m,i))
          j.append(i)
          f.append(j)
      k=0;
      #Fraction Conversion
      for i in range(0,num):
          for j in range(0,num):
              if f[i][0]!=0:
                  m[i][j]=Fraction(m[i][j],f[i][0])
      j=[]
      for i in range(0,len(f)):
          if f[i][0].numerator==0:
              j.append(i)
              del m[f[i][1]-k]
              k=k+1
      q=m
      k=[]
      t=0
      e=m
     # print(m)
      q=[]
      for i in range(0,len(m)):
          row=[]
          for r in range(0,len(m[0])):
              for t in range(0,len(j)):
                  if j[t] is r:
                      row.append(m[i][r])
          q.append(row)
     # print(q)
      t=0;
      w=0;
      e=[]
      for i in range(0,len(m)):
          row=[]
          flag=1
          for r in range(0,len(m[0])):
              for t in range(0,len(j)):
                  if j[t] is r:
                      flag=0
                      break
              if flag is 1:
                  row.append(m[i][r])
          e.append(row)
      #print(e)
      l=[]
      for i in range(0,len(e)):
          k=[]
          for b in range(0,len(e)):
              if i==b:
                  k.append(1)
              else:
                  k.append(0)
          l.append(k)
      #print(l)
      #print(e)
      l=substract(l,e)
      #print(l)
      l=invert(l)
      r = matrixmult(l,q)
      #print(r)
      if r == 0:
          return 0
      else:
          m =r[0]
      e=[]
      for i in range(0,len(m)):
          e.append(m[i].denominator)
      k=lcm(e,len(e))
      e=[]
      for i in range(0,len(m)):
          e.append((m[i].numerator*k)//m[i].denominator)
      e.append(k)
      #print(e)
      return e
  #answer (m = [[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]])
  #answer (m = [[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]])
  </code></pre>
  
  <p>time left was around 19h please tell me where I am doing mistake I'm absolutely new to python just started coding in python yesterday as dealing with fractions here is easy compared to java.</p>
  
  <p><strong>Note:</strong> Online console Won't accept numpy library so we have to hard code things like matrix inverse</p>
  
  <p>After testing various cases I found this error </p>
  
  <pre><code>Traceback (most recent call last):
    File "C:\Users\python.py", line 148, in &lt;module&gt;
      answer (m = [[0, 2, 1, 0, 0], [0, 0, 0, 3, 4], [0, 0, 0, 0, 0], [0, 4, 0, 0, 0], [0, 0, 0, 0, 0]])
    File "C:\Users\python.py", line 131, in answer
      l=invert(l)
    File "C:\Users\python.py", line 18, in invert
      matrix[j][k] = matrix[j][k] - ratio * matrix[i][k]
  IndexError: list index out of range
  </code></pre>