fork download
  1. #include <iostream>
  2. #include <string>
  3. #include <vector>
  4. #include <algorithm>
  5. #include <stdexcept>
  6.  
  7. class NumberSpeller {
  8. private:
  9. const std::vector<std::string> ones = {
  10. "", "one", "two", "three", "four", "five",
  11. "six", "seven", "eight", "nine"
  12. };
  13.  
  14. const std::vector<std::string> teens = {
  15. "ten", "eleven", "twelve", "thirteen", "fourteen",
  16. "fifteen", "sixteen", "seventeen", "eighteen", "nineteen"
  17. };
  18.  
  19. const std::vector<std::string> tens = {
  20. "", "", "twenty", "thirty", "forty", "fifty",
  21. "sixty", "seventy", "eighty", "ninety"
  22. };
  23.  
  24. // Helper function to spell numbers 0-99
  25. std::string spellTwoDigit(int n) {
  26. if (n == 0) return "";
  27. if (n < 10) return ones[n];
  28. if (n < 20) return teens[n - 10];
  29.  
  30. int tensDigit = n / 10;
  31. int onesDigit = n % 10;
  32. if (onesDigit == 0) {
  33. return tens[tensDigit];
  34. }
  35. return tens[tensDigit] + ones[onesDigit];
  36. }
  37.  
  38. // Helper function to spell numbers 0-999
  39. std::string spellThreeDigit(int n) {
  40. if (n == 0) return "";
  41. if (n < 100) return spellTwoDigit(n);
  42.  
  43. int hundreds = n / 100;
  44. int remainder = n % 100;
  45. std::string result = ones[hundreds] + "hundred";
  46.  
  47. if (remainder > 0) {
  48. // Note: In US English, "and" is often omitted, but can be included
  49. // For consistency with UK English, you could add "and" here
  50. result += spellTwoDigit(remainder);
  51. }
  52.  
  53. return result;
  54. }
  55.  
  56. public:
  57. std::string spellNumber(long long n) {
  58. if (n < 1) {
  59. throw std::invalid_argument("Number must be positive");
  60. }
  61.  
  62. // Handle numbers up to 999 trillion (999,999,999,999,999)
  63. if (n >= 1000000000000000LL) {
  64. throw std::invalid_argument("Number too large (max: 999 trillion)");
  65. }
  66.  
  67. if (n < 100) {
  68. return spellTwoDigit(static_cast<int>(n));
  69. }
  70.  
  71. std::vector<std::pair<long long, std::string>> scales = {
  72. {1000000000000LL, "trillion"},
  73. {1000000000LL, "billion"},
  74. {1000000LL, "million"},
  75. {1000LL, "thousand"},
  76. {1LL, ""}
  77. };
  78.  
  79. std::string result;
  80. bool first = true;
  81.  
  82. for (const auto& [scale, name] : scales) {
  83. if (n >= scale) {
  84. int part = static_cast<int>(n / scale);
  85. if (part > 0) {
  86. if (!first) {
  87. // Add separation between parts if needed
  88. // In this implementation, we concatenate directly
  89. }
  90. result += spellThreeDigit(part);
  91. if (!name.empty()) {
  92. result += name;
  93. }
  94. first = false;
  95. }
  96. n %= scale;
  97. }
  98. }
  99.  
  100. return result;
  101. }
  102.  
  103. int countLetters(const std::string& word) {
  104. return std::count_if(word.begin(), word.end(),
  105. [](char c) { return std::isalpha(c); });
  106. }
  107. };
  108.  
  109. class BeautifulNumberCounter {
  110. private:
  111. NumberSpeller speller;
  112.  
  113. public:
  114. bool isBeautiful(long long num) {
  115. try {
  116. std::string spelling = speller.spellNumber(num);
  117. int letterCount = speller.countLetters(spelling);
  118. return letterCount > 0 && (num % letterCount == 0);
  119. } catch (const std::exception&) {
  120. return false;
  121. }
  122. }
  123.  
  124. long long countBeautifulNumbers(long long n) {
  125. if (n < 1) {
  126. throw std::invalid_argument("N must be positive");
  127. }
  128.  
  129. long long count = 0;
  130. for (long long i = 1; i <= n; ++i) {
  131. if (isBeautiful(i)) {
  132. count++;
  133. }
  134. }
  135. return count;
  136. }
  137.  
  138. std::vector<long long> getBeautifulNumbers(long long n) {
  139. if (n < 1) {
  140. throw std::invalid_argument("N must be positive");
  141. }
  142.  
  143. std::vector<long long> beautifulNumbers;
  144. for (long long i = 1; i <= n; ++i) {
  145. if (isBeautiful(i)) {
  146. beautifulNumbers.push_back(i);
  147. }
  148. }
  149. return beautifulNumbers;
  150. }
  151.  
  152. void printBeautifulNumberDetails(long long n) {
  153. try {
  154. std::string spelling = speller.spellNumber(n);
  155. int letterCount = speller.countLetters(spelling);
  156. bool beautiful = (n % letterCount == 0);
  157.  
  158. std::cout << n << ": '" << spelling << "' has " << letterCount
  159. << " letters, " << n << " % " << letterCount
  160. << " = " << (n % letterCount)
  161. << ", beautiful: " << (beautiful ? "true" : "false") << std::endl;
  162. } catch (const std::exception& e) {
  163. std::cout << n << ": Error - " << e.what() << std::endl;
  164. }
  165. }
  166. };
  167.  
  168. int main() {
  169. BeautifulNumberCounter counter;
  170. NumberSpeller speller;
  171.  
  172. // Test the examples from the problem
  173. std::cout << "Testing known examples:" << std::endl;
  174. std::vector<long long> testCases = {4, 6, 12, 86};
  175. for (long long num : testCases) {
  176. counter.printBeautifulNumberDetails(num);
  177. }
  178.  
  179. // Test some larger numbers
  180. std::cout << "\nTesting larger numbers:" << std::endl;
  181. std::vector<long long> largeTests = {100, 144, 200, 1000, 1200};
  182. for (long long num : largeTests) {
  183. counter.printBeautifulNumberDetails(num);
  184. }
  185.  
  186. // Find all beautiful numbers from 1 to 99 (original problem)
  187. std::cout << "\nFinding all beautiful numbers from 1 to 99:" << std::endl;
  188. std::vector<long long> beautifulNumbers = counter.getBeautifulNumbers(99);
  189.  
  190. for (long long num : beautifulNumbers) {
  191. std::string spelling = speller.spellNumber(num);
  192. int letterCount = speller.countLetters(spelling);
  193. std::cout << num << ": '" << spelling << "' (" << letterCount << " letters)" << std::endl;
  194. }
  195.  
  196. // Test with various values of N
  197. std::cout << "\nBeautiful numbers count for different values of N:" << std::endl;
  198. std::vector<long long> testValues = {10, 20, 30, 40, 50, 60, 70, 80, 90, 99, 100, 150, 200};
  199. for (long long n : testValues) {
  200. long long count = counter.countBeautifulNumbers(n);
  201. std::cout << "N = " << n << ": " << count << " beautiful numbers" << std::endl;
  202. }
  203.  
  204. // Final answer for original problem
  205. std::cout << "\nAnswer: There are " << counter.countBeautifulNumbers(99)
  206. << " beautiful numbers between 1 and 99" << std::endl;
  207.  
  208. // Example: Find beautiful numbers between 100 and 200
  209. std::cout << "\nExample: Beautiful numbers between 100 and 200:" << std::endl;
  210. std::vector<long long> beautiful100to200;
  211. for (long long i = 100; i <= 200; ++i) {
  212. if (counter.isBeautiful(i)) {
  213. beautiful100to200.push_back(i);
  214. }
  215. }
  216.  
  217. std::cout << "Found " << beautiful100to200.size() << " beautiful numbers: ";
  218. for (size_t i = 0; i < beautiful100to200.size(); ++i) {
  219. if (i > 0) std::cout << ", ";
  220. std::cout << beautiful100to200[i];
  221. }
  222. std::cout << std::endl;
  223.  
  224. return 0;
  225. }
