Генераторы для двумерных массивов

Для создания двумерных массивов можно использовать вложенные генераторы, разместив генератор списка, являющегося строкой, внутри генератора для строк. Например, сделать список из n строк и m столбцов при помощи генератора, создающего список из n элементов, каждый элемент которого является списком из m нулей:

[ [0] * m for i in range(n)]

Но при этом внутренний список также можно создать при помощи, например, такого генератора: [0 for j in range(m)]. Вложив один генератор в другой получим вложенные генераторы:

[ [0 for j in range(m)] for i in range(n)]

Но если число 0 заменить на некоторое выражение, зависящее от i (номер строки) и j (номер столбца), то можно получить список, заполненный по некоторой формуле.

В этом листке вам нужно будет придумать генераторы для заданных двумерных массивов.

Например, пусть нужно задать следующий массив (для удобства добавлены дополнительные пробелы между элементами):

0  0  0  0  0  0
0  1  2  3  4  5
0  2  4  6  8 10
0  3  6  9 12 15
0  4  8 12 16 20

В этом массиве n = 5 строк, m = 6 столбцов, и элемент в строке i и столбце j вычисляется по формуле: A[i][j] = i * j.

Ответом на это задание будет выражение:

[[ i * j for j in range(m)] for i in range(n)]

Ответ, содержащий заданное выражение, нужно ввести в поле ввода (лучше - скопировав из работающей программы). В выражении должны использоваться переменные n и m, означающие число строк и столбцов в массиве. Если в задании сказано, что массив — квадратный, то число строк и столбцов в нем равно n, а значение m не определено и использовать его нельзя.

0: Таблица умножения

Заполните массив таблицей умножения по правилу A[i][j] = i * j.

Пример для n = 5, m = 6.

0  0  0  0  0  0
0  1  2  3  4  5
0  2  4  6  8 10
0  3  6  9 12 15
0  4  8 12 16 20

Ответом на это задание будет выражение без print'ов, input'ов и прочего такого вида:

[[ выражение_от_i_и_j for j in range(m)] for i in range(n)]
IDE

A: Номера строк

Заполните массив, записав в каждом элементе номер строки, в которой он находится.

Пример для n = 5, m = 6.

0 0 0 0 0 0
1 1 1 1 1 1
2 2 2 2 2 2
3 3 3 3 3 3
4 4 4 4 4 4
IDE

B: Номера столбцов

Заполните массив, записав в каждом элементе номер столбца, в котором он находится.

Пример для n = 5, m = 6.

0 1 2 3 4 5
0 1 2 3 4 5
0 1 2 3 4 5
0 1 2 3 4 5
0 1 2 3 4 5
IDE

Вывод для отладки

Если вы до сих пор не написали удобную функцию для печати двумерных списков, то можете воспользоваться следующей:

def str4(x):
    return str(x).rjust(4)


def print_2_dim_array(A):
    for row in A:
        print(''.join(map(str4, row)))

Можно ещё короче, если вы уже понимаете, что такое lambda.

def print_2_dim_array(A):
    for row in A:
        print(''.join(map(lambda el: str(el).rjust(4), row)))

Ещё можно так, если вы — маньяк :)

def print_2_dim_array(A):
    print('\n'.join(map(lambda row: ''.join(map(lambda el: str(el).rjust(4), row)), A)))

C: Слева направо, сверху вниз

Заполните массив целыми числами начиная с нуля по строчкам, слева направо, строчки обходятся сверху вниз.

Пример для n = 5, m = 6.

 0  1  2  3  4  5
 6  7  8  9 10 11
12 13 14 15 16 17
18 19 20 21 22 23
24 25 26 27 28 29
IDE

D: Сверху вниз, слева направо

Заполните массив целыми числами начиная с нуля по столбцам, сверху вниз, столбцы обходятся слева направо.

Пример для n = 5, m = 6.

 0  5 10 15 20 25
 1  6 11 16 21 26
 2  7 12 17 22 27
 3  8 13 18 23 28
 4  9 14 19 24 29
IDE

E: Снизу вверх, слева направо

Заполните массив целыми числами начиная с нуля по столбцам, снизу вверх, столбцы обходятся слева направо.

Пример для n = 5, m = 6.

 4  9 14 19 24 29
 3  8 13 18 23 28
 2  7 12 17 22 27
 1  6 11 16 21 26
 0  5 10 15 20 25
IDE

F: Справа налево, снизу вверх

Заполните массив целыми числами начиная с нуля по строчкам, справа налево, строчки обходятся снизу вверх.

Пример для n = 5, m = 6.

