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.

<font color=#FF0000>Undecidable problems are problems that algorithms simply cannot solve. One of the first problems discovered is the halting problem. Most of these problems are paradoxical and theoretical situations where answers are most likely are subjective. However, some of these problems can have situations where some inputs have values. But not all values are going to have outputs.</p>

Decidable problems are problems that algorithms can return an output for all inputs. Mostly, these are algebraical problems that are simply solvable.

</div> </div> </div>

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

<font color=#FF0000>ANSWER: C</p>

STEP 1: 3 x 8

STEP 2 & 3: (24)^2

The first step is simply multiplying two numbers. The second and third is squaring the result of step one.

</div> </div> </div>

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

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
    }
  }
}
}

new one below

function sum(n) {
    if (n <= 1) {
      return n;
    }
    return n + sum(n - 1);
}

Recursive functions work by repetitive calls where recursive conditions perform calls to the functions until the condition is met. Once it is met, the functions stops

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

def merge_sort(data):
    if len(data) <= 1:
        return
    
    #splits data in half, defines left and right
    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)
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
data = [9, 1, 7, 6, 2, 8, 5, 3, 4, 0]

print("original list")
print(data)
data.sort()
print("-----------------")
print("sorted list")
print(data)
original list
[9, 1, 7, 6, 2, 8, 5, 3, 4, 0]
-----------------
sorted list
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

The python sort() works by returning a sorted list as in terms of the specified iterable object. However, you must define ascending or descending order. This is way more efficient as using a library to do this skips all the steps that you made by re-coding it.

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

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))
[1, 2, 3]
[2, 1, 3]
[3, 1, 2]
[1, 3, 2]
[2, 3, 1]
[3, 2, 1]
from itertools import permutations 

perm = permutations([1, 2, 3]) 

for i in list(perm):
    print(i)
  
(1, 2, 3)
(1, 3, 2)
(2, 1, 3)
(2, 3, 1)
(3, 1, 2)
(3, 2, 1)

Using a permutation library, I was able to rewrite the original code is 3-4 lines. This library from itertools imports code that you coded yourself. Not only is it more efficient but generally easier.

</div>