N'nin bölenlerinin toplamını bulun


20

Ekranda, kullanıcı tarafından 1 ila N aralığında girilen bir sayının (1 ≤ N ≤ 100) bölücülerinin toplamını görüntüleyen bir program yazın.

Bu OEIS A000203 .


Örnekler:

Giriş : 7

7 / 1 = 7
7 / 7 = 1

7 + 1 = 8

Çıktı: 8


Giriş: 15

15 / 1 = 15
15 / 3 = 5
15 / 5 = 3
15 / 15 = 1

15 + 5 + 3 + 1 = 24

Çıktı: 24


Giriş: 20

20 / 1 = 20
20 / 2 = 10
20 / 4 = 5
20 / 5 = 4
20 / 10 = 2
20 / 20 = 1

20 + 10 + 5 + 4 + 2 + 1 = 42

Çıktı: 42


Giriş: 1

1 / 1 = 1

Çıktı: 1


Giriş: 5

5 / 1 = 5
5 / 5 = 1

5 + 1 = 6

Çıktı: 6


6
@ H.PWiz Bence o "N sayısının bölenleri" anlamına gelir
benzen

Bence bölücülerin toplamı, yani sigma fonksiyonu mu demek istiyorsun ?
Stephen

Üzgünüm, "N katının toplamı" demek istiyorum.
Kevin Halley

@ H.PWiz bu toplamı, bu yüzden bilmiyorum
Stephen

@Stephen Bu benim için önemsiz bir değişiklik gibi görünüyor
H.PWiz

Yanıtlar:



6

x86-64 Makine Kodu, 23 bayt

89 F9 89 FE EB 0D 89 F8 99 F7 F1 85 D2 99 0F 44 D1 01 D6 E2 F1 96 C3

Yukarıdaki kod baytları, tek bir tamsayıyı (N) kabul eden ve sonuç olarak katlarının toplamını döndüren bir işlevi tanımlar.

Tek parametre, EDISystem V AMD64 ABI (* nix tarzı sistemlerde kullanıldığı gibi) ile tutarlı olarak kayıtta geçirilir . Sonuç, EAXtüm x86 çağrı kurallarında olduğu gibi kayıt defterinde döndürülür .

Algoritma, diğer dillerdeki diğer gönderilerin çoğuna benzer şekilde çok basittir. Her seferinde modulo'yu hesaplayıp bunu çalışan toplamımıza ekleyerek N kez döngü yapıyoruz.

Ungolfed montaj anımsatıcıları:

; unsigned SumOfMultiples(unsigned N  /* (EDI) */)
    mov     ecx, edi      ; make copy of input N, to be used as our loop counter
    mov     esi, edi      ; make copy of input N, to be used as our accumulator
    jmp     CheckEnd      ; jump directly to 'CheckEnd'
AddModulo:
    mov     eax, edi      ; make copy of input N, to be used as input to DIV instruction
    cdq                   ; short way of setting EDX to 0, based on EAX
    div     ecx           ; divide EDX:EAX by ECX, placing remainder in EDX
    test    edx, edx      ; test remainder, and set ZF if it is zero
    cdq                   ; again, set EDX to 0, without clobbering flags
    cmovz   edx, ecx      ; set EDX to ECX only if remainder was zero (EDX = ZF ? 0 : ECX)
    add     esi, edx      ; add EDX to accumulator
CheckEnd:
    loop    AddModulo     ; decrement loop counter (ECX), and keep looping if it != 0
    xchg    eax, esi      ; move result from accumulator (ESI) into EAX
    ret                   ; return, with result in EAX

Çevrimiçi deneyin!

Bunu kısaltmanın bir yolu olmalı gibi görünüyor, ama göremiyorum. X86 üzerinde modulo hesaplamak biraz kod alır, çünkü bunu DIV(veya IDIV) komutunu kullanarak yaparsınız ve her ikisi de değerleri clobbered olan sabit giriş kayıtlarını ( EDXve EAX) kullanır (çünkü sonuçları alırlar, geri kalanı ve sırasıyla).

Burada sadece gerçek hileler oldukça standart golf olanları:

  • Ben LOOPtemelde DEC+ sadece örtülü işlenen olarak kayıt JNZile bir kombinasyonu olan CISC tarzı talimatı kullanabilirsiniz böylece kodu biraz alışılmadık bir şekilde yapılandırdım ECX.
  • Ben kullanıyorum XCHGyerine sonunda MOVzaman eski özel 1 bayt kodlama, çünkü EAXişlenen biridir.
  • İmzasız bölünme için normalde sadece a kullanarak sıfırlamanıza rağmen, bölünme hazırlığında CDQsıfıra giderim . Ancak, her zaman 2 bayt, yalnızca 1 bayttır. Kullandığım sıfıra tekrar döngünün ikinci kez içini önce, talimat. Bu çalışır, çünkü bölümün (in ) bölümünün her zaman imzasız olduğu garanti edilebilir , bu nedenle içine bir oturum uzantısı 0'a eşit olacaktır .EDXXORXORCDQCDQEDXCMOVZEAXEDXEDX