29 28 27 26 25 24
23 22 21 20 19 18
17 16 15 14 13 12
11 10  9  8  7  6
 5  4  3  2  1  0
IDE

Генераторы — внутри почти что угодно

Внутри генератора можно использовать не только арифметику, но и функции. Например, функции max и min.

>>> print_2_dim_array([[ max(i + j, 3) for j in range(5)] for i in range(6)])
   4   4   4   4   4
   4   4   4   4   5
   4   4   4   5   6
   4   4   5   6   7
   4   5   6   7   8
   5   6   7   8   9

G: Квадраты-1

Заполните квадратный массив целыми числами по образцу.

Пример для n = 5.

0 1 2 3 4
1 1 2 3 4
2 2 2 3 4
3 3 3 3 4
4 4 4 4 4
IDE

H: Квадраты-2

Заполните квадратный массив целыми числами по образцу.

Пример для n = 5.

0 1 2 3 4
0 1 2 3 3
0 1 2 2 2
0 1 1 1 1
0 0 0 0 0
IDE

I: Шахматная доска

Заполните прямоугольный массив числами 0 и 1 в шахматном порядке. В левом верхнему углу записана 1.

Пример для n = 5, m = 6.

1 0 1 0 1 0
0 1 0 1 0 1
1 0 1 0 1 0
0 1 0 1 0 1
1 0 1 0 1 0
IDE

J: Нумерация диагоналей - 1

Заполните прямоугольный массив целыми числами по образцу.

Пример для n = 5, m = 6.

0 1 2 3 4 5
1 2 3 4 5 6
2 3 4 5 6 7
3 4 5 6 7 8
4 5 6 7 8 9
IDE

K: Нумерация диагоналей - 2

Заполните прямоугольный массив целыми числами по образцу (на главной диагонали стоят нули, выше нее стоят 1, затем 2, 0, 1 и т.д. Номера всех диагоналей чередуются по циклу 0, 1, 2, ...).

Пример для n = 5, m = 6.

0 1 2 0 1 2
2 0 1 2 0 1
1 2 0 1 2 0
0 1 2 0 1 2
2 0 1 2 0 1
IDE

L: Расстояние до побочной диагонали

Заполните квадратный массив целыми числами по образцу. На побочной диагонали стоят нули, на соседних с нею диагоналях стоят 1, затем 2 и т.д.

Пример для n = 5.

4 3 2 1 0
3 2 1 0 1
2 1 0 1 2
1 0 1 2 3
0 1 2 3 4
IDE

Тернарный оператор

В языке python есть конструкция, которая позволяет использовать if прямо внутри выражений. Например, можно писать

A = 1 if i > j else 0
или даже
A = some_number + (1 if i > j else 2 if j < i else 3) + other_number

Их можно использовать и в генераторах. Впрочем, если условие нетривиально, то такую конструкцию лучше не использовать.

M: Каждая четвертая диагональ

Заполните квадратный массив целыми числами по образцу. На побочной диагонали стоят единицы, каждая четвертая по счету диагональ, параллельная побочной, также заполнена единицами.

Пример для n = 10.

0 1 0 0 0 1 0 0 0 1
1 0 0 0 1 0 0 0 1 0
0 0 0 1 0 0 0 1 0 0
0 0 1 0 0 0 1 0 0 0
0 1 0 0 0 1 0 0 0 1
1 0 0 0 1 0 0 0 1 0
0 0 0 1 0 0 0 1 0 0
0 0 1 0 0 0 1 0 0 0
0 1 0 0 0 1 0 0 0 1
1 0 0 0 1 0 0 0 1 0
IDE

N: Решетка

Заполните прямоугольный массив целыми числами по образцу (нули стоят на пересечении строк и столбцов с нечетными номерами, в остальных клетках стоят единицы).

Пример для n = 5, m = 6.

1 1 1 1 1 1
1 0 1 0 1 0
1 1 1 1 1 1
1 0 1 0 1 0
1 1 1 1 1 1
IDE

O: Выше и ниже главной диагонали

Заполните прямоугольный массив целыми числами по образцу. На главной диагонали стоят нули, выше главной диагонали — единицы, ниже — двойки

Пример для n = 5, m = 6.

0 1 1 1 1 1
2 0 1 1 1 1
2 2 0 1 1 1
2 2 2 0 1 1
2 2 2 2 0 1
IDE

P: Андреевский крест

Заполните квадратный массив целыми числами по образцу. На главной и побочной диагоналях стоят единицы, остальные элементы равны нулю.

Пример для n = 7.

1 0 0 0 0 0 1
0 1 0 0 0 1 0
0 0 1 0 1 0 0
0 0 0 1 0 0 0
0 0 1 0 1 0 0
0 1 0 0 0 1 0
1 0 0 0 0 0 1
IDE

Приведение типов

Иногда оказывается удобным явно или неявно приводить логические типы к int и наоборот. В этом случае действуют следующие правила.

При приведении значений типа bool к типу int значение True переводится в 1, значение False переводится в 0. Такое преобразование может быть выполнено явно при помощи функции int, или оно выполняется неявно если значение типа bool используется в арифметических операциях. Например, выражение (x > 0) + (y > 0) + (z > 0) позволяет определить, сколько среди чисел x, y, z положительных.

Это позволяет также конструировать аналоги логических выражений. Например, максимум из чисел a и b можно найти так:

print(a * (a > b) + b * (a <= b))

В этом примере если (a > b), то первое слагаемое будет равно a, а второе слаемое будет равно 0. Если же (a <= b), то первое слагаемое будет 0, а второе будет равно b.

При приведении значения типа int к типу bool число 0 переводится в False, а ненулевые числа переводятся в True. При переводе строк и списков к типу bool пустые строки и списки приводятся к значению False, а непустые — к True.

Интересны правила применения логических операций and и or к выражениям нелогического типа. Здесь применяются правила неполного вычисления логических выражений. Для операции and сначала вычисляется значение левого операнда. Если левый операнд приводится к логическому False (то есть имеет значение False, 0, является пустой строкой или пустым списком), то возвращается значение левого операнда. Иначе возвращается значение правого операнда. Аналогично работает операция or: если значение левого операнда True, неотрицательное число, непустая строка или список, то возвращается значение левого операнда, иначе возвращается значение правого операнда.

Q: Квадранты

Заполните квадратный массив целыми числами по образцу. На главной и побочных диагоналях стоят нули, эти диагонали делят массив на четыре части. В верхней части записаны единицы, в правой записаны двойки, в нижней записаны тройки, в левой записаны четверки.

Пример для n = 8.

0 1 1 1 1 1 1 0
4 0 1 1 1 1 0 2
4 4 0 1 1 0 2 2
4 4 4 0 0 2 2 2
4 4 4 0 0 2 2 2
4 4 0 3 3 0 2 2
4 0 3 3 3 3 0 2
0 3 3 3 3 3 3 0
IDE

R: Большие квадраты

Заполните прямоугольный массив целыми числами квадратами размера 2×2 из единиц, квадраты идут в шахматном порядке, начиная с левого верхнего угла.

Пример для n = 7, m = 10.

1 1 0 0 1 1 0 0 1 1
1 1 0 0 1 1 0 0 1 1
0 0 1 1 0 0 1 1 0 0
0 0 1 1 0 0 1 1 0 0
1 1 0 0 1 1 0 0 1 1
1 1 0 0 1 1 0 0 1 1
0 0 1 1 0 0 1 1 0 0
IDE

S: Змейка

Заполните прямоугольный массив целыми числами начиная с нуля по строчкам “змейкой”: слева направо, затем справа налево. строчки обходятся сверху вниз.

Пример для n = 5, m = 6.

 0  1  2  3  4  5
11 10  9  8  7  6
12 13 14 15 16 17
23 22 21 20 19 18
24 25 26 27 28 29
IDE

T: Заполнение в шахматном порядке

Заполните прямоугольный массив целыми числами начиная с единицы по строчкам слева направо, строчки обходятся сверху вниз. При этом в левом верхнем углу записано число 1, далее заполняются только клетки, имеющие тот же цвет в шахматной раскраске, что и левый верхний угол, а в остальных клетках записано число 0.

Пример для n = 5, m = 6.

 1  0  2  0  3  0
 0  4  0  5  0  6
 7  0  8  0  9  0
 0 10  0 11  0 12
13  0 14  0 15  0
IDE

U: Вложенные прямоугольники

Заполните прямоугольный массив вложенными прямоугольниками. Клетки, находящиеся на краях прямоугольника, заполняются числом 0, соседние с ними клетки заполняются числом 1, соседние с ними — числом 2 и т.д.

Пример для n = 6, m = 9.

0 0 0 0 0 0 0 0 0
0 1 1 1 1 1 1 1 0
0 1 2 2 2 2 2 1 0
0 1 2 2 2 2 2 1 0
0 1 1 1 1 1 1 1 0
0 0 0 0 0 0 0 0 0
IDE

V: Крест

Заполните квадратный массив целыми числами по образцу. В углах записан число 0, в соседних с ними с углами клетках записано число 1, в соседних с ними клетках записано число 2 и т.д. Клетки считаются соседними, если у них есть общая сторона или вершина.

