Project Euler 41ãé«éãªç´ æ°å¤å®
Pandigitalãªæ°ãä½ããããã1ã¤ãã¤ç´ æ°å¤å®ããæ¹æ³ã§æ±ãã¾ãããï¼ã¾ããç´ ç´ã§æç´ãªæ¹æ³ã§ãï¼
ä»ã¾ã§ç´ æ°å¤å®ã«ã¤ãã¦ãã¨ã©ãã¹ããã¹ã®ç¯©ã§æ±ããç´ æ°ã«å«ã¾ãã¦ãããï¼ã¨ããææãæ¹æ³ã§å®è£ ãã¦ãã¾ããããæµç³ã«é度ããã¾ãããªããªã£ãã®ã§é«éãªç´ æ°å¤å®ã¢ã«ã´ãªãºã ã調ã¹ããã¨ã«ãã¾ããã
ã¡ãªã¿ã«ã¨ã©ãã¹ããã¹ã®ç¯©ã§ç¾å®çã«ç´ æ°å¤å®ã§ããã®ã¯ãRubyã§ã¯100ä¸ã¾ã§ã§ããã1000ä¸ã¬ãã«ã¯ããã¶ãããªãããã¤ã1åè¿ãããã£ã¦ãã¾ãã¾ããä»åã¯9æ¡ãªã®ã§ã¨ã©ãã¹ããã¹ã®ç¯©ã§ã¯ç¡çã§ãã
ã¨ãããã¨ã§ã調ã¹ãçµæå©ç¨ãããã¨ã«ããã®ãããã©ã¼ã»ã©ãã³ç´ æ°å¤å®æ³ãã
ã¨ã¯ãããã®ã®ãçµå±ã¢ã«ã´ãªãºã ã¯ç解ã§ãããã½ã¼ã¹ã³ã¼ãã¯ãããã«ãããã®ããã®ã¾ã¾æµç¨ããæãã«ãªã£ã¦ãã¾ãã¾ããããã
ãã£ã±ãæ°å¦ã¯é£ããã§ã¤ã ã¤Ð`)
ã¨ãããã¨ã§åèã«ããã¦ããã ãããµã¤ãã¯ãã¡ãã
- http://d.hatena.ne.jp/pashango_p/20090704/1246692091
- http://www.weblio.jp/wkpja/content/%E3%83%9F%E3%83%A9%E3%83%BC-%E3%83%A9%E3%83%93%E3%83%B3%E7%B4%A0%E6%95%B0%E5%88%A4%E5%AE%9A%E6%B3%95_%E3%82%B3%E3%83%BC%E3%83%89%E4%BE%8B
Pythonã«ã¯ pow(a,b,c) ã¨ãããa^b mod c ãæ±ããã¡ã½ãããæ¨æºã«ç¨æããã¦ãã¦ãããããããæ©ãããããããã¢ã³ã´ã¡ãªä¹ç®ããCè¨èªã§å®è£
ããã¦ããã®ã§ã¯ãªããã¨ã®ãã¨ã
Ruby ã«ã¯ãã®ãããªã¡ã½ããã¯æ¨æºã§ã¯ç¨æããã¦ããããèªä½ããããå¾ããçµå±ããã©ã¼ã»ã©ãã³ç´ æ°å¤å®æ³ãã¯Pythonã®æ¹ãå§åçã«æ©ãã¨ããçµæã«ãªã£ã¦ãã¾ãã¾ãããï¼ç®æ¸¬ï¼åï¼
ã¨ãããã¨ã§ä»åç¨æããç´ æ°å¤å®ã¡ã½ããã¯ãã¡ãã
module ModMath def self.pow(base, power, mod) result = 1 while power > 0 result = (result * base) % mod if power & 1 == 1 base = (base * base) % mod power >>= 1 end result end def self.is_prime(q, k=50) q = q.abs return true if q == 2 return false if q < 2 || q&1 == 0 d = (q-1)>>1 while d&1 == 0 do d >>= 1 end k.times do a = rand(q-2) + 1 t = d y = ModMath.pow(a, t, q) while t != q-1 && y != 1 && y != q-1 do y = ModMath.pow(y, 2, q) t <<= 1 end return false if y != q-1 && t&1 == 0 end return true end end
ããã¦Problem41ã®ã³ã¼ãã¯ããã§ããï¼ã¡ãã¼é©å½ã§ãï¼
def problem41 def getmaxprime(aryall) maxprime = -1 firstlist = aryall.dup firstlist.delete_if {|t| t!=3 && t!=7 && t!=9} firstlist.each do |first| aryalldup = aryall.dup aryalldup.delete_if {|t| t == first} permutation(aryalldup).each do |pand| num = digits_to_num([first] + pand) if ModMath.is_prime(num) p num maxprime = (maxprime < num) ? num : maxprime end end end maxprime end maxprime = -1 maxprime = getmaxprime([1,2,3,4,5,6,7,8,9]) if maxprime < 0 maxprime = getmaxprime([1,2,3,4,5,6,7,8]) if maxprime < 0 maxprime = getmaxprime([1,2,3,4,5,6,7]) if maxprime < 0 maxprime = getmaxprime([1,2,3,4,5,6]) if maxprime < 0 maxprime = getmaxprime([1,2,3,4,5]) if maxprime < 0 maxprime = getmaxprime([1,2,3,4]) if maxprime < 0 maxprime end
ããããããã°é åãä½ãã¡ã½ãããèªä½ãã¦ããã ã£ãããã¨ãåæ¡ã並ã¹ãæ°åãæ°åã«æ»ãã¡ã½ãããã
def permutation(ary) return [ary] if ary.size == 1 res = [] (0..ary.size-1).each do |t| arydup = ary.dup arydup.delete_at(t) permutation(arydup).each do |subary| res << [ary[t]] + subary end end res end def digits_to_num(dig) num = 0 t = 0 while dig.size > t num += dig[t] * 10**t t += 1 end return num end
9æ¡ã®Pandigitalæ°ã®ç´ æ°å¤å®ã« 16.8125s ãããã£ã¦ãããæçµçã«ããã°ã©ã ãçµããã®ã 19.25s ã¨çµæ§æéããããã
ã¾ããProject Euler ã® "one-minute rule" ã¯æºããã¦ãããããããã©ããã¶ããã£ã¨æ©ãã¢ã«ã´ãªãºã ã¯ãããã ãããªã