3

Mathematica, 14 bayt

Tr@Divisors@#&   

veya @Loki tarafından yanıt

Mathematica, 17 bayt

DivisorSum[#,#&]&

@Jennymathy Çok hoş, teşekkürler! Yazmanın eşdeğer ve eğlenceli bir yolu da: DivisorSum [#, # &] &
Rebel-Scum

@Jennymathy Hmm, bu daha da iyi: Total @ Divisors @ sadece 15 karakter uzunluğunda! Ve işe yarıyor: örneğin Total @ Divisors @ 15 beklendiği gibi 24 veriyor. Mathematica FTW :)
Rebel-Scum

2
@Loki ve Tr@Divisors@#&daha da iyi ;-)
J42161217

1
@Loki program f=f [x] girişini alan bir işlev olmalıdır , bu yüzden onu bu şekilde sunuyorum. PPCG'ye hoş geldiniz
J42161217

3
Tr@*DivisorsBir baytı tıraş etmek için kullanabilirsiniz .
wchargin

3

C, C ++, C #, D, Java, 65 62 bayt

int d(int n){int s=0,i=1;for(;i<=n;++i)s+=n%i>0?0:i;return s;}

Bu benzerlikler nedeniyle tüm tez 5 programlama dillerinde çalışır.

C, C ++ ve D optimizasyonu: 62 60 bayt

C ++ ve D'de tamsayılar dolaylı olarak booleans'e dönüştürür (Sıfır => false, Sıfır Değil => true), bu nedenle !=0

int d(int n){int s=0,i=1;for(;i<=n;++i)s+=n%i?0:i;return s;}

D optimizasyonu: golfy şablon sistemi, 55 bayt

T d(T)(T n){T s,i=1;for(;i<=n;++i)s+=n%i?0:i;return s;}

Test edilecek kod :

C:

printf("%d %d %d %d %d", d(7), d(15), d(20), d(1), d(5));

C ++:

std::cout << d(7) << ' ' << d(15) << ' ' << d(20) << ' ' << d(1) << ' ' << d(5);

C #:

class FindSum
{
    int d(int n) { int s = 0, i = 1; for (; i <= n; ++i) s += n % i > 0 ? 0 : i; return s; }

    static void Main(string[] args)
    {
        var f = new FindSum();
        Console.WriteLine(string.Format("{0}, {1}, {2}, {3}, {4}", f.d(7), f.d(15), f.d(20), f.d(1), f.d(5)));
    }
}

D:

writeln(d(7));
writeln(d(15));
writeln(d(20));
writeln(d(1));
writeln(d(5));

Java:

public class FindSum {
    int d(int n){int s=0,i=1;for(;i<=n;++i)s+=n%i>0?0:i;return s;}

    public static void main(String[] args) {
        FindSum f = new FindSum();
        System.out.println(String.format("%d, %d, %d, %d, %d", f.d(7), f.d(15), f.d(20), f.d(1), f.d(5)));
    }
}

Birkaç şey: İlk olarak, herhangi bir dilde n%i/ çevresinde parantezlere ihtiyacınız olduğunu düşünmüyorum n%i!=0. İkinci olarak, ilk çözümünüz n%i>0yerine sahip olmalıdır n%i!=0. Üçüncü olarak, D'nin çözümü T d(T)(T n){T s,i=1;for(;i<=n;++i)s+=n%i?0:i;return s;}şablon sistemini ve varsayılan değerleri kötüye kullanmak olabilir .
Zacharý

3

Shnap , 44 43 bayt

Bay Xcoder sayesinde -1 güle güle (lol kendi dilimde geride kaldım)

 $n return:{s=0for d:range(n+1)if n%d<1s+=d}

Bu bir işlevdir ( $Shnap'ta bir işlevi başlatır).

Çevrimiçi deneyin!

Açıklama:

$ n                        //Start function with parameter n
    return: {              //Technically, we are returning a scope-block, which evaluates to the last statement run
        s = 0              //Our result
        for d : range(n+1) //For each value in the iterator range(n+1)
            if n % d < 1  // If n is divisible by d
                s += d     // Add d to the sum
                           // Since (s += d) returns (s + d), and a scope-block returns the last run statement, this will be the last statement and equal to our result
    }

Rekabet etmeyen, 19 bayt

Birçok dil güncellemesinden sonra, bu artık 19 bayta indirgenebilir:

$n=>sum(factors(n))

Çevrimiçi deneyin!


1
==0olduğu <1( 43 byte )
Sayın Xcoder

@Bay. Xcoder teşekkürler ... Ben aşıldı ... Kendi dilimde ... Bu bile ezoterik değil xD
Socratic Phoenix

2

Python, 44 bayt

lambda k:sum(i*(k%i<1)for i in range(1,1+k))
  • Stephen sayesinde boşlukları kaldırarak 1 bayt tasarruf edin.
  • Jonathan Frech sayesinde, çarpma durumunda değiştirerek 1 bayt daha kaydedin.

2

J, 23 bayt

[:+/](([:=&0]|[)#])1+i.

Çevrimiçi deneyin!

J hayranları için akıllı 13 baytlık bir çözüm var :>:@#.~/.~&.q: ama benim buluşum olmadığından resmi cevabım olarak göndermiyorum.

Kendi çözümüm, bölenleri bulmak için 1..n'yi filtreler, sonra toplar. Bunun en önemli özelliği ikili çatal

](([:=&0]|[)#])

Bu bağlamda ]1..n ve [n'nin kendisi olduğuna dikkat edin. Bu nedenle ]|[, 1..n öğelerinin her birini n'ye böldüğünüzde kalanlar ve 0'a =&0eşit olup olmadıklarını söyler.


2
Bu 13 bayt için eşdeğer olmalıdır:+1#.i.*0=i.|]
mil

Miles, bu gerçekten çok hoş. Bu kısım i.|]benim yaklaşımımda büyük bir gelişme. Yine de bu kısmı tam olarak anlamıyorum: +1#.i.- açıklayabilir misiniz?
Jonah

2
1#.eşittir temel 1 dönüşüm +/"1. Önce i.|]geri kalanları elde etmek, sonra 0=0'a (bölenlere) eşit olanları bulmak, daha sonra i.*aralıktaki bölen olmayanları sıfırlamak, daha sonra kullanarak toplamak 1#., sonra özel bir aralık olduğu için +kendini ekleyin i..
mil




2

Javascript, 54 44 bayt

n=>[...Array(x=n)].reduce(y=>y+!(n%x)*x--,0)

Shaggy sayesinde 10 bayt kaydedildi

Çevrimiçi deneyin!

const f = n=>[...Array(x=n)].reduce(y=>y+!(n%x)*x--,0)

console.log(f(7))
console.log(f(15))
console.log(f(20))
console.log(f(1))
console.log(f(5))


2

Brain-Flak , 96 bayt

((({})<>){<(([()]{})){<>(({})(<()>))<>{(({})){({}[()])<>}{}}{}<>([{}()]({})){((<{}{}>))}}{}>{}})

Çevrimiçi deneyin!

Açıklama:

Şimdi iyileştirmelerle modası geçmiş.

Algoritmanın kalbi şudur:

({}(<>))<>{(({})){({}[()])<>}{}}{}<>([{}()]({})) turns |N, M...| into |N mod M, M...|
{((<{}{}>))} if the top of stack is not zero, replace it and the second with zero

Bu bizi verecek mod hakkında bir değişikliktir Mbu bir faktör ise Nve 0aksi. Tam kod aşağıdadır.

((({})<>) place input, N on both stacks
{ Loop to find factors
 <
  (([()]{})) Decrement and Duplicate; get next factor to check
  { if not zero
   (<>({})<>) Copy N from other stack
   ({}(<>))<>{(({})){({}[()])<>}{}}{}<>([{}()]({})){((<{}{}>))} Code explained above
  }
  {} drop the zero
 >
 {} add the factor
}) push the sum

Bir açıklamanız var mı?
Buğday Büyücüsü

@FunkyComputerMan Şimdi bir tane aldım!
MegaTom

2

R , 31 26 bayt

function(N)(x=1:N)%*%!N%%x

Çevrimiçi deneyin!

Döndürür 1x1 matris .

Hesaplar !N%%xelemanlarını eşler darasında1:N ölçütü:d->(1 if d divides N, 0 otherwise)

O zaman nerede olduğu toplamıyla sonuçlanan x%*%x!N%%xmatris ürünüdür . Temiz! Teknik olarak Luis Mendo'nun Octave cevabının bir limanı ama bunu sadece düşündükten sonra gördüm.1:Nx!N%%x1

R + sayıları, 14 bayt

numbers::Sigma

Çevrimiçi deneyin!


Birincisi için 2 bayt kaydedebilirsinizN=scan();
gstats

@gstats evet, ancak meta tartışma başına +4 bayt almalıyım . Eğer güçlü bir fikriniz varsa, Jarko'nun cevabına ağırlık verebilirsiniz, ancak kimsenin bir alternatif önermediği gibi, aklımda duruyor.
Giuseppe

İkincisi olmamalı numbers::Sigma(N)mı? Bunun gibi, fonksiyonun kaynak kodunu çıkarır Sigma.
Rui Barradas - Monic'i Yeniden Başlat

@RuiBarradas bir fonksiyon mükemmel derecede iyi bir sunumdur. test etmek için, ilk başvuruda yaptığım gibi aramalısınız.
Giuseppe

1

JavaScript, 31 bayt

f=(n,i=n)=>i&&!(n%i)*i+f(n,i-1)



1

VBA (Excel), 73 bayt

a=Cells(1,1)
x=1
While x<=a
If a Mod x = 0 Then b=b+x
x=x+1
Wend
MsgBox b

Bu yanıt, stand olarak tek bir birim olarak çalıştırılamayan bir snippet koleksiyonu olduğu için geçersizdir. Bunu geçerli kılmak için, bunu bir alt rutine veya anonim bir VBE anlık pencere işlevine dönüştürmeniz gerekir.
Taylor Scott

Söylediklerine çok aşina değilim. Bana biraz daha yardım edebilir misin?
4'te remoel

Bu gönderiyi geçerli kılmak için, aşağıdaki biçimlerden birine dönüştürmeniz gerekir: 1 - Alt program, 2 - İşlev, 3 - Anonim VBE anlık pencere işlevi (Anında pencerede yürütülebilir tek bir satır); Senin uygulanması için, bu en basit uygulama ile sarma tarafından altprograma dönüştürmek olacaktır Sub Y... End Sub85 Byte çözüm elde etmekSub y A=Cells(1,1) x=1 While x<=A If A Mod x=0 Then b=b+x x=x+1 Wend MsgBox b End Sub
Taylor Scott

Bununla birlikte, Sub y While x<=[A1] x=x+1 If [A1]Mod x=0Then b=b+x Wend Debug.?b End Subtemiz bir modülde (x = varsayılan int değeri 0) çalıştırıldığını ve VBE anlık penceresine ( ?otomatik biçimlendirilen Print ) çıktı aldığını varsayarak 72 baytlık çözüme kadar oldukça optimize edilebilir
Taylor Scott

Bunun ötesinde ve çözümünüzün altyordam çağrısı yoluyla girdi almadığının farkına varıldığında , bu, varsayılan değer olan 0 olduğunu ve VBE anlık penceresine (şu değerden) While x<=[A1]:x=x+1:b=IIf([A1]Mod x,b,b+x):Wend:?bçıktığını kabul eden 50 Bayt için bir VBE anlık pencere işlevine dönüştürülebilir. VBE anlık penceresi ile eşdeğerdir )xb?Debug.Print
Taylor Scott

1

Pyth , 6 bayt

s*M{yP

Burada deneyin!

Pyth'in bölücüler için yerleşik bir özelliği yoktur, bu yüzden bunun makul olduğunu düşünüyorum.

açıklama

s * M {yP - Örtük girdili tam program.

     P - Girdinin ana faktörleri.
    y - Asal faktörlerinin güç kümesi.
   {- Veri tekilleştirme.
 * M - Çarpma ile harita.
s - Toplam.
          - Sonuçları dolaylı olarak görüntüler.

Verilen 20Örneğin, bu program her talimat sonrasında yaptığı iştir:

  • P: [2, 2, 5].

  • y: [[], [2], [2], [5], [2, 2], [2, 5], [2, 5], [2, 2, 5]].

  • {: [[], [2], [5], [2, 2], [2, 5], [2, 2, 5]].

  • *M: [1, 2, 5, 4, 10, 20].

  • s: 42.



1

Kabuk , 5 bayt

ṁΠuṖp

Çevrimiçi deneyin!

Nasıl?

ṁΠuṖp - Tam program, örtük girdi.

     p - Asal faktörler.
    Ṗ - Powerset.
   u - Kopyaları kaldırın.
list - Her listenin, toplamı ve dolaylı olarak çıktısını alın.

Sohbet önerileri için Zgarb'a teşekkürler!





0

Bash + GNU yardımcı programları, 36

bc<<<`seq -f"n=%g;a+=n*!$1%%n;" $1`a

Çevrimiçi deneyin .


Saf Bash, 41

for((;++i<=$1;a+=$1%i?0:i))
{
:
}
echo $a

Çevrimiçi deneyin .

İlk olarak süslü bir bash genişleme cevabını denedim, ancak yukarıdaki basit döngüden daha uzun oldu:

echo $[$(eval echo +\\\(n={1..$1},$1%n?0:n\\\))]


0

QBIC , 17 bayt

[:|~b%a|\p=p+a}?p

açıklama

[:|      FOR a = 1; a <= b (read from cmd line); a++
~b%a|    IF b modulo a has a remainder THEN - empty block - 
\p=p+a   ELSE add divisor 'a' to running total 'p'
}        END IF, NEXT
?p       PRINT p

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.