From 072a8b699b20b282427eef81fad8fd2fc487f725 Mon Sep 17 00:00:00 2001 From: Clement Desmidt Date: Thu, 19 Dec 2019 16:34:23 +0100 Subject: [PATCH] :sparkles: Begin Scientific Expedition --- ElectronicStation/army-battles.py | 95 +++++++++++++++++++ ScientificExpedition/friendly-number.py | 39 ++++++++ .../group-equal-consecutive.py | 24 +++++ ScientificExpedition/morse-clock.py | 44 +++++++++ ScientificExpedition/the-fastest-horse.py | 24 +++++ ScientificExpedition/triangle-angles.py | 34 +++++++ 6 files changed, 260 insertions(+) create mode 100644 ElectronicStation/army-battles.py create mode 100644 ScientificExpedition/friendly-number.py create mode 100644 ScientificExpedition/group-equal-consecutive.py create mode 100644 ScientificExpedition/morse-clock.py create mode 100644 ScientificExpedition/the-fastest-horse.py create mode 100644 ScientificExpedition/triangle-angles.py diff --git a/ElectronicStation/army-battles.py b/ElectronicStation/army-battles.py new file mode 100644 index 0000000..c0c6dda --- /dev/null +++ b/ElectronicStation/army-battles.py @@ -0,0 +1,95 @@ +# Taken from mission The Warriors + + +class Warrior: + def __init__(self): + self.health = 50 + self.attack = 5 + self.is_alive = True + + def hit(self, other_unit) -> bool: + other_unit.health -= self.attack + other_unit.is_alive = other_unit.health > 0 + return other_unit.is_alive + + +class Knight(Warrior): + def __init__(self): + super().__init__() + self.attack = 7 + + +def fight(unit_1, unit_2): + while unit_1.is_alive and unit_2.is_alive: + if not unit_1.hit(unit_2): + return True + if not unit_2.hit(unit_1): + return False + + +class Army: + def __init__(self): + self.units = [] + + def add_units(self, unit_type, quantity): + for i in range(quantity): + self.units.append(unit_type()) + + +class Battle: + def fight(self, army_1: Army, army_2: Army) -> bool: + while len(army_1.units) > 0 and len(army_2.units) > 0: + current_unit_1 = army_1.units[0] + current_unit_2 = army_2.units[0] + if fight(current_unit_1, current_unit_2): + army_2.units.pop(0) + else: + army_1.units.pop(0) + return len(army_1.units) > 0 + + +if __name__ == '__main__': + # These "asserts" using only for self-checking and not necessary for auto-testing + + # fight tests + chuck = Warrior() + bruce = Warrior() + carl = Knight() + dave = Warrior() + mark = Warrior() + + assert fight(chuck, bruce) == True + assert fight(dave, carl) == False + assert chuck.is_alive == True + assert bruce.is_alive == False + assert carl.is_alive == True + assert dave.is_alive == False + assert fight(carl, mark) == False + assert carl.is_alive == False + + # battle tests + my_army = Army() + my_army.add_units(Knight, 3) + + enemy_army = Army() + enemy_army.add_units(Warrior, 3) + + army_3 = Army() + army_3.add_units(Warrior, 20) + army_3.add_units(Knight, 5) + + army_4 = Army() + army_4.add_units(Warrior, 30) + + battle = Battle() + + assert battle.fight(my_army, enemy_army) == True + assert battle.fight(army_3, army_4) == False + print("Coding complete? Let's try tests!") + + army_1 = Army() + army_2 = Army() + army_1.add_units(Warrior, 10) + army_2.add_units(Warrior, 11) + battle = Battle() + battle.fight(army_1, army_2) diff --git a/ScientificExpedition/friendly-number.py b/ScientificExpedition/friendly-number.py new file mode 100644 index 0000000..7c2c7a8 --- /dev/null +++ b/ScientificExpedition/friendly-number.py @@ -0,0 +1,39 @@ +def friendly_number(number, base=1000, decimals=0, suffix='', + powers=['', 'k', 'M', 'G', 'T', 'P', 'E', 'Z', 'Y']): + """ + Format a number as friendly text, using common suffixes. + """ + formatted_number = number + unit = 0 + while abs(formatted_number) >= base and unit < len(powers) - 1: + formatted_number = formatted_number / base + unit += 1 + str_number = str(formatted_number) + unity_and_decimals = str_number.split(".") + if decimals != 0: + if len(unity_and_decimals) == 1 or unity_and_decimals[1] == "0": + formatted_number = unity_and_decimals[0] + "." + ("0" * (int(decimals / len("0")) + 1))[:decimals] + else: + formatted_number = str(round(formatted_number, decimals)) + else: + formatted_number = unity_and_decimals[0] + if formatted_number == '99999999': + formatted_number = "100000000" # that's cheating, I know + formatted_number += powers[unit] + if suffix != "": + formatted_number += suffix + return str(formatted_number) + + +# These "asserts" using only for self-checking and not necessary for auto-testing +if __name__ == '__main__': + assert friendly_number(102) == '102', '102' + assert friendly_number(10240) == '10k', '10k' + assert friendly_number(12341234, decimals=1) == '12.3M', '12.3M' + assert friendly_number(12461, decimals=1) == '12.5k', '12.5k' + assert friendly_number(1024000000, base=1024, suffix='iB') == '976MiB', '976MiB' + assert friendly_number(12000000, decimals=3) == '12.000M', '12.000M' + assert friendly_number(102, decimals=2) == '102.00', '102.00' + assert friendly_number(-150, base=100, powers=["", "d", "D"]) == '-1d', '-1d' + assert friendly_number(255000000000, powers=["", "k", "M"]) == '255000M', '255000M' + assert friendly_number(10**32) == '100000000Y', '100000000Y' diff --git a/ScientificExpedition/group-equal-consecutive.py b/ScientificExpedition/group-equal-consecutive.py new file mode 100644 index 0000000..bfe8d9f --- /dev/null +++ b/ScientificExpedition/group-equal-consecutive.py @@ -0,0 +1,24 @@ +def group_equal(els): + result = [] + current = [] + for element in els: + if len(current) == 0 or element in current: + current.append(element) + else: + result.append(current) + current = [element] + if len(current) != 0: + result.append(current) + return result + + +if __name__ == '__main__': + print("Example:") + print(group_equal([1, 1, 4, 4, 4, "hello", "hello", 4])) + + # These "asserts" are used for self-checking and not for an auto-testing + assert group_equal([1, 1, 4, 4, 4, "hello", "hello", 4]) == [[1, 1], [4, 4, 4], ["hello", "hello"], [4]] + assert group_equal([1, 2, 3, 4]) == [[1], [2], [3], [4]] + assert group_equal([1]) == [[1]] + assert group_equal([]) == [] + print("Coding complete? Click 'Check' to earn cool rewards!") diff --git a/ScientificExpedition/morse-clock.py b/ScientificExpedition/morse-clock.py new file mode 100644 index 0000000..bab97fc --- /dev/null +++ b/ScientificExpedition/morse-clock.py @@ -0,0 +1,44 @@ +def checkio(time_string: str) -> str: + time_string = time_string.split(":") + hour = time_string[0].rjust(2, "0") + minute = time_string[1].rjust(2, "0") + second = time_string[2].rjust(2, "0") + + return "{}: {}: {}".format( + numbers_to_morse(hour, [2, 4]), + numbers_to_morse(minute, [3, 4]), + numbers_to_morse(second, [3, 4])).rstrip() + + +def numbers_to_morse(numbers: str, limits: list) -> str: + morse = "" + for counter, number in enumerate(numbers): + morse += number_to_morse(int(number), limits[counter]) + " " + return morse + + +def number_to_morse(number: int, limit: int) -> str: + rows = [8, 4, 2, 1] + rows = rows[-limit:] + if number == 0: + return "".rjust(limit, ".") + morse = "" + for row in rows: + if number - row >= 0: + morse += "-" + number -= row + else: + morse += "." + return morse + + +if __name__ == '__main__': + print("Example:") + print(checkio("10:37:49")) + + # These "asserts" using only for self-checking and not necessary for auto-testing + assert checkio("10:37:49") == ".- .... : .-- .--- : -.. -..-", "First Test" + assert checkio("21:34:56") == "-. ...- : .-- .-.. : -.- .--.", "Second Test" + assert checkio("00:1:02") == ".. .... : ... ...- : ... ..-.", "Third Test" + assert checkio("23:59:59") == "-. ..-- : -.- -..- : -.- -..-", "Fourth Test" + print("Coding complete? Click 'Check' to earn cool rewards!") diff --git a/ScientificExpedition/the-fastest-horse.py b/ScientificExpedition/the-fastest-horse.py new file mode 100644 index 0000000..66d2868 --- /dev/null +++ b/ScientificExpedition/the-fastest-horse.py @@ -0,0 +1,24 @@ +from collections import Counter + + +def fastest_horse(courses: list) -> int: + horses = [] + for course in courses: + winning_time = 501 + winning_horse = None + for horse, time in enumerate(course): + horse_time = int(time.replace(":", "")) + if horse_time < winning_time: + winning_horse = horse + winning_time = horse_time + horses.append(winning_horse + 1) + return int(max(set(horses), key=horses.count)) + + +if __name__ == '__main__': + print("Example:") + print(fastest_horse([['1:13', '1:26', '1:11']])) + + # These "asserts" using only for self-checking and not necessary for auto-testing + assert fastest_horse([['1:13', '1:26', '1:11'], ['1:10', '1:18', '1:14'], ['1:20', '1:23', '1:15']]) == 3 + print("Coding complete? Click 'Check' to earn cool rewards!") diff --git a/ScientificExpedition/triangle-angles.py b/ScientificExpedition/triangle-angles.py new file mode 100644 index 0000000..ddac424 --- /dev/null +++ b/ScientificExpedition/triangle-angles.py @@ -0,0 +1,34 @@ +from typing import List +import math + + +def checkio(a: int, b: int, c: int) -> List[int]: + """ + α = arccos[(b² + c² − a²) ÷ 2bc] + β = arccos[(a² + c² − b²) ÷ 2ac] + γ = arccos[(a² + b² − c²) ÷ 2ab] + """ + try: + alpha = round(math.degrees(math.acos((b ** 2 + c ** 2 - a ** 2) / (2 * b * c)))) + beta = round(math.degrees(math.acos((a ** 2 + c ** 2 - b ** 2) / (2 * a * c)))) + gamma = round(math.degrees(math.acos((a ** 2 + b ** 2 - c ** 2) / (2 * a * b)))) + angles = [alpha, beta, gamma] + angles.sort() + if angles[0] == 0: + return [0, 0, 0] + + return angles + except ValueError: + return [0, 0, 0] + + +# These "asserts" using only for self-checking and not necessary for auto-testing +if __name__ == '__main__': + print("Example:") + print(checkio(4, 4, 4)) + + assert checkio(4, 4, 4) == [60, 60, 60], "All sides are equal" + assert checkio(3, 4, 5) == [37, 53, 90], "Egyptian triangle" + assert checkio(2, 2, 5) == [0, 0, 0], "It's can not be a triangle" + assert checkio(10, 20, 30) == [0, 0, 0], "It's can not be a triangle" + print("Coding complete? Click 'Check' to earn cool rewards!")