Comparer les numéros de version


26

Lorsque nous publions un logiciel, nous lui attribuons un numéro de version. Et les utilisateurs peuvent vouloir mettre à jour vers la dernière version de certains logiciels. C'est donc le moment de découvrir quelle version devrait être la plus récente.

Contribution

Saisissez deux numéros de version sous forme de chaînes.

Dans le cadre de ce défi, nous ne prenons en charge que les numéros de version qui sont des chiffres joints par des points.

  • Un numéro de version est une chaîne qui ne peut contenir que des chiffres ( 0~ 9) et des points ( .).
  • Les points ne seraient pas le premier / dernier caractère d'un numéro de version.
  • Il doit y avoir des chiffres entre les points. Deux points ne peuvent apparaître en continu.
  • Tous les numéros d'un numéro de version seraient inférieurs à 2 16 .

Sortie

Comparez les numéros de version saisis et indiquez si le premier est supérieur / égal à / inférieur au second. Vous êtes autorisé à choisir l'une des présentations suivantes:

  • Utilisez un nombre positif / zéro / nombre négatif, tandis que zéro signifie égal;
  • Utilisez trois valeurs distinctes constantes;

Comparant

Vous n'êtes pas obligé d'implémenter l'algorithme décrit dans cette section. Votre soumission est valide tant qu'elle donne la même sortie avec cet algorithme.

  • Les numéros de version sont des nombres décimaux joints par des points. Nous avons d'abord divisé les deux numéros de version en tableaux de nombres;
  • Remplir la fin des tableaux avec des zéros pour leur donner la même longueur;
  • Comparez du premier article au dernier:
    • Si les deux éléments du tableau sont différents, le plus grand nombre signifie un plus grand numéro de version
    • S'ils sont identiques, continuez à comparer les éléments suivants;
    • Si tous les éléments du tableau sont égaux, les deux versions sont égales.

Cas de test

version1  version2  result
2         1         >
1.0.0     1         =
1.0       1.0.0     =
1.2.42    1.2.41    >
1.1.56789 1.2.0     <
1.10      1.2       >
1.20      1.150     <
18.04     18.4      =
7.010     7.8       >
1.0.0.1.0 1.00.00.2 <
00.00.01  0.0.0.1   >
0.0.1     0.1       <
42.0      4.2.0     >
999.999   999.999.1 <
2018.08.1 2018.08   >


.NET a un objet Version, mais un seul caractère n'est pas pris en charge :(
Brian J

@BrianJ et l'ajout de '.0' coûte à de nombreux caractères? :)
RobAu

Eh bien, il attend en fait 2, 3 ou 4 portions. Donc, il échoue sur le cas de test 1.0.0.1.0 (bien que j'aie d'abord essayé votre idée :))
Brian J

Je pense que Windows a un intégré qui fera cela: StrCmpLogicalW
bace1000

Réponses:



6

05AB1E (hérité) , 15 14 13 octets

'.¡0ζε`.S}0K¬

Sorties -1 [] 1pour < = >respectivement.

-1 octet grâce à @Emigna .

Essayez-le en ligne ou vérifiez tous les cas de test .

Explication:

