11
1

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 3 years have passed since last update.

RubyでGoogleの問題を解く

Last updated at Posted at 2020-12-16

Googleの問題を解く

問題

「e(自然対数の底)の値で連続する10桁の数のうち、最初の素数」を求める。

  • 素数判定

回答

def getNums()
  line = readlines
  len = line.length
  num = ''

  (0..len-1).each do |i|
    num = num + line[i].chomp
  end

  return num
end

def prime?(num)
  (2..Math.sqrt(num).to_i).each do |i|
    if(num%i == 0)
      return false
    end
  end
  return true
end

digits = 10

if $PROGRAM_NAME == __FILE__
  num = getNums().delete('.')
  res = 0

  (0..num.length-digits).each do |i|
    res = num[i, digits].to_i
    prime?(res) ? break : next 
  end

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

解説

  • 問題が、外部ファイルに記述された e の数字を入力としていたので getNums() で複数行の入力を結合するようになっています。が、まぁそこは気にせずに、数値の標準入力を受け取ります。

prime? の実装

require 'prime' によって Prime.prime?(n) が利用でき、高速に素数判定できますが面白く無いので今回は利用しません。自力で prime? を実装します。

def prime?(num)
  (2..Math.sqrt(num).to_i).each do |i|
    if(num%i == 0)
      return false
    end
  end
  return true
end

短っ!いや、もっと高速にするなら 偶数は弾く とかもあるけど、とりあえずこれでいいや。

  • 理論的には、自分より低い数字で割り切れるかを見て、 true or false を出力しているだけ。

(2..Math.sqrt(num).to_i).each do |i|

(2..Math.sqrt(num).to_i).each do |i| ここが重要な部分です。
(2..num).each do |i| とするのが理論的ですが、これだと桁が多いときに処理が終わりません。いや、終わるけど時間がかかりすぎます。

Math.sqrt(num).to_i までの演算でいい理由

合成数(素数とは逆の意味) に関する性質$x$ が合成数ならば $\sqrt{x}$ 以下の約数を持つ
を利用しています。ですので、 num が合成数(=素数でない)なら

(2..Math.sqrt(num).to_i).each do |i|
  if(num%i == 0)
    return false
  end
end

ここで引っかかって false を返します。逆に、ここをすり抜けた num は合成数でない(=素数)ので、 true を返します。

実行結果

  • テキストファイルに e の値を記述します。
2.71828182845904523536028747135266249775
7247093699959574966967627724076630353547
5945713821785251664274274663919320030599
2181741359662904357290033429526059563073
81323286279434907632338298807531952510190

これをプログラムに渡してあげます。

$ ruby google_recruit.rb < in.txt
e(自然対数の底)の値で連続する10桁の数のうち, 最初の素数は7427466391

答えは 7427466391 である!

発展課題!?

この問題には続きというか、この問題の回答者だけに次の問題が用意されていたらしい。それが次の問題。

f(1)=7182818284
f(2)=8182845904
f(3)=8747135266
f(4)=7427466391
f(5)=__________

なるほどー。規則性を見つけるやつ。そして f(1)=7182818284 に見覚えがあった。
上の問題の e にこの数字あったやん
f(2)=8182845904 これもあるやん。

解く

規則性を見つけましょう。

何桁目にあるか

小数第何位〜何位にその数が現れているかを探しましょう。

def getNums()
  line = readlines
  len = line.length
  num = ''

  (0..len-1).each do |i|
    num = num + line[i].chomp
  end

  return num
end

if $PROGRAM_NAME == __FILE__
  num = getNums().delete('.')

  ["7182818284", "8182845904", "8747135266", "7427466391"].each do |i|
    pos = num.index(i)
    puts "#{i} -> #{pos} ~ #{pos+(10-1)}"
  end
end

こんなん作って

$ ruby google_recruit_find.rb < google_recruit_in.txt
7182818284 -> 1 ~ 10
8182845904 -> 5 ~ 14
8747135266 -> 23 ~ 32
7427466391 -> 99 ~ 108

さっぱりわからん。笑

テレビのクイズ問題にあるやつやろ

こういうのは大体、足したらいいねん

def getNums()
  line = readlines
  len = line.length
  num = ''

  (0..len-1).each do |i|
    num = num + line[i].chomp
  end

  return num
end

if $PROGRAM_NAME == __FILE__
  num = getNums().delete('.')

  ["7182818284", "8182845904", "8747135266", "7427466391"].each do |n|
    sum = 0
    (0..9).each do |i|
      sum += n[i].to_i
    end
    puts "#{n} -> #{sum}"
  end
end

こんなん作って

$ ruby google_recruit_sum.rb < google_recruit_in.txt
7182818284 -> 49
8182845904 -> 49
8747135266 -> 49
7427466391 -> 49

天才かもしれん (テレビの見過ぎ)
各桁の合計(10桁分)が49になる数字を e から探して5番目が答え。

回答

Ruby でこれを探すプログラムを書いて、回答を得る。

def getNums()
  line = readlines
  len = line.length
  num = ''

  (0..len-1).each do |i|
    num = num + line[i].chomp
  end

  return num
end

digits = 10

if $PROGRAM_NAME == __FILE__
  e = getNums().delete('.')
  num = 0
  (1..e.length-digits).each do |i|
    sum = 0
    (0..digits-1).each do |j|
      sum += e[i, digits][j].to_i
      break if sum > 49
    end
    puts "f(#{num = num.succ})=#{e[i, digits]}" if sum == 49
  end
end

こんな感じ??

$ ruby google_recruit2.rb < google_recruit_in.txt
f(1)=7182818284
f(2)=8182845904
f(3)=8747135266
f(4)=7427466391
f(5)=5966290435
f(6)=2952605956

答えは 5966290435 である!


11
1
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
11
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?