IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)

Commentaires

  1. Avatar de User
    • |
    • permalink
    Petite mise à jour des tableaux
  2. Avatar de User
    • |
    • permalink
    Bonjour,

    Oui la bonne curiosité merci pour ces précisions.

    En fait concernant l'optimisation l'objectif était surtout ensuite d'économiser de la mémoire (2nde version).

    Cdlt,
  3. Avatar de unanonyme
    • |
    • permalink
    Bonjour,

    Merci pour votre réponse.

    Expert, je ne sais pas, curieux, volontiers.

    Oui la lisibilité en a pris un coup pour supprimer les divisions et modulos.
    Le manque de commentaire n'y aide pas et la relecture me fait penser
    que ce n'est pas une implémentation optimale.

    Mais il n'y a vraiment rien de spécial la dedans, la série produite présente
    des cas particuliers pour faire pivoter les valeurs.
    L'algo s'appuie la dessus. (4, 1) (3, 1, 1) (2, 1, 1, 1) etc

    Bonne journée.
  4. Avatar de User
    • |
    • permalink
    Bonjour et merci pour votre message,

    Tout ce qu'on apprend en maths ou dans d'autres matières n'a pas toujours une application directe, mais déjà avoir la satisfaction de comprendre les choses, en rendant accessible un sujet pas forcément simple de prime abord ça peut être sympa..

    Concernant le code, l'objectif était surtout d'écrire du code le plus lisible possible, sans chercher forcément la performance, car le billet ne s'adresse pas à des experts en programmation En tout cas chercher le meilleur compromis entre les deux.

    Je voulais aussi proposer quelque chose de différent de ce qu'on trouve habituellement sur les forums, autre chose par exemple que les fonctions récursives..

    En tout cas merci pour le code, je ne connais pas Go

    Cordialement,
  5. Avatar de unanonyme
    • |
    • permalink
    Bonjour,

    Merci pour la ressource, intéressant ! Question annexe, ça sert à quel genre d'applications ces calculs ?

    Par curiosité j'ai porté votre bout de code en Go, on fait x2.
    C'est pas mal pour un portage sans douleur.

    Code Go : Sélectionner tout - Visualiser dans une fenêtre à part
    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
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    func partition_suivante(a []int, k, N int) ([]int, int, int) {
    	// # Construit la partition b qui suit la partition a dans la liste des partitions.
    	// # a : liste des entiers représentant la partition passée en argument
    	// # k : rang du dernier entier dans a strictement supérieur à 1
    	// # N : nombre d'entiers qui valent 1 dans la liste a
     
    	b := make([]int, 0, k+3)
    	b = append(b[:0], a[:k]...)
     
    	// # pour tout j < k, on définit b[j] = a[j] : a = [2, 2, 1] -> b = [2]
    	// b := a[:k]
     
    	// # On ajoute (a[k] - 1) à la liste b : b[k] = a[k] - 1 : a = [2, 2, 1] -> b = [2, 1]
    	b = append(b, a[k]-1)
     
    	// # En notant N+1 = b[k]*q + r la division euclidienne de N+1 par b[k]
    	// # On obtient le quotient q et le reste r de cette division.
    	q := int(math. Floor(float64(N+1) / float64(b[k])))
    	r := (N + 1) % b[k]
     
    	// # On évalue ensuite les entiers b[j] = b[k] pour k < j < k + q + 1 : a = [2, 2, 1] -> b = [2, 1] + 2*[1] = [2, 1, 1, 1]
    	for e := 0; e < q; e++ {
    		b = append(b, b[k])
    	}
     
    	// # Si le reste r est non nul.
    	if r != 0 {
    		// # On ajoute l'entier r à la liste b : b[k+q+1] = r
    		b = append(b, r)
    	}
     
    	// # calcul des valeurs de k et N pour la nouvelle partition b
    	for b[k] != 1 {
    		k++
    		if k == len(b) {
    			break
    		}
    	}
     
    	// # renvoi de la partition b suivant la partition a, du rang k dans b, et du nombre N d'entiers valant 1 dans b
    	return b, k - 1, len(b) - k
    }


    Si on pousse l'optimisation un petit peu on fait encore 2x, mais si on est vraiment motivé je crois qu'on peut faire beaucoup mieux en généralisant cette ébauche.
    Ici, seul les 1 sont optimisés, on peut généraliser cela et gagner sur les durées d'allocations.

    Code Go : Sélectionner tout - Visualiser dans une fenêtre à part
    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
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    type partition struct {
    	a    []int
    	n    int
    	ones int
    }
     
    func (p partition) is_last() bool {
    	return len(p.a) < 1 || p.a[0] == 1
    }
     
    func (p partition) len() int {
    	return len(p.a) + p.ones
    }
     
    func (p partition) slice() []int {
    	out := make([]int, p.len())
    	copy(out, p.a)
    	for i := 0; i < p.ones; i++ {
    		out[len(p.a)+i] = 1
    	}
    	return out
    }
     
    func partition_from_slice(s []int) partition {
     
    	n := 0
    	i := 0
    	for ; i < len(s); i++ {
    		if s[i] == 1 {
    			break
    		}
    		n += s[i]
    	}
    	ones := len(s) - i
     
    	return partition{
    		a:    s[:i],
    		n:    n + ones,
    		ones: ones,
    	}
    }
     
    func gen_part(p partition) partition {
     
    	if p.is_last() {
    		return p
    	}
     
    	n := p.a[len(p.a)-1]
     
    	if n == 2 {
    		np := partition{
    			a:    make([]int, len(p.a)-1),
    			n:    p.n,
    			ones: p.ones + 2,
    		}
    		copy(np.a, p.a)
    		return np
    	}
     
    	if len(p.a) == 1 {
    		np := partition{
    			a:    make([]int, 0, 10),
    			n:    p.n,
    			ones: 0,
    		}
    		j := 0
    		m := n - 1
    		for {
    			if j+m > np.n {
    				break
    			}
    			np.a = append(np.a, m)
    			j += m
    		}
    		if u := np.n - j; u > 1 {
    			np.a = append(np.a, u)
    		} else if u > 0 {
    			np.ones++
    		}
    		return np
    	}
     
    	if p.ones < 1 {
    		np := partition{
    			a:    make([]int, len(p.a)),
    			n:    p.n,
    			ones: 1,
    		}
    		copy(np.a, p.a)
    		np.a[len(p.a)-1]--
    		return np
    	}
     
    	np := partition{
    		a:    make([]int, len(p.a)+1),
    		n:    p.n,
    		ones: 0,
    	}
    	copy(np.a, p.a)
    	n--
    	ones := p.ones + 1
    	np.a[len(p.a)-1] = n
    	if n > ones {
    		np.a[len(p.a)] = ones
    	} else {
    		np.a[len(p.a)] = n
    		o := 0
    		for _, j := range np.a {
    			o += j
    		}
    		for o < p.n {
    			r := p.n - o
    			if r >= n {
    				np.a = append(np.a, n)
    			} else if r > 1 {
    				np.a = append(np.a, r)
    			} else {
    				np.ones++
    				break
    			}
    			o += n
    		}
    	}
    	return np
    }

    Quelques cas de tests pour montrer l'utilisation.

    Code Go : Sélectionner tout - Visualiser dans une fenêtre à part
    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
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    package main
     
    import (
    	"fmt"
    	"reflect"
    	"testing"
    )
     
    func TestGenPart(t *testing.T) {
     
    	type tcase struct {
    		input      []int
    		expect     []int
    		expect_end bool
    	}
     
    	cases := []tcase{
    		{
    			input:  []int{15},
    			expect: []int{14, 1},
    		},
    		{
    			input:  []int{10, 5},
    			expect: []int{10, 4, 1},
    		},
    		{
    			input:  []int{7, 1, 1, 1, 1, 1, 1, 1, 1},
    			expect: []int{6, 6, 3},
    		},
    		{
    			input:  []int{4, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1},
    			expect: []int{3, 3, 3, 3, 3},
    		},
    		{
    			input:  []int{6, 6, 3},
    			expect: []int{6, 6, 2, 1},
    		},
    		{
    			input:      []int{1},
    			expect:     []int{1},
    			expect_end: true,
    		},
    		{
    			input:      []int{1, 1, 1},
    			expect:     []int{1, 1, 1},
    			expect_end: true,
    		},
    		{
    			input:      []int{2, 1, 1},
    			expect:     []int{1, 1, 1, 1},
    			expect_end: true,
    		},
    		{
    			input:      []int{2, 1, 1, 1, 1, 1, 1},
    			expect:     []int{1, 1, 1, 1, 1, 1, 1, 1},
    			expect_end: true,
    		},
    		{
    			input:  []int{3, 3, 3, 3, 3},
    			expect: []int{3, 3, 3, 3, 2, 1},
    		},
    		{
    			input:  []int{3, 2, 1},
    			expect: []int{3, 1, 1, 1},
    		},
    		{
    			input:  []int{4, 4},
    			expect: []int{4, 3, 1},
    		},
    		{
    			input:  []int{5, 3},
    			expect: []int{5, 2, 1},
    		},
    		{
    			input:  []int{18, 2},
    			expect: []int{18, 1, 1},
    		},
    		{
    			input:  []int{18, 1, 1},
    			expect: []int{17, 3},
    		},
    		{
    			input:  []int{6, 6, 6, 1, 1},
    			expect: []int{6, 6, 5, 3},
    		},
    		{
    			input:  []int{14, 3, 1, 1, 1},
    			expect: []int{14, 2, 2, 2},
    		},
    		{
    			input:  []int{15, 3, 1, 1},
    			expect: []int{15, 2, 2, 1},
    		},
    		{
    			input:  []int{12, 4, 1, 1, 1, 1},
    			expect: []int{12, 3, 3, 2},
    		},
    	}
     
    	for i, c := range cases {
    		p := partition_from_slice(c.input)
    		res := gen_part(p)
     
    		if !reflect.DeepEqual(res.slice(), c.expect) {
    			fmt.Printf("%#v\n", p)
    			fmt.Printf("%#v\n", res)
    			t.Fatalf(`invalid result at #%v
    		expected    %#v
    		result      %#v`, i, c.expect, res.slice())
    		}
    		if c.expect_end != res.is_last() {
    			t.Fatalf(`invalid result at #%v
    		expected    %#v
    		result      %#v`, i, c.expect_end, res.is_last())
    		}
    	}
    }

    Évidemment, si on pouvait trouver à répartir les de calculs sur plusieurs fils d'exécution on gagnerait d'autant plus, mais la répartition de la charge n'est pas évidente.

    Bref, des babioles sans conséquence.

    Bonne journée.
    Mis à jour 12/11/2023 à 13h47 par f-leb (balises [CODE=Go]...[/CODE] pour coloration syntaxique)
  6. Avatar de f-leb
    • |
    • permalink
    Citation Envoyé par User
    Merci Fabien

    Mais tu as en partie raison, comme je l'indique plus il y a de billes sur la planche et plus ça ralenti, d'où l'utilité du bouton finaliser qui donne le résultat de la simulation

    Oui oui, mais vu la lenteur avec peu de billes alors que ça fonctionne très bien dans une VM Linux sur la même machine, j'ai vraiment un problème pas normal sous Windows
  7. Avatar de User
    • |
    • permalink
    Merci Fabien

    Mais tu as en partie raison, comme je l'indique plus il y a de billes sur la planche et plus ça ralenti, d'où l'utilité du bouton finaliser qui donne le résultat de la simulation
  8. Avatar de f-leb
    • |
    • permalink
    Marrant Par contre, l'animation ralentit sérieusement chez moi au fur et à mesure de l'apparition des billes. Bizarre...


    Edit : Programme qui fonctionne très bien dans une VM sous Linux, j'ai donc une m#@! à résoudre sous Windows
    Mis à jour 05/07/2023 à 17h51 par f-leb
  9. Avatar de User
    • |
    • permalink
    Ah ouais en effet très didactique pour les débutants

    Merci Fabien pour ce complément
  10. Avatar de f-leb
    • |
    • permalink
    Super

    pour le débutant avec Thonny, tu peux visualiser la pile en exécutant le programme en mode débogage (pas-à-pas) :



    Une nouvelle fenêtre s'ouvre quand tu empiles un nouveau contexte, la fenêtre se ferme quand tu dépiles le contexte. C'est assez visuel
  11. Avatar de User
    • |
    • permalink
    Merci à toi pour le commentaire et les liens
  12. Avatar de pcouaillier
    • |
    • permalink
    Très bon tutoriel pour un débutant en python et en programmation.

    En entreprise ou pour des projets personnels, beaucoup de personnes s'arrêtent à ce niveau.

    Je regrette l'absence d'ouverture en fin de billet vers de l'outillage professionnel (profileur et traceur).

    Voici deux exemples d'outils :
    - cProfile : https://docs.python.org/3/library/profile.html
    - opentelemetry-python : https://opentelemetry-python.readthe...l#useful-links
  13. Avatar de User
    • |
    • permalink
    Citation Envoyé par FALLOU_N
    Merci pour l'article. Je voulais juste savoir self.reduire() (def reduire() ) c'est une fonction que vous avez crée avant si oui est ce qu'il y a moins de voir le contenu.
    Merci et bonne année, oui la méthode réduire est dans le module complet contenant la classe et disponible à la fin
    Cdlt
  14. Avatar de User
    • |
    • permalink
    C'est vrai que le mot est en trop, je n'avais pas vérifié, je te remercie, je corrige
  15. Avatar de web bea
    • |
    • permalink
    Merci pour ce rappel sur le raisonnement par récurrence.
    Toutefois je souhaiterais préciser un point sur la définition que tu donnes :

    Lorsque ces deux étapes sont réalisées, on admet sans démonstration que la proposition Pn est vraie pour tout naturel n≥n0.
    Le principe du raisonnement par récurrence c'est que si on a démontré que P(n0) est vraie et que P(n) entraine P(n+1) alors on a démontré que P(n) était vraie pour tout entier naturel n >= n0
    Du coup l'emploi de l'expression "on admet sans démonstration" alors que l'on vient précisément de fournir une démonstration ne me paraît pas vraiment approprié


    Il convient aussi de mentionner que tout problème qui possède une solution récursive possède aussi une solution itérative (et réciproquement).
    Ainsi une fonction python récursive peut toujours être réécrite sous une forme purement itérative (ça ne sera pas forcément simple à faire, mais en tout cas c'est toujours faisable).
  16. Avatar de User
    • |
    • permalink
    Citation Envoyé par houariES
    Merci pour cet article
    Merci pour votre retour
  17. Avatar de houariES
    • |
    • permalink
    Merci pour cet article
  18. Avatar de User
    • |
    • permalink
    Citation Envoyé par Pierre Fauconnier
    Hé hé... Un petit défi pas si petit que ça... Merci Denis de nous proposer d'activer nos méninges. C'est bien mieux que ce qui passait à la télé.

    Je te souhaite une belle année 2021, pleine de tutos et de billets de blog, et pleine aussi de tout ce que tu auras envie d'y mettre...
    Merci Pierre

    Je te souhaite également une Excellente année 2021, créative avec surtout la santé pour toi et tes proches
    Mis à jour 01/01/2021 à 15h17 par User
  19. Avatar de Pierre Fauconnier
    • |
    • permalink
    Hé hé... Un petit défi pas si petit que ça... Merci Denis de nous proposer d'activer nos méninges. C'est bien mieux que ce qui passait à la télé.

    Je te souhaite une belle année 2021, pleine de tutos et de billets de blog, et pleine aussi de tout ce que tu auras envie d'y mettre...
  20. Avatar de esamy
    • |
    • permalink
    Citation Envoyé par User
    Bonjour,

    En fait le sous-formulaire inséré dans le formulaire principal n'est pas en mode feuille de données. Son affichage par défaut est en mode formulaires continus (cf. propriété "affichage par défaut" du sous-formulaire)

    Une fois en mode continu, vous pouvez ajoutez dans la section détail du sous-formulaire des contrôles zone de texte ou bouton de commande. L'en-tête servant à mettre les étiquettes des contrôles zone de texte ou autre.

    Cdlt,

    Ok Un grand merci. Top !
    Et surtout quelle réactivité !!!
Page 1 sur 2 12 DernièreDernière