'.¡              # Split on dots
                 #  i.e. ['1.0.1.1.0','1.00.2.0']
                 #   → [['1','0','1','1','0'],['1','00','2','0']]
   0ζ            # Zip, swapping rows and columns, using '0' as filler
                 #  i.e. [['1','0','1','1','0'],['1','00','2','0']]
                 #   → [['1','1'],['0','00'],['1','2'],['1','0'],['0','0']]
     ε   }       # Map each:
      `          #  Push both values to the stack
       .S        #  And calculate the signum (1 if a>b; -1 if a<b; 0 if a==b)
                 #   i.e. [['1','1'],['0','00'],['1','2'],['1','0'],['0','0']]
                 #    → [0,0,-1,1,0]
          0K     # Remove all zeros
                 #  i.e. [0,0,-1,1,0] → [-1,1]
            ¬    # Then take the head as result
                 #  i.e. [-1,1] → -1

1
Vous pouvez utiliser à la 0Kplace de ʒĀ}.
Emigna

@Emigna Ah bien sûr .. Merci.
Kevin Cruijssen

5

R , 32 octets

rank(numeric_version(scan(,"")))

Essayez-le en ligne!

Utilisation d'un R intégré

Sorties 1 2, 1.5 1.5, 2 1moins, égal, supérieur.


Meilleur jusqu'à présent, sans intégré:

R , 151 142 125 107 107 octets

function(v,L=strsplit(v,'\\.'))Find(c,sign(Reduce('-',Map(as.double,Map(c,L,Map(rep,0,rev(lengths(L))))))))

Essayez-le en ligne!

Code déroulé avec explication:

function(v){             # character vector of 2 elements as function arg;
  L=strsplit(v,'\\.')    # obtain a list of two character vectors
                         # with the separated version numbers;
  R=rev(lengths(L))      # store in vector R the lengths of the 2 vectors and reverse it;
  M1=Map(rep,0,R)        # create a list of 2 vector containing zeros
                         # repeated R[1] and R[2] times;
  M2=Map(c,L,M1)         # append to the vectors in list L the zeros in M1;
  M3=Map(as.double,M2)   # convert the character vectors in M2 to double;
  w=sign(Reduce('-',M3)  # compute the sign of element by element difference M[[1]] - M[[2]]);
  Find(c,w)            # returns the first non zero element in w, if none return NULL;
}
# N.B. as.double is necessary because "0XX" is interpreted as octal by strtoi unless 
#      we use strtoi(x,10) which is exactly the same length of as.double(x)

Sorties -1, NULL, 1moins, égal, supérieur.


Concept original, golfé en utilisant sapply, [<-et %*%:

R , 129 octets

function(x,y=strsplit(x,"\\."),w=sign(sapply(y,function(x)strtoi("[<-"(rep(0,max(lengths(y))),seq(x),x),10))%*%c(1,-1)))w[!!w][1]

Essayez-le en ligne!

Vous avez maintenant une liste de deux vecteurs d'entiers de longueur égale. Calculez les différences par paire en utilisant Reduceet sortez le premier élément non nul en utilisant la petite w[!!w][1]forme délicate à la fin.

Sorties -1, NA, 1moins, égal, supérieur.


Impressionnant! Golf rapide: nouvelle ligne supplémentaire à la fin de votre code - elle devrait être de 150 octets;)
JayCe

réduire le nombre de variables nommées ... . Je pense qu'il existe un moyen de le faire en utilisant une matrice au lieu de listes, mais je n'ai pas encore trouvé comment le faire.
JayCe

1
Vous pouvez le réduire à 100 octets en utilisant scan function(a,b,d=scan(t=a,se='.'),e=scan(t=b,se='.'),f=1:max(lengths(list(d,e))),g=d[f]-e[f])g[!!g][1](ou 106 si vous souhaitez renvoyer -1, NA, 1 non (négatif), NA, (positif).
mnel

1
@mnel la solution de 100 octets a besoin d'un peu de travail. Il échoue sur les deux derniers cas de test. Le rembourrage doit être 0et non (implicitement) NA. J'ai fait de la réponse un wiki communautaire pour que quiconque puisse le réparer puisse simplement l'ajouter.
ngm

1
@digEmAll a joué 4 octets en calculant d'abord le signe, puis en faisant Find(c,x). Je pense que c'est une nouvelle astuce.
JayCe

4

APL (Dyalog Unicode) , 18 17 octets

1 octet enregistré grâce à @ Adám pour avoir utilisé à la ⍤1place ∘↑(...)¨et en changeant le format d'entrée d'un tableau imbriqué à une matrice

(⍋-⍒)(⍎¨∊∘⎕D⊆⊢)⍤1

Essayez-le en ligne!

Prend l'entrée comme une matrice de caractères comme argument de droite, où chaque chaîne de version est sur sa propre ligne. Sorties ¯1 1, 0 0, 1 ¯1pour <, =, >respectivement.

(⍎¨∊∘⎕D⊆⊢)⍤1 sur chaque rangée

  • ∊∘⎕D⊆⊢ regrouper toutes les occurrences de chiffres, c'est-à-dire diviser .

  • ⍎¨ et convertir chacune de ces occurrences en un nombre

convertir en une matrice, où la première entrée se trouve sur la rangée du haut et la seconde en bas, en remplissant avec 0s si nécessaire

(⍋-⍒) et

  • - soustraire
    • les indices dans les lignes qui les trieraient par ordre décroissant
    • comme le haut mais pour l'ordre croissant

4

Perl 6 , 63 47 22 octets

{"v$^a cmp v$^b".EVAL}

Essayez-le en ligne!

Il s'avère que Perl 6 a un type de version qui correspond à peu près à la description. Il s'agit d'un bloc de code anonyme qui prend une liste de deux chaînes de version et renvoie soit More, Samesoit Less.

Explication:

{                    }  # Anonymous code block
 "             "        # Create a string of code
  v$^a cmp v$^b         # Comparing the two versions
                .EVAL   # And EVAL it

Ou, sans types intégrés pour 47 octets:

{first +*,[Z<=>] map *.split('.')[^@_.ords],@_}

Essayez-le en ligne!

Bloc de code anonyme qui prend deux chaînes et renvoie Moresi la seconde est supérieure, Lesssi la seconde est plus petite et Nilsi elles sont égales.

Explication:

{                                             } # Anonymous code block
                 map *.split('.')          ,@_  # Split both strings by '.'
                                 [^@_.ords]     # Pad the lists by a lot
          [Z<=>]   # Zip the strings with the <=> operator
 first +*,  # Get the first value that when coerced to an int, is not 0

3

Brachylog , 49 40 octets

+0|{~c[H,".",T]hị;T|ị;0|0}ᵐz{h-0&t↰₀|h-}

... C'est encore assez peu impressionnant.

Attend une liste de deux chaînes. Utilise positive number / zero / negative number comme > / = / <.

Essayez-le en ligne!

Explication

Fractionner les entrées

Étant donné une entrée qui ne s'unifie pas [0, 0], comme ["1.02.0", "1.2.0.1.0"]les sorties de segment ci-dessous, par exemple [[1, "02.0"], [1, "2.0.1.0"]].

                            # unify the input with...
+0                          # : a list whose sum = 0 (output is 0)
  |{                     }ᵐ # : OR a list that when mapped...
    ~c                      # : : if the input string unifies with a list of the form...
      [H,".",T]             # : : : e.g. "1.02.0", H = "1", T = "02.0"
               hị           # : : : coerce the head to an integer
                 ;T         # : : : append the string T
                            # : : : "1.02.0" -> [1, "02.0"]
                   |ị       # : : OR it unifies with an integer
                     ;0     # : : : append 0
                            # : : : "1" -> [1, 0]
                       |0   # : : OR it unifies with 0
                            # : : : 0 -> [0]

Comparaison des entrées

Étant donné, par exemple, [[1, "02.0"], [1, "2.0.1.0"]]zippe les sous-listes [[1, 1], ["02.0", "2.0.1.0"]]et compare les valeurs dans la tête ( [1,1]). Revenez sur la deuxième sous-liste. Notez que le prédicat zip zparcourt des listes plus courtes de sorte que le zip avec [0,0]est équivalent au zip avec [0], d'où l'étape précédente s'unifie 0avec 0sans autres valeurs ajoutées.

z             # zip the sublists
 {          } # unify the result (r) with...
  h           # : take the head of the result
   -          # : : subtract the second value from the first
    0         # : : if the difference unifies with 0...
     &t↰₀     # : : recur on the tail of r
         |h-  # : OR unify with the difference of the elements of the head
              # : (equivalent to returning early)

3

JavaScript (ES6), 73 68 octets

5 octets enregistrés grâce à @redundancy

(a)(b)0

a=>b=>(a+[...b].fill`.`).split`.`.some((x,i)=>d=~b.split`.`[i]-~x)*d

Essayez-le en ligne!


Agréable. Si j'ai bien compris, vous pouvez économiser des octets en remplaçant replacepar fill. Les opérandes de -sont échangés car les deux doivent maintenant être contraints à un nombre. Essayez-le en ligne!
redondance

@redundancy Bonne idée! (Je ne sais pas si ma mise en œuvre correspond exactement à ce que vous aviez à l'esprit, cependant.)
Arnauld

J'ai supposé que votre intention était d'ajouter suffisamment de valeurs coercibles à 0, de sorte que le mappage sur les sous-chaînes afinit par parcourir ces valeurs 0 s'il bcontient plus de segments numériques que a. Il se trouve que la méthode la plus courte pour s'assurer qu'il en est ainsi consiste à diviser sur une bchaîne de longueur "." en tirant parti de la répartition existante appliquée a.
redondance

3

Java (JDK 10) , 201 96 89 octets

java.util.Comparator.comparing(java.lang.module.ModuleDescriptor.Version::parse)::compare

Essayez-le en ligne!

Renvoie un nombre négatif si la première version est plus petite que la seconde, un positif si la première version est supérieure à la seconde et 0s'ils sont égaux.

Oui, c'est un gros travail d'appeler "juste" un intégré!

Crédits


1
J'ai essayé, mais je ne peux supprimer que trois octets. 228 octets
Kevin Cruijssen

1
Trouvé quelque chose de plus: 217 octets
Kevin Cruijssen

1
C'est probablement ça .. Déjà essayé try-finallypour que le if-check puisse être simplifié; essayé de retourner à l'intérieur de la boucle si t!=0; essayé d'utiliser Integeret i.compare(i.valueOf(...),i.valueOf(...)); essayé d'utiliser des génériques comme celui-ci <T>T[]g(T s){return(T[])(s+"").replaceAll("(\\.0+)*$","").split("\\.");}; etc. Tous sont de 2 à 6 octets de plus. Si vous (ou quelqu'un d'autre) trouvez quelque chose de plus, faites le moi savoir s'il vous plaît. Curieux de savoir quoi. :)
Kevin Cruijssen

1
@KevinCruijssen Non, je ne peux pas parce que "Tous les nombres dans un numéro de version seraient inférieurs à 2^16." Courts intervalles de - (2 ^ 15) à 2 ^ 15-1.
Olivier Grégoire du

1
@KevinCruijssen J'ai pu supprimer 105 octets! Comment? Bon, j'ai trouvé un intégré;)
Olivier Grégoire


2

Retina 0.8.2 , 54 octets

\d+
$*
+`^(.)(.*=)\1
$2
(.*=|^=.*)1.*
<
.*1.*=.*
>
\.

