简体   繁体   English

如何在没有 numpy 的情况下生成形成棋盘的二维数组?

[英]How to generate a 2d array forming a chequerboard without numpy?

The problem is the following:问题如下:

chequerboard(n, m, offset_h, offset_w) , all arguments >=1, returns an n by m chequerboard where each (region) is of size offset_h by offset_w, the top left cell is always filled, and only the right hand and bottom edge may contain incomplete chequers. chequerboard(n, m, offset_h, offset_w) ,所有 arguments >=1,返回一个n x m棋盘,其中每个(区域)的大小为 offset_h x offset_w,左上角的单元格始终被填充,只有右手和底部边缘可能包含不完整的支票。

Examples:例子:

chequerboard(6, 8, 2, 2) returns
    [['#', '#', ' ', ' ', '#', '#', ' ', ' '],
     ['#', '#', ' ', ' ', '#', '#', ' ', ' '],
     [' ', ' ', '#', '#', ' ', ' ', '#', '#'],
     [' ', ' ', '#', '#', ' ', ' ', '#', '#'],
     ['#', '#', ' ', ' ', '#', '#', ' ', ' '],
     ['#', '#', ' ', ' ', '#', '#', ' ', ' ']]

chequerboard(5, 7, 2, 3) returns
    [['#', '#', '#', ' ', ' ', ' ', '#'],
     ['#', '#', '#', ' ', ' ', ' ', '#'],
     [' ', ' ', ' ', '#', '#', '#', ' '],
     [' ', ' ', ' ', '#', '#', '#', ' '],
     ['#', '#', '#', ' ', ' ', ' ', '#']]

How can I solve it without Numpy?没有 Numpy 怎么解决? ie, using only vanilla python?即,仅使用香草 python?

You could utilize the modulo operator ( % ) :您可以使用模运算符( %

def print_chequerboard(board: list[list[str]]) -> None:
    for row in board:
        print(row)


def chequerboard(n: int, m: int, offset_h: int, offset_w: int) -> list[list[str]]:
    board = [[' ' for _ in range(m)] for _ in range(n)]
    for i in range(n):
        for j in range(m):
            if i // offset_h % 2 == 0 and j // offset_w % 2 == 0 or \
               i // offset_h % 2 == 1 and j // offset_w % 2 == 1:
                board[i][j] = '#'
    return board


def main() -> None:
    print('chequerboard(6, 8, 2, 2): ')
    print_chequerboard(chequerboard(6, 8, 2, 2))
    print('chequerboard(5, 7, 2, 3): ')
    print_chequerboard(chequerboard(5, 7, 2, 3))
    print('chequerboard(6, 8, 2, 2): ')
    print_chequerboard(chequerboard(6, 8, 2, 2))
    print('chequerboard(5, 7, 2, 3): ')
    print_chequerboard(chequerboard(5, 7, 2, 3))


if __name__ == '__main__':
    main()

Output: Output:

chequerboard(6, 8, 2, 2): 
['#', '#', ' ', ' ', '#', '#', ' ', ' ']
['#', '#', ' ', ' ', '#', '#', ' ', ' ']
[' ', ' ', '#', '#', ' ', ' ', '#', '#']
[' ', ' ', '#', '#', ' ', ' ', '#', '#']
['#', '#', ' ', ' ', '#', '#', ' ', ' ']
['#', '#', ' ', ' ', '#', '#', ' ', ' ']
chequerboard(5, 7, 2, 3): 
['#', '#', '#', ' ', ' ', ' ', '#']
['#', '#', '#', ' ', ' ', ' ', '#']
[' ', ' ', ' ', '#', '#', '#', ' ']
[' ', ' ', ' ', '#', '#', '#', ' ']
['#', '#', '#', ' ', ' ', ' ', '#']
chequerboard(6, 8, 2, 2): 
['#', '#', ' ', ' ', '#', '#', ' ', ' ']
['#', '#', ' ', ' ', '#', '#', ' ', ' ']
[' ', ' ', '#', '#', ' ', ' ', '#', '#']
[' ', ' ', '#', '#', ' ', ' ', '#', '#']
['#', '#', ' ', ' ', '#', '#', ' ', ' ']
['#', '#', ' ', ' ', '#', '#', ' ', ' ']
chequerboard(5, 7, 2, 3): 
['#', '#', '#', ' ', ' ', ' ', '#']
['#', '#', '#', ' ', ' ', ' ', '#']
[' ', ' ', ' ', '#', '#', '#', ' ']
[' ', ' ', ' ', '#', '#', '#', ' ']
['#', '#', '#', ' ', ' ', ' ', '#']

You can do it by creating the first row and then repeating it offset_h times.您可以通过创建第一行然后重复offset_h次来做到这一点。 This is then rolled by offset_w for the subsequent offset_h rows.然后由offset_w滚动到后续的offset_h行。 Each row is sliced to the desired size and the process is repeated.每行都被切成所需的大小并重复该过程。

def ceiling(a, b):
    return -(a//-b)

def chequerboard(n, m, offset_h, offset_w):
    pattern = ['#']*offset_w+[' ']*offset_w
    row = pattern + pattern * (ceiling(m, 2*offset_w)-1)
    return [(row[offset_w:]+row[:offset_w])[:m] if i % 2 else row[:m] for i in range(ceiling(n, offset_h)) for _ in range(offset_h)][:n]

Test:测试:

for i in ((6, 8, 2, 2), (5, 7, 2, 3)):
    for j in chequerboard(*i):
        print(j)
    print('\n')

Output: Output:

['#', '#', ' ', ' ', '#', '#', ' ', ' ']
['#', '#', ' ', ' ', '#', '#', ' ', ' ']
[' ', ' ', '#', '#', ' ', ' ', '#', '#']
[' ', ' ', '#', '#', ' ', ' ', '#', '#']
['#', '#', ' ', ' ', '#', '#', ' ', ' ']
['#', '#', ' ', ' ', '#', '#', ' ', ' ']


['#', '#', '#', ' ', ' ', ' ', '#']
['#', '#', '#', ' ', ' ', ' ', '#']
[' ', ' ', ' ', '#', '#', '#', ' ']
[' ', ' ', ' ', '#', '#', '#', ' ']
['#', '#', '#', ' ', ' ', ' ', '#']

Benchmarks:基准:

assert chequerboard(6, 8, 2, 2) == chequerboard_sash(6, 8, 2, 2)

%timeit chequerboard(6, 8, 2, 2)
%timeit chequerboard_sash(6, 8, 2, 2)

Output: Output:

2.1 µs ± 30.9 ns per loop (mean ± std. dev. of 7 runs, 100,000 loops each)
10.3 µs ± 74.7 ns per loop (mean ± std. dev. of 7 runs, 100,000 loops each)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM