#!/usr/bin/env python # coding: utf-8 #

cs1001.py , Tel Aviv University, Fall 2017-2018

# # # Recitation 4 # We talked about comlexity. First we had an intuitive intro through an exercise and then we formally defined the notion of $O$ and solved some theoretical exercises. # # #### Takeaways: # #
    #
  1. The time complexity bound implies how that the running time changes as a function of the input size.
  2. #
  3. Two solutions that have the same time complexity bound may differ in their running time (one can be more efficient than the other).
  4. #
  5. The Big O notation "hides" additive and multiplicative constants
  6. #
  7. Two solutions that have the same time complexity bound may differ in their running time (one can be more efficient than the other).
  8. #
  9. To analyze nested loops that are dependent, use a sum ($\sum$), with the boundaries of the external loop as the limits and the number of iterations for the inner loop in the sum itself.
  10. #
# ## Exercise: Given an natural number $p$, how many right triangles exist with integer sized sides whose perimeter is $p$? # ### Model: # # How many triplets (a,b,c) are there such that: # #
    #
  1. $a^2 + b^2 = c^2$
  2. #
  3. $a + b + c = p$
  4. #
  5. $a,b,c > 0$ are all integers
  6. #
# # ### In order to avoid counting a triplet twice or more, we require: # #
    #
  1. $0 < a < b < c$
  2. #
# # ### Note: # #
    #
  1. $a \neq b$ and $b \neq c$
  2. #
  3. The condition $b < c$ is redundant (since we require that $a,b,c > 0$ and $a^2 + b^2 = c^2$)
  4. #
# When computing code complexity, we #
    #
  1. define the entire content of the innermost loop as an “atomic operation” which takes constant time.
  2. #
  3. describe the complexity as a function of $p$ (i.e., use $p$ as the “problem size” or “input size”). # Note, however, that the formal definition of “problem size” for a numeric input is the size it takes to represent the input, i.e. $n = \log(p)$. # Working with $p$ here is easier and more intuitive.
  4. #
# # Trivial solution (v1): # In[3]: def number_of_integer_right_triangles_v1(p): cnt = 0 for a in range(1,p): for b in range(1,p): for c in range(1,p): if a + b + c == p and a < b and a*a + b*b == c*c: cnt += 1 return cnt # ### Analysis: # # $(p-1)^3$ iterations. # # The complexity is $O(p^3)$ (cubic complexity) # # Second version (v2): # Once we set $a,b$ and $p$, $c$ is already defined! # In[4]: def number_of_integer_right_triangles_v2(p): cnt = 0 for a in range(1,p): for b in range(1,p): c = p - a - b if a < b and a*a + b*b == c*c: cnt += 1 return cnt # ### Analysis: # # $(p-1)^2$ iterations. # # The complexity is $O(p^2)$ (squared complexity) # # Third version (v3): # We require $an_0$ # $|f(n)| \leq c\cdot|g(n)|$ # ### Time complexity hierarchy # # Let $n$ denote the size of the input. # The most common time complexities we encounter are : # # * Constant - $O(1)$ # * Logarithmic - $O(\log(n))$ # * Root/fractional - $O(n^{1/c})$ for $c>1$ # * Linear - $O(n)$ # * Loglinear - $O(n \log(n))$ # * Polynomial - $O(n^{c})$ for $c>1$ # * Exponential - $O(c^{n})$ for $c>1$ # # See also this list on [Wikipedia](http://en.wikipedia.org/wiki/Time_complexity#Table_of_common_time_complexities). # ## Prove or Disprove examples # See some examples [here](http://tau-cs1001-py.wdfiles.com/local--files/recitation-logs-2017a/complexity_prove_or_disprove.pdf)