mirror of
https://github.com/Xevion/exercism.git
synced 2025-12-06 09:14:59 -06:00
atbash, robot simulator, sum of multiples exercises
This commit is contained in:
1
python/atbash-cipher/.exercism/metadata.json
Normal file
1
python/atbash-cipher/.exercism/metadata.json
Normal file
@@ -0,0 +1 @@
|
||||
{"track":"python","exercise":"atbash-cipher","id":"5a7e43952bd94c4d9a1d698c45748d49","url":"https://exercism.io/my/solutions/5a7e43952bd94c4d9a1d698c45748d49","handle":"Xevion","is_requester":true,"auto_approve":false}
|
||||
78
python/atbash-cipher/README.md
Normal file
78
python/atbash-cipher/README.md
Normal file
@@ -0,0 +1,78 @@
|
||||
# Atbash Cipher
|
||||
|
||||
Create an implementation of the atbash cipher, an ancient encryption system created in the Middle East.
|
||||
|
||||
The Atbash cipher is a simple substitution cipher that relies on
|
||||
transposing all the letters in the alphabet such that the resulting
|
||||
alphabet is backwards. The first letter is replaced with the last
|
||||
letter, the second with the second-last, and so on.
|
||||
|
||||
An Atbash cipher for the Latin alphabet would be as follows:
|
||||
|
||||
```text
|
||||
Plain: abcdefghijklmnopqrstuvwxyz
|
||||
Cipher: zyxwvutsrqponmlkjihgfedcba
|
||||
```
|
||||
|
||||
It is a very weak cipher because it only has one possible key, and it is
|
||||
a simple monoalphabetic substitution cipher. However, this may not have
|
||||
been an issue in the cipher's time.
|
||||
|
||||
Ciphertext is written out in groups of fixed length, the traditional group size
|
||||
being 5 letters, and punctuation is excluded. This is to make it harder to guess
|
||||
things based on word boundaries.
|
||||
|
||||
## Examples
|
||||
|
||||
- Encoding `test` gives `gvhg`
|
||||
- Decoding `gvhg` gives `test`
|
||||
- Decoding `gsvjf rxpyi ldmul cqfnk hlevi gsvoz abwlt` gives `thequickbrownfoxjumpsoverthelazydog`
|
||||
|
||||
## Exception messages
|
||||
|
||||
Sometimes it is necessary to raise an exception. When you do this, you should include a meaningful error message to
|
||||
indicate what the source of the error is. This makes your code more readable and helps significantly with debugging. Not
|
||||
every exercise will require you to raise an exception, but for those that do, the tests will only pass if you include
|
||||
a message.
|
||||
|
||||
To raise a message with an exception, just write it as an argument to the exception type. For example, instead of
|
||||
`raise Exception`, you should write:
|
||||
|
||||
```python
|
||||
raise Exception("Meaningful message indicating the source of the error")
|
||||
```
|
||||
|
||||
## Running the tests
|
||||
|
||||
To run the tests, run the appropriate command below ([why they are different](https://github.com/pytest-dev/pytest/issues/1629#issue-161422224)):
|
||||
|
||||
- Python 2.7: `py.test atbash_cipher_test.py`
|
||||
- Python 3.4+: `pytest atbash_cipher_test.py`
|
||||
|
||||
Alternatively, you can tell Python to run the pytest module (allowing the same command to be used regardless of Python version):
|
||||
`python -m pytest atbash_cipher_test.py`
|
||||
|
||||
### Common `pytest` options
|
||||
|
||||
- `-v` : enable verbose output
|
||||
- `-x` : stop running tests on first failure
|
||||
- `--ff` : run failures from previous test before running other test cases
|
||||
|
||||
For other options, see `python -m pytest -h`
|
||||
|
||||
## Submitting Exercises
|
||||
|
||||
Note that, when trying to submit an exercise, make sure the solution is in the `$EXERCISM_WORKSPACE/python/atbash-cipher` directory.
|
||||
|
||||
You can find your Exercism workspace by running `exercism debug` and looking for the line that starts with `Workspace`.
|
||||
|
||||
For more detailed information about running tests, code style and linting,
|
||||
please see [Running the Tests](http://exercism.io/tracks/python/tests).
|
||||
|
||||
## Source
|
||||
|
||||
Wikipedia [http://en.wikipedia.org/wiki/Atbash](http://en.wikipedia.org/wiki/Atbash)
|
||||
|
||||
## Submitting Incomplete Solutions
|
||||
|
||||
It's possible to submit an incomplete solution so you can see how others have completed the exercise.
|
||||
19
python/atbash-cipher/atbash_cipher.py
Normal file
19
python/atbash-cipher/atbash_cipher.py
Normal file
@@ -0,0 +1,19 @@
|
||||
from string import ascii_letters, punctuation, whitespace
|
||||
|
||||
rev = ascii_letters[25::-1] + ascii_letters[:25:-1]
|
||||
enc = str.maketrans(ascii_letters, rev)
|
||||
dec = str.maketrans(rev, ascii_letters)
|
||||
san = str.maketrans('', '', punctuation)
|
||||
|
||||
def groupings(text, groupby=5):
|
||||
for i in range(0, len(text), groupby):
|
||||
yield text[i:i + groupby]
|
||||
|
||||
def sanitize(text):
|
||||
return ''.join(text.translate(san).split())
|
||||
|
||||
def encode(plain_text):
|
||||
return ' '.join(groupings(sanitize(plain_text.translate(enc).lower())))
|
||||
|
||||
def decode(ciphered_text):
|
||||
return ''.join(ciphered_text.translate(dec).lower().split())
|
||||
69
python/atbash-cipher/atbash_cipher_test.py
Normal file
69
python/atbash-cipher/atbash_cipher_test.py
Normal file
@@ -0,0 +1,69 @@
|
||||
import unittest
|
||||
|
||||
from atbash_cipher import decode, encode
|
||||
|
||||
|
||||
# Tests adapted from `problem-specifications//canonical-data.json` @ v1.2.0
|
||||
|
||||
class AtbashCipherTest(unittest.TestCase):
|
||||
def test_encode_no(self):
|
||||
self.assertMultiLineEqual(encode("no"), "ml")
|
||||
|
||||
def test_encode_yes(self):
|
||||
self.assertMultiLineEqual(encode("yes"), "bvh")
|
||||
|
||||
def test_encode_OMG(self):
|
||||
self.assertMultiLineEqual(encode("OMG"), "lnt")
|
||||
|
||||
def test_encode_O_M_G(self):
|
||||
self.assertMultiLineEqual(encode("O M G"), "lnt")
|
||||
|
||||
def test_encode_long_word(self):
|
||||
self.assertMultiLineEqual(encode("mindblowingly"), "nrmwy oldrm tob")
|
||||
|
||||
def test_encode_numbers(self):
|
||||
self.assertMultiLineEqual(
|
||||
encode("Testing, 1 2 3, testing."), "gvhgr mt123 gvhgr mt")
|
||||
|
||||
def test_encode_sentence(self):
|
||||
self.assertMultiLineEqual(
|
||||
encode("Truth is fiction."), "gifgs rhurx grlm")
|
||||
|
||||
def test_encode_all_things(self):
|
||||
plaintext = "The quick brown fox jumps over the lazy dog."
|
||||
ciphertext = "gsvjf rxpyi ldmul cqfnk hlevi gsvoz abwlt"
|
||||
self.assertMultiLineEqual(encode(plaintext), ciphertext)
|
||||
|
||||
def test_decode_word(self):
|
||||
self.assertMultiLineEqual(decode("vcvix rhn"), "exercism")
|
||||
|
||||
def test_decode_sentence(self):
|
||||
self.assertMultiLineEqual(
|
||||
decode("zmlyh gzxov rhlug vmzhg vkkrm thglm v"),
|
||||
"anobstacleisoftenasteppingstone")
|
||||
|
||||
def test_decode_numbers(self):
|
||||
self.assertMultiLineEqual(
|
||||
decode("gvhgr mt123 gvhgr mt"), "testing123testing")
|
||||
|
||||
def test_decode_all_the_letters(self):
|
||||
ciphertext = "gsvjf rxpyi ldmul cqfnk hlevi gsvoz abwlt"
|
||||
plaintext = "thequickbrownfoxjumpsoverthelazydog"
|
||||
self.assertMultiLineEqual(decode(ciphertext), plaintext)
|
||||
|
||||
def test_decode_with_too_many_spaces(self):
|
||||
self.assertMultiLineEqual(decode("vc vix r hn"), "exercism")
|
||||
|
||||
def test_decode_with_no_spaces(self):
|
||||
ciphertext = "zmlyhgzxovrhlugvmzhgvkkrmthglmv"
|
||||
plaintext = "anobstacleisoftenasteppingstone"
|
||||
self.assertMultiLineEqual(decode(ciphertext), plaintext)
|
||||
|
||||
# additional track specific test
|
||||
def test_encode_decode(self):
|
||||
self.assertMultiLineEqual(
|
||||
decode(encode("Testing, 1 2 3, testing.")), "testing123testing")
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
1
python/robot-simulator/.exercism/metadata.json
Normal file
1
python/robot-simulator/.exercism/metadata.json
Normal file
@@ -0,0 +1 @@
|
||||
{"track":"python","exercise":"robot-simulator","id":"257266d04daa4093a7d60012d0c003ef","url":"https://exercism.io/my/solutions/257266d04daa4093a7d60012d0c003ef","handle":"Xevion","is_requester":true,"auto_approve":false}
|
||||
77
python/robot-simulator/README.md
Normal file
77
python/robot-simulator/README.md
Normal file
@@ -0,0 +1,77 @@
|
||||
# Robot Simulator
|
||||
|
||||
Write a robot simulator.
|
||||
|
||||
A robot factory's test facility needs a program to verify robot movements.
|
||||
|
||||
The robots have three possible movements:
|
||||
|
||||
- turn right
|
||||
- turn left
|
||||
- advance
|
||||
|
||||
Robots are placed on a hypothetical infinite grid, facing a particular
|
||||
direction (north, east, south, or west) at a set of {x,y} coordinates,
|
||||
e.g., {3,8}, with coordinates increasing to the north and east.
|
||||
|
||||
The robot then receives a number of instructions, at which point the
|
||||
testing facility verifies the robot's new position, and in which
|
||||
direction it is pointing.
|
||||
|
||||
- The letter-string "RAALAL" means:
|
||||
- Turn right
|
||||
- Advance twice
|
||||
- Turn left
|
||||
- Advance once
|
||||
- Turn left yet again
|
||||
- Say a robot starts at {7, 3} facing north. Then running this stream
|
||||
of instructions should leave it at {9, 4} facing west.
|
||||
|
||||
## Exception messages
|
||||
|
||||
Sometimes it is necessary to raise an exception. When you do this, you should include a meaningful error message to
|
||||
indicate what the source of the error is. This makes your code more readable and helps significantly with debugging. Not
|
||||
every exercise will require you to raise an exception, but for those that do, the tests will only pass if you include
|
||||
a message.
|
||||
|
||||
To raise a message with an exception, just write it as an argument to the exception type. For example, instead of
|
||||
`raise Exception`, you should write:
|
||||
|
||||
```python
|
||||
raise Exception("Meaningful message indicating the source of the error")
|
||||
```
|
||||
|
||||
## Running the tests
|
||||
|
||||
To run the tests, run the appropriate command below ([why they are different](https://github.com/pytest-dev/pytest/issues/1629#issue-161422224)):
|
||||
|
||||
- Python 2.7: `py.test robot_simulator_test.py`
|
||||
- Python 3.4+: `pytest robot_simulator_test.py`
|
||||
|
||||
Alternatively, you can tell Python to run the pytest module (allowing the same command to be used regardless of Python version):
|
||||
`python -m pytest robot_simulator_test.py`
|
||||
|
||||
### Common `pytest` options
|
||||
|
||||
- `-v` : enable verbose output
|
||||
- `-x` : stop running tests on first failure
|
||||
- `--ff` : run failures from previous test before running other test cases
|
||||
|
||||
For other options, see `python -m pytest -h`
|
||||
|
||||
## Submitting Exercises
|
||||
|
||||
Note that, when trying to submit an exercise, make sure the solution is in the `$EXERCISM_WORKSPACE/python/robot-simulator` directory.
|
||||
|
||||
You can find your Exercism workspace by running `exercism debug` and looking for the line that starts with `Workspace`.
|
||||
|
||||
For more detailed information about running tests, code style and linting,
|
||||
please see [Running the Tests](http://exercism.io/tracks/python/tests).
|
||||
|
||||
## Source
|
||||
|
||||
Inspired by an interview question at a famous company.
|
||||
|
||||
## Submitting Incomplete Solutions
|
||||
|
||||
It's possible to submit an incomplete solution so you can see how others have completed the exercise.
|
||||
32
python/robot-simulator/robot_simulator.py
Normal file
32
python/robot-simulator/robot_simulator.py
Normal file
@@ -0,0 +1,32 @@
|
||||
import re
|
||||
|
||||
# Globals for the bearings
|
||||
# Change the values as you see fit
|
||||
EAST = (1, 0)
|
||||
NORTH = (0, 1)
|
||||
WEST = (-1, 0)
|
||||
SOUTH = (0, -1)
|
||||
BEARINGS = [NORTH, EAST, SOUTH, WEST]
|
||||
BEARINGSF = ['North', 'East', 'South', 'West']
|
||||
|
||||
class Robot(object):
|
||||
def __init__(self, bearing=NORTH, x=0, y=0):
|
||||
self.x, self.y, self.bearing = x, y, bearing
|
||||
self.turn_left, self.turn_right = lambda : self.turn(), lambda : self.turn(isright=True)
|
||||
@property
|
||||
def coordinates(self):
|
||||
return (self.x, self.y)
|
||||
|
||||
def simulate(self, commands):
|
||||
[self.turn(True, n=len(c)) if c[0] == 'R' else self.turn(n=len(c)) if c[0] == 'L' else self.advance(n=len(c)) if c[0] == 'A' else None for c in map(lambda item : item[0], re.finditer(r'(\w)\1*', commands))]
|
||||
|
||||
def advance(self, n=1):
|
||||
self.x, self.y = self.x + (self.bearing[0] * n), self.y + (self.bearing[1] * n)
|
||||
|
||||
def turn(self, isright=False, n=1):
|
||||
for _ in range(n):
|
||||
index = (BEARINGS.index(self.bearing) + (1 if isright else -1))
|
||||
self.bearing = BEARINGS[0 if index == 4 else index]
|
||||
|
||||
def __repr__(self):
|
||||
return f'<Robot ({self.x}, {self.y})/{BEARINGSF[BEARINGS.index(self.bearing)]}>'
|
||||
102
python/robot-simulator/robot_simulator_test.py
Normal file
102
python/robot-simulator/robot_simulator_test.py
Normal file
@@ -0,0 +1,102 @@
|
||||
import unittest
|
||||
|
||||
from robot_simulator import Robot, NORTH, EAST, SOUTH, WEST
|
||||
|
||||
|
||||
# Tests adapted from `problem-specifications//canonical-data.json` @ v3.2.0
|
||||
|
||||
class RobotSimulatorTest(unittest.TestCase):
|
||||
|
||||
def test_create_robot_at_origin_facing_north(self):
|
||||
robot = Robot(NORTH, 0, 0)
|
||||
self.assertEqual(robot.coordinates, (0, 0))
|
||||
self.assertEqual(robot.bearing, NORTH)
|
||||
|
||||
def test_create_robot_at_negative_position_facing_south(self):
|
||||
robot = Robot(SOUTH, -1, -1)
|
||||
self.assertEqual(robot.coordinates, (-1, -1))
|
||||
self.assertEqual(robot.bearing, SOUTH)
|
||||
|
||||
def test_rotating_clockwise(self):
|
||||
dirA = [NORTH, EAST, SOUTH, WEST]
|
||||
dirB = [EAST, SOUTH, WEST, NORTH]
|
||||
for x in range(len(dirA)):
|
||||
robot = Robot(dirA[x], 0, 0)
|
||||
robot.turn_right()
|
||||
self.assertEqual(robot.bearing, dirB[x])
|
||||
|
||||
def test_rotating_clockwise_by_simulate_R(self):
|
||||
A = [NORTH, EAST, SOUTH, WEST]
|
||||
B = [EAST, SOUTH, WEST, NORTH]
|
||||
for x in range(len(A)):
|
||||
robot = Robot(A[x], 0, 0)
|
||||
robot.simulate("R")
|
||||
self.assertEqual(robot.bearing, B[x])
|
||||
|
||||
def test_rotating_counter_clockwise(self):
|
||||
dirA = [NORTH, EAST, SOUTH, WEST]
|
||||
dirB = [WEST, NORTH, EAST, SOUTH]
|
||||
for x in range(len(dirA)):
|
||||
robot = Robot(dirA[x], 0, 0)
|
||||
robot.turn_left()
|
||||
self.assertEqual(robot.bearing, dirB[x])
|
||||
|
||||
def test_rotating_counter_clockwise_by_simulate_L(self):
|
||||
A = [NORTH, WEST, SOUTH, EAST]
|
||||
B = [WEST, SOUTH, EAST, NORTH]
|
||||
for x in range(len(A)):
|
||||
robot = Robot(A[x], 0, 0)
|
||||
robot.simulate("L")
|
||||
self.assertEqual(robot.bearing, B[x])
|
||||
|
||||
def test_moving_forward_one_facing_north_increments_Y(self):
|
||||
robot = Robot(NORTH, 0, 0)
|
||||
robot.advance()
|
||||
self.assertEqual(robot.coordinates, (0, 1))
|
||||
self.assertEqual(robot.bearing, NORTH)
|
||||
|
||||
def test_moving_forward_one_facing_south_decrements_Y(self):
|
||||
robot = Robot(SOUTH, 0, 0)
|
||||
robot.advance()
|
||||
self.assertEqual(robot.coordinates, (0, -1))
|
||||
self.assertEqual(robot.bearing, SOUTH)
|
||||
|
||||
def test_moving_forward_one_facing_east_increments_X(self):
|
||||
robot = Robot(EAST, 0, 0)
|
||||
robot.advance()
|
||||
self.assertEqual(robot.coordinates, (1, 0))
|
||||
self.assertEqual(robot.bearing, EAST)
|
||||
|
||||
def test_moving_forward_one_facing_west_decrements_X(self):
|
||||
robot = Robot(WEST, 0, 0)
|
||||
robot.advance()
|
||||
self.assertEqual(robot.coordinates, (-1, 0))
|
||||
self.assertEqual(robot.bearing, WEST)
|
||||
|
||||
def test_series_of_instructions_moving_east_and_north_from_README(self):
|
||||
robot = Robot(NORTH, 7, 3)
|
||||
robot.simulate("RAALAL")
|
||||
self.assertEqual(robot.coordinates, (9, 4))
|
||||
self.assertEqual(robot.bearing, WEST)
|
||||
|
||||
def test_series_of_instructions_moving_west_and_north(self):
|
||||
robot = Robot(NORTH, 0, 0)
|
||||
robot.simulate("LAAARALA")
|
||||
self.assertEqual(robot.coordinates, (-4, 1))
|
||||
self.assertEqual(robot.bearing, WEST)
|
||||
|
||||
def test_series_of_instructions_moving_west_and_south(self):
|
||||
robot = Robot(EAST, 2, -7)
|
||||
robot.simulate("RRAAAAALA")
|
||||
self.assertEqual(robot.coordinates, (-3, -8))
|
||||
self.assertEqual(robot.bearing, SOUTH)
|
||||
|
||||
def test_series_of_instructions_moving_east_and_north(self):
|
||||
robot = Robot(SOUTH, 8, 4)
|
||||
robot.simulate("LAAARRRALLLL")
|
||||
self.assertEqual(robot.coordinates, (11, 5))
|
||||
self.assertEqual(robot.bearing, NORTH)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
1
python/sum-of-multiples/.exercism/metadata.json
Normal file
1
python/sum-of-multiples/.exercism/metadata.json
Normal file
@@ -0,0 +1 @@
|
||||
{"track":"python","exercise":"sum-of-multiples","id":"376b2f4ace694adf9de021c6cc10e243","url":"https://exercism.io/my/solutions/376b2f4ace694adf9de021c6cc10e243","handle":"Xevion","is_requester":true,"auto_approve":false}
|
||||
58
python/sum-of-multiples/README.md
Normal file
58
python/sum-of-multiples/README.md
Normal file
@@ -0,0 +1,58 @@
|
||||
# Sum Of Multiples
|
||||
|
||||
Given a number, find the sum of all the unique multiples of particular numbers up to
|
||||
but not including that number.
|
||||
|
||||
If we list all the natural numbers below 20 that are multiples of 3 or 5,
|
||||
we get 3, 5, 6, 9, 10, 12, 15, and 18.
|
||||
|
||||
The sum of these multiples is 78.
|
||||
|
||||
## Exception messages
|
||||
|
||||
Sometimes it is necessary to raise an exception. When you do this, you should include a meaningful error message to
|
||||
indicate what the source of the error is. This makes your code more readable and helps significantly with debugging. Not
|
||||
every exercise will require you to raise an exception, but for those that do, the tests will only pass if you include
|
||||
a message.
|
||||
|
||||
To raise a message with an exception, just write it as an argument to the exception type. For example, instead of
|
||||
`raise Exception`, you should write:
|
||||
|
||||
```python
|
||||
raise Exception("Meaningful message indicating the source of the error")
|
||||
```
|
||||
|
||||
## Running the tests
|
||||
|
||||
To run the tests, run the appropriate command below ([why they are different](https://github.com/pytest-dev/pytest/issues/1629#issue-161422224)):
|
||||
|
||||
- Python 2.7: `py.test sum_of_multiples_test.py`
|
||||
- Python 3.4+: `pytest sum_of_multiples_test.py`
|
||||
|
||||
Alternatively, you can tell Python to run the pytest module (allowing the same command to be used regardless of Python version):
|
||||
`python -m pytest sum_of_multiples_test.py`
|
||||
|
||||
### Common `pytest` options
|
||||
|
||||
- `-v` : enable verbose output
|
||||
- `-x` : stop running tests on first failure
|
||||
- `--ff` : run failures from previous test before running other test cases
|
||||
|
||||
For other options, see `python -m pytest -h`
|
||||
|
||||
## Submitting Exercises
|
||||
|
||||
Note that, when trying to submit an exercise, make sure the solution is in the `$EXERCISM_WORKSPACE/python/sum-of-multiples` directory.
|
||||
|
||||
You can find your Exercism workspace by running `exercism debug` and looking for the line that starts with `Workspace`.
|
||||
|
||||
For more detailed information about running tests, code style and linting,
|
||||
please see [Running the Tests](http://exercism.io/tracks/python/tests).
|
||||
|
||||
## Source
|
||||
|
||||
A variation on Problem 1 at Project Euler [http://projecteuler.net/problem=1](http://projecteuler.net/problem=1)
|
||||
|
||||
## Submitting Incomplete Solutions
|
||||
|
||||
It's possible to submit an incomplete solution so you can see how others have completed the exercise.
|
||||
5
python/sum-of-multiples/sum_of_multiples.py
Normal file
5
python/sum-of-multiples/sum_of_multiples.py
Normal file
@@ -0,0 +1,5 @@
|
||||
ismultiple = lambda num, multiples: any(num % sub == 0 for sub in multiples)
|
||||
|
||||
def sum_of_multiples(limit, multiples):
|
||||
multiples = [mult for mult in multiples if mult != 0]
|
||||
return sum([i for i in range(1, limit) if ismultiple(i, multiples)])
|
||||
69
python/sum-of-multiples/sum_of_multiples_test.py
Normal file
69
python/sum-of-multiples/sum_of_multiples_test.py
Normal file
@@ -0,0 +1,69 @@
|
||||
"""
|
||||
You can make the following assumptions about the inputs to the
|
||||
'sum_of_multiples' function:
|
||||
* All input numbers are non-negative 'int's, i.e. natural numbers
|
||||
including zero.
|
||||
* A list of factors must be given, and its elements are unique
|
||||
and sorted in ascending order.
|
||||
"""
|
||||
|
||||
import unittest
|
||||
|
||||
from sum_of_multiples import sum_of_multiples
|
||||
|
||||
|
||||
# Tests adapted from `problem-specifications//canonical-data.json` @ v1.5.0
|
||||
|
||||
class SumOfMultiplesTest(unittest.TestCase):
|
||||
def test_multiples_with_no_factors_in_limit(self):
|
||||
self.assertEqual(sum_of_multiples(1, [3, 5]), 0)
|
||||
|
||||
def test_multiples_of_one_factor_within_limit(self):
|
||||
self.assertEqual(sum_of_multiples(4, [3, 5]), 3)
|
||||
|
||||
def test_various_multiples_in_limit(self):
|
||||
self.assertEqual(sum_of_multiples(7, [3]), 9)
|
||||
|
||||
def test_various_factors_with_multiples_in_limit(self):
|
||||
self.assertEqual(sum_of_multiples(10, [3, 5]), 23)
|
||||
|
||||
def test_multiples_counted_only_once(self):
|
||||
self.assertEqual(sum_of_multiples(100, [3, 5]), 2318)
|
||||
|
||||
def test_multiples_with_large_limit(self):
|
||||
self.assertEqual(sum_of_multiples(1000, [3, 5]), 233168)
|
||||
|
||||
def test_multiples_with_three_factors(self):
|
||||
self.assertEqual(sum_of_multiples(20, [7, 13, 17]), 51)
|
||||
|
||||
def test_multiples_with_factors_not_prime(self):
|
||||
self.assertEqual(sum_of_multiples(15, [4, 6]), 30)
|
||||
|
||||
def test_multiples_with_factors_prime_and_not(self):
|
||||
self.assertEqual(sum_of_multiples(150, [5, 6, 8]), 4419)
|
||||
|
||||
def test_multiples_with_similar_factors(self):
|
||||
self.assertEqual(sum_of_multiples(51, [5, 25]), 275)
|
||||
|
||||
def test_multiples_with_large_factors(self):
|
||||
self.assertEqual(sum_of_multiples(10000, [43, 47]), 2203160)
|
||||
|
||||
def test_multiples_of_one_will_be_all(self):
|
||||
self.assertEqual(sum_of_multiples(100, [1]), 4950)
|
||||
|
||||
def test_multiples_of_an_empty_list(self):
|
||||
self.assertEqual(sum_of_multiples(10000, []), 0)
|
||||
|
||||
def test_multiples_of_zero_will_be_none(self):
|
||||
self.assertEqual(sum_of_multiples(1, [0]), 0)
|
||||
|
||||
def test_multiples_with_a_zero_factor(self):
|
||||
self.assertEqual(sum_of_multiples(4, [0, 3]), 3)
|
||||
|
||||
def test_multiples_of_several_factors(self):
|
||||
self.assertEqual(sum_of_multiples(10000,
|
||||
[2, 3, 5, 7, 11]), 39614537)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
Reference in New Issue
Block a user