最初のn個の素数の合計を計算する


15

とても明白なので、この挑戦​​がまだここにないことに驚いています。(または、私はそれを見つけることができなかったと誰もがそれを複製としてマークすることに驚いています。)

仕事

非負の整数与えられた場合、最初のn個の素数の合計を計算して出力します。nn

例1

以下のために、最初の5つの素数です。n=5

  • 2
  • 3
  • 5
  • 7
  • 11

これらの数値の合計はであるため、プログラムは28を出力する必要があります。2+3+5+7+11=2828

例2

以下のために、「最初のゼロ」素数はどれもありません。そして、無数の合計は-もちろん-0です。n=00

ルール

  • たとえば、数値が素数かどうかをチェックするために、組み込みを使用できます。
  • これはなので、各言語の最小バイト数が勝ちです!



2
OEIS-A7504 (余談:数式セクションでこれをLOL、「a(n)= A033286(n)-A152535(n)」)
ジョナサンアラン

@JonathanAllan:関連していますが、同等ではありません。範囲内の素数または複数の素数をチェックする場合、それは重要な違いだと思います。両方のタスクに共通することは、a)数値が素数であるかどうかを確認し、b)数値を合計することです。これは、多くのコードゴルフタスクに共通しています。
xanoetux

回答:


15

6502マシンコードルーチン、75バイト

A0 01 84 FD 88 84 FE C4 02 F0 32 E6 FD A0 00 A5 FD C9 04 90 1F 85 64 B1 FB 85
65 A9 00 A2 08 06 64 2A C5 65 90 02 E5 65 CA D0 F4 C9 00 F0 DC C8 C4 FE D0 DB
A5 FD A4 FE 91 FB C8 D0 C8 A9 00 18 A8 C4 FE F0 05 71 FB C8 D0 F7 60

$fb/の一時的なストレージへのポインタ$fcと、合計するプライムの数を期待し$2ます。合計を返しますA(accuレジスタ)。

6502マシンコードでいくつかのプライムチェックを行ったことがないため、ようやくここに来ます;)

これは14以上の入力に対して間違った結果を与え始めることに注意してください。これはオーバーフローのため、コードはunsigned0 - 255用の8ビットプラットフォームの「自然な」数値範囲で動作します。

コメント付きの分解

; function to sum the first n primes
;
; input:
;   $fb/$fc: pointer to a buffer for temporary storage of primes
;   $2:      number of primes to sum (n)
; output:
;   A:       sum of the first n primes
; clobbers:
;   $fd:     current number under primality test
;   $fe:     number of primes currently found
;   $64:     temporary numerator for modulo check
;   $65:     temporary divisor for modulo check
;   X, Y
 .primesum:
A0 01       LDY #$01            ; init variable for ...
84 FD       STY $FD             ; next prime number to test
88          DEY                 ; init number of found primes
 .mainloop:
84 FE       STY $FE             ; store current number of found primes
C4 02       CPY $02             ; compare with requested number
F0 32       BEQ .sum            ; enough primes -> calculate their sum
 .mainnext:
E6 FD       INC $FD             ; check next prime number
A0 00       LDY #$00            ; start check against first prime number
 .primecheckloop:
A5 FD       LDA $FD             ; load current number to check
C9 04       CMP #$04            ; smaller than 4?
90 1F       BCC .isprime        ; is a prime (shortcut to get list started)
85 64       STA $64             ; store to temp as numerator
B1 FB       LDA ($FB),Y         ; load from prime number table
85 65       STA $65             ; store to temp as divisor
A9 00       LDA #$00            ; init modulo to 0
A2 08       LDX #$08            ; iterate over 8 bits
 .bitloop:
06 64       ASL $64             ; shift left numerator
2A          ROL A               ; shift carry into modulo
C5 65       CMP $65             ; compare with divisor
90 02       BCC .bitnext        ; smaller -> to next bit
E5 65       SBC $65             ; otherwise subtract divisor
 .bitnext:
CA          DEX                 ; next bit
D0 F4       BNE .bitloop
C9 00       CMP #$00            ; compare modulo with 0
F0 DC       BEQ .mainnext       ; equal? -> no prime number
C8          INY                 ; next index in prime number table
C4 FE       CPY $FE             ; checked against all prime numbers?
D0 DB       BNE .primecheckloop ; no -> check next
 .isprime:
