# Ruby 1.8에서 테스트
# shoemaker 문제

# 2개의 일을 놓고 비교한다면 (1번 작업날짜 * 2번 벌금)금액과
# (2번 작업 날짜 * 1번 벌금)금액을 비교해 봐서 적은쪽을 먼저 한다
# 이렇게 전체작업을 끝까지 정렬하면은 저 순서대로
# 정렬되어 있게 된다

class Job

  def initialize(job_num, day, fine)
    @job_num = job_num
    @day = day
    @fine = fine
  end

  attr_reader :job_num, :day, :fine

  def <=>(obj)
    return (self.day * obj.fine <=> self.fine * obj.day)
  end

end


def shoemaker(jobs)
  return (jobs.sort).map! {|x| x = x.job_num}
end

require 'test/unit'

class TestShoemaker < Test::Unit::TestCase

  def test_method
    ans = [2, 1, 3, 4]
    input = [Job.new(1, 3, 4), Job.new(2, 1, 1000), Job.new(3, 2, 2), Job.new(4, 5, 5)]

    assert_equal(ans, shoemaker(input))
  end

end
크리에이티브 커먼즈 라이선스
Creative Commons License
Posted by sloth_chord
# Ruby 1.8에서테스트
# 타이핑 할때 키보드에서 손의 위치가 원래위치보다 한칸 오른쪽옆에 가면
# 'Q'는 'W', 'J'는 'K'같은 식으로 잘못 입력되는데 이런 실수를 바로잡기다
# 입력은 숫자, 스페이스, 대문자, 구두기호(`는 제외임)
# 가 들어갈수있다.  
# ('Q', 'A', 'Z'는 제외이다)
# 이 입력을 바로 왼쪽에 있는 키로 바꿔야 함

def adjust(key_ch)

  # 일단 키보드에 각 열에 글자들을 저장해놓구
  key_lines = [ "`1234567890-=", "QWERTYUIOP[]",
                "ASDFGHJKL;'", "ZXCVBNM,./" ]

  # key_lines에 있는 문자며
  # 젤 왼쪽 문자가아니라면은 한칸 옆문자를 리턴


  key_lines.each {|line| idx = line.index(key_ch)
                        (return line[idx - 1].chr) if ( (idx != nil) and (idx > 0) )}

  # 아니면 원래 입력한 글자를리턴을함

  return key_ch

end

def qwerty(str)
  (str.length).times do |i| str[i] = adjust(str[i]) end
  return str
end


require 'test/unit'

class TestQWERTY < Test::Unit::TestCase

  def test_empty_str
    assert_equal('', qwerty(''))
  end

  def test_one_char
    assert_equal('A', qwerty('S'))
  end

  def test_one_line
    assert_equal("I AM FINE TODAY.", qwerty("O S, GOMR YPFSU/"))
  end

  def test_two_lines
    assert_equal("I AM FINE TODAY.\nI AM FINE TODAY.",
                 qwerty("O S, GOMR YPFSU/\nO S, GOMR YPFSU/"))
  end

end
크리에이티브 커먼즈 라이선스
Creative Commons License
Posted by sloth_chord
# Ruby 1.8에서테스트

def max(i, j)
  return (i >= j) ? i : j
end

def min(i, j)
  return (i <= j) ? i : j
end

def calcul_next(n)
  return (n % 2 == 0) ? (n / 2) : (3 * n + 1)
end

def cycle_of_n(n, tab)

  cycle = 1

  # 규칙에 따라 n이 1이 아닌동안 루프를 실행하는데
  # tab[n] > 0 이라는건 그 전에 n의 싸이클 길이를 계산한적이 있단말임
  # 다시 계산할 필요없이 cycle + tab[n] - 1을 리턴하구,
  # 아니면 n의 값을 규칙에 따라 계속 계산하면서 cycle도 증가한다

  while n != 1
    (tab[n] > 0) ? (return cycle + tab[n] - 1) : (n = calcul_next(n); cycle += 1)
  end

  return cycle

end

def out_bound?(i, input_limit)
  return ( (i < 1) or (i > input_limit) )
end

def hailstorm(i, j)

  input_limit = 1000000

  (return nil) if ( (out_bound?(i, input_limit)) or out_bound?(j, input_limit) )

  longest = 0

  tab = Array.new(input_limit + 1, 0)

  # n일때 싸이클길이를 구해와서 tab[n]에 저장해놓구, 가장 긴값을 비교해감

  min(i, j).upto(max(i, j)) do |n|
    cycle = cycle_of_n(n, tab)
    tab[n] = cycle
    longest = max(longest, cycle)
  end

  return [i, j, longest]

end

require 'test/unit'

class TestHailStorm < Test::Unit::TestCase

  def test_hailstorm
    input = [ [1, 10], [100, 200], [201, 210], [900, 1000] ]
    ans = [ [1, 10, 20], [100, 200, 125], [201, 210, 89], [900, 1000, 174] ]

    input.each_index {|i| assert_equal(ans[i], hailstorm(input[i][0], input[i][1]))}
  end

end

크리에이티브 커먼즈 라이선스
Creative Commons License
Posted by sloth_chord