Armstrong Sayısı bulma

Merhabalar,

Aşağıda kullanıcıdan alınan bir sayının Armstrong sayısı olup olmadığını bulan bir program var.
ama ben bu programı anlayamadım.
Mesela neden geçici sayı oluşturulmuş.

SAtır satır anlatabilirseniz çok memnun olurum. Şimdiden teşekkür ederim…

sayı = input("Sayı:")
basamak_sayisi = len(sayı)
sayı = int(sayı)
basamak = 0
toplam = 0

gecici_sayı = sayı

while (gecici_sayı > 0):
    
    basamak = gecici_sayı % 10
    
    toplam += basamak ** basamak_sayisi
    
    gecici_sayı //= 10
    

if (toplam == sayı):
    print(sayı,"bir armstrong sayısıdır.")
else:
    print(sayı,"bir armstrong sayısı değildir.")

Merhaba, yanılmıyorsam paylaştığınız kodlar bazen yanlış sonuçlar üretiyor. Armstrong sayısının tanımı şöyle değil mi?

Tüm basamaklarındaki rakamların sayı değerlerinin küpleri toplamı,kendisine eşit olan sayılara " Armstrong sayı" denir.

Yukarıdaki kodları çalıştırdığımızda, sayı olarak 2 yazarsak, 2 bir armstrong sayısıdır. gibi bir sonuçla karşılaşıyoruz. Oysa 2 yukarıdaki tanıma göre bir armstrong sayısı değildir. Çünkü 2 ile 2’nin küpü farklı sayılar.

Yukarıdaki işlem yerine bir sayının armstrong sayısı olup olmadığını şöyle bulabilirsiniz:

def armstrong_sayisi_mi(sayi: int):
    return sum(int(i) ** 3 for i in str(sayi)) == sayi
2 Beğeni

Bu şekilde de yazabiliriz sanırım. @dildeolupbiten Armstrong sayı tanımında bir hatanız var. Küpleri değilde basamak sayısı kadar üstü olması gerekiyor.

Bende @dildeolupbiten 'den ilham alarak bu şekilde bir kod oluşturdum.

def armstrong_sayisi_mi(sayi: int):
x = len(str(sayi))
toplam_basamaklar = 0
for i in str(sayi):
    üstler = int(i)**int(x)
    toplam_basamaklar += üstler
if (toplam_basamaklar == sayi):
    print("Doğru")
else:
    print("Yanlış")
2 Beğeni

Hmm. tamam o zaman, kodları aşağıdaki gibi değiştirirsek tanıma uygun bir kod yazmış oluruz.

def armstrong_sayisi_mi(sayi: int): return sum(int(i) ** len(str(sayi)) for i in str(sayi)) == sayi
2 Beğeni

OP’un sorusuna cevap verelim:

  1. gecici_sayı = sayı ifadesinde, gecici_sayı, sayı değişkenine eşitlenir. mesela input() fonksiyonuna 153 yazarsak, gecici_sayı, 153 sayısına eşit olacaktır.
  2. Şöyle bir döngü tanımlanmış: -> while (gecici_sayı > 0):
    gecici_sayı'nın ilk değeri 153 olduğu için bu döngünün koşulu sağlanmış olur ve döngü blokunda yer alan işlemlere geçilir.
  3. basamak = gecici_sayı % 10 şeklinde bir ifade var. Burada basamak adlı sayı gecici_sayı'nın 10'a bölümünden kalan hangi sayıysa ona eşitleniyor. 153 % 10 işleminde kalan 3 olur.
  4. toplam += basamak ** basamak_sayısı ifadesine baktığımızda toplam sayısına basamak üzeri basamak_sayısı eklenir. Burada toplam'ın ilk değeri 0 idi. basamak sayısının değeri 3 ve basamak_sayısı sayısının değeri de 3 olunca, toplam sayısının alacağı ilk değer 3 ** 3 yani 27 olacaktır.
  5. gecici_sayı //= 10 ifadesinde, gecici_sayı 10'a bölünür ve gecici_sayı bölüme eşitlenir. gecici_sayı'nın ilk değeri 153 idi. 15310'a bölersek bölüm 15 olacaktır. O halde gecici_sayı'nın yeni değeri 15.

Şimdi buraya kadar olan işlemler döngünün 1. adımı. while koşulu gecici_sayı, 0'dan büyük olduğu sürece sağlanmış olur ve döngü çalışmaya devam eder. 15 sayısı 0'dan büyük olduğu için döngü yeni gecici_sayı ile çalışmaya devam edecektir.

  1. İkinci döngüde basamak = gecici_sayı % 10 ifadesi bize 5 sayısını verecektir. Çünkü 15 sayısının 10'a bölümünden kalan 5'tir.
  2. toplam += basamak ** basamak_sayisi ifadesinde toplam sayısına 5 ** 3 sayısı eklenir. 5 ** 3 sayısı 125'e eşit olduğu için toplam sayısına 125 daha eklenir. toplam sayısının ilk değeri 27 idi, bu sayıya 125 eklediğimizde 152 sayısını elde ederiz.
  3. gecici_sayı //= 10 ifadesinde, gecici_sayı'nın alacağı değere bakalım. döngünün bir önceki aşamasında gecici_sayı, 15 sayısına eşitlenmişti. O halde 15 sayısını 10 a bölersek, bölüm 1 olacaktır. Yani gecici_sayı'nın yeni değeri bu sefer 1 olur.

1 sayısı halen 0 sayısından büyük olduğu için döngü çalışmaya devam eder.

  1. basamak = gecici_sayı % 10 ifadesinde, basamak sayımızın değeri yine 1 olur.
  2. toplam += basamak ** basamak_sayisi ifadesinde, toplam sayısına 1 ** 3 sayısı eklenir. Daha önceki toplam değişkeni 152 olmuştu, bunun üzerine 1 eklediğimiz zaman 153 sayısını elde ederiz.
  3. gecici_sayı //= 10 ifadesinde, 1'i 10'a bölersek, bölüm 0 olacaktır.

gecici_sayı'nın yeni değeri 0 olduğu için artık while döngüsünün koşulu sağlanmaz ve döngüden çıkılır.

Sonraki kodlarda da toplam sayısının sayı sayısına eşit olup olmadığı sorgulanır. toplam değişkeni en son 153 olmuştu, sayımız da 153 idi. O halde, 153, bir armstrong sayısıdır.

1 Beğeni

True if x else False mu? çık çık çık :grin:

Şöyle olmalıydı değil mi? :slight_smile:

def armstrong_sayisi_mi(sayi: int): return sum(int(i) ** len(str(sayi)) for i in str(sayi)) == sayi

Çünkü şöyle bir anlama geliyor: return True if True else False

Aynen :slight_smile:

Pedantik olmak gerekirse bool(x), ama burada (ve cogu yerde) zaten boolean olacagi/otomatik cevrilecegi icin sadece x.

1 Beğeni

“Bunu niye böyle yazmışım ki” diyebileceğimiz hatalar yapıyoruz bazen. :grin: