Skip to content
Merged
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
8 changes: 7 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,8 @@
.idea
__pycache__
.coursecreator
*.pyc
*.DS_Store
*_windows
venv/
.idea/
*-remote-info.yaml
3 changes: 3 additions & 0 deletions L01/Welcome/main.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
if __name__ == "__main__":
# Write your solution here
pass
4 changes: 4 additions & 0 deletions L01/Welcome/task-info.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
type: theory
files:
- name: main.py
visible: true
41 changes: 41 additions & 0 deletions L01/Welcome/task.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
This course contains programming assignments for our <a href="https://www.coursera.org/learn/algorithmic-toolbox/">Algorithmic Toolbox</a> course on Coursera,
which is part of the <a href="https://www.coursera.org/specializations/data-structures-algorithms">Data Structures and Algorithms specialization</a>.
Here you will find the tasks used to study core algorithmic ideas and develop practical problem-solving skills in Python.
We encourage you to explore this material and learn it step by step, just as thousands of talented learners around the world have done.

A particular goal of this framework is to help you to learn how to
write efficient, reliable, and compact Python code. The PyCharm IDE
will make the learning process smooth and enjoyable: it will help
you with testing and debugging as well as structuring and formatting your code.

The assumed pipeline is the following.
For each programming challenge in this course:
<ol>
<li>Design an algorithm, prove that it is correct and has the expected asymptotic behavior.</li>
<li>Implement it in Python here, in PyCharm.</li>
<li>Implement unit tests and stress tests for your solution. If a bug is found, fix it and test again.</li>
<li>By pressing the play button on the right pane, check your solution against a few test cases.</li>
<li>Finally, make sure that your implementation works correctly and that all tests pass.
When you are ready, move on to the next programming challenge on Coursera.</li>
</ol>

Enjoy!

### Getting Started

1. We assume that you are already familiar
with basic Python programming. To refresh
your Python skills, you may want to take an
Introductory Python course here
(File -> Learn and Teach -> Browse Courses).

2. To get familiar with PyCharm,
take a look at the
<a href="https://www.jetbrains.com/help/pycharm/getting-started.html">Start Guide</a>.

3. The <a href="http://bit.ly/2ETCmR6">companion MOOCBook</a> contains
detailed statements of all 30 programming challenges
from this course as well as good programming practices
and solutions for selected problems.

Now that you know how this course is organized and which tools you will use, let’s move on to the first programming challenge.
3 changes: 3 additions & 0 deletions L01/lesson-info.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
custom_name: Introduction
content:
- Welcome
Binary file added L02/T01/images/check.gif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added L02/T01/images/check_dark.gif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added L02/T01/logo.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
8 changes: 8 additions & 0 deletions L02/T01/sum_of_two_digits.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
def sum_of_two_digits(first_digit, second_digit):
assert 0 <= first_digit <= 9 and 0 <= second_digit <= 9
return first_digit + second_digit


if __name__ == '__main__':
a, b = map(int, input().split())
print(sum_of_two_digits(a, b))
23 changes: 23 additions & 0 deletions L02/T01/task-info.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
type: edu
custom_name: Sum of Two Digits
files:
- name: sum_of_two_digits.py
visible: true
placeholders:
- offset: 121
length: 26
placeholder_text: "# TODO: write your code here"
- name: tests/sum_of_two_digits_unit_tests.py
visible: true
- name: tests/tests.py
visible: false
- name: logo.png
visible: false
is_binary: true
- name: images/check.gif
visible: false
is_binary: true
- name: images/check_dark.gif
visible: false
is_binary: true
feedback_link: https://www.coursera.org/learn/algorithmic-toolbox/programming/sLjtY/programming-assignment-1-sum-of-two-digits/discussions
38 changes: 38 additions & 0 deletions L02/T01/task.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
# Programming Challenge: Sum of Two Digits

<center><img src="logo.png" height="200px"></center>

## Implementing a Solution
Implement the `compute_sum` function that takes two digits (that is,
integers in the range from 0 to 9) and returns the sum of these two digits.

We start from this ridiculously simple problem to show you the
pipeline of designing an algorithm,
implementing it, testing and debugging your program.

For this trivial problem, we will skip “Designing an algorithm” and "Implementing"
steps and will move to testing.

