2016-04-12 CodeJam 2016 Qualification B

B問題までは時間内に解いたので、書き残します。

B問題

問題内容

問題はこちら (https://code.google.com/codejam/contest/6254486/dashboard#s=p1)

  • 無限パンケーキ屋のバイトリーダーになったつもり
  • パンケーキの裏表を透視できる超能力を持っている
  • そしてパンケーキを上からN枚裏返すことができる
    • 上からN枚裏返すとき、(1,,,,N,,,L)が(N,N-1,,,,2,1,N+1,,,L)になることに注意
  • 上から順番の表裏を+-の入力値で表されるので、何回繰り返せば全部表にできるのか

(正確には英語を読みましょう)

回答のコード

#!env ruby

def flip_counter(string)
  count = 0
  before_char = '^'
  string.chars do |char|
    case before_char + char
    when '^-'
      count += 1
    when '+-'
      count += 2
    end
    before_char = char
  end
  count
end


case_num = STDIN.gets.strip

(1..case_num.to_i).each do |i|
  line = STDIN.gets.strip
  count = flip_counter(line)

  print "Case ##{i}: #{count}\n"
end

コーディングしたときに考えてたこと

  • とりあえず法則性があるはずなので少ない枚数で見つけてみる
    • 最初が表と裏で何か違いがあるのか
    • 最初の裏の数に依存するのか
    • など
  • 2枚の並びに依存することが判明
    • ^- → +1回
    • +- → +2回
    • それ以外は特にカウント不要
  • あとは文字列から上記の並びを探すのみ
  • これは法則性を見つけるかどうかの問題だった気がする

CodeJam 2016 Qualification A

2016年のCodeJamもQualificationは通ったので、どういう風に解いたかとかを記録してみる。

概要

  • 英語であることが日本人プログラマにとって一番つらいことなんだと思う
  • 5年半プログラマではなかったのですが、ここ1年でだいぶ勘が戻ってきたんだろうなぁって感じ
  • AとBを解いたけど、どちらも時間配分はこんな感じ
    • 英語を読むのに1時間(飽きて別のサイト見たりアニメ見たりもしながら)
    • 問題を解くのに20分程度
  • 去年とかはprint文の書き方とかも調べながらだったので、問題を解くのに2時間くらいかかった気がする

A問題

問題内容

問題文はこちら https://code.google.com/codejam/contest/6254486/dashboard

  • とりあえずCounting Sheepってタイトルで「羊が一匹、二匹、、」って寝るやつな感じのものを想像したが、あんまり関係なかった気がする
  • 初期値の数字から、それを2倍3倍していって、0〜9の数字を全部使えばOK
  • 0〜9までの数字が出てきたときに、初期値がどの数字まで増えたかが答え
  • 何倍にしても0〜9まで現れない場合は、答えに「INSOMNIA」って書く

(正確には英語を読みましょう)

回答のコード

  • こういうので初めてRubyを使ってみた
#!env ruby

def check(target)
  list = target.split("").uniq
  if list.count == 10
    return true
  else
    return false
  end
end

case_num = STDIN.gets

(1..case_num.to_i).each do |i|
  input_num = STDIN.gets.to_i

  if input_num == 0
    print "Case ##{i}: INSOMNIA\n"
    next
  end

  number = input_num
  target_string = input_num.to_s

  until check(target_string) do
    number += input_num
    target_string += number.to_s
  end

  print "Case ##{i}: #{number}\n"
end

コーディングしたときに考えてたこと

  • とりあえずINSOMNIAになるのは0だけか
    • 0は必ずINSOMNIAは自明
    • 奇数は10倍までで、少なくとも一の位だけでそろう
    • 5は20回あれば全部そろう
    • 偶数も何回か足せば、十の位以上に奇数が出てくるし、そんなに多くない数で全部そろいそうだ
  • Nは最大100万なので100回たしてもたかだか1億だから桁あふれとかは心配なさそう
  • ループの間、今まで使った数値をためてくところを作るのも面倒だし、数字を文字列としてどんどん連結しちゃえ
  • 文字列をチェックして、各文字の重複排除をすれば、10個の要素になったタイミングが答えか
  • 配列にuniqで重複排除できるのね、ruby便利だなぁ

以上

チェックボックスのvalidation

チェックボックスはONかOFFでないとならない。

この命題に対してvalidationを書ける方法は、「チェックボックス rails validates」でググっても出てこなかったので記録しておく。

答え

答えを見てしまえば簡単。

validates :checkbox, inclusion: { in: [true, false] }

うまくいかなかった方法

  1. 数値

    HTTP上は0か1が返ってきている(debug(params)でも0か1が表示されている)ことから以下のように書いたがダメだった。

    ruby validates :checkbox, inclusion: { in: [0, 1] }

  2. 文字

    リクエストパラメータは、'0'か'1'という文字なので以下のように書いたがダメだった。

    ruby validates :checkbox, inclusion: { in: ['0', '1'] }

わかったこと

  • Modelに記載するvalidatesは、modelの型に合わせる

DeviseのREADMEを翻訳してみた

Deviseを使ったら簡単に認証機能を追加できたのだけど、細かい調整の仕方がわからなかったので、勉強をかねて翻訳してみた。

qiita.com

知りたかったことでわかったこと

  • requestベースの結合試験で利用するためのメソッド(helper)は用意されていない
  • 複数のロールで認証機能を作成することは可能
  • ユーザ情報の追加のやり方
  • I18n
  • Viewのカスタマイズ方法

理解にもう少し時間がかかりそうなところ

  • メール送付の仕組みとやり方
  • Rails自体

Elastic BeanstalkにHello Worldするのに苦労した件

ちょっとがんばったので qiita に投稿してみた。

qiita.com

db:seedでテストデータを共有する

目的

開発者が各ローカル環境で開発を実施しているとき、テストデータを共有したいことがよくある。 マスタデータは、以下の記事で対応済みなので、これに合わせてseedを使って、同じデータを共有して開発を仮装させようという話。

gakkie.hatenablog.com

実施方法

seed.rb を以下のように記載する。

if Rails.env == 'development'
  CSV.foreach('db/csv/development/user.csv') do |row|
    User.create(:id => row[0], :name => row[1])
  end 
end

あとは、

  • db/csv/development/user.csv にテストユーザデータを配置する
  • rake db:reset を実行し、入れ替える

と完成。