3
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

CodeIQ「スーパー素数」問題に参加しました。

Posted at

CodeIQ「スーパー素数」問題の公開期間が終了したということで、自分の答案を公開したいと思います。

利用した言語はBash――なのですが、実際はawkですね(´・ω・`) プログラミング・パズルをBashで解こうとすると、どうしてもawkを多用しがちです。

#!/bin/bash

awk '{
    n = 200000
    
    eratosthenes[0] = eratosthenes[1] = 1
    for (i = 2; i <= sqrt(n); i++) {
        if (eratosthenes[i] == 1) continue;
        for (j = i * 2; j <= n; j += i) eratosthenes[j] = 1;
    }

    for (i = 1; i <= n; i++) {
        if (eratosthenes[i] != 1) primes[++x] = i;
    }
    
    for(i = 1; i <= 2017; i++) super_primes[i] = primes[primes[i]];
    
    print(super_primes[$0])
}'

問題の内容としては「素数列の素数番目だけを集めた『スーパー素数』列のn番目を求めなさい」というもの。解答にあたっては素数列を求める必要があるのですが、問題の制約上200000程度まで計算せねばなりません。よって比較的効率のよいアルゴリズム、すなわち「エラトステネスのふるい」により素数列挙を行いました。実際にやってみたわけではないのですが、試し割りのような計算量の多いアルゴリズムだと、CodeIQの制限時間(1秒)には間に合わないと思います。

要するに本問はエラトステネスのふるいがきちんと実装できるかということが問われていたのでした。

おまけ: 現役システムエンジニアらしく、VBAでも実装しておきました(´・ω・`)

Sub SuperPrimes()
    Const UpperBound As Long = 200000
    Const SuperPrimesUpperBound As Long = 2017
    
    Dim X As Long
    
    ' エラトステネスのふるい: 素数判定を行う。
    Dim IsPrime(UpperBound + 1) As Boolean
    For X = 0 To UpperBound
        IsPrime(X) = True
    Next X
    IsPrime(0) = IsPrime(1) = False
    
    For X = 2 To Sqr(UpperBound)
        If IsPrime(X) Then
            Dim NonPrime As Long
            For NonPrime = X * 2 To UpperBound Step X
                IsPrime(NonPrime) = False
            Next NonPrime
        End If
    Next X
    
    ' 素数列を求める。
    Dim Primes(UpperBound) As Long
    Dim PrimesIdx As Long
    PrimesIdx = 1
    For X = 2 To UpperBound
        If IsPrime(X) Then
            Primes(PrimesIdx) = X
            PrimesIdx = PrimesIdx + 1
        End If
    Next X
    
    ' スーパー素数列を求める。
    Dim SuperPrimes(SuperPrimesUpperBound) As Long
    For X = 1 To SuperPrimesUpperBound
        SuperPrimes(X) = Primes(Primes(X))
    Next X
    
    ' スーパー素数列をシートに書き出す。
    For X = 1 To SuperPrimesUpperBound
        Cells(X, 1).Value = SuperPrimes(X)
    Next X
End Sub

以上のマクロをエクセルに張り付けて実行すると、シートのA列にスーパー素数が書き出されます。業務で「素数」「エラトステネスのふるい」「スーパー素数」が必要になりそうな方は参考にしてください(`・ω・´)シャキーン

3
3
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?