atcoder041のABCを解いた

いつもやってるatcoderの問題シリーズ。

今回は最新のabc041を解いてきた。

問題はこちら。

A問題の回答

s, i = STDIN.read.split(?\n)
i = i.to_i - 1
puts s[i]

改行コード区切りで縦に並んだ文字列をそれぞれ変数に入れる。
iという数字を整数の型にセットして、1引く。
文字列sのi番目を表示させる。

B問題の回答

A, B, C = STDIN.gets.split(" ").map(&:to_i)
X = A * B * C
Y = (10**9) + 7
puts X % Y

スペース区切りで変数にセットし、整数の型にセットする。
AとBとCを積算する。
Yは指定された数字10の9乗足す7を計算している。
そして最後にX割るYの余りを出している。

C問題の回答

N = STDIN.read.split("\n").map(&:to_s)
hash = {}
i = 1.to_i
N[1].split(/ /).each do | val |
  hash[i] = val.to_i
  i = i + 1
end
 
A = Hash[ hash.sort_by { | _, v | -v } ]
 
A.map { | key, value | puts key }

改行区切りで縦に変数に文字列としてセットする。
hashを宣言する。
iに1を整数としてセットする。
変数Nの2行目の値をスペース区切りで、hashにセットする。その際にkeyは整数で1から足していく。
hash.sort_byを使って、valueをsortする。※配列をソートすると、順番が変わるのでkeyを並べることはできない。結果は123のようになってしまう。
最後にhashのkeyだけを取り出している。

いつもこの手の文字列の変数セットに悩む。

S
A1,A2,A3... An

このような標準入力があって、Anを配列に入れたい場合はみなさんどうしているのだろうか。
上記方法以外になにかあるのだろうか。なんかこう1行目だけを無視して、2行目をいきなりhashに入れるみたいなことができないのだろうか。
私は分からずに、いつも一旦変数に入れて、string関数で抽出するようにしている。最近はこれが定着しつつあるけど正しいのかわからない。

来週のRubyの勉強会で聞いてみよう。
もし教えたくてムズムズした人がいたら是非教えてほしいです。

atcoder039のABCを解いた

こんにちは、いなむーです。

いつものatcoderシリーズです。

今回はいつもより問題が簡単だったため、初めてCまで解くことができました。

問題Aはこちら

そして書いたコードはこちら。

A,B,C = STDIN.gets.split(/ /).map {|v|v.to_i}
p 2 * ( A*B + A*C + B*C )

表面積の公式に当てはめただけです。
ただ、公式を思い出すのに苦労しましたがw

つぎに問題Bはこちら

そして書いたコードはこちら。

X = gets.to_i
 
(1..1000000000).each do | v |
  if (v ** 4) == X
    puts v
    exit
  end
end

この辺がプログラマーとの違いな気がします。このコードでは無駄にとにかく4乗になる値を回してるだけなので、きっともっと良い方法がありそうです。

そして問題Cはこちら

書いたコードはこちら。

K = "WBWBWWBWBWBW" * 3
 
arr1 = %w[ Do Re Mi Fa So La Si ]
arr2 = Array.new
 
(0..11).each do | v |
  if K[v,1] == "W"
    arr2 << K[v,20]
  end
end
 
X = arr1.zip(arr2)
S = gets.chomp
S2 = X.select { | v2 | v2[1]==S }
puts S2[0][0]

鍵盤で判断するための20文字が網羅できる数を変数に入れます。
つぎにドレミの値を配列にいれます。
次にドからシまでの間の文字数12鍵分、eachで回しながら取得する文字の位置を変えていき、一文字目がWだったら、その文字の位置から20文字取得して、arr2の配列にいれます。

そして、zipメソッドで配列に配列をいれます。
その配列の2つ目の要素が、標準入力と一緒だったら、1つ目の要素(音階)を表示させる。

これが流れです。

もはやClassとかにしていないし、結構雑になってしまったのでリファクタリングしたいですが、色々勉強になったので良かったです。

以上。

abc038のaとbを解いた

こんにちは、いなむーです。

毎度いつものatcoderです。

今回はabc038のaとbを解きました。
早速aの問題。

コードはこちら。

S = gets.chomp.to_s
puts S[-1] == 'T' ? 'YES' : 'NO'

ここでのポイントはStringメソッドを使用しているところです。
S[-1]とすることで最後から1文字目を抽出して、チェックしてます。

次にb問題。

問題はこちら。


巨大ディスプレイの話ですね笑
一瞬解像度かな?と思うのですが、1920mmとかでているので、1.92m幅のディスプレイを使っているようなので、会議でもするのでしょうか。

実際に書いたコードはこちら。

class ABC038b
  def setvar
    array = Array[]
    STDIN.read.each_line do | var |
      array << var
    end
    @H1, @W1 = array[0].split(' ').map { | v | v.to_i }
    @H2, @W2 = array[1].split(' ').map { | v | v.to_i }
  end
  def checkvar
    self.setvar
    if @H1 == @H2 or @H1 == @W2
      "YES"
    else
      if @W1 == @H2 or @W1 == @W2
        "YES"
      else
        "NO"
      end
    end
  end
end
 
x = ABC038b.new
puts x.checkvar

ここでのポイントはeach_lineを使用して、値を配列に入れている所です。
縦にも横にも値がある場合にどのように変数に入れれば良いのかがわからなかったので、とりあえず1行づつ取り出して、arrayの配列に保存。
その後、2行しかないので、それぞれを抽出して、変数にいれてます。

あとは変数にいれた値同士を比較して、YESかNOを返すようにしています。

この配列に入れた後で、それぞれを分割するなどしていく方法が一般的なのかわからなかったので、あとで会社のRubyistに聞いてみようと思いました。

以上。