btvn.vn
Tìm kiếm Đăng nhập

Chương trình Tháp Hà Nội và danh sách bước

Lưu trên thiết bị này
Chuyên đề lựa chọn CS: Đệ quy · Chọn bài khác

In một lần chuyển giữa hai lời gọi nhỏ

Hàm dưới dùng điều kiện n≥1 và ba tên cọc khác nhau: ```python def Hanoi(n, i, j, k): if n == 1: print(f'Đĩa {n}: {i} -> {j}') else: Hanoi(n - 1, i, k, j) print(f'Đĩa {n}: {i} -> {j}') Hanoi(n - 1, k, j, i) ``` Lời gọi `Hanoi(2,1,3,2)` in ba dòng: ```text Đĩa 1: 1 -> 2 Đĩa 2: 1 -> 3 Đĩa 1: 2 -> 3 ``` Lần in ở giữa chỉ xảy ra sau khi lời gọi đầu hoàn tất. Hàm in thông tin, không trả một danh sách; nếu gán kết quả lời gọi thì nhận None.

Có thể chọn cơ sở không còn đĩa

Một bản rút gọn dùng n≥0 và chỉ làm việc khi n>0: ```python def Hanoi_zero(n, i, j, k): if n > 0: Hanoi_zero(n - 1, i, k, j) print(f'Đĩa {n}: {i} -> {j}') Hanoi_zero(n - 1, k, j, i) ``` Khi n=0, hàm kết thúc mà không in. Với n≥1, bản này in cùng dãy lần chuyển như bản cơ sở n=1. Không gọi bản đầu với n=0 vì cơ sở của bản ấy chỉ kiểm n==1.

Lưu kết quả để dùng lại

Mỗi bước được lưu thành bộ ba (số đĩa, cọc nguồn, cọc đích). Bản sau trả danh sách thay vì in; cơ sở không đĩa trả danh sách rỗng: ```python def Hanoi_list(n, i, j, k): if n == 0: return [] first = Hanoi_list(n - 1, i, k, j) last = Hanoi_list(n - 1, k, j, i) return first + [(n, i, j)] + last ``` Gọi với n≥0. Các danh sách được ghép theo đúng thứ tự: lời giải phần đầu, bước chuyển đĩa n, lời giải phần cuối. Ví dụ `Hanoi_list(2,1,3,2)` trả `[(1,1,2),(2,1,3),(1,2,3)]`; danh sách ghi ba lần chuyển, không ghi lại mọi trạng thái cọc.

Chạy và đối chiếu dãy lần chuyển

Tải mã, mở terminal tại thư mục chứa tệp và chạy bằng Python3: ```text python3 g11-cs-thap-ha-noi.py 3 python3 g11-cs-thap-ha-noi.py 2 --names A C B ``` Lệnh đầu báo H(3)=7 rồi in bảy lần chuyển. Lần thứ tư phải là đĩa 3 từ cọc 1 sang cọc 3; sau lần thứ bảy, cả chồng ở cọc 3. Lệnh sau in đĩa 1 từ A sang B, đĩa 2 từ A sang C, đĩa 1 từ B sang C; thứ tự tên sau --names là nguồn, đích, trung gian. Có thể nhập các lời gọi hàm trực tiếp trong Python để so sánh bản in với bản trả danh sách. Thử n=1,2,3,4; đối chiếu từng bước với quy tắc đĩa trên cùng và không đặt lớn lên nhỏ. Mẫu dòng lệnh chỉ liệt kê n từ 1 đến 10 để giữ bộ thử nhỏ; nhập 0, số âm hoặc ba tên cọc trùng nhau phải báo lỗi. Nếu máy gọi Python3 bằng lệnh python thì dùng tên lệnh tương ứng.

Bài luyện

Muốn dùng bản Hanoi in hai đĩa từ A sang C, lấy B làm trung gian, lời gọi nào đúng?
Chọn một đáp án

Bài luyện

Gán result=Hanoi(2,1,3,2) bằng bản in trong bài. Kết luận nào đúng?
Chọn một đáp án

Bài luyện

Với Hanoi_list(2,1,3,2), phần tử thứ hai của danh sách trả về là gì?
Chọn một đáp án

Bài luyện

Với n=0 theo điều kiện của hai bản Hanoi_zero và Hanoi_list, kết quả nào đúng?
Chọn một đáp án

Đang học