はじめに
本稿はマルチスケールシミュレーションという講義の最終課題についての記事です
目次
課題内容
課題:Google recruit problem, exp and prime
(Rubyを用いて)e(自然対数の底)の値で連続する10桁の数のうち,最初の素数を求めよ
2.71828182845904523536028747135266249775
7247093699959574966967627724076630353547
5945713821785251664274274663919320030599
2181741359662904357290033429526059563073
81323286279434907632338298807531952510190
課題解答
まぁ、つまりは数値をどんどん読み込んでいって、10桁ずつ数値取り出して、
それらが素数かを判定するプログラムを書けということ。
なるほど。。。
いかに実際に作ったコードを記載する。
require "./assert_equal"
# 素数判定
def prime(n)
monitor = 1
# max = n-1 #実行時間遅い
max = Math::sqrt(n).to_i+1 # 実行時間早い
(2..max).each do |i|
if n%i == 0
break
end
monitor = i
end
return true if monitor == max
return false
end
# テキストの読み込み
def read_exp
exp1=gets.to_s.chomp
end
# Main
exp1 = read_exp()
for t in 2..191
last = t+10-1
num = exp1[t..last]
# puts num + "...実行中" # 動作確認用
if prime(num.to_i) == true
puts "\n\nanswer = " + num
break
end
end
これで完成、と言いたいところですが、、、
一応、class化もしてみました。
require "./assert_equal"
class Google
attr_accessor :exp
def initialize(exp="")
@exp = exp
@num = 0
end
def to_loop
len = @exp.length-2
for t in 2..(len-9)
last = t+9
@num = @exp[t..last].to_i
# puts @num.to_s + "...実行中" # 動作確認用
if to_prime == true
puts "\n\nanswer = " + @num.to_s
break
end
end
end
def to_prime
monitor = 1
# max = @num-1 #実行時間遅い
max = Math::sqrt(@num).to_i+1 # 実行時間早い
(2..max).each do |i|
if (@num)%i == 0
break
end
monitor = i
end
return true if monitor == max
return false
end
end
greeter = Google.new()
greeter.exp = gets.to_s.chomp
greeter.to_loop
作ってみたのはいいけど、なんか冗長になっている。。。
でもプログラムとしてはまとまった気もする。
以下に出力結果を載せます。
$ ruby Google_Recruit.rb < exp.txt
answer = 7427466391
$ ruby Google_Recruit_class.rb < exp.txt
answer = 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)=__________
引用:類題
解答編
まずは、これらの法則を見つけたい。。
何番目から始まっているかとか、これらの数字自体が数列になっていないかなど、
いろいろ調べましたが、 結果、足し算したら合計値が49になるということが判明しました。
というわけでプログラムです。↓↓
# テキストの読み込み
def read_exp
exp1=gets.to_s.chomp
end
# Main
exp1 = read_exp()
sum = 0
for start in 2..191
last = start+10-1
num = exp1[start..last]
if start == 2 then
for i in start..last
sum += exp1[i].to_i
end
else
sum -= exp1[start-1].to_i
sum += exp1[last].to_i
end
if sum == 49
puts num.to_s + ", " + sum.to_s
end
end
↓結果画面↓
$ ruby Google2.rb < exp.txt
7182818284
8182845904
8747135266
7427466391
5966290435
2952605956
工夫ポイントとしては、
次の10桁に移る際に、最初の数字を引いて、次の数字を足すだけにした というところです。
個人的には少し早くなったのではないだろうかと予測しています
参考
以下のサイトを参考にしました。
- source ~/grad_members_20f/members/Rooter-edi/qiita/Google_Recruit.org