HACK 1

Please write a short 1-2 sentence explanation describing the difference between decidable and undecidable problems. Make sure to provide at least one example of each.

A decidable problem is a problem that is possible to determine whether a given solution is correct, while an undecidable problem is a problem that is not possible to determine whether a given solution is correct. An example of a decidable problem is solving an equation, while an example of an undecidable problem is determining whether a given computer program will run forever or halt.

HACK 2

Which of the following is a 3 step algorithm?

A. 2 x 6 x 8

B. 4^5

C. (3 x 8)^2

D. None of the above

E. All of the above

E, A is 2 steps, 2 6 then 12 8. B is 4 steps because you have to multiply 4 times. C is 2 steps as well, 3 8 then 2424.

HACK 3: Rewrite this JavaScript Code in a More Efficient Way (Hint: Use Binary Search)

function peak_finder(array) {
  // Find the middle element
  let middle = Math.floor(array.length / 2);

  // If the middle element is greater than or equal to its neighbors, it is a peak
  if (array[middle] >= array[middle - 1] && array[middle] >= array[middle + 1]) {
    return `The ${middle} indexed number, ${array[middle]} is a peak`;
  }
  // If the middle element is less than its left neighbor, the peak is to the left
  else if (array[middle] < array[middle - 1]) {
    return peak_finder(array.slice(0, middle));
  }
  // Otherwise, the peak is to the right
  else {
    return peak_finder(array.slice(middle + 1));
  }
}

HACK 4: Rewrite this Python Code in a More Efficient Way

def merge_sort(data):
    # create a new empty list
    sorted_lst = []

    # loop over the unsorted list until it is empty
    while len(data) > 0:
        min_val = min(data)
        data.remove(min_val)
        sorted_lst.append(min_val)
    
    print(sorted_lst)
    
if __name__ == '__main__':
    data2 = [9, 1, 7, 6, 2, 8, 5, 3, 4, 0]
    merge_sort(data2)
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

HACK 5: Rewrite this Python Code in a More Efficient Way

from array import array

def faster_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.swap(i, n-1)
        else:
            data.swap(0, n-1)

if __name__ == '__main__':
    data = array('i', [1, 2, 3])
    heap_permutation(data, len(data))
array('i', [1, 2, 3])
array('i', [2, 1, 3])
array('i', [3, 1, 2])
array('i', [1, 3, 2])
array('i', [2, 3, 1])
array('i', [3, 2, 1])

Extra notes

Algorithm efficiency refers to how well a computer program performs in terms of its usage of resources such as time and memory. An efficient algorithm can complete its tasks quickly and with minimal use of resources, while an inefficient algorithm may take a long time to complete or use up a large amount of memory.

Undecidable problems are problems for which there is no known algorithm that can always produce a correct solution. These problems are typically impossible to solve using a computer program, as there is no way to guarantee that the program will always find the correct solution. Examples of undecidable problems include the halting problem and the problem of determining whether a given statement in a formal system is true or false.

In summary, algorithm efficiency is a measure of how well a computer program performs, while undecidable problems are those that cannot be solved using a computer program.