From 268fda0a6bd99aea4da4bbca7566579b72524f08 Mon Sep 17 00:00:00 2001 From: Edoardo Vergerio Date: Tue, 25 Aug 2026 11:08:53 +0200 Subject: [PATCH] added HW5_final with suggestion system and repo cleanup --- .gitignore | 4 + HW3/requirements.txt | 2 + HW4/requirements.txt | 3 + HW5/core.py | 12 +- HW5/dataset.csv | 441 --------------------------------- HW5/game_data.py | 2 +- HW5/hw5.py | 10 +- HW5/hw5_final.py | 571 +++++++++++++++++++++++++++++++++++++++++++ HW5/plots/tree_0.gv | 33 --- HW5/plots/tree_0.pdf | Bin 11840 -> 0 bytes HW5/plots/tree_1.gv | 33 --- HW5/plots/tree_1.pdf | Bin 11795 -> 0 bytes HW5/plots/tree_2.gv | 21 -- HW5/plots/tree_2.pdf | Bin 11123 -> 0 bytes HW5/requirements.txt | 6 + 15 files changed, 601 insertions(+), 537 deletions(-) create mode 100644 HW3/requirements.txt create mode 100644 HW4/requirements.txt delete mode 100644 HW5/dataset.csv create mode 100644 HW5/hw5_final.py delete mode 100644 HW5/plots/tree_0.gv delete mode 100644 HW5/plots/tree_0.pdf delete mode 100644 HW5/plots/tree_1.gv delete mode 100644 HW5/plots/tree_1.pdf delete mode 100644 HW5/plots/tree_2.gv delete mode 100644 HW5/plots/tree_2.pdf create mode 100644 HW5/requirements.txt diff --git a/.gitignore b/.gitignore index 7dee432..00048f7 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,7 @@ HW3/results HW4/results HW5/results +HW5/plots +HW5/plots/* +HW5/dataset.csv +HW5/trained_model.joblib diff --git a/HW3/requirements.txt b/HW3/requirements.txt new file mode 100644 index 0000000..ff211f0 --- /dev/null +++ b/HW3/requirements.txt @@ -0,0 +1,2 @@ +numpy>=1.24.0 +matplotlib>=3.5.0 diff --git a/HW4/requirements.txt b/HW4/requirements.txt new file mode 100644 index 0000000..9889646 --- /dev/null +++ b/HW4/requirements.txt @@ -0,0 +1,3 @@ +numpy>=1.24.0 +matplotlib>=3.5.0 +pandas>=2.0.0 diff --git a/HW5/core.py b/HW5/core.py index 6c03f8f..558cd6b 100644 --- a/HW5/core.py +++ b/HW5/core.py @@ -78,7 +78,7 @@ class Pokemon: break return effect - def _useMove(self, move, opponent): + def _useMove(self, move, opponent, game_status = None): if random.random() < move['accuracy']: if move['category'] == 'physical': attack = self.ActStats['attack'] @@ -97,17 +97,19 @@ class Pokemon: opponent.curr_hp -= damage if opponent.curr_hp < 0: opponent.curr_hp = 0 - #print(f"{self.name} used {move['name']} and dealt {damage} damage to {opponent.name}!") + if not game_status == 'new_random_battle': + print(f"{self.name} used {move['name']} and dealt {damage} damage to {opponent.name}!") else: damage = 0 - #print(f"{self.name}'s attack missed!") + if not game_status == 'new_random_battle': + print(f"{self.name}'s attack missed!") return damage - def useMove(self, move_name, opponent): + def useMove(self, move_name, opponent, game_status = None): if move_name not in self.moves_dict: raise ValueError(f"{self.name} does not know the move {move_name}.") else: - return self._useMove(self.moves_dict[move_name], opponent) + return self._useMove(self.moves_dict[move_name], opponent, game_status) def print_move(self,move): print(f"Move: {self.moves_dict[move]['name']}") diff --git a/HW5/dataset.csv b/HW5/dataset.csv deleted file mode 100644 index b13a285..0000000 --- a/HW5/dataset.csv +++ /dev/null @@ -1,441 +0,0 @@ -player_hp,player_attack,player_defense,player_speed,player_special,player_type_normal,player_type_fire,player_type_water,player_type_electric,player_type_grass,player_type_ice,player_type_fighting,player_type_poison,player_type_ground,player_type_flying,player_type_psychic,player_type_bug,player_type_rock,player_type_ghost,player_type_dragon,opponent_hp,opponent_attack,opponent_defense,opponent_speed,opponent_special,opponent_type_normal,opponent_type_fire,opponent_type_water,opponent_type_electric,opponent_type_grass,opponent_type_ice,opponent_type_fighting,opponent_type_poison,opponent_type_ground,opponent_type_flying,opponent_type_psychic,opponent_type_bug,opponent_type_rock,opponent_type_ghost,opponent_type_dragon,battle_result -32,15,26,18,33,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,56,33,29,51,31,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 -32,15,26,18,33,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,34,30,28,22,20,0,0,1,0,0,0,0,0,0,0,0,0,1,0,0,1 -32,15,26,18,33,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,20,12,10,11,11,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1 -32,15,26,18,33,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,20,12,9,11,10,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1 -32,15,26,18,33,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,12,6,6,7,7,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,1 -27,17,13,16,13,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,62,45,33,23,25,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0 -27,17,13,16,13,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,49,20,23,20,28,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0 -27,17,13,16,13,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,12,6,6,6,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1 -27,17,13,16,13,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,36,22,20,14,27,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0 -27,17,13,16,13,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,21,11,12,16,14,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,1 -36,27,31,14,16,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,42,25,23,28,24,0,0,0,0,0,0,0,1,0,1,0,0,0,0,0,1 -36,27,31,14,16,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,52,25,23,53,59,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,1 -36,27,31,14,16,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,32,9,17,11,10,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1 -36,27,31,14,16,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,24,11,11,15,15,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1 -36,27,31,14,16,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,47,20,22,28,32,0,0,0,0,0,0,0,0,0,1,0,1,0,0,0,1 -42,21,20,22,21,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,26,14,12,16,14,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1 -42,21,20,22,21,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,44,30,16,18,28,0,0,0,0,1,0,0,1,0,0,0,0,0,0,0,0 -42,21,20,22,21,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,23,16,18,9,10,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,1 -42,21,20,22,21,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,17,9,8,12,8,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,1 -42,21,20,22,21,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,31,13,13,11,15,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1 -22,17,19,13,12,0,0,1,0,0,0,0,0,0,0,0,0,1,0,0,22,13,9,14,9,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1 -22,17,19,13,12,0,0,1,0,0,0,0,0,0,0,0,0,1,0,0,54,22,29,14,24,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 -22,17,19,13,12,0,0,1,0,0,0,0,0,0,0,0,0,1,0,0,26,16,12,14,13,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1 -22,17,19,13,12,0,0,1,0,0,0,0,0,0,0,0,0,1,0,0,28,19,13,13,18,0,0,0,0,1,0,0,1,0,0,0,0,0,0,0,1 -22,17,19,13,12,0,0,1,0,0,0,0,0,0,0,0,0,1,0,0,51,31,31,30,37,0,0,0,0,1,0,0,1,0,0,0,0,0,0,0,0 -42,22,23,15,30,0,0,0,0,1,0,0,1,0,0,0,0,0,0,0,25,13,12,20,23,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0,0 -42,22,23,15,30,0,0,0,0,1,0,0,1,0,0,0,0,0,0,0,42,23,23,30,19,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,1 -42,22,23,15,30,0,0,0,0,1,0,0,1,0,0,0,0,0,0,0,28,16,15,17,14,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1 -42,22,23,15,30,0,0,0,0,1,0,0,1,0,0,0,0,0,0,0,20,9,14,11,18,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1 -42,22,23,15,30,0,0,0,0,1,0,0,1,0,0,0,0,0,0,0,28,19,15,21,14,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1 -38,27,20,14,16,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,11,6,5,6,5,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,1 -38,27,20,14,16,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,24,15,11,17,9,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1 -38,27,20,14,16,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,49,35,28,30,30,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1 -38,27,20,14,16,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,51,34,25,42,35,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0 -38,27,20,14,16,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,28,17,13,15,14,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1 -16,8,8,12,11,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,21,14,10,10,13,0,0,0,0,1,0,0,1,0,0,0,0,0,0,0,0 -16,8,8,12,11,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,40,32,39,11,15,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0 -16,8,8,12,11,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,50,37,40,25,22,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0 -16,8,8,12,11,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,35,23,17,28,23,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0 -16,8,8,12,11,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,21,13,10,15,13,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1 -36,16,15,15,26,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,28,7,19,25,10,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,1 -36,16,15,15,26,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,17,11,8,12,8,0,0,0,0,0,0,0,0,0,1,0,0,1,0,0,1 -36,16,15,15,26,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,53,36,26,44,37,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0 -36,16,15,15,26,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,15,8,9,6,8,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,1 -36,16,15,15,26,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,38,21,31,24,38,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1 -27,14,18,8,14,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,47,30,23,17,20,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0 -27,14,18,8,14,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,33,16,15,19,14,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1 -27,14,18,8,14,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,52,30,29,34,27,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0 -27,14,18,8,14,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,42,29,32,17,14,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0 -27,14,18,8,14,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,38,33,37,24,21,0,0,1,0,0,0,0,0,0,0,0,0,1,0,0,0 -38,21,17,33,17,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,37,29,15,26,15,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1 -38,21,17,33,17,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,49,29,28,30,29,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0 -38,21,17,33,17,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,36,31,21,29,19,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0 -38,21,17,33,17,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,19,9,10,8,11,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1 -38,21,17,33,17,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,49,32,28,30,27,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,1 -14,7,7,6,8,0,0,0,0,1,0,0,1,0,0,0,0,0,0,0,46,30,23,25,25,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0 -14,7,7,6,8,0,0,0,0,1,0,0,1,0,0,0,0,0,0,0,51,23,17,39,39,0,0,0,0,0,1,0,0,0,0,1,0,0,0,0,0 -14,7,7,6,8,0,0,0,0,1,0,0,1,0,0,0,0,0,0,0,54,32,33,32,39,0,0,0,0,1,0,0,1,0,0,0,0,0,0,0,0 -14,7,7,6,8,0,0,0,0,1,0,0,1,0,0,0,0,0,0,0,14,7,7,10,8,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1 -14,7,7,6,8,0,0,0,0,1,0,0,1,0,0,0,0,0,0,0,27,11,17,11,14,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0 -22,15,14,16,12,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,40,21,22,14,29,0,0,0,0,1,0,0,1,0,0,0,0,0,0,0,0 -22,15,14,16,12,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,35,23,31,14,21,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0 -22,15,14,16,12,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,38,15,16,13,19,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1 -22,15,14,16,12,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,40,33,22,17,19,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0 -22,15,14,16,12,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,46,24,27,17,29,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 -51,37,23,24,35,0,0,0,0,1,0,0,1,0,0,0,0,0,0,0,23,20,12,12,18,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1 -51,37,23,24,35,0,0,0,0,1,0,0,1,0,0,0,0,0,0,0,37,30,19,27,19,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1 -51,37,23,24,35,0,0,0,0,1,0,0,1,0,0,0,0,0,0,0,59,44,29,54,27,0,0,0,0,0,0,0,0,0,1,0,0,1,0,0,0 -51,37,23,24,35,0,0,0,0,1,0,0,1,0,0,0,0,0,0,0,31,15,14,12,16,0,0,1,0,0,1,0,0,0,0,0,0,0,0,0,1 -51,37,23,24,35,0,0,0,0,1,0,0,1,0,0,0,0,0,0,0,23,11,13,21,14,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1 -23,10,11,13,14,0,0,0,0,0,0,0,0,0,1,0,1,0,0,0,42,35,62,27,32,0,0,1,0,0,1,0,0,0,0,0,0,0,0,0,0 -23,10,11,13,14,0,0,0,0,0,0,0,0,0,1,0,1,0,0,0,46,29,20,15,15,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0 -23,10,11,13,14,0,0,0,0,0,0,0,0,0,1,0,1,0,0,0,56,42,28,30,41,0,0,0,0,1,0,0,1,0,0,0,0,0,0,0,0 -23,10,11,13,14,0,0,0,0,0,0,0,0,0,1,0,1,0,0,0,46,37,27,38,30,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0 -23,10,11,13,14,0,0,0,0,0,0,0,0,0,1,0,1,0,0,0,35,17,14,30,16,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 -43,17,29,17,23,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,48,44,35,33,18,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0 -43,17,29,17,23,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,49,36,24,26,35,0,0,0,0,1,0,0,1,0,0,0,0,0,0,0,1 -43,17,29,17,23,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,18,9,9,8,8,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,1 -43,17,29,17,23,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,32,27,30,20,17,0,0,1,0,0,0,0,0,0,0,0,0,1,0,0,0 -43,17,29,17,23,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,15,7,7,9,9,0,0,1,0,0,0,0,1,0,0,0,0,0,0,0,1 -48,27,21,25,21,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,15,8,8,8,7,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1 -48,27,21,25,21,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,47,31,26,36,41,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,1 -48,27,21,25,21,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,51,41,30,42,33,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0 -48,27,21,25,21,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,36,18,29,14,15,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1 -48,27,21,25,21,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,38,21,20,25,21,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1 -24,11,10,19,23,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0,25,17,12,20,12,0,0,0,0,0,0,0,0,0,1,0,0,1,0,0,1 -24,11,10,19,23,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0,36,18,24,10,19,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,1 -24,11,10,19,23,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0,52,32,30,35,42,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0 -24,11,10,19,23,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0,24,12,10,19,11,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1 -24,11,10,19,23,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0,46,31,28,28,37,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,1 -17,9,9,10,9,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,44,37,66,28,33,0,0,1,0,0,1,0,0,0,0,0,0,0,0,0,0 -17,9,9,10,9,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,38,14,15,18,11,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0 -17,9,9,10,9,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,62,30,31,26,35,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 -17,9,9,10,9,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,40,13,11,41,47,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0 -17,9,9,10,9,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,18,11,11,14,13,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,1 -19,11,14,8,11,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,25,14,13,20,23,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0,0 -19,11,14,8,11,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,16,8,8,7,7,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,1 -19,11,14,8,11,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,42,19,14,31,31,0,0,0,0,0,1,0,0,0,0,1,0,0,0,0,0 -19,11,14,8,11,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,42,21,17,24,19,0,0,0,0,0,0,0,1,0,1,0,0,0,0,0,0 -19,11,14,8,11,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,32,25,18,36,23,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1 -51,20,14,14,16,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,38,20,59,28,15,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0 -51,20,14,14,16,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,45,23,23,22,34,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,1 -51,20,14,14,16,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,37,32,35,23,20,0,0,1,0,0,0,0,0,0,0,0,0,1,0,0,0 -51,20,14,14,16,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,23,15,12,9,10,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1 -51,20,14,14,16,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,42,23,19,37,19,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,1 -16,9,10,7,6,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,53,41,38,16,17,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0 -16,9,10,7,6,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,24,12,11,21,23,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,1 -16,9,10,7,6,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,30,17,13,9,11,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0 -16,9,10,7,6,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,22,15,14,8,8,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0 -16,9,10,7,6,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,44,42,35,30,21,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0 -50,20,21,16,25,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,22,9,9,19,21,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,1 -50,20,21,16,25,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,16,6,6,12,13,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,1 -50,20,21,16,25,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,41,20,37,19,34,0,0,1,0,0,0,0,0,0,0,0,0,1,0,0,0 -50,20,21,16,25,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,43,26,25,29,35,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0 -50,20,21,16,25,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,14,8,7,8,7,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1 -38,23,22,27,23,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,40,20,16,35,18,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1 -38,23,22,27,23,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,17,9,9,7,11,0,0,0,0,1,0,0,1,0,0,0,0,0,0,0,1 -38,23,22,27,23,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,29,17,15,16,14,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1 -38,23,22,27,23,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,40,31,27,13,27,0,0,0,0,1,0,0,0,0,0,0,1,0,0,0,1 -38,23,22,27,23,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,28,20,14,21,16,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1 -26,14,12,21,12,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,46,28,27,31,37,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0 -26,14,12,21,12,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,61,38,36,45,39,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0 -26,14,12,21,12,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,16,9,8,11,10,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1 -26,14,12,21,12,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,38,23,19,21,19,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0 -26,14,12,21,12,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,54,31,33,21,39,0,0,0,0,1,0,0,1,0,0,0,0,0,0,0,0 -20,11,11,12,10,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,22,14,9,9,13,0,0,0,0,1,0,0,1,0,0,0,0,0,0,0,1 -20,11,11,12,10,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,18,9,7,6,7,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1 -20,11,11,12,10,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,29,16,16,15,19,0,0,0,0,1,0,0,1,0,0,0,0,0,0,0,1 -20,11,11,12,10,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,46,30,26,28,26,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,1 -20,11,11,12,10,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,12,5,5,5,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1 -28,13,27,12,24,0,0,1,0,0,0,0,0,0,0,0,0,1,0,0,45,22,22,22,22,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1 -28,13,27,12,24,0,0,1,0,0,0,0,0,0,0,0,0,1,0,0,46,26,20,24,20,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1 -28,13,27,12,24,0,0,1,0,0,0,0,0,0,0,0,0,1,0,0,42,21,28,37,41,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,1 -28,13,27,12,24,0,0,1,0,0,0,0,0,0,0,0,0,1,0,0,29,12,15,9,13,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1 -28,13,27,12,24,0,0,1,0,0,0,0,0,0,0,0,0,1,0,0,62,37,25,15,21,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0 -61,38,36,45,39,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,76,6,6,16,28,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1 -61,38,36,45,39,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,49,35,27,41,24,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1 -61,38,36,45,39,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,13,6,9,6,8,0,0,1,0,0,0,0,0,0,0,0,0,1,0,0,1 -61,38,36,45,39,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,21,18,11,11,16,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1 -61,38,36,45,39,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,12,6,6,6,6,0,0,0,0,0,0,0,1,0,1,0,0,0,0,0,1 -40,20,22,20,25,0,0,1,0,0,1,0,0,0,0,0,0,0,0,0,28,20,19,9,10,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0 -40,20,22,20,25,0,0,1,0,0,1,0,0,0,0,0,0,0,0,0,40,27,37,16,25,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1 -40,20,22,20,25,0,0,1,0,0,1,0,0,0,0,0,0,0,0,0,42,27,25,26,22,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0 -40,20,22,20,25,0,0,1,0,0,1,0,0,0,0,0,0,0,0,0,44,29,24,33,38,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,1 -40,20,22,20,25,0,0,1,0,0,1,0,0,0,0,0,0,0,0,0,37,20,17,32,17,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,1 -46,35,23,34,32,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,19,7,10,8,7,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,1 -46,35,23,34,32,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,51,20,35,20,27,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,1 -46,35,23,34,32,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,28,16,22,20,22,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,1 -46,35,23,34,32,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,32,26,20,17,21,0,0,0,0,0,0,0,0,0,1,0,0,0,0,1,1 -46,35,23,34,32,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,33,26,17,24,17,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1 -36,25,20,21,21,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,53,52,43,37,25,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1 -36,25,20,21,21,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,43,29,26,26,35,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,1 -36,25,20,21,21,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,33,20,12,23,13,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1 -36,25,20,21,21,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,15,7,7,10,7,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1 -36,25,20,21,21,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,45,20,22,18,18,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0 -30,18,16,17,16,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,49,29,29,29,35,0,0,0,0,1,0,0,1,0,0,0,0,0,0,0,0 -30,18,16,17,16,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,28,18,15,20,23,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,1 -30,18,16,17,16,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,53,27,31,20,33,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 -30,18,16,17,16,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,18,8,11,8,9,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,1 -30,18,16,17,16,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,41,24,23,25,24,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0 -29,16,16,15,19,0,0,0,0,1,0,0,1,0,0,0,0,0,0,0,46,28,33,26,28,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,1 -29,16,16,15,19,0,0,0,0,1,0,0,1,0,0,0,0,0,0,0,33,15,12,24,24,0,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1 -29,16,16,15,19,0,0,0,0,1,0,0,1,0,0,0,0,0,0,0,21,10,10,10,10,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1 -29,16,16,15,19,0,0,0,0,1,0,0,1,0,0,0,0,0,0,0,27,16,15,11,20,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,1 -29,16,16,15,19,0,0,0,0,1,0,0,1,0,0,0,0,0,0,0,38,27,21,24,21,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0 -25,12,12,12,12,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,44,23,21,39,46,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0,0 -25,12,12,12,12,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,44,11,23,15,13,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1 -25,12,12,12,12,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,18,9,12,11,12,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,1 -25,12,12,12,12,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,65,33,46,16,35,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0 -25,12,12,12,12,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,32,18,21,18,25,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,1 -17,8,9,8,8,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,56,31,29,57,49,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0 -17,8,9,8,8,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,43,22,28,20,23,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0 -17,8,9,8,8,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,23,14,12,13,12,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,1 -17,8,9,8,8,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,36,27,24,12,24,0,0,0,0,1,0,0,0,0,0,0,1,0,0,0,0 -17,8,9,8,8,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,21,10,12,10,11,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,1 -33,15,14,23,31,0,0,1,0,0,0,0,1,0,0,0,0,0,0,0,44,27,23,25,24,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0 -33,15,14,23,31,0,0,1,0,0,0,0,1,0,0,0,0,0,0,0,43,39,36,29,26,0,0,1,0,0,0,0,0,0,0,0,0,1,0,0,0 -33,15,14,23,31,0,0,1,0,0,0,0,1,0,0,0,0,0,0,0,22,15,16,11,10,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1 -33,15,14,23,31,0,0,1,0,0,0,0,1,0,0,0,0,0,0,0,33,24,28,13,14,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,1 -33,15,14,23,31,0,0,1,0,0,0,0,1,0,0,0,0,0,0,0,29,22,13,35,19,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1 -28,18,20,12,10,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,34,11,18,14,11,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0 -28,18,20,12,10,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,14,9,7,8,7,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1 -28,18,20,12,10,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,12,7,7,6,6,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1 -28,18,20,12,10,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,15,8,7,6,6,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1 -28,18,20,12,10,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,29,14,16,14,18,0,0,1,0,0,1,0,0,0,0,0,0,0,0,0,1 -38,21,21,20,25,0,0,0,0,1,0,0,1,0,0,0,0,0,0,0,29,10,7,7,8,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1 -38,21,21,20,25,0,0,0,0,1,0,0,1,0,0,0,0,0,0,0,49,28,25,44,27,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1 -38,21,21,20,25,0,0,0,0,1,0,0,1,0,0,0,0,0,0,0,18,10,10,9,9,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,1 -38,21,21,20,25,0,0,0,0,1,0,0,1,0,0,0,0,0,0,0,41,24,23,25,24,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,1 -38,21,21,20,25,0,0,0,0,1,0,0,1,0,0,0,0,0,0,0,47,37,32,15,32,0,0,0,0,1,0,0,0,0,0,0,1,0,0,0,1 -51,27,25,37,43,0,0,1,0,0,0,0,1,0,0,0,0,0,0,0,26,13,13,13,15,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1 -51,27,25,37,43,0,0,1,0,0,0,0,1,0,0,0,0,0,0,0,28,22,16,31,20,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1 -51,27,25,37,43,0,0,1,0,0,0,0,1,0,0,0,0,0,0,0,19,9,10,8,11,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1 -51,27,25,37,43,0,0,1,0,0,0,0,1,0,0,0,0,0,0,0,63,39,37,43,52,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0 -51,27,25,37,43,0,0,1,0,0,0,0,1,0,0,0,0,0,0,0,37,18,17,21,15,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1 -28,17,14,15,15,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,38,19,17,22,16,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0 -28,17,14,15,15,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,54,40,27,49,25,0,0,0,0,0,0,0,0,0,1,0,0,1,0,0,0 -28,17,14,15,15,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,47,29,27,19,37,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0 -28,17,14,15,15,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,12,7,6,6,7,0,0,0,0,0,0,0,0,0,1,0,0,0,0,1,1 -28,17,14,15,15,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,48,41,73,31,37,0,0,1,0,0,1,0,0,0,0,0,0,0,0,0,0 -46,28,27,31,37,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,22,11,9,12,10,0,0,0,0,0,0,0,1,0,1,0,0,0,0,0,1 -46,28,27,31,37,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,48,24,24,23,31,0,0,0,0,1,0,0,1,0,0,0,0,0,0,0,1 -46,28,27,31,37,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,48,37,25,39,29,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1 -46,28,27,31,37,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,62,39,35,24,50,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,1 -46,28,27,31,37,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,49,25,24,25,29,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1 -14,11,10,8,6,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,22,11,10,19,21,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0 -14,11,10,8,6,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,28,16,14,15,9,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 -14,11,10,8,6,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,18,15,14,11,9,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,1 -14,11,10,8,6,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,25,18,17,9,9,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,1 -14,11,10,8,6,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,46,5,5,11,17,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1 -39,23,23,29,29,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,33,18,16,21,18,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0 -39,23,23,29,29,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,34,22,19,25,29,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,1 -39,23,23,29,29,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,17,7,6,14,15,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,1 -39,23,23,29,29,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,38,19,30,26,30,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,1 -39,23,23,29,29,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,32,18,18,17,17,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,1 -66,57,37,27,31,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,37,18,28,25,28,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,1 -66,57,37,27,31,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,53,29,29,39,24,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,1 -66,57,37,27,31,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,35,27,14,24,14,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1 -66,57,37,27,31,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,27,13,25,12,23,0,0,1,0,0,0,0,0,0,0,0,0,1,0,0,1 -66,57,37,27,31,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,21,11,12,16,14,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,1 -24,13,15,13,17,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,20,8,8,8,11,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,1 -24,13,15,13,17,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,40,20,33,15,17,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0 -24,13,15,13,17,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,35,17,30,18,27,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0 -24,13,15,13,17,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,12,5,5,5,6,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,1 -24,13,15,13,17,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,19,10,9,14,16,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0,0 -53,30,37,28,31,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,29,20,29,14,15,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,1 -53,30,37,28,31,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,16,9,7,10,7,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1 -53,30,37,28,31,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,50,27,25,35,35,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,1 -53,30,37,28,31,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,23,12,12,12,14,0,0,0,0,1,0,0,1,0,0,0,0,0,0,0,1 -53,30,37,28,31,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,22,11,11,14,14,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,1 -28,21,16,21,17,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,24,12,20,11,18,0,0,1,0,0,0,0,0,0,0,0,0,1,0,0,0 -28,21,16,21,17,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,45,29,32,41,37,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0 -28,21,16,21,17,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,11,6,6,5,6,0,0,0,0,1,0,0,0,0,0,0,1,0,0,0,1 -28,21,16,21,17,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,22,9,9,8,11,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1 -28,21,16,21,17,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,32,25,14,41,22,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1 -42,26,15,30,16,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,35,17,16,20,14,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1 -42,26,15,30,16,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,29,22,12,20,12,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1 -42,26,15,30,16,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,11,6,5,6,5,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,1 -42,26,15,30,16,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,63,37,35,41,33,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1 -42,26,15,30,16,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,16,10,8,10,8,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1 -43,26,25,31,27,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,53,29,27,54,46,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0 -43,26,25,31,27,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,51,39,25,43,39,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0 -43,26,25,31,27,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,16,12,11,9,8,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,1 -43,26,25,31,27,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,28,26,14,20,11,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1 -43,26,25,31,27,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,54,32,31,33,32,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,1 -20,9,9,12,12,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,57,50,37,32,39,0,0,0,0,0,0,0,0,0,1,0,0,0,0,1,0 -20,9,9,12,12,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,44,25,24,28,23,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0 -20,9,9,12,12,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,14,7,8,7,9,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1 -20,9,9,12,12,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,28,17,14,11,12,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1 -20,9,9,12,12,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,23,8,6,6,7,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1 -47,36,33,14,15,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,29,15,14,24,28,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0,0 -47,36,33,14,15,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,19,15,13,11,9,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1 -47,36,33,14,15,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,40,24,21,23,22,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1 -47,36,33,14,15,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,67,25,24,25,40,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,1 -47,36,33,14,15,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,34,30,28,22,20,0,0,1,0,0,0,0,0,0,0,0,0,1,0,0,1 -38,25,33,16,18,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,52,27,18,11,18,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 -38,25,33,16,18,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,12,6,6,6,6,0,0,0,0,0,0,0,1,0,1,0,0,0,0,0,1 -38,25,33,16,18,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,47,30,23,17,20,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1 -38,25,33,16,18,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,57,23,30,15,25,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 -38,25,33,16,18,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,28,13,10,20,20,0,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1 -44,28,21,16,19,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,46,35,24,37,28,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0 -44,28,21,16,19,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,66,31,31,11,21,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,1 -44,28,21,16,19,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,34,29,20,27,18,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1 -44,28,21,16,19,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,34,13,22,13,18,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,1 -44,28,21,16,19,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,35,32,27,23,17,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1 -11,6,6,5,6,0,0,0,0,1,0,0,0,0,0,0,1,0,0,0,48,31,29,30,25,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0 -11,6,6,5,6,0,0,0,0,1,0,0,0,0,0,0,1,0,0,0,42,15,16,20,11,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0 -11,6,6,5,6,0,0,0,0,1,0,0,0,0,0,0,1,0,0,0,46,26,24,32,27,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0 -11,6,6,5,6,0,0,0,0,1,0,0,0,0,0,0,1,0,0,0,38,34,27,26,14,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0 -11,6,6,5,6,0,0,0,0,1,0,0,0,0,0,0,1,0,0,0,59,47,31,32,39,0,0,1,0,0,0,0,0,0,1,0,0,0,0,0,0 -26,9,7,7,7,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,36,21,15,10,13,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0 -26,9,7,7,7,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,63,43,39,39,52,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0 -26,9,7,7,7,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,14,8,8,6,6,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1 -26,9,7,7,7,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,53,36,26,44,37,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0 -26,9,7,7,7,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,11,5,5,6,7,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0,0 -14,7,7,8,8,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,27,17,18,23,21,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0 -14,7,7,8,8,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,36,22,18,20,18,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0 -14,7,7,8,8,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,46,23,21,27,19,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0 -14,7,7,8,8,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,21,10,16,11,15,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,1 -14,7,7,8,8,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,12,5,7,8,5,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,1 -19,9,13,10,16,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,46,27,28,27,33,0,0,0,0,1,0,0,1,0,0,0,0,0,0,0,0 -19,9,13,10,16,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,20,10,9,10,10,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,1 -19,9,13,10,16,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,35,21,13,24,13,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1 -19,9,13,10,16,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,20,10,9,10,10,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,1 -19,9,13,10,16,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,35,36,32,23,17,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0 -31,20,27,13,19,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,27,15,15,19,19,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1 -31,20,27,13,19,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,48,25,23,29,22,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0 -31,20,27,13,19,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,52,37,29,43,25,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 -31,20,27,13,19,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,26,22,19,16,12,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1 -31,20,27,13,19,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,53,28,26,37,37,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0 -35,30,18,27,15,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,19,12,12,7,7,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,1 -35,30,18,27,15,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,28,13,23,14,21,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,1 -35,30,18,27,15,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,36,12,8,8,9,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1 -35,30,18,27,15,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,21,12,11,9,15,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,1 -35,30,18,27,15,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,47,27,25,42,49,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0,0 -12,6,6,6,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,18,10,10,8,12,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0 -12,6,6,6,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,20,10,14,8,9,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0 -12,6,6,6,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,41,24,33,30,33,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0 -12,6,6,6,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,43,20,26,47,29,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0 -12,6,6,6,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,20,11,9,15,9,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0 -19,12,9,12,11,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,49,32,18,30,20,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0 -19,12,9,12,11,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,28,18,24,12,17,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0 -19,12,9,12,11,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,63,37,43,37,52,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0 -19,12,9,12,11,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,15,8,7,10,11,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0,0 -19,12,9,12,11,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,51,29,27,35,29,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0 -51,29,27,46,54,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0,48,33,37,20,16,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1 -51,29,27,46,54,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0,63,55,41,35,43,0,0,0,0,0,0,0,0,0,1,0,0,0,0,1,1 -51,29,27,46,54,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0,28,17,11,17,12,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,1 -51,29,27,46,54,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0,38,26,14,16,24,0,0,0,0,1,0,0,1,0,0,0,0,0,0,0,1 -51,29,27,46,54,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0,12,6,7,6,7,0,0,1,0,0,0,0,0,0,0,0,0,1,0,0,1 -19,10,9,10,7,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,22,15,14,16,12,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1 -19,10,9,10,7,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,56,17,10,10,12,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1 -19,10,9,10,7,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,38,28,41,19,21,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0 -19,10,9,10,7,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,45,23,29,21,24,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0 -19,10,9,10,7,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,46,27,31,27,37,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0 -45,33,35,23,20,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,18,8,9,10,11,0,0,0,0,0,0,0,0,0,1,0,1,0,0,0,1 -45,33,35,23,20,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,33,21,17,20,16,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1 -45,33,35,23,20,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,26,10,14,23,14,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1 -45,33,35,23,20,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,51,24,46,26,41,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,1 -45,33,35,23,20,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,15,7,8,10,11,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,1 -15,8,8,7,7,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,15,8,8,6,6,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,1 -15,8,8,7,7,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,14,8,7,9,8,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1 -15,8,8,7,7,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,35,17,15,33,37,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0 -15,8,8,7,7,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,26,13,14,10,15,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1 -15,8,8,7,7,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,19,7,10,8,7,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,1 -17,7,7,7,8,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,30,13,14,13,17,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0 -17,7,7,7,8,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,38,33,37,24,21,0,0,1,0,0,0,0,0,0,0,0,0,1,0,0,0 -17,7,7,7,8,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,25,17,12,13,17,0,0,0,0,1,0,0,1,0,0,0,0,0,0,0,1 -17,7,7,7,8,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,15,8,7,7,8,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,1 -17,7,7,7,8,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,53,54,27,29,46,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0 -30,11,12,14,9,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,40,16,12,12,13,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1 -30,11,12,14,9,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,34,18,19,12,24,0,0,0,0,1,0,0,1,0,0,0,0,0,0,0,1 -30,11,12,14,9,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,22,11,17,10,16,0,0,1,0,0,0,0,0,0,0,0,0,1,0,0,0 -30,11,12,14,9,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,40,19,19,8,13,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,1 -30,11,12,14,9,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,57,49,32,23,27,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0 -42,16,15,16,24,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,28,9,8,26,30,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,1 -42,16,15,16,24,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,26,14,15,14,14,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,1 -42,16,15,16,24,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,38,38,19,29,14,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1 -42,16,15,16,24,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,30,23,17,23,19,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1 -42,16,15,16,24,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,30,19,17,18,17,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,1 -40,28,24,27,23,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,29,17,16,19,22,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,1 -40,28,24,27,23,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,59,44,29,54,27,0,0,0,0,0,0,0,0,0,1,0,0,1,0,0,0 -40,28,24,27,23,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,34,14,14,12,17,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1 -40,28,24,27,23,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,16,8,10,9,10,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,1 -40,28,24,27,23,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,20,13,11,14,10,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1 -12,6,6,6,6,0,0,0,0,1,0,0,1,0,0,0,0,0,0,0,12,6,6,7,6,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0 -12,6,6,6,6,0,0,0,0,1,0,0,1,0,0,0,0,0,0,0,34,21,21,21,21,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0 -12,6,6,6,6,0,0,0,0,1,0,0,1,0,0,0,0,0,0,0,12,7,6,6,7,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,1 -12,6,6,6,6,0,0,0,0,1,0,0,1,0,0,0,0,0,0,0,26,12,21,13,19,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,1 -12,6,6,6,6,0,0,0,0,1,0,0,1,0,0,0,0,0,0,0,14,7,7,7,7,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1 -22,13,9,14,9,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,50,40,27,27,33,0,0,1,0,0,0,0,0,0,1,0,0,0,0,0,0 -22,13,9,14,9,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,24,23,21,14,9,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0 -22,13,9,14,9,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,30,17,13,9,11,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1 -22,13,9,14,9,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,50,33,28,38,45,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0 -22,13,9,14,9,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,44,29,26,27,23,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0 -28,11,11,11,16,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,23,13,10,7,9,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1 -28,11,11,11,16,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,19,10,9,15,13,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1 -28,11,11,11,16,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,34,11,18,14,11,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,1 -28,11,11,11,16,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,46,33,43,24,32,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0 -28,11,11,11,16,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,37,23,16,20,18,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1 -37,15,18,15,21,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,23,11,17,13,22,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1 -37,15,18,15,21,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,30,28,15,16,24,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1 -37,15,18,15,21,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,23,14,9,14,10,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,1 -37,15,18,15,21,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,49,24,27,24,31,0,0,1,0,0,1,0,0,0,0,0,0,0,0,0,1 -37,15,18,15,21,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,34,16,20,35,22,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1 -49,29,28,30,29,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,68,44,33,24,29,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0 -49,29,28,30,29,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,67,32,30,24,35,0,0,1,0,0,1,0,0,0,0,0,0,0,0,0,0 -49,29,28,30,29,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,45,23,22,23,27,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1 -49,29,28,30,29,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,44,22,22,21,28,0,0,0,0,1,0,0,1,0,0,0,0,0,0,0,1 -49,29,28,30,29,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,16,6,6,12,13,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,1 -37,21,19,32,20,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,49,27,27,26,33,0,0,0,0,1,0,0,1,0,0,0,0,0,0,0,0 -37,21,19,32,20,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,43,22,21,22,25,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1 -37,21,19,32,20,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,29,14,12,24,13,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1 -37,21,19,32,20,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,26,14,16,22,19,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,1 -37,21,19,32,20,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,13,8,6,7,6,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1 -37,21,29,27,29,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,13,6,6,6,7,0,0,0,0,1,0,0,1,0,0,0,0,0,0,0,1 -37,21,29,27,29,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,62,37,36,39,37,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0 -37,21,29,27,29,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,26,10,14,23,14,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1 -37,21,29,27,29,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,23,11,9,16,16,0,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1 -37,21,29,27,29,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,18,11,10,11,10,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1 -17,8,8,9,7,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,44,22,18,39,20,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 -17,8,8,9,7,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,48,33,37,20,16,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0 -17,8,8,9,7,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,44,27,17,41,25,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0 -17,8,8,9,7,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,26,8,13,9,9,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1 -17,8,8,9,7,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,19,11,14,8,11,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1 -46,28,31,12,13,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,19,11,11,11,11,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,1 -46,28,31,12,13,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,12,6,6,5,6,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1 -46,28,31,12,13,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,18,10,9,11,10,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1 -46,28,31,12,13,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,25,13,12,20,23,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0,0 -46,28,31,12,13,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,12,7,7,6,6,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1 -19,9,11,14,15,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,11,5,6,7,6,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1 -19,9,11,14,15,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,33,14,12,32,36,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,1 -19,9,11,14,15,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,12,7,6,6,5,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1 -19,9,11,14,15,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,51,28,26,51,44,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0 -19,9,11,14,15,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,42,33,17,30,17,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0 -30,15,14,17,14,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,34,24,17,27,24,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0 -30,15,14,17,14,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,46,30,26,28,26,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0 -30,15,14,17,14,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,28,14,18,13,15,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,1 -30,15,14,17,14,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,28,12,13,12,16,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,1 -30,15,14,17,14,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,29,14,23,16,29,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1 -38,25,21,23,21,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,25,17,14,9,14,0,0,0,0,1,0,0,0,0,0,0,1,0,0,0,1 -38,25,21,23,21,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,46,29,29,29,29,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,1 -38,25,21,23,21,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,21,10,16,11,15,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,1 -38,25,21,23,21,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,32,17,17,17,21,0,0,0,0,1,0,0,1,0,0,0,0,0,0,0,1 -38,25,21,23,21,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,15,7,7,10,7,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1 -35,22,13,21,14,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,33,33,30,21,16,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0 -35,22,13,21,14,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,19,12,12,7,7,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,1 -35,22,13,21,14,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,38,19,16,22,17,0,0,0,0,0,0,0,1,0,1,0,0,0,0,0,1 -35,22,13,21,14,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,46,31,28,28,37,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0 -35,22,13,21,14,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,40,32,39,11,15,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0 -42,23,23,30,19,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,32,16,20,15,17,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,1 -42,23,23,30,19,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,39,19,19,19,19,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1 -42,23,23,30,19,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,27,18,16,17,15,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1 -42,23,23,30,19,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,32,23,17,24,19,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1 -42,23,23,30,19,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,16,9,8,10,8,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1 -23,15,11,12,15,0,0,0,0,1,0,0,1,0,0,0,0,0,0,0,58,37,25,19,19,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0 -23,15,11,12,15,0,0,0,0,1,0,0,1,0,0,0,0,0,0,0,64,5,5,14,23,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1 -23,15,11,12,15,0,0,0,0,1,0,0,1,0,0,0,0,0,0,0,28,18,20,12,10,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1 -23,15,11,12,15,0,0,0,0,1,0,0,1,0,0,0,0,0,0,0,53,52,43,37,25,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0 -23,15,11,12,15,0,0,0,0,1,0,0,1,0,0,0,0,0,0,0,63,55,41,35,43,0,0,0,0,0,0,0,0,0,1,0,0,0,0,1,0 -50,38,36,15,16,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,64,33,21,12,21,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1 -50,38,36,15,16,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,47,18,32,18,25,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,1 -50,38,36,15,16,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,20,17,10,13,8,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1 -50,38,36,15,16,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,35,17,14,20,16,0,0,0,0,0,0,0,1,0,1,0,0,0,0,0,1 -50,38,36,15,16,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,43,38,26,35,23,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1 -49,27,33,25,28,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,49,35,29,33,28,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1 -49,27,33,25,28,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,12,6,6,6,6,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1 -49,27,33,25,28,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,63,37,43,37,52,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0 -49,27,33,25,28,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,27,19,27,13,14,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,1 -49,27,33,25,28,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,12,6,6,6,6,0,0,0,0,0,0,0,1,0,1,0,0,0,0,0,1 -14,8,12,7,8,0,0,1,0,0,1,0,0,0,0,0,0,0,0,0,43,21,20,18,17,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0 -14,8,12,7,8,0,0,1,0,0,1,0,0,0,0,0,0,0,0,0,30,32,28,18,11,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0 -14,8,12,7,8,0,0,1,0,0,1,0,0,0,0,0,0,0,0,0,12,6,7,5,5,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,1 -14,8,12,7,8,0,0,1,0,0,1,0,0,0,0,0,0,0,0,0,41,21,22,19,19,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0 -14,8,12,7,8,0,0,1,0,0,1,0,0,0,0,0,0,0,0,0,16,10,15,9,10,0,0,1,0,0,1,0,0,0,0,0,0,0,0,0,1 -32,25,18,36,23,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,22,10,16,12,20,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1 -32,25,18,36,23,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,33,18,17,31,27,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0 -32,25,18,36,23,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,45,22,21,19,17,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0 -32,25,18,36,23,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,37,19,18,22,17,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1 -32,25,18,36,23,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,35,28,19,14,16,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0 diff --git a/HW5/game_data.py b/HW5/game_data.py index 1ef9669..f1cdc02 100644 --- a/HW5/game_data.py +++ b/HW5/game_data.py @@ -47,7 +47,7 @@ pokemons_df = pd.DataFrame.from_dict(pokemons_dict,orient='index') available_pokemon_names = list(pokemons_dict.keys()) -available_starters = ['bulbasaur', 'charmander', 'squirtle'] +available_starter_names = ['bulbasaur', 'charmander', 'squirtle'] #type effectiveness type_effectiveness = [] diff --git a/HW5/hw5.py b/HW5/hw5.py index bb54961..94c3761 100644 --- a/HW5/hw5.py +++ b/HW5/hw5.py @@ -4,6 +4,7 @@ import random import copy import game_data as gd import pickle +import joblib import matplotlib.pyplot as plt import numpy as np import os @@ -310,7 +311,9 @@ def train_model(dataset_column_labels): impurity = False, proportion = True) graph = graphviz.Source(dot_data) - graph.render(outfile=f"plots/tree_{i}.pdf", format='pdf') + graph.render(outfile=f"plots/tree_{i}.pdf", format='pdf') + + return best_model if __name__ == "__main__": Ngames = 10 @@ -327,5 +330,6 @@ if __name__ == "__main__": print("Generating dataset") dataset_column_labels = build_dataset() print("Training model") - train_model(dataset_column_labels) - print("Ended") \ No newline at end of file + best_model = train_model(dataset_column_labels) + joblib.dump(best_model, 'trained_model.joblib') + print("Ended") diff --git a/HW5/hw5_final.py b/HW5/hw5_final.py new file mode 100644 index 0000000..7b79e9f --- /dev/null +++ b/HW5/hw5_final.py @@ -0,0 +1,571 @@ +from core import Trainer +import game_data as gd +import random +import copy +import numpy as np +import pickle +import joblib +import os +import pandas as pd +from sklearn.model_selection import train_test_split +from sklearn.ensemble import RandomForestClassifier +from sklearn.metrics import accuracy_score, classification_report, confusion_matrix +from sklearn.model_selection import RandomizedSearchCV +from scipy.stats import randint +from sklearn.tree import export_graphviz +import graphviz + +game_status = 'story' +game_active_flag = True +if os.path.exists('trained_model.joblib'): + recommender_sys_avail = True +else: + recommender_sys_avail = False + +def recommend(player_pokemon, opponent_pokemon): + global recommender_sys_avail + if recommender_sys_avail: + model = joblib.load('trained_model.joblib') + + # Prepare input data + all_pokemon_types = list(gd.available_types) + player_ActStats = list(player_pokemon.ActStats.values()) + player_pokemon_type = player_pokemon.types + player_pokemon_type_encoded = [1 if t in player_pokemon_type else 0 for t in all_pokemon_types] + opponent_ActStats = list(opponent_pokemon.ActStats.values()) + opponent_pokemon_type = opponent_pokemon.types + opponent_pokemon_type_encoded = [1 if t in opponent_pokemon_type else 0 for t in all_pokemon_types] + + input_data = player_ActStats + player_pokemon_type_encoded + opponent_ActStats + opponent_pokemon_type_encoded + labels = build_dataset()[:-1] # Exclude the last label which is 'battle_result' + df_to_eval = pd.DataFrame([input_data], columns=labels) + + prediction_proba = model.predict_proba(df_to_eval) + return prediction_proba[0][1] # Returns 1 if prediction is a win, 0 otherwise, and the probability of winning + else: + raise ValueError("Recommender system is not available. Play NewRandomBattle once!") +def Battle(trainer,cpu_trainer): + global game_status + global game_active_flag + print(f"You are in battle against CPU's {cpu_trainer.get_active_pokemon().name}!") + battle_active = True + + while battle_active: + player_battle_action_selected = False + while not player_battle_action_selected: + print("Type the number of one of the following actions:") + print(f"1) Attack - [Your active Pokemon - {trainer.get_active_pokemon().name}]") + print("2) Change pokemon") + print("3) Use item") + print("4) Consult the Oracle") + print("5) Run away") + print('6) Check status') + + try: + action = int(input("Choose an action (1-6): ").strip()) + player_battle_action_selected = True + except ValueError: + print("Invalid input. Please enter a number between 1 and 6.") + continue + + if action == 1: + #check if the player can sustain a battle: first check the active pokemon, + #then check the pokemons in the list + if not trainer.active_pokemon_can_battle(): + print("Your active pokemon cannot battle!") + if not trainer.can_battle(): + print("You have no more pokemon that can battle! You lost the battle!") + battle_active = False + game_status = 'pokemon_center' + break + else: + print("You have other pokemon that can battle! Please change your active pokemon!") + continue + + selected_combat_move_flag = False + while not selected_combat_move_flag: + active_pokemon = trainer.get_active_pokemon() + cpu_active_pokemon = cpu_trainer.get_active_pokemon() + print(f"Choose a move for {active_pokemon.name} to use against {cpu_active_pokemon.name}:\n", active_pokemon.get_moves()) + player_move_name = input("Choose:") + try: + active_pokemon.useMove(player_move_name,cpu_active_pokemon) + selected_combat_move_flag = True + #check if the opponent has been defeated + if not cpu_trainer.active_pokemon_can_battle(): + print(f"{cpu_trainer.get_active_pokemon().name} has been defeated!") + battle_active = False + game_status = 'story' + break + + #if the opponent has not been defeated, then its the CPU turn to play + cpu_active_pokemon_selected_move_name = random.choice(cpu_active_pokemon.get_moves()) + print(f"CPU's {cpu_active_pokemon.name} is using {cpu_active_pokemon_selected_move_name} against your {active_pokemon.name}!") + cpu_active_pokemon.useMove(cpu_active_pokemon_selected_move_name, active_pokemon) + + #update the player pokemon list + trainer.update_pokemon_list(active_pokemon) + #check if the player has been defeated + if not trainer.active_pokemon_can_battle(): + print(f"Your {active_pokemon.name} has been defeated!") + if not trainer.can_battle(): + print("You have no more Pokemons that can battle! You lost!") + battle_active = False + game_status = 'pokemon_center' + break + else: + print("You have other Pokemons that can battle!") + continue + except ValueError as e: + print(e) + print("Please try again...") + + elif action == 2: + print('='*30) + print("Change active pokemon") + print('-'*30) + change_pokemon_success = False + while not change_pokemon_success: + try: + print("Select the name of a pokemon in your list:") + print(trainer.get_pokemon_list()) + chosen_new_pokemon_name = input('Choose...') + trainer.change_active_pokemon(chosen_new_pokemon_name) + change_pokemon_success = True + except ValueError as e: + print(e) + + elif action == 3: + print("Select the item index to use:") + trainer.print_items() + item_selected_flag = False + while not item_selected_flag: + try: + avail_items = list(trainer.items.keys()) + item_index = int(input("Choose an item index (1-2): ").strip()) + item_selected_flag = True + is_pokeball = trainer.use_item(item_name=avail_items[item_index - 1]) + if is_pokeball: + catch_prob = 1 - (cpu_trainer.get_active_pokemon().get_current_hp() / cpu_trainer.get_active_pokemon().baseStats['hp']) + random_value = random.uniform(0, 1) + if random_value < catch_prob: + print(f"You caught {cpu_trainer.get_active_pokemon().name}!") + trainer.add_pokemon(cpu_trainer.get_active_pokemon()) + battle_active = False + game_status = 'story' + else: + print(f"{cpu_trainer.get_active_pokemon().name} escaped your pokeball!") + except ValueError: + print("Please enter a number between 1 and 2.") + continue + + elif action == 4: + global recommender_sys_avail + if recommender_sys_avail: + try: + for pokemon in trainer.pokemon_list: + win_prob = recommend(player_pokemon=pokemon, opponent_pokemon=cpu_trainer.get_active_pokemon()) + print(f"The Oracle predicts {pokemon.name} to have {win_prob:.2f} of chances to win against {cpu_trainer.get_active_pokemon().name}.") + except ValueError as e: + print(e) + + elif action == 5: + runaway_prob = 0.6 + random_value = random.uniform(0, 1) + if random_value < runaway_prob: + print("You successfully ran away from the battle!") + battle_active = False + game_status = 'story' + else: + print("You could not run away from the battle!") + + elif action == 6: + print('='*30) + print("BATTLE INFO") + print('-'*30) + print("Your items:") + trainer.print_items() + print("Your pokemon list info:") + for pokemon in trainer.pokemon_list: + pokemon.print_pokemon_info() + print("-"*30) + print("CPU active pokemon info:") + cpu_trainer.get_active_pokemon().print_pokemon_info() + print('='*30) + else: + print("Invalid action. Please choose again.") + +def RandomBattle(trainer,cpu_trainer): + #print(f"You are in battle against {cpu_trainer.name}!") + battle_active = True + + active_pokemon = trainer.get_active_pokemon() + cpu_active_pokemon = cpu_trainer.get_active_pokemon() + #print(f"Your active Pokemon is {active_pokemon.name} and the CPU's active Pokemon is {cpu_active_pokemon.name}.") + did_player_won = False + battle_turns_num = 0 + + player_hp_evolution = [] + player_selected_moves = [] + player_damage_done = [] + cpu_hp_evolution = [] + cpu_selected_moves = [] + cpu_damage_done = [] + while battle_active: + player_move_name = random.choice(active_pokemon.get_moves()) + player_selected_moves.append(player_move_name) + #print(f"{active_pokemon.name} selected {player_move_name} to use against {cpu_active_pokemon.name}:\n") + try: + player_damage_done_value = active_pokemon.useMove(player_move_name,cpu_active_pokemon,game_status='new_random_battle') + + player_damage_done.append(player_damage_done_value) + player_hp_evolution.append(active_pokemon.get_current_hp()) + cpu_hp_evolution.append(cpu_active_pokemon.get_current_hp()) + + battle_turns_num += 1 + #check if the opponent has been defeated + if not cpu_trainer.active_pokemon_can_battle(): + #print(f"{cpu_trainer.get_active_pokemon().name} has been defeated! You win!") + did_player_won = True + battle_active = False + break + + #if the opponent has not been defeated, then its the CPU turn to play + cpu_active_pokemon_selected_move_name = random.choice(cpu_active_pokemon.get_moves()) + #print(f"CPU's {cpu_active_pokemon.name} is using {cpu_active_pokemon_selected_move_name} against your {active_pokemon.name}!") + cpu_selected_moves.append(cpu_active_pokemon_selected_move_name) + + cpu_damage_done_value = cpu_active_pokemon.useMove(cpu_active_pokemon_selected_move_name, active_pokemon,game_status='new_random_battle') + + cpu_damage_done.append(cpu_damage_done_value) + player_hp_evolution.append(active_pokemon.get_current_hp()) + cpu_hp_evolution.append(cpu_active_pokemon.get_current_hp()) + battle_turns_num += 1 + + #update the player pokemon list + trainer.update_pokemon_list(active_pokemon) + #check if the player has been defeated + if not trainer.active_pokemon_can_battle(): + #print(f"Your {active_pokemon.name} has been defeated!") + if not trainer.can_battle(): + #print("You have no more Pokemons that can battle! You lose!") + did_player_won=False + battle_active = False + break + else: + #print("You have other Pokemons that can battle!") + continue + + except ValueError as e: + print(e) + + #manage those cases for which the player wins in the first turn and the cpu does not play any turn + if len(player_damage_done) == 0: + player_damage_done = [0] + if len(cpu_damage_done) == 0: + cpu_damage_done = [0] + + player_avg_damage_done = np.mean(player_damage_done) #average damage done per turn + cpu_avg_damage_done = np.mean(cpu_damage_done) #average damage done per turn + + player_residual_hp_percent = trainer.get_active_pokemon().get_current_hp_percent() + + player_history = {'player_hp_evolution':player_hp_evolution, + 'player_selected_moves':player_selected_moves, + 'player_damage_done':player_damage_done, + 'player_avg_damage_done':player_avg_damage_done + } + cpu_history = {'cpu_hp_evolution':cpu_hp_evolution, + 'cpu_selected_moves':cpu_selected_moves, + 'cpu_damage_done':cpu_damage_done, + 'cpu_avg_damage_done':cpu_avg_damage_done + } + turn_history = {'player_history':player_history, + 'cpu_history':cpu_history + } + battle_results = { + 'player_pokemon':trainer.get_active_pokemon(), + 'encountered_pokemon':cpu_trainer.get_active_pokemon(), + 'result':did_player_won, + 'battle_turns_num':battle_turns_num, + 'player_residual_hp_percent':player_residual_hp_percent, + 'turn_history':turn_history + } + return battle_results + +def build_dataset(): + #if the dataset.csv file does not exist, then build, otherwise load it + all_pokemon_types = list(gd.available_types) + player_ActStats_labels = ["player_hp", "player_attack", "player_defense", "player_speed", "player_special"] + player_type_label = ['player_type_' + t for t in all_pokemon_types] + opponent_ActStats_labels = ["opponent_hp", "opponent_attack", "opponent_defense", "opponent_speed", "opponent_special"] + opponent_type_label = ['opponent_type_' + t for t in all_pokemon_types] + + #define a padas dataframe to store the dataset + dataset_column_labels = player_ActStats_labels + player_type_label + opponent_ActStats_labels + opponent_type_label + ['battle_result'] + dataset = pd.DataFrame(columns=dataset_column_labels) + files_to_analyze = os.listdir('results/') + dataset_row = [] + for file_name in files_to_analyze: + pickle_in = open(f"results/{file_name}",'rb') + all_battle_results = pickle.load(pickle_in) + pickle_in.close() + for battle_result in all_battle_results: + player_pokemon_ActStats = list(battle_result['player_pokemon'].ActStats.values()) + player_pokemon_type = battle_result['player_pokemon'].types + player_pokemon_type_encoded = [1 if t in player_pokemon_type else 0 for t in all_pokemon_types] + opponent_pokemon = list(battle_result['encountered_pokemon'].ActStats.values()) + opponent_pokemon_type = battle_result['encountered_pokemon'].types + opponent_pokemon_type_encoded = [1 if t in opponent_pokemon_type else 0 for t in all_pokemon_types] + battle_result_integer = 1 if battle_result['result'] else 0 + dataset_row = player_pokemon_ActStats + player_pokemon_type_encoded + opponent_pokemon + opponent_pokemon_type_encoded + [battle_result_integer] + #append the row to the dataset + dataset.loc[len(dataset)] = dataset_row + + #save the dataset to a csv file + dataset.to_csv('dataset.csv', index=False) + + return dataset_column_labels + +def train_model(dataset_column_labels): + dataset_labels = dataset_column_labels[:-1] + # Load the dataset + dataset = pd.read_csv('dataset.csv') + + # Split the dataset into features and target variable + X = dataset.drop('battle_result', axis=1) + y = dataset['battle_result'] + + # Split the data into training and testing sets + X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42) + + # Create a Random Forest Classifier + model = RandomForestClassifier() + param_dist = { + 'n_estimators': randint(50, 500), + 'max_depth': randint(1, 20), + } + + rand_search = RandomizedSearchCV(model, + param_distributions=param_dist, + n_iter=5, cv=5).fit(X_train, y_train) + + # Train the model + best_model = rand_search.best_estimator_ + print(f"Best parameters found: {rand_search.best_params_}") + + # Make predictions on the test set + y_pred = best_model.predict(X_test) + + # Evaluate the model + accuracy = accuracy_score(y_test, y_pred) + print(f"Model Accuracy: {accuracy:.2f}") + print("Classification Report:") + print(classification_report(y_test, y_pred)) + print("Confusion Matrix:") + print(confusion_matrix(y_test, y_pred)) + + + # Visualize the first three estimators + for i in range(3): + tree = best_model.estimators_[i] + dot_data = export_graphviz(tree, + feature_names=dataset_labels, + filled = True, + max_depth = 2, + impurity = False, + proportion = True) + graph = graphviz.Source(dot_data) + graph.render(outfile=f"plots/tree_{i}.pdf", format='pdf') + + # Save the trained model + joblib.dump(best_model, 'trained_model.joblib') + +def MainRandomBattle(starter_choice,Nbattles): + try: + starter_name = starter_choice + trainer = Trainer(name='trainer', starter_name=starter_name) + #print(f"{trainer.name} has chosen {trainer.starter} as their starter Pokemon!") + #print("Adding potions and pokeballs to your inventory...") + trainer.items = {"potions": 10, "pokeball": 10} + #print("Your character is ready!") + #print(f"Welcome {trainer.name}! Your adventure begins now!") + except ValueError as e: + print(e) + print("Something went wrong!") + + game_active_flag = True + while game_active_flag: + all_battle_results = [] + for i in range(0,Nbattles): + #print("You entered the Random Battle mode") + #print("Battle #",i) + cpu_trainer = Trainer(name='CPU',starter_name=gd.pokemons_df.index[random.randint(0,len(gd.pokemons_df.index)-1)],is_CPU=True) + battle_results = RandomBattle(trainer,cpu_trainer) + all_battle_results.append(battle_results) + heal_flag = 'yes' + if heal_flag == 'yes': + for pokemon in trainer.pokemon_list: + pokemon.curr_hp = pokemon.baseStats['hp'] + #print("All your Pokemon have been healed!") + + game_active_flag = False + #save all battle results + return all_battle_results + +def Main(): + global game_status + global game_active_flag + player_created_flag = False + while not player_created_flag: + try: + trainer_name = input("Enter your trainer name: ") + print("Available starter Pokemon: ", gd.available_starter_names) + starter_name = input("Choose your starter Pokemon: ") + trainer = Trainer(name=trainer_name, starter_name=starter_name) + print(f"{trainer.name} has chosen {trainer.starter} as their starter Pokemon!") + print("Adding potions and pokeballs to your inventory...") + trainer.items = {"potions": 10, "pokeball": 10} + print("Your character is ready!") + #trainer.print_trainer_info() + player_created_flag = True + print(f"Welcome {trainer.name}! Your adventure begins now!") + except ValueError as e: + print(e) + print("Please try again...") + continue + + while game_active_flag: + if game_status == 'story': + print("Type the number of one of the following actions:") + print("1) Explore ") + print("2) Pokemon Center") + print("3) Pokemon Store") + print("4) Show trainer data") + print("5) NewRandomBattle") + print("6) Exit") + + try: + action = int(input("Choose an action (1-6): ").strip()) + except ValueError: + print("Invalid input. Please enter a number between 1 and 6.") + continue + if action == 1: + game_status = 'explore' + elif action == 2: + game_status = 'pokemon_center' + elif action == 3: + game_status = 'pokemon_store' + elif action == 4: + print("Showing trainer data:") + trainer.print_trainer_info() + elif action == 5: + confirm=input("Are you sure you want to start a new random battle? This will generate data and train the model. Type 'yes' to continue: ") + if confirm.lower() == 'yes': + print("Starting a new random battle!") + game_status = 'new_random_battle' + else: + print("Cancelled starting a new random battle.") + elif action == 6: + print("Exiting the game. Goodbye!") + game_active_flag = False + else: + print("Invalid action. Please choose again.") + + elif game_status == 'explore': + print("You are exploring") + battle_prob = random.uniform(0, 1) + #print(f"Battle probability: {battle_prob:.2f}") + if battle_prob < 0.8: + cpu_trainer = Trainer(name='CPU',starter_name=gd.pokemons_df.index[random.randint(0,len(gd.pokemons_df.index)-1)],is_CPU=True) + print(f"A wild {cpu_trainer.get_active_pokemon().name} appeared!") + + #print(cpu_trainer.get_active_pokemon().print_pokemon_info()) + game_status = 'battle' + #before entering the battle, we predict the win probability of + #each of the player's pokemon against the opponent's pokemon + try: + win_probs = [] + for pokemon in trainer.pokemon_list: + win_prob = recommend(player_pokemon=pokemon, opponent_pokemon=cpu_trainer.get_active_pokemon()) + win_probs.append(win_prob) + print(f"The Oracle predicts {pokemon.name} to have {win_prob:.2f} of chances to win.") + #if all the win probabilities are below 0.5, we suggest the player to run away + if all(prob < 0.5 for prob in win_probs): + print("The Oracle suggests to RUN AWAY!") + else: + if len(win_probs) > 1: + #find the pokemon with the highest win probability + best_pokemon_index = win_probs.index(max(win_probs)) + best_pokemon = trainer.pokemon_list[best_pokemon_index] + print(f"The Oracle suggests to use {best_pokemon.name}!") + else: + continue + except ValueError as e: + print("HINT: Unlock access to the Oracle by playing NewRandomBattle!") + + Battle(trainer,cpu_trainer) + else: + print('-'*30) + print("No wild Pokemon appeared.") + game_status = 'story' + + elif game_status == 'pokemon_center': + print("You are at the Pokemon Center. You can heal your Pokemon here.") + heal_flag = input("Type 'yes' to heal your Pokemons or any other key to exit: ").strip().lower() + if heal_flag == 'yes': + for pokemon in trainer.pokemon_list: + pokemon.curr_hp = pokemon.baseStats['hp'] + for move in pokemon.moves_dict.keys(): + pokemon.moves_dict[move]['pp'] = copy.deepcopy(gd.available_moves_df.loc[move]['pp']) + print("All your Pokemon have been healed!") + game_status = 'story' + else: + print("You exited the Pokemon Center.") + game_status = 'story' + # Add Pokemon Center logic here + + elif game_status == 'pokemon_store': + print("You are in the Pokemon Store. You can buy items here.") + restore_items_flag = input("Type 'yes' to restore your items: ").strip().lower() + if restore_items_flag == 'yes': + trainer.items = {"potions": 10, "pokeball": 10} + print("Your items have been restored!") + game_status = 'story' + else: + print("You exited the Pokemon Store.") + game_status = 'story' + + elif game_status == 'new_random_battle': + Ngames = 1000 + Nbattles = 500 + print("Generating data...") + for i in range(Ngames): + starter_choice = gd.pokemons_df.index[random.randint(0,len(gd.pokemons_df.index)-1)] + #print(f"Generating data for {starter_choice}, game {i}...") + results = MainRandomBattle(starter_choice=starter_choice, Nbattles=Nbattles) + pickle_out = open(f"results/{starter_choice}_game_{i}_{Nbattles}_battles.pickle",'wb') + pickle.dump(results,pickle_out) + pickle_out.close() + + print("Generating dataset") + dataset_column_labels = build_dataset() + print("Training model") + try: + train_model(dataset_column_labels) + print("Model has been trained! Ending NewRandomBattle") + global recommender_sys_avail + recommender_sys_avail = True + except Exception as e: + print(f"An error occurred during model training: {e}") + print("Ending NewRandomBattle without training the model.") + game_status = 'story' + + else: + print("Unknown game status. Try again.") + +if __name__ == "__main__": + if not os.path.exists('results'): + os.makedirs('results') + + Main() \ No newline at end of file diff --git a/HW5/plots/tree_0.gv b/HW5/plots/tree_0.gv deleted file mode 100644 index c0979b1..0000000 --- a/HW5/plots/tree_0.gv +++ /dev/null @@ -1,33 +0,0 @@ -digraph Tree { -node [shape=box, style="filled", color="black", fontname="helvetica"] ; -edge [fontname="helvetica"] ; -0 [label="player_defense <= 14.5\nsamples = 100.0%\nvalue = [0.332, 0.668]", fillcolor="#9ccef2"] ; -1 [label="opponent_speed <= 16.5\nsamples = 40.8%\nvalue = [0.579, 0.421]", fillcolor="#f8ddc9"] ; -0 -> 1 [labeldistance=2.5, labelangle=45, headlabel="True"] ; -2 [label="player_hp <= 13.0\nsamples = 20.2%\nvalue = [0.321, 0.679]", fillcolor="#97cbf1"] ; -1 -> 2 ; -3 [label="(...)", fillcolor="#C0C0C0"] ; -2 -> 3 ; -6 [label="(...)", fillcolor="#C0C0C0"] ; -2 -> 6 ; -29 [label="opponent_hp <= 37.5\nsamples = 20.6%\nvalue = [0.873, 0.127]", fillcolor="#e99356"] ; -1 -> 29 ; -30 [label="(...)", fillcolor="#C0C0C0"] ; -29 -> 30 ; -39 [label="(...)", fillcolor="#C0C0C0"] ; -29 -> 39 ; -40 [label="opponent_speed <= 36.5\nsamples = 59.2%\nvalue = [0.145, 0.855]", fillcolor="#5baee9"] ; -0 -> 40 [labeldistance=2.5, labelangle=-45, headlabel="False"] ; -41 [label="player_attack <= 14.0\nsamples = 54.3%\nvalue = [0.102, 0.898]", fillcolor="#50a8e8"] ; -40 -> 41 ; -42 [label="(...)", fillcolor="#C0C0C0"] ; -41 -> 42 ; -43 [label="(...)", fillcolor="#C0C0C0"] ; -41 -> 43 ; -80 [label="player_special <= 30.0\nsamples = 4.9%\nvalue = [0.714, 0.286]", fillcolor="#efb388"] ; -40 -> 80 ; -81 [label="(...)", fillcolor="#C0C0C0"] ; -80 -> 81 ; -88 [label="(...)", fillcolor="#C0C0C0"] ; -80 -> 88 ; -} diff --git a/HW5/plots/tree_0.pdf b/HW5/plots/tree_0.pdf deleted file mode 100644 index 15e91b42fb1db33a6ead827690f40950d9a1ffeb..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 11840 zcmch-byyTy*EdWk(k)02(mgZ4%uv$ZjdXX&Zf#-Oh zbAQkMeb@WfJ2Thpz1FT3d+)WcYyB8hB&0Y%oKQ@L`kjhPOdbFb;ACoxDJTfwQm}Be zLRbTM?^tS>004kX%ElgH;d)ovn;gv*h6=I3Mf8PCB z!Ky}c;3Nr?S-V-cIF%+1Bz!#Ji_M$F8WGRPQE)Rhd$asz>eKa{B+conyU_9N(hA1S z?TnCb6qDI)N$!;YBE004d{>K*CJxK#`-l4eUh~3+(cM1LT>NqPW(rTYTKkjxe{!!8 z!c3XI8R@^kTP$0_R6ikgYA*cJ?V=fSO4qsEnc{KgzP5avf;i);D8dzvhPBj4Uu~qj zBu@C>0xM?r$?z=n-J3?D*{DBuMM4DI&0LyAS4*(L6$tcIxnRL(pFBoYjU8o)8psKm zd~I)=Y3ta^Vww%q^}hw6g~%sq*M;x?48`u?2HRd_???X1!Z6J zsiistJ8xGb(1f4BnprI2zfRS1;Tn)$CtlSuE7_0zy{B^;^!|ea1w-|nt_3Yt0&Fj= zr4M&!Wnai%dM=tL+2N2~zkK>r(8Yfm{y8&%f>)zdheK5NXPB)@uTU<6Zb=j)#`@c* zZT}fde*uoF&-utekW4wGoF_Y}v(P(Qnx6P`hlnI$XQunS>r}6=q?r06QWJi{*$WhX zQo8&GNBS+`kXzgHQe7hr@lQ}0({Ei1b{Hpar~LR8w{WWc)=ANZ$1@S*h-kN}%^#hl zt^h`1usWclMbAei_+X&ds`1qHdhu=mJn{!r8z*2f6=a_%8jOi=>wP&4_4+ufAXh%bv(6@>> zDd7)JCh#?*MKX0Ua2&YvNtkC_G(;%@5o@jbNcJdaY)pdjV&$FhK2n}GrR#CU=xAW( zu^*8+Qic+42mtUqw-wL$(fw437Eo6Whjum!wtRfw3bM!wC=Us>7=poLtQZg^}p3|wKYW-6r467(0?@`MvzJl95{L?!amR?Mpd6sDY0Dp z*>un3wCQ4bx(S`hWH11`P)bxVBdDq~xX~V`1}&db{w2;fSw;b~pI8d7ZpsL85f$4G zdWE=+F23Tq!3l&4siXIorJH>nODM*Nv#;tFT)~-?N&)gMZh|ah?@?Gm^v<_RBCkhy z-6&LEp)1wkFi&i}FcW#li*1~4ZL*MIaJnl&?9ki1&*()x(%BSGm-dwkKkesxz}Jr9 zt7anAhOZUd1fAs7o|(FWy(^)MvENo@S-XE`+BbkDGw1DJ_St5v6vx;UoidA#i%WYt zKuEqQ;WG76A$|4Ydr&Yft~sa24n@<|1HMhf zR?zOFPdmT--f|QVPE;5UY>~+k1e=6R z?kH_=RL;7U@gI6M@DFUF84eW?xNU69(@6CT)Me3f6z8RW!AX2$QUPQV3i}y_-=wu6 zL+W>8GcT2<_#Cx1cvgq%#}>B-RbcS8htH!8u0wo^IRl%(2}fb-CIE^k#$4O^M=w6u z+zY`cA9!K#$QGb(V~6E)z3k$dimn2AW70ye2kFiX6M)8>N4S%ED_ytD>_W_DX8y!B zwMt&C*Q!U;3i0(evJNx)+aE-A{d>Kl!`?b5_A%OZZV&6@3Zw=+xLKbdrk|SgWM&T3 z7UdKmegNh6Wv)|ZNpsF*OndlnnQFUF){F^27f45=MBW8fTr(AXny7C~cFSW$ap@>l z&p&CM_F&X>s&}Lx@yOR4XG3A6L*ZoEieeyQBDXn7+FI4Q1KdYf_pOalxH3^Xwe$^O z@|mu$TA*p>T5RB0Qffyt8V6B2S9j)a$XhEXDkY8sg=Kc;O{Z~5T=Er`QH)ru67@L?*s0Ac^7g)FdpcAhkKIy zpV0g}7)yE}q}363ffyhtc+a@|aG3z_2mqJ3C;$ZDGBdgRzYEWI4S)S}NjW(p{?*%( z1IPgcK>vjIyH0n%zZZl3vlxI&!_(OUz@=*}5x$Osga$)4_}^BzpZ$*&Ab-RHf&L}e-(rBk|H$#*9w_&A`Ku=g z00IJeA^-7YS@-hxAl7Wyo2f4;S)3ow+!Ykq+@;UNZ>OVwfc`dtxksK+&f@_N5xtZT zm59W*wg&<95^ej~;h?%F_$XikG6evzh(KZ~0(S{Yjo5#cV-^$kDef{EBTF|AcfB92#MgVUpm6s@}*bNE!^-rAWejn3{vkbxLpVCFU*_S_j z;UQ!dA4~jLbS-d0Vz$y9sbCUhhUqdPP8SXxdX{HVerpK}+FJ}YB_AX=Zl(kVOt_i$l%;LR} z+=E;ozu~6!Kz~clvDb3@Yc`H@xxRetagCHJdfJ42n}8n7fI)hzr0XU|ytXC9WGwUF=DA%1*tc9k-Mra z-!6N(=}WkoLZocoJLj*;mAW3qx%Q^6_PeZ`7v07ZWXHxV_w8Ff024~*l^oax{8YcT z6;bSu98&B#UcZ2&z7Km}3|CL?)~44uW4(I(YCX(OO}yBl7(=M?q~+V8n2FfC%3-4? zDe1sT=%g^Tirys5Da>CM(ERdo6*b2~2bw^9%}zu@x{$Mq7C>*ZidIkEE6@4tYBwLA zNv7r6hja8MIZ)W$M0(~pG}|sZ6l0kv3Z4|E6{IogG3p)eoJZ+ff!Iha(`l-NmzWVrPqM3omy3d| z6#6*&$`c#pyz^H*$E5nCwk$6#r8DyfoBKZYjVxWoAGXx?c^V-T%e+V$tg%^^1}0gU zK5xGWqaZ2w_YgDGdWq+qK48qfkafMQp5C4CJ&Z^Ivh*cw2pt%`{V`#CL2;N@TM-S9 zJCQZ^6dRlS=RtFxJc8tX?+{h%BIc9$Lp<3 zK_Co$Mttk%qu0WNB2`7ujy@C$D~^8msrplKv?p%A2|S1|i_fJXz|*`mO9bWl>f6uM zV0B?yWPIu;7oY*9&e5pW33VqykL`u$d%_)+`)2Irt8hze;)e36Idf7=1z{iir8c3~ z%PQLb{-;yrSMf=TmnYwBPdt&3x?>fTdQ|3XI+2vHw5BK&2heKmAFNs@kB*F{$>Pe_ zI`P5P($7B5g>n#}49L*T9b)lIN-e_{r=Iav;y8|V$Yk@O;>@w{P<4)&B6GdV;C!)~S{cA4Gi zeD2$TqmJwLh-^J~;sNtU5M5^Dz*-jdnfY)w<0;Vq8_F-u$~<7HOJP5&alC;e1d9L- zm_naBV3N9|#m{5ax?6Z+bcOJc@7_-$NydFm3Kq~!luy;@HNMnTu3%ad)pblW6vXmC z$y?0ZX2(ei$|kp*|9o+Xmqt#0LK!zd^nEZ(b9{tGxG2rTS=)o7^Qmqh`jfn_w;02N zYnUHuM`r9T0|*#xbp&V1J1IEkj%X@a`ZmLJ9&;RB_2!l{M?Q|?m?YI?x7Dw+UfnGy zh^^%EI4n|`^o&;dkbmNAVD*q=%U3elW{%ImXbD6Peau<%#X;+{W9phbFzrF0XWURS zaMWIQKa85$DlzB7oI2V38gY66F~Ex{{KcB_@rZ z7P}UkR3nS?i(>*c+G1QrX~G;a8M=;~jR|^v4x9t54@Dt;By~ABJ3mAongK~xhuON) z)h-JoWiB0bZD!)?cx~R*HPl%LM0@rVHTb&cMKb`S^$OZz)50H)3 zsK(gX_U3^(7PI4@6#OrjS8}=gwB{S-=a1(KZ=bg)Q&tyhSGEYc*|#lRo_|fdmX!^u ztv%eM%%(ulJF%C}XW~bV(|pF>%xI!AZxY|(`1Urm3@xR|7hNHap(r*#HjWt>;~a7o z{t6?8osq2W^+cUVe!ZUO3XZ7A6{qkBy@w7Ye$e1jmZt$O+XnfVRJl0xY-;e?@YNoj z7IWs8a(=vDC6FS5HS!T=5J6l7=CsoWmqKX2hJbL~gYxVbQF`um<6H3C2z%FNL{d{g ziID2P5-Ua{X6 zt$zc--hqvBaXv8ZY4YLxp1zQ zg=omCgu~AAKV4_uE}dpSiK+fnVCnCQiRh*j7hINns-UfIp3E|X?Ar3#tUUD8%uF91 zA*R}6!t?dLQZC&jg+l~YX5O@`w6t_7wd^Gx(~nV7xxk0KPwDueo{qoL*6=g^6`p0! zCE7n_9~^p=Go-S-F$MK zA3-zaTvrDcRQtQ1+*M%^&0%s4S%;u))tEe~9$M0%GCPCP97RKE6fYr{5igCOXw~v$ z3RuDwWeTLKXBv?`;%YfB9&1gsoISm6JzL?mT+yyHSk+FI{kmRwCd*o=Lz0R5Tq|_w z`+7^jkX7k){5DHNn%ZNIXXK+^8zMi_A13~MYc36BNLi6lRHDMzD#O^iD33BsX0NQR zP;x2%nb`8e*cQMkV?JaCou)+AYZe;Zcw$UeB+06twSns%?Nnt;+W4Z{F1gAZdwA2L zl(9dW+``>$tbdvGh=lNfG>3(t;YzH$S4Yi;3K2@L(o!vy(i!*Ev5CnS=r&PS9B(y{ zrtiJ9^yVGvBLRqFs@vYT;@WU$ks>p%9_?8l=f0!@)b<%1M3*!)yPJE*G$Bmah>b;5aN8q^*r7N)|QfF&PP zFP3Ti4GsJ*?CHCZPSdg!v8LEyo1DcIMQl%I+{fGzxh6amZ_GMJMxQ+AReHt3PIK6) zZw4Z+eYB5!;AhjIZ>^6MT}{YNKq{l$+h@X8+96l1#+qFEF3o`uvI<{;k1~3O9EHyr z3z`Z#ZG#sSbco*(7$hOoQx<-C&vdp&3C{U)+xo7e?(5%&maXQju;4tK9jn!moZiaKnZU;GOJ-U#KZ(C-ha_>a}U zC>5lI6IxzaUc5nhO8kRe^y+a?Fi{Kzw_>ayvUHhm>ZhSkSuWe3Tij{*e9CNQv#u%Z zjQku&m!-ec4Bdu5&+dF%X)(aG_$bf`ucxfS%WL)IHT-)rec|@urSQ}T>tseN-swwN z+!$7ULS}cDN!_F@WQYC@O>xWGoH5q>$#8r^5fE1YcBGn0)Z~MsH5;*oc{+xlYFRcy zuJjSjx(XjhFW!8XU#v!}%sB)WSSpbe%BW*2hbhZOcWZV$k-#_W&;cp^dWII=hh_S` zTWEtL@K;LBR813j4|j^-JAFL1nolqFgFq+C+cLC3>@qcvS~C=6!-;+YLzdf}O{Oe< z?j5@gYBzW6PijU+pJK|XE_w>8u}Y;Eyj(>#CY|PM9UKL3wT!;caFTkbuM|B1l{~gH zNsY)MQLq5Va5K3HjI6LQO4emo=y{PY4nzYJecpy|=jwKknWq#mO7|GEHHtB-;d;_F zve4RDtmy8QyyYEPiT9QYWiJ^S;S3fRot3xabKdu`@V8pU|ODB zqBw@Hctt%%shZJXXanQviC0`JE|DZBrcsoLey~(my}jJxyUhld)`E2wXik&Vi}+du zCG>}7Rziw`HMNU)7DJhSt;1{@?`-3NgN5C@t;+A`Gx=MF8`_nI>)KmgWd>Ree!kN+ z_3Z-bY^;z^Du&gb;r@GZlZ*bh#|+-rVbZ0~E-tpBOQLF0qZ1Q_q$G`2&4M1o5oJ9p zkLP+%rW<`<~Ji}O2lZQ1IR`Q;MT ztisrc$4FMMj>B(RkA@bjyeGSkKe$&qnQ{6R@9bTH;Vb8Fx}%M*F6PY^zwNtwvfW0- zol}0Dp0^L>JT*qy+RN8%xA_{n6F2fo;B#+U1zAQ7!S4w< zW)~K{QISL!6#78wHTB!0y(Be+AAPQ_#6t!h%Zp-c&-FAj-+c{BZ@hZWTxJRl zS!I4z2TS)T#IF5j-OKX!?W3_+LKmfkm@sVful!04L5*jQZQ;%;--az_Xm!Df{JA`- z`<;9qG9Q1YF#^fV@+oa15W*0VK>Ohp&9*ObI>wKvH?OXERx_WEPP6RD=N|!Yb>-|d zMIlt>m$q@ANxyuhWi(%441Nn9B~_b{s=y>~SrCyxp=b1RXf7SCIWAk!)-@zM`PP$^ z(r6mpL3KbK=Fj%7)2hgw_rpgQRZK&m&LcbRAd*giH^BV$b^KG^Xp^yaKgc^vLC+t< zt$6-lD?#h<;Qn5tRU@S$6R5j)b@WyIbc)?qq5gv%ZFV&#xZc@3MtcD@&BTe+jO?ey z7(X0y-xtrP(B&ly2t%|Pa$SRmB`0kx(Z*7HX@Nhzcmk@WqX~?Ey=o`^Y^9=5VpC!B zrdQ+TGDpx$cEjBkM9v{0=Z!dTBu%EjR4;o3*<_9C&bj;T8e{97N5%!mU{NP-;> zrP6k|_8#*uU*J;cVLq|Q6i4%n!^2}0G98QV|m*{X!e(PN!J$mgr zjyUY`l~DDSq>l11tWMdPV3Q$g$)O4pQ+LGYH$+DLzSloSCgDaI9^DNAN;kAyeQUjX zo!j%9n?@P@$C6%NzOG;fl@}YP;_+Utkm}%xaqI!xv=Lc}>7|4)j*#iPF7}AHms8m3 z3N;-P(?!=g#u(`_S;}}$t;4k;bbgbln9IJQt>K!pUFYS@DUq>aB{7Wo6ou%W?bluB z?PA3WMG0BF6{IEkie1SMlV!oZ0S^a)4O3W8;zrjIfwq~EuP5a6mDoM%^)03%(y@=v z!s{0Iqn5?LXxe`%HBEn_2UMo}tmNibQdFxa36F_FmLDd;K4;CSJI8b-?3jNSX*Kj=NT(_b)=1LLsRwIYu$_X+`OJa!C zyX(~cBkb)prsYG`6q#&{1TVU&cf`$8^pJR=&wkw#7}Bq!uUT%eZ&hx0MNGAmPcDgr zrVPqrcDZ&x(ukhI{odbxqKW7_OL4H|ElV0yIrU5!bf5lkq2PrZ?Wgz-TTP%Yd!3m! zN3adK+B^iaDO45>koC)Lr)s3^_FU!$dMI^ejF*HHDWV_G-au_T^`hjl`k|mL28Oo@AN$*+#%YY4 zG2dbbfx6E&UNtC6#;xe~l;)~zZPIZ_+B($RxzAif9oC+huj~_b`mPw5=6a|KJ`C(U zUty_M$r!3}F6EJ&QDS(sNT5$F?K9jn_{9hIa?zLs@}@ED1uVL-iuz-oYMq+^vZl%- z1|CvqI%<9b`JyC8cbL4HDmiYOmP1-zi1NLA$oEg*XZBiz~d!@GMD(u4`HE=5X zyOa(8hzownJ*VLFr!rQlWKA(j4m{rETZY%<(Z2b$7t>OPS}2|>Owg~6;)IboHueJE z>GfZ?Xde_FP-ldEpK=As&e2A_Dyc%N!Y?V>8<-Jr1$oDrPYx26yPLez>G`=#Q9bO; zb$lJgND%p6x#)HYajV2Szkjrgs)vLAlY|6 zRx6MBEJBW;J~MYn_X`G0B>Qpj08n`=WMMk+nf2QSa@O%9eGXqO)#tK1-5p#u8T3yS zj;S<~!i^C1Z_<~WAW0|GiTu?m7c=BpMyDB0xvsB*4&&7r@mmNWqY z6y=I7&YQoYCLa<%mhpo8vU^#ytZ_mhp>8zt2FbLi%~W#7pA+FwXhxm)#Xg(@r8DSz z{WyV;7`<i(o{riafZ41a@2UCp<> zsvy^!J(zuQMbYgPyfR65@U*)Ue9(s#pT|{tfFk5!Lg;tk>A(5r#Z`;2U)OIHj1-&<3Y;Kzh!UeK!;2DUt)$G-M)Tll96;b!? znnww_a+XYtlB;0s%RP$~mni9Ef&5%UA0|RQ*vEkbjwmNr!S;h_N<6q=M|J9|Xw;*O zDGlm`G#KQgi;C^qS=SB9W@O-57op27O~B|4N&U1q<=~!E^k1gYztr=l@J7;PH!9QYE zcpaB@E^`uVz&<14yj&eJypm__mXcnyXi&DZ7P9Qsrs5e!hZP-%FOf&1UAA*o3!Dx= zUT^I*RZvY<@G+OKHx-nK=)&g0zHp}FvOYqDL+mclBwLxy5fhUNki z+1StZM{xDE?h^>@Czv+!JehWXUIoC%+` zxty4`WV3cs?yc%{xR7*v^9@plzutj;34chrw*kvEyWy!#Sd1F$hw*}?($d1zVM+zD zOwk>JcuJ<>JS^mUuB(}=PxA!$Hgxx)luQfnWQh0{-Yq?dTHPGv3Mca27)RITeG`aH)69CC z354=1C}cI}v!jiS04{Z&OyE3>dG;xe8gMoMl?d1uoQle>#@LNa(*MIL7HmJY7;t@& zmgk3g!fTSPps+`kF#4v-Jx%^6RR<60i5!kxtK;WyfPx1cYT>AXBnlfT9iWj{$Z_0D zV*UgdGoV)zGR*BB6kf7{hEXm%PXq|fiU_}en$dG*)Kw|zHuHO)962N45lcUE9_dqN z(wD;NS>KGP2EB-a*yWk8TIUy*$67C2YYlgd$V8LzkhBg?GMZIf z<9}wynp<7fFdoS%$aFWC9H-WQ50)6IzKjbIO~FnF-o zp`y`YKR_cy!yFdn@sROAKc_!OOO*m+*wfpS80xk3F!e%zfL_zsD@{@URQkE|vKD*g zArl7Eatr-;-X)&bM11so2rOSVK4a_GpI7|K=AuzQ5&60PaL;iWqCcI>DNM{lJ6C)! zzNXg;9WJo;P&}71ZfLi6Az`zs{?YpeyKCq{PiPPO?O>L0VM2EWwofWFwT|W2p1)}- zsY~K_3I)zlm;bU4{vht|^3*(_f0F&6KOlhneEwev`1|a=gazEp)y5g&%T3+H5&loRl!=3ly(fVAuO`5K8_Qpf_9j+v05|xbo?>E7 z9soT62M7oT0yuaeU;qfp#|;31xxoN~-@RlJCiXUFqK;Pf769OHjwsyB;to{62ZsG7 z@8!FvIl$b!zZv2t&N3D@R@R8$)BI+sBP<-W0Iy{n_CE*+H-r<+4dj9F0sb#k?`45;-|4{z zgn)VfUHzldpOP2K`)}3$u>Z4!fPkDZZax^#|Cr>y!@unC{~~yS_w5i6m=nqe=DX7w z2;k-6BAs`SZ38>?{x@vQ9p2|3@UCX8s$C$E`1RuTRlR_DSLh=x*>pENfaYgHC*$InmBfT=&0649hH0~J@AqS&>_5NDf^-ZeX zCj88t$Rk;?JNjpLC&TVK`y;w(^5#Y*$2P5N*-{q~)w9n-wcQe=2p5gR1?&a+Inpc4 zQt9^!`Rba#J`mMBqY^@-3RUK-=8}v8^n|z^Rj2rxU9``%E7y|zi%&)d4VF{~!~Bpr zB^>Ae%XR$+79-^df<7EK=|8*&9 z1N1fFOVN$UhD=Gd4cE%?^9@<`uF85L8oXYHV!2 z^oVdfUeuIQB&o|4@R=6(sU-@=4g+9 1 [labeldistance=2.5, labelangle=45, headlabel="True"] ; -2 [label="player_special <= 6.5\nsamples = 45.0%\nvalue = [0.479, 0.521]", fillcolor="#eff7fd"] ; -1 -> 2 ; -3 [label="(...)", fillcolor="#C0C0C0"] ; -2 -> 3 ; -12 [label="(...)", fillcolor="#C0C0C0"] ; -2 -> 12 ; -47 [label="opponent_attack <= 17.5\nsamples = 2.3%\nvalue = [0.9, 0.1]", fillcolor="#e88f4f"] ; -1 -> 47 ; -48 [label="(...)", fillcolor="#C0C0C0"] ; -47 -> 48 ; -49 [label="(...)", fillcolor="#C0C0C0"] ; -47 -> 49 ; -50 [label="opponent_hp <= 40.5\nsamples = 52.7%\nvalue = [0.156, 0.844]", fillcolor="#5eafea"] ; -0 -> 50 [labeldistance=2.5, labelangle=-45, headlabel="False"] ; -51 [label="player_defense <= 17.5\nsamples = 38.6%\nvalue = [0.075, 0.925]", fillcolor="#49a5e7"] ; -50 -> 51 ; -52 [label="(...)", fillcolor="#C0C0C0"] ; -51 -> 52 ; -59 [label="(...)", fillcolor="#C0C0C0"] ; -51 -> 59 ; -78 [label="player_attack <= 26.5\nsamples = 14.1%\nvalue = [0.391, 0.609]", fillcolor="#b8dcf6"] ; -50 -> 78 ; -79 [label="(...)", fillcolor="#C0C0C0"] ; -78 -> 79 ; -98 [label="(...)", fillcolor="#C0C0C0"] ; -78 -> 98 ; -} diff --git a/HW5/plots/tree_1.pdf b/HW5/plots/tree_1.pdf deleted file mode 100644 index 2e792ddc7e1eda8ffaad32aefcc6c9a5dd3a3f87..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 11795 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 diff --git a/HW5/plots/tree_2.gv b/HW5/plots/tree_2.gv deleted file mode 100644 index 4f312ae..0000000 --- a/HW5/plots/tree_2.gv +++ /dev/null @@ -1,21 +0,0 @@ -digraph Tree { -node [shape=box, style="filled", color="black", fontname="helvetica"] ; -edge [fontname="helvetica"] ; -0 [label="opponent_type_ghost <= 0.5\nsamples = 100.0%\nvalue = [0.361, 0.639]", fillcolor="#a9d4f4"] ; -1 [label="opponent_defense <= 28.5\nsamples = 98.7%\nvalue = [0.352, 0.648]", fillcolor="#a4d2f3"] ; -0 -> 1 [labeldistance=2.5, labelangle=45, headlabel="True"] ; -2 [label="player_type_bug <= 0.5\nsamples = 80.4%\nvalue = [0.254, 0.746]", fillcolor="#7cbeee"] ; -1 -> 2 ; -3 [label="(...)", fillcolor="#C0C0C0"] ; -2 -> 3 ; -58 [label="(...)", fillcolor="#C0C0C0"] ; -2 -> 58 ; -65 [label="opponent_type_dragon <= 0.5\nsamples = 18.3%\nvalue = [0.794, 0.206]", fillcolor="#eca26c"] ; -1 -> 65 ; -66 [label="(...)", fillcolor="#C0C0C0"] ; -65 -> 66 ; -83 [label="(...)", fillcolor="#C0C0C0"] ; -65 -> 83 ; -84 [label="samples = 1.3%\nvalue = [1.0, 0.0]", fillcolor="#e58139"] ; -0 -> 84 [labeldistance=2.5, labelangle=-45, headlabel="False"] ; -} diff --git a/HW5/plots/tree_2.pdf b/HW5/plots/tree_2.pdf deleted file mode 100644 index d9ce5fe38f18acdc3cfce4679cdaa249f29ab1e8..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 11123 zcmch7byQqS_a!7GxO=e1Ay_w!H16&e9D=(O+zC!_2q9Q-x8M@oB}kAUjk`O+GLZL@ z@4fkbGi&}Dn$`E7Q>W}y)xN#%-qebs;!GfBP9*A@{jwV*HUJP{XK0DU%L`zUHL*2w zHV3djxRj9q004`)g|)MZ9FqL z3`Hf7=a8SI=Ox1#~Rr>M$?$^_ZZUDbzctj z^h-Kk0(P#mc=mr1Xj}_~s7=U_*!fP+p+DVpIJ*?g_2pC~k;njnqV?xGWoF*oNu(iK z9SERmv_U3Oi)Vb_-Awr!se594gYMFyn(cCu+^9-gc6IO}V;fm)YNT*W-`)5d`SK|e z;Jf8gBJ=y$keZE1rBMoh58mzx&Gj{De>HkZ(#ShC4)@H{*ulbB;q4@(Gd%-IL^MjhDWM`)? z;dozNN083KU%Q%>tu9g*OZ?4QyjEYBSgwmu9ouvvQjBQ-Q*n$PhA- zYY>i+ix?DkUZ59QefY+HsIE@4=U^m(N^1@x6s4{xvJB-{w{|>_c`X~sFGQ?Hh3vt6 z{B8&Ks*p_)g=mC-5+y(3V>GM+RdTYvf&AI*87Mw~D)K&;B<2LQSZR6irE6w?Z|;#l z0}Pj8;k4Q7eyN}nepY=bdb+ki0o8klUKUr9{R_AdKisbkj5w!1ige82FWz_7Sf@1K z*sm9Qpe=`E6E;G!YYe7^*|pje392W}ndmJ1cUEMdDPbm%U|9)mVgSwuC_WFA`Pt$6 zuHrK47(@}o510m1yeyaDS+9w-*>MD-YX+!S;+@eAyu{%Z@SjW(w_+2dR;ha0Z#=ZuEg1; zobb&?(j^LM7y1Ei2?m8wVH6AWZhvz8V2qyHnVY4Lep&9wTxZC+|Gztf{OJt9qUvsM0$@=vv{Z4n`PKE`Fwgb7CW|}(^s7MJ z!qLeY!1nk3{~h|lD!`@ijqvp+FwY^dy8kl^kFEdC0>|%Rfk6Kl*WbecvHlsye|y|K z=H;(Q5P*w|74om=&$^bUj+)vReXE}r&`s|V{tzcO(viSU*mih?tgJj9xzohJFmy%| z3<|5A@DG|+Q}km8ga+ByMovht4OY+{qaG?|q9@D{@7+NRV_Ywz^t$YGo@=D^J6i zNvm_uQm9V4GgDw_8H;8^&+WveLZ}0zXFQ$dYTb(;6obL4hK5CClQTB+dXAvzv!-dl zFbJf&W7%33IqA}(+n7Rk(-X8F?^P+NlF2lRyM>JMqvwf=e?yxx09WJG#=jy8$e=5j zEgHfH;j(ZWs7RinGE59*k^ZrkWK+DLUt3e_Vg+AQSxn+?1MP(8iG(UAAbdaS1UdRC4G-Txjk!R5DsvC1=vKp7SlOmaQ_? zKuW?l1{>|U^9`3mLh31##;N)zWeU2yx=VG}CH+yAY?`rQr()fs2B0rKn%h-9JxX>P z8Pt4yW~Ym5;s*;=CgtNrP3WQ5DXEN8T|OPz^btODj_cCM95~U6j>#DO@axDFo$J6+ zOrT2TjI|ArW1Bvo8Z66QY7nOzD~HKs5J~Z25-%>r4LETu0Ut6eTcn5eK+ z)3h;Ky{b#ffb^@q5$IDpDB*oIsXJsw>PEMzm9dXxug4PxaCc;LP}GgR;A*doMtUdi zK~+6A^?H6Q(%xPxBuRGFIw?$kGI{uwwq?1{Tu!l@PHQ+xnB#nXUvr<}T1YHOYzKrj zDr&Wdt49nWkPUGbZUJzIRrQv6ISG;^x`oFm_JKqXe}K#DZKtd^X?Jab$}mQF@#xVr z-SZwNI{^<%rHhbOgXytU2i*)6xup>rr;>d8%LB8Nr9`SVgV5^aX>L*dN5Y^!$4FUu%D-CZYdTu@nA zS{mLR6045oO)uBX21=;Fzkqb_$VkzL@$ECl)qU2Aq#Zo$=a+`)S=y3H1K-+L(l_62WN6x0Sd(M?L({hUt ziqp!U+@8pvw3r}Eo(>(OiylgTWu~D1<&v1}!`Qqvs*+7Gv$0%FURF!qa7upc+e5av z+VXR6{4dB-1EE=tA(C*V1y5Bf_`9e+c;(?t;M|p;fn`tMoSsMTM95jmYRhr(36Y}& zjJ@X25H1LecauUGn?rRms^^-=lF71Q+g#=oPId7cDUaq5B{Gsb-f)ZPta%$)m@qDYu%fkS~YF5kLl@q zCfSSG$lD#4co}*PMvh9{0@+qXyyB`}n&Gvn<%UZzU4r__AZ0TKBqZBvL8HiW@>;2B zbFLSpgxKQMJ)UA8hruBE9m^hww6yS{m93R}Y_P6k79IPsqUmkQl^|~>85EX@9BcDk zc$l1$$OdybId-=uHBpbdq%`Z^tZuE%<$;Y!6A{7gP*ED!=ac(IGTBo7^N_MKfs!Hx zo23J8@9ptzmG{ivgZyTTqK(iOIKF3T@KyL@N;q^15=;YS4M8GVBt~X4EDq*3zVAf# z?;xrf--$R~vtrJD1cOq)3(m48M@?n zil!_oJ?*sNhv^cc{W`VQjM;PcHhcI_AB3_CC zeC?QIylw1lB%5KU;=Op=5h!9k6!CIlrcv1ES+J3>pMW(41Aqu22=*tjjWciS9UNMt z7(%tN>*$#=rZMruZEF*_RWn8A8Ve)1_p%O?96-y|qvUKRGxn-v*2zkItvSYHwGP8g zcDL^Lp3&>+LoesAMt$6W%4FP=UjhUU+WcU*w@+}&x$f8F!bSKOD-#kTKTM3@CT&%9 z3}~sdOnC|8A>sev6Q#QBKh}A6B*=iUo`@~+ObLLS1=L&Ol7=h5yR@W}$a2pR2UTZv z@9ujKtRBK3-#10lk!)tttJb@n((29i!=Z7{nAVm9iwBTieWF=v6iq|xS#ruC*dD`}^>qaTxz zSV=NdHp{5lmh^Q%R%^tSgC9^Q(vd8` z+8h{&BajO4lCZtT`;D66a9oNdu6Nyr7o}U>7mTfo8CLMfCm}}xYRlFAI-T0XuC^IswU%eL}=rGYVJ+)?< zHuL7JzVvlx3^{vcrLMO|VVJ0{SnLnSNb`vxtx$qO2Z9JnzEO-Z92$$z$*jq6i&v%8 z!-Pes8EYylg~i3ix+V&UMln5w%_9CZTy!9ACTlA_co9*1** zvF7@)USwa_lH;)TT+bI78pj>!Jv|O@zLw0RQx~USFFQT6)h||DN-CZ|AK)o3UOQYC zEB0_$hV$VKbVH}wv8hVS)?(dG(jTOeiV0#PSLws%hKprJkgmO!XJZS!$e2rX73kCf zk$LMX7=H(mKH zZ}CQay|c_KIT1bnMVN@%z_&7(f#`6ex$A<7WR4nmgAF`)EDU&G%@VlF4zBCDw7Yxb z9puK<^rNx)y}gFdpFf+alk%TfE*-^|?K@TB52t-hdn)o&_w?z(KprKJD+lQYhn;6_ zMM;Uhu4a2Kr3AAc@3?d9;7bNCm$_QA=_LHyTl6vK+OOZ_=TV^rt6iPXqwBr=k;sBn}HX865J(P6gqBA_`&Eq|`HgW$_^T zFOUzO34@zR^%SyWuxwT~qikI=t<9Zaf- z@RbM^6&tGKv%+>q$v3pWJu=&Hs)7677p(a4;{xntc-qd)H+F*7Q4C5;0uICo9MF7(krS}>2U}+R7X=|J5gxCtBLpXYDL#V&&nJKdj?@j z_JT1aV!lXjGM~UbBhK@)E#5+LtG(ukAR;O6eZ~`rFw>a|BJD?XsgsXXSy^>?HGZCi zUJ4;`q@l)$DX%TumgGzD5;f6{Vi-(Y?>{~<_8&06($C4&Q}(94J|RE^+Me$2iCmm_ zs6^*w_}tDE_AJ1oC8~Y7A1^UdVC0EE#%2G4;NyCl*Xnh6*~-aQ*nIZAijUzWXvu}rX2}eFh*ZL$I{m^5-FLv66WFy@oG|FJ{vy~Hm zh1H@@_kA8#l$f(CnOX5(<=AD669SbihcLA!?UQm0bj(~kzT#Q^Wzr?&9f*F-h0m+O zC>6rtNE(4wLpp2f6L?*ZoN@%`?)X?$vb0 zjjctrEGpQvYucLUgE46VqVHzCDVS*Hh7IG>k;gIK$&aQm25-BVEW9+ooV?!9uKChf zGiI%_t)Z=qpI1VaTagoDERjOFB>0qDv01VxMlz$S>60SmL4M=jjro(Cg37XkHl?w9 z$Jv#=@iMrp0_UFCJ34i)jl{w&b$R8mAt3J);j~vnB(H`TS97OJ=44@SOw-{Y6x&=y zuECN3@s||b1ve`w`d#UGN<<=P4;ExXz~qy>$wjO8h<@-#N1b(3-#oMAlYCCj zr!x}Lb2Jt3@c6^zx(Q@OZw=S%Df*K{o-x3uN)z-TYZUus?xA2{7PoyKZuxeP#&b^N z(_M8MWvDR#A!wwTo#Hk$4z~W-tAyDRq-s!g1pF4ut(3iHTpoB`Q1>Fr)z>Gz>cDup zBXy*vqYcWJK%9_^WU?F@R+30rh$su!#+L3UgxywM|4QPW#|lnO^H|B6gouZLCio@u z@+q)r zXD(gD-9ki@NhKC4Bg5_^K^WLrhlJb;Wc(3l7MxpM{kDd(HA}qA4~K;}K529}oODgW zvWdeK>f%!;sy#0h@T!#=ObOInrNUHEXR<|$cVuL$@2-(3xH)4Bx*FKyok=baG5=gkyj#}GP0p!}p(?-? zxO=*M?Mx+K8)nkn*ufc7Vs0PXtXF8I^>Ol@YVMQrIs!V~%%p-HtdX|c177CRrh})s zSE)J^e8LOyy>3Oqso=8}7Pc2mjXjFJ;xZy#7eK?$3q+PUmFA5tl#3y)w7&kWuC`wm zE9uFKD=4n2e1Epwbk8-NWWOM4c*|eEe$Z;9z@PsjcYEFBM;2;}{ab5Hec>f`3xpX_ ztQ_?_W=Vg|JCejkJ^#hpoD1kxPl>G9h(TS@m0^8?K`o|^kJ57Ex&KL(&79bry7gWn zgZ0__#qszIy}aRlh<;+qT*8m}DzWUL{7+r4R|BizHi?|>F6xE)+c`qgCa!|#l!G1A zAjX>RukRY)WR<49Yq+H+I^TbPcE_N;)s*vI2uA7tg$Wfe=hLsuL(YOjIeurOnrspL za=tQk_OuN$=>!T{W(oOIM3WQQw`rkpTX$^Ohvf%NWN$B3>=u3=`qGU!gdJq!R%1mA zE;?XEPpJNgNL-$ZM>}_d2~+usIm0+J)YrpDg>tM$v8%Bw^3`*n|>8TX?&@#n@|7tIpdz)7^8FMK(HslBujQpn$q-pY3mv^>lBDZ146CPf}? zg`n`8yb3$T#wFpc(7n$W|JIHSO3EvfTQ2^1eermM_dto6Kqg%1rgf-uLXJ*J9_#eiH~h`CkAt{I^cV@T4+F_grV=r*sPj zjZr!P7TB+HG>Kiog;0HvHyZ>B+J|y-8;HALR-o&H3Z&(UMFYQolJjNfhM=*g`cc) zxY3~^6w_%NT<@~pr!Kzv>gYptuve#z6s_K>IPR={IOWX;HwVJsP2@_9yX{D7rEL=` zh$tw`@*3L`z6tn@c00=rJ-pd#ZTj(jNoZnx!+ocb7COPX(>3H-VK>ElTcl&ad7;oO z(ULE#MSFGZDs7rZ>sh(!zU{tPu$dboj!N_Li6b&mI%(6zs=jv5t>C=YWXRW6o{Hk1 zUaPBR+Z!lpRo+?iIW6*0*B+_lw#nb$Me~@YfUmFZes*PtY@F!FQNB{;rnT&v4tf;diq^X)V@J$R$6@q%!#ROyIJ5Eg!73X?yjKDdcBXK6c)U7f&Cd7|pu3wVL+{ zG;rTaC;6lmAzWE&tZt&BltMH)a$IWWD1BoWnm61Pe7N)cb?4@p+agdL*2sFGAqfLJ z%HSTcov61W^FGJ)t;QJ}!^K>T_N-#B(A=oqbMiGK6+w14N^)|DzT{J3a1=@SVeluT zAim<;uYpDDZj!W5`wdf(A`nli3~{0D&sIO!Elu_DJ-j`fT{aWAO@QMZSe5|awk>f7 z`d%%2f^S=hxo_?Fe>4SIp_C3;q+^VvA!^daClYN z;CUUp2ONpfdZoi;fUXkS*Qu_GN$!==-V^9lx3`uDD@3(r5PC&M`!>H|u7)z`XrPu} zcKi?!L)av|rGLV2ctjp3za2jb_;0-J(nP413@~LDsW#!+zL|$2G>O+prSzes|DR|5Sm+p1hA`Z>+34d<4GDye30xDaS4%+%u^NX}2X( z1-W^@*L34UbosDcLyWLQ>F+qxpLwE|t=PY$MycA2MWedb#=t|hoCusDZy)q<3v0h{ zjIT%&YCs$~%B^yoshwoBCW6r(uE@pau;Zq%HmxXh_OIARu-58)|78nb8egz*sC6p@ zpTK$^C_2;kx)Z~V^!<<91;vw8A-c*=CrN|KYzTa~qKcT0hFy>uVF^Pu(k=mxmH|^B zI|>p(A786(i`ErW;AF9Z8roVu&s#5n65}J3!2IEg4g`g51Fk??9s^BU-Z4ZO9`fjR ztmi*_mOw1G!R^^o#~s<9moT44sCRa{#SSi!Kj%WJB4jj-VMk)+G5Cau2Xymm_j*ov zdL}GRJ2cTbzXUX}#TqgI5}Bp*k&cr9BcwY@6zdn!!1>P+!Gt-4OX?`5^R$Ryf_d6@ z=jRhgBW%xA@+CXI0g|ySu<|5<-{CGLg*!-p&Kl@|(gQWY z?wMUK1K}+*6Gal*VDU|Gs0tez^M)$_Cm$=I(8<{+jP2+;%(i z8iFOYJK2IoYtwt397N?$grfSS!;fP$^_*qY|0ljr-_Kf@pC_~@0x>?Jg1~HlSjGQPtG~HI0O(QI^8Y4c(N$@;O$FjK-!OQ|qGOhz(!`ERt9g7E884di zftiU$Rh|a0c+Rwz_kNbnA#UqD9Rm9B7QOF`7D?sQy_1d*7|6@#3Z{C$p3=OfB=4lk zlij&jccap9b6QdKG9tQekY-aP6>svg@j8u@MZ0l3uVYgEw$}b7cVEK3-oqP6NJLrq)iK7&ee(k8=e_vj&DwB|b@yILA4Eq@covIL zS|xAY!#4tQp41?(?^XwK4kw2q$}JyRYsyZuuFIGqEDg*h$o4Yx0TVG3#`DT^c>Cbp zuS>3Lu5Aik3QHP});+<8tZwhmpKVgF3KIMES1u83fclI+^io96jrqdMmIh9ZP2egx zGD3p2R7O^kdtpCAKS85-rxBRI+QzkO+DE8&a>twBnMRS!&F-?+_7$roWh z3*g;V?tK(nWUQ$@`%wSvpkP1KX6t*~MCE}Z=Na1(+fWidO6Og%5hJjb>~y1?eqD({ zM9&muf?eW47BpoNRHXA0Hu(N)^MBa`zx7HFyf7OG{AUaNCfy(T^S=o1N48wl#L39f z!rs}=@h?vM!6k2C^T37+Ysv}<$ufwVSQ@-~qhes|^ru|hz{bMb9YFV25#X_m{;xu7 z12ZQ8nDtMju&|vQKpVgW06#(*A{YOLcxA8c` z2g=;!q2othUHKpU|D!74@ud7a9e=g=#?bkfB0$ygjmcxGetCrroJ@Y{3;s{3d6Wi- zm>W3$&Va1J-!_Q#Z}Gst@(lp}M@1%P`yd>%ur&j)s9V?y**aPLcKqsD-NM+}-02~a zU=SxWgcAhhdR*eaK3wcTW)K%U_}9q?0>E4kCYXa0#P!eH$IyS({g=T3=3r(81KBvZ z0RJCuAIAa#Kg@#*$id3~&)eTq`h8{RWdG;Xe!KsD81Rog{BH(3 z@Uff&#LCRc#me<-&TPz_9PE#SdGLe(7#tw>hqSPPIoSbVc2;H}JCG9s`d0uL%*^>~ z8V?m8KdhV&(*m;s!4EnNPB!L;Wq({Lj{k&lfI!R;5CWL7B+K0eKkKW1s&pf1Rj@vu&qlYw@T<1b`k<|DSsv z^jPEHn_l66h+aUC%9y{N3-W)IE)QE9zzY7g8~>XGf9I9%GKFuxWO`J|nN#ZnbZW zd_FP#cNpk-cVFpUn1hs;Q)K|a3uz&k?h+&3=g@lbQ_*=1.24.0 +pandas>=2.0.0 +scikit-learn>=1.3.0 +scipy>=1.10.0 +joblib>=1.3.0 +graphviz>=0.20.0