A5 FD       LDA $FD             ; prime found
A4 FE       LDY $FE             ; then store in table
91 FB       STA ($FB),Y
C8          INY                 ; increment number of primes found
D0 C8       BNE .mainloop       ; and repeat whole process
 .sum:
A9 00       LDA #$00            ; initialize sum to 0
18          CLC
A8          TAY                 ; start adding table from position 0
 .sumloop:
C4 FE       CPY $FE             ; whole table added?
F0 05       BEQ .done           ; yes -> we're done
71 FB       ADC ($FB),Y         ; add current entry
C8          INY                 ; increment index
D0 F7       BNE .sumloop        ; and repeat
 .done:
60          RTS

ルーチンを使用したC64アセンブラープログラムの例:

オンラインデモ

ca65構文のコード:

.import primesum   ; link with routine above

.segment "BHDR" ; BASIC header
                .word   $0801           ; load address
                .word   $080b           ; pointer next BASIC line
                .word   2018            ; line number
                .byte   $9e             ; BASIC token "SYS"
                .byte   "2061",$0,$0,$0 ; 2061 ($080d) and terminating 0 bytes

.bss
linebuf:        .res    4               ; maximum length of a valid unsigned
                                        ; 8-bit number input
convbuf:        .res    3               ; 3 BCD digits for unsigned 8-bit
                                        ; number conversion
primebuf:       .res    $100            ; buffer for primesum function

.data
prompt:         .byte   "> ", $0
errmsg:         .byte   "Error parsing number, try again.", $d, $0

.code
                lda     #$17            ; set upper/lower mode
                sta     $d018

input:
                lda     #<prompt        ; display prompt
                ldy     #>prompt
                jsr     $ab1e

                lda     #<linebuf       ; read string into buffer
                ldy     #>linebuf
                ldx     #4
                jsr     readline

                lda     linebuf         ; empty line?
                beq     input           ; try again

                lda     #<linebuf       ; convert input to int8
                ldy     #>linebuf
                jsr     touint8
                bcc     numok           ; successful -> start processing
                lda     #<errmsg        ; else show error message and repeat
                ldy     #>errmsg
                jsr     $ab1e
                bcs     input

numok:          
                sta     $2
                lda     #<primebuf
                sta     $fb
                lda     #>primebuf
                sta     $fc
                jsr     primesum        ; call function to sum primes
                tax                     ; and ...
                lda     #$0             ; 
                jmp     $bdcd           ; .. print result

; read a line of input from keyboard, terminate it with 0
; expects pointer to input buffer in A/Y, buffer length in X
.proc readline
                dex
                stx     $fb
                sta     $fc
                sty     $fd
                ldy     #$0
                sty     $cc             ; enable cursor blinking
                sty     $fe             ; temporary for loop variable
getkey:         jsr     $f142           ; get character from keyboard
                beq     getkey
                sta     $2              ; save to temporary
                and     #$7f
                cmp     #$20            ; check for control character
                bcs     checkout        ; no -> check buffer size
                cmp     #$d             ; was it enter/return?
                beq     prepout         ; -> normal flow
                cmp     #$14            ; was it backspace/delete?
                bne     getkey          ; if not, get next char
                lda     $fe             ; check current index
                beq     getkey          ; zero -> backspace not possible
                bne     prepout         ; skip checking buffer size for bs
checkout:       lda     $fe             ; buffer index
                cmp     $fb             ; check against buffer size
                beq     getkey          ; if it would overflow, loop again
prepout:        sei                     ; no interrupts
                ldy     $d3             ; get current screen column
                lda     ($d1),y         ; and clear 
                and     #$7f            ;   cursor in
                sta     ($d1),y         ;   current row
output:         lda     $2              ; load character
                jsr     $e716           ;   and output
                ldx     $cf             ; check cursor phase
                beq     store           ; invisible -> to store
                ldy     $d3             ; get current screen column
                lda     ($d1),y         ; and show
                ora     #$80            ;   cursor in
                sta     ($d1),y         ;   current row
                lda     $2              ; load character
store:          cli                     ; enable interrupts
                cmp     #$14            ; was it backspace/delete?
                beq     backspace       ; to backspace handling code
                cmp     #$d             ; was it enter/return?
                beq     done            ; then we're done.
                ldy     $fe             ; load buffer index
                sta     ($fc),y         ; store character in buffer
                iny                     ; advance buffer index
                sty     $fe
                bne     getkey          ; not zero -> ok
