Liệt kê toàn bộ các số điện thoại đẹp lên trang tính.

Liên hệ QC

ChanhTQ@

0901452không62
Tham gia
5/9/08
Bài viết
4,256
Được thích
4,863
Tôi muốn liệt kê toàn bộ các số điện thoại đẹp gồm 7 chữ số. Điều kiện, chỉ liệt kê các số đẹp có số chẵn ở số đầu mà thôi,
Ví dụ: 2000 007, . . . . , 4000 005, . . . . .
Chúng được liệt kê lên từng cột, bắt đầu từ cột 'A'

Xin rất cảm ơn các bạn viết cho macro như vậy.--=--

From PTM0412:
Trước tiên, bạn phải định nghĩa thế nào là số đẹp, giống như bảo người đầu bếp nấu món khoái khẩu của thủ tướng X nước Y, mà không đưa thực đơn vậy.


Số đẹp là (tổng các số trong nó) MOD 10 = 9

Và như vậy cứ coi như số không cũng là số chẵn luôn giúp nha.


Các bạn giúp mình đi nha, sẽ có hậu tạ!
:-=
 
Chỉnh sửa lần cuối bởi điều hành viên:
Số đẹp là (tổng các số trong nó) MOD 10 = 9Và như vậy cứ coi như số không cũng là số chẵn luôn giúp nha
Các bạn giúp mình đi nha, sẽ có hậu tạ!

MOD 10 = 9, hay: chia hết cho 9. Bạn đưa một loại ví dụ cụ thể nữa lên xem. Nói như thế cũng còn khó hiểu quá!
 
Chỉnh sửa lần cuối bởi điều hành viên:
MOD 10 = 9, hay: chia hết cho 9. Bạn đưa một loại ví dụ cụ thể nữa lên xem. Nói như thế cũng còn khó hiểu quá!
Mã:
[SIZE=3]Ví dụ số điện thoại là  [B]8737 393[/B] Thì[/SIZE]
[SIZE=3]8 + 7 + 3 + 7 + 3 + 9 + 3 = 40 =>    40 MOD 10 = 0[/SIZE]
[SIZE=3]Trường hợp số ĐT là [B]2345 678[/B][/SIZE]
[SIZE=3]2 + 3 + 4 + 5 + 6 + 7 + 8 = 35  =>    35 MOD 10 = 5[/SIZE]
[SIZE=3]Them nữa: Với số [B]6000 003[/B]  =>           9 MOD 10 = 9[/SIZE]
 
1. Công thức để tính tổng các chữ số trong một dãy số là:
Ô A1 chứa dãy số, ô B1 gõ công thức:
{=SUM(--MID(A1,ROW(INDIRECT("1:"&LEN(A1))),1))}

2. Chon một biến chạy từ 1000000 đến 9999999 và tính tổng các chữ số trong chuỗi đó, nếu MOD 10 của tổng đó = 9 thì lấy riêng ra một sheet.

Cách này hơi lâu.
 
Chỉnh sửa lần cuối bởi điều hành viên:
Không biết có đúng ý bạn không.
Ca_Dafi đã viết:
Hầu như cứ 10 số có một số điện thoại gọi là đẹp (theo như định nghĩa của mình);
Vậy cách dùng công thức là không ăn thua đâu, chắc vậy!
9 triệu số thì có khoảng 600.000 số đẹp . Bỏ đi phân nữa hay chỉ lấy 1/3 những số ấy cũng chiếm 6 cột trang tính excel 2003 rồi!
Bỡi lẻ đó mình mới post bài vô đây í mà!

Rất xin cảm ơn các bạn & rất mong chúng ta cùng tiếp tục giúp.&&&%$R
 
Hầu như cứ 10 số có một số điện thoại gọi là đẹp (theo như định nghĩa của mình);
Vậy cách dùng công thức là không ăn thua đâu, chắc vậy!
Rất xin cảm ơn các bạn & rất mong chúng ta cùng tiếp tục giúp.&&&%$R

Có hai cách :
1 . Xét số đó, cộng từng số hạng lại với nhau và MOD 10 (Đơn giản, dễ hiểu)
2. Lập ra danh mục tất cả các số có 6 chữ số thỏa mãn điều kiện đó. Khi phát sinh số nào thì chỉ cần kiểm tra xem số đó có nằm trong danh mục đó không (Khổ trước sướng sau)
Chúc vui
 
