Project Euler Problem #10

ผลรวมของจำนวนเฉพาะ (Prime Number) ต่ำที่กว่า 10 คือ 2 + 3 + 5 + 7 = 17

จงหาผลรวมของจำนวนเฉพาะทั้งหมด ที่ต่ำกว่าสองล้าน

(โจทย์นี้แปลมาจาก projecteuler.net สามารถเผยแพร่ภายใต้ลิขสิทธิ์ CC BY-NC-SA 2.0 UK)

@prin09
ชัดเจน: 2/3 สร้างสรรค์: 1/3 กระชับ 2/3 ความเร็ว 2/3
Comment: ชัดเจน เรียบง่าย ตรงไปตรงมาครับ

@teerathornmoon3
Comment: คำตอบผิดครับ

@IMPREM
ชัดเจน: 2/3 สร้างสรรค์: 1/3 กระชับ 2/3 ความเร็ว 1/3
Comment: ดู comment ด้านล่างครับ บรรทัดแปดไม่ต้องเช็คเลขคู่ได้ครับเพราะนอกจาก 2 แล้วไม่มีเลขคู่ที่เป็นจำนวนเฉพาะอีก

@STGSafe
Comment: ต้องแก้ครับ

@Rain
ชัดเจน: 2/3 สร้างสรรค์: 1/3 กระชับ 2/3 ความเร็ว 2/3
Comment: ไม่ชอบตรงที่ตั้งชื่อว่า less_than จริงๆมันควรเป็น upper limit จะทำให้ชัดเจนกว่านี้ ตอนจะ scan หาเลขเฉพาะ ควรเช็คว่าเป็นเลขคู่แล้วตัดเลขคู่ทั้งหมดออกไปเลย หลังจากนั้นเริ่มที่เลข 3 แล้วบวก 2 ไปเรื่อยๆ จะเร็วกว่าเยอะครับ

@Akira
ชัดเจน: 1/3 สร้างสรรค์: 1/3 กระชับ 1/3 ความเร็ว 0/3
Commment: คำตอบไม่ถูกต้องครับ แต่ผมแก้แล้วรันให้ ไม่ควรใช้ list(range( แบบนี้ครับเว้นแต่จะจำเป็นจริงๆเพราะ range เป็น lazy ครับ จะไม่ได้รันจนกว่าจะถูกใช้งาน จะทำให้กิน RAM เยอะครับ แถมการเพิ่ม loop เข้าไปช่วงบรรทัดที่ 13-23 ทำให้ช้ามากๆๆเลยครับ

@STGSafe
ชัดเจน: 2/3 สร้างสรรค์: 1/3 กระชับ 2/3 ความเร็ว 1/3
Comment: ถ้าจะให้เร็วกว่านี้ครับ บรรทัดที่ 4 ไม่ต้องเช็คเลขคู่ยกเว้นเลข 2 ครับ จะทำให้เร็วขึ้น อ่าน comment ที่เขียนไว้ก่อนหน้านี้ครับ

รอนานมากครับ เเต่คำตอบน่าจะถูกนะ ของธีครับ


Rain’s answer in #10

@mishariคอมเม้นท์โค้ดน้องเรนหน่อยค่ะ เพื่อการปรับปรุงในอนาคต พยายามหาทางทำให้เร็วขึ้นค่ะ แต่ทำได้แค่นี้ค่ะ

is_prime วิธีเช็คนะครับ

สังเกตุไหมครับว่าแทนที่จะเช็ค 2 3 4 5 6 7 8 9 10
ตอนนี้เราจะเช็คแค่ 3 5 7 9 ทำให้การเช็คลดลงจาก 9 เหลือ 4 แปลว่าเร็วขึ้น 50%

ถ้าจะให้เร็วกว่านี้ ทุกครั้งที่ได้ prime ให้เอา prime ไปใส่ใน list ครับ แล้วเอา prime list ตรงนั้นไปเช็ค is_prime
ยกตัวอย่างเคสนี้นะครับ ถ้าหาร 3 ไม่ลงตัว แปลว่าไม่ต้องเช็คแล้วหละ ว่า 6 กับ 9 หารลงตัวไหม มันไม่ลงตัวแน่

root = sqrt(candidate) + 1
if candidate == 2:
  return True
if candidate % 2 == 0:
  return False
for i in range(3,root,2):
  if candidate % i == 0:
     return True
return False