iT邦幫忙

第 12 屆 iThome 鐵人賽

DAY 26
0
自我挑戰組

Codewars Ruby Challenge in 30 Days系列 第 26

Codewars Ruby Challenge - Day 26/30

學習

  1. ruby 在 Std 有內建 Prime :雖然練習自己寫判斷質數很好,但如果寫之前能先知道 ruby 在標準函式庫早就幫你做好會更好A_A,在寫之前要記得掛上 require 'prime',這樣才能使用 prime? 的方法
  2. blank? 方法需要掛 active_support:寫這題剛好遇到想判斷「Array 是否為空」,直覺想使用 blank? 但發現會有問題。查了很久才發現跟 prime? 方法一樣,需要額外掛上才是,prime? 是掛上「std-lib」但 blank? 則是屬於在「active_support」(下面說明)
# 在 irb 中執行
[].blank?
結果:true

# 在 rb 檔中執行
puts [].blank?
結果:undefined method `blank?' for []:Array (NoMethodError)

# 解決方式:掛上 active_support(整個程式碼如下)
require 'active_support/core_ext'
puts [].blank? 
結果:true (會正常)

題目:

Define a function that takes one integer argument and returns logical value true or false depending on if the integer is a prime.
Per Wikipedia, a prime number (or a prime) is a natural number greater than 1 that has no positive divisors other than 1 and itself.
# 翻譯:講那麼多...就是要確認是否是質數

def isPrime(input)
end

答案需要過以下測試:

RSpec.describe "isPrime" do
  it "Should return false for non-prime numbers." do
    expect(isPrime(4)).to eq(false)
    expect(isPrime(100)).to eq(false)
    expect(isPrime(999)).to eq(false)
    expect(isPrime(958297)).to eq(false)
    expect(isPrime(-7)).to eq(false)
  end
  
  it "Should return true for prime numbers." do
    expect(isPrime(2)).to eq(true)
    expect(isPrime(3)).to eq(true)
    expect(isPrime(5)).to eq(true)
    expect(isPrime(457)).to eq(true)
    expect(isPrime(39229)).to eq(true)
  end
end

我的答案

def isPrime(input)
  return false if input < 1
  return true if input == 2
  [*(2..(Math.sqrt(input).ceil))].select { |i| (input % i) == 0  }.empty?
end

思路:

  1. 一樣先用 guard clause 大範圍去掉小於 1 的所有值
  2. 運用質數的特質「因數只有1跟自己」,所以去看 2~ input -1 的所有數值能否被 input 整除,如果任何一個都沒被整除,那就是質數啦。但這時會有個 bug,當 input 是 2 時「2 可以被 2 整除,但它確實是質數」所以又需要再多一個 guard clause 先排除
  3. Codewars 的 test 能過,但 attemp 時在數字很大時會有 timeout 的問題,還要考慮效能。這時又找到「判斷質數只需要確認 input 數值的前一半即可」,加上這個處理就開心過關啦~

Best practice in Codewars

require 'prime'

def isPrime(input)
  input.prime?
end

(我無言……有…現成的…)


上一篇
Codewars Ruby Challenge - Day 25/30
下一篇
Codewars Ruby Challenge - Day 27/30
系列文
Codewars Ruby Challenge in 30 Days30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言