2014年1月2日木曜日

Numerical Nirvana

Pythonなら、リスト内包のチカラで、すごく直感的に書けるのだが…。
import sys

def isHappy(n,closeset):
  if n==1:
    return True
  if n in closeset:
    return False
  closeset.add(n)
  n2=sum([int(x,10)**2 for x in str(n)])
  return isHappy(n2,closeset)

def run():
  n=int(sys.stdin.readline(),10)
  if isHappy(n,set()):
    print "Y"
  else:
    print "N"
  
for i in range(int(sys.stdin.readline())):
  run()

RubyだとMapとReduceを使うのかな…。ブロックを使うのかな…。
def is_happy(n,closeset)
  if n==1
    return true;
  end
  if closeset.include?(n)
    return false;
  end

  closeset << n
  #n2=n.to_s.map{ |x| x.to_i**2 }.reduce{ |i,j| i+j }
  n2=n.to_s.each_char.map{ |x| x.to_i**2 }.reduce{ |i,j| i+j }
  return is_happy(n2,closeset)
end

def run
  if is_happy(STDIN.gets.to_i,[])
    puts "Y"
  else
    puts "N"
  end
end

STDIN.gets.to_i.times { run }
コメントアウトしてあるけど、Ruby 1.8→1.9でStringがEnumerableじゃなくなったんだとか。なんでやねん。
Pythonが2→3で文字列をバイト列としているのと比較すると、なんかRubyはそれと逆行しているような感じがする。
  • String#each_byte, each_char → PythonのStringに近い。1文字1文字のenumerable。冗長にbyteやらcharやらあるところがRubyらしくて嫌い。
  • String#each_codepoint → Python3のbStringに近い。バイト列のenumerable

A happy number is defined by the following process: 

Given a number X, square each digit and sum the results. Repeat this procedure on the resulting sum until you either reach 1, or fall into a repeating cycle which does not include 1. When this process ends in 1, X is a happy number.

The first line of the input will be an integer N (1 <= N <= 100).

Each of the following N lines represents a single test case, containing an integer X (1 <= X <= 100000).
 
For each test case, print 'Y' if X is a happy number, and 'N' if not. No blank line between test cases.

Sample Input/Output
4
1
7
635
699
Y
Y
Y
N

0 件のコメント: