LoginSignup
8
0

More than 3 years have passed since last update.

Google recruit problem

Last updated at Posted at 2020-12-20

課題

{e(自然対数の底)の値で連続する10桁の数のうち,最初の素数}

を求める.ただし,e(自然対数の底)は200桁までで

2.71828182845904523536028747135266249775
7247093699959574966967627724076630353547
5945713821785251664274274663919320030599
2181741359662904357290033429526059563073
81323286279434907632338298807531952510190

をテキストにコピーしてそのファイルを読み込んで動作させる.

解法

やることとしては

  • テキストファイルに記載されているeの小数点と改行を取り除く.
  • 頭から10桁を取り出しそれが素数かどうかを判定する.
  • 1桁ずつずらしていき最初に素数が出てきたところでストップ

をすれば良さそう.

まず「テキストファイルに記載されているeの小数点と改行を取り除く.」をやってみる.

exp = File.read("e.txt").delete("\n .")

これで「e.txt」に書かれたeの値を小数点と改行を取り除き変数expに格納できる.

次に,「頭から10桁を取り出し,一桁ずつずらしていく」ことを実装する.

exp = File.read("e.txt").delete("\n .")

for i in Range.new(0, exp.length - 10)
    num = exp.slice(i .. i + 9).to_i
    if #素数かどうかを判定 
        #初めてできた素数を表示
        break
    end
end

forループで実現したがこの時

Range.new(範囲開始値, 範囲終了値)

というものを使用している.

さて,いよいよ「素数の判定」だがrubyには素数を判定するクラスがあるようなのでそれ使用してみる.

使い方は

require 'prime'

Prime.prime?(判定する数値)

これで素数ならture,そうでなければfalseが返ってくる.

require 'prime'

exp = File.read("e.txt").delete("\n .")

for i in Range.new(0, exp.length - 10)
    num = exp.slice(i .. i + 9).to_i
    if Prime.prime?(num)
        puts num
        break
    end
end

これでひとまず完成.

結果は

7427466391

となる.

発展課題

Congratulations. You've made it to level 2. 
Go to www.Linux.org and enter Bobsyouruncle 
as the login and the answer to this equation as the password.
f(1)=7182818284
f(2)=8182845904
f(3)=8747135266
f(4)=7427466391
f(5)=__________

解法

先程の問題をクリアすると,この問題が次に出題されたらしい.

これらには何かしらの法則があるようだが,どうやら先程のeに現れる10桁の整数のうち全ての桁を足し合わせると合計が49になるものという法則のようだ.

その整数を探索するプログラムを作成する.

簡単に思いつくのは,先程同様に前から10桁の整数を1桁ずつずらして探索していくということだ.以下がそのプログラム.

require 'prime'

exp = File.read("e.txt").delete("\n .")

count = 0
for i in Range.new(0, exp.length - 10)
    num = exp.slice(i .. i + 9).to_i
    num_sum = num.to_s.split("").map { |s| s.to_i }.inject(:+) 
    if num_sum == 49 
      puts num
      count += 1
      if count == 5
        break
      end
    end
end

結果は,

7182818284
8182845904
8747135266
7427466391
5966290435

となる.

今回使用したものとして

num_sum = num.to_s.split("").map { |s| s.to_i }.inject(:+) 

があるが,これはまず取ってきた10桁の数字を文字列に変換し,それ一文字ずつ分割し数値化,その後全てを足し合わせるということを行っている.

まとめ

今回は素数判定をするプログラムを作成した.これはGoogleのリクルートに使用された問題らしい.

参考


  • source ~/prog/github/grad_members_20f/members/miyanagi/post/google.org
8
0
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
8
0