From acc13b7ab0b5e453e41577b756ac4552c11aebfa Mon Sep 17 00:00:00 2001 From: Aaro Koivukangas Date: Tue, 7 Nov 2023 01:27:43 +0200 Subject: [PATCH] initial commit --- viikko2/alternation.py | 55 +++++++++++++++++ viikko2/forbidden.py | 48 +++++++++++++++ viikko2/onechar.old.py | 54 +++++++++++++++++ viikko2/onechar.py | 74 +++++++++++++++++++++++ viikko2/permutations.py | 34 +++++++++++ viikko2/time.py | 44 ++++++++++++++ viikko3/candies.py | 30 +++++++++ viikko3/distance.py | 72 ++++++++++++++++++++++ viikko3/interval.py | 51 ++++++++++++++++ viikko3/merge-sort.py | 49 +++++++++++++++ viikko3/sorting.py | 27 +++++++++ viikko4/brackets.py | 53 ++++++++++++++++ viikko4/chars.py | 44 ++++++++++++++ viikko4/fliptwo.py | 28 +++++++++ viikko4/list1.py | 22 +++++++ viikko4/list2.py | 23 +++++++ viikko4/quicklist.py | 52 ++++++++++++++++ viikko4/stack.py | 112 ++++++++++++++++++++++++++++++++++ viikko5/hashing.py | 38 ++++++++++++ viikko5/hashing2.py | 34 +++++++++++ viikko5/mex.py | 32 ++++++++++ viikko5/mode.py | 43 +++++++++++++ viikko5/robot.py | 29 +++++++++ viikko6/binary.py | 50 +++++++++++++++ viikko6/leaves.py | 24 ++++++++ viikko6/samelevel.py | 121 +++++++++++++++++++++++++++++++++++++ viikko6/subtrees.py | 73 ++++++++++++++++++++++ viikko7/binarytree.txt | 1 + viikko7/heap.py | 38 ++++++++++++ viikko7/maxheap.py | 34 +++++++++++ viikko7/minheap.py | 107 ++++++++++++++++++++++++++++++++ viikko7/minheap.test.py | 6 ++ viikko7/tasks.py | 23 +++++++ viikko7/tasks.py.old | 43 +++++++++++++ viikko7/twothree.py | 21 +++++++ viikko8/abcdiff.py | 70 +++++++++++++++++++++ viikko8/abclist.py | 57 +++++++++++++++++ viikko8/anagrams.py | 32 ++++++++++ viikko8/count_recursion.py | 15 +++++ viikko8/number.py | 22 +++++++ viikko8/partition.py | 95 +++++++++++++++++++++++++++++ viikko8/recursion.py | 18 ++++++ viikko9/anagrams.py | 11 ++++ viikko9/brackets.py | 36 +++++++++++ viikko9/fastcoin.py | 25 ++++++++ viikko9/getsum.py | 26 ++++++++ viikko9/oddlist.py | 58 ++++++++++++++++++ viikko9/subsets.py | 23 +++++++ 48 files changed, 2077 insertions(+) create mode 100644 viikko2/alternation.py create mode 100644 viikko2/forbidden.py create mode 100644 viikko2/onechar.old.py create mode 100644 viikko2/onechar.py create mode 100644 viikko2/permutations.py create mode 100644 viikko2/time.py create mode 100644 viikko3/candies.py create mode 100644 viikko3/distance.py create mode 100644 viikko3/interval.py create mode 100644 viikko3/merge-sort.py create mode 100644 viikko3/sorting.py create mode 100644 viikko4/brackets.py create mode 100644 viikko4/chars.py create mode 100644 viikko4/fliptwo.py create mode 100644 viikko4/list1.py create mode 100644 viikko4/list2.py create mode 100644 viikko4/quicklist.py create mode 100644 viikko4/stack.py create mode 100644 viikko5/hashing.py create mode 100644 viikko5/hashing2.py create mode 100644 viikko5/mex.py create mode 100644 viikko5/mode.py create mode 100644 viikko5/robot.py create mode 100644 viikko6/binary.py create mode 100644 viikko6/leaves.py create mode 100644 viikko6/samelevel.py create mode 100644 viikko6/subtrees.py create mode 100644 viikko7/binarytree.txt create mode 100644 viikko7/heap.py create mode 100644 viikko7/maxheap.py create mode 100644 viikko7/minheap.py create mode 100644 viikko7/minheap.test.py create mode 100644 viikko7/tasks.py create mode 100644 viikko7/tasks.py.old create mode 100644 viikko7/twothree.py create mode 100644 viikko8/abcdiff.py create mode 100644 viikko8/abclist.py create mode 100644 viikko8/anagrams.py create mode 100644 viikko8/count_recursion.py create mode 100644 viikko8/number.py create mode 100644 viikko8/partition.py create mode 100644 viikko8/recursion.py create mode 100644 viikko9/anagrams.py create mode 100644 viikko9/brackets.py create mode 100644 viikko9/fastcoin.py create mode 100644 viikko9/getsum.py create mode 100644 viikko9/oddlist.py create mode 100644 viikko9/subsets.py diff --git a/viikko2/alternation.py b/viikko2/alternation.py new file mode 100644 index 0000000..9d7fa12 --- /dev/null +++ b/viikko2/alternation.py @@ -0,0 +1,55 @@ +def count(t): + """ + Saat syötteenä listan, jossa on jokin lukujen 1…n + permutaatio. Tehtäväsi on laskea listan vuorottelevien + osajonojen lukumäärä. + + Tässä vuorotteleva tarkoittaa sitä, että osajonossa + seuraava luku on aina vuorotellen pienempi tai suurempi + kuin edellinen. Toisin ilmaistuna vuorotteleva osajono + on sellainen, joka ei sisällä ainuttakaan vähintään + kolmen pituista kasvavaa eikä vähenevää osajonoa. + + Tavoitteena on, että algoritmin aikavaativuus on O(n). + + Toteuta tiedostoon alternation.py funktio count, joka + palauttaa vuorottelevien osajonojen lukumäärän. + """ + result = 0 + result += len(t) * 2 - 1 + dict = {} + last_group = [] + next_itr = "" + print() + print(t) + + for i, x in enumerate(t): + print(f"len of dict = {len(dict)} - iteration: {i}") + + if len(dict) == 0: + dict[x] = "" + + elif len(dict) == 1: + # print(f"{list(dict.keys())[0]} < {x} = lower {list(dict.keys())[0] < x}") + # print(f"{list(dict.keys())[0]} > {x} = higher {list(dict.keys())[0] > x}") + if list(dict.keys())[0] < x: + dict[t[i - 1]] = "lower" + dict[x] = "higher" + elif list(dict.keys())[0] > x: + dict[t[i - 1]] = "higher" + dict[x] = "lower" + else: + print("???") + + elif len(dict) >= 2: + print("***") + + print(dict) + + return result + + +if __name__ == "__main__": + print(count([1, 2, 3, 4])) # 7 -7 = 0 + print(count([1, 4, 2, 5, 3])) # 15 -9 = 6 + print(count([7, 2, 1, 3, 5, 4, 6])) # 17 -13 = 4 diff --git a/viikko2/forbidden.py b/viikko2/forbidden.py new file mode 100644 index 0000000..6e6a325 --- /dev/null +++ b/viikko2/forbidden.py @@ -0,0 +1,48 @@ +def count(s, c): + """ + Tehtäväsi on laskea, moniko merkkijonon osajono ei sisällä + kiellettyä merkkiä. Syötteenä sinulle annetaan merkkijono ja merkki, + jota osajonot eivät saa sisältää. + + Voit olettaa, että merkkijono muodostuu merkeistä a–z, + siinä on enintään 105 merkkiä ja kielletty merkki on jokin merkeistä a–z. + Tavoitteena on, että algoritmin aikavaativuus on O(n). + + Toteuta tiedostoon forbidden.py funktio count, + joka palauttaa halutun tuloksen. + """ + result = 0 + combination = 0 + prev_str = "" + + # print() + # print(f"{s} --- {c}") + # print() + + for char in s: + if char == c: + # print(f"forbidden char {c}") + result += combination + combination = 0 + prev_str = "" + continue + + if prev_str == "": + prev_str = char + combination += len(prev_str) + + else: + prev_str += char + combination += len(prev_str) + + # print(f"char: {char} -> prev_str: {prev_str} = {combination}") + + result += combination + return result + + +if __name__ == "__main__": + print(count("abacabb", "b")) # 7 + print(count("abcdef", "g")) # 21 + print(count("xxxxxxxxx", "x")) # 0 + print(count("pupujussikainen", "u")) # 48 diff --git a/viikko2/onechar.old.py b/viikko2/onechar.old.py new file mode 100644 index 0000000..e1337aa --- /dev/null +++ b/viikko2/onechar.old.py @@ -0,0 +1,54 @@ +def count(s): + """ + Tehtäväsi on laskea, monessako merkkijonon osajonossa jokainen + merkki on sama. Esimerkiksi merkkijonossa abbbcaa tällaiset osajonot ovat + + a (kolmesti) + aa + b (kolmesti) + bb (kahdesti) + bbb + c + + eli yhteensä 11 osajonoa. + + Voit olettaa, että merkkijono muodostuu merkeistä a–z ja siinä on + enintään 105 merkkiä. Tavoitteena on, että algoritmin + aikavaativuus on O(n). + + Toteuta tiedostoon onechar.py funktio count, + joka palauttaa halutun tuloksen. + """ + prev_char = "" + total = 0 + for char in s: + if prev_char == "": + prev_char = char + print( + f"{total} + {s.count(char)} = {total + s.count(char)} --- {char} -> {prev_char}" + ) + total += s.count(char) + + elif prev_char[0] == char: + prev_char += char + print( + f"{total} + {s.count(prev_char)} = {total + s.count(prev_char)} --- {char} -> {prev_char}" + ) + total += s.count(prev_char) + + elif prev_char != char: + prev_char = char + print( + f"{total} + {s.count(char)} = {total + s.count(char)} --- {char} -> {prev_char}" + ) + total += s.count(char) + + print(s) + + return total + + +if __name__ == "__main__": + print(count("aaa")) # 6 + print(count("abbbcaa")) # 11 + print(count("abcde")) # 5 diff --git a/viikko2/onechar.py b/viikko2/onechar.py new file mode 100644 index 0000000..cd6e379 --- /dev/null +++ b/viikko2/onechar.py @@ -0,0 +1,74 @@ +def count(s): + """ + Tehtäväsi on laskea, monessako merkkijonon osajonossa jokainen + merkki on sama. Esimerkiksi merkkijonossa abbbcaa tällaiset osajonot ovat + + a (kolmesti) + aa + b (kolmesti) + bb (kahdesti) + bbb + c + + eli yhteensä 11 osajonoa. + + Voit olettaa, että merkkijono muodostuu merkeistä a–z ja siinä on + enintään 105 merkkiä. Tavoitteena on, että algoritmin aikavaativuus on O(n) + + Toteuta tiedostoon onechar.py funktio count, joka palauttaa halutun + tuloksen. + + Args: + s (string): the string to be calculated + + Returns: + int: result of the calculation + """ + + import math + + # is the number of combinations one can make with + # the same letter, this case it is n + (n+1) + # ex. if str len 3 (aaa), comb is 1 + 2 + 3 = 6 + combination = 0 + total = 0 + prev_str = "" + + # print() + # print(s) + # print() + + for char in s: + if prev_str == "": + prev_str = char + + elif char in prev_str: + prev_str += char + + elif char not in prev_str: + # print( + # f"{total} + {math.factorial(len(prev_str))} = {total + math.factorial(len(prev_str))}, combination: {combination}" + # ) + total += combination + combination = 0 + prev_str = char + + else: + print("?") + + # print(f"char: {char}, prev: {prev_str}") + combination += len(prev_str) + + # print( + # f"{total} + {math.factorial(len(prev_str))} = {total + math.factorial(len(prev_str))}, combination: {combination}" + # ) + total += combination + + return total + + +if __name__ == "__main__": + print(count("aaa")) # 6 + print(count("abbbcaa")) # 11 + print(count("abcde")) # 5 + print(count(s="a" * 10**5)) diff --git a/viikko2/permutations.py b/viikko2/permutations.py new file mode 100644 index 0000000..8001d55 --- /dev/null +++ b/viikko2/permutations.py @@ -0,0 +1,34 @@ +def count(a, b): + """ + Sinulle annetaan kaksi listaa A ja B, joissa molemmissa on lukujen 1…n jokin + permutaatio (eli molemmat listat sisältävät luvut 1…n jossain järjestyksessä). + + Tehtäväsi on laskea, moniko luvuista 1…n esiintyy aiemmin listalla A kuin + listalla B. Tavoitteena on, että algoritmin aikavaativuus on O(n). + + Toteuta tiedostoon permutations.py funktio count, joka palauttaa halutun tuloksen. + """ + result = 0 + dict = {} + # print() + + for index, value in enumerate(a): + dict[value] = index + # print(dict, b) + + for index, value in enumerate(b): + # print(value, index, dict.get(value) < index) + if dict.get(value) < index: + result += 1 + + return result + + +if __name__ == "__main__": + print(count([1, 2, 3], [1, 2, 3])) # 0 + print(count([2, 3, 4, 1], [1, 2, 3, 4])) # 3 + print(count([4, 7, 3, 1, 6, 2, 5], [5, 6, 1, 2, 4, 3, 7])) # 3 + print(count([5, 4, 9, 1, 8, 3, 2, 6, 7], [6, 2, 8, 4, 9, 1, 5, 7, 3])) # 5 + # a = list(range(1, 10**5 + 1)) + # b = list(range(10**5, 0, -1)) + # print(count(a, b)) diff --git a/viikko2/time.py b/viikko2/time.py new file mode 100644 index 0000000..78e1763 --- /dev/null +++ b/viikko2/time.py @@ -0,0 +1,44 @@ +import time +import random + + +def timespent(listLen): + """ + Creates list and calculates the time needed to make it + + Args: + :param listLen: length of the tested list + Returns: + :param result: the time it took to make the list + """ + testList = [] + for x in range(listLen): + testList.append(random.randint(0, 1)) + + startTimeO2 = time.time() + laskuri = 0 + for x in range(listLen - 1): + for y in range(x + 1, listLen - 1): + if testList[x] == 0 and testList[y] == 1: + laskuri += 1 + endTimeO2 = time.time() + + startTimeO = time.time() + laskuri = 0 + nollat = 0 + for x in range(listLen - 1): + if testList[x] == 0: + nollat += 1 + else: + laskuri += nollat + endTimeO = time.time() + + timeToO2 = startTimeO2 - endTimeO2 + timeToO = startTimeO - endTimeO + return timeToO2, timeToO + + +if __name__ == "__main__": + print(timespent(10**2)) + print(timespent(10**4)) + print(timespent(10**5)) diff --git a/viikko3/candies.py b/viikko3/candies.py new file mode 100644 index 0000000..d3b7161 --- /dev/null +++ b/viikko3/candies.py @@ -0,0 +1,30 @@ +def solve(prices, x): + """ + Kaupassa on myytävänä n karkkia, joilla jokaisella on tietty hinta. + Montako karkkia voit ostaa enintään, kun sinulla on rahaa x? + + Karkkien määrä on enintään 105, ja jokaisen karkin hinta ja x on välillä 1…109. + Tavoitteena on, että algoritmin aikavaativuus on O(n) tai O(nlogn). + + Toteuta tiedostoon candies.py funktio solve, joka ilmoittaa, + montako karkkia voit ostaa enintään. + """ + total = 0 + prices.sort() + + for y in prices: + if y > x: + return total + else: + x -= y + total += 1 + + return total + + +if __name__ == "__main__": + print(solve([1, 1, 1, 1], 2)) # 2 + print(solve([2, 5, 3, 2, 8, 7], 10)) # 3 + print(solve([2, 3, 4, 5], 1)) # 0 + print(solve([2, 3, 4, 5], 10**9)) # 4 + print(solve([10**9, 1, 10**9], 10**6)) # 1 diff --git a/viikko3/distance.py b/viikko3/distance.py new file mode 100644 index 0000000..8d39d12 --- /dev/null +++ b/viikko3/distance.py @@ -0,0 +1,72 @@ +from math import ceil, floor + + +def find(t, k): + """ + Annettuna on lista kokonaislukuja, jotka kaikki ovat väliltä 1…k. + Listalle halutaan lisätä uusi kokonaisluku väliltä 1…k, + jonka etäisyys lähimpään listalla jo valmiiksi olevaan lukuun on mahdollisimman + suuri. Kuinka suuri tuo etäisyys voi korkeintaan olla? + + Voit olettaa, että listalla on korkeintaan 105 lukua ja k on korkeintaan 109. + Tavoitteena on, että algoritmin aikavaativuus on O(n) tai O(nlogn). + + Toteuta tiedostoon distance.py funktio find, + joka ilmoittaa suurimman mahdollisen etäisyyden. + """ + t.sort() + result = 0 + dict = {} + # print(t) + + prev_val = None + for i, x in enumerate(t): + if prev_val == x: + continue + if i == 0: + dict[x] = x - 1 + prev_val = x + else: + dict[x] = x - t[i - 1] + prev_val = x + + # print(dict) + + for i, x in enumerate(dict): + # print(f"x, k, distance: {x}, {k}, {dict[x]}") + + if i == 0: + result = dict[x] + if i == len(dict) - 1: + last_value = k - x + if last_value > result: + result = last_value + + # jos max pituus on pienempi kuin dictin väli aiempaan // 2 + index + # if k < ceil(dict[x] // 2) + x: + # print( + # f"if k > x + (dict[x] // 2): {x} + ({ceil(dict[x] // 2)}) = {x+ceil((dict[x] // 2))}" + # ) + + division = dict[x] / 2 + if x > k: + if k > x - floor(division): + return result + + elif x <= k: + if floor(division) > result: + result = division + + return floor(result) + + +if __name__ == "__main__": + print(find([1, 2, 9], 11)) # 3 + print(find([2, 1, 3], 3)) # 0 + print(find([7, 4, 10, 4], 10)) # 3 + print(find([15, 2, 6, 4, 18], 20)) # 4 + print( + find([41222388, 392676742, 307110407, 775934683, 25076911], 809136843) + ) # 191628970 + print(find([2, 11, 9, 10, 10], 15)) # 4 + print(find([2], 15)) diff --git a/viikko3/interval.py b/viikko3/interval.py new file mode 100644 index 0000000..83fd66d --- /dev/null +++ b/viikko3/interval.py @@ -0,0 +1,51 @@ +def count(t): + """ + Annettuna on lista, josta tulee poimia mahdollisimman monta lukua. + Ensimmäinen luku saa olla mikä tahansa listan luku ja tämän jälkeen seuraavan + poimitun luvun tulee olla tasan yhden suurempi kuin edellinen. + Kuinka monta lukua voidaan näin korkeintaan poimia? + + Voit olettaa, että listalla on enintään 105 lukua ja että jokainen luku + on väliltä 1…109. Tavoitteena on, että algoritmin aikavaativuus on O(n) + tai O(nlogn). + + Toteuta tiedostoon interval.py funktio count, joka ilmoittaa, + montako lukua listalta voidaan enintään poimia halutulla tavalla. + """ + + t.sort() + # print() + # print(t) + # print() + prevNum = -1 + total = 0 + result = 0 + + for x in t: + # print(t) + # print(x, prevNum, total, prevNum + 1 == x or prevNum - 1 == x) + if prevNum == -1: + prevNum = x + total = 1 + elif prevNum + 1 == x or prevNum - 1 == x: + total += 1 + prevNum = x + else: + if prevNum == x: + continue + prevNum = x + total = 1 + + if total > result: + result = total + + return result + + +if __name__ == "__main__": + print(count([1, 1, 1, 1])) # 1 + print(count([10, 4, 8])) # 1 + print(count([7, 6, 1, 8])) # 3 + print(count([1, 2, 1, 2, 1, 2])) # 2 + print(count([987654, 12345678, 987653, 999999, 987655])) # 3 + print(count([14, 15, 16, 15, 13])) diff --git a/viikko3/merge-sort.py b/viikko3/merge-sort.py new file mode 100644 index 0000000..c5f5c8e --- /dev/null +++ b/viikko3/merge-sort.py @@ -0,0 +1,49 @@ +from random import shuffle +from time import time + +n = 10**5 +randList = [x for x in range(1, n + 1)] +helper_list = [0 for x in range(n + 1)] +shuffle(randList) + + +def main(): + a = 0 + b = len(randList) - 1 + + start_time = time() + sort(a, b) + end_time = time() + + final_time = end_time - start_time + print(final_time, "s") + + +def sort(a, b): + if a == b: + return + k = (a + b) // 2 + sort(a, k) + sort(k + 1, b) + merge(a, k, k + 1, b) + + +def merge(a1, b1, a2, b2): + + a = a1 + b = b2 + + for x in range(a, b + 1): + if a2 > b2 or (a1 <= b1 and randList[a1] <= randList[a2]): + helper_list[x] = randList[a1] + a1 += 1 + else: + helper_list[x] = randList[a2] + a2 += 1 + + for x in range(a, b + 1): + randList[x] = helper_list[x] + + +if __name__ == "__main__": + main() diff --git a/viikko3/sorting.py b/viikko3/sorting.py new file mode 100644 index 0000000..40f0dce --- /dev/null +++ b/viikko3/sorting.py @@ -0,0 +1,27 @@ +from random import randint +from time import time + + +def main(): + n = 10**5 + randList = [randint(1, n) for x in range(n)] + + start_time = time() + for i in range(1, n): + j = i - 1 + while j >= 0 and randList[j] > randList[j + 1]: + temp = randList[j] + randList[j] = randList[j + 1] + randList[j + 1] = temp + j -= 1 + # print("at sorting", j) + + print("at round", i, "out of", n, " -- left", n - i) + end_time = time() + + print(randList) + print("total time:", end_time - start_time) + + +if __name__ == "__main__": + main() diff --git a/viikko4/brackets.py b/viikko4/brackets.py new file mode 100644 index 0000000..726c9c6 --- /dev/null +++ b/viikko4/brackets.py @@ -0,0 +1,53 @@ +from collections import deque + + +def balance(s): + brackets = 0 + right_brackets_for_stars = 0 + stars = [] + list = deque(s) + star_count = 0 + # print(list) + + for x in list: + if x == "*": + star_count += 1 + if star_count != 0: + if x == ")": + right_brackets_for_stars += 1 + + for x in list: + if x == "(": + brackets += 1 + elif x == ")": + if brackets <= 0: + return None + brackets -= 1 + elif x == "*": + if star_count == 1: + stars.append(brackets) + brackets = 0 + star_count -= 1 + elif star_count != 0: + stars.append(1) + star_count -= 1 + brackets -= 1 + + if brackets < 0: + return None + + if brackets != 0: + return None + + return stars + + +if __name__ == "__main__": + print(balance("*(*")) # None + print(balance("*(")) # None + print(balance("(*")) # [1] + print(balance("(())")) # [] + print(balance("(((((*")) # [5] + print(balance("(((((*(")) # None + print(balance("((((*(()*()*")) # [2,2,1] + print(balance("((*))(((*")) # None diff --git a/viikko4/chars.py b/viikko4/chars.py new file mode 100644 index 0000000..f3956be --- /dev/null +++ b/viikko4/chars.py @@ -0,0 +1,44 @@ +def solve(s): + print() + list = s + print(list) + + i = 0 + while i < len(s) - 1 >= 1: + if i > len(list) - 1: + i = 0 + + # lol memory error jos ei + if i < 0: + i = 0 + + # 1. kaksi merkkiä yhtäsuuria peräkkäin + if list[i] == list[i + 1]: + if ord(s[i]) == 122: + int_to_char = 96 + else: + int_to_char = ord(s[i]) + + # 3. poista kaksi, lisää yksi, yhtä suurempi + list = s[0:i] + chr(int_to_char + 1) + s[(i + 2) :] + s = list + i -= 1 + + # 2. jos ei, lopeta, i menee yli len(s)-1 + else: + i += 1 + return s + + +if __name__ == "__main__": + print(solve("auto")) # auto + print(solve("ddqqirr")) # eris + print(solve("aaaaaa")) # cb + print(solve("wsstuva")) # xa + print(solve("zzzzzzzz")) # c + print(solve("mlkjihgfedcbb")) # n + print(solve("kkkjjiikjkjiikjjiijkjji")) # mjkjmlki + print(solve("zaaazzzaaz")) # zczbz + s = "a" * 10**5 + print(solve(s)) + print(solve("aaabbbbb")) diff --git a/viikko4/fliptwo.py b/viikko4/fliptwo.py new file mode 100644 index 0000000..0836436 --- /dev/null +++ b/viikko4/fliptwo.py @@ -0,0 +1,28 @@ +from collections import deque + + +def solve(n, k): + + list = deque() + + for x in range(1, n + 1): + list.append(x) + + for x in range(k): + first_val = list[0] + second_val = list[1] + + list.append(second_val) + list.append(first_val) + + list.popleft() + list.popleft() + + return list[0] + + +if __name__ == "__main__": + print(solve(4, 3)) # 4 + print(solve(12, 5)) # 11 + print(solve(99, 555)) # 11 + print(solve(12345, 54321)) # 9875 diff --git a/viikko4/list1.py b/viikko4/list1.py new file mode 100644 index 0000000..e1d9c4e --- /dev/null +++ b/viikko4/list1.py @@ -0,0 +1,22 @@ +from time import time + +n = 10**5 +list = [] + + +def main(): + start_time = time() + for x in range(1, n): + list.append(x) + end_time = time() + print(end_time - start_time) + + start_time = time() + for x in list: + list.pop() + end_time = time() + print(end_time - start_time) + + +if __name__ == "__main__": + main() diff --git a/viikko4/list2.py b/viikko4/list2.py new file mode 100644 index 0000000..d8a5dd2 --- /dev/null +++ b/viikko4/list2.py @@ -0,0 +1,23 @@ +from collections import deque +from time import time + +n = 10**5 +list = deque() + + +def main(): + start_time = time() + for x in range(1, n): + list.append(x) + end_time = time() + print(end_time - start_time) + + start_time = time() + for x in range(1, n): + list.pop() + end_time = time() + print(end_time - start_time) + + +if __name__ == "__main__": + main() diff --git a/viikko4/quicklist.py b/viikko4/quicklist.py new file mode 100644 index 0000000..ca0e9d5 --- /dev/null +++ b/viikko4/quicklist.py @@ -0,0 +1,52 @@ +class QuickList: + def __init__(self, t): + self.list = t + self.index_of_first = 0 + # print(self.list) + + def move(self, current_index): + list_len = len(self.list) + # print("listlen:", list_len) + + if current_index // list_len != 0: + current_index -= list_len * current_index // list_len + + self.index_of_first += current_index + # print("current index:", current_index, "+=", self.index_of_first) + + # print("index of first > listlen:", self.index_of_first > list_len) + if self.index_of_first > list_len: + self.index_of_first -= list_len + # print("updated index:", self.index_of_first) + + # print(f"moved {current_index} to index_of_first: {self.index_of_first}") + + def get(self, i): + # print("get of index:", i) + list_len = len(self.list) + # print(f"{self.index_of_first} + {i} = {self.index_of_first + i}") + current_index = self.index_of_first + current_index += i + if current_index >= list_len: + current_index -= list_len + + return self.list[current_index] + + +if __name__ == "__main__": + q = QuickList([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]) + print(q.get(0)) # 1 + print(q.get(4)) # 5 + q.move(3) + print(q.get(4)) # 8 + q.move(3) + print(q.get(4)) # 1 + q.move(10) + print(q.get(4)) # 1 + q.move(7) + q.move(5) + print(q.get(0)) # 9 + q = QuickList(list(range(1, 10**5 + 1))) + for i in range(10**5 - 1): + q.move(10**5 - 1) + print(q.get(10**4)) diff --git a/viikko4/stack.py b/viikko4/stack.py new file mode 100644 index 0000000..613ee1f --- /dev/null +++ b/viikko4/stack.py @@ -0,0 +1,112 @@ +from collections import deque + + +class Stack: + def __init__(self): + self.list = [] + self.value_dict = {} + # print(self.list) + + def push(self, x): + self.list.append(x) + # if len(self.list) - 1 not in self.value_dict: + # self.value_dict[len(self.list) - 1] = [] + # print("pushed:", self.list, "--- value dict:", self.value_dict) + + def pop(self): + # print() + # print("pop") + pop_value = self.list.pop() + current_list_len = len(self.list) + value_increase = 0 + # print(self.list) + # print(self.value_dict) + if current_list_len not in self.value_dict: + self.value_dict[current_list_len] = [] + + for x in self.value_dict: + if self.value_dict[x] == []: + continue + + # print("current list len:", current_list_len, "- x:", x) + + if current_list_len > x: + continue + + elif current_list_len < x: + value_increase += len(self.value_dict[x]) + difference = x - current_list_len + + for y in self.value_dict[x]: + if y - difference <= 0: + continue + self.value_dict[current_list_len].append(y - difference) + + self.value_dict[x] = [] + # print("dict values at x", self.value_dict[x]) + + # elif current_list_len == x: + # print( + # "value increased as current list len == x", + # current_list_len, + # x, + # current_list_len == x, + # ) + # value_increase += len(self.value_dict[x]) + + # print("value dict", self.value_dict) + # print("self list", self.list) + return pop_value + value_increase + + def increase(self, k): + if len(self.list) not in self.value_dict: + self.value_dict[len(self.list)] = [] + + self.value_dict[len(self.list)].append(k) + # print("incremented:", len(self.list), self.value_dict) + + def get_len(self): + print("list", len(self.list)) + print("value dict", len(self.value_dict)) + + +if __name__ == "__main__": + s = Stack() + s.push(1) + s.push(2) + s.push(3) + s.increase(2) + print(s.pop()) # 4 + s.push(1) + s.increase(2) + print(s.pop()) # 2 + print(s.pop()) # 4 + print(s.pop()) # 1 + print() + + # s = Stack() + # s.push(1) + # s.push(2) + # s.push(3) + # s.increase(2) + # s.increase(2) + # print(s.pop()) + # print(s.pop()) + s = Stack() + for i in range(5 * 10**4): + s.push(i + 1) + for i in range(5 * 10**4 - 1): + s.increase(5 * 10**4) + # print(s.pop()) + s = Stack() + for i in range(14000): + for j in range(3): + s.push(i * i + 1) + s.increase(i + 1) + # print(s.pop()) + s.pop() + s.get_len() + for i in range(28000): + # print(s.pop()) + s.pop() + s.get_len() diff --git a/viikko5/hashing.py b/viikko5/hashing.py new file mode 100644 index 0000000..f916984 --- /dev/null +++ b/viikko5/hashing.py @@ -0,0 +1,38 @@ +A = 19 +N = 10**6 + + +def main(): + hash_function("aybabtu") + hash_function("maanantai") + hash_function("tiistai") + hash_function("keskiviikko") + hash_function("torstai") + hash_function("perjantai") + hash_function("lauantai") + hash_function("sunnuntai") + + +def hash_function(s): + print(s) + + list = [] + for x in s: + list.append(ord(x)) + + print(list) + + result = 0 + for i, y in enumerate(list): + # print(list, y) + print(f"{A} ** {len(list)}-1-{i}={(len(list) - 1 - i)} * {y}") + result += A ** (len(list) - 1 - i) * y + + result %= N + + print(result) + print() + + +if __name__ == "__main__": + main() diff --git a/viikko5/hashing2.py b/viikko5/hashing2.py new file mode 100644 index 0000000..b51a447 --- /dev/null +++ b/viikko5/hashing2.py @@ -0,0 +1,34 @@ +from random import randint +from time import time + +n = 10**6 +randList = [randint(1, 10**9) for x in range(n)] + + +def main(): + list_start_time = time() + sortedRandList = sorted(randList) + prev_val = -1 + count = 0 + for x in sortedRandList: + if prev_val != x: + count += 1 + + prev_val = x + list_end_time = time() + + print(count) + + set_start_time = time() + randset = set() + for x in randList: + randset.add(x) + set_end_time = time() + + print(len(randset)) + + print(list_end_time - list_start_time, set_end_time - set_start_time) + + +if __name__ == "__main__": + main() diff --git a/viikko5/mex.py b/viikko5/mex.py new file mode 100644 index 0000000..72f6112 --- /dev/null +++ b/viikko5/mex.py @@ -0,0 +1,32 @@ +class Mex: + def __init__(self): + self.set = {0} + self.lowest_missing = 0 + + def add(self, x): + self.set.add(x) + + if x != self.lowest_missing: + return self.lowest_missing + + for y in range(self.lowest_missing, len(self.set) + 1): + if y in self.set: + continue + else: + self.lowest_missing = y + return self.lowest_missing + + return self.lowest_missing + + +if __name__ == "__main__": + m = Mex() + print(m.add(1)) # 0 + print(m.add(3)) # 0 + print(m.add(4)) # 0 + print(m.add(0)) # 2 + print(m.add(5)) # 2 + print(m.add(2)) # 6 + # m = Mex() + # for i in range(10**5): + # print(m.add(i)) diff --git a/viikko5/mode.py b/viikko5/mode.py new file mode 100644 index 0000000..3d246bd --- /dev/null +++ b/viikko5/mode.py @@ -0,0 +1,43 @@ +class Mode: + def __init__(self): + self.dict = {} + self.mode = 0 + self.count = 0 + + def add(self, x): + if self.dict.get(x) is None: + self.dict[x] = 1 + else: + self.dict[x] += 1 + + if self.dict[x] > self.count: + self.mode = x + self.count = self.dict[x] + return self.mode + + elif self.dict[x] == self.count: + self.mode = x if x < self.mode else self.mode + return self.mode + + return self.mode + + +if __name__ == "__main__": + m = Mode() + print(m.add(1)) # 1 + print(m.add(2)) # 1 + print(m.add(2)) # 2 + print(m.add(1)) # 1 + print(m.add(3)) # 1 + print(m.add(3)) # 1 + print(m.add(3)) # 3 + m = Mode() + print(m.add(500000000)) + print(m.add(500000008)) + print(m.add(500000002)) + print(m.add(500000004)) + print(m.add(500000005)) + print(m.add(500000001)) + print(m.add(500000003)) + print(m.add(500000001)) + print(m.add(500000005)) diff --git a/viikko5/robot.py b/viikko5/robot.py new file mode 100644 index 0000000..850dd9f --- /dev/null +++ b/viikko5/robot.py @@ -0,0 +1,29 @@ +def count(s): + # print() + x = 0 + y = 0 + visited_cords = {"0,0"} + + for char in s: + if char == "L": + x -= 1 + elif char == "R": + x += 1 + elif char == "U": + y += 1 + elif char == "D": + y -= 1 + + str_cord = f"{x},{y}" + visited_cords.add(str_cord) + + return len(visited_cords) + + +if __name__ == "__main__": + print(count("LL")) # 3 + print(count("UUDLRR")) # 5 + print(count("UDUDUDU")) # 2 + print(count("LDLRLLRDLU")) # 2 + s = "RULDD" * (2 * 10**4) + print(count(s)) diff --git a/viikko6/binary.py b/viikko6/binary.py new file mode 100644 index 0000000..4ee5f9a --- /dev/null +++ b/viikko6/binary.py @@ -0,0 +1,50 @@ +from random import randint, shuffle + +n = 10**5 +# n = 10 +h = 0 + + +class Node: + def __init__(self, value): + self.left = None + self.right = None + self.value = value + self.height = 1 + + def set_h(self, x): + self.height = x + 1 + + def add(self, value): + global h + + if self.height > h: + h = self.height + + # print(value, "-", self.value, "---", self.left, self.right) + + if value > self.value: + if self.right is not None: + self.right.add(value) + else: + self.right = Node(value) + self.right.set_h(self.height) + return + else: + if self.left is not None: + self.left.add(value) + else: + self.left = Node(value) + self.left.set_h(self.height) + return + + +list = [] +list = [x for x in range(1, n)] +shuffle(list) + +N = Node(randint(1, n)) +for x in list: + N.add(x) + +print(h) diff --git a/viikko6/leaves.py b/viikko6/leaves.py new file mode 100644 index 0000000..cdc4ccb --- /dev/null +++ b/viikko6/leaves.py @@ -0,0 +1,24 @@ +from collections import namedtuple + + +def count(node): + counter = 0 + if node[0] is None and node[1] is None: + counter += 1 + return counter + if node[0] is not None: + print(node, "------ left") + counter += count(node[0]) + if node[1] is not None: + print(node, "------ right") + counter += count(node[1]) + + return counter + + +if __name__ == "__main__": + Node = namedtuple("Node", ["left", "right"]) + tree = Node(None, Node(Node(None, None), Node(None, None))) + tree2 = Node(left=Node(left=None, right=None), right=Node(left=None, right=None)) + print(count(tree)) # 2 + print(count(tree2)) # 2 diff --git a/viikko6/samelevel.py b/viikko6/samelevel.py new file mode 100644 index 0000000..5e74179 --- /dev/null +++ b/viikko6/samelevel.py @@ -0,0 +1,121 @@ +from collections import namedtuple + + +def count(node, level): + leaf_counter = 0 + + # print() + # print(node, level) + + if level == 1: + # print("only 1 depth, returned 1") + return 1 + elif level == 0: + # print("no depth, no nodes counted") + return 0 + + level -= 1 + + # print( + # "left:", + # node[0] is not None, + # "right:", + # node[1] is not None, + # " --- on level:", + # level, + # " - while leaf:", + # leaf_counter, + # ) + if node[0] is not None: + leaf_counter += count_rec(node[0], level, 0) + # print("got", leaf_counter, "from left") + if node[1] is not None: + leaf_counter += count_rec(node[1], level, 0) + # print("got", leaf_counter, "from right") + + return leaf_counter + + +def count_rec(node, level, leaf_counter): + level -= 1 + current_leaf_counter = leaf_counter + + if level < 0: + return 0 + + elif level == 0: + # print("incd leaf", leaf_counter + 1) + return 1 + + # print( + # "left:", + # node[0] is not None, + # "right:", + # node[1] is not None, + # " --- on level:", + # level, + # " - while leaf:", + # leaf_counter, + # ) + if node[0] is not None: + leaf_counter += count_rec(node[0], level, current_leaf_counter) + # print(node[0], " --- left --- level:", level, "leaf counter:", leaf_counter) + + if node[1] is not None: + leaf_counter += count_rec(node[1], level, current_leaf_counter) + # print(node[1], " --- right --- level:", level, "leaf counter:", leaf_counter) + + return leaf_counter + + +if __name__ == "__main__": + Node = namedtuple("Node", ["left", "right"]) + tree = Node(None, Node(Node(None, None), Node(None, None))) + tree2 = Node(left=None, right=None) + print(count(tree, 1)) # 1 + print(count(tree, 2)) # 1 + print(count(tree, 3)) # 2 + print(count(tree, 4)) # 0 + print(count(tree, 0)) # 0 + print(count(tree2, 1)) # 1 + print( + count( + Node( + left=Node( + left=Node( + left=Node(left=Node(left=None, right=None), right=None), + right=None, + ), + right=None, + ), + right=Node( + left=Node( + left=Node( + left=Node(left=Node(left=None, right=None), right=None), + right=None, + ), + right=None, + ), + right=None, + ), + ), + 3, + ) + ) + # 2 + print( + count( + Node( + left=Node( + left=Node(left=Node(left=None, right=None), right=None), + right=Node( + left=Node(left=None, right=None), + right=Node(left=Node(left=None, right=None), right=None), + ), + ), + right=Node(left=None, right=Node(left=None, right=None)), + ), + 4, + ) + ) + # 3 diff --git a/viikko6/subtrees.py b/viikko6/subtrees.py new file mode 100644 index 0000000..62b66b0 --- /dev/null +++ b/viikko6/subtrees.py @@ -0,0 +1,73 @@ +from collections import namedtuple + + +def diff(node): + left_diff = 0 + right_diff = 0 + leaf_count_l = 0 + leaf_count_r = 0 + + print() + # print("left:", node[0] is not None, "- right:", node[1] is not None) + + if node[0] is not None: + returns_l = diff_rec(node[0], 0) + left_diff = returns_l[0] + leaf_count_l = returns_l[1] + 1 + + if node[1] is not None: + returns_r = diff_rec(node[1], 0) + right_diff = returns_r[0] + leaf_count_r = returns_r[1] + 1 + + highest_diff = ( + leaf_count_l - leaf_count_r + if leaf_count_l >= leaf_count_r + else leaf_count_r - leaf_count_l + ) + + if left_diff >= highest_diff or right_diff > highest_diff: + if left_diff >= right_diff: + return left_diff + else: + return right_diff + else: + return highest_diff + + +def diff_rec(node, count_leaves): + leaf_count_l = 0 + leaf_count_r = 0 + diff_l = 0 + diff_r = 0 + + # print("left:", node[0] is not None, "- right:", node[1] is not None) + if node[0] is not None: + returns_l = diff_rec(node[0], leaf_count_l) + leaf_count_l += 1 + leaf_count_l += returns_l[1] + diff_l = returns_l[0] + + if node[1] is not None: + returns_r = diff_rec(node[1], leaf_count_r) + leaf_count_r += 1 + leaf_count_r += returns_r[1] + diff_r = returns_r[0] + + highest_diff = ( + leaf_count_l - leaf_count_r + if leaf_count_l >= leaf_count_r + else leaf_count_r - leaf_count_l + ) + + if diff_l > highest_diff or diff_r > highest_diff: + highest_diff = diff_l if diff_l >= diff_r else diff_r + + # print(leaf_count_l, leaf_count_r, "-", highest_diff) + return highest_diff, leaf_count_l + leaf_count_r + + +if __name__ == "__main__": + Node = namedtuple("Node", ["left", "right"]) + tree = Node(None, Node(Node(None, None), Node(None, None))) + print(diff(tree)) # 3 diff --git a/viikko7/binarytree.txt b/viikko7/binarytree.txt new file mode 100644 index 0000000..c3f0e71 --- /dev/null +++ b/viikko7/binarytree.txt @@ -0,0 +1 @@ +# [1, [2, [4, [8, [16, [32, [64, null, null], [0, null, null]], [0, [0, null, null], [0, null, null]]], [0, [0, [0, null, null], [0, null, null]], [0, [0, null, null], [70, null, null]]]], [0, [0, [0, null, null], [0, null, null]], [0, [0, null, null], [0, null, null]]]], [0, [0, [0, [0, null, null], [0, null, null]], [0, [0, null, null], [0, null, null]]], [0, [0, [0, null, null], [0, null, null]], [0, [0, null, null], [0, null, null]]]]], [3, [0, [0, [0, [0, null, null], [0, null, null]], [0, [0, null, null], [0, null, null]]], [0, [0, [0, null, null], [0, null, null]], [0, [0, null, null], [0, null, null]]]], [0, [0, [0, [0, null, null], [0, null, null]], [0, [0, null, null], [0, null, null]]], [0, [0, [0, null, null], [0, null, null]], [0, [0, null, null], [0, null, null]]]]]] diff --git a/viikko7/heap.py b/viikko7/heap.py new file mode 100644 index 0000000..790161d --- /dev/null +++ b/viikko7/heap.py @@ -0,0 +1,38 @@ +from random import shuffle, randint +from time import time +from heapq import heapify, heappop + +n = 10**6 +list = [randint(1, 10**9) for x in range(n)] +shuffle(list) + + +def main(): + start_time_1 = time() + sorted_list = sorted(list) + shorter_list = sorted_list[: n // 10] + sum1 = 0 + for x in shorter_list: + sum1 += x + end_time_1 = time() + print(end_time_1 - start_time_1, sum1) + + start_time_2 = time() + sum2 = 0 + + heapify(list) + + for x in range(0, n // 10): + sum2 += list[0] + heappop(list) + + end_time_2 = time() + + print(end_time_2 - start_time_2, sum2) + + print(sorted_list[:10]) + print(list[:10]) + + +if __name__ == "__main__": + main() diff --git a/viikko7/maxheap.py b/viikko7/maxheap.py new file mode 100644 index 0000000..93f6732 --- /dev/null +++ b/viikko7/maxheap.py @@ -0,0 +1,34 @@ +from math import floor, ceil, log + + +def count(n): + print() + result = 0 + nodes = 0 + levels = 0 + + while 2**levels <= n // 2: + levels += 1 + levels -= 1 + print("levels", levels) + + bottom_leaves = n + 1 - 2 * 2**levels + if bottom_leaves == 2 ** (levels + 1): + levels += 1 + bottom_leaves = 0 + + print("bottom leaves:", bottom_leaves) + + for x in range(1, levels + 1): + result += x * 2**x + + result += bottom_leaves * (levels + 1) + + return result + + +if __name__ == "__main__": + print(count(4)) # 4 + print(count(7)) # 10 + print(count(123)) # 618 + # print(count(999999999)) # 27926258178 diff --git a/viikko7/minheap.py b/viikko7/minheap.py new file mode 100644 index 0000000..c56d89e --- /dev/null +++ b/viikko7/minheap.py @@ -0,0 +1,107 @@ +# for binarytree visualization +from math import log, floor, ceil + + +def count(n, k): + things = 0 + print() + print("n:", n, "- k:", k) + + if n <= 1: + return 1 + elif k == 1: + return 1 + elif n >= 3 and k == 2: + return 2 + + nodes = 0 + for x in range(floor(log(n + 1, 2))): + nodes += 2**x + + bottom_leaves = ( + n - nodes + (2 ** (floor(log(n + 1, 2)) - 1) - ceil((n - nodes) / 2)) + ) + if bottom_leaves == 2 ** (floor(log(n + 1, 2))): + bottom_leaves = 0 + # print("bottom", bottom_leaves) + + if k == n: + if bottom_leaves != 0: + return bottom_leaves + else: + return 2 ** (floor(log(n + 1, 2))) + + spots = 0 + for x in range(1, ceil(log(n + 1, 2)) + 1): + values_below = n - 1 + for y in range(1, x): + values_below -= 2**y + # print("lv", x, "--- val below", values_below) + print("lv:", x) + + # jos n arvoja ei riitä syvyyteen x asti + # esim 8, 3 - 1, 2, 3 ja syvin olisi 4 + if ceil(log(n + 1, 2) > k) and x == 1: + for z in range(k - 1): + spots += 2 * 2**z + print("removed bottom things") + return spots + + # jos k on yhden tai ali päästä n eli voi olla vain 2 alimmalla + # tasolla + if n - k <= 1: + spots += bottom_leaves + if bottom_leaves % 2 != 0 and n > 5: + spots += 1 + elif n - nodes != 0 and (n - nodes) % 2 != 0: + spots += 1 + print("returned from n-k <= 1") + return spots + + # if there is enough bottom values for higher than k values + if n - k >= values_below: + print(" n-k > below values ") + spots = n - 1 + + # + print(values_below) + if (values_below - (n - nodes)) // 2 + (n - nodes) > n - k and x > 1: + print("hiiiiih") + things += 1 + + # spots liian iso -> suurin mahdollinen + if spots >= n: + print("spots too much") + return n - 1 + + # jos viimeinen kierros, k arvoja riittää syvyyteen x + # ja alin epätäydellisen kerroksen leaveja on epätasainen määrä + # if ( + # x == ceil(floor(log(n + 1, 2))) + 1 + # and n - k >= x - 1 + # and (n - nodes) % 2 != 0 + # ): + # print("i dunno") + # spots += n - nodes + + # jos k on suurempi kuin koko syvyys + # jos k suuremmat jäsenet riittävät täyttämään kaikki syvyydellä x + # isommalla puolella + if ( + k >= ceil(log(n + 1, 2)) + and (n - 1 - (n - nodes)) // 2 + (n - nodes) <= n - k + ): + print("holy cwap lol") + return n - 1 + + print("got here") + # return ceil(spots) + return spots - things + + +if __name__ == "__main__": + print(count(9, 3)) # 6 + print(count(9, 4)) # 8 + print(count(9, 6)) # 7 + print(count(70, 34)) # 68 + print(count(6, 4)) # 5 diff --git a/viikko7/minheap.test.py b/viikko7/minheap.test.py new file mode 100644 index 0000000..72d0651 --- /dev/null +++ b/viikko7/minheap.test.py @@ -0,0 +1,6 @@ +def count(n, k): + pn = 0 + while 2**pn <= n // 2: + pn -= 1 + pn -= 1 + bottom_leaves = n + 1 - 2 * 2**pn diff --git a/viikko7/tasks.py b/viikko7/tasks.py new file mode 100644 index 0000000..a3d2198 --- /dev/null +++ b/viikko7/tasks.py @@ -0,0 +1,23 @@ +from heapq import heappush, heappop + + +class Tasks: + def __init__(self): + self.heap = [] + + def add(self, name, priority): + heappush(self.heap, (-1 * priority, name)) + + def next(self): + return heappop(self.heap)[1] + + +if __name__ == "__main__": + t = Tasks() + t.add("siivous", 10) + t.add("ulkoilu", 50) + t.add("opiskelu", 50) + print(t.next()) # opiskelu + t.add("treffit", 100) + print(t.next()) # treffit + print(t.next()) # ulkoilu diff --git a/viikko7/tasks.py.old b/viikko7/tasks.py.old new file mode 100644 index 0000000..36f401c --- /dev/null +++ b/viikko7/tasks.py.old @@ -0,0 +1,43 @@ +from heapq import heappush, heappop + + +class Tasks: + def __init__(self): + self.dict = {} + self.priorities = [] + + def add(self, name, priority): + if self.dict.get(priority) is None: + self.dict[priority] = [] + heappush(self.dict[priority], name) + else: + self.dict[priority].append(name) + + heappush(self.priorities, -1 * priority) + print(self.priorities, self.dict) + + def next(self): + highest_prio = self.priorities[0] * -1 + top_prio_items = self.dict.get(highest_prio) + print(top_prio_items) + + if len(top_prio_items) > 1: + highest_string = "" + for x in top_prio_items: + if x >= highest_string: + highest_string = x + else: + return top_prio_items[0] + + return highest_string + + +if __name__ == "__main__": + t = Tasks() + t.add("siivous", 10) + t.add("ulkoilu", 50) + t.add("opiskelu", 50) + print(t.next()) # opiskelu + t.add("treffit", 100) + print(t.next()) # treffit + print(t.next()) # ulkoilu diff --git a/viikko7/twothree.py b/viikko7/twothree.py new file mode 100644 index 0000000..49dfa5c --- /dev/null +++ b/viikko7/twothree.py @@ -0,0 +1,21 @@ +from heapq import heappush, heappop + + +def smallest(n): + list = [] + heappush(list, 1) + + for x in range(n): + first_item = list[0] + heappush(list, first_item * 2) + heappush(list, first_item * 3) + heappop(list) + + return list[0] + + +if __name__ == "__main__": + print(smallest(1)) # 2 + print(smallest(5)) # 6 + print(smallest(123)) # 288 + print(smallest(55555)) # 663552 diff --git a/viikko8/abcdiff.py b/viikko8/abcdiff.py new file mode 100644 index 0000000..a4a84f0 --- /dev/null +++ b/viikko8/abcdiff.py @@ -0,0 +1,70 @@ +abc = ["A", "B", "C"] + + +def create(n): + print() + list = [] + create_rec(0, n, list) + + return remove_duplicates(list) + + +def remove_duplicates(list): + no_dups_list = [] + for x in list: + no_dups = True + if x.find("AA") != -1: + no_dups = False + elif x.find("BB") != -1: + no_dups = False + elif x.find("CC") != -1: + no_dups = False + + if no_dups: + no_dups_list.append(x) + + return sorted(no_dups_list) + + +def create_rec(k, n, list): + if k == n: + return + elif k == 0: + for x in range(3**n): + if x < (1 / 3) * 3**n: + list.append("A") + elif x < (2 / 3) * 3**n: + list.append("B") + else: + list.append("C") + create_rec(1, n, list) + + else: + repeating = 3**n / (3 ** (k + 1)) + round = 0 + i = repeating + # print("repeat amount:", repeating) + + for x in range(len(list)): + + if round % 3 == 0: + char = "A" + elif round % 3 == 1: + char = "B" + else: + char = "C" + + if i % repeating == 0: + round += 1 + # print("round:", round, "- i", i, "--- char:", char) + i += 1 + + list[x] += char + + create_rec(k + 1, n, list) + + +if __name__ == "__main__": + print(create(1)) # [A,B,C] + print(create(2)) # [AB,AC,BA,BC,CA,CB] + print(len(create(5))) # 48 diff --git a/viikko8/abclist.py b/viikko8/abclist.py new file mode 100644 index 0000000..06277b0 --- /dev/null +++ b/viikko8/abclist.py @@ -0,0 +1,57 @@ +abc = ["A", "B", "C"] + + +def create(n): + print() + # print(n) + list = [] + create_rec(0, n, list) + + return sorted(list) + + +def create_rec(k, n, list): + # print("k:", k, "n:", n) + if k == n: + # print(list) + return + elif k == 0: + for x in range(3**n): + if x < (1 / 3) * 3**n: + list.append("A") + elif x < (2 / 3) * 3**n: + list.append("B") + else: + list.append("C") + create_rec(1, n, list) + + else: + repeating = 3**n / (3 ** (k + 1)) + round = 0 + i = repeating + # print("repeat amount:", repeating) + + for x in range(len(list)): + + if round % 3 == 0: + char = "A" + elif round % 3 == 1: + char = "B" + else: + char = "C" + + if i % repeating == 0: + round += 1 + # print("round:", round, "- i", i, "--- char:", char) + i += 1 + + list[x] += char + + create_rec(k + 1, n, list) + + +if __name__ == "__main__": + print(create(1)) # [A,B,C] + print(create(2)) # [AA,AB,AC,BA,BB,BC,CA,CB,CC] + print(create(3)) # [AAA, AAB, AAC, ABA, ABB, ABC, ACA, ACB, ACC, BAA, BAB, BAC ...] + # print(len(create(5))) # 243 diff --git a/viikko8/anagrams.py b/viikko8/anagrams.py new file mode 100644 index 0000000..9ee2f3e --- /dev/null +++ b/viikko8/anagrams.py @@ -0,0 +1,32 @@ +def create(s): + global not_used, result + not_used = [] + result = [] + not_used = [x for x in s] + haku(0, len(s), sorted(s)) + print() + return sorted(result) + + +def haku(k, n, s): + print(s, not_used) + list = [] + + if k == n: + print(list) + result.append("".join(list)) + else: + for i, x in enumerate(s): + + if x not in not_used: + not_used.remove(x) + list.append(x) + + haku(k + 1, n, s) + + +if __name__ == "__main__": + print(create("ab")) # [ab,ba] + print(create("abac")) + # [aabc,aacb,abac,abca,acab,acba,baac,baca,bcaa,caab,caba,cbaa] + print(len(create("aybabtu"))) # 1260 diff --git a/viikko8/count_recursion.py b/viikko8/count_recursion.py new file mode 100644 index 0000000..79f47fe --- /dev/null +++ b/viikko8/count_recursion.py @@ -0,0 +1,15 @@ +def f(n): + global count + count += 1 + if n <= 2: + return n + return f(n - 1) + f(n - 2) + f(n - 3) + + +if __name__ == "__main__": + count = 0 + f(10) + print(count) + count = 0 + f(30) + print(count) diff --git a/viikko8/number.py b/viikko8/number.py new file mode 100644 index 0000000..1b0ec75 --- /dev/null +++ b/viikko8/number.py @@ -0,0 +1,22 @@ +def count(n): + print() + result = 0 + + for x in reversed(range(1, n + 1)): + remainder = n - x + print("x:", x, "remainder:", remainder) + + for y in range(x + 1, remainder + 1): + print("remainder:", y) + continue + + result += 1 + + return result + + +if __name__ == "__main__": + print(count(4)) # 5 + print(count(5)) # 7 + print(count(8)) # 22 + # print(count(42)) # 53174 diff --git a/viikko8/partition.py b/viikko8/partition.py new file mode 100644 index 0000000..3522c9d --- /dev/null +++ b/viikko8/partition.py @@ -0,0 +1,95 @@ +def check(t): + print() + sum = 0 + for x in t: + sum += x + + # odd sum cannot be divided by two + if sum % 2 != 0: + print(t, sum) + print("sum odd") + return False + + # for ease + t.sort() + print(t, sum) + + # count the half, or the closest thing to it + half = 0 + close_to_half_list = [] + i = len(t) - 1 + while half < sum // 2: + half += t[i] + close_to_half_list.append(t[i]) + i -= 1 + + # half is already half of the sum == is possible to + # halve the sum_list + if half == sum // 2: + print(half, "==", sum // 2) + return True + + # remove the overgoing sum value + half -= close_to_half_list.pop() + print(close_to_half_list) + + # number we need to be == half + needed_sum = sum // 2 - half + print(needed_sum) + + # if needed sum is already somewhere in the + # sum_list and is not already used for making the half + if needed_sum in t and needed_sum not in close_to_half_list: + return True + + # for i, x in enumerate(t): + # if x > needed_sum: + # continue + # if x in close_to_half_list: + # continue + # for j, y in enumerate(t): + # # print(x, "+", y, "=", x + y, "==", needed_sum) + # if y + x == needed_sum: + # # print(" ****** THIS ******* ") + # if y not in close_to_half_list and i != j: + # return True + + global result, sum_list + result = set() + sum_list = set() + find_sum_rec(0, len(t), t) + print("result", result) + + # for x in result: + # print(x) + + return False + + +def find_sum_rec(k, n, t): + global sum_list + print(k, n) + + if k == n: + print("dict", sum_list) + # result.add(frozenset(sum_list)) + # sum_list = set() + else: + for x in range(0, 2): + print("k,x", k, x) + if x != 0: + sum_list.add(t[k]) + print("sum_list", sum_list) + find_sum_rec(k + 1, n, t) + + +if __name__ == "__main__": + # print(check([3, 4, 5])) # False doenst work + # print(check([16, 8, 4, 4])) # True + # print(check([9, 4, 8, 7, 6])) # True + # print(check([1, 2, 3, 4, 5, 6])) # False + # print(check([1, 2, 3, 4, 5, 6, 7])) # True doesnt work + # print(check([4, 4, 4, 6, 6])) # True + # print(check([10, 27, 15, 6, 17, 22, 1, 22])) # True + # print(check([10, 4, 9, 1])) # False + print(check([30, 8, 28, 11, 4, 16, 10, 3])) # True diff --git a/viikko8/recursion.py b/viikko8/recursion.py new file mode 100644 index 0000000..676fba8 --- /dev/null +++ b/viikko8/recursion.py @@ -0,0 +1,18 @@ +from time import time + + +def f(n): + if n <= 2: + return n + return f(n - 1) + f(n - 2) + f(n - 3) + + +if __name__ == "__main__": + start = time() + print(f(10)) + end = time() + print(end - start) + start = time() + print(f(30)) + end = time() + print(end - start) diff --git a/viikko9/anagrams.py b/viikko9/anagrams.py new file mode 100644 index 0000000..0d21ee0 --- /dev/null +++ b/viikko9/anagrams.py @@ -0,0 +1,11 @@ +import itertools + + +def create(s): + return sorted("".join(x) for x in {i for i in itertools.permutations(s)}) + +if __name__ == "__main__": + print(create("abc")) # ['abc', 'acb', 'bac', 'bca', 'cab', 'cba'] + print(create("aaaaa")) # ['aaaaa'] + print(create("abab")) # ['aabb', 'abab', 'abba', 'baab', 'baba', 'bbaa'] + # print(len(create("aybabtu"))) # 1260 diff --git a/viikko9/brackets.py b/viikko9/brackets.py new file mode 100644 index 0000000..6acd893 --- /dev/null +++ b/viikko9/brackets.py @@ -0,0 +1,36 @@ +import itertools + + +def count(n, k): + bracket_count = 0 + + for i in itertools.product("()", repeat=n): + if check_brackets(i, k): + bracket_count += 1 + + return bracket_count + +def check_brackets(i: [str], k): + bracket_equality = 0 + for char in i: + match char: + case "(": + bracket_equality += 1 + case ")": + bracket_equality -= 1 + if bracket_equality < 0: + return False + + if bracket_equality > k: + return False + + return True if bracket_equality == 0 else False + + + +if __name__ == "__main__": + print(count(6, 1)) # 1 + print(count(6, 2)) # 4 + print(count(6, 3)) # 5 + print(count(9, 1)) # 0 + print(count(16, 4)) # 1094 diff --git a/viikko9/fastcoin.py b/viikko9/fastcoin.py new file mode 100644 index 0000000..9acaa18 --- /dev/null +++ b/viikko9/fastcoin.py @@ -0,0 +1,25 @@ +import itertools + +coins = [1, 2, 5] + +def count(x): + amount = x + used_coins = 0 + + if amount // 5 > 0: + used_coins += amount // 5 + amount %= 5 + + if amount // 2 > 0: + used_coins += amount // 2 + amount %= 2 + + if amount == 1: + used_coins += 1 + + return used_coins + +if __name__ == "__main__": + print(count(13)) # 4 + print(count(12345)) # 2469 + print(count(1337**9)) # 2730314408854633746890878156 diff --git a/viikko9/getsum.py b/viikko9/getsum.py new file mode 100644 index 0000000..a798f0c --- /dev/null +++ b/viikko9/getsum.py @@ -0,0 +1,26 @@ +from itertools import combinations + +def count(n, k, x): + # n = [1...n] of numbers + # k = how many numbers + # x = the wanted sum + + list_n = [num for num in range(1,n + 1)] + count_sums = 0 + + for i in combinations(list_n, k): + if sum(i) == x: + count_sums += 1 + + # return none if no sums cannot be made = not implemented yet + return count_sums + +if __name__ == "__main__": + print(count(1, 1, 1)) # 1 + print(count(5, 2, 6)) # 2 + print(count(8, 3, 12)) # 6 + print(count(10, 4, 20)) # 16 + + # 1, 2, 3, 4, 5 + # all of the 2-len tuples that produce the sum 6 + # len((x+y) = 6) = 2 diff --git a/viikko9/oddlist.py b/viikko9/oddlist.py new file mode 100644 index 0000000..190a657 --- /dev/null +++ b/viikko9/oddlist.py @@ -0,0 +1,58 @@ +import itertools + +def count(n, x): + list_n = [i for i in range(1, n+1)] + list_count = 0 + + for i in itertools.permutations(list_n): + if i[0] != x: + continue + if check_sums(i): + list_count += 1 + + return list_count + +def alternate_check_sums(permutation): + prev_sum = 0 + prev_num = None + for i in permutation: + if prev_num == None: + prev_num = i + continue + if prev_sum == prev_num + i: + return False + + print(prev_sum, prev_num+i) + prev_sum = prev_num + i + prev_num = i + return True + +def check_sums(permutation): + print() + print(permutation) + for i in range(0, len(permutation), 2): + print("i:", i) + # needed if the n is uneven + if len(permutation) - i < 2: + print("Got to the end, breaking freeee") + break + if i == 0: + prev_sum = permutation[i] + permutation[i+1] + print("No previous sum, it is now", prev_sum) + continue + + if prev_sum == permutation[i] + permutation[i+1]: + print("Previous sum was the same D:, returning False", prev_sum, permutation[i] + permutation[i+1]) + return False + + print("Old prev_sum:", prev_sum, "New prev_sum:", permutation[i] + permutation[i+1]) + prev_sum = permutation[i] + permutation[i+1] + + return True + + +if __name__ == "__main__": + print(count(1, 1)) # 1 + print(count(4, 2)) # 4 + print(count(5, 1)) # 10 + # print(count(8, 5)) # 830 diff --git a/viikko9/subsets.py b/viikko9/subsets.py new file mode 100644 index 0000000..26a516a --- /dev/null +++ b/viikko9/subsets.py @@ -0,0 +1,23 @@ +import itertools + + +def create(t): + subsets = [] + for x in range(len(t) + 1): + for i in itertools.combinations(t, x): + subsets.append(i) + + sums = [] + for i in subsets: + sums.append(sum(i)) + + sums.sort() + + return sums + + +if __name__ == "__main__": + print(create([1, 2, 3])) # [0, 1, 2, 3, 3, 4, 5, 6] + print(create([42, 1337])) # [0, 42, 1337, 1379] + print(create([1, 1, 1])) # [0, 1, 1, 1, 2, 2, 2, 3] + print(create([5])) # [0, 5]