LoginSignup
2
1

More than 3 years have passed since last update.

Ruby で 繰返し二乗法 を解くなら Integer#pow がお薦め

Posted at

はじめに

AtCoder Problems の Recommendation を利用して、過去の問題を解いています。
AtCoder さん、AtCoder Problems さん、ありがとうございます。

事の始まり

Ruby と Perl と Java と Python で解く AtCoder ATC 002 B 繰返し二乗法 でコメントをいただきました。

Ruby だと専用メソッド Integer#pow がありますね。

早速試しました。

AtCoder Typical Contest 002 B - n^p mod m

pow.rb
n, m, p = gets.split.map(&:to_i)
puts n.pow(p, m)
zisaku.rb
n, m, p = gets.split.map(&:to_i)
def mpow(n, p, mod)
  r = 1
  while p > 0
    r = r * n % mod if p % 2 == 1
    n = n * n % mod
    p >>= 1
  end
  r
end
puts mpow(n, p, m)
Integer#pow 自作mpow
コード長 (Byte) 50 183
実行時間 (ms) 68 62
メモリ (KB) 14356 14356

AtCoder Regular Contest 066 C - Lining Up

pow.rb
n = gets.to_i
a = gets.split.map(&:to_i)
h = Hash.new(0)
a.each do |x|
  h[x] += 1
end
f = true
h.each do |k, v|
  if n.odd? && k == 0
    if v != 1
      f = false
      break
    end
  elsif v != 2
    f = false
    break
  end
end
MOD = 1_000_000_007
puts (f ? 2.pow(n / 2, MOD) : 0)
Integer#pow 自作mpow
コード長 (Byte) 305 438
実行時間 (ms) 101 100
メモリ (KB) 22676 22488

エイシング プログラミング コンテスト 2020

pow.rb
n = gets.to_i
x = gets.chomp
xs = x.to_i(2)
xc = x.count('1')
def mpow(n, p, mod)
  return 0 if mod.zero?
  n.pow(p, mod)
end
def popcount(u)
  return 0 if u.zero?
  a = u % u.to_s(2).count('1')
  1 + popcount(a)
end
xsp = mpow(xs, 1, xc + 1)
xsm = mpow(xs, 1, xc - 1)
n.times do |i|
  if x[i] == '0'
    y = xsp + mpow(2, n - i - 1, xc + 1)
    y = mpow(y, 1, xc + 1)
  elsif xc == 1
    puts '0'
    next
  else
    y = xsm - mpow(2, n - i - 1, xc - 1)
    y = mpow(y, 1, xc - 1)
  end
  puts popcount(y) + 1
end
Integer#pow 自作mpow
コード長 (Byte) 541 629
実行時間 (ms) 421 625
メモリ (KB) 14704 15392

いずれも同等以上の成績でした。
rubyの時代が来ましたね。

まとめ

  • Integer#pow を使おう
  • Ruby の時代が来た

参照したサイト
instance method Integer#**
Ruby と Perl と Java と Python で解く AtCoder ATC 002 B 繰返し二乗法
Ruby と Python で解く AtCoder ARC 059 C 最小二乗法
Ruby と Python で解く AtCoder AISING2020 D 繰返し二乗法

2
1
5

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