Repeated Digit Sum with a Special Key
National Olympiad — Regional round (2014 season)
Submission name: numerology.cpp
Problem summary
Give A…Z values 1…9 cyclically, ignoring case, and sum a name’s letter values. Repeatedly sum decimal digits until one digit remains, but stop immediately if the value is 33.
Input
One Latin-letter name.
Output
Its resulting key.
Constraints
The name contains at most 20 uppercase or lowercase Latin letters.
Worked example
Input and output for the worked example discussed below.
Input
teodora
Output
33
Solution analysis
- The cyclic mapping is (uppercaseLetter−A) mod 9 + 1. Thus A,J,S all map to 1, while I,R map to 9. Sum these values before beginning decimal digit reduction.
- While the total has at least two digits and is not 33, replace it by its decimal digit sum. Check the exception before every reduction, including the first one.
- For teodora the mapped values are 2,5,6,4,6,9,1, summing to 33. The exception retains 33 rather than reducing it to 6. ISKRA instead sums to 22 and then becomes 4.
Why it works
The modulo expression implements exactly the repeated 1…9 letter table. Every reduction computes the decimal digit sum prescribed by the rules, and the loop stops exactly at one digit or the exceptional value 33.
Watch out. Do not use alphabet positions 1…26 without cycling, ignore case incorrectly, or reduce 33 to 6.
Commented C++17 solution
An independently written complete program with standard headers.
#include<cctype>
#include<iostream>
#include<string>
using namespace std;
int main(){
string name;
cin>>name;
int key=0;
for(char letter:name){
int upper=toupper(static_cast<unsigned char>(letter));
key+=(upper-'A')%9+1;
}
// The exceptional key must be checked before each reduction.
while(key>9&&key!=33){
int sum=0;
while(key>0){
sum+=key%10;
key/=10;
}
key=sum;
}
cout<<key<<'\n';
}