[Bài tập VBA cho người rỗi rảnh] Hãy viết 1 macro tìm ra 3 số nguyên tố liên tiếp

Liên hệ QC

SA_DQ

/(hông là gì!
Thành viên danh dự
Tham gia
8/6/06
Bài viết
14,582
Được thích
22,906
Nghề nghiệp
U80
Ba số nguyên tố liên tiếp này bé hơn con số 999 & lớn hơn 100. (đã sửa sau góp ý của các bài 2 - 5)

Chúc các bạn vui vẻ nhân dịp xuân về!
 
Lần chỉnh sửa cuối:
Hai, ba, và năm. Đủ nhỉ?
 
Upvote 0
Đáp án đúng, nhưng bài làm (các câu lệnh VBA) đâu vậy?!?
 
Upvote 0
Hai, ba, và năm. Đủ nhỉ?
Hình như thớt diễn tả câu hỏi không rõ.
Có lẽ muốn nói "các bộ ba số nguyên tố liên liếp"
2, 3, 5
3, 5, 7
5, 7, 11
...
(tìm các số nguyên tố nhỏ hơn hay bằng giới hạn)

Chú cho các quý vị muốn thử viết:
Bài này thuộc về giải thuật nhiều hơn code.
 
Upvote 0
Đáp án đúng, nhưng bài làm (các câu lệnh VBA) đâu vậy?!?
Đối với câu đố này thì không cần VBA, chỉ cần thuộc định nghĩa số nguyên tố là gì rồi xòe bàn tay là thấy 3 con.
Có lẽ bài đố nên như sau:
- Hoặc là 3 số liên tiếp nhỏ hơn 600 nhưng gần 600 nhất
- Hoặc là liệt kê hết các bộ 3. (có trùng hoặc không trùng).

Hình như thớt diễn tả câu hỏi không rõ.
Có lẽ muốn nói "các bộ ba số nguyên tố liên liếp"
Hiển nhiên là không rõ ràng. Nếu tôi viết code để có 2, 3, 5 thì thủ thuật khác, nếu tôi viết code để lấy bộ 3 bất kỳ thì thủ thuật khác, nếu liệt kê hết các bộ 3 thì thủ thuật lại khác nữa. Nếu lấy bộ 3 gần 600 nhất, thì lại khác nữa.

Thứ hai, một câu đố mà giải ra kết quả nào cũng đúng thì không phải là câu đố chuẩn.
 
Upvote 0
Thể theo ý kiến đã đóng góp của các bạn, mình xin sửa lại đề bài như sau:

Tìm 3 số nguyên tố liên tiếp bất kỳ mà chúng gồm toàn các số có 3 kí số
 
Upvote 0
Thuật toán Capilot:
Đây là hướng dẫn từng bước về cách bạn có thể tìm ba số nguyên tố liên tiếp với ba chữ số:

  1. Hiểu về số nguyên tố:
    • Số nguyên tố là số tự nhiên lớn hơn 1 và chỉ chia hết cho 1 và chính nó.
  2. Xác định phạm vi:
    • Bạn cần tìm các số nguyên tố có ba chữ số, vì vậy chúng nên nằm trong khoảng từ 100 đến 999.
  3. Kiểm tra từng số:
    • Bắt đầu từ 100 và kiểm tra từng số xem có phải là số nguyên tố hay không. Bạn có thể sử dụng phương pháp chia thử, tức là chia số đó cho từng số nguyên từ 2 đến căn bậc hai của nó. Nếu tất cả các phép chia này không cho kết quả là số nguyên, thì số đó là số nguyên tố.
  4. Tìm các số nguyên tố liên tiếp:
    • Sau khi bạn tìm thấy số nguyên tố ba chữ số đầu tiên (là 101), tiếp tục đến số tiếp theo (102) và kiểm tra xem nó có phải là số nguyên tố không. Nếu không, chuyển sang số tiếp theo (103) và tiếp tục cho đến khi bạn tìm thấy ba số nguyên tố liên tiếp.

      Marco Capilot:

      Mã:
      Sub FindConsecutivePrimes()
          Dim count As Integer
          Dim num As Integer
          Dim primes(2) As Integer
      
          count = 0
          num = 100
      
          Do While count < 3
              If IsPrime(num) Then
                  primes(count) = num
                  count = count + 1
              End If
              num = num + 1
          Loop
      
          ' In ra ba số nguyên tố liên tiếp
          For i = 0 To 2
              Debug.Print primes(i)
          Next i
      End Sub
      
      Function IsPrime(n As Integer) As Boolean
          Dim i As Integer
          If n <= 1 Then
              IsPrime = False
              Exit Function
          End If
          For i = 2 To Int(Sqr(n))
              If n Mod i = 0 Then
                  IsPrime = False
                  Exit Function
              End If
          Next i
          IsPrime = True
      End Function
 

File đính kèm

  • Untitled.png
    Untitled.png
    53.6 KB · Đọc: 5
Lần chỉnh sửa cuối:
Upvote 0
Điểm code để người khác chấm. Tôi chỉ chấm điểm thuật toán:

1. Nếu chỉ theo đúng chỉ dẫn 3 của bài #7: tối đa 7/10 điểm
2. Áp dụng các thuật toán, mẹo, đặc điểm của ngôn ngữ để ưu hóa: tối đa 10/10 điểm.

Đó là theo đề bài sửa lại ở bài #6.
Nếu sửa đề bài theo bài #4 thì còn một thuật toán ưu việt nữa. (nói như vậy là tôi đã gợi ý rồi đấy)
 
Upvote 0
Upvote 0
Có 1 tính chất của các SNT (số nguyên tố) lớn hơn 100 là toàn số lẻ
Như vậy bài toán có thể rút ngắn gần phân nữa đoạn đường nhờ khảo sát chỉ những số lẽ 101, 103,. . . .,999
Để snh động hơn, ta có thể tìm số lẽ N bất kỳ trong khoảng 101.. 505 & bắt đầu tìm 3 SNT liền kề ( > N) từ N này
 
Upvote 0
Có 1 tính chất của các SNT (số nguyên tố) lớn hơn 100 là toàn số lẻ
Như vậy bài toán có thể rút ngắn gần phân nữa đoạn đường nhờ khảo sát chỉ những số lẽ 101, 103,. . . .,999
Để snh động hơn, ta có thể tìm số lẽ N bất kỳ trong khoảng 101.. 505 & bắt đầu tìm 3 SNT liền kề ( > N) từ N này
Đúng. Vì vậy thuật toán xét đã được ưu hóa là xét xem nó có phải là số lẻ trước. Lúc xét chia chẵn thì cũng chỉ xét chia cho số lẻ (từ 3 đến căn hai số step 2)

Function IsPrime(n As Long) As Boolean
IsPrime = True
Select Case n
Case 0, 1 ???? ' tùy theo định nghĩa mà là nguyên tố hay không?
Case 2
Exit Function
Case Else
If (n And 1) = 0 Then ' số chẵn
IsPrime = False
Exit Function
End If
For i = 3 To Sqrt(n) Step 2
If n % i = 0 Then
IsPrime = False
Exit Function
End If
Next i
End Select
End Function

Chú cho những người quên toán số học cấp 2:
Tại sao chỉ xét đến sqrt(n)?
Lô gic toán: nếu i chia chẵn n thì có một số j sao cho n = i*j
Số j này cũng chia chẵn n
nếu i < sqrt(n) thì j > sqrt(i) và ngược lại.
Vì vậy chỉ cần xét chia chẵn đến sqrt(n) bởi vì j đã được ngầm xét rồi.

Tại sao tôi đề nghị đề bài mở rộng thêm ở chỗ bài #4?
 
Upvote 0
Có 1 tính chất của các SNT (số nguyên tố) lớn hơn 100 là toàn số lẻ
Như vậy bài toán có thể rút ngắn gần phân nữa đoạn đường nhờ khảo sát chỉ những số lẽ 101, 103,. . . .,999
Để snh động hơn, ta có thể tìm số lẽ N bất kỳ trong khoảng 101.. 505 & bắt đầu tìm 3 SNT liền kề ( > N) từ N này
Xin được góp vui và rất mong nhận được nhiều góp ý để nâng cao kiến thức
Mã:
Option Explicit
Public t&, KQ()
Sub SoNguyenTo(ByVal S1 As Long, S2 As Long, Chon As Integer)
'Chon =1  lay tât ca cac sô nguyen tô tim đươc thành 1 cot
'Chon=2  lay 1 tap gôm 3 sô nguyên to liên kê
'Chon = 3 lay 1 tâp gôm nhiêu tâp 3 sô nguyên to liên kê xêp vào 1 côt
Dim i&, j&, k&, a&, N&, Nhay&, SN&
Dim S, L
S = Array(2, 3, 5, 7, 9, 11, 13, 17, 19, 23, 29, 31, 37)
ReDim KQ(1 To (S2 - S1), 1 To 1)
SN = SoNgauNghien(S1, S2)
t = 0
If SN = 1 Then SN = 2
If SN >= 100 Then
    If SN Mod 2 = 0 Then SN = SN + 1
    Nhay = 2
Else
    Nhay = 1
End If
For i = SN To S2 Step Nhay
    For j = LBound(S) To UBound(S)
        If i = S(j) Or i Mod S(j) <> 0 Then N = 1 Else N = 0: Exit For
    Next j
    If N = 1 Then
    Select Case Chon
        Case Is = 1
        t = t + 1: KQ(t, 1) = i
        Case Is = 2
            a = a + 1: If L = Empty Then L = 1 Else L = L & ";" & i
            If a = 3 Then t = t + 1: KQ(t, 1) = L: Exit For
        Case Is = 3
            a = a + 1: If L = Empty Then L = i Else L = L & ";" & i
            If a Mod 3 = 0 Then t = t + 1: KQ(t, 1) = L: L = Empty
        End Select
    End If
Next i
End Sub

Sub Test()
Call SoNguyenTo(100, 999, 3)
Sheet2.[A10].Resize(1000, 1).ClearContents
Sheet2.[A10].Resize(t, 1) = KQ
End Sub
Function SoNgauNghien(iMin As Long, iMax As Long)
    Call Randomize
    SoNgauNghien = Int((iMax - iMin + 1) * Rnd + iMin)
End Function
Đoạn code này sẽ tìm được các số nguyên tố (SNT) Theo ý định:
*.2 tham số đầu là Từ số...., đến số và bắt đầu tìm từ 1 số ngẫu nghiên nằm trong khoảng Từ ...đến...,
*.tham số thứ 3 là:
Nếu Chon=1 :Kết quả trả về là 1 tập gồm tất cả các CNT tìm được gán vào 1 cột
Nếu Chon= 2: Kết quả trả về là 1 tập gồm 3 số NT liền kề cách nhau bởi dấu ";"
Nếu Chon=3: Kết quả trả về là 1 tập gồm nhiều tập Con có 3 số NT liền kề cách nhau bởi dấu ";"
 
Upvote 0
Có 1 tính chất của các SNT (số nguyên tố) lớn hơn 100 là toàn số lẻ
Như vậy bài toán có thể rút ngắn gần phân nữa đoạn đường nhờ khảo sát chỉ những số lẽ 101, 103,. . . .,999
Để snh động hơn, ta có thể tìm số lẽ N bất kỳ trong khoảng 101.. 505 & bắt đầu tìm 3 SNT liền kề ( > N) từ N này
Tuy sinh động nhưng nó liên quan đến loại toán khác, không nằm trong tinh thần "số nguyên tố",
Bài toán tôi đề nghị ở bài #4 là một loại triển khai đặc tính nguyên tố. Gợi ý đến đây là gần hết cái thuật toán mà tôi muốn nói rồi.
 
Upvote 0
Bài toán tôi đề nghị ở bài #4 là một loại triển khai đặc tính nguyên tố. Gợi ý đến đây là gần hết cái thuật toán mà tôi muốn nói rồi.
Nếu trong khoảng từ 101 đến 999 có n số nguyên tố, thì giải bài 4 sẽ được n - 2 bộ 3 liền kề. Vẫn phải liệt kê hết n số ra rồi mới ghép bộ, và quá trình liệt kê vẫn phải dựa vào định nghĩa (đặc tính) số nguyên tố rồi. Ý anh cũng không rõ ràng như bài 1 vậy á.
Còn giải thuật thì cũng chỉ là vònglặp với step 2. Hoặc giải thuật khác cũng vậy, không giúp gì cho việc liệt kê hết n số tốt hơn.

À còn 1 ý nữa, số (2 ký số trở lên) tận cùng là 5 cũng là số lẻ nhưng không phải số nguyên tố, có thể bỏ qua để giảm thiểu số vòng lặp.
 
Lần chỉnh sửa cuối:
Upvote 0
Nếu trong khoảng từ 101 đến 999 có n số nguyên tố, thì giải bài 4 sẽ được n - 2 bộ 3 liền kề. Vẫn phải liệt kê hết n số ra rồi mới ghép bộ, và quá trình liệt kê vẫn phải dựa vào định nghĩa (đặc tính) số nguyên tố rồi. Ý anh cũng không rõ ràng như bài 1 vậy á.
Còn giải thuật thì cũng chỉ là vònglặp với step 2. Hoặc giải thuật khác cũng vậy, không giúp gì cho việc liệt kê hết n số tốt hơn.

À còn 1 ý nữa, số (2 ký số trở lên) tận cùng là 5 cũng là số lẻ nhưng không phải số nguyên tố, có thể bỏ qua để giảm thiểu số vòng lặp.
Không phải vậy.
Xét xem môt số có phải là nguyên tố và xét xem có bao nhiêu số nguyên tố từ 1 đến k dùng giải thuật khác nhau.

Cũng toán số cấp 2:
Lúc mò xem một số có phải là nguyên tố, ta chỉ cần chia thử cho các số nguyên tố nhỏ hơn hay bằng căn hai nó.


Vì vậy:
Nếu phải tìm tất cả các số nguyên tố từ 1 thì ta có thể chép các kết quả tuần tự vào một mảng. Lúc thử số kế tiếp thì lôi mảng này ra mà chia.
Đây là kỹ thuật dùng "sàng số nguyên tố", kỹ thuật kia là "trâu bò/ brute force cải tiến".
Khi vùng giới hạn k1~k2 có đặc tính k1 khá nhỏ và k2 khá lớn thì kỹ thuật sàng số nhanh hơn hẳn. Mặc dù phải phí một mớ năng lượng để fill mảng từ 1 đến k1.
 
Upvote 0
Cũng toán số cấp 2:
Lúc mò xem một số có phải là nguyên tố, ta chỉ cần chia thử cho các số nguyên tố nhỏ hơn hay bằng căn hai nó.
Vụ này giờ tôi mới biết. Cấp 2, cấp 3 đều không có dạy. Tôi học lớp 6 năm 1972, lớp 6, 7, 8 học chương trình trước giải phóng, qua lớp 9 là chương trình sau giải phóng mà không có cái này. Giới hạn chia thử là căn 2 thì tôi tự suy luận ra chứ trường cũng không dạy.
 
Upvote 0
Web KT

Bài viết mới nhất

Back
Top Bottom