○P 10分間コーディング2009/05/18

10分でコーディング(プログラミングに自信があるやつこい!!) viaときどきの雑記帖 i戦士篇

を見付けたので、特にこだわりなくrubyでコーディング

def deal(num_of_player, deck)
  cards = Array.new(num_of_player){""}
  deck.scan(/./).each_slice(num_of_player) do |slice|
    next if slice.size < num_of_player
    slice.each_with_index do |card, index|
      cards[index] << card
    end
  end
  cards
end

p deal(3, "123123123")
#=> ["111", "222", "333"]
p deal(4, "123123123")
#=> ["12", "23", "31", "12"]
p deal(6, "012345012345012345")
#=> ["000", "111", "222", "333", "444", "555"]
p deal(4, "111122223333")
#=> ["123", "123", "123", "123"]
p deal(1, "012345012345012345")
#=> ["012345012345012345"]
p deal(6, "01234")
#=> ["", "", "", "", "", ""]
p deal(2, "")
#=> ["", ""]

配列の転置の問題ですな。

末尾を捨てるのを忘れていたので5分ぐらいかかった。 精進が足りない。

あと、末尾を捨てるのは、breakする方が正しいね。

で、コード・カタ的に、他の実装にも思いを馳せてみることにする。

とは言え、あまり考える余地は無いような気もする。

  • 入力のdeckからArrayを得る方法
    • scan(/./) (↑で使った)
    • split(//) (これを別実装と呼ぶか?)
    • each_byte (普通に使うならblockの中に後の処理を入れる必要がある。each にaliasするか、1.9を使う)
    • unpack("C*") (Arrayの中身はInteger)
  • Arrayの転置
    • sliceを作ってそこでindexを取って配る (↑)
    • 全体で回して随時modを取って配る
  • 末尾の処理
    • 事前に数を揃えておく
    • 残数が足りなくなったら終わる (↑)

の組み合わせぐらいだろうか?

で色々考えてみたけど、

上記のバリエーション

def deal(num_of_player, deck)
  class << deck
    alias each each_byte
  end
  cards = Array.new(num_of_player){""}
  deck.each_slice(num_of_player) do |slice|
    break if slice.size < num_of_player
    slice.each_with_index do |card, index|
      cards[index] << card
    end
  end
  cards
end
def deal(num_of_player, deck)
  cards = Array.new(num_of_player){""}
  deck.unpack("C*").each_slice(num_of_player) do |slice|
    break if slice.size < num_of_player
    slice.each_with_index do |card, index|
      cards[index] << card.chr
    end
  end
  cards
end
def deal(num_of_player, deck)
  cards = Array.new(num_of_player){[]}
  deck.unpack("C*").each_slice(num_of_player) do |slice|
    break if slice.size < num_of_player
    slice.each_with_index do |card, index|
      cards[index] << card
    end
  end
  cards.map{|card| card.pack("C*")}
end

引数Deckに対するindexを取り回す

def deal(num_of_player, deck)
  num_of_card = deck.size / num_of_player
  deck = deck[0, num_of_card * num_of_player]
  cards = Array.new(num_of_player){""}
  class << deck
    alias each each_byte
  end
  deck.each_with_index do |card, index|
    cards[index % num_of_player] << card
  end
  cards
end

出力用のArrayを仮り組みしてそこでindexを回す

def deal(num_of_player, deck)
  num_of_card = deck.size / num_of_player
  Array.new(num_of_player) do |i|
    (0...num_of_card).map{|j| deck[i + j * num_of_player, 1]}.join
  end
end
def deal(num_of_player, deck)
  num_of_card = deck.size / num_of_player
  Array.new(num_of_player){" " * num_of_card}.each_with_index do |cards, i|
    cards.gsub!(/./){deck[i + $`.size * num_of_player, 1]}
  end
end
def deal(num_of_player, deck)
  num_of_card = deck.size / num_of_player
  Array.new(num_of_player){[*(0...num_of_card)] * ""}.each_with_index do |cards, i|
    cards.gsub!(/./){|j| deck[i + j.to_i * num_of_player, 1]}
  end
end

ぐらいしか思いつかなかった。

Golf

def deal(num_of_player, deck)
  num_of_card = deck.size / num_of_player
  Array.new(num_of_player) do |i|
    (0...num_of_card).map{|j| deck[i + j * num_of_player, 1]}.join
  end
end

これを

def deal(n,d)(0...n).map{|i|(0...d.size/n).map{|j|d[i+j*n,1]}*""};end

ぐらいにして、このお題は終了。

コメント

コメントをどうぞ

※メールアドレスとURLの入力は必須ではありません。 入力されたメールアドレスは記事に反映されず、ブログの管理者のみが参照できます。

※なお、送られたコメントはブログの管理者が確認するまで公開されません。

名前:
メールアドレス:
URL:
コメント:

トラックバック

このエントリのトラックバックURL: http://dragonstar.asablo.jp/blog/2009/05/18/4311040/tb

※なお、送られたトラックバックはブログの管理者が確認するまで公開されません。