کاشیکاری با ترومینو
صفحهی 2^k × 2^k با یک خانهی کم را با کاشیهای L شکل سهخانهای میپوشاند: صفحه را چهار تکه میکند، یک ترومینو در وسط میگذارد تا هر تکه دقیقاً یک خانهی پر داشته باشد، و هر تکه را بازگشتی حل میکند. اثبات استقرایی به شکل الگوریتم.
صفحهای 2^k × 2^k داریم که یک خانهاش کم است. آیا میشود بقیه را با ترومینو (کاشی L شکل سهخانهای) پوشاند؟ تعداد خانهها 4^k − 1 است که بر ۳ بخشپذیر است، ولی این کافی نیست؛ باید راهی ساخت.
- زمان:
Θ(4^k) (one step per tromino) - حافظه:
O(k) for the recursion - جانسونباو، فصل ۲
- گریمالدی، فصل ۴
صفحهی ۸ × ۸ (k = ۳) که خانهی (۲، ۵) آن کم است؛ ۲۱ ترومینو.
def tromino_tiling(k, row, col):# A 2^k × 2^k board with the cell (row, col) missing, tiled with L-shaped trominoes. Cells show the tile number.n = 2 ** kif row >= n or col >= n:return Noneboard = [["·"] * n for _ in range(n)]board[row][col] = "■"count = [0]tile(board, n, 0, 0, row, col, count)tiles = count[0]return tilesdef tile(board, size, top, left, mr, mc, count):# (mr, mc) is the one cell of this square that is already taken.if size == 1:returnhalf = size // 2count[0] = count[0] + 1t = count[0]quads = []cells = []for dr in [0, 1]:for dc in [0, 1]:qt = top + dr * halfql = left + dc * halfif qt <= mr < qt + half and ql <= mc < ql + half:quads.append([qt, ql, mr, mc])else:# The quadrant's cell next to the centre gets a piece of tromino t.cr = top + half - 1 + drcc = left + half - 1 + dccells.append([cr, cc])quads.append([qt, ql, cr, cc])place(board, cells, t)for qt, ql, r, c in quads:tile(board, half, qt, ql, r, c, count)def place(board, cells, t):for r, c in cells:board[r][c] = t
شروع اجرا
جدول هنوز خالی است.
درخت فراخوانیهای بازگشتی
نارنجی پر = فراخوانی در حال اجرا · حاشیهی نارنجی = هنوز روی پشته · خاکستری = تمام شده
متغیرهای محلی
نارنجی = در همین گام عوض شد
Call stack
- tromino_tiling()خط 1
توضیح
مسئله
صفحهای 2^k × 2^k داریم که یک خانهاش کم است. آیا میشود بقیه را با ترومینو (کاشی L شکل سهخانهای) پوشاند؟ تعداد خانهها 4^k − 1 است که بر ۳ بخشپذیر است، ولی این کافی نیست؛ باید راهی ساخت.
اثبات استقرایی = الگوریتم
- پایه: صفحهی ۲ × ۲ با یک خانهی کم، خودش یک ترومینو است.
- گام: صفحه را به چهار ربع
2^(k−1) × 2^(k−1)تقسیم کن. خانهی کم در یکی از آنهاست. یک ترومینو در وسط بگذار که یک خانه از هر کدام از سه ربع دیگر را بپوشاند. حالا هر ربع دقیقاً یک خانهی پر دارد و طبق فرض استقرا کاشیکاری میشود.
این اثبات (Golomb، ۱۹۵۴) دقیقاً یک الگوریتم تقسیم و حل است: (4^k − 1)/3 ترومینو، هر کدام در یک گام.
ورودی
k اندازهی صفحه را تعیین میکند (2^k)، و row و col خانهی کم را (از ۰). عدد هر خانه شمارهی ترومینوی آن است و ■ خانهی کم.