[Bài tập vui]: Tìm ra mươi ngày 13 rơi vào thứ sáu gần hôm nay nhất!

Liên hệ QC
Thì chủ thớt đã nói rồi đó chi. Gần nhất 10 ngày là phải tính 5 ngày từ hiện tại đến tương lai + 5 ngày từ hiện tại đến quá khứ.
Dễ òm chứ gì, sắp xếp theo trình tự thời gian luôn nè.

PHP:
Function Find2DFriday13th(ByVal intCount As Integer) As Variant
    Dim intBefore As Integer, intAfter As Integer
    Dim arrDate, d1 As Date, d2 As Date, blnLimit As Boolean
    ReDim arrDate(1 To intCount, 1 To 1) As Date
    d1 = Date: d2 = d1
    intBefore = Fix(intCount / 2): intAfter = intBefore
    Do
        If Not blnLimit Then
            If Weekday(d1) = 6 And Day(d1) = 13 Then
                arrDate(intBefore, 1) = d1
                intBefore = intBefore - 1
                If intBefore = 0 Then blnLimit = True
            End If
            d1 = d1 - 1
        Else
            If Weekday(d2) = 6 And Day(d2) = 13 Then
                intAfter = intAfter + 1
                arrDate(intAfter, 1) = d2
                If intAfter = intCount Then Exit Do
            End If
            d2 = d2 + 1
        End If
    Loop
    Find2DFriday13th = arrDate
End Function

Tính số lẻ đi cho nó máu!

=Find2DFriday13th(13)
 
Mà bài #41 nó dài dòng quá nhỉ? Vậy thì rút gọn lại thôi!

PHP:
Function Find2DFriday13th_New(ByVal intCount As Integer) As Variant
    Dim arrDate, d As Date, intBefore As Integer, intAfter As Integer
    ReDim arrDate(1 To intCount, 1 To 1) As Date
    intBefore = Fix(intCount / 2): intAfter = intBefore: d = Date
    Do
        d = IIf(intBefore, d - 1, d + 1)
        If Weekday(d) = 6 And Day(d) = 13 Then
            If intBefore > 0 Then
                arrDate(intBefore, 1) = d
                intBefore = intBefore - 1
                If intBefore = 0 Then d = Date
            Else
                intAfter = intAfter + 1
                arrDate(intAfter, 1) = d
            End If
        End If
    Loop Until intAfter = intCount
    Find2DFriday13th_New = arrDate
End Function
 
Bài đã được tự động gộp:


Mình viết code thấy nó ngắn gọn sao các bác viết dài thòn vậy ta?
Mấy cái code này thế giới giải đầy ra rồi vụ thứ sáu ngày 13. chỉ là tập thể dục thôi. Dài ngắn quan trọng gì.
Ngon viết thứ sáu ngày 20 đi. Nhớ viết bằng công thức nha. Yêu cầu của thớt là công thức. còn VBA thì người ta giải cách đây 20 năm rồi.
 
Ủa mà quên, mỗi tháng chỉ có một ngày 13 duy nhất, mắc mớ gì mình tính theo ngày chi ta? Cập nhật lại:
PHP:
Function Find2DFriday13th_HTN(ByVal intCount As Integer) As Variant
    Dim arrDate, d As Date, intBefore As Integer, intAfter As Integer
    ReDim arrDate(1 To intCount, 1 To 1) As Date
    intBefore = Fix(intCount / 2): intAfter = intBefore
    d = DateSerial(Year(Date), Month(Date), 13)
    Do
        d = DateSerial(Year(d), Month(d) + IIf(intBefore, -1, 1), 13)
        If Weekday(d) = 6 Then
            If intBefore > 0 Then
                arrDate(intBefore, 1) = d
                intBefore = intBefore - 1
                If intBefore = 0 Then d = DateSerial(Year(Date), Month(Date) - 1, 13)
            Else
                intAfter = intAfter + 1
                arrDate(intAfter, 1) = d
            End If
        End If
    Loop Until intAfter = intCount
    Find2DFriday13th_HTN = arrDate
