Akademisyenler öncülüğünde matematik/fizik/bilgisayar bilimleri soru cevap platformu
2 beğenilme 0 beğenilmeme
1.9k kez görüntülendi
$10$ dan küçük $3$ veya $5$ in pozitif katları olan sayıları listelersek, $3,5,6$ ve $9$ sayılarını elde ederiz. Bu katların toplamı $23$ tür.

$\underline{Soru:}$ $1000$ den küçük $3$ veya $5$ in tüm pozitif katlarının toplamını bulunuz.

("A veya B programlama dili üzerinden nasıl yazarız?" sorusu değildir. Matematiksel olarak mantığını, algoritmasını adım adım nasıl kurabiliriz? Daha sonra isteğe göre programlama dilleri üzerinde yazımlarını da paylaşabiliriz.)
Veri Bilimi kategorisinde (470 puan) tarafından 
tarafından düzenlendi | 1.9k kez görüntülendi

Mathematica ile:

 

If[Mod[#, 3] == 0 || Mod[#, 5] == 0, #, Nothing] & /@ Range@999 // Total
233168

 

4 Cevaplar

4 beğenilme 0 beğenilmeme
En İyi Cevap

İçeri-dışarı (inclusion-exclusion) yöntemiyle:

  • $1000$'den küçük $3$'ün katlarının toplamını hesaplamak kolay. $1$'den $333$'e kadar sayıları $3$'le çarpıp toplayabiliriz. $$\sum_{i=1}^{333} 3k$$
  • $1000$'den küçük $5$'in katlarının toplamını hesaplamak da kolay. $1$'den $199$'a kadar sayıları $5$'le çarpıp toplayabiliriz. $$\sum_{i=1}^{199} 5k$$

  • Yukarıda bulduklarımızı toplarsak hem $3$'e hem $5$'e bölünen sayıları iki kere saymış oluruz. O zaman toplamdan bunları çıkartmamız gerekir. Hem $3$'e hem $5$'e bölünmek, $15$'e bölünmek demektir. Yani şu toplamı arıyoruz: $$\sum_{i=1}^{66} 15k$$ 

Sonuç olarak aradığımız sayı $$\sum_{i=1}^{333} 3k + \sum_{i=1}^{199} 5k - \sum_{i=1}^{66} 15k$$

(1.8k puan) tarafından 
tarafından seçilmiş
3 beğenilme 0 beğenilmeme

İçeri-dışarı yöntemini bir python döngüsü ile uygulayabiliriz.

toplam = 0

for i in range(1,1000):
    # 3'e bölünenleri toplama ekle
    if i % 3 == 0:
        toplam += i
    # 5'e bölünenleri toplama ekle 
    if i % 5 == 0:
        toplam += i
    # 15'e bölünenleri toplamdan çıkart
    if i % 15 == 0:
        toplam -= i

 

(1.8k puan) tarafından 

Bu kodda 1000 kere dongu yapmaniz gerekiyor. Her dongude 3 kere dogruluk test ediyorsunuz ve 3 kere kalan bakiyorsunuz. Yukarida yazdiginiz toplama islemi gibi yaparsaniz daha az dongu ve islemle isin icinden cikabiliriz.

sum(3*i for i in range(1,334)) + sum(5*i for i in range(1,200)) - sum(15*i for i in range(1,67))

bu kodda 334+200+67 kere dongu yapmamiz gerekiyor ve kalan islemini carpma islemiyle degistirdik ve dogruluk test etmemize gerek yok.

2 beğenilme 0 beğenilmeme

Soruda istemiyor ama ben de ek olarak, sadece $1000$ için değil, vereceğimiz her sayı için nasıl hesaplardık onu yazayım.

a=int(input("Bir değer giriniz:"))

#Genel bir hesaplayıcı tanımla
def hesapla(b):
    # Verilen sayıya kadar 3'e ya da 5'e bölünenleri topla.
	toplam = sum(i for i in range(b) if (i % 3 == 0 or i % 5 == 0))

    #Elde ettiğin sonucu değer olarak ata.
	return toplam

#Bulunan değeri ekrana çıktı olarak ver.
print(hesapla(a))

Bana ilginç gelen seylerden biri $n \geq 3$ için $10^n$ lerde aşağıdaki gibi sonuçlar geliyor.
$10^3$ için $233168$
$10^4$ için $23331668$
$10^5$ için $2333316668$
$10^6$ için $233333166668$
$10^7$ için $23333331666668$
şeklinde örüntülü devam ediyor. Hesaplama yaptırmasak bile çok daha büyük sayılarda gelen sonucu tahmin etmek zor değil gibi.

(470 puan) tarafından 
uce ve bese bolunenleri iki kere sayiyorsunuz kodunuzda

//yanilmisim, kodunuz dogru
Hayır iki kere saymıyor. "i % 3 == 0 or i % 5 == 0" bu kısım karar veriyor ne yapacağını. Hem 3'e hem de 5'e aynı anda bölünenlerde kodda arada veya olduğu için ve sıralı kıyasladığı için 3'e bölündüğünü gördüğü anda veya yı atlayıp hesaplamasını yapıp diğer bir i değerine geçiyor.
evet haklisiniz kafam karisti kusura bakmayin
2 beğenilme 0 beğenilmeme

Ben de simdiye kadar onerilen kodlarin zamanini olctum.

def cevap_1():
    toplam = 0
    for i in range(1,1000):
        if i % 3 == 0:
            toplam += i
        if i % 5 == 0:
            toplam += i
        if i % 15 == 0:
            toplam -= i
    return toplam
def cevap_2():
    toplam=sum(3*i for i in range(1,334)) + sum(5*i for i in range(1,200)) - sum(15*i for i in range(1,67))
    return toplam

def cevap_3():
    toplam = sum(i for i in range(1000) if (i % 3 == 0 or i % 5 == 0))
    return toplam


if __name__ == '__main__':
    import timeit
    print("Cevap 1 : ", cevap_1() , "Zaman : ",timeit.timeit("cevap_1()", setup="from __main__ import cevap_1",number=10000) )
    print("Cevap 2 : ", cevap_2() , "Zaman : ",timeit.timeit("cevap_2()", setup="from __main__ import cevap_2",number=10000) )
    print("Cevap 3 : ", cevap_3() , "Zaman : ",timeit.timeit("cevap_3()", setup="from __main__ import cevap_3",number=10000) )
    
    
###################################################
#  Cevap 1 :  233168 Zaman :  2.4881908050738275  #
#  Cevap 2 :  233168 Zaman :  0.5679739599581808  #
#  Cevap 3 :  233168 Zaman :  1.5673820079537109  #
###################################################

 

(1.6k puan) tarafından 
20,279 soru
21,810 cevap
73,492 yorum
2,475,950 kullanıcı