## Testing
Switch to the file `sum_of_two_digits_unit_tests.py`.
It contains unit tests for your implementation. If
you haven't heard about unit testing before, we
encourage you to read about it in
<a href="https://docs.python.org/3/library/unittest.html">this official
doc article</a>
or to take a short course here, in PyCharm
(through File -> Learn and Teach -> Browse Courses).

For this starting programming challenge, we've already
implemented everything for you. Press the blue `Check`
button at the bottom of the theory section, to run the
tests and make sure that all tests pass successfully.

<img src="images/check.gif" width="800">

In this challenge, the space of all possible inputs
is so small that it is possible to check just all possible
test cases: the `test_all_inputs` method goes through all
pairs $0 \le a, b \le 9$.

<div class='hint'>Just type "first_digit + second_digit"</div>
13 changes: 13 additions & 0 deletions L02/T01/tests/sum_of_two_digits_unit_tests.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import unittest
from itertools import product
from L02.T01.sum_of_two_digits import sum_of_two_digits


class TestSumOfTwoDigits(unittest.TestCase):
def test_all_inputs(self):
for first_digit, second_digit in product(range(10), repeat=2):
self.assertEqual(sum_of_two_digits(first_digit, second_digit), first_digit + second_digit)


if __name__ == '__main__':
unittest.main()
14 changes: 14 additions & 0 deletions L02/T01/tests/tests.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import unittest
from itertools import product
from L02.T01.sum_of_two_digits import sum_of_two_digits


class TestCase(unittest.TestCase):

def test_all_single_digit_combinations(self):
for a, b in product(range(10), repeat=2):
self.assertEqual(a + b, sum_of_two_digits(a, b), msg=f"Wrong answer for a={a}, b={b}")


if __name__ == '__main__':
unittest.main()
Binary file added L02/T02/images/run.gif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 4 additions & 0 deletions L02/T02/images/run.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added L02/T02/images/run_dark.gif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 4 additions & 0 deletions L02/T02/images/run_dark.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added L02/T02/logo.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
25 changes: 25 additions & 0 deletions L02/T02/maximum_pairwise_product.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
def max_pairwise_product_naive(numbers):
assert len(numbers) >= 2
assert all(0 <= x <= 2 * 10 ** 5 for x in numbers)

product = 0

for i in range(len(numbers)):
for j in range(i + 1, len(numbers)):
product = max(product, numbers[i] * numbers[j])

return product


def max_pairwise_product(numbers):
assert len(numbers) >= 2
assert all(0 <= x <= 2 * 10 ** 5 for x in numbers)
numbers = sorted(numbers)
return numbers[-1] * numbers[-2]


if __name__ == '__main__':
n = int(input())
input_numbers = list(map(int, input().split()))
assert len(input_numbers) == n
print(max_pairwise_product(input_numbers))
31 changes: 31 additions & 0 deletions L02/T02/task-info.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
type: edu
custom_name: Maximum Pairwise Product
files:
- name: logo.png
visible: false
is_binary: true
- name: maximum_pairwise_product.py
visible: true
placeholders:
- offset: 427
length: 62
placeholder_text: "# TODO: write your code here"
- name: tests/maximum_pairwise_product_unit_tests.py
visible: true
placeholders:
- offset: 409
length: 49
placeholder_text: "# TODO: write your test here"
- name: tests/tests.py
visible: false
- name: images/run_dark.gif
visible: false
is_binary: true
- name: images/run.svg
visible: false
- name: images/run_dark.svg
visible: false
- name: images/run.gif
visible: false
is_binary: true
feedback_link: https://www.coursera.org/learn/algorithmic-toolbox/programming/Xscmz/programming-assignment-1-maximum-pairwise-product/discussions
74 changes: 74 additions & 0 deletions L02/T02/task.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
<center><img src="logo.png" height="200px"></center>

Given a list $A$ of non-negative integers, find
the maximum product of two distinct elements (that is,
the maximum value of $A[i] \cdot A[j]$ where $i \neq j$;
note that it may be the case that $A[i]=A[j]$).
The length of $A$ is at least 2 and at most $2 \cdot 10^5$,
all elements are non-negative and do not exceed
$2\cdot 10^5$.

# Naive Algorithm

The source file `maximum_pairwise_product.py`
contains an implementation of a naive algorithm
that just goes through all possible pairs. While it is
clearly correct, it is too slow. To enusre this,
make the following experiment. Add the following
three lines to the end of the file:
```
n = 10
A = [0] * n
print(max_pairwise_product_naive(A))
```
This code creates a list $A$ of size
$10$ filled with zeros. It then passes it to the
function `max_pairwise_product_naive` and prints
the result. To see the result, press the
`Run` ![](images/run.svg) button. It will print the result (0) in the
Run area on blink of an eye.