Chỉnh sửa lần cuối bởi điều hành viên:
Chính xác là trong 10 triệu số đầu, có 500.000 số "đẹp".
1. Dùng 1 biến i chạy từ 0 đến 9.999.999, số nào thoả đk thì xuất ra cell: duyệt 10.000.000 số, rất chậm

2. Chia ra 5 khoảng, mỗi khoảng 1.000.000 số với số đầu là 0, 2, 4, 6, 8, vẫn dùng thuật toán duyệt từng số, nhanh hơn 1 chút: từ 1 phút 56 giây đến 2 phút 08 giây (kết quả 500.000 số và chính xác): chỉ duyệt 5.000.000 số, giảm 1 nửa

3. Cũng chia 5 khoảng như trên, dùng thuật toán duyệt nhưng hạn chế vòng lặp, nhanh hơn: từ 1 phút 08 giây đến 1 phút 15 giây, nhưng kết quả kém hơn: chỉ cho 460.557 số. Lý do: chưa thấy được quy luật hiệu số giữa 2 số "đẹp" kế tiếp nhau.
Số lượng số bị duyệt ước khoảng 2.000.000 đến 3.000.000, không thống kê được.

Xem file kèm theo, mỗi sheet có 1 code theo 2 cách.
 

File đính kèm

  • SodepPtm.zip
    13.6 KB · Đọc: 346
Lần chỉnh sửa cuối:
Rất biết ơn các bác & các bạn xa gần! Nhất là Lệnh Hồ & PTM0412

Chính xác là trong 10 triệu số đầu, có 500.000 số "đẹp".
1. Dùng 1 biến i chạy từ 0 đến 9.999.999, số nào thoả đk thì xuất ra cell: duyệt 10.000.000 số, rất chậm
2. Chia ra 5 khoảng, . . . . .
3. Số lượng số bị duyệt ước khoảng 2.000.000 đến 3.000.000, không thống kê được.
Mình mới nghĩ ra cách như sau, các bác cho í kiến (đúng/sai):
Duyệt từ 0000009 - 9999999 Step 9; vị chi giảm còn hơn triệu gì đó số lần duyệt;
Nếu kết hợp với cách của bác PTM0412 thì giảm đi 1 nữa?!

Xin các bác phát biểu tiếp tục giúp cho.

Rất cảm ơn sự quan tâm!
 
Mình mới nghĩ ra cách như sau, các bác cho í kiến (đúng/sai):
Duyệt từ 0000009 - 9999999 Step 9; vị chi giảm còn hơn triệu gì đó số lần duyệt;
Nếu kết hợp với cách của bác PTM0412 thì giảm đi 1 nữa?!

Xin các bác phát biểu tiếp tục giúp cho.

Rất cảm ơn sự quan tâm!
Bác ơi, hình như quy luật +9 chỉ tính cho từng 100 số hạng
90+9=99 => mod(9+9,10)=8
Tương tự
180+9=1+8+9=18
199+9=2+0+8=10
Chắc phải tìm theo cách khác. Em thử cho 1 dãy số mà chưa tìm ra quy luật.
 
List số đẹp (đầu chẵn + 9 nước)

boyxin nghĩ thế này có vẻ nhanh hơn:

b1: chọn ra các số trong khoảng 1-1000000 được 100 000 số, ghi thành 2 cột
b2: thêm 2,4,6,8 vào đầu và cộng hoặc trừ số cuối thích hợp => ta được 400 000 số nữa
vậy tổng cộng có 500 000 số thỏa mãn yêu cầu
(đã test thử trên máy của boyxin: Total = 31 giây List ra được 500 000 số)
 

File đính kèm

  • Sodep_new.rar
    9.8 KB · Đọc: 98
Lần chỉnh sửa cuối:
boyxin nghĩ thế này có vẻ nhanh hơn:

b1: chọn ra các số trong khoảng 1-1000000 được 100 000 số, ghi thành 2 cột
b2: thêm 2,4,6,8 vào đầu và cộng hoặc trừ số cuối thích hợp => ta được 400 000 số nữa
vậy tổng cộng có 500 000 số thỏa mãn yêu cầu
Nói chung, về cơ bản ta chỉ cần tìm 6 số hạng mà mod=7, vì số 2 đầu. Còn 4, 6, 8 thì từ kế quả trên ta cộng 2 thôi.
Nhưng mà tìm quy luật: từ 000,000 - 999,999 mà mod(TC,10) = 7 hay 6,5 hay bằng 1 số nào thì chưa biết.
 