Пример для n = 8.

0 1 2 3 3 2 1 0
1 1 2 3 3 2 1 1
2 2 2 3 3 2 2 2
3 3 3 3 3 3 3 3
3 3 3 3 3 3 3 3
2 2 2 3 3 2 2 2
1 1 2 3 3 2 1 1
0 1 2 3 3 2 1 0
IDE

W: Ромбы

Заполните квадратный массив целыми числами по образцу. В углах записан число 0, в соседних с ними с углами клетках записано число 1, в соседних с ними клетках записано число 2 и т.д. Клетки считаются соседними, если у них есть общая сторона.

Пример для n = 7.

0 1 2 3 2 1 0
1 2 3 4 3 2 1
2 3 4 5 4 3 2
3 4 5 6 5 4 3
2 3 4 5 4 3 2
1 2 3 4 3 2 1
0 1 2 3 2 1 0

Пример для n = 8.

0 1 2 3 3 2 1 0
1 2 3 4 4 3 2 1
2 3 4 5 5 4 3 2
3 4 5 6 6 5 4 3
3 4 5 6 6 5 4 3
2 3 4 5 5 4 3 2
1 2 3 4 4 3 2 1
0 1 2 3 3 2 1 0
IDE

X: Вдоль главной диагонали

Заполните квадратный массив целыми числами по образцу. Часть массива ниже главной диагонали заполнена нулями. На главной диагонали записаны числа 0, 1, ..., n - 1. На диагонали выше главной — числа n, n + 1, ..., 2n - 2. Следующая диагональ заполняется, начиная с числа 2n - 1 и т.д.

Пример для n = 7.

 0  7 13 18 22 25 27
 0  1  8 14 19 23 26
 0  0  2  9 15 20 24
 0  0  0  3 10 16 21
 0  0  0  0  4 11 17
 0  0  0  0  0  5 12
 0  0  0  0  0  0  6
IDE

Y: Заполнение по диагоналям

Заполните прямоугольный массив целыми числами начиная с нуля вдоль диагоналей, параллельных побочной диагонали. Заполнение проводится сверху вниз, диагонали обходятся слева направо.

Пример для n = 7, m = 10.

 0  1  3  6 10 15 21 28 35 42
 2  4  7 11 16 22 29 36 43 49
 5  8 12 17 23 30 37 44 50 55
 9 13 18 24 31 38 45 51 56 60
14 19 25 32 39 46 52 57 61 64
20 26 33 40 47 53 58 62 65 67
27 34 41 48 54 59 63 66 68 69
IDE

Z: Заполнение по спирали

Заполните прямоугольный массив целыми числами начиная с нуля спиралью, закручивающейся по часовой стрелке из левого верхнего угла к центру массива.

Пример для n = 7, m = 10.

 0  1  2  3  4  5  6  7  8  9
29 30 31 32 33 34 35 36 37 10
28 51 52 53 54 55 56 57 38 11
27 50 65 66 67 68 69 58 39 12
26 49 64 63 62 61 60 59 40 13
25 48 47 46 45 44 43 42 41 14
24 23 22 21 20 19 18 17 16 15
IDE

ZA: Проверка на простоту

Необходимо проверить числа на простоту. Для данного числа \(n\) составьте список из \(n-1\) элемента. \(i\)-й элемент списка будет равен True, если число \(i+2\) — простое, и False — если составное, то есть список содержит признаки простоты для чисел от 2 до \(n\).

Ограничения на \(n\) от 2 до 4000, поэтому проверка числа \(i\) на простоту должна иметь сложность \(O(\sqrt{i})\).

Пример для n = 12.

[True, True, False, True, False, True, False, False, False, True, False]
IDE

ZB: Последовательность Туе–Морса

Последовательность Туе–Морса является бесконечной последовательностью из 0 и 1, построенной следующим образом:

Последовательность начинается с числа 0. Далее построенная часть последовательности удваивается: к уже построенной части в конец дописывается эта же часть, но с инвертированием всех символов: 0 меняется на 1, а 1 меняется на 0.

Например, к последовательности 0 дописывается 1, получилось 01. Затем к 01 дописывается 10, получилось 0110. Затем к 0110 дописывается 1001, получилось 01101001. Затем получится 0110100110010110 и т.д.

По данному числу \(n \le 1000\) постройте первые \(n\) элементов последовательности Туе–Морса в виде списка из чисел 0 и 1.

Например для n = 12 необходимо вернуть список:

[0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1]

Примечание: вряд ли вам удастся построить нужный генератор, используя только определение последовательности Туе–Морса.

IDE