<img src="images/run.gif" width="800">

Now, change the value
of $n$ from $10$ to $10^5$ by replacing `10` with
`10**5` and run the resulting program again.
You'll see that it hangs.

# Fast Algorithm

See the materials of the first week at Coursera
to implement a faster algorithm as `max_pairwise_product`
function.

# Testing

After implementing the function `max_pairwise_product`,
start testing your solution. For this, switch to the file
`maximum_pairwise_product_unit_tests.py`. It contains
several unit tests that ensure the correctness of
your program. The function `test_small` checks your
function against a few manually created tests.
The function `test_stress` generates a few short
lists and checks whether your function returns the same
as the naive one. Finally, the function `test_large` checks
your function against massive datasets: the first one
is a list of size $2 \cdot 10^5$ filled in with 4's, the
second one is a list $[0, 1, \ldots, 10^5-1]$.

Add one more unit test and run it. Ensure that all tests pass.


# Checking Your Solution

When all unit tests pass, check your solution by
pressing the "Check" button.


<div class='hint'>Use some small list for which you are able to compute the result by hand</div>

<style>
img {
display: inline !important;
}
</style>
30 changes: 30 additions & 0 deletions L02/T02/tests/maximum_pairwise_product_unit_tests.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import unittest
from random import randint
from L02.T02.maximum_pairwise_product import max_pairwise_product_naive, max_pairwise_product

class TestMaxPairwiseProduct(unittest.TestCase):
def test_small(self):
self.assertEqual(max_pairwise_product([1, 2, 3]), 6)
self.assertEqual(max_pairwise_product([9, 3, 2]), 27)
self.assertEqual(max_pairwise_product([7, 3, 7, 2]), 49)
self.assertEqual(max_pairwise_product([1, 2]), 2)


def test_stress(self):
number_of_iterations = 10
array_size = 100
max_number = 2 * 10**5

for _ in range(number_of_iterations):
numbers = [randint(0, max_number) for _ in range(array_size)]
self.assertEqual(max_pairwise_product(list(numbers)), max_pairwise_product_naive(numbers))


def test_large(self):
self.assertEqual(max_pairwise_product([4] * (2 * 10**5)), 16)
self.assertEqual(max_pairwise_product([x for x in range(10**5)]), (10**5 - 1) * (10**5 - 2))
self.assertEqual(max_pairwise_product([1] * (2 * 10**5)), 1)


if __name__ == '__main__':
unittest.main()
35 changes: 35 additions & 0 deletions L02/T02/tests/tests.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import unittest
from L02.T02.maximum_pairwise_product import max_pairwise_product


class TestCase(unittest.TestCase):

def test_two_elements_ascending(self):
self.assertEqual(2, max_pairwise_product([1, 2]), msg="Wrong answer for A=[1, 2]")

def test_two_elements_descending(self):
self.assertEqual(2, max_pairwise_product([2, 1]), msg="Wrong answer for A=[2, 1]")

def test_small_array_ascending(self):
self.assertEqual(15, max_pairwise_product([3, 5]), msg="Wrong answer for A=[3, 5]")

def test_small_array_descending(self):
self.assertEqual(15, max_pairwise_product([5, 3]), msg="Wrong answer for A=[5, 3]")

def test_equal_elements(self):
self.assertEqual(49, max_pairwise_product([7, 7]), msg="Wrong answer for A=[7, 7]")

def test_three_elements_with_duplicates_at_end(self):
self.assertEqual(25, max_pairwise_product([5, 1, 5]), msg="Wrong answer for A=[5, 1, 5]")

def test_three_elements_with_duplicates_at_start(self):
self.assertEqual(25, max_pairwise_product([1, 5, 5]), msg="Wrong answer for A=[1, 5, 5]")

def test_large_array(self):
array = [i + 1 for i in range(10**5)]
expected = (10**5 - 1) * (10 ** 5)
self.assertEqual(expected, max_pairwise_product(array), msg=f"Wrong answer for A={array}")


if __name__ == '__main__':
unittest.main()
4 changes: 4 additions & 0 deletions L02/lesson-info.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
custom_name: Programming Challenges
content:
- T01
- T02
Loading
Loading