N의 제수의 합을 구합니다


20

사용자가 1에서 N까지 입력 한 숫자의 제수 (1 ≤ N ≤ 100)의 합계를 화면에 표시하는 프로그램을 작성하십시오.

이다 OEIS A000203 .


예 :

입력 : 7

7 / 1 = 7
7 / 7 = 1

7 + 1 = 8

출력 : 8


입력 : 15

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

15 + 5 + 3 + 1 = 24

출력 : 24


입력 : 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

출력 : 42


입력 : 1

1 / 1 = 1

출력 : 1


입력 : 5

5 / 1 = 5
5 / 5 = 1

5 + 1 = 6

출력 : 6


6
@ H.PWiz 나는 그가 "숫자 N의 제수"를 의미한다고 생각합니다
벤젠

나는 당신이 제수, 일명 시그마 함수의 합을 의미한다고 생각 합니까?
Stephen

죄송합니다, "N의 배수의 합"을 의미합니다.
Kevin Halley

@ H.PWiz 이것은 이것의 합이므로, 나는 몰라
Stephen

@Stephen 그것은 나에게 사소한 변화처럼 보인다
H.PWiz

답변:



6

x86-64 기계 코드, 23 바이트

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

위의 바이트 코드는 단일 정수 N을 허용하고 그 배수의 합을 결과로 반환하는 함수를 정의합니다.

단일 파라미터는 EDISystem V AMD64 ABI (* nix 스타일 시스템에서 사용)와 일치 하는 레지스터 로 전달됩니다 . EAX모든 x86 호출 규칙과 마찬가지로 결과가 레지스터에 반환됩니다 .

이 알고리즘은 다른 언어로 된 다른 많은 제출물과 유사한 매우 간단한 알고리즘입니다. 우리는 모듈로를 계산하고이를 누계에 추가 할 때마다 N 번 반복합니다.

ungolfed 어셈블리 니모닉 :

; 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

온라인으로 사용해보십시오!

이것을 더 짧게 만드는 방법이 있어야하는 것처럼 보이지만 그것을 볼 수는 없습니다. x86에서 모듈로 컴퓨팅은 DIV(또는 IDIV) 명령어를 사용하여 수행하기 때문에 상당히 많은 코드가 필요합니다. 둘 다 고정 입력 레지스터 ( EDXEAX)를 사용합니다. 몫).

여기에서 유일한 트릭은 꽤 표준적인 골프 트릭입니다.

  • CISC 스타일 LOOP명령을 사용할 수 있도록 코드를 다소 특이한 방식으로 구성했습니다. 기본적으로 DEC+ JNZECX레지스터를 암시 적 피연산자로 조합 한 것입니다 .
  • 전자는 피연산자 중 하나 일 때 전자가 특별한 1 바이트 인코딩을 가지고 있기 때문에 XCHG대신에 사용 하고 있습니다.MOVEAX
  • 내가 사용 CDQ제로화 EDX부호 분할을 위해 당신은 단지 그것이를 사용하여 제로 통상 것에도 불구하고, 분할에 대비하여 XOR. 그러나 XOR항상 2 바이트이며 CDQ1 바이트입니다. I 사용 CDQ제로 다시 루프의 제 2 시간 내부 EDX전과, CMOVZ명령어. 나누기 (in EAX) 의 몫 이 항상 부호가 없음을 보증 할 수 있기 때문에 부호 확장 EDXEDX0과 같습니다.




3

수학, 14 바이트

Tr@Divisors@#&   

또는 @Loki의 답변

수학, 17 바이트