Success #stdin #stdout 0.01s 5220KB
stdin
Standard input is empty
stdout
Testing known examples:
4: 'four' has 4 letters, 4 % 4 = 0, beautiful: true
6: 'six' has 3 letters, 6 % 3 = 0, beautiful: true
12: 'twelve' has 6 letters, 12 % 6 = 0, beautiful: true
86: 'eightysix' has 9 letters, 86 % 9 = 5, beautiful: false

Testing larger numbers:
100: 'onehundred' has 10 letters, 100 % 10 = 0, beautiful: true
144: 'onehundredfortyfour' has 19 letters, 144 % 19 = 11, beautiful: false
200: 'twohundred' has 10 letters, 200 % 10 = 0, beautiful: true
1000: 'onethousand' has 11 letters, 1000 % 11 = 10, beautiful: false
1200: 'onethousandtwohundred' has 21 letters, 1200 % 21 = 3, beautiful: false

Finding all beautiful numbers from 1 to 99:
4: 'four' (4 letters)
6: 'six' (3 letters)
12: 'twelve' (6 letters)
30: 'thirty' (6 letters)
33: 'thirtythree' (11 letters)
36: 'thirtysix' (9 letters)
40: 'forty' (5 letters)
45: 'fortyfive' (9 letters)
50: 'fifty' (5 letters)
54: 'fiftyfour' (9 letters)
56: 'fiftysix' (8 letters)
60: 'sixty' (5 letters)
70: 'seventy' (7 letters)
81: 'eightyone' (9 letters)
88: 'eightyeight' (11 letters)
90: 'ninety' (6 letters)

Beautiful numbers count for different values of N:
N = 10: 2 beautiful numbers
N = 20: 3 beautiful numbers
N = 30: 4 beautiful numbers
N = 40: 7 beautiful numbers
N = 50: 9 beautiful numbers
N = 60: 12 beautiful numbers
N = 70: 13 beautiful numbers
N = 80: 13 beautiful numbers
N = 90: 16 beautiful numbers
N = 99: 16 beautiful numbers
N = 100: 17 beautiful numbers
N = 150: 19 beautiful numbers
N = 200: 22 beautiful numbers

Answer: There are 16 beautiful numbers between 1 and 99

Example: Beautiful numbers between 100 and 200:
Found 6 beautiful numbers: 100, 112, 150, 162, 170, 200