Skip to content

Commit ff0efef

Browse files
committed
Up to two fer
1 parent 8eff1e1 commit ff0efef

File tree

103 files changed

+3265
-59
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

103 files changed

+3265
-59
lines changed

.DS_Store

2 KB
Binary file not shown.

README.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,7 @@ Exercises from the main track are:
8080
- ![#E8C14E](https://placehold.it/10/E8C14E/000000?text=+) [saddle-points](saddle-points) ([_.py solution_](saddle-points/saddle_points.py))
8181
8282
Extra exercises that I think are interesting:
83-
- ![#E8C14E](https://placehold.it/10/E8C14E/000000?text=+) [bank-account](bank-account) ([_.py solution_](bank-account/bank_account.py)): decorators and errors:
83+
- ![#E8C14E](https://placehold.it/10/E8C14E/000000?text=+) [bank-account](bank-account) ([_.py solution_](bank-account/bank_account.py)): concurrency, decorators and errors
8484
- ![#FF7C63](https://placehold.it/10/FF7C63/000000?text=+) [flatten-array](flatten-array) ([_.py solution_](flatten-array/flatten_array.py)): Python stack discussion (iterative array flattening)
8585
- ![#E8C14E](https://placehold.it/10/E8C14E/000000?text=+) [binary search tree](binary-search-tree) ([_.py solution_](binary-search-tree/binary_search_tree.py)): basically a simpler version of the array flattening problem (same techniques involved)
8686
- ![#FF7C63](https://placehold.it/10/FF7C63/000000?text=+) [rectangles](rectangles) ([_.py solution_](rectangles/rectangles.py)): interesting algorithmic problem (if you have a simpler solution I'm interested)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
{}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
[
2+
"armstrong_numbers_test.py::ArmstrongNumbersTest::test_four_digit_number_that_is_an_armstrong_number",
3+
"armstrong_numbers_test.py::ArmstrongNumbersTest::test_four_digit_number_that_is_not_an_armstrong_number",
4+
"armstrong_numbers_test.py::ArmstrongNumbersTest::test_seven_digit_number_that_is_an_armstrong_number",
5+
"armstrong_numbers_test.py::ArmstrongNumbersTest::test_seven_digit_number_that_is_not_an_armstrong_number",
6+
"armstrong_numbers_test.py::ArmstrongNumbersTest::test_single_digit_numbers_are_armstrong_numbers",
7+
"armstrong_numbers_test.py::ArmstrongNumbersTest::test_there_are_no_two_digit_armstrong_numbers",
8+
"armstrong_numbers_test.py::ArmstrongNumbersTest::test_three_digit_number_that_is_an_armstrong_number",
9+
"armstrong_numbers_test.py::ArmstrongNumbersTest::test_three_digit_number_that_is_not_an_armstrong_number"
10+
]

armstrong-numbers/.solution.json

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
{"track":"python","exercise":"armstrong-numbers","id":"369d7861d45c48c29b291a4747a89292","url":"https://exercism.io/my/solutions/369d7861d45c48c29b291a4747a89292","handle":"cglacet","is_requester":true,"auto_approve":false}

armstrong-numbers/README.md

+61
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
# Armstrong Numbers
2+
3+
An [Armstrong number](https://en.wikipedia.org/wiki/Narcissistic_number) is a number that is the sum of its own digits each raised to the power of the number of digits.
4+
5+
For example:
6+
7+
- 9 is an Armstrong number, because `9 = 9^1 = 9`
8+
- 10 is *not* an Armstrong number, because `10 != 1^2 + 0^2 = 1`
9+
- 153 is an Armstrong number, because: `153 = 1^3 + 5^3 + 3^3 = 1 + 125 + 27 = 153`
10+
- 154 is *not* an Armstrong number, because: `154 != 1^3 + 5^3 + 4^3 = 1 + 125 + 64 = 190`
11+
12+
Write some code to determine whether a number is an Armstrong number.
13+
14+
## Exception messages
15+
16+
Sometimes it is necessary to raise an exception. When you do this, you should include a meaningful error message to
17+
indicate what the source of the error is. This makes your code more readable and helps significantly with debugging. Not
18+
every exercise will require you to raise an exception, but for those that do, the tests will only pass if you include
19+
a message.
20+
21+
To raise a message with an exception, just write it as an argument to the exception type. For example, instead of
22+
`raise Exception`, you should write:
23+
24+
```python
25+
raise Exception("Meaningful message indicating the source of the error")
26+
```
27+
28+
## Running the tests
29+
30+
To run the tests, run the appropriate command below ([why they are different](https://github.com/pytest-dev/pytest/issues/1629#issue-161422224)):
31+
32+
- Python 2.7: `py.test armstrong_numbers_test.py`
33+
- Python 3.4+: `pytest armstrong_numbers_test.py`
34+
35+
Alternatively, you can tell Python to run the pytest module (allowing the same command to be used regardless of Python version):
36+
`python -m pytest armstrong_numbers_test.py`
37+
38+
### Common `pytest` options
39+
40+
- `-v` : enable verbose output
41+
- `-x` : stop running tests on first failure
42+
- `--ff` : run failures from previous test before running other test cases
43+
44+
For other options, see `python -m pytest -h`
45+
46+
## Submitting Exercises
47+
48+
Note that, when trying to submit an exercise, make sure the solution is in the `$EXERCISM_WORKSPACE/python/armstrong-numbers` directory.
49+
50+
You can find your Exercism workspace by running `exercism debug` and looking for the line that starts with `Workspace`.
51+
52+
For more detailed information about running tests, code style and linting,
53+
please see [Running the Tests](http://exercism.io/tracks/python/tests).
54+
55+
## Source
56+
57+
Wikipedia [https://en.wikipedia.org/wiki/Narcissistic_number](https://en.wikipedia.org/wiki/Narcissistic_number)
58+
59+
## Submitting Incomplete Solutions
60+
61+
It's possible to submit an incomplete solution so you can see how others have completed the exercise.
Binary file not shown.
Binary file not shown.
+2
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
def is_armstrong(number):
2+
return sum(int(x)**len(str(number)) for x in str(number)) == number
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
import unittest
2+
3+
from armstrong_numbers import is_armstrong
4+
5+
6+
# Tests adapted from `problem-specifications//canonical-data.json` @ v1.0.0
7+
8+
class ArmstrongNumbersTest(unittest.TestCase):
9+
10+
def test_single_digit_numbers_are_armstrong_numbers(self):
11+
self.assertIs(is_armstrong(5), True)
12+
13+
def test_there_are_no_two_digit_armstrong_numbers(self):
14+
self.assertIs(is_armstrong(10), False)
15+
16+
def test_three_digit_number_that_is_an_armstrong_number(self):
17+
self.assertIs(is_armstrong(153), True)
18+
19+
def test_three_digit_number_that_is_not_an_armstrong_number(self):
20+
self.assertIs(is_armstrong(100), False)
21+
22+
def test_four_digit_number_that_is_an_armstrong_number(self):
23+
self.assertIs(is_armstrong(9474), True)
24+
25+
def test_four_digit_number_that_is_not_an_armstrong_number(self):
26+
self.assertIs(is_armstrong(9475), False)
27+
28+
def test_seven_digit_number_that_is_an_armstrong_number(self):
29+
self.assertIs(is_armstrong(9926315), True)
30+
31+
def test_seven_digit_number_that_is_not_an_armstrong_number(self):
32+
self.assertIs(is_armstrong(9926314), False)
33+
34+
35+
if __name__ == '__main__':
36+
unittest.main()
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
{}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
[
2+
"binary_search_tree_test.py::BinarySearchTreeTest::test_can_create_complex_tree",
3+
"binary_search_tree_test.py::BinarySearchTreeTest::test_can_sort_complex_tree",
4+
"binary_search_tree_test.py::BinarySearchTreeTest::test_can_sort_if_second_number_is_greater_than_first",
5+
"binary_search_tree_test.py::BinarySearchTreeTest::test_can_sort_if_second_number_is_same_as_first",
6+
"binary_search_tree_test.py::BinarySearchTreeTest::test_can_sort_if_second_number_is_smaller_than_first",
7+
"binary_search_tree_test.py::BinarySearchTreeTest::test_can_sort_single_number",
8+
"binary_search_tree_test.py::BinarySearchTreeTest::test_data_is_retained",
9+
"binary_search_tree_test.py::BinarySearchTreeTest::test_greater_number_at_right_node",
10+
"binary_search_tree_test.py::BinarySearchTreeTest::test_same_number_at_left_node",
11+
"binary_search_tree_test.py::BinarySearchTreeTest::test_smaller_data_at_left_node"
12+
]

binary-search-tree/.solution.json

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
{"track":"python","exercise":"binary-search-tree","id":"ef4c867df95a45c5b7cadfc0a1eb256e","url":"https://exercism.io/my/solutions/ef4c867df95a45c5b7cadfc0a1eb256e","handle":"cglacet","is_requester":true,"auto_approve":false}
Binary file not shown.
Binary file not shown.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
{}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
[
2+
"binary_search_test.py::BinarySearchTest::test_empty_array",
3+
"binary_search_test.py::BinarySearchTest::test_finds_value_at_beginning_of_array",
4+
"binary_search_test.py::BinarySearchTest::test_finds_value_at_end_of_array",
5+
"binary_search_test.py::BinarySearchTest::test_finds_value_in_array_of_even_length",
6+
"binary_search_test.py::BinarySearchTest::test_finds_value_in_array_of_odd_length",
7+
"binary_search_test.py::BinarySearchTest::test_finds_value_in_array_with_one_element",
8+
"binary_search_test.py::BinarySearchTest::test_finds_value_in_middle_of_array",
9+
"binary_search_test.py::BinarySearchTest::test_identifies_value_missing",
10+
"binary_search_test.py::BinarySearchTest::test_value_larger_than_arrays_maximum",
11+
"binary_search_test.py::BinarySearchTest::test_value_smaller_than_arrays_minimum"
12+
]

binary-search/.solution.json

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
{"track":"python","exercise":"binary-search","id":"4436f1ba33d14769a9767c0cb3c42a84","url":"https://exercism.io/my/solutions/4436f1ba33d14769a9767c0cb3c42a84","handle":"cglacet","is_requester":true,"auto_approve":false}

binary-search/README.md

+84
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
# Binary Search
2+
3+
Implement a binary search algorithm.
4+
5+
Searching a sorted collection is a common task. A dictionary is a sorted
6+
list of word definitions. Given a word, one can find its definition. A
7+
telephone book is a sorted list of people's names, addresses, and
8+
telephone numbers. Knowing someone's name allows one to quickly find
9+
their telephone number and address.
10+
11+
If the list to be searched contains more than a few items (a dozen, say)
12+
a binary search will require far fewer comparisons than a linear search,
13+
but it imposes the requirement that the list be sorted.
14+
15+
In computer science, a binary search or half-interval search algorithm
16+
finds the position of a specified input value (the search "key") within
17+
an array sorted by key value.
18+
19+
In each step, the algorithm compares the search key value with the key
20+
value of the middle element of the array.
21+
22+
If the keys match, then a matching element has been found and its index,
23+
or position, is returned.
24+
25+
Otherwise, if the search key is less than the middle element's key, then
26+
the algorithm repeats its action on the sub-array to the left of the
27+
middle element or, if the search key is greater, on the sub-array to the
28+
right.
29+
30+
If the remaining array to be searched is empty, then the key cannot be
31+
found in the array and a special "not found" indication is returned.
32+
33+
A binary search halves the number of items to check with each iteration,
34+
so locating an item (or determining its absence) takes logarithmic time.
35+
A binary search is a dichotomic divide and conquer search algorithm.
36+
37+
## Exception messages
38+
39+
Sometimes it is necessary to raise an exception. When you do this, you should include a meaningful error message to
40+
indicate what the source of the error is. This makes your code more readable and helps significantly with debugging. Not
41+
every exercise will require you to raise an exception, but for those that do, the tests will only pass if you include
42+
a message.
43+
44+
To raise a message with an exception, just write it as an argument to the exception type. For example, instead of
45+
`raise Exception`, you should write:
46+
47+
```python
48+
raise Exception("Meaningful message indicating the source of the error")
49+
```
50+
51+
## Running the tests
52+
53+
To run the tests, run the appropriate command below ([why they are different](https://github.com/pytest-dev/pytest/issues/1629#issue-161422224)):
54+
55+
- Python 2.7: `py.test binary_search_test.py`
56+
- Python 3.4+: `pytest binary_search_test.py`
57+
58+
Alternatively, you can tell Python to run the pytest module (allowing the same command to be used regardless of Python version):
59+
`python -m pytest binary_search_test.py`
60+
61+
### Common `pytest` options
62+
63+
- `-v` : enable verbose output
64+
- `-x` : stop running tests on first failure
65+
- `--ff` : run failures from previous test before running other test cases
66+
67+
For other options, see `python -m pytest -h`
68+
69+
## Submitting Exercises
70+
71+
Note that, when trying to submit an exercise, make sure the solution is in the `$EXERCISM_WORKSPACE/python/binary-search` directory.
72+
73+
You can find your Exercism workspace by running `exercism debug` and looking for the line that starts with `Workspace`.
74+
75+
For more detailed information about running tests, code style and linting,
76+
please see [Running the Tests](http://exercism.io/tracks/python/tests).
77+
78+
## Source
79+
80+
Wikipedia [http://en.wikipedia.org/wiki/Binary_search_algorithm](http://en.wikipedia.org/wiki/Binary_search_algorithm)
81+
82+
## Submitting Incomplete Solutions
83+
84+
It's possible to submit an incomplete solution so you can see how others have completed the exercise.
Binary file not shown.
Binary file not shown.
Binary file not shown.

binary-search/binary_search.py

+18
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
"""Exercise from https://exercism.io/my/tracks/python"""
2+
3+
4+
def binary_search(list_of_numbers, number):
5+
"""Returns the index of `number` in the sorted list `list_of_numbers`.
6+
Raise ``ValueError`` if `number` is not in `list_of_numbers`."""
7+
left, right = 0, len(list_of_numbers)-1
8+
while right >= left:
9+
middle = (left+right)//2
10+
middle_number = list_of_numbers[middle]
11+
if middle_number == number:
12+
return middle
13+
if middle_number < number:
14+
left = middle + 1
15+
else:
16+
right = middle - 1
17+
18+
raise ValueError("Not found.")

binary-search/binary_search_test.py

+59
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
import unittest
2+
3+
from binary_search import binary_search
4+
5+
6+
# Tests adapted from `problem-specifications//canonical-data.json` @ v1.1.0
7+
8+
class BinarySearchTest(unittest.TestCase):
9+
def test_finds_value_in_array_with_one_element(self):
10+
self.assertEqual(binary_search([6], 6), 0)
11+
12+
def test_finds_value_in_middle_of_array(self):
13+
self.assertEqual(binary_search([1, 3, 4, 6, 8, 9, 11], 6), 3)
14+
15+
def test_finds_value_at_beginning_of_array(self):
16+
self.assertEqual(binary_search([1, 3, 4, 6, 8, 9, 11], 1), 0)
17+
18+
def test_finds_value_at_end_of_array(self):
19+
self.assertEqual(binary_search([1, 3, 4, 6, 8, 9, 11], 11), 6)
20+
21+
def test_finds_value_in_array_of_odd_length(self):
22+
self.assertEqual(
23+
binary_search([1, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, 634],
24+
144), 9)
25+
26+
def test_finds_value_in_array_of_even_length(self):
27+
self.assertEqual(
28+
binary_search([1, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377], 21),
29+
5)
30+
31+
def test_identifies_value_missing(self):
32+
with self.assertRaisesWithMessage(ValueError):
33+
binary_search([1, 3, 4, 6, 8, 9, 11], 7)
34+
35+
def test_value_smaller_than_arrays_minimum(self):
36+
with self.assertRaisesWithMessage(ValueError):
37+
binary_search([1, 3, 4, 6, 8, 9, 11], 0)
38+
39+
def test_value_larger_than_arrays_maximum(self):
40+
with self.assertRaisesWithMessage(ValueError):
41+
binary_search([1, 3, 4, 6, 8, 9, 11], 13)
42+
43+
def test_empty_array(self):
44+
with self.assertRaisesWithMessage(ValueError):
45+
binary_search([], 1)
46+
47+
# Utility functions
48+
def setUp(self):
49+
try:
50+
self.assertRaisesRegex
51+
except AttributeError:
52+
self.assertRaisesRegex = self.assertRaisesRegexp
53+
54+
def assertRaisesWithMessage(self, exception):
55+
return self.assertRaisesRegex(exception, r".+")
56+
57+
58+
if __name__ == '__main__':
59+
unittest.main()
+43
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
import random
2+
3+
4+
def main():
5+
for _ in range(1000):
6+
list_of_numbers = sorted([random.randint(1, 30) for _ in range(random.randint(10, 30))])
7+
number = random.choice(list_of_numbers)
8+
position = binary_search(list_of_numbers, number, debug=True)
9+
assert list_of_numbers[position] == number
10+
11+
def state_repr(list_of_numbers, left, middle, right):
12+
text = ""
13+
for i, number in enumerate(list_of_numbers):
14+
number_text = str(number)
15+
if i == middle:
16+
number_text = "(" + number_text + ")"
17+
left_text = "[" if left == i else " "
18+
right_text = "]" if right == i else " "
19+
text += left_text + number_text + right_text
20+
return text
21+
22+
23+
def binary_search(list_of_numbers, number, debug=False):
24+
if debug:
25+
print("Looking for {} in {}".format(number, list_of_numbers))
26+
left, right = 0, len(list_of_numbers)-1
27+
while right-left >= 0:
28+
middle = left + (right-left)//2
29+
middle_number = list_of_numbers[middle]
30+
if debug:
31+
print(state_repr(list_of_numbers, left, middle, right))
32+
if middle_number == number:
33+
return middle
34+
if middle_number < number:
35+
left = middle + 1
36+
else:
37+
right = middle - 1
38+
39+
return None
40+
41+
42+
if __name__ == "__main__":
43+
main()
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
{}
+16
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
[
2+
"book_store_test.py::BookStoreTest::test_empty_basket",
3+
"book_store_test.py::BookStoreTest::test_five_different_books",
4+
"book_store_test.py::BookStoreTest::test_four_different_books",
5+
"book_store_test.py::BookStoreTest::test_four_groups_of_4_are_cheaper_than_2_groups_each_of_5_and_3",
6+
"book_store_test.py::BookStoreTest::test_group_of_4_plus_group_of_2_is_cheaper_than_2_groups_of_3",
7+
"book_store_test.py::BookStoreTest::test_only_a_single_book",
8+
"book_store_test.py::BookStoreTest::test_three_copies_of_first_book_and_2_each_of_remaining",
9+
"book_store_test.py::BookStoreTest::test_three_different_books",
10+
"book_store_test.py::BookStoreTest::test_three_each_of_first_2_books_and_2_each_of_remaining_books",
11+
"book_store_test.py::BookStoreTest::test_two_copies_of_each_book",
12+
"book_store_test.py::BookStoreTest::test_two_different_books",
13+
"book_store_test.py::BookStoreTest::test_two_each_of_first_4_books_and_1_copy_each_of_rest",
14+
"book_store_test.py::BookStoreTest::test_two_groups_of_4_is_cheaper_than_group_of_5_plus_group_of_3",
15+
"book_store_test.py::BookStoreTest::test_two_of_the_same_book"
16+
]

0 commit comments

Comments
 (0)