done:           lda     #$0             ; terminate string in buffer with zero
                ldy     $fe             ; get buffer index
                sta     ($fc),y         ; store terminator in buffer
                sei                     ; no interrupts
                ldy     $d3             ; get current screen column
                lda     ($d1),y         ; and clear 
                and     #$7f            ;   cursor in
                sta     ($d1),y         ;   current row
                inc     $cc             ; disable cursor blinking
                cli                     ; enable interrupts
                rts                     ; return
backspace:      dec     $fe             ; decrement buffer index
                bcs     getkey          ; and get next key
.endproc

; parse / convert uint8 number using a BCD representation and double-dabble
.proc touint8
                sta     $fb
                sty     $fc
                ldy     #$0
                sty     convbuf
                sty     convbuf+1
                sty     convbuf+2
scanloop:       lda     ($fb),y
                beq     copy
                iny
                cmp     #$20
                beq     scanloop
                cmp     #$30
                bcc     error
                cmp     #$3a
                bcs     error
                bcc     scanloop
error:          sec
                rts
copy:           dey
                bmi     error
                ldx     #$2
copyloop:       lda     ($fb),y
                cmp     #$30
                bcc     copynext
                cmp     #$3a
                bcs     copynext
                sec
                sbc     #$30
                sta     convbuf,x
                dex
copynext:       dey
                bpl     copyloop
                lda     #$0
                sta     $fb
                ldx     #$8
loop:           lsr     convbuf
                lda     convbuf+1
                bcc     skipbit1
                ora     #$10
skipbit1:       lsr     a
                sta     convbuf+1
                lda     convbuf+2
                bcc     skipbit2
                ora     #$10
skipbit2:       lsr     a
                sta     convbuf+2
                ror     $fb
                dex
                beq     done
                lda     convbuf
                cmp     #$8
                bmi     nosub1
                sbc     #$3
                sta     convbuf
nosub1:         lda     convbuf+1
                cmp     #$8
                bmi     nosub2
                sbc     #$3
                sta     convbuf+1
nosub2:         lda     convbuf+2
                cmp     #$8
                bmi     loop
                sbc     #$3
                sta     convbuf+2
                bcs     loop
done:           lda     $fb
                clc
                rts
.endproc

4
私はこれをゴルフ言語の絶え間ない流れよりもはるかに楽しんでいます(今日はMOS 6502 Tシャツを着ている場合と着ていない場合があります)。
マットレイシー

1
@MattLacey感謝:)スペースを節約することは実際にそのチップ上の標準的なプログラミングの練習ですので、私はすべてのこれらの言語を学ぶことがあまりにも怠惰なんだ...と親切な「自然」の6502のコードフィールで、いくつかのパズルをやって:)
フェリックスPalmen

MOS 6502 Tシャツを購入する必要があります。
タイタス

8

Python 2、49バイト

f=lambda n,t=1,p=1:n and p%t*t+f(n-p%t,t+1,p*t*t)

