# Chapter 1: Introduction to Algorithms

## 1.4 Practice Problems of Chapter 1: Introduction to Algorithms

Having covered the fundamentals of algorithms and computational thinking, it's now time to put these principles into practice. The problems in this section have been designed to help you think computationally and apply the concepts of decomposition, pattern recognition, abstraction, and algorithmic thinking. Don't worry if you can't solve a problem immediately - remember that part of computational thinking is iteration and refining your approach.

**Problem 1: Password Generator**

**Problem Description:** Write an algorithm to generate a password of length n. The password should be randomly generated and must include at least one uppercase letter, one lowercase letter, one digit, and one special character.

**Hint:** Consider decomposing the problem into parts - generating an uppercase letter, generating a lowercase letter, generating a digit, generating a special character, and then combining these parts.

**Solution**:

To solve this problem, we could create four functions to generate a random uppercase letter, a random lowercase letter, a random digit, and a random special character respectively. Then, we combine these randomly generated characters, and fill the rest of the password length with random characters from all groups.

Here's how we could write it in Python:

`import random`

import string

def generate_password(n):

# Ensure n is at least 4 so we can include at least one of each character type

assert(n >= 4), "Password length must be at least 4"

password = []

password.append(random.choice(string.ascii_uppercase))

password.append(random.choice(string.ascii_lowercase))

password.append(random.choice(string.digits))

password.append(random.choice(string.punctuation))

for i in range(n - 4):

random_choice = random.choice([0, 1, 2, 3])

if random_choice == 0:

password.append(random.choice(string.ascii_uppercase))

elif random_choice == 1:

password.append(random.choice(string.ascii_lowercase))

elif random_choice == 2:

password.append(random.choice(string.digits))

else:

password.append(random.choice(string.punctuation))

random.shuffle(password)

return ''.join(password)

**Problem 2: Calendar Events**

**Problem Description:** You have a list of events with their start times and end times (in 24-hour format). Write an algorithm to determine if any of the events overlap.

**Hint:** Look for patterns in how events overlap, and think about how you might abstract the problem to make it more manageable.

**Solution:**

First, we'll sort the list of events based on their start times. Then, we'll iterate through the sorted list and compare the end time of the current event to the start time of the next event. If the end time of the current event is later than the start time of the next event, then there is an overlap.

`def has_overlap(events):`

# Sort events by start time

events.sort(key = lambda x: x['start'])

for i in range(len(events) - 1):

if events[i]['end'] > events[i + 1]['start']:

return True

return False

**Problem 3: Building a Pyramid**

**Problem Description:** Given a number n, write an algorithm to print a pyramid of asterisks with n levels. For example, if n = 3, the output should be:

` *`

***

*****

**Hint:** Decompose the problem into two parts - generating each level of the pyramid, and then combining the levels. Also, try to recognize patterns in the number of asterisks and spaces.

**Solution**:

This problem can be solved by printing each level of the pyramid one by one. At each level, we print some spaces, followed by some asterisks, and then some spaces again.

`def print_pyramid(n):`

for i in range(n):

print(' ' * (n - i - 1) + '*' * (2 * i + 1) + ' ' * (n - i - 1))

**Problem 4: Text Compression**

**Problem Description:** Write an algorithm to compress a given string by replacing consecutive identical characters with the character followed by the number of times it appears. For example, the string "aaabbbbcc" should be compressed to "a3b4c2".

**Hint:** This problem can be approached using algorithmic thinking - devise a step-by-step process to traverse the string and keep track of the count of each character.

**Solution:**

We can solve this problem by iterating over the string and keeping track of the current character and its count. If the current character is different from the previous one, we add the previous character and its count to the compressed string and reset the count.

`def compress_text(text):`

compressed = ''

count = 1

for i in range(1, len(text)):

if text[i] == text[i - 1]:

count += 1

else:

compressed += text[i - 1] + str(count)

