トランスパイラで学ぶRuby

# はじめに
以前におバカな投稿をしたことがあります。
*[Ruby と Crystal で解く AtCoder ABC 129 D](https://qiita.com/superrino130/items/ad53e6a36cee2a3efe0c)*

今回は、ちょっとだけマジメです。
# Py2Ruby
`Ruby`で競技プログラミングをやっていて困るのが、Qiitaをはじめ投稿が少なく参考できないことです。

でももう安心。
素敵なサイトがあります。
*[Py2Ruby](https://www.py2ruby.com/)*
*[Py2Ruby: Convert Python Code to Ruby Instantly! -- youtube](https://www.youtube.com/watch?v=DXiKAEBdDBg)*
# やってみた
参考にさせてもらっている @u2dayo さんの解答をお借ります。
*[【AtCoder解説】PythonでABC225のA,B,C,D問題を制する！](https://qiita.com/u2dayo/items/bf500b82edac4441d9f3)*
# [A問題『Distinct Strings』](https://qiita.com/u2dayo/items/bf500b82edac4441d9f3#a%E5%95%8F%E9%A1%8Cdistinct-strings)
![20211104a.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/538241/050f2d1a-200a-5f88-4731-736b70e5e1bb.png)
左が @u2dayo さんの解答で、右がトランスパイラされた解答。

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

if N == 1 
    p(1)
elsif N == 2 
    p(3)
else
    p(6)
end
```
`require`が必要なので敷居が高くなりましたが、動作するコードは次の通り。

```Ruby
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』](https://qiita.com/u2dayo/items/bf500b82edac4441d9f3#b%E5%95%8F%E9%A1%8Cstar-or-not)
```Ruby
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")
```
辛くなってきました

```Ruby
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』](https://qiita.com/u2dayo/items/bf500b82edac4441d9f3#c%E5%95%8F%E9%A1%8Ccalendar-validator)

```Ruby
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")
```
入出力の部分はダメですが、メソッド部分はそのまま使えます。

```Ruby
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』](https://qiita.com/u2dayo/items/bf500b82edac4441d9f3#d%E5%95%8F%E9%A1%8Cplay-train)

```Ruby
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`はするようです。

```Ruby
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 さんには期待しております