0
0

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

Posted at

はじめに

以前におバカな投稿をしたことがあります。
Ruby と Crystal で解く AtCoder ABC 129 D

今回は、ちょっとだけマジメです。

Py2Ruby

Rubyで競技プログラミングをやっていて困るのが、Qiitaをはじめ投稿が少なく参考できないことです。

でももう安心。
素敵なサイトがあります。
Py2Ruby
Py2Ruby: Convert Python Code to Ruby Instantly! -- youtube

やってみた

参考にさせてもらっている @u2dayo さんの解答をお借ります。
【AtCoder解説】PythonでABC225のA,B,C,D問題を制する!

A問題『Distinct Strings』

20211104a.png
左が @u2dayo さんの解答で、右がトランスパイラされた解答。

S = gets.chomp
N = set(S).length()

if N == 1 
    p(1)
elsif N == 2 
    p(3)
else
    p(6)
end

requireが必要なので敷居が高くなりましたが、動作するコードは次の通り。

require 'set'
S = gets.chomp.chars
N = Set.new(S).length()

if N == 1 
    p(1)
elsif N == 2 
    p(3)
else
    p(6)
end

putsではなくpなのが気になりますが、なんとなく理解できるような。

B問題『Star or Not』

N = gets.chomp.to_i
counter = [0] * (N + 1)

for _ in (0..N - 1-1) 
    a, b = map(int, gets.chomp.split())
    counter[a] += 1
    counter[b] += 1
end

puts("Yes" if N - 1 in counter else "No")

辛くなってきました

N = gets.chomp.to_i
counter = [0] * (N + 1)

for _ in (0..N - 1-1) 
    a, b = gets.split.map(&:to_i)
    counter[a] += 1
    counter[b] += 1
end

puts counter.include?(N - 1) ? "Yes" : "No"

入出力と三項演算子が。

C問題『Calendar Validator』

def judge() 
  for col in (0..M-1) 
      if B[0][col] % 7 == 0 && col != M - 1 
          return false
      end
  end
  
  for row in (0..N-1) 
      for col in (0..M - 1-1) 
          if B[row][col] + 1 != B[row][col + 1] 
              return false
          end
      end
  end
  
  for row in (0..N - 1-1) 
      for col in (0..M-1) 
          if B[row][col] + 7 != B[row + 1][col] 
              return false
          end
      end
  end
  return true
end


N, M = map(int, gets.chomp.split())
B = []
for _ in (0..N-1) 
  _b = [map(int, gets.chomp.split())].chars()
  B.push(_b)
end

puts("Yes" if judge() else "No")

入出力の部分はダメですが、メソッド部分はそのまま使えます。

def judge() 
  for col in (0..M-1) 
      if B[0][col] % 7 == 0 && col != M - 1 
          return false
      end
  end
  
  for row in (0..N-1) 
      for col in (0..M - 1-1) 
          if B[row][col] + 1 != B[row][col + 1] 
              return false
          end
      end
  end
  
  for row in (0..N - 1-1) 
      for col in (0..M-1) 
          if B[row][col] + 7 != B[row + 1][col] 
              return false
          end
      end
  end
  return true
end


N, M = gets.split.map(&:to_i)
B = []
for _ in (0..N-1) 
  _b = gets.split.map(&:to_i)
  B.push(_b)
end

puts judge() ? "Yes" : "No"

D問題『Play Train』

def main() 
    N, Q = map(int, gets.chomp.split())
    _next = [-1] * (N + 1)  # すぐ後ろの電車の番号
    _prev = [-1] * (N + 1)  # すぐ前の電車の番号
    
    for _ in (0..Q-1) 
        query = [map(int, gets.chomp.split())].chars()
        q = query[0]
        if q == 1 
            x, y = query[1...]
            _next[x] = y  # xの後ろにyがくる
            _prev[y] = x  # yの前にxがくる
        elsif q == 2 
            x, y = query[1...]
            _next[x] = -1  # xが新しい最後尾
            _prev[y] = -1  # yが新しい先頭
        else
            x = query[1]
            ans = []
            
            curr = x
            
            # まず電車を先頭までたどります
            while _prev[curr] != -1 
                curr = _prev[curr]
            end
            
            # 先頭から最後尾までたどっていきます
            while curr != -1 
                ans.push(curr)
                curr = _next[curr]
            end
            
            p(ans.length(), *ans)  # 連結成分の大きさも出力することに注意
        end
    end
end


if __name__ == '__main__' 
    main()
end

少しの手直しでACはするようです。

def main() 
  nn, qq = gets.split.map(&:to_i)
  _next = [-1] * (nn + 1)  # すぐ後ろの電車の番号
  _prev = [-1] * (nn + 1)  # すぐ前の電車の番号
  
  for _ in (0..qq-1) 
      query = gets.split.map(&:to_i)
      q = query[0]
      if q == 1 
          x, y = query[1...]
          _next[x] = y  # xの後ろにyがくる
          _prev[y] = x  # yの前にxがくる
      elsif q == 2 
          x, y = query[1...]
          _next[x] = -1  # xが新しい最後尾
          _prev[y] = -1  # yが新しい先頭
      else
          x = query[1]
          ans = []
          
          curr = x
          
          # まず電車を先頭までたどります
          while _prev[curr] != -1 
              curr = _prev[curr]
          end
          
          # 先頭から最後尾までたどっていきます
          while curr != -1 
              ans.push(curr)
              curr = _next[curr]
          end
          
          puts(([ans.length()] + ans).join(" "))  # 連結成分の大きさも出力することに注意
      end
  end
end

main()

まとめ

  • @u2dayo さんにはお世話になっております
  • Py2Ruby さんには期待しております
0
0
0

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
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?