디리클레 컨볼 루션


19

디리클레의 컨볼 루션 의 특별한 종류 회선 번호를 이론에 매우 유용한 도구로 나타납니다. 산술 함수 집합에서 작동 합니다.

도전

주어진 두 개의 산술 함수 (즉, 함수 )는 Dirichlet convolution 계산합니다 아래에 정의 된대로.f,gf,g:NR (fg):NR

세부

  • 우리는 규칙을 사용합니다 .0N={1,2,3,}
  • 두 개의 산술 함수 의 Dirichlet convolution 는 다시 산술 함수이며(두 합계는 동일합니다. 표현 은 나누는 것을 의미 하므로, 합계는 의 자연 제수 를 초과합니다 . 마찬가지로 우리는 대체 할 수 있습니다fgf,g
    (fg)(n)=d|nf(nd)g(d)=ij=nf(i)g(j).
    d|ndNnni=ndN,j=dN두 번째 등가 공식을 얻습니다. 이 표기법에 익숙하지 않은 경우 아래에 단계별 예제가 있습니다. 자세히 설명하기 (이 문제와 직접 관련이 없음) : Dirichlet 시리즈 의 제품을 계산하여 정의한 내용 :
    (nNf(n)ns)(nNg(n)ns)=nN(fg)(n)ns
  • 입력은 두 개의 블랙 박스 기능으로 제공 됩니다. 또는 무한 목록, 생성기, 스트림 또는 무제한의 값을 생성 할 수있는 유사한 항목을 사용할 수도 있습니다.
  • 두 가지 출력 방법이 있습니다. 함수 가 리턴되거나 추가 입력 가져 와서 직접 리턴 할 수 있습니다.fgnN(fg)(n)
  • 간단하게하기 위해 의 모든 요소 를 예를 들어 양의 32 비트 int로 표현할 수 있다고 가정 할 수 있습니다.N
  • 간단히하기 위해 모든 항목 을 단일 실수 부동 소수점 숫자로 나타낼 수 있다고 가정 할 수도 있습니다.R

먼저 몇 가지 함수를 정의하겠습니다. 각 정의 아래의 숫자 목록은 해당 함수의 처음 몇 값을 나타냅니다.

  • 곱하기 ID ( A000007 )
    ϵ(n)={1n=10n>1
    1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ...
  • 상수 단위 함수 ( A000012 )
    1(n)=1n
    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, ...
  • 항등 함수 ( A000027 )
    id(n)=nn
    1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, ...
  • Möbius 함수 ( A008683 )
    μ(n)={(1)k if n is squarefree and k is the number of Primefactors of n0 otherwise 
    1, -1, -1, 0, -1, 1, -1, 0, 0, 1, -1, 0, -1, 1, 1, 0, -1, 0, -1, ...
  • 오일러 잠복 자 함수 ( A000010 )
    φ(n)=np|n(11p)
    1, 1, 2, 2, 4, 2, 6, 4, 6, 4, 10, 4, 12, 6, 8, 8, 16, 6, 18, 8, ...
  • Liouville 함수 ( A008836 ) 여기서 는 다중 도로 계산 된 의 소인수입니다.
    λ(n)=(1)k
    kn1, -1, -1, 1, -1, 1, -1, -1, 1, 1, -1, -1, -1, 1, 1, 1, -1, -1, -1, ...
  • 제수 합 함수 ( A000203 )
    σ(n)=d|nd
    1, 3, 4, 7, 6, 12, 8, 15, 13, 18, 12, 28, 14, 24, 24, 31, 18, 39, 20, ...
  • 제수 계산 함수 ( A000005 )
    τ(n)=d|n1
    1, 2, 2, 3, 2, 4, 2, 4, 3, 4, 2, 6, 2, 4, 4, 5, 2, 6, 2, 6, 4, 4, 2, 8, ...
  • 제곱의 특징 함수 ( A010052 )
    sq(n)={1 if n is a square number0otherwise
    1, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, ...

다음 예제가 있습니다.

  • ϵ=1μ
  • f=ϵff
  • ϵ=λ|μ|
  • σ=φτ
  • id=σμσ=id1
  • sq=λ1λ=μsq
  • τ=111=τμ
  • id=φ1φ=idμ

대한 최후의 결과이다 뫼비우스 반전 : 임의 들어 식 동등 .f,gg=f1f=gμ

단계별 예

이것은 정의에 사용 된 표기법에 익숙하지 않은 사람들을 위해 단계별로 계산되는 예입니다. 및 함수를 고려하십시오 . 이제 에서 컨볼 루션 를 평가할 것 입니다. 그들의 첫 몇 용어는 아래 표에 나열되어 있습니다.f=μg=σμσn=12

ff(1)f(2)f(3)f(4)f(5)f(6)f(7)f(8)f(9)f(10)f(11)f(12)μ111011100110σ134761281513181228

이 합은 를 나누는 모든 자연수 대해 반복 되므로 는 모든 자연 제수를 가정합니다 . 이들은 입니다. 각각의 요약에서, 우리 는 에서 를 평가 하고 그것을 에서 평가로 곱합니다 . 이제 결론을 내릴 수 있습니다dNn=12dn=12=223d=1,2,3,4,6,12g=σdf=μnd

(μσ)(12)=μ(12)σ(1)+μ(6)σ(2)+μ(4)σ(3)+μ(3)σ(4)+μ(2)σ(6)+μ(1)σ(12)=01+13+04+(1)7+(1)12+128=0+310712+28=12=id(12)

답변:


4

, 108 100 95 78 75 바이트

def d(f g:_->int)(n):=(list.iota n).foldr(λd s,ite(n%d=0)(s+f d*g(n/d))s)0

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

모든 기능을 갖춘 더 많은 테스트 케이스.


람다는 실제로 4 바이트보다 비쌉 fun 니까?
마리오 카네이로

람다는 3 바이트입니다
Leaky Nun

나는 UTF8 두 (그리스어 꽤 낮은 유니 코드입니다) 생각
마리오 Carneiro

네가 옳아. 나도 수입 골프
Leaky Nun

나는 또한 cond5 바이트를 저장 하는 데 사용
Leaky Nun


3

파이썬 3 , 59 바이트

lambda f,g,n:sum(f(d)*g(n//d)for d in range(1,n+1)if 1>n%d)

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


되어 //정말 대신 필요 /?
Mr. Xcoder

/수레를 올바르게 생산합니까?
Leaky Nun

정의 dn의한 제수 이므로 소수 부분 n/d은 0이므로 부동 소수점 산술에 문제가 없어야합니다. 소수 부분이 0 인 부동 소수점은 파이썬 목적을 위해 정수에 가깝고 함수의 출력은 실수이므로 n/d대신 수행하는 것이 좋습니다 n//d.
Mego


2

추가 ++ , 51 바이트

D,g,@~,$z€¦~¦*
D,f,@@@,@b[VdF#B]dbRzGb]$dbL$@*z€g¦+

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

두 개의 미리 정의 된 함수를 인수, 더하기 취합니다.n(fg)(n)

작동 원리

D,g,		; Define a helper function, $g
	@~,	; $g takes a single argument, an array, and splats that array to the stack
		; $g takes the argument e.g. [[τ(x) φ(x)] [3 4]]
		; STACK : 			[[τ(x) φ(x)] [3 4]]
	$z	; Swap and zip:			[[3 τ(x)] [4 φ(x)]]
	€¦~	; Reduce each by execution:	[[τ(3) φ(4)]]
	¦*	; Take the product and return:	τ(3)⋅φ(4) = 4

D,f,		; Define the main function, $f
	@@@,	; $f takes three arguments: φ(x), τ(x) and n (Let n = 12)
		; STACK:			[φ(x) τ(x) 12]
	@	; Reverse the stack:		[12 τ(x) φ(x)]
	b[V	; Pair and save:		[12]			Saved: [τ(x) φ(x)]
	dF#B]	; List of factors:		[[1 2 3 4 6 12]]
	dbR	; Copy and reverse:		[[1 2 3 4 6 12] [12 6 4 3 2 1]]
	z	; Zip together:			[[[1 12] [2 6] [3 4] [4 3] [6 2] [12 1]]]
	Gb]	; Push Saved:			[[[1 12] [2 6] [3 4] [4 3] [6 2] [12 1]] [[τ(x) φ(x)]]]
	$dbL	; Number of dividors:		[[[τ(x) φ(x)]] [[1 12] [2 6] [3 4] [4 3] [6 2] [12 1]] 6]
	$@*	; Repeat:			[[[1 12] [2 6] [3 4] [4 3] [6 2] [12 1]] [[τ(x) φ(x)] [τ(x) φ(x)] [τ(x) φ(x)] [τ(x) φ(x)] [τ(x) φ(x)] [τ(x) φ(x)]]]
	z	; Zip:				[[[τ(x) φ(x)] [1 12]] [[τ(x) φ(x)] [2 6]] [[τ(x) φ(x)] [3 4]] [[τ(x) φ(x)] [4 3]] [[τ(x) φ(x)] [6 2]] [[τ(x) φ(x)] [12 1]]]
	€g	; Run $g over each subarray:	[[4 4 4 6 4 6]]
	¦+	; Take the sum and return:	28

2

R , 58 바이트

function(n,f,g){for(i in (1:n)[!n%%1:n])F=F+f(i)*g(n/i)
F}

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

소요 n, f그리고 g. 운 좋게도 numbers패키지에는 이미 구현 된 기능이 꽤 있습니다.

로 벡터를 래핑하여 벡터화 된 버전을 사용할 수있는 Vectorize경우 다음 45 바이트 버전이 가능합니다.

R , 45 바이트

function(n,f,g,x=1:n,i=x[!n%%x])f(i)%*%g(n/i)

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




1

자바 스크립트 (ES6), 47 바이트

로 입력을 (f)(g)(n)받습니다.

f=>g=>h=(n,d=n)=>d&&!(n%d)*f(n/d)*g(d)+h(n,d-1)

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

liouville =
n => (-1) ** (D = (n, k = 2) => k > n ? 0 : (n % k ? D(n, k + 1) : 1 + D(n / k, k)))(n)

mobius =
n => (M = (n, k = 1) => n % ++k ? k > n || M(n, k) : n / k % k && -M(n / k, k))(n)

sq =
n => +!((n ** 0.5) % 1)

identity =
n => 1

// sq = liouville * identity
console.log([...Array(25)].map((_, n) => F(liouville)(identity)(n + 1)))

// liouville = mobius * sq
console.log([...Array(20)].map((_, n) => F(mobius)(sq)(n + 1)))

1

APL (Dyalog Classic) , 20 바이트

{(⍺⍺¨∘⌽+.×⍵⍵¨)∪⍵∨⍳⍵}

⎕IO←1

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

해결하기 쉽고 테스트하기 어려운-일반적으로 내 유형의 도전이 아닙니다. 그러나 나는 이것을 매우 즐겼습니다!

{ }그 피연산자 이항 연산자 정의 ⍺⍺⍵⍵컨벌루션되는 두 가지 기능이있다; 숫자 인수입니다

∪⍵∨⍳⍵오름차순 의 제수 , 즉 모든 자연수 를 가진 LCM의 고유 ( ) ( )

⍵⍵¨ 각각에 올바른 피연산자를 적용하십시오

⍺⍺¨∘⌽ 왼쪽 피연산자를 각각 반대로 적용

+.× 내부 곱-해당 요소와 합계 곱하기


ngn / apl도 유니 코드 식별자로 인해 더 좋아 보이지만 1 인덱싱으로 인해 2 바이트가 더 필요합니다.


ngn / apl에서 27 바이트가 더 필요합니다.
Outgolfer Erik

1

C (gcc) , 108 바이트

#define F float
F c(F(*f)(int),F(*g)(int),int n){F s=0;for(int d=0;d++<n;)if(n%d<1)s+=f(n/d)*g(d);return s;}

Leaky Nun의 Python answer 에서 뻔뻔스럽게 도난당한 간단한 구현 .

언 골프 드 :

float c(float (*f)(int), float (*g)(int), int n) {
    float s = 0;
    for(int d = 1; d <= n;++d) {
        if(n % d == 0) {
            s += f(n / d) * g(d);
        }
    }
    return s;
}

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


1

F #, 72 바이트

let x f g n=Seq.filter(fun d->n%d=0){1..n}|>Seq.sumBy(fun d->f(n/d)*g d)

두 기능 fg자연수를 취합니다 n. d자연적으로 나누지 않는 값을 필터링합니다 n. 그런 다음와를 평가 f(n/d) 하고 g(d)함께 배수하여 결과를 합산합니다.


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