התוכנית בשפת C++
:
#include <iostream>
#include <string>
using namespace std;
bool isLucky(int n) {
bool arr[10];
for (int i = 0; i < 10; i++) {
arr[i] = false;
}
while (n > 0) {
int digit = n % 10;
if (arr[digit]) {
return false;
}
arr[digit] = true;
n = n/10;
}
return true;
}
bool isDivisible(long long number) {
if (number == 11) {
return true;
}
if (number < 11) {
return false;
}
if (!(isLucky(number))) {
return false;
}
std::string num_str = std::to_string(number);
int odd_digits_sum = 0, even_digit_sum = 0;
for (int i = 0; i < num_str.size(); i++) {
if (i % 2 == 0) {
odd_digits_sum += (num_str[i]-'0');
} else {
even_digit_sum += (num_str[i]-'0');
}
}
return isDivisible(odd_digits_sum - even_digit_sum);
}
int main() {
for (long long current_num = 999999999; current_num >= 100000000; --current_num) {
bool result = isDivisible(current_num);
if (result) {
std::cout << "Biggest number: " << current_num << std::endl;
break;
}
}
return 0;
}
הגדרתי שתי פונקציות עזר:
- הפונקציה
isLucky
בודקת אם המספר הוא מספר מזל. מספר מזל הוא מספר שאין בו ספרות זהות. כלומר למשל 123 הוא מספר מזל אבל 122 הוא לא מספר מזל. לשם כך, הגדרנו מערך בגודל עשר (שכן יש רק עשר ספרות) ונמלא אותו ב-false
. נעבור על המספר ועבור כל ספרה נבדוק אם כבר ראינו אותה. אם כן, אז נחזירfalse
כי זה לא מספר מזל. אחרת, נשיםtrue
במקום המתאים במערך ונמשיך לספרה הבאה. - הפונקציה
isDivisible
בודקת אם המספר הוא מספר מזל שמתחלק ב-11. הפונקציה עובדת בשיטתBacktracking
בצורה כזו שכל פעם אנחנו נעביר את ההפרש בין סכום הספרות במקומות האי-זוגיים, וסכום הספרות במקומות הזוגיים שלו, ברקורסיה. תנאי העצירה הוא שאם הגענו ל-11 אז זה אומר שהמספר מתחלק ב-11 ואם המספר קטן מ-11 אז הוא לא מתחלק ב-11.
ב-main
אנחנו יוצרים לולאה שעוברת מהמספר הגדול ביותר בעל תשע ספרות עד המספר הקטן ביותר בעל תשע ספרות. בכל איטרציה נבדוק אם הוא מספר מזל שמתחלק ב-11 ואם כן אז נדפיס אותו וניצא מהלולאה.
הערה: אפשר לבצע פה אופטיזציה קטנה על-ידי התחלה מהמספר 987654321 כמו שהצעת.
תוצאה: מספר המזל הגדול ביותר בעל תשע ספרות שמתחלק ב-11 הוא 987652413.