Solving Two Programming Problems: Josephus Variant and Rational Number Summation
Problem 1: Josephus Game with Alternating Directions
Description: There are N friends numbered from 1 to N arranged in a circle. The game starts with the first person counting counterclockwise, and the M-th person is eliminated. Then, from the next person, counting proceeds clockwise, and the K-th person is eliminated. This pattern alternates between counterclockwise and clockwise until only one person remains. Write a program to output the elimination order of the persons.
Input Format: Three positive integers N, M, K, each not exceeding 1000.
Output Format: A single line of integers representing the elimination order, each followed by a space.
Sample Input:
6 3 5
Sample Output:
5 3 1 2 4 6
Implementation Notes: Initially, the solution marked eliminated persons but failed to correctly skip eliminated individuals when moving to the next person. The correct approach is to move to the next non-eliminated person in the sequence.
Code Example:
#include <stdio.h>
int main() {
int totalPlayers, counterClockwiseStep, clockwiseStep;
scanf("%d %d %d", &totalPlayers, &counterClockwiseStep, &clockwiseStep);
int eliminated[1005] = {0};
int eliminationOrder[1005];
int orderIndex = 0;
int currentPosition = 1;
int direction = -1; // -1 for counterclockwise, 1 for clockwise
while (orderIndex < totalPlayers) {
int stepCount = 0;
int stepTarget = (direction == -1) ? counterClockwiseStep : clockwiseStep;
while (stepCount < stepTarget) {
if (eliminated[currentPosition] == 0) {
stepCount++;
}
if (stepCount == stepTarget) {
break;
}
if (direction == -1) {
currentPosition--;
if (currentPosition <= 0) {
currentPosition = totalPlayers;
}
} else {
currentPosition++;
if (currentPosition > totalPlayers) {
currentPosition = 1;
}
}
}
eliminated[currentPosition] = 1;
eliminationOrder[orderIndex++] = currentPosition;
// Move to next non-eliminated person
while (eliminated[currentPosition] == 1) {
if (direction == -1) {
currentPosition--;
if (currentPosition <= 0) {
currentPosition = totalPlayers;
}
} else {
currentPosition++;
if (currentPosition > totalPlayers) {
currentPosition = 1;
}
}
}
direction *= -1; // Switch direction
}
for (int i = 0; i < totalPlayers; i++) {
printf("%d ", eliminationOrder[i]);
}
return 0;
}
Problem 2: Summation of Rational Numbers
Description: Given N rational numbers in the form numerator/denominator, compute their sum and output it in simplest form. The result should be expressed as an integer part and a fractional part (if any), with the fractional part in reduced form (numerator < denominator, no common factors). If the integer part is zero, output only the fractional part.
Input Format: The first line contains a positive integer N (≤100). The next line contains N rational numbers in the format a1/b1 a2/b2 ... aN/bN, where negative signs appear before the numerator. All numerators and denominators are within the range of long integers.
Output Format: Output the sum in simplest form as described.
Sample Input 1:
5
2/5 4/15 1/30 -2/60 8/3
Sample Output 1:
3 1/3
Sammple Input 2:
2
4/3 2/3
Sample Output 2:
2
Sample Input 3:
3
1/3 -1/6 1/8
Sample Output 3:
7/24
Implementation Notes: A common mistake is using Euclideen algorithm incorrectly; ensure the loop terminates when the remainder is zero. Also, handle zero inputs appropriately and use at least long int data types to prevent overflow.
Code Example:
#include <stdio.h>
long long gcd(long long a, long long b) {
while (b != 0) {
long long temp = b;
b = a % b;
a = temp;
}
return a;
}
int main() {
long long count;
scanf("%lld", &count);
if (count == 0) {
return 0;
}
long long numerators[105], denominators[105];
for (long long i = 0; i < count; i++) {
scanf("%lld/%lld", &numerators[i], &denominators[i]);
}
long long commonDenominator = 1;
for (long long i = 0; i < count; i++) {
long long divisor = gcd(commonDenominator, denominators[i]);
commonDenominator = commonDenominator / divisor * denominators[i];
}
long long totalNumerator = 0;
for (long long i = 0; i < count; i++) {
if (numerators[i] != 0) {
long long multiplier = commonDenominator / denominators[i];
totalNumerator += multiplier * numerators[i];
}
}
long long integerPart = totalNumerator / commonDenominator;
long long fractionalNumerator = totalNumerator % commonDenominator;
if (fractionalNumerator != 0) {
long long commonDivisor = gcd(fractionalNumerator, commonDenominator);
fractionalNumerator /= commonDivisor;
commonDenominator /= commonDivisor;
}
if (fractionalNumerator == 0) {
printf("%lld", integerPart);
} else if (integerPart == 0) {
printf("%lld/%lld", fractionalNumerator, commonDenominator);
} else {
printf("%lld %lld/%lld", integerPart, fractionalNumerator, commonDenominator);
}
return 0;
}