count = 1

# Add the last character and its count

compressed += text[-1] + str(count)

return compressed

Remember, these problems are not just about finding the correct answer, but about understanding and applying computational thinking. Once you've attempted a problem, try to reflect on how you used decomposition, pattern recognition, abstraction, and algorithmic thinking. If you find a solution, consider how you might refine it to make it more efficient or more elegant.

## 1.4 Practice Problems of Chapter 1: Introduction to Algorithms

Having covered the fundamentals of algorithms and computational thinking, it's now time to put these principles into practice. The problems in this section have been designed to help you think computationally and apply the concepts of decomposition, pattern recognition, abstraction, and algorithmic thinking. Don't worry if you can't solve a problem immediately - remember that part of computational thinking is iteration and refining your approach.

**Problem 1: Password Generator**

**Problem Description:** Write an algorithm to generate a password of length n. The password should be randomly generated and must include at least one uppercase letter, one lowercase letter, one digit, and one special character.

**Hint:** Consider decomposing the problem into parts - generating an uppercase letter, generating a lowercase letter, generating a digit, generating a special character, and then combining these parts.

**Solution**:

To solve this problem, we could create four functions to generate a random uppercase letter, a random lowercase letter, a random digit, and a random special character respectively. Then, we combine these randomly generated characters, and fill the rest of the password length with random characters from all groups.

Here's how we could write it in Python:

`import random`

import string

def generate_password(n):

# Ensure n is at least 4 so we can include at least one of each character type

assert(n >= 4), "Password length must be at least 4"

password = []

password.append(random.choice(string.ascii_uppercase))

password.append(random.choice(string.ascii_lowercase))

password.append(random.choice(string.digits))

password.append(random.choice(string.punctuation))

for i in range(n - 4):

random_choice = random.choice([0, 1, 2, 3])

if random_choice == 0:

password.append(random.choice(string.ascii_uppercase))

elif random_choice == 1:

password.append(random.choice(string.ascii_lowercase))

elif random_choice == 2:

password.append(random.choice(string.digits))

else:

password.append(random.choice(string.punctuation))

random.shuffle(password)

return ''.join(password)

**Problem 2: Calendar Events**

**Problem Description:** You have a list of events with their start times and end times (in 24-hour format). Write an algorithm to determine if any of the events overlap.

**Hint:** Look for patterns in how events overlap, and think about how you might abstract the problem to make it more manageable.

**Solution:**

First, we'll sort the list of events based on their start times. Then, we'll iterate through the sorted list and compare the end time of the current event to the start time of the next event. If the end time of the current event is later than the start time of the next event, then there is an overlap.

`def has_overlap(events):`

# Sort events by start time

events.sort(key = lambda x: x['start'])

for i in range(len(events) - 1):

if events[i]['end'] > events[i + 1]['start']:

return True

return False

**Problem 3: Building a Pyramid**

**Problem Description:** Given a number n, write an algorithm to print a pyramid of asterisks with n levels. For example, if n = 3, the output should be:

` *`

***

*****

**Hint:** Decompose the problem into two parts - generating each level of the pyramid, and then combining the levels. Also, try to recognize patterns in the number of asterisks and spaces.

**Solution**:

This problem can be solved by printing each level of the pyramid one by one. At each level, we print some spaces, followed by some asterisks, and then some spaces again.

`def print_pyramid(n):`

for i in range(n):

print(' ' * (n - i - 1) + '*' * (2 * i + 1) + ' ' * (n - i - 1))

**Problem 4: Text Compression**

**Problem Description:** Write an algorithm to compress a given string by replacing consecutive identical characters with the character followed by the number of times it appears. For example, the string "aaabbbbcc" should be compressed to "a3b4c2".

**Hint:** This problem can be approached using algorithmic thinking - devise a step-by-step process to traverse the string and keep track of the count of each character.

**Solution:**

