Raku: Van Eck 시퀀스 생성기

2360 단어 raku
Perl Weekly Challenge #14.1의 작업 중 하나는 Van Eck 시퀀스를 생성하는 프로그램을 작성하는 것입니다. 나는 그것에 대해 들어본 적이 있다는 것을 알고 있었고, 그것은 Numberphile 비디오에서 나온 것입니다: and OEIS/A181391 .

Van Eck 시퀀스를 설명하려면: 첫 번째 항은 0이고 다음 항은 이전 항의 발생 횟수에서 항 색인을 뺀 것으로 정의됩니다.

a[1] = 0
a[n+1] = 0, if a[n] is absent within a[0..n]
a[n+1] = n - m, Otherwise, where a[m] = a[n] and m < n and m is the largest of such.

정의에 따라 a[n+1] 를 계산하기 위해 a[n] 에 대한 전체 시퀀스를 거꾸로 봅니다.

~laurent_r은 루프 기반 솔루션을 제공했습니다.

use v6;

my @a = 0,;
for ^20 -> $n {
    my $result = 0;
    for reverse ^$n -> $m {
        $result = $n - $m and last if @a[$m] == @a[$n];
            # Note: $m is always smaller than $n, so $n - $m > 0
    }
    push @a, $result;
}
say @a;

이 수열의 무한한 성질을 감안할 때, 나는 이 무한 수열을 나타내는 객체를 만들고 싶고, 물론 게으르게 평가된다. 결과는 다음과 같습니다.

my $vaneck = Seq.new(
    class :: does Iterator {
        has %!seen is default(-1);
        has Int $!term = -1;
        has Int $!pos  = 0;
        method pull-one {
            my $next = %!seen{$!term} == -1 ?? 0 !! $!pos - %!seen{$!term};
            %!seen{$!term} = $!pos++;
            return $!term = $next;
        }
    }.new()
);


SeqIterator은 모두 Raku의 내장 유형입니다. %!seen는 이전에 발생한 숫자의 위치를 ​​기록하기 위한 private 변수입니다.

시작하는 200개 용어를 인쇄하는 방법은 다음과 같습니다.

$vaneck[^200].map({ .say });

... 또는 영원히 인쇄하도록 유지하십시오.

$vaneck.map({ .say });



本文為 Perl6: Van Eck 數列產生器 之英文版.

좋은 웹페이지 즐겨찾기