技術メモ

主にRuby関連

Easy編 Pick up

ブログに対してもメールが来たら削除します。メモっておきたいんだけどなぁ

'Fizz Buzz' - http://www.codeeval.com/open_browse/1

定番のFizzBuzz
ARGF.lines.each do |line| 
  fizz, buzz, limit = line.scan(/\d+/).map(&:to_i)
  puts 1.upto(limit).map { |n| "#{?F[n%fizz]}#{?B[n%buzz]}"[/.+/] || n } * " "
end

'Sum of Primes' - http://www.codeeval.com/browse/4

Prime使って反則気味
require "prime"
puts Prime.take(1000).inject(:+)

'Bit Positions' - http://www.codeeval.com/browse/19

『Integer#pred』を#prevと間違えないようにメモ
ARGF.lines.each do |line| 
  n, *p = line.scan(/\d+/).map(&:to_i)
  p1, p2 = p.map(&:pred).map(&n.method(:[]))
  puts p1 == p2
end

'Fibonacci Series' - http://www.codeeval.com/browse/22

定番フィボナッチ
ARGF.lines.each do |line| 

  n = line.to_i
  cache = { 0 => 0, 1 => 1}

  fib = -> { _fib_ = -> n { cache[n] ||= _fib_[n-2] + _fib_[n-1] } }.call
  
  puts fib[n]

  # fib = -> f, n { cache[n] ||= f[n-2] + f[n-1] }.curry
  # z = -> f {
  #   -> g { -> m { f[g[g]][m] }
  #     }[ -> g { -> m { f[g[g]][m] } } ]
  # }
  # 
  # puts z[fib][n]

end

'Multiplication Tables' - http://www.codeeval.com/browse/23

Array#product,Enumerable#each_sliceあるよ
n = 12
a = [*1..n]
a.product(a).map { |x, y| x * y }.each_slice(n) do |row|
  puts ("#{["%4d"]*n*""}" % row).strip
end

'Unique Elements' - http://www.codeeval.com/browse/29

Array#uniq使わずにEnumerable#chunkで
ARGF.lines.each do |line| 
  puts line.scan(/\d+/).chunk(&:to_i).map(&:first) * ","
end

'Rightmost Char' - http://www.codeeval.com/browse/31

String#index初めて使ったかも
ARGF.lines.each do |line| 
  str, c = line.chomp.split(/,/)
  puts str.index(c) || -1
end

'Happy Numbers' - http://www.codeeval.com/browse/39

終了条件不足&凡ミスで一発で100点とれなかった。こういうの知らなかった。
sosq = -> e { 
  @@terms[e] ||= 0
  e.to_s.scan(/\d/).map { |e| e.to_i ** 2 }.inject(:+)
}

func = -> { 
  _f = -> e { @@terms[e] || _f[sosq[e] ] } 
}.call

ARGF.lines.each do |line| 
  @@terms = { 0 => 0, 1 => 1, }
  puts func[line.to_i]
end 

'Self Describing Numbers' - http://www.codeeval.com/browse/40

知らなかったので。
ARGF.lines.each do |line| 
  
  digits = line.scan(/\d/).map(&:to_i)
  
  descs = Hash.new(0).tap { |descs| 
    digits.each { |d| descs[d] += 1 }      
  }.values_at(*digits.size.times.to_a)
  
  puts digits == descs ? 1 : 0
  
end