End Function

Mấy cái code này thế giới giải đầy ra rồi vụ thứ sáu ngày 13. chỉ là tập thể dục thôi. Dài ngắn quan trọng gì.
Ngon viết thứ sáu ngày 20 đi. Nhớ viết bằng công thức nha. Yêu cầu của thớt là công thức. còn VBA thì người ta giải cách đây 20 năm rồi.
Nói có sách, mách có chứng, xin nguồn.
Còn hiện tại ở bài này, ngắn thì nói ngắn.
 
Lần chỉnh sửa cuối:
Ủa mà quên, mỗi tháng chỉ có một ngày 13 duy nhất, mắc mớ gì mình tính theo ngày chi ta? Cập nhật lại:
PHP:
Function Find2DFriday13th_HTN(ByVal intCount As Integer) As Variant
    Dim arrDate, d As Date, intBefore As Integer, intAfter As Integer
    ReDim arrDate(1 To intCount, 1 To 1) As Date
    intBefore = Fix(intCount / 2): intAfter = intBefore
    d = DateSerial(Year(Date), Month(Date), 13)
    Do
        d = DateSerial(Year(d), Month(d) + IIf(intBefore, -1, 1), 13)
        If Weekday(d) = 6 Then
            If intBefore > 0 Then
                arrDate(intBefore, 1) = d
                intBefore = intBefore - 1
                If intBefore = 0 Then d = DateSerial(Year(Date), Month(Date) - 1, 13)
            Else
                intAfter = intAfter + 1
                arrDate(intAfter, 1) = d
            End If
        End If
    Loop Until intAfter = intCount
    Find2DFriday13th_HTN = arrDate
End Function
Bài đã được tự động gộp:


Nói có sách, mách có chứng, xin nguồn.
Còn hiện tại ở bài này, ngắn thì nói ngắn.
Topic này yêu cầu là công thức mà các hạ!???? VBA ai chả biết!
 
Topic này yêu cầu là công thức mà các hạ!???? VBA ai chả biết!
Ủa các hạ không để ý sao? Tôi trích bài #20 của chính tác giả, và tác giả dùng VBA để viết hàm, nên tôi mới dùng VBA để so sánh. Mà GPE đã từng có tiền lệ ai viết code ngắn nhất và có thời gian nhanh nhất hay sao??????
 
Ủa các hạ không để ý sao? Tôi trích bài #20 của chính tác giả, và tác giả dùng VBA để viết hàm, nên tôi mới dùng VBA để so sánh. Mà GPE đã từng có tiền lệ ai viết code ngắn nhất và có thời gian nhanh nhất hay sao??????
À, nếu so ngắn dài, thì ngắn bằng này hông các hạ?? Viết code VBA chi cho dài dòng vậy cà!
LET(td,TODAY(),n,10,l_date,td+SEQUENCE(10001)-5001,l_filter,FILTER(l_date,TEXT(l_date,"dd ddd")="13 Fri"),pst,MATCH(td,l_filter),INDEX(l_filter,SEQUENCE(n*2)-n+pst))
 
Code VBA thì ngắn từng này thôi (nếu xét về độ ngắn)

Sub ChaubaThong()
Sheet1.[A1].Formula2 = "=LET(td,TODAY(),n,10,l_date,td+SEQUENCE(10001)-5001,l_filter,FILTER(l_date,TEXT(l_date,""dd ddd"")=""13 Fri""),pst,MATCH(td,l_filter),INDEX(l_filter,SEQUENCE(n*2)-n+pst))"
End Sub

Khà khà khà
-----------
Xoá 1 phần bài viết bởi ptm0412
 
