3 Intermediate Python coding challenges (with solutions)
Tags: python, challenge, tutorial, beginners
Published: 2023-01-25 11:43:33

The previous [Python coding challenges for beginners](https://dev.to/rachelsarchive/5-coding-challenges-for-beginners-with-solutions-in-python-5f2l) seem to be well-received so I decided to create another post for intermediate coding challenges. Have fun solving & don't hesistate to share your feedback or solutions in the comment section :)

### 1. Caesar Cipher

**Background:** 
Caesar's cipher is a simple encryption technique, in which the plaintext character is replaced by a letter some fixed number of positions down the alphabet. 

For example, with a right shift of 3, A would be replaced by D, B would become E, and so on. 

![Caesar's cipher](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/txybw0mpkn5rwx3r0kfh.png)

**Task:** 
Write a Python program to decode the following secret message: `N qtaj uwtlwfrrnsl zxnsl Udymts`, given that the key is 5.

**Starter code:**

```python
ciphertext = "N qtaj uwtlwfrrnsl zxnsl Udymts"

def decrypt(ciphertext, key):
    # complete code here

decrypt(ciphertext, 5)
```

**Sample solution:**

```python
def decrypt(ciphertext, key):
    letters = "abcdefghijklmnopqrstuvwxyz"
    letters_upper = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
    
    message = ""
    
    for char in ciphertext:
        if char in letters:      
            position = letters.find(char)
            new_pos = (position - key) % 26
            new_char = letters[new_pos]
            message += new_char
        elif char in letters_upper:
            position = letters_upper.find(char)
            new_pos = (position - key) % 26
            new_char = letters_upper[new_pos]
            message += new_char
        else:
            message += char
        return message

print(decrypt(cipher, 5))
```

---

### 2. Simple Mastermind Game

**Task:** 
Write a program that randomly generates a 4 digit number. The user has maximum 10 tries to guess the number. 

+ If any of the digit guessed is wrong, print "A" to indicate wrong guess. 

+ If the digit is guessed correctly but in the wrong position, print "B".

+ If the digit guessed is both the correct value and position, print "C".

**Starter code:**

```python
import random

def generate_number():
    # complete code here
	
def input_guess():
    guess = input("Enter your guess: ")
    return guess

def start_game():
    # complete code here
		
start_game()
```

**Sample solution:**

```python
import random

def generate_number():
    num = random.randint(1000,9999)
    num = [int(x) for x in str(num)]
    return num
	
def input_guess():
    guess = input("Enter your guess: ")
    return guess

def start_game():
    tries = 0
    number = generate_number()
	
    while tries < 10:
        result = ""
        guess = [int(i) for i in input_guess()]

        if len(guess) != 4:
            print("Enter only 4 digit number")
            continue
        
        if guess == number:
            print("You won with ", tries, " attempts.")
            break
    
        for element in guess:
            if element in number:
                if guess.index(element) == number.index(element):
                    result+="C"
                else:
                    result+="B"
            else:
                result+="A"
        print(result)
        tries += 1

    else:	
        print("You ran out of attempts. The answer is: " , "".join(map(str, number)))	
		
start_game()
```
---

###3. Roman Numerals & Integer Converter

**Background:** 
The Roman numeral system consists of the following symbols:

|Symbol	|Value|
|---------------|-----|
|I	|1|
|V	|5|
|X	|10|
|L	|50|
|C	|100|
|D	|500|
|M	|1000|

Numbers are constructed by combining these symbols. For instance, the number `12` can be represented by `XII`, since `X + I + I = 10 + 1 + 1`. 

The following list is set of rules for Roman numerals:

+ Zero is not represented.

+ A symbol can be repeated only for three times.

+ Roman numerals are repeated to add value: `III` is equivalent to 1 +1 +1 = 3. However, only powers of 10 may be repeated in this way. Thus, `VV` is invalid; 5 + 5 would instead be expressed as `X`. 

+ When a Roman numeral is placed after another Roman numeral of greater value, the result is the sum of the numerals. When a Roman numeral is placed before another Roman numeral of greater value, the result is the difference between the numerals.

+ Only `I`, `X`, and `C` can be used as subtractive numerals as shown:
    + `I` can be used before `V(5)` and `X(10)` to make it `IV(4)` and `XV(9)` respectively.
    + `X` cab be used before `L(50)` and `C(100)` to make it `XL(40)` and `XC(90)` respectively
    + `C` can be used before `D(500)` and `M(1000)` to make them `CD(400)` and `CM(900)` respectively.

**Task:**
Write a program that allows users to either convert integers to roman numerals, or convert roman numerals to integers.

**Starter code:**
```python
def roman_to_int(roman):
  # complete code here
  
def int_to_roman(int):
  # complete code here
  
print(" ---------- Roman Numberals Conversion ----------")  
print(" > 1 - Convert an integer to a roman numerals,")  
print(" > 2 - Convert a roman numerals to an integer.")  
option = input("Choose an option (1 or 2):")  
# complete code here
```

**Sample solution:**

```python
def roman_to_int(s):
    roman_values = {"I": 1, "V": 5, "X": 10, "L": 50, "C": 100, "D": 500, "M": 1000}
  
    result = 0
  
    for i in range(len(s)):
        if i + 1 < len(s) and roman_values[s[i]] < roman_values[s[i + 1]]:
            result -= roman_values[s[i]]
        else:
            result += roman_values[s[i]]

    return result
  
  
def int_to_roman(x):
    roman_map = { 1: 'I', 4: 'IV', 5: 'V', 9: 'IX', 10: 'X', 40: 'XL', 50: 'L', 90: 'XC', 100: 'C', 400: 'XD', 500: 'D', 900: 'CM', 1000: 'M'}
    integers = list(roman_map)
    symbols = list(roman_map.values())
  
    i = 12
    result = ""

    while x != 0:
        if integers[i] <= x:
            result += symbols[i]
            x -= integers[i]
        else:
            i -= 1
    
    return result

  
print(" ---------- Roman Numberals Conversion ----------")  
print(" > 1 - Convert an integer to a roman numerals,")  
print(" > 2 - Convert a roman numerals to an integer.")  
option = input("Choose an option (1 or 2):")  

if option == "1":
    num = int(input("Enter an integer: "))
    print(int_to_roman(num))
elif option == "2":
    roman = input("Enter a Roman numeral: ")
    print(roman_to_int(roman))
else:
    print("Invalid input.")
```