Mình mới nghĩ ra cách như sau, các bác cho í kiến (đúng/sai):
Duyệt từ 0000009 - 9999999 Step 9; vị chi giảm còn hơn triệu gì đó số lần duyệt;
Nếu kết hợp với cách của bác PTM0412 thì giảm đi 1 nữa?!
Step không phải là 9, mà là 5, 6, 7, 8, 9, 15, 16, 17, 18, 19.
Dựa vào Step và dùng gợi ý trên của bạn Chanh@, rút lại còn 18 giây, đủ 500.000 con, số lần duyệt ước chừng dưới 250.000.
 

File đính kèm

  • SodepPtm2.zip
    11.3 KB · Đọc: 48
Thật tuyệt vời, thêm tý
PHP:
    With Application
        .DisplayAlerts = False
        .ScreenUpdating = False
        .Calculation = xlCalculationManual
'----------------------------------------
.............CODE..........................
'----------------------------------------
        .Calculation = xlCalculationAutomatic
        .ScreenUpdating = True
        .DisplayAlerts = True
    End With
Test tại máy
attachment.php
chỉ mất có 9 giây
 

File đính kèm

  • Test.JPG
    Test.JPG
    10.3 KB · Đọc: 272
Đúng là thật tuyệt vời, một khi có cộng đồng góp sức.

Coi như chúng ta tạm thời dừng đầu tư thời gian cho bài 01 tại đây. Vì có lẽ phương cách như trên là tối ưu rồi cũng nên.

Xin các bác ra tay với bài thứ hai, như sau:
Với các số có sáu chữ số, ta lại phải liệt kê lên trang tính các số khi mà tổng ba số hàng nghìn bằng tổng ba số hàng đơn vị;
Ví dụ như sau
123123, 123321, 123132, 123312, 123213 & 123231, 123006, 123015. . . . --=0

Xin trân trọng cảm ơn các bác quan tâm!
 
Lần chỉnh sửa cuối:
Nếu tính luôn số 000 000, dùng 2 vòng lặp:
- 1 vòng ngoài chạy đủ 1.000 vòng, từ 1 đến 999
- 1 vòng trong chạy cũng 1.000 vòng, từ 1 đến 999. Điều kiện là (trong mỗi vòng của vòng For ngoài): tổng 3 số bằng 1 số cho trước.

Đại khái vầy: (06 giây, kể luôn số 0 là 55.252 con)

PHP:
Sub LietKe()

Range("M5") = Time()
Range("A1:k5500").NumberFormat = "000 000"
With Application
        .DisplayAlerts = False
        .ScreenUpdating = False
        .Calculation = xlCalculationManual
        Cells(1, 1) = 0
        Rowi = 1
        Colj = 1
        Socong1 = 0
        Socong2 = 0
For i = 1 To 999
    So1 = i
    Sotinh1 = Right("000" & So1, 3)
    Socong1 = Left(Sotinh1, 1) * 1 + Mid(Sotinh1, 2, 1) * 1 + Right(Sotinh1, 1) * 1
    For j = 1 To 999
        So2 = j
        Sotinh2 = Right("000" & So2, 3)
        Socong2 = Left(Sotinh2, 1) * 1 + Mid(Sotinh2, 2, 1) * 1 + Right(Sotinh2, 1) * 1
        If Socong2 = Socong1 Then
            Rowi = IIf(Rowi + 1 = 5501, 1, Rowi + 1)
            Colj = Colj + IIf(Rowi = 1, 1, 0)
            Cells(Rowi, Colj) = So1 * 1000 + So2
        End If
    Next
Next
    Range("M6") = Time()
        .Calculation = xlCalculationAutomatic
        .ScreenUpdating = True
        .DisplayAlerts = True
    End With
End Sub
 

File đính kèm

  • SobangnhauPtm.zip
    10.1 KB · Đọc: 42
Lần chỉnh sửa cuối:
Theo mình, cần thêm câu lệnh thoát vòng lặp bên trong, lúc cần thiết

