Skip to content

Lab 6 #9

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 10 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
73 changes: 55 additions & 18 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,24 +1,61 @@
# Lab-1
# Lab 6 - Dynamic Programming

## Task
Implement a sorting algorithm - HeapSort(ascending/descending)
In search of the Holy Grail, Indiana Jones faced a dangerous trial.
He needs to go through a rectangular corridor, which consists of fragile plates
(recall a scene from the movie "Indiana Jones and the Last Crusade").
There is a letter written on each plate:
![](readme_images/corridor_example.png)

## Result output
- Algorithm's name
- Execution time
- Counters: swaps, comparisons
- Sorting result
He can start from any plate on the left edge. There are 2 exits: the most right
top and bottom plates. (a and f in the example above)

## Code must be covered with tests
- sort the input array
- sort in ascending order of sorted array in ascending order
- sort in descending order of sorted array in ascending order
- sort in ascending order of sorted array in descending order
- sort in descending order of sorted array in descending order
There are 3 rules for Indiana to move:

1. After each step, Indiana must be more right than he was before.

![](readme_images/moving_rule_1.png)

2. You can always move to one plate on the right.

![](readme_images/moving_rule_2.png)

3. In addition to moving to one plate to the right, you can jump to any plate
with the same letter if it's on the right. For example, you can jump from the letter a
to any other the letter a, provided that it's on the right.

![](readme_images/moving_rule_3.png)

For a given corridor calculate how many ways there are to pass it successfully.

---

## Input
The input file ijones .in consists of H + 1 lines.
+ The first line contains two numbers W and H, separated by a space: W - width of corridor,
H - height of the corridor, 1 ≤ W, H ≤ 2000.
+ Each of the next H lines contains a word with length W, which consists of lowercase Latin letters from a to z.

---

## Output
Output file ijones.out contains only one integer - the number of different ways to pass the corridor.

---

## Algorithm
Main idea: number of paths to random plate C is a sum of numbers of paths to all plates from which we can get to C.
With this idea we can build recursive algorithm and with the help of cash of results we can make this algorithm effective

<b>Complexity = O(W * H)</b>

---

## How to run
- 'cd' into folder where you want to store this repository
- Clone this repository with command 'git clone https://github.com/yeldmitrenko/Algorithms_Labs.git'
- Choose branch lab_1 with command 'git checkout lab_1'
- Go into folder with files with command 'cd Algorithms_Labs'
- run command 'python main.py'
+ `cd` into folder where you want to store this repository
+ Clone this repository with command `git clone https://github.com/yeldmitrenko/Algorithms_Labs.git`
+ Choose branch lab_3 with command `git checkout lab_6`
+ Go into folder with files with command `cd Algorithms_Labs/Lab_6`
+ Insert input in a file `ijones.in`
+ Run command `python3 ijones.py` on Mac/Linux or `py ijones.py` on Windows
+ You will get output in `ijones.out`
64 changes: 0 additions & 64 deletions heap_sort.py

This file was deleted.

4 changes: 4 additions & 0 deletions ijones.in
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
3 3
aaa
cab
def
1 change: 1 addition & 0 deletions ijones.out
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
5
45 changes: 45 additions & 0 deletions ijones.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
from collections import defaultdict
from typing import List


def find_ways_count(corridor: List, columns: int, rows: int):
memorized_path = defaultdict(int)
plates = [[1] for elem in range(rows)]

for row in range(rows):
memorized_path[corridor[row][0]] += 1

for column in range(1, columns):
all_ways = {}

for row in range(rows):
plate = corridor[row][column]

if plate is not corridor[row][column - 1]:
cur_way = plates[row][column - 1] + memorized_path[plate]
else:
cur_way = memorized_path[plate]

plates[row].append(cur_way)
all_ways[plate] = cur_way + all_ways.get(plate, 0)

if column < columns:
for plate in all_ways:
memorized_path[plate] += all_ways[plate]

if columns == 1:
return plates[0][columns - 1]

return plates[0][columns - 1] + plates[rows - 1][columns - 1]


if __name__ == '__main__':
input_file = open("ijones.in", "r")
row, column = map(int, input_file.readline().split())
corridor = [[] for _ in range(row)]
for plate in range(column):
corridor[plate] = input_file.readline()
input_file.close()

output_file = open("ijones.out", "w")
output_file.write(str(find_ways_count(corridor, row, column)))
54 changes: 30 additions & 24 deletions test.py
Original file line number Diff line number Diff line change
@@ -1,28 +1,34 @@
import unittest
from heap_sort import heap_sort
from copy import deepcopy

from lab6.ijones import find_ways_count

class TestHeapSort(unittest.TestCase):
def setUp(self) -> None:
self.array_example = [1, 2, 56, 45, -9, 78, 11]
self.array_sorted_asc = [-9, 1, 2, 11, 45, 56, 78]
self.array_sorted_desc = [78, 56, 45, 11, 2, 1, -9]

def test_sort_asc(self):
self.assertListEqual(heap_sort(deepcopy(self.array_example), "asc"), self.array_sorted_asc)

def test_sort_desc(self):
self.assertListEqual(heap_sort(deepcopy(self.array_example), "desc"), self.array_sorted_desc)

def test_sort_asc_in_asc(self):
self.assertListEqual(heap_sort(deepcopy(self.array_sorted_asc), "asc"), self.array_sorted_asc)

def test_sort_asc_in_desc(self):
self.assertListEqual(heap_sort(deepcopy(self.array_sorted_asc), "desc"), self.array_sorted_desc)

def test_sort_desc_in_asc(self):
self.assertListEqual(heap_sort(deepcopy(self.array_sorted_desc), "asc"), self.array_sorted_asc)

def test_sort_desc_in_desc(self):
self.assertListEqual(heap_sort(deepcopy(self.array_sorted_desc), "desc"), self.array_sorted_desc)
class FindWaysCountTest(unittest.TestCase):
def setUp(self) -> None:
self.matrix1 = [
["a", "a", "a"],
["c", "a", "b"],
["d", "e", "f"]
]
self.matrix2 = [['a', 'b', 'c', 'd', 'e', 'f', 'a', 'g', 'h', 'i']]
self.matrix3 = [
["a", "a", "a", "a", "a", "a", "a"],
["a", "a", "a", "a", "a", "a", "a"],
["a", "a", "a", "a", "a", "a", "a"],
["a", "a", "a", "a", "a", "a", "a"],
["a", "a", "a", "a", "a", "a", "a"],
["a", "a", "a", "a", "a", "a", "a"]
]

def test_first_case(self):
self.assertEqual(find_ways_count(self.matrix1, 3, 3), 5)

def test_second_case(self):
self.assertEqual(find_ways_count(self.matrix2, 10, 1), 4)

def test_third_case(self):
self.assertEqual(find_ways_count(self.matrix3, 7, 6), 201684)


if __name__ == '__main__':
unittest.main()