We can solve this problem by iterating over the string and keeping track of the current character and its count. If the current character is different from the previous one, we add the previous character and its count to the compressed string and reset the count.

`def compress_text(text):`

compressed = ''

count = 1

for i in range(1, len(text)):

if text[i] == text[i - 1]:

count += 1

else:

compressed += text[i - 1] + str(count)

count = 1

# Add the last character and its count

compressed += text[-1] + str(count)

return compressed

Remember, these problems are not just about finding the correct answer, but about understanding and applying computational thinking. Once you've attempted a problem, try to reflect on how you used decomposition, pattern recognition, abstraction, and algorithmic thinking. If you find a solution, consider how you might refine it to make it more efficient or more elegant.

## 1.4 Practice Problems of Chapter 1: Introduction to Algorithms

Having covered the fundamentals of algorithms and computational thinking, it's now time to put these principles into practice. The problems in this section have been designed to help you think computationally and apply the concepts of decomposition, pattern recognition, abstraction, and algorithmic thinking. Don't worry if you can't solve a problem immediately - remember that part of computational thinking is iteration and refining your approach.

**Problem 1: Password Generator**

**Problem Description:** Write an algorithm to generate a password of length n. The password should be randomly generated and must include at least one uppercase letter, one lowercase letter, one digit, and one special character.

**Hint:** Consider decomposing the problem into parts - generating an uppercase letter, generating a lowercase letter, generating a digit, generating a special character, and then combining these parts.

**Solution**:

To solve this problem, we could create four functions to generate a random uppercase letter, a random lowercase letter, a random digit, and a random special character respectively. Then, we combine these randomly generated characters, and fill the rest of the password length with random characters from all groups.

Here's how we could write it in Python:

`import random`

import string

def generate_password(n):

# Ensure n is at least 4 so we can include at least one of each character type

assert(n >= 4), "Password length must be at least 4"

password = []

password.append(random.choice(string.ascii_uppercase))

password.append(random.choice(string.ascii_lowercase))

password.append(random.choice(string.digits))

password.append(random.choice(string.punctuation))

for i in range(n - 4):

random_choice = random.choice([0, 1, 2, 3])

if random_choice == 0:

password.append(random.choice(string.ascii_uppercase))

elif random_choice == 1:

password.append(random.choice(string.ascii_lowercase))

elif random_choice == 2:

password.append(random.choice(string.digits))

else:

password.append(random.choice(string.punctuation))

random.shuffle(password)

return ''.join(password)

**Problem 2: Calendar Events**

**Problem Description:** You have a list of events with their start times and end times (in 24-hour format). Write an algorithm to determine if any of the events overlap.

**Hint:** Look for patterns in how events overlap, and think about how you might abstract the problem to make it more manageable.

**Solution:**

First, we'll sort the list of events based on their start times. Then, we'll iterate through the sorted list and compare the end time of the current event to the start time of the next event. If the end time of the current event is later than the start time of the next event, then there is an overlap.

`def has_overlap(events):`

# Sort events by start time

events.sort(key = lambda x: x['start'])

for i in range(len(events) - 1):

if events[i]['end'] > events[i + 1]['start']:

return True

return False

**Problem 3: Building a Pyramid**

**Problem Description:** Given a number n, write an algorithm to print a pyramid of asterisks with n levels. For example, if n = 3, the output should be:

` *`

***

*****

**Hint:** Decompose the problem into two parts - generating each level of the pyramid, and then combining the levels. Also, try to recognize patterns in the number of asterisks and spaces.

**Solution**:

This problem can be solved by printing each level of the pyramid one by one. At each level, we print some spaces, followed by some asterisks, and then some spaces again.

`def print_pyramid(n):`

for i in range(n):

print(' ' * (n - i - 1) + '*' * (2 * i + 1) + ' ' * (n - i - 1))

**Problem 4: Text Compression**