ウィルソンの定理を使用します(xnorがサイトに紹介したように、私はここで信じています

オンラインでお試しください!

この関数fは再帰的であり、最初の入力がnあり、nゼロに達するとテールがあり、その論理ゼロのためにゼロが得られますandnが減少するたびにt、の呼び出しごとに増加するテスト番号fが素数になります。素数検定はn 1 かどうかです!- 1に対して、階乗の二乗を追跡します。n1  1モッドnp


私はリンの一般的なヘルパー機能の1つを適応させていましたが、まったく同じことを達成しました。
Mr Xcoder

...ああ、定理はxnorによってサイトに導入されました。良い参考記事、ありがとう!
ジョナサンアラン



6

Java 8、89バイト

n->{int r=0,i=2,t,x;for(;n>0;r+=t>1?t+0*n--:0)for(t=i++,x=2;x<t;t=t%x++<1?0:t);return r;}

オンラインでお試しください。

説明:

n->{               // Method with integer as both parameter and return-type
  int r=0,         //  Result-sum, starting at 0
      i=2,         //  Prime-integer, starting at 2
      t,x;         //  Temp integers
  for(;n>0         //  Loop as long as `n` is still larger than 0
      ;            //    After every iteration:
       r+=t>1?     //     If `t` is larger than 1 (which means `t` is a prime):
           t       //      Increase `r` by `t`
           +0*n--  //      And decrease `n` by 1
          :        //     Else:
           0)      //      Both `r` and `n` remain the same
    for(t=i++,     //   Set `t` to the current `i`, and increase `i` by 1 afterwards
        x=2;       //   Set `x` to 2
        x<t;       //   Loop as long as `x` is still smaller than `t`
      t=t%x++<1?   //    If `t` is divisible by `x`:
         0         //     Set `t` to 0
        :          //    Else:
         t);       //     `t` remains the same
                   //   If `t` is still the same after this loop, it means it's a prime
  return r;}       //  Return the result-sum



5

Brachylog8 7バイト

~lṗᵐ≠≜+

オンラインでお試しください!

@sundarのおかげで1バイト節約されました。

説明

~l        Create a list of length input
  ṗᵐ      Each element of the list must be prime
    ≠     All elements must be distinct
     ≜    Find values that match those constraints
      +   Sum

~lṗᵐ≠≜+7バイトのため、動作しているようです(実行した場合、それは標識することなく、出力2 *入力+ 1を与える理由も、私は興味があります。)
サンダー-復活モニカ

2
@sundarデバッガーを使用してチェックし、理由を見つけました:プライムの値を選択しませんが、それでもすべての1つが[2,+inf)明らかになければならないことをまだ知っています。したがって、5つの素数の合計(入力が5の場合)は少なくとも10でなければならないことがわかっており、要素は異なる必要があるため、すべてが2になれないため、少なくともであることが部分的にわかっています11。TL; DRによる暗黙的なラベル付けの実装は十分に強力ではありません。
致命的

それはとても興味深いです。理由は、構文の奇抜や実装の偶然の偶然ではなく、制約に基づいて意味のあるものであることが好きです。ご覧いただきありがとうございます!
スンダ



2

網膜、41バイト

K`_
"$+"{`$
$%"_
)/¶(__+)\1+$/+`$
_
^_

_

オンラインでお試しください!nプライムを見つけるまで1を追加し続けたかったのですが、Retinaでそれを行う方法がわからなかったため、ネストループに頼りました。説明:

K`_

1から始めます。

"$+"{`

ループn時間。

$
$%"_

前の値のコピーを作成し、増分します。

)/¶(__+)\1+$/+`$
_

合成中はインクリメントを続けます。()外側のループを閉じます。)

^_

オリジナルを削除し1ます。

_

合計して10進数に変換します。



2

PHP、66バイト

もう一度自分の素数関数を使用し ...

for(;$k<$argn;$i-1||$s+=$n+!++$k)for($i=++$n;--$i&&$n%$i;);echo$s;

でパイプとして実行する-nr、オンラインで試してください

壊す

for(;$k<$argn;      # while counter < argument
    $i-1||              # 3. if divisor is 1 (e.g. $n is prime)
        $s+=$n              # add $n to sum
        +!++$k              # and increment counter
    )
    for($i=++$n;        # 1. increment $n
        --$i&&$n%$i;);  # 2. find largest divisor of $n smaller than $n:
echo$s;             # print sum

同じ長さで、変数が1つ少ない:for(;$argn;$i-1||$s+=$n+!$argn--)for($i=++$n;--$i&&$n%$i;);echo$s;
Titus

2

Haskell、48バイト

sum.(`take`[p|p<-[2..],all((>0).mod p)[2..p-1]])

オンラインでお試しください!

注: \p-> all((>0).mod p)[2..p-1]それはあることから、有効な首相のチェックではないTrueため01同様に。しかし、私たちはそれを回避するために、2、したがって、この場合はそれで十分です。



2

C、C ++、D:147142バイト

int p(int a){if(a<4)return 1;for(int i=2;i<a;++i)if(!(a%i))return 0;return 1;}int f(int n){int c=0,v=1;while(n)if(p(++v)){c+=v;--n;}return c;}

CおよびC ++の5バイトの最適化:

ザカリーのおかげで-2バイト

#define R return
int p(int a){if(a<4)R 1;for(int i=2;i<a;++i)if(!(a%i))R 0;R 1;}int f(int n){int c=0,v=1;while(n)if(p(++v))c+=v,--n;R c;}

p数が素数かどうかをテストしfn最初の数を合計します

テストに使用されるコード:

C / C ++:

for (int i = 0; i < 10; ++i)
    printf("%d => %d\n", i, f(i));

DZacharýによる最適化された回答133 131バイト

Dにはゴルフテンプレートシステムがあります

T p(T)(T a){if(a<4)return 1;for(T i=2;i<a;)if(!(a%i++))return 0;return 1;}T f(T)(T n){T c,v=1;while(n)if(p(++v))c+=v,--n;return c;}