Chỉnh sửa lần cuối bởi điều hành viên:
VBA cho kết quả vầy nè:
STTNgàyThứ
10
4/13/2018​
6​
8
7/13/2018​
6​
6
9/13/2019​
6​
4
12/13/2019​
6​
3
3/13/2020​
6​
1
11/13/2020​
6​
2
8/13/2021​
6​
5
5/13/2022​
6​
7
1/13/2023​
6​
9
10/13/2023​
6​
Nếu code chạy ngày 20.02.2021 thì kết quả sai. Vì không đúng với giả thiết là liệt kê 5 ngày trước và 5 ngày sau ngày hiện hành. Kết quả trên có 6 ngày trước và 4 ngày sau ngày hiện hành.
 
Ủa các hạ không để ý sao? Tôi trích bài #20 của chính tác giả, và tác giả dùng VBA để viết hàm, nên tôi mới dùng VBA để so sánh.
Bài #20 không tính vì lúc đó trạng thái là đã uống hết 1 xị rồi (ngồi đợi quen tay cứ rót thôi). Muốn biết lúc tỉnh táo thế nào thì xem bài #1
Sẽ có 3 xị rượu cho ai giải đúng & sớm nhất bằng công thức!
 
Code VBA thì ngắn từng này thôi (nếu xét về độ ngắn)

Sub ChaubaThong()
Sheet1.[A1].Formula2 = "=LET(td,TODAY(),n,10,l_date,td+SEQUENCE(10001)-5001,l_filter,FILTER(l_date,TEXT(l_date,""dd ddd"")=""13 Fri""),pst,MATCH(td,l_filter),INDEX(l_filter,SEQUENCE(n*2)-n+pst))"
End Sub

Khà khà khà
Bài đã được tự động gộp:


Google sheet thì qua Google sheet chơi cho vui đi, vô đây làm gì ta!?? Excel 365 là Excel 365, chẳng lẽ quay lại excel 2003, hay thích quay lại Lotus 123??? Mà thôi, VBA sắp lạc hậu rồi các hạ à!
Vẫn còn dài lắm các hạ ơi!

Mã:
Sub N()
    [A1].Resize(20).Formula = Find2DFriday13th_HTN(20)
End Sub
 
Code ngắn chưa hẳn là nhanh, code dài chưa hẳn là không tối ưu. GPE không có "tiền lệ", việc đánh giá code ngon căn cứ vào tốc độ và độ dài ngắn chỉ là 1 số người trên GPE chứ không phải nguyên GPE.
Code VBA thì ngắn từng này thôi (nếu xét về độ ngắn)
Đây là code ăn gian.
Công thức dùng hàm VBA, hay hàm VBA dùng công thức (Formula) cũng đều là ăn gian.
365 xài Lambda mới là đỉnh của rút gọn công thức.
 
Mấy bài nhảm nhàm không liên quan không có ích cho diễn đàn, hy vọng các cao nhân soi sét dẹp bớt cho thiên hạ thái bình!
befaint có lý mà. Nếu so sánh ngắn gài, nhanh chậm thì phải xét trong cùng bối cảnh. Vd. phải cùng phiên bản. Nếu so sánh phiên bản 365 với 2010 thì khác gì anh chơi cờ mà lại có lợi con xe. Mà dùng 365 thì hỏa lực của anh hạn chế rồi. Có rất nhiều người không chạy được công thức dùng 365.
 
Phàm nếu thứ sáu ngày 13 thì ngày đầu tháng đó là chủ nhật, ngày chúa nghỉ ngơi!
Còn ông Như lai hay Ala có nghỉ hay không không chắc á nha!

Chúc các bạn vui khỏe & hẹn gặp nhau sau mùa dịch!
 
Chỗ tôi ảnh hưởng bão Conson, mưa quá trời luôn. Mưa quá chẳng ngủ được. Bác Sa dậy sớm hay là cũng không ngủ được vậy?
 
Tên bão đó do VN đăng ký, nên phải viết chí ít là Con Son, khà, khà, khà,. . . .
Mình vừa trãi qua 1 đêm ngon giấc đó bạn!

Chúc 1 buổi sáng tốt lành!
 
Web KT
Back
Top Bottom