**Problem Description:** Write an algorithm to compress a given string by replacing consecutive identical characters with the character followed by the number of times it appears. For example, the string "aaabbbbcc" should be compressed to "a3b4c2".

**Hint:** This problem can be approached using algorithmic thinking - devise a step-by-step process to traverse the string and keep track of the count of each character.

**Solution:**

We can solve this problem by iterating over the string and keeping track of the current character and its count. If the current character is different from the previous one, we add the previous character and its count to the compressed string and reset the count.

`def compress_text(text):`

compressed = ''

count = 1

for i in range(1, len(text)):

if text[i] == text[i - 1]:

count += 1

else:

compressed += text[i - 1] + str(count)

count = 1

# Add the last character and its count

compressed += text[-1] + str(count)

return compressed

Remember, these problems are not just about finding the correct answer, but about understanding and applying computational thinking. Once you've attempted a problem, try to reflect on how you used decomposition, pattern recognition, abstraction, and algorithmic thinking. If you find a solution, consider how you might refine it to make it more efficient or more elegant.

## 1.4 Practice Problems of Chapter 1: Introduction to Algorithms

**Problem 1: Password Generator**

**Problem Description:** Write an algorithm to generate a password of length n. The password should be randomly generated and must include at least one uppercase letter, one lowercase letter, one digit, and one special character.

**Hint:** Consider decomposing the problem into parts - generating an uppercase letter, generating a lowercase letter, generating a digit, generating a special character, and then combining these parts.

**Solution**:

Here's how we could write it in Python:

`import random`

import string

def generate_password(n):

# Ensure n is at least 4 so we can include at least one of each character type

assert(n >= 4), "Password length must be at least 4"

password = []

password.append(random.choice(string.ascii_uppercase))

password.append(random.choice(string.ascii_lowercase))

password.append(random.choice(string.digits))

password.append(random.choice(string.punctuation))

for i in range(n - 4):

random_choice = random.choice([0, 1, 2, 3])

if random_choice == 0:

password.append(random.choice(string.ascii_uppercase))

elif random_choice == 1:

password.append(random.choice(string.ascii_lowercase))

elif random_choice == 2:

password.append(random.choice(string.digits))

else:

password.append(random.choice(string.punctuation))

random.shuffle(password)

return ''.join(password)

**Problem 2: Calendar Events**

**Problem Description:** You have a list of events with their start times and end times (in 24-hour format). Write an algorithm to determine if any of the events overlap.

**Hint:** Look for patterns in how events overlap, and think about how you might abstract the problem to make it more manageable.

**Solution:**

`def has_overlap(events):`

# Sort events by start time

events.sort(key = lambda x: x['start'])

for i in range(len(events) - 1):

if events[i]['end'] > events[i + 1]['start']:

return True

return False

**Problem 3: Building a Pyramid**

**Problem Description:** Given a number n, write an algorithm to print a pyramid of asterisks with n levels. For example, if n = 3, the output should be:

` *`

***

*****

**Hint:** Decompose the problem into two parts - generating each level of the pyramid, and then combining the levels. Also, try to recognize patterns in the number of asterisks and spaces.

**Solution**:

`def print_pyramid(n):`

for i in range(n):

print(' ' * (n - i - 1) + '*' * (2 * i + 1) + ' ' * (n - i - 1))

**Problem 4: Text Compression**

**Problem Description:** Write an algorithm to compress a given string by replacing consecutive identical characters with the character followed by the number of times it appears. For example, the string "aaabbbbcc" should be compressed to "a3b4c2".

**Hint:** This problem can be approached using algorithmic thinking - devise a step-by-step process to traverse the string and keep track of the count of each character.

**Solution:**

`def compress_text(text):`

compressed = ''

count = 1

for i in range(1, len(text)):

if text[i] == text[i - 1]:

count += 1

else:

compressed += text[i - 1] + str(count)

count = 1

# Add the last character and its count

compressed += text[-1] + str(count)

return compressed