Matrizes

Strings, Tuplas e Listas são exemplos de sequências em Python, representando coleções unidimensionais. Matrizes, por sua vez, são estruturas bidimensionais organizadas em linhas e colunas, a exemplo de:

matriz1

na qual há 3 linhas e 4 colunas.

In [ ]:
# Uma estrutura bidimensional (matriz)
matriz = [[10, 20, 30, 40],
          [-5, -7, -3, -2],
          [47, 43, 49, 53]]
print(matriz)

Como temos duas dimensões, são necessários dois índices para identificar um elemento específico na matriz. Por convenção, em geral o primeiro índice identifica a linha, enquanto que o segundo índice identifica a coluna

In [ ]:
# Pegar o segundo elemento (índice 1) da terceira linha (índice 2)
matriz[2][1]
In [ ]:
# Pegar o último elemento da matriz (último elemento da última linha)
matriz[-1][-1]
In [ ]:
# Alterar o valor de uma posição da matriz
matriz[2][0] = 500
print(matriz)

Aninhamento de estruturas

Em realidade, a construção da matriz acima faz uso de um recurso disponível em Python chamado de aninhamento de estruturas de dados, ou seja, a possibilidade de um elemento de uma lista ser uma outra lista (ou uma tupla).

matriz2

Essa noção é importante para compreender algumas operações sobre essa estrutura.

In [ ]:
# Pegar a segunda linha (uma lista) da matriz
linha = matriz[1]
print(linha)
In [ ]:
# Obter o número de linhas da matriz (tamanho da primeira dimensão)
print(len(matriz))

print(len(matriz[0]))

Para obter o número de colunas da matriz (tamanho da segunda dimensão) basta pegarmos o tamanho de qualquer uma das 3 listas que definem as linhas.

In [ ]:
# Obter o número de colunas da matriz (tamanho da segunda dimensão)
# que corresponde ao tamanho de qualquer de suas linhas
print(len(matriz[0]))
print(len(matriz[1]))
print(len(matriz[2]))

Estruturas mistas e não uniformes

Como trata-se de estruturas aninhadas, os elementos de cada lista (as linhas) podem ter tamanho distintos. Os valores podem, também, ser de tipos distintos.

matriz3

In [ ]:
# Uma estrutura bidimensional cujas linhas possuem quantidades diferentes de elementos
bi = [[10, 20, 30, 40], [-5, -7], [47, 43, 49]]
print(len(bi))
print(len(bi[0]))
print(len(bi[1]))
print(len(bi[2]))
In [ ]:
# Matriz como elementos não homogêneos
lista1 = [ ["Huguinho", "Zézinho", "Luizinho"],
           [10, 50],
           [3.14, 2.15] ]
print(lista1)
In [ ]:
# Uma lista de duplas
lista2 = [(4, 5), (5, 15), (-5, 10)]
print(lista2)
In [ ]:
#i Imprimir o primeiro elemento da última dupla
print(lista2[-1][0])

Operações com matrizes

In [ ]:
# Lendo uma matriz 
# A primeira linha tem dois valores inteiros n e m correspondentes as dimensões da matriz
# Em seguinda vem n linhas, cada uma delas com os m valores que definem cada linha

n, m = [int(x) for x in input().split()]
matriz = []
for _ in range(n):
    matriz.append([int(x) for x in input().split()])
In [ ]:
# Lendo uma matriz 
# O código acima pode ser escrito de forma mais sintética como:

n, m = [int(x) for x in input().split()]
matriz = [[int(x) for x in input().split()] for _ in range(n)]
In [ ]:
# Cria uma matriz de n linhas e m colunas com valor 0 (zero) para seus elementos

n_linhas = 3
m_colunas = 4
matriz = [ [0] * m_colunas for _ in range(n_linhas) ]
print(matriz))
In [ ]:
# Imprimir a matriz, linha a linha

matriz = [ [10, 15, 18], [7, 5, 3]]

for linha in matriz:
    print(* linha)
In [ ]:
# Somar todos os elementos da matriz
# Percorrer todas as linhas, e para cada linha percorrer a lista correspondente às colunas

matriz = [ [10, 15, 18], [7, 5, 3]]

soma = 0
for linha in matriz:
    for x in linha:
        soma += x
print(soma)
In [ ]:
# Somar todos os elementos da matriz
# O código acima pode ser escrito de forma mais sintética como:

matriz = [ [10, 15, 18], [7, 5, 3]]

soma = 0
for linha in matriz:
    soma += sum(linha)
print(soma)
In [ ]:
# Somar todos os elementos da matriz
# O código acima pode ser escrito de forma aind mais sintética como:

matriz = [ [10, 15, 18], [7, 5, 3]]

soma = sum( sum(linha) for linha in matriz )
print(soma)
In [ ]:
# Somar todos os elementos da matriz
# Com percorrimento das linhas e para cada linha de seus valores (as colunas) baseado nos índices.

matriz = [ [10, 15, 18], [7, 5, 3]]

soma = 0
for i in range(len(matriz)):
    for j in range(len(matriz[i])):
        soma += matriz[i][j]
print(soma)
In [ ]:
# Somar todos os elementos da matriz
# Agora com percorrimento das colunas e para cada coluna de seus valores (as linhas) baseado nos índices.

matriz = [ [10, 15, 18], [7, 5, 3]]

soma = 0
for j in range(len(matriz[0])):
    for i in range(len(matriz)):
        soma += matriz[i][j]
print(soma)

Matriz Transposta

Em matemática, matriz transposta é a matriz que se obtém pela troca (transposição) de linhas por colunas de uma dada matriz.

Uma matriz:

102030
567

Sua transposta:

105
206
307
In [ ]:
#Obter a matriz transposta

matriz = [ [10, 20, 30], [5, 6, 7] ]

num_linhas = len(matriz)
num_colunas = len(matriz[0])

transposta = [ [0] * num_linhas for _ in range(num_colunas) ]
for i in range(num_linhas):
    for j in range(num_colunas):
        transposta[j][i] = matriz[i][j]

print(transposta)

Sudoku

Sudoku é um jogo de lógica cujo objetivo é distribuir números de 1 a 9 em cada uma das células numa grade de 9x9 de tal forma que não haja repetição de um desses números em cada uma das linha, em cada uma das colunas ou em cada uma das subgrades (regiões) de 3x3 do tabuleiro.

sudoku

O tabuleiro acima apresenta uma possível solução para esta distribuição. Desejamos, agora, verificar se de fato esta distribuição de números atende às restrições acima mencionadas.

In [ ]:
# Lê os números do tabuleiro de Sudoku
tabuleiro = [ [int(x) for x in input().split()] for _ in range(9) ]

# Supõe, por hipótese, que o tabuleiro está corretamente preenchido e procura situação que negue esta hipótese
sudoku = True

# Verifica se há repetição de número nas linhas
for lin in range(9):
    c = set( tabuleiro[lin] )
    if len(c) != 9:
        sudoku = False
        break

# Verifica se há repetição de número nas colunas
if sudoku:
    for col in range(9):
        c = set( tabuleiro[lin][col] for lin in range(9) )
        if len(c) != 9:
            sudoku = False
            break

# Verifica se há repetição de número nas subgrades de 3x3
for lin in range(0, 9, 3):   
    if not sudoku:
        break
    for col in range(0, 9, 3):
        c = set( tabuleiro[lin][col:col+3] + tabuleiro[lin+1][col:col+3] + tabuleiro[lin+2][col:col+3] )
        if len(c) != 9:
            sudoku = False
            break
            
print(sudoku)