Narcissistic Numbers
A narcissistic number (also known as an Armstrong number) is a three-digit number where the sum of each digit raised to the power of three equals the original number. For instance, 153 is narcissistic because 1³ + 5³ + 3³ = 153.
for num in range(100, 1000):
hundreds = num // 100
tens = (num // 10) % 10
units = num % 10
if hundreds ** 3 + tens ** 3 + units ** 3 == num:
print(f"{num} is a narcissistic number")
Output: 153, 370, 371, 407
Four-Leaf Rose Numbers
A four-leaf rose number is the four-digit version of Armstrong numbers. It requires that the sum of each digit raised to the fourth power equals the number itself.
for num in range(1000, 10000):
thousands = num // 1000
hundreds = (num // 100) % 10
tens = (num // 10) % 10
units = num % 10
if thousands ** 4 + hundreds ** 4 + tens ** 4 + units ** 4 == num:
print(f"{num} is a four-leaf rose number")
Output: 1634, 8208, 9474
Reversing a String
Method 1: Slice Notation
text = input("Enter a string: ")
print(text[::-1])
Method 2: Loop with List Building
text = input("Enter a string: ")
result = []
for idx in range(len(text) - 1, -1, -1):
result.append(text[idx])
print(''.join(result))
Number Guessing Game
Generate a random number between 0 and 100. The player gets 10 attempts to guess it, receiving hints whether their guess is higher or lower than the target.
import random
target = random.randint(0, 100)
for attempt in range(10):
guess = int(input("Enter your guess: "))
if guess > target:
print("Too high")
elif guess < target:
print("Too low")
else:
print(f"Correct! You used {attempt + 1} attempts")
break
print(f"Remaining attempts: {9 - attempt}")
else:
print("Game over - you didn't find the number")
Chicken Purchasing Problem
With 100 yuan, purchase exactly 100 chickens. Roosters cost 5 yuan each, hens cost 3 yuan each, and chicks cost 1 yuan for three. Find all possible combinations.
Mathematical constraints:
- x + y + z = 100 (total chickens)
- 5x + 3y + z/3 = 100 (total cost)
count = 0
for roosters in range(1, 20):
for hens in range(1, 33):
chicks = 100 - roosters - hens
if chicks > 0 and 5 * roosters + 3 * hens + chicks / 3 == 100:
count += 1
print(f"Solution {count}: Roosters={roosters}, Hens={hens}, Chicks={chicks}")
Output: Three valid combinations exist for this problem.
Day of Year Calculator
Input a date (year, month, day) and determine whether it's a leap year, then calculate which day of the year it represents.
Leap year conditions:
- Divisible by 4 but not by 100, OR
- Divisible by 400
year = int(input("Year: "))
month = int(input("Month: "))
day = int(input("Day: "))
days_in_month = [31, 29 if (year % 4 == 0 and year % 100 != 0) or year % 400 == 0 else 28,
31, 30, 31, 30, 31, 31, 30, 31, 30, 31]
total_days = day
for m in range(month - 1):
total_days += days_in_month[m]
leap_status = "leap" if (year % 4 == 0 and year % 100 != 0) or year % 400 == 0 else "common"
print(f"{year} is a {leap_status} year")
print(f"{month}/{day} is day {total_days} of the year")
Monkey and Peaches
A monkey collects some peaches. Each morning, it eats half of the remaining peaches plus one additional peach. After 10 mornings, only 1 peach remains. Calculate the initial number of peaches.
Working backwards from day 10: if p peaches remain before eating on day 9, then p/2 - 1 = 1, giving p = 4.
remaining = 1
print(f"Morning 10: {remaining} peaches")
for d in range(9, 0, -1):
remaining = (remaining + 1) * 2
print(f"Morning {d}: {remaining} peaches")
print(f"Initial count: {remaining} peaches")
Output: The monkey initially collected 1534 peaches.
Bubble Sort
The algorithm repeatedly steps through the list, comparing adjacent elements and swapping them if they are in the wrong order. The pass through the list is repeated until the list is sorted.
import random
data = [random.randint(0, 99) for _ in range(6)]
n = len(data)
print(f"Unsorted: {data}")
for i in range(n - 1):
for j in range(n - i - 1):
if data[j] > data[j + 1]:
data[j], data[j + 1] = data[j + 1], data[j]
print(f"Sorted: {data}")
Binary Search
Binary search efficiently finds a target in a sorted sequence by repeatedly dividing the search interval in half.
Iterative Approach
def binary_search(arr, target):
low, high = 0, len(arr) - 1
attempts = 0
while low <= high:
mid = (low + high) // 2
attempts += 1
if target > arr[mid]:
low = mid + 1
elif target < arr[mid]:
high = mid - 1
else:
return mid, attempts
return -1, attempts
sorted_array = [5, 7, 11, 22, 27, 33, 39, 52, 58]
index, count = binary_search(sorted_array, 11)
print(f"Found at index {index} in {count} attempts")
Recursive Approach
def binary_search_recursive(arr, target, low, high):
if low <= high:
mid = (low + high) // 2
if target < arr[mid]:
return binary_search_recursive(arr, target, low, mid - 1)
elif target > arr[mid]:
return binary_search_recursive(arr, target, mid + 1, high)
else:
return mid
return -1
result = binary_search_recursive([5, 7, 11, 22, 27, 33, 39, 52, 58], 11, 0, 8)
print(f"Index: {result}")
Selection Sort
The algorithm divides the input list into two parts: sorted and unsorted. It repeatedly selects the minimum element from the unsorted portion and moves it to the sorted portion.
import random
items = [random.randint(1, 100) for _ in range(8)]
size = len(items)
print(f"Unsorted: {items}")
for i in range(size - 1):
min_pos = i
for j in range(i + 1, size):
if items[min_pos] > items[j]:
min_pos = j
items[i], items[min_pos] = items[min_pos], items[i]
print(f"Pass {i + 1}: {items}")
print(f"Final sorted: {items}")
Rock Paper Scissors Game
A game where both player and computer start with 100 points. Winning adds 10 points, losing subtracts 10. The game ends when either player reaches 200 (win) or 0 (lose).
import random
choices = {1: "Scissors", 2: "Rock", 3: "Paper"}
points = 100
print("=" * 40)
print(" ROCK PAPER SCISSORS")
print("1=Scissors 2=Rock 3=Paper")
while True:
computer = random.randint(1, 3)
player_input = input("Your choice: ")
if player_input not in ('1', '2', '3'):
print("Invalid input, try again")
continue
player = int(player_input)
print(f"Computer: {choices[computer]} | You: {choices[player]}")
if (player == 1 and computer == 3) or \
(player == 2 and computer == 1) or \
(player == 3 and computer == 2):
points += 10
print(f"You win! Score: {points}")
elif player == computer:
print(f"Draw! Score: {points}")
else:
points -= 10
print(f"You lose! Score: {points}")
if points >= 200:
print("Congratulations - you win!")
break
elif points <= 0:
print("Game over - you lose")
break
Happy Numbers
A happy number is one where repeatedly replacing the number with the sum of squares of its digits eventually yields 1. If it never reaches 1, it's an unhappy number.
Example with 19: 19 → 82 → 68 → 100 → 1 (happy)
def digit_square_sum(n):
total = 0
for digit in str(n):
total += int(digit) ** 2
return total
def is_happy(n):
seen = set()
while digit_square_sum(n) not in seen:
n = digit_square_sum(n)
seen.add(n)
return n == 1
num = int(input("Enter a number: "))
print("Happy number" if is_happy(num) else "Not a happy number")
Age Puzzle - Two Sisters
The product of two sisters' ages is 6 times their sum, and their age difference is at most 8 years. Find the younger sister's age.
for older in range(1, 100):
for younger in range(1, older):
if older * younger == 6 * (older + younger) and older - younger <= 8:
print(f"Older: {older}, Younger: {younger}")
Solution: The sisters are 15 and 10 years old.
Age Puzzle - Mathematician Wiener
A mathematician's age has a cube that is 4 digits and a fourth power that is 6 digits. These 10 digits contain each digit 0-9 exactly once. Find his age.
for age in range(10, 30):
cube = str(age ** 3)
fourth = str(age ** 4)
if len(cube) == 4 and len(fourth) == 6:
if len(set(cube + fourth)) == 10:
print(f"Age: {age}")
print(f"Cube: {cube}, Fourth power: {fourth}")
The mathematician was 18 years old (18³=5832, 18⁴=104976).
Custom Split Function
Implement a string splitting function similar to Python's built-in split(), handling a separator and optional limit parameter.
def custom_split(text, delimiter="", limit=0):
parts = []
start = 0
splits = 0
for idx, char in enumerate(text):
if limit > 0 and splits == limit:
parts.append(text[start:])
break
if char == delimiter:
parts.append(text[start:idx])
start = idx + 1
splits += 1
elif idx == len(text) - 1:
parts.append(text[start:idx + 1])
return parts
print(custom_split("life-is-short-you-need-python", "-"))
# ['life', 'is', 'short', 'you', 'need', 'python']
print(custom_split("life-is-short-you-need-python", "-", 2))
# ['life', 'is', 'short-you-need-python']
Dayan Sequence
An ancient Chinese sequecne: 0, 2, 4, 8, 12, 18, 24, 32, 40, 50, ... The pattern: even positions are n²/2, odd positions are (n²-1)/2.
for n in range(1, 101):
if n % 2 == 0:
value = int((n ** 2) / 2)
else:
value = int((n ** 2 - 1) / 2)
print(value)
Character Frequency Analysis
Given a string, find the character that appears most frequently and count its occurrences.
def most_frequent(text):
frequencies = {}
for ch in text:
frequencies[ch] = frequencies.get(ch, 0) + 1
max_char = max(frequencies, key=frequencies.get)
return max_char, frequencies[max_char]
char, count = most_frequent("HelloWorld")
print(f"Most frequent: '{char}', count: {count}")
Output: l appears 3 times
Diamond Pattern Using Stack
Print a diamond of given side length using stack-based logic for the lower half.
def print_diamond(size):
stack = []
for row in range(1, 2 * size):
if row <= size:
pattern = ' ' * (size - row) + '*' * (2 * row - 1)
if row != size:
stack.append(pattern)
print(pattern)
else:
print(stack.pop())
print_diamond(5)
Output forms a diamond shape with the upper half printed directly and lower half popped from stack.
Understanding Recursion
A recursive function calls itself. Every recursive call adds a new frame to the stack, and there must be a base case to terminate.
Three elements of recursion design:
- Define the function's purpose clearly
- Identify the termination condition
- Establish the recursive relationship
def recursive_demo(n):
if n == 0:
return
print(f"Before recursive call: {n}")
recursive_demo(n - 1)
print(f"After recursive call: {n}")
recursive_demo(5)
Output demonstrates how function calls stack up before unwinding on return.
Fibonacci Sequence with Recursion
The Fibonacci sequence: 1, 1, 2, 3, 5, 8, 13, 21, 34, ... Each term (from the third onward) equals the sum of the two preceding terms.
Formula: f(n) = f(n-1) + f(n-2)
def fibonacci(n):
if n <= 2:
return 1
return fibonacci(n - 1) + fibonacci(n - 2)
for i in range(1, 11):
print(f"fib({i}) = {fibonacci(i)}")
Recursion and stack memory: Each function call pushes a frame onto the call stack. The first call returns last, following LIFO (Last In, First Out) principles.
Finding Maximum of Three Numbers
Determine the largest of three numbers using only conditional statements, without built-in functions or data structures.
a, b, c = 10, 6, 18
max_val = a if a > b else b
max_val = max_val if max_val > c else c
print(max_val)
Perfect Numbers
A perfect number equals the sum of its proper divisors (excluding itself). For example, 6 = 1 + 2 + 3.
def divisor_sum(n):
total = 0
for i in range(1, n):
if n % i == 0:
total += i
return total
for num in range(1, 1000):
if num == divisor_sum(num):
print(f"{num} is perfect")
Output: 6, 28, 496
Factorial Sum
Calculate the sum of factorials: 1! + 2! + 3! + ... + 10!
Formula: f(n) = n × f(n-1)
def factorial(n):
if n < 2:
return 1
return n * factorial(n - 1)
total = sum(factorial(i) for i in range(1, 11))
print(f"Sum of factorials: {total}")
Valid Parentheses
Determine if a string containing '(', ')', '{', '}', '[', ']' is valid. Valid means matching pairs in correct order.
Method 1: String Replacement
def is_valid_v1(s):
if len(s) % 2 == 1:
return False
while '()' in s or '[]' in s or '{}' in s:
s = s.replace('()', '').replace('[]', '').replace('{}', '')
return len(s) == 0
print(is_valid_v1("()")) # True
print(is_valid_v1("()[]{}")) # True
print(is_valid_v1("([])")) # True
Method 2: Stack-Based
def is_valid_v2(s):
if len(s) % 2 == 1:
return False
stack = []
pairs = {')': '(', '}': '{', ']': '['}
for char in s:
if char in pairs:
if not stack or stack[-1] != pairs[char]:
return False
stack.pop()
else:
stack.append(char)
return len(stack) == 0
print(is_valid_v2("(){}[({[]})]")) # True
print(is_valid_v2("(){}[({[)}]")) # False
Palindrome Numbers
A palindrome reads the same forwards and backwards. Examples: 121, 1221, 12321.
Method 1: String Reversal
def is_palindrome_str(n):
if n < 0 or (n > 0 and n % 10 == 0):
return False
return str(n) == str(n)[::-1]
print(is_palindrome_str(121)) # True
print(is_palindrome_str(-121)) # False
Method 2: Reverse Half the Number
def is_palindrome_math(n):
if n < 0 or (n > 0 and n % 10 == 0):
return False
reversed_half = 0
while n > reversed_half:
reversed_half = reversed_half * 10 + n % 10
n //= 10
return n == reversed_half or n == reversed_half // 10
print(is_palindrome_math(1221)) # True
print(is_palindrome_math(123321)) # True
print(is_palindrome_math(12321)) # True