https://abc096.contest.atcoder.jp/tasks/abc096_d

出力

  • AGC001以降のAtCoderでは、区切りは空白区切り改行区切りのどちらでも構いません(trailing spaceも可)。
  • よってputs arr*' 'puts arr、ひいてはp *arrでokです。以下では後者を使います。

解法

  • 5で割ってあまりが1になる整数の集合から5個選んだ合計は5で割り切れます。
  • 素数を列挙していき、1の位が1であるものをN個拾えば良いです。
    • 実際には1の位は(統一していれば)1,3,7,9のいずれも大丈夫です。以下の答案では9を採用しています。
    • 64bytes
1
require'prime';p *Prime.each(1499).select{|e|e%5>3}[0,gets.to_i]
  • 1の位がX(奇数、以下の答案では3)である整数を全て列挙し、素数をN個拾うようにすると以下のようになります。
  • 62bytes
1
require'prime';p *3.step(1499,5).select(&:prime?)[0,gets.to_i]

フェルマーテスト

  • require'prime'をカットすることで字数の節約にはなりますが、Integer#prime?は使えなくなるので、別の素数判定が必要になります。そこで、フェルマーテストを用います。
  • [1]に載っている式、2**i%i==2を使います。なおこの素数判定の場合stepの初期値を1にすることはできなくなるので注意してください(3,7,9は可)。
  • 51bytes
1
p *3.step(1499,5).select{|i|2**i%i==2}[0,gets.to_i]

redo

  • [2]では、ループカウンタをインクリメントしないよう、条件を満たさない場合はredoを使っています。これはPerlだけでなくRubyでも有用なテクニックです。
  • https://abc096.contest.atcoder.jp/submissions/2470406 (最終答案)
  • 46bytes
1
i=3;gets.to_i.times{i+=5;2**i%i==2?(p i):redo}

discussion

  • フェルマーテストやredoの実践例を挙げることができました。どちらもゴルフには有用であると思われます。

reference

  1. cojnaさん https://abc096.contest.atcoder.jp/submissions/2465874
  2. %20さん https://abc096.contest.atcoder.jp/submissions/2467541