#!/usr/bin/env python3 # -*- coding: utf-8 -*- """ Created on Tue Jan 5 09:56:50 2021 @author: andrea """ # analisi di un problema ricorsivo # 1) riduzione: ogni problema può essere ridotto a 1 o più sottoproblemi più piccoli # 2) caso base: esistono 1 o più casi base di cui si conosce la soluzione # 3) convergenza: tutti i problemi portano ad un caso base per riduzione # 4) costruzione: è possibile ottenere la soluzione più generale # dalle soluzioni dei sottoproblemi # Rotazione ricorsiva di una immagine ha H=L = potenza di 2 # riduzione: dividiamo l'immagine in 4 parti # caso base: 1*1 pixel => non c'è bisogno di muovere i pixel # convergenza: ogni volta dividiamo per 2 si H che L # la costruzione della soluzione: spostiamo ciascuna delle 4 parti in senso antiorario # e ruotiamo ciascuna delle 4 parti su se stessa # per dividere una immagine in 4 # dividiamo le righe in due blocchi e ciascuna delle righe in due parti # torniamo come risultato la tupla di 4 sotto immagini # 1234 5678 # 1234 5678 # 1234 5678 # 1234 5678 # # 1234 5678 # 1234 5678 # 1234 5678 # 1234 5678 def dividi_in_4(matrice): lato = len(matrice) sopra = matrice[:lato//2] sotto = matrice[lato//2:] alto_sx = [ riga[:lato//2] for riga in sopra ] alto_dx = [ riga[lato//2:] for riga in sopra ] basso_sx = [ riga[:lato//2] for riga in sotto ] basso_dx = [ riga[lato//2:] for riga in sotto ] return alto_sx, alto_dx, basso_sx, basso_dx M = [ [1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12], [13, 14, 15, 16]] print(dividi_in_4(M)) # per riunire 4 sottoimmagini # concateniamo le rghe delle due sottoimmagini affiancate # mettiamo una dopo l'altra le serie di rghe delle due parti sopra/sotto def unisci_matrici(alto_sx, alto_dx, basso_sx, basso_dx): sopra = [ sx+dx for sx,dx in zip(alto_sx, alto_dx) ] sotto = [ sx+dx for sx,dx in zip(basso_sx, basso_dx) ] return sopra + sotto print(unisci_matrici(*dividi_in_4(M))) # per ruotare l'immagine # se la dimensione è 1 torno la stessa immagine # altrimenti la divido in 4 sottoimmagini # ruoto ciascuna delle sottoimmagini # riordino le sottoimmagini ruotate spostandole di posto # le riunisco in una sola immagine # a_dx_r <= b_dx_r # v ^ # a_sx_r => b_sx_r def ruota_immagine(matrice): L = len(matrice) if L == 1: return matrice else: a_sx, a_dx, b_sx, b_dx = dividi_in_4(matrice) a_sx_r = ruota_immagine(a_sx) a_dx_r = ruota_immagine(a_dx) b_sx_r = ruota_immagine(b_sx) b_dx_r = ruota_immagine(b_dx) return unisci_matrici(a_dx_r, b_dx_r, a_sx_r, b_sx_r) print(*M, sep='\n') print(*ruota_immagine(M), sep='\n') import images img = images.load('scarabocchio.png') ruotata = ruota_immagine(img) images.save(ruotata, 'scarabocchio-ruotata.png') # come definire un oggetto "callable" che si comporta # come una funzione usando anche valori di stato in esso # contenuti class Chiamabile: def __init__(self, VALORE): self.V = VALORE def __call__(self, a, b, c): return a+b+c+self.V c1 = Chiamabile(33) print(c1(3, 7, 9))