Socong1 = Left(Sotinh1, 1) * 1 + Mid(Sotinh1, 2, 1) * 1 + Right(Sotinh1, 1) * 1
Mã:
[COLOR=#007700]For [/COLOR][COLOR=#0000bb]j [/COLOR][COLOR=#007700]= [/COLOR][COLOR=#0000bb]1 To 1000 [/COLOR]
[COLOR=#0000bb]      So2 [/COLOR][COLOR=#007700]= [/COLOR][COLOR=#0000bb]j :                            Sotinh2 [/COLOR][COLOR=#007700]= [/COLOR][COLOR=#0000bb]Right[/COLOR][COLOR=#007700]([/COLOR][COLOR=#dd0000]"000" [/COLOR][COLOR=#007700]& [/COLOR][COLOR=#0000bb]So2[/COLOR][COLOR=#007700], [/COLOR][COLOR=#0000bb]3[/COLOR][COLOR=#007700]) [/COLOR]
[COLOR=#007700]      [SIZE=3][B]If j > SoCong1 Then Exit For[/B][/SIZE]  'Mới thêm'[/COLOR]
[COLOR=#0000bb]Socong2 [/COLOR][COLOR=#007700]= [/COLOR][COLOR=#0000bb]Left[/COLOR][COLOR=#007700]([/COLOR][COLOR=#0000bb]Sotinh2[/COLOR][COLOR=#007700], [/COLOR][COLOR=#0000bb]1[/COLOR][COLOR=#007700]) * [/COLOR][COLOR=#0000bb]1 [/COLOR][COLOR=#007700]+ [/COLOR][COLOR=#0000bb]Mid[/COLOR][COLOR=#007700]([/COLOR][COLOR=#0000bb]Sotinh2[/COLOR][COLOR=#007700], [/COLOR][COLOR=#0000bb]2[/COLOR][COLOR=#007700], [/COLOR][COLOR=#0000bb]1[/COLOR][COLOR=#007700]) * [/COLOR][COLOR=#0000bb]1 [/COLOR][COLOR=#007700]+ [/COLOR][COLOR=#0000bb]Right[/COLOR][COLOR=#007700]([/COLOR][COLOR=#0000bb]Sotinh2[/COLOR][COLOR=#007700], [/COLOR][COLOR=#0000bb]1[/COLOR][COLOR=#007700]) * [/COLOR][COLOR=#0000bb]1 [/COLOR]
[COLOR=#007700]If [/COLOR][COLOR=#0000bb]Socong2 [/COLOR][COLOR=#007700]= [/COLOR][COLOR=#0000bb]Socong1 Then [/COLOR]
 
Mã:
If j > SoCong1 Then Exit For  'Mới thêm'
Nếu j > SoCong1 mà thoát, sẽ chỉ liệt kê được 220 em thôi!

Thí dụ:

- Với i = 1, đáng lẽ ta có 3 kết quả: 001 001, 001 010, 001 100, nhưng chỉ tóm được 1 em đầu, bỏ qua 2 em sau, bởi tại bị kể từ j = 2 trở về sau, j > 1
- Với i = 2, đáng lẽ ta có kết quả: 002 002, 002 011, 002 101, 002 110, 002 020, 000 200, nhưng cũng chỉ tóm được đúng 1 em đầu tiên.

Sodep.gif
 
Ờ hén! Vậy không thể rút gọn bằng cách đó, vậy cách khác xem sao?!

Nếu j > SoCong1 mà thoát, sẽ chỉ liệt kê được 220 em thôi!

Mình nghĩ ra thêm cách này:
Thay vì 1 vòng lặp bên trong, ta phân ra làm 3 vòng lặp, như kiểu vầy, được không vậy?

PHP:
 Dim Tram As Byte, Chuc As Byte, DVi As Byte
'. . . . . '
'. . . . . '
    For Tram = 0 to 9
           For Chuc =0 To 9
                 For DVi = 0 To 9
                       If SoCong1 = Tram + Chuc + DVi then
                               ' Lệnh gán lên trang tính'
                       End If
 
    Next DVi, Chuc, Tram
' . . . . . . . . '
 
Tạm thời, thay vì dùng: If j > socong1 Then Exit For

Ta dùng: If j > socong1 * 100 Then Exit For

Giảm được 70.062 vòng lặp
Còn cách dùng 3 vòng For, để thử cái đã. Mà sao bạn không thử nhỉ? Hay đây là câu đố? Vậy câu đố có giải thưởng hông?
 
Lần chỉnh sửa cuối:
Web KT
Back
Top Bottom