Essayez-le en ligne! Le lien inclut des cas de test. Utilise la valeur du séparateur comme sortie d'égalité.Par conséquent, pour plus de commodité, l'en-tête convertit le séparateur d'entrée en =mais il peut ne pas être dans [.\d]. Explication:

\d+
$*

Convertissez en unaire.

+`^(.)(.*=)\1
$2

Supprimez à plusieurs reprises le premier caractère de chaque côté jusqu'à ce qu'ils diffèrent ou qu'un côté s'épuise. C'est beaucoup plus rapide que d'essayer de faire correspondre des préfixes, bien que ce ne soit pas un golfeur. À ce stade, les chaînes se présentent sous plusieurs formes, qui doivent être décodées en résultat de comparaison.

  1. Si aucune chaîne ne contient un, 1le résultat est=
  2. Si la chaîne de gauche commence par un, 1le résultat est>
  3. Si la bonne chaîne commence par un, 1le résultat est<
  4. Si la chaîne de gauche est vide, le résultat est <
  5. À ce stade, la chaîne de droite est vide, le résultat est >

Une autre façon de penser à ce sujet est que si une chaîne contient un 1et que l'autre ne commence pas par un, 1cette chaîne est plus grande, mais cela se révèle être un octet plus long.

(.*=|^=.*)1.*
<

Vérifiez le cas 3 ou le cas 4 sans le cas 1.

.*1.*=.*
>

Si la chaîne de gauche contient toujours un 1à ce stade, il est supérieur.

\.

Sinon, supprimez les restes de l' .art.

Firefox Browser Console REPL, 19 octets

Services.vc.compare

Je crois que cette fonction interne effectue la comparaison requise. Il renvoie -1, 0 ou 1.


1
Je vous suggère de publier le code Chrome de Firefox comme une autre réponse ...
tsh

btw, je ne sais pas comment le code Chrome de Firefox compte ses octets. Doit Cu.import("resource://gre/modules/Services.jsm");être compté?
tsh

1
@tsh C'est pourquoi j'ai ajouté "Browser Console REPL" ...
Neil

2

PHP , 38 octets

<?=version_compare($argv[1],$argv[2]);

Les sorties -1 → < | 0 → = | 1 → >

Essayez-le en ligne!


Je pense que votre soumission peut juste être la fonction elle
Jo King

1
Cela renvoie le mauvais résultat pour toute paire d'entrées qui ne diffèrent que par des zéros de fin, par exemple 1.0.0et1
oktupol

2

C (gcc) ,  140  134 octets

Ce code produit un négatif, 0ou positif pour <, =ou >respectivement.

i;n;p;q;g(char*s){for(i=n=0;*s&&++n&&*s-46;i=i*10+*s++-48);i=i;}f(char*a,char*b){for(p=q=0;*a+*b&&p==q;b+=n)p=g(a),a+=n,q=g(b);a=p-q;}

Essayez-le en ligne!

Modifications:

  • Économisé 6 octets grâce à ce plafond!

Le défi stipule: "Utilisez trois valeurs distinctes constantes;" Votre code ne renvoie pas de constantes.
Olivier Grégoire

1
@Olivier Il indique que je peux "Utiliser trois valeurs distinctes constantes;" OU "Utiliser un nombre positif / zéro / nombre négatif, tandis que zéro signifie égal;"
Annyo

Ma faute! Vous avez raison.
Olivier Grégoire


1

JavaScript (Node.js) , 105 88 80 octets

-17 octets de @redundancy. Hou la la!

-8 octets supprimant Math.sign. Merci @tsh

Renvoie une valeur négative, nulle ou positive

f=(a,b,r=/(\d*).?(.*)/)=>a+b&&+((a=r.exec(a))[1]-(b=r.exec(b))[1]||f(a[2],b[2]))

Essayez-le en ligne!


1
88 octets execpour fractionner les chaînes. Essayez-le en ligne!
redondance

@redundancy Damn, merci! c'est un truc assez cool
Luis felipe De jesus Munoz

Vous souhaitez peut-être supprimer le Math.sign pour enregistrer certains octets en passant à des valeurs positives / nulles / négatives. Et peut-être qu'un signe positif est requis.
tsh


0

Nettoyer , 116 111 octets

import StdEnv,Text
?s=map toInt(split"."s)
$a b= @(?a)(?b)
@[h:t][u:v]|h==u= @t v=h-u
@l[]=sum l
@[]l= ~(sum l)

Essayez-le en ligne!

Génère un nombre négatif lorsque le premier argument est inférieur au second, zéro lorsqu'ils sont équivalents et un nombre positif lorsqu'il est supérieur au second.


0

Swift 4 , 155 octets

En-tête (non compté: le code n'est pas récursif):

let f:(String,String)->Bool? = 

Code

{let x:(String)->[Int]={$0.split{$0=="."}.map{Int($0)!}.reversed().drop{$0==0}.reversed()},a=x($0),b=x($1)
return a==b ?nil:a.lexicographicallyPrecedes(b)}

Essayez-le en ligne!

Explications

  • Nous coupons le 0,0 final.
  • Nous comparons les composants numériquement.

Constantes retournées

  • nul pour =
  • vrai pour <
  • faux pour>

0

JavaScript 64 octets

a=>b=>(e=i=>(g=v=>v.split`.`[i]||0)(a)-g(b)||!a[i]-1&&e(i+1))(0)

Essayez-le en ligne!

Avec commentaires:

a=>b=>(                            // Main function takes arguments like ("1.2.42")("1.2.41")
    e=i=>                          // e(i) compares the ith number, returns >0, <0 or =0.
        (   g=v=>v.split`.`[i]||0  // g() returns the ith string or 0
        )(a)                       // call g(a)
        -g(b)                      // subtracting g(b) from g(a) casts strings to integer
        ||                         // If they are not equal return result now
        !a[i]-1 &&                 // recursion limited to a.length, always sufficient
        e(i+1)                     // next i
    )(0)                           // Start with i = 0


0

Burlesque - 17 octets

wd{'.;;)ri}m[^pcm


blsq ) "2018.08.1 2018.08"wd{'.;;)ri}m[^pcm
1
blsq ) "0.0.1 0.1"wd{'.;;)ri}m[^pcm
-1
blsq ) "1.1.56789 1.2.0"wd{'.;;)ri}m[^pcm
-1

Si vous voulez une sortie dans '> <=' alors ajoutez ?i"<=>"j!!Q.


0

Powershell, 88 octets

Renvoie 0pour égal, a positive integerpour supérieur à ou a negative integerpour inférieur à.

param($a,$b)+(($x=$a-split'\.')+($y=$b-split'\.')|%{$x[+$i]-$y[$i++]}|?{$_}|Select -f 1)

Script de test moins golfé:

$f = {

param($a,$b)
$x=$a-split'\.'
$y=$b-split'\.'
$z=$x+$y|%{
    $x[+$i]-$y[$i++]
}|?{$_}|Select -first 1
+$z             # convert $null to 0

}

@(
    ,("2"         ,"1"         , 1)
    ,("1.0.0"     ,"1"         , 0)
    ,("1.0"       ,"1.0.0"     , 0)
    ,("1.2.42"    ,"1.2.41"    , 1)
    ,("1.1.56789" ,"1.2.0"     ,-1)
    ,("1.10"      ,"1.2"       , 1)
    ,("1.20"      ,"1.150"     ,-1)
    ,("18.04"     ,"18.4"      , 0)
    ,("7.010"     ,"7.8"       , 1)
    ,("1.0.0.1.0" ,"1.00.00.2" ,-1)
    ,("00.00.01"  ,"0.0.0.1"   , 1)
    ,("0.0.1"     ,"0.1"       ,-1)
    ,("42.0"      ,"4.2.0"     , 1)
    ,("999.999"   ,"999.999.1" ,-1)
    ,("2018.08.1" ,"2018.08"   , 1)
) | % {
    $v1,$v2,$expected = $_
    $result = &$f $v1 $v2
    "$([Math]::Sign($result)-eq$expected): $result"
}

Sortie:

True: 1
True: 0
True: 0
True: 1
True: -1
True: 8
True: -130
True: 0
True: 2
True: -1
True: 1
True: -1
True: 38
True: -1
True: 1

0

Dart , 277 231 octets

F(s,{t}){t=s.split('.').map(int.parse).toList();while(t.last<1)t.removeLast();return t;}f(a,b,{d,e,f,g,h,i=0}){d=F(b);e=F(a);g=d.length;h=e.length;f=h>g?g:h;for(;i<f;i++)if(e[i]!=d[i])return e[i]>d[i]?1:-1;return h>g?1:(h<g?-1:0);}

Essayez-le en ligne!

  • -44 octets en utilisant des variables pour stocker la longueur et en utilisant ternaire en boucle
  • -2 octets en supprimant les parenthèses for

0

Swift 4 + Foundation , 160 octets (142 + 18) , 155 octets (142 + 13)

Importation (13 octets, y compris ;pour séparer du code):

Cela importera Foundation, mais est 5 octets plus court que import Foundation.

import UIKit;

En-tête (non compté: le code n'est pas récursif):

let f:(String,String)->ComparisonResult =

Code (142 octets):

{var x={($0 as String).split{$0=="."}.count},a=$0,b=$1
while x(a)<x(b){a+=".0"}
while x(b)<x(a){b+=".0"}
return a.compare(b,options:.numeric)}

Essayez-le en ligne!

Explications

  1. Nous ajoutons quelques .0 de fin pour le même nombre de composants.
  2. Nous comparons les composants numériquement.

Constantes retournées

  • ComparisonResult.orderedSame pour =
  • ComparisonResult.orderedAscending pour <
  • ComparisonResult.orderedDescending pour>

Je ne sais pas si nous comptons la importdéclaration, j'ai donc posté une réponse distincte qui ne nécessite pas Foundationet avec un nombre d'octets compris entre 142 octets (sans compter l'importation) et 160 octets (compter l'importation).
Cœur

0

Zsh , 54 octets

eval {autoload,}' is-at-least $'{1\ $2,2\ $1}';<<<$?;'

Essayez-le en ligne! Essayez une suite de tests!

Cela correspond evalaux huit déclarations suivantes:

autoload is-at-least $1 $2     # loads the "is-at-least" function
<<<$?                          # success, prints 0
autoload is-at-least $2 $1     # redundant
<<<$?                          # success, prints 0
is-at-least $1 $2              # exits 1 if $1 < $2
<<<$?
is-at-least $2 $1              # exits 1 if $2 < $1
<<<$?

Les trois valeurs uniques sont donc:

 cmp |  value
-----+------------------------------------------
  =  |  0<newline>0<newline>0<newline>0<newline>
  <  |  0<newline>0<newline>1<newline>0<newline>
  >  |  0<newline>0<newline>0<newline>1<newline>
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.