1
T p(T)(T a){if(a<4)return 1;for(T i=2;i<a;)if(!(a%i++))return 0;return 1;}T f(T)(T n){T c,v=1;while(n)if(p(++v)){c+=v;--n;}return c;}。また、C / C ++ / Dであることができるint p(int a){if(a<4)return 1;for(int i=2;i<a;++i)if(!(a%i))return 0;return 1;}int f(int n){int c=0,v=1;while(n)if(p(++v)){c+=v;--n;}return c;}(ちょうどアルゴリズムABITを調整する、C / C ++最適化と同じ)
ザカリー

たぶんすべての答えについては、コンマを使用してする{c+=v;--n;}ことができc+=v,--n;ますか?
ザカリー

Dの別の1つ(およびintsに戻した場合はC / C ++の場合もあります):T p(T)(T a){T r=1,i=2;for(;i<a;)r=a%i++?r:0;return r;}T f(T)(T n){T c,v=1;while(n)if(p(++v))c+=v,--n;return c;}
ザカリー

提案a>3&i<aの代わりi<aと削除if(a<4)...
ceilingcat




1

APL(Dyalog Unicode)、7 + 9 = 16バイト

+/pco∘⍳

オンラインでお試しください!

インポートする追加の9バイト pco(およびその他の)Dfn:⎕CY'dfns'

どうやって:

+/pco∘⍳
        Generate the range from 1 to the argument
        Compose
  pco    P-colon (p:); without a left argument, it generates the first <right_arg> primes.
+/       Sum

もう1バイト追加する必要はありませんか?import X(改行)X.something()pythonでは、改行でカウントされます。
ザカリー

1

ルビー、22 + 7 = 29バイト

ruby -rprime(+7)で実行

->n{Prime.take(n).sum}


1

JAEL、5バイト

#&kȦ

説明(自動生成):

./jael --explain '#&kȦ'
ORIGINAL CODE:  #&kȦ

EXPANDING EXPLANATION:
Ȧ => .a!

EXPANDED CODE:  #&k.a!,

#     ,                 repeat (p1) times:
 &                              push number of iterations of this loop
  k                             push nth prime
   .                            push the value under the tape head
    a                           push p1 + p2
     !                          write p1 to the tape head
       ␄                print machine state

0

パイソン263の 59 56 51バイト

f=lambda n:n and prime(n)+f(n-1)
from sympy import*

オンラインでお試しください!


保存済み:

  • -5バイト、ジョナサンアランのおかげ

ライブラリなし:

Python 2、83バイト

n,s=input(),0
x=2
while n:
 if all(x%i for i in range(2,x)):n-=1;s+=x
 x+=1
print s

オンラインでお試しください!


f=lambda n:n and prime(n)+f(n-1)5を節約します(さらにゴルフが可能かもしれません)
ジョナサンアラン


0

CJam、21バイト

0{{T1+:Tmp!}gT}li*]:+


Explanation:
0{{T1+:Tmp!}gT}li*]:+ Original code

 {            }li*    Repeat n times
  {        }          Block
   T                  Get variable T | stack: T
    1+                Add one | Stack: T+1 
      :T              Store in variable T | Stack: T+1
        mp!           Is T not prime?     | Stack: !(isprime(T))
            g         Do while condition at top of stack is true, pop condition
             T        Push T onto the stack | Stack: Primes so far
0                 ]   Make everything on stack into an array, starting with 0 (to not throw error if n = 0)| Stack: array with 0 and all primes up to n
                   :+ Add everything in array

オンラインでお試しください!


0

F#、111バイト

let f n=Seq.initInfinite id|>Seq.filter(fun p->p>1&&Seq.exists(fun x->p%x=0){2..p-1}|>not)|>Seq.take n|>Seq.sum

オンラインでお試しください!

Seq.initInfiniteパラメーターとしてアイテムインデックスを受け取るジェネレーター関数を使用して、無限に長いシーケンスを作成します。この場合、ジェネレーター関数は単なる恒等関数ですidです。

Seq.filter 素数である無限シーケンスによって作成された数値のみを選択します。

Seq.takenそのシーケンスの最初の要素を取ります。

そして最後に、Seq.sumそれらを合計します。




0

APL(NARS)、27文字、54バイト

{⍵=0:0⋄+/{⍵=1:2⋄¯2π⍵-1}¨⍳⍵}

ここで{¯2π⍵}は2と異なるn素数を返します。したがって、{⍵= 1:2⋄¯2π⍵-1}はその中のn個の素数2を返します...

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.