Lesson 17/18 Hacks
Notes 3.17
Problem: a description of a task that can be solved through an algorithm.
- Instance: includes a specific input, ex: sorting problem
Decision problem: binary problem with answer (yes or no)
Optimization problem: finding the best solution amongst many
Efficiency of an algorithm is determined through formal or mathematical reasoning.
Reasonable amount of time: Linear or square algorithm Unreasonable amount of time: Exponential or factorial algorithm
Types of Run Times (when input increases, does the number of steps it takes to solve the problem increase)</p>
Constant Time: fixed number of steps no matter input Linear Time: steps increase proportional to input Quadratic Time: steps increase proportional to input squared Exponential Time: steps increase faster than polynomial function of input Notes 3.18 Computers can't solve all problems. Even problems they can solve, may not be able to be done in a short enough amount of time. Undecidable problem: Problems where an algorithm cannot be built to give an accurate yes or no answer Decidable problem: Problems for which an algorthm could be written to provide a correct answer Hack 1
A decidable problem is one which can be solved with an algorithm and a correct answer with be outputted (example: average of 10 integers). An undecideable problem is one which cannot be correctly solved with an algorithm (example from research: whether a CFG generates all the strings or not). Hack 2
C, because the algorithm includes a square (classified as 3 steps and reasonable) Hack 3 I had trouble shortening the code myself, so I compares the two and analyzed why the section of code was shortened the way it was. Explanation:
Because counter, peak, and peal_index all equal 0, it is uneccesary to seperate the let statements. Instead the series of else/if statements based on the arrays relative size to zero, can be done as such (instead of using different variables that are not needed). Hack 4 With help of W3 Schools, I was able to find a much simpler way of sorting the values in a list. This sort() method will also work to sort values in a list alphabetically. Hack 5 Use of permutations by using a prexisting algorithm is most efficient, and shortens the code significantly. There is also an option of using combinations in python, which may be useful in certain statistical contexts. Reflection I found this lesson interesting and relavant, as it shows different ways to identify if a computer will be able to efficiently solve a problem. When a computer cannot solve a problem in a timely manner using the resources provided by code, it is important to find alternate ways to help it complete the same function (as demonstrated in hacks).function peak_finder(array){
let counter = 0
let peak = 0
let peak_index =0
while (counter <= array.length){
console.log(counter)
if (counter === 0){
if (a[0]>=a[1]){
peak = a[0]
peak_index = counter
counter = array.length
return `The ${counter-1} indexed number, ${peak} is a peak`
}else{
counter+=1
}
}else if(counter === array.length-1){
if (a[array.length-1] >= a[array.length-2]){
peak = a[array.length-1]
peak_index = counter
counter = array.length
return `The ${counter-1} indexed number, ${peak} is a peak`
}
}else{
if (a[counter]> a[counter+1] && a[counter]> a[counter-1]){
peak = a[counter]
peak_index = counter
counter = array.length
return `The ${counter-1} indexed number, ${peak} is a peak`
}else{
counter += 1
}
}
}
}
function peak_finder2(array){
if (array.length) === 0{
return `Array cannot be empty`
}else if (array.length === 1){
return array[0]
}else{
let mid_index = Math.floor(array.length*0.5)
if (array[mid_index +1]>array[mid_index]){
return peak_finding(array.slice(mid_index + 1 ))
}else if (array[mid_index -1]>array[mid_index]){
new=array.reverse().slice(mid_index+1).reverse()
return peak_finding(new)
}else{
return array[mid_index]
}
}
}
def merge_sort(data):
if len(data) <= 1:
return
mid = len(data) // 2
left_data = data[:mid]
right_data = data[mid:]
merge_sort(left_data)
merge_sort(right_data)
left_index = 0
right_index = 0
data_index = 0
while left_index < len(left_data) and right_index < len(right_data):
if left_data[left_index] < right_data[right_index]:
data[data_index] = left_data[left_index]
left_index += 1
else:
data[data_index] = right_data[right_index]
right_index += 1
data_index += 1
if left_index < len(left_data):
del data[data_index:]
data += left_data[left_index:]
elif right_index < len(right_data):
del data[data_index:]
data += right_data[right_index:]
if __name__ == '__main__':
data = [9, 1, 7, 6, 2, 8, 5, 3, 4, 0]
merge_sort(data)
print(data)
data = [9, 1, 7, 6, 2, 8, 5, 3, 4, 0]
data.sort()
print(data)
def heap_permutation(data, n):
if n == 1:
print(data)
return
for i in range(n):
heap_permutation(data, n - 1)
if n % 2 == 0:
data[i], data[n-1] = data[n-1], data[i]
else:
data[0], data[n-1] = data[n-1], data[0]
if __name__ == '__main__':
data = [1, 2, 3]
heap_permutation(data, len(data))
from itertools import permutations
perm = permutations([1, 2, 3])
for i in list(perm):
print(i)
from itertools import combinations_with_replacement
comb = combinations_with_replacement([1, 2, 3], 3)
for i in list(comb):
print(i)