from jyquickhelper import add_notebook_menu
add_notebook_menu()

"""
Explanation: 1A - Enoncé 15 novembre 2021 - rattrapage
Correction de l'examen du 15 novembre 2021.
End of explanation
"""


def surface(longueur, largeur):
    return longueur * largeur

surface(3, 4)

"""
Explanation: Exercice 1 : optimisation de volume
On cherche à expliquer la forme des briques de lait. On rappelle quelques formules :

aire d'une surface : S = longueur x largeur
volume d'une brique : V = longueur x largeur x hauteur

Q1 : écrire une fonction qui calcule l'aire d'une surface
End of explanation
"""


def volume(longueur, largeur, hauteur):
    return longueur, largeur, hauteur

volume(3, 4, 5)

"""
Explanation: Q2 : écrire une fonction qui calcule le volume d'une brique
End of explanation
"""


def surface_brique(longueur, largeur, hauteur):
    return (surface(longueur, largeur) + 
            surface(largeur, hauteur) + 
            surface(hauteur, longueur)) * 2

surface_brique(3, 4, 5)

"""
Explanation: On veut connaître les dimensions de la brique idéale d'un litre : son volume est 1 et sa surface (la somme des surfaces de toutes les faces) est minimale. Ceci afin de minimiser l'utilisation de matières premières.
Q3 : écrire une fonction qui retourne la somme des surfaces des faces d'une brique
End of explanation
"""


import numpy

def brique_optimale(ensemble):
    meilleur = None
    
    for longueur in ensemble:
        for largeur in ensemble:
            hauteur = 1 / (longueur * largeur)
            surf = surface_brique(longueur, largeur, hauteur)
            if meilleur is None or surf < meilleur:
                meilleur = surf
                solution = longueur, largeur, hauteur
    return meilleur, solution


ensemble = (numpy.arange(20) + 1) / 10
brique_optimale(ensemble)

"""
Explanation: Q4 : la brique optimale
On considère l'ensemble [0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1., 1.1, 1.2, 1.3, 1.4, 1.5, 1.6, 1.7, 1.8, 1.9, 2.]. On fait varier plusieurs dimensions dans cet ensemble, on ne garde que celle dont le volume est 1 et la surface minimale. Quelles sont les dimensions optimales ?
End of explanation
"""


def brique_optimale_surplus(ensemble):
    meilleur = None
    
    for longueur in ensemble:
        for largeur in ensemble:
            hauteur = 1 / (longueur * largeur)
            surf = (surface_brique(longueur, largeur, hauteur) + 
                    surface(longueur, largeur) + largeur ** 2)
            if meilleur is None or surf < meilleur:
                meilleur = surf
                solution = longueur, largeur, hauteur
    return meilleur, solution


ensemble = (numpy.arange(20) + 1) / 10
brique_optimale_surplus(ensemble)

"""
Explanation: Q5 : on inclut la surface nécessaire pour coller les extremités
Pour fermer une brique, il faut pouvoir coller les faces entre elles. La surface additionnelle est égale à une fois la plus petite des faces + la surface d'un carré de côté la plus petite dimension. Modifier la fonction précédente pour en tenir compte.
End of explanation
"""


def brique_optimale_surplus_deux_litres(ensemble):
    meilleur = None
    
    for longueur in ensemble:
        for largeur in ensemble:
            if largeur > longueur:
                continue
            hauteur = 1 / (longueur * largeur)
            surf1 = (surface_brique(longueur, largeur, hauteur) + 
                     surface(longueur, largeur) + largeur ** 2)
            surf2 = surf1 - surface(largeur, hauteur) * 2
            surf = surf1 * 2 / 3 + surf2 / 3  # donc autant de litres de lait dans chacun des contenants
            if meilleur is None or surf < meilleur:
                meilleur = surf
                solution = longueur, largeur, hauteur
    return meilleur, solution


ensemble = (numpy.arange(20) + 1) / 10
brique_optimale_surplus_deux_litres(ensemble)

"""
Explanation: Dans cette écriture, le programme suppose implicitement que largeur est le plus petit côté. Ce n'est pas toujours le cas. Quand ce n'est pas le cas, on peut vérifier en permutant longueur et largeur, la surface est plus grande. L'optimisation ne choisira pas cette solution. Si ce n'était pas le cas, il suffirait d'exclure tous les cas où largeur &gt; longueur.
Q6 :  une bouteille de deux litres deux fois plus large
Le producteur souhaite écouler la moitié de sa marchandise avec des bouteilles de lait de deux litres, aussi hautes et longues mais deux fois plus large pour pouvoir les stocker facilement. La surface de cette bouteille est celle-ci :
surface_brique2(longueur, largeur, hauteur) = surface_brique(longueur, largeur, hauteur) - 2 * surface(largeur, hauteur).
Quelles sont les dimensions optimales ?
End of explanation
"""


def messages(n):
    possibilites = [1 for i in range(n + 1)]
    for i in range(2, n + 1):
        possibilites[i] = possibilites[i-1] + possibilites[i-2]
    return possibilites

messages(10)

"""
Explanation: Q7 : petite brique en bleue, grosse brique en rouge
Le producteur se sert d'une rangée de longueur de 10 briques de 1 litre dans laquelle il insère des briques de deux litres pour envoyer des messages codés (en binaire).
Example de message : A A B B A B B A B B A = une bouteille de 1 litre, B = moitié d'une bouteille de deux litres.
Combien y a-t-il de possibilités dans une rangée d'une longueur de 10 briques de 1 litre.
End of explanation
"""


