mirror of
https://github.com/TheAlgorithms/Python.git
synced 2024-11-23 21:11:08 +00:00
Add solution for Project Euler: Problem 89 (#2948)
* add solution for euler problem 89 * updates to accommodate euler solution guideline updates * use more descriptive vars * updating DIRECTORY.md Co-authored-by: github-actions <${GITHUB_ACTOR}@users.noreply.github.com>
This commit is contained in:
parent
06f01c0eeb
commit
b55e132b80
|
@ -717,6 +717,8 @@
|
|||
* [Sol1](https://github.com/TheAlgorithms/Python/blob/master/project_euler/problem_081/sol1.py)
|
||||
* Problem 087
|
||||
* [Sol1](https://github.com/TheAlgorithms/Python/blob/master/project_euler/problem_087/sol1.py)
|
||||
* Problem 089
|
||||
* [Sol1](https://github.com/TheAlgorithms/Python/blob/master/project_euler/problem_089/sol1.py)
|
||||
* Problem 091
|
||||
* [Sol1](https://github.com/TheAlgorithms/Python/blob/master/project_euler/problem_091/sol1.py)
|
||||
* Problem 097
|
||||
|
@ -735,10 +737,14 @@
|
|||
* [Sol1](https://github.com/TheAlgorithms/Python/blob/master/project_euler/problem_123/sol1.py)
|
||||
* Problem 125
|
||||
* [Sol1](https://github.com/TheAlgorithms/Python/blob/master/project_euler/problem_125/sol1.py)
|
||||
* Problem 129
|
||||
* [Sol1](https://github.com/TheAlgorithms/Python/blob/master/project_euler/problem_129/sol1.py)
|
||||
* Problem 173
|
||||
* [Sol1](https://github.com/TheAlgorithms/Python/blob/master/project_euler/problem_173/sol1.py)
|
||||
* Problem 174
|
||||
* [Sol1](https://github.com/TheAlgorithms/Python/blob/master/project_euler/problem_174/sol1.py)
|
||||
* Problem 188
|
||||
* [Sol1](https://github.com/TheAlgorithms/Python/blob/master/project_euler/problem_188/sol1.py)
|
||||
* Problem 191
|
||||
* [Sol1](https://github.com/TheAlgorithms/Python/blob/master/project_euler/problem_191/sol1.py)
|
||||
* Problem 203
|
||||
|
|
1
project_euler/problem_089/__init__.py
Normal file
1
project_euler/problem_089/__init__.py
Normal file
|
@ -0,0 +1 @@
|
|||
#
|
5
project_euler/problem_089/numeralcleanup_test.txt
Normal file
5
project_euler/problem_089/numeralcleanup_test.txt
Normal file
|
@ -0,0 +1,5 @@
|
|||
IIII
|
||||
IV
|
||||
IIIIIIIIII
|
||||
X
|
||||
VIIIII
|
1000
project_euler/problem_089/p089_roman.txt
Normal file
1000
project_euler/problem_089/p089_roman.txt
Normal file
File diff suppressed because it is too large
Load Diff
141
project_euler/problem_089/sol1.py
Normal file
141
project_euler/problem_089/sol1.py
Normal file
|
@ -0,0 +1,141 @@
|
|||
"""
|
||||
Project Euler Problem 89: https://projecteuler.net/problem=89
|
||||
|
||||
For a number written in Roman numerals to be considered valid there are basic rules
|
||||
which must be followed. Even though the rules allow some numbers to be expressed in
|
||||
more than one way there is always a "best" way of writing a particular number.
|
||||
|
||||
For example, it would appear that there are at least six ways of writing the number
|
||||
sixteen:
|
||||
|
||||
IIIIIIIIIIIIIIII
|
||||
VIIIIIIIIIII
|
||||
VVIIIIII
|
||||
XIIIIII
|
||||
VVVI
|
||||
XVI
|
||||
|
||||
However, according to the rules only XIIIIII and XVI are valid, and the last example
|
||||
is considered to be the most efficient, as it uses the least number of numerals.
|
||||
|
||||
The 11K text file, roman.txt (right click and 'Save Link/Target As...'), contains one
|
||||
thousand numbers written in valid, but not necessarily minimal, Roman numerals; see
|
||||
About... Roman Numerals for the definitive rules for this problem.
|
||||
|
||||
Find the number of characters saved by writing each of these in their minimal form.
|
||||
|
||||
Note: You can assume that all the Roman numerals in the file contain no more than four
|
||||
consecutive identical units.
|
||||
"""
|
||||
|
||||
import os
|
||||
|
||||
SYMBOLS = {"I": 1, "V": 5, "X": 10, "L": 50, "C": 100, "D": 500, "M": 1000}
|
||||
|
||||
|
||||
def parse_roman_numerals(numerals: str) -> int:
|
||||
"""
|
||||
Converts a string of roman numerals to an integer.
|
||||
e.g.
|
||||
>>> parse_roman_numerals("LXXXIX")
|
||||
89
|
||||
>>> parse_roman_numerals("IIII")
|
||||
4
|
||||
"""
|
||||
|
||||
total_value = 0
|
||||
|
||||
index = 0
|
||||
while index < len(numerals) - 1:
|
||||
current_value = SYMBOLS[numerals[index]]
|
||||
next_value = SYMBOLS[numerals[index + 1]]
|
||||
if current_value < next_value:
|
||||
total_value -= current_value
|
||||
else:
|
||||
total_value += current_value
|
||||
index += 1
|
||||
total_value += SYMBOLS[numerals[index]]
|
||||
|
||||
return total_value
|
||||
|
||||
|
||||
def generate_roman_numerals(num: int) -> str:
|
||||
"""
|
||||
Generates a string of roman numerals for a given integer.
|
||||
e.g.
|
||||
>>> generate_roman_numerals(89)
|
||||
'LXXXIX'
|
||||
>>> generate_roman_numerals(4)
|
||||
'IV'
|
||||
"""
|
||||
|
||||
numerals = ""
|
||||
|
||||
m_count = num // 1000
|
||||
numerals += m_count * "M"
|
||||
num %= 1000
|
||||
|
||||
c_count = num // 100
|
||||
if c_count == 9:
|
||||
numerals += "CM"
|
||||
c_count -= 9
|
||||
elif c_count == 4:
|
||||
numerals += "CD"
|
||||
c_count -= 4
|
||||
if c_count >= 5:
|
||||
numerals += "D"
|
||||
c_count -= 5
|
||||
numerals += c_count * "C"
|
||||
num %= 100
|
||||
|
||||
x_count = num // 10
|
||||
if x_count == 9:
|
||||
numerals += "XC"
|
||||
x_count -= 9
|
||||
elif x_count == 4:
|
||||
numerals += "XL"
|
||||
x_count -= 4
|
||||
if x_count >= 5:
|
||||
numerals += "L"
|
||||
x_count -= 5
|
||||
numerals += x_count * "X"
|
||||
num %= 10
|
||||
|
||||
if num == 9:
|
||||
numerals += "IX"
|
||||
num -= 9
|
||||
elif num == 4:
|
||||
numerals += "IV"
|
||||
num -= 4
|
||||
if num >= 5:
|
||||
numerals += "V"
|
||||
num -= 5
|
||||
numerals += num * "I"
|
||||
|
||||
return numerals
|
||||
|
||||
|
||||
def solution(roman_numerals_filename: str = "/p089_roman.txt") -> int:
|
||||
"""
|
||||
Calculates and returns the answer to project euler problem 89.
|
||||
|
||||
>>> solution("/numeralcleanup_test.txt")
|
||||
16
|
||||
"""
|
||||
|
||||
savings = 0
|
||||
|
||||
file1 = open(os.path.dirname(__file__) + roman_numerals_filename, "r")
|
||||
lines = file1.readlines()
|
||||
for line in lines:
|
||||
original = line.strip()
|
||||
num = parse_roman_numerals(original)
|
||||
shortened = generate_roman_numerals(num)
|
||||
savings += len(original) - len(shortened)
|
||||
|
||||
return savings
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
||||
print(f"{solution() = }")
|
Loading…
Reference in New Issue
Block a user