DivisorSum[#,#&]&

@Jennymathy 감사합니다! DivisorSum [#, # &] &
Rebel-Scum

@Jennymathy 흠, 이것이 더 좋습니다 : Total @ Divisors @의 길이는 15 자입니다! 그리고 그것은 작동합니다 : 예를 들어 Total @ Divisors @ 15는 예상대로 24를 제공합니다. Mathematica FTW :)
Rebel-Scum

2
@Loki 그리고 Tr@Divisors@#&더 나은 ;-)
J42161217

1
@Loki 프로그램은 f=입력 f [x]를 받는 함수 여야합니다. 이것이 내가 이런 식으로 그것을 제시하는 이유입니다. PPCG에 오신 것을 환영합니다
J42161217

3
Tr@*Divisors바이트를 면도 하는 데 사용할 수 있습니다 .
wchargin

3

C, C ++, C #, D, Java, 65 62 바이트

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

이것은 유사성 때문에 5 가지 프로그래밍 언어 모두에서 작동합니다.

C, C ++ 및 D 최적화 : 62 60 바이트

C ++ 및 D에서 정수는 암시 적으로 부울로 변환 (Zero => false, Not Zero => true)하므로 !=0

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

D 최적화 : 골프 템플릿 시스템, 55 바이트

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

테스트 코드 :

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));

자바 :

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)));
    }
}

몇 가지 : 첫째, 나는 당신이 어떤 언어로 n%i/ 주위에 괄호가 필요하다고 생각하지 않습니다 n%i!=0. 둘째, 첫 번째 솔루션이 n%i>0대신 사용할 수 있어야합니다 n%i!=0. 셋째, D의 솔루션은 T d(T)(T n){T s,i=1;for(;i<=n;++i)s+=n%i?0:i;return s;}템플릿 시스템과 기본값을 남용함으로써 가능합니다.
Zacharý

3

잘림 , 44 43 바이트

Xcoder 씨 덕분에 -1 안녕 (내가 모국어로 능가했다)

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

이것은 기능입니다 ( $Snap에서 기능을 시작합니다).

온라인으로 사용해보십시오!

설명:

$ 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
    }

비경쟁, 19 바이트

많은 언어 업데이트 후, 이것은 대략 19 바이트로 줄어들 수 있습니다 :

$n=>sum(factors(n))

온라인으로 사용해보십시오!


1
==0is <1( 43 bytes )
Mr. Xcoder

@씨. Xcoder 감사합니다 ... 나는 능가했습니다 ... 내 언어로 ... 심지어 난해하지 않은 xD
Socratic Phoenix

2

파이썬, 44 바이트

lambda k:sum(i*(k%i<1)for i in range(1,1+k))
  • Stephen 덕분에 공백을 제거하여 1 바이트를 절약하십시오.
  • Jonathan Frech 덕분에 곱할 것인지 변경하여 1 바이트를 더 절약 할 수 있습니다.

2

J, 23 바이트

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

온라인으로 사용해보십시오!

J 팬에게는 영리한 13 바이트 솔루션이 있습니다 . >:@#.~/.~&.q:하지만 내 발명품이 아니기 때문에 공식 답변으로 게시하지 않습니다.

내 솔루션은 단순히 1..n을 필터링하여 제수를 찾은 다음 합계합니다. 그것의 핵심은 dyadic 포크입니다

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

이 문맥 ]에서 1..n [이며 n 자체입니다. 따라서 ]|[1..n의 각 요소를 n으로 나눌 때 나머지가 있으며 =&00과 같은지 알려줍니다.


2
13 바이트이 동일해야 :+1#.i.*0=i.|]
마일

@ 마일, 정말 좋습니다. 이 부분은 i.|]내 접근 방식에서 크게 개선되었습니다. 그래도이 부분을 완전히 이해하지 못합니다 : +1#.i.-설명해 주시겠습니까?
요나

2
1#.동등베이스 (1) 변환이다 +/"1. 먼저 i.|]나머지를 0=구한 다음 0과 같은 것을 찾은 다음 (제수) i.*범위에서 비제 수를 제로화 한 다음를 사용하여 합한 1#.다음 배타적 범위 +이므로 자체 를 더 합니다 i..
마일




2

자바 스크립트, 54 44 바이트

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

Shaggy 덕분에 10 바이트 절약

온라인으로 사용해보십시오!

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 바이트

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

온라인으로 사용해보십시오!

설명:

이제 개선으로 인해 구식입니다.

알고리즘의 핵심은 다음과 같습니다.

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

그것은 mod에 대한 수정 M이며 N, 0그렇지 않으면 우리에게 줄 것 입니다. 전체 코드는 다음과 같습니다.

((({})<>) 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

설명이 있습니까?
밀 마법사

@FunkyComputerMan 나는 지금 하나를 얻었다!
MegaTom

2

R , 31 26 바이트

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

온라인으로 사용해보십시오!

1x1행렬을 반환합니다 .

다음 에 의해 !N%%x맵 요소 d를 계산 합니다 1:N.d->(1 if d divides N, 0 otherwise)

그 다음 x%*%x!N%%x의 매트릭스 제품 1:N의 합계의 결과되는 x!N%%x이다 1. 산뜻한! 기술적으로 Luis Mendo의 Octave 답변 포트 이지만 이것을 생각한 후에 만 ​​보았습니다.

R + 숫자, 14 바이트

numbers::Sigma

온라인으로 사용해보십시오!


첫 번째 바이트의 경우 다음을 사용하여 2 바이트를 절약 할 수 있습니다.N=scan();
gstats

@gstats 예, 그러나 메타 토론 당 +4 바이트를 가져와야합니다 . 당신이 강한 의견을 가지고 있다면 Jarko의 대답에 무게를 둘 수 있지만 아무도 대안을 제안하지 않았으므로 그것은 내 마음 속에 있습니다.
주세페

두 번째가 아니어야합니까 numbers::Sigma(N)? 이와 같이 함수의 소스 코드를 출력합니다 Sigma.
Rui Barradas

@RuiBarradas 함수는 완벽하게 좋은 제출입니다. 그것을 테스트하기 위해, 당신은 분명히 첫 번째 제출에서와 같이 그것을 호출해야합니다.
주세페

1

자바 스크립트, 31 바이트

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



1

VBA (Excel), 73 bytes

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

This answer is invalid as it is a collection of snippets that cannot be run as a single unit as stands. To make this valid you will need to convert this to a subroutine or an anonymous VBE immediate window function.
Taylor Scott

I am not very familiar in what you had said. Can you help me a bit more?
remoel

To make this post valid you would have to convert it into one of the following formats, 1 - Subroutine, 2 - Function, 3 - Anonymous VBE immediate window function (a single line that can be executed in the Immediate window); For your implementation, the simplest implementation of this would be to convert to a subroutine by wrapping with Sub Y...End Sub to get the 85 Byte solution Sub 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

That however can be optimized quite heavily down to the 72 byte solution Sub y While x<=[A1] x=x+1 If [A1]Mod x=0Then b=b+x Wend Debug.?b End Sub which assumes that it is run in a clean module (x = default int value, 0) and outputs to the VBE immediate window (? autoformats to Print )
Taylor Scott

Beyond this, and recognizing that your solution does not take input via the subroutine call, this can then be converted to a VBE immediate window function for 50 Bytes While x<=[A1]:x=x+1:b=IIf([A1]Mod x,b,b+x):Wend:?b which assumes that x,b are the default value of 0 and outputs to the VBE immediate window (from the VBE immediate window ? is equivalent to Debug.Print )
Taylor Scott

1

Pyth, 6 bytes

s*M{yP

Try it here!

Pyth doesn't have a built-in for divisors, so I think this is reasonable.

Explanation

s*M{yP    - Full program with implicit input.

     P    - The prime factors of the input.
    y     - The powerset of its prime factors.
   {      - Deduplicate.
 *M       - Map with multiplication.
s         - Sum.
          - Implicitly display the result.

Given 20, for instance, this is what our program does after each instruction:

  • 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

Husk, 5 bytes

ṁΠuṖp

Try it online!

How?

ṁΠuṖp  - Full program, implicit input.

     p  - Prime factors.
    Ṗ   - Powerset.
   u    - Remove duplicates.
ṁΠ     - Get the product of each list, sum and implicitly output.

Thanks to Zgarb for the suggestions in chat!





0

Bash + GNU utilities, 36

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

Try it online.


Pure Bash, 41

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

Try it online.

I first tried a fancy bash expansion answer, but it ended up being longer than the simple loop above:

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


0

QBIC, 17 bytes

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

Explanation

[:|      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

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.