




C - Üç Basamaklı İki Sayının Çarpımından Palindrom Olarak Çıkan En Büyük Sayı
-
Merhaba arkadaşlar. İnternette Project Euler denilen sitedeki problemleri çözmeye başladım. C'de yeni olduğum için de bu dilde yazıyorum pratik olması açısından. Bir çözüm geliştirdim fakat bana daha iyi bir algoritma çıkabilir gibi geldi. Soru tam olarak şu şekilde;
A palindromic number reads the same both ways. The largest palindrome made from the product of two 2-digit numbers is 9009 = 91
99.
Find the largest palindrome made from the product of two 3-digit numbers.
Palindrom sayı iki yönden de okunuşu aynı olan sayıdır. İki basamaklı iki sayının çarpımının palindrom olduğu en büyük sonuç 9009 dur. 91 x 99 = 9009. Üç basamaklı iki sayının çarpımından çıkan en büyük palindrom sayıyı bulun demiş.
Bu da benim çözümüm:
----------------------------------------------
#include <stdio.h>
#include <string.h>
#define YES 1
#define NO 0
/*
Bu fonksiyonla argümanın palindrome olup olmadığına bakılıyor.
*/
int ispalindrome(char x[6]){
int a,i;
a=strlen(x);
for (i=0;i<a;i++){
if (x[i]!=x[a-i-1])
return NO;
}
return YES;
}
int main(){
int h,g,maxi=0;
char b[6];
for (h=999;h>99;h--)
{
for(g=999;g>99;g--) //Bütün olasılıkları hesaplatıyorum.
{
sprintf(b, "%d", g*h);
if (ispalindrome(b)){
if((h*g)>maxi) //Her seferinde maxi'nin o anki değerinden büyükse maxi nin değerini değiştiriyor.
maxi=h*g;
}
}
}
printf("%d", maxi); //Maximum palindrome sayıyı ekrana bastırıyorum.
return 0;
}
-
h * g değeri her seferinde tekrar ettiği için o kısım en iyileştirilebilir (optimizasyon). Ayrıca olası en büyük çarpım sonucundan en küçüğe doğru elde ettiğimizden, bulduğumuz ilk palindrom sayı, en büyük palindrom sayı olacaktır. Aşağıda mümkün mertebe en iyilenmiş kod parçasını yolluyorum. En iyilenmiş kod karışıktır, okunması zordur. Kabul ediyorum:) Ön arttırma ve eksiltme işleçlerine de dikkat etmemiz gerekli. Aradaki fark bazen oldukça büyüktür.
#include <stdio.h> #include <string.h> #define TRUE 1 #define FALSE 0 #define BASAMAKSAYISI 10 // daha genişletilebilir çözüm int PalindromMu( char * sayi ) // bu sefer işaretçi kullanalım { int uzunluk = 0; int i = 0; uzunluk = strlen(sayi); for (i = 0; i < uzunluk; ++i) { if ( *(sayi + i) != *(sayi + uzunluk - i - 1) ) { return FALSE; } } return TRUE; } int main() { int dmaks = 999; // döngü başlangıç int dmin = dmaks / 10; // çözümü daha fazla genişletelim int i = 0; // döngülerde int j = 0; // kullanacağımız sayaçlar unsigned long aradeger = 0uL; // ara çarpım char tamponsayi[BASAMAKSAYISI] = {}; // tampon belleğimiz i = dmaks; j = dmaks; while ( i > dmin ) { while ( j > dmin ) { aradeger = i * j; sprintf(tamponsayi, "%Lu", aradeger); if (PalindromMu(&tamponsayi[0]) == TRUE) // zaten en büyüğünü arıyoruz { // en büyüğünü bulduğunda çıkmak lazım printf("%d'den kucuk sayilarda en buyuk palindrom sayi: " "%d * %d = %Lu\n", dmaks, i, j, aradeger); i = -1; // iki döngüden de çıkmak için basit bir hile break; // içteki döngüyü kır } --j; } j = dmaks; --i; } return 0; }
YeniHarman tarafından 21/Şub/13 03:05 tarihinde düzenlenmiştir -
Hocam malesef senin program 580085 veriyor. doğru cevap 993*913=906609. Aynı algoritmayı ben de düşünmüş ve uygulamıştım. İlk bulduğu palindromu ekrana bastırdım. Fakat üstteki forun değişkeni azalmadan bulduğundan daha küçük bir cevap çıkıyor senin programda da çıkan 580085 i veriyor. O yüzden bütün olasılıkları hesaplattırdım. Ayrıca dediğin gibi optimizasyon için h*g yi bir değişkene atamalıymışım :)
ZoRKaYa tarafından 21/Şub/13 10:25 tarihinde düzenlenmiştir -
Evet, öyleymiş:) 99'dan başlatarak denediğim için o doğru cevabı bulduğumda genelleme yaptım:)