Chevauchement des blocs de chaînes


22

Défi:

Étant donné une liste de chaînes multi-lignes, superposez-les (en haut à gauche) et affichez le résultat.

Exemple:

Entrée: ["aaaa\naaaa\naaaa\naaaa","bb\nbb\nbb","c"]
Sortie:

cbaa
bbaa
bbaa
aaaa

Règles du défi:

  • Le format d'entrée est flexible. Vous êtes autorisé à obtenir l'entrée sous la forme d'une liste 2D de lignes (ie [["aaaa","aaaa","aaaa","aaaa"],["bb","bb","bb"],["c"]]) ou d'une liste 3D de caractères (ie [[["a","a","a","a"],["a","a","a","a"],["a","a","a","a"],["a","a","a","a"]],[["b","b"],["b","b"],["b","b"]],[["c"]]]). Vous êtes autorisé à prendre toutes les entrées une par une via STDIN. Etc.
  • Le format de sortie est strict. Vous pouvez choisir d'imprimer ou de renvoyer la chaîne multiligne. (Si votre langue n'a pas de chaînes, la sortie sous forme de liste 2D de caractères est autorisée comme alternative. Mais uniquement si votre langue n'a pas de chaînes du tout.)
  • L'ordre de la liste d'entrées est bien sûr important (mais vous pouvez prendre l'entrée en sens inverse si vous le souhaitez).
  • Les entrées ne contiendront que de l'ASCII imprimable dans la plage unicode [33,126] ( !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~).
  • Les entrées ne seront que des rectangles (donc pas de formes étranges). Cependant, la sortie n'est pas un rectangle nécessaire.
  • Les espaces de fin et une seule nouvelle ligne de fin sont autorisés. Espaces de tête et / ou nouvelles lignes non.

Règles générales:

  • C'est du , donc la réponse la plus courte en octets l'emporte.
    Ne laissez pas les langues de golf de code vous décourager de publier des réponses avec des langues autres que le golf de code. Essayez de trouver une réponse aussi courte que possible pour «n'importe quel» langage de programmation.
  • Des règles standard s'appliquent à votre réponse avec des règles d'E / S défaut , vous êtes donc autorisé à utiliser STDIN / STDOUT, des fonctions / méthodes avec les paramètres appropriés et des programmes complets de type retour. Ton appel.
  • Failles par défaut sont interdites.
  • Si possible, veuillez ajouter un lien avec un test pour votre code (par exemple TIO ).
  • De plus, l'ajout d'une explication à votre réponse est fortement recommandé.

Cas de test:

Entrée: ["aaaa\naaaa\naaaa\naaaa","bb\nbb\nbb","c"]
Sortie:

cbaa
bbaa
bbaa
aaaa

Entrée: ["12345\n54321","00\n00\n00\n00","001\n011\n012"]
Sortie:

00145
01121
012
00

Entrée: ["sm\noo\nmr\nee\nt!\nh_\ni_\nn_\ng_","!@#$%^\n&*()_+\nqwerty\nuiopas","this\nis_a\ntest"]
Sortie:

this%^
is_a_+
testty
uiopas
t!
h_
i_
n_
g_

Les sauts de ligne sont-ils autorisés? Ou plus précisément, un nombre arbitraire de nouvelles lignes de fin est-il autorisé?
JAD

@JAD Oui bien sûr, pourquoi pas. Tant que le reste est sorti sans espaces / sauts de ligne. Les sauts de ligne / espaces ne sont pas vraiment importants, ils peuvent donc être ajoutés en option.
Kevin Cruijssen

Réponses:


6

Gelée , 3 octets

a/Y

Essayez-le en ligne!

Je n'avais pas utilisé Jelly depuis un moment mais je pensais que le défi dans les commentaires était battable. Utilise très directement logique et ( a) pour effectuer l'opération d'empilement entre chaque élément de l'entrée ( /). Yest utilisé pour imprimer dans le format requis.


Ah bien! Je suis assez mauvais avec Jelly tbh. Ma solution préparée était ḷ""/Yavec une liste d'entrée inversée. Je ne savais même pas a..
Kevin Cruijssen

11

JavaScript (Node.js) , 24 octets

Sauvegardé 2 octets grâce à @Grimy

Suppose que la chaîne renvoyée est imprimée sur un terminal qui prend en charge les codes d'échappement ANSI . Contient le caractère non imprimable ESC, qui est échappé (sans jeu de mots) comme \x1Bci-dessous.

a=>`\x1B[2J\x1B[H`+a.join`\x1B[H`

Cela ne fonctionne pas sur TIO, mais vous pouvez l' essayer en ligne! pour voir la sortie brute à la place.

Comment?

Les séquences CSI utilisées sont:

  • ED (Effacer à l'écran):

    ESC[2J

    2 signifie "effacer tout l'écran"

  • CUP (position du curseur):

    ESC[H

    ce qui signifie "déplace le curseur sur la ligne n , colonne m "n et m sont omis et définis implicitement sur 1 (coin supérieur gauche de l'écran).

Exemple de sortie

sortie


En supposant un terminal compatible ECMA-48, vous pouvez omettre les deux ;. En outre, je pense que cela devrait être "JavaScript + terminal" ou quelque chose de similaire qui ne rivalise pas avec JavaScript pur.
Grimmy

@Grimy Merci! (Pour toute personne intéressée, voici la spécification ECMA-48 - mais je n'ai pas trouvé où il est mentionné que le point-virgule peut être omis - s'il est mentionné du tout.)
Arnauld

1
5.4.2.h est quelque peu formulée confusément, mais le bit est intéressant: if the last parameter sub-string(s) is empty, the separator preceding it may be omitted. Puisqu'il n'y a que deux sous-chaînes, le séparateur précédant la dernière sous-chaîne est le seul, et il peut être omis.
Grimmy

Je ne connais pas ANSI, mais le premier \x1B[H+ est-il nécessaire? N'est-ce pas commencer en haut à gauche par défaut, et vous n'avez qu'à le réinitialiser après chaque entrée (ce que fait la jointure)? Ou commence-t-il initialement ailleurs par défaut, et vous devez explicitement le laisser démarrer à cette position du curseur pour qu'il se réinitialise avec succès à cette position dans la jointure?
Kevin Cruijssen

1
@Arnauld Puisque vous aurez probablement toujours quelque chose d'autre sur le terminal lors de l'exécution de cette fonction, je suppose que la réinitialisation initiale est nécessaire après tout. En ce qui concerne la suppression de l'impression, je suppose f=a=>print(`\x1B[H`+a.join`\x1B[H`)qu'avec f(input_here)produirait la même sortie que print(f(input_here))? Je ne vois donc pas pourquoi vous ne seriez pas autorisé à omettre le printet à renvoyer simplement une chaîne.
Kevin Cruijssen

7

R , 120 , 111 110 107 octets

function(x,`!`=ncol,M=array('',Reduce(pmax,Map(dim,x)))){for(m in x)M[1:!t(m),1:!m]=m
write(t(M),1,!M,,'')}

Essayez-le en ligne!

Une fonction acceptant une liste de matrice de caractères (la saisie 3D est acceptée).

(comme vous pouvez le constater à partir du nombre d'octets, ce n'est pas très facile à faire dans R ...)

  • -9 octets grâce à @Giuseppe
  • -4 octets grâce à @RobinRyder

4
Je m'attendais vraiment à une solution de plus de 200 octets! Je lui donnerai une belle prime chaque fois que cette question deviendra une prime éligible
Giuseppe

@Giuseppe: toujours beaucoup plus longtemps que les autres langues ... :(
digEmAll

2
111 octets en utilisant arrayau lieu de matrix!
Giuseppe

@Giuseppe: soigné!
digEmAll

3
107 avec un alias pour ncol(vous pouvez transposer pour obtenir nrow).
Robin Ryder

5

Python 2 , 88 octets

n,f=None,filter
for l in map(n,*input()):print''.join(f(n,x)[-1]for x in map(n,*f(n,l)))

Essayez-le en ligne!


Explication (avec exemple):

Prend une liste 2D en entrée.

Input: [["12345","54321"],["00","00","00","00"],["001","011","012"]]

D'abord, la liste d'entrée est zippée, pour obtenir les lignes de chaque rectangle d'entrée ( map(None,l)est la même une plus longue zip):

map(n,*input())   gives:

('12345', '00', '001')
('54321', '00', '011')
(None, '00', '012')
(None, '00', None)

Chacune de ces lignes est ensuite filtrée en Nones supprimés et zippée à nouveau:

map(None,*filter(None,l))

filter(None,l) for each l gives:

('12345', '00', '001')
('54321', '00', '011')
('00', '012')
('00',)

map*... gives:

[('1', '0', '0'), ('2', '0', '0'), ('3', None, '1'), ('4', None, None), ('5', None, None)]
[('5', '0', '0'), ('4', '0', '1'), ('3', None, '1'), ('2', None, None), ('1', None, None)]
[('0', '0'), ('0', '1'), (None, '2')]
['0', '0']

C'est une liste de caractères pour chaque position du résultat souhaité. Ces listes sont à nouveau filtrées et la dernière est prise:

filter(None,x)   gives:

[('1', '0', '0'), ('2', '0', '0'), ('3', '1'), ('4',), ('5',)]
[('5', '0', '0'), ('4', '0', '1'), ('3', '1'), ('2',), ('1',)]
[('0', '0'), ('0', '1'), ('2',)]
['0', '0']

and with [-1]:

['0', '0', '1', '4', '5']
['0', '1', '1', '2', '1']
['0', '1', '2']
['0', '0']

Enfin, les listes résultantes sont jointes et imprimées:

print''.join(..)

00145
01121
012
00

RE "Renvoie une liste de chaînes", les règles indiquent "Le format de sortie est strict. Vous pouvez choisir d'imprimer ou de renvoyer la chaîne multi-lignes. Les listes 2D ou 3D en tant que sorties ne sont pas autorisées.". Le programme complet de 88 octets semble correct
Jonathan Allan

@JonathanAllan, welp, j'ai mal lu la sortie stricte (ou oublié?: P)
TFeld

5

R, 107 97 octets

function(x)for(i in 1:max(lengths(x))){for(m in x)if(i<=length(m))cat(m[i],'\r',sep='');cat('
')}

Ne semble pas fonctionner sur TIO, ce qui pourrait être lié à l'utilisation du \r caractère de retour chariot. Cela fonctionne sur mon installation locale de R.

Prend l'entrée comme une liste contenant un vecteur de lignes:

x <- list(c("aaaa","aaaa","aaaa","aaaa"),c("bb","bb","bb"),c("c"))

Boucles sur les lignes de chaque rectangle, imprimant un retour chariot après chaque, redémarrant la ligne.

Si nous étirons un peu les règles, nous pouvons éliminer la vérification de la longueur de l'entrée et boucler à l'infini, en imprimant une énorme quantité de nouvelles lignes:

R, 85 octets

function(x)for(i in 1:8e8){for(m in x)if(i<=length(m))cat(m[i],'\r',sep='');cat('
')}

106 octets Ravi de vous voir faire du golf ici et là!
Giuseppe

Peut-être 97 octets ; pas clair si cela fonctionne réellement puisque je teste uniquement en TIO
Giuseppe

@Giuseppe Salut! Votre suggestion fonctionne pour moi. Si nous sommes autorisés à imprimer des sauts de ligne de fin, il est également possible d'utiliser simplement une boucle arbitrairement grande pour, mais je suppose que cela repousse les limites du défi.
JAD

@JAD: bonne idée d'utilisation \ret bon retour! Juste une note, je pense que cela ne fonctionne que dans les sessions R interactives (quand interactive()retourne vrai)
digEmAll

@digEmAll Cela fonctionne sur ma machine en utilisant la rscriptligne de commande. Je soupçonne que c'est une chose Windows / Linux, car Windows utilise \r\npour les nouvelles lignes et Linux \n.
JAD

4

APL (Dyalog Unicode) , 22 octets SBCS

Fonction de préfixe tacite anonyme prenant comme argument la liste des tableaux de caractères 2D. Impressions.

(⊃{⍺@(⍳⍴⍺)⊢⍵}/)⌽,∘⊂1⌷↑

Essayez-le en ligne!

Cela fonctionne en créant un canevas, puis en l'ajoutant à la liste des blocs et en réduisant (pliant) avec une fonction qui place les blocs dans le coin.

 mélanger le bloc 2D pour créer un bloc 3D orthogonal, en les remplissant d'espaces au besoin

1⌷ prendre la première couche

 joindre qui
 ensuite
⌽, ajouter la liste inversée des blocs

() Appliquez la fonction tacite suivante:

{}/ Réduisez en utilisant le lambda anonyme suivant:

  ⊢⍵ avec le bon argument comme toile…

  ⍺@() Modifier avec les éléments de l'argument de gauche, placés aux indices suivants:

   ⍴⍺ la forme de l'argument de gauche

    les ɩ ndices d'un tableau de cette forme

 divulguer (parce que la réduction incluse pour réduire le rang)


4

Haskell, 66 octets

unlines.foldl((const?)?)[]
(g?(a:b))(c:d)=g a c:(g?b)d;(_?a)b=a++b

L' entrée est considérée comme une liste de la liste des chaînes dans l' ordre inverse, par exemple pour le premier test: [["c"],["bb","bb","bb"],["aaaa","aaaa","aaaa","aaaa"]].

Essayez-le en ligne!


3

05AB1E , 12 octets

Port de la solution python de TFeld
2 octets économisés grâce à Grimy

ζεðKζðδK€θJ,

Essayez-le en ligne!

Explication

ζ             # transpose input with space as filler
 ε            # apply to each
  ðK          # remove spaces
    ζ         # transpose with space as filler
     ðδK      # deep remove spaces
        €θ    # get the tail of each
          J   # join each
           ,  # print

Version alternative à 14 octets

õζεÅ»DŠg.$J}θ,

Essayez-le en ligne!

Explication

õζ              # zip with empty string as filler
  ε             # apply to each
   Å»      }    # cumulative reduce by
     D          # duplicate second input
      Š         # move down twice on stack
       g.$      # remove len(other_copy) elements from the other input
          J     # join with other copy
            θ,  # print the last element

1
Oh, il faut se rappeler que --no-lazyc'est le correctif de toujours utiliser une carte / filtre avec impression pour l'implicite y, pour enregistrer un octet par rapport à vy...,:) Je savais que cela fonctionnait dans la version héritée, mais dans la nouvelle version, il produirait également le [...]. Je ne savais pas que c'était dû au manque de --no-lazy. ;) Quant à la réponse elle-même, très sympa! Je savais qu'une réduction cumulative était nécessaire, mais je ne pouvais pas vraiment m'en sortir quand je l'ai essayée moi-même. Vous avez l'air si facile ..
Kevin Cruijssen

Je l'avais mentionné dans les règles, mais j'ai oublié de l'appliquer aux cas de test .., mais les espaces ne seront pas dans l'entrée. Vous pouvez donc probablement y sauvegarder quelques octets car le zip-filler est un espace par défaut. (Je ne sais pas si cela enregistre quoi que ce soit dans votre première réponse, mais dans le port, cela pourrait l'être.)
Kevin Cruijssen

2
õζεõKpeut être ζεðK, õζõδKpeut être ζðδK.
Grimmy

@Grimy: Oh oui, les espaces ne peuvent plus être en entrée. Merci!
Emigna



2

PowerShell 6 , console uniquement, 20 octets

basé sur Arnauld réponse . Cela fonctionne uniquement avec la console et ne fonctionne pas sur TIO.

cls
$args-join"`e[H"

Essayez-le en ligne!


PowerShell , 103 octets

$args|%{$l=$_-split'
';$r=&{$r+($l|%{''})|%{($x=$l[$j++])+($_-replace"^.{0,$("$x"|% Le*)}")}|?{$_}}}
$r

Essayez-le en ligne!

Déroulé:

$args|%{
    $l=$_-split"`n"
    $r=&{                           # run this scriptblock in a new scope
        $r+($l|%{''})|%{
            $x=$l[$j++]             # a new line or $null
            $w="$x"|% Length
            $y=$_-replace"^.{0,$w}" # remove first chars from the current line
            $x+$y                   # output the new line plus tail of the overlapped line
        }|?{$_}                     # filter out not empty lines only
    }                               # close the scope and remove all variables created in the scope
}
$r


1

Rubis , 67 octets

L'entrée est une liste de lignes. Construit une liste de lignes et écrase tout au long des entrées, puis les joint avec une nouvelle ligne (représentée par la variable $/) à la fin pour correspondre à la sortie stricte.

->i,*r{i.map{|e|j=-1;e.map{|l|r[j+=1]||='';r[j][0,l.size]=l}};r*$/}

Essayez-le en ligne!


1

C (GCC, MinGW) 138 octets

Suppose que CR place le curseur au début de la ligne actuelle.

d,i,l;f(S,n,p,t)char**S,*p,*t;{for(d=i=0;i<n;d+=l)p=strchr(t=S[i],10),printf("\n%.*s\r"+!!i,l=p?p-t:strlen(t),t),S[i++]+=l+!!p;d&&f(S,n);}

Testé avec:

int main()
{
    char *test1[] = {"aaaa\naaaa\naaaa\naaaa","bb\nbb\nbb","c"};
    char *test2[] = {"12345\n54321","00\n00\n00\n00","001\n011\n012"};
    char *test3[] = {"sm\noo\nmr\nee\nt!\nh_\ni_\nn_\ng_","!@#$%^\n&*()_+\nqwerty\nuiopas","this\nis_a\ntest"};

    f(test1, 3);
    f(test2, 3);
    f(test3, 3);
}


1

Javascript (navigateur) , 216 208 204 octets

Ma tentative. Je ne suis pas content de la taille, et il doit certainement y avoir plus à améliorer, mais je ne suis pas très expérimenté au golf.

var n='\n',x=s=>s.split``.reverse().join``,i,j,f=a=>a.map(s=>s.split(n).map(y=>x(y))).reduce((a,b)=>{for(i=0;i<b.length;i++){j=a[i];if(!j)j=b[i];a[i]=b[i].padStart(j.length,j)}return a}).map(s=>x(s)).join(n)

Quoi qu'il en soit, ce qu'il fait est d'abord de diviser toutes les chaînes, puis d'inverser toutes les chaînes, puis tout en bouclant dans un pad d' opération de réduction toutes les chaînes ensemble. Ensuite, inversez à nouveau toutes les chaînes, puis joignez-les à nouveau avec des nouvelles lignes.

Un merci spécial à Kevin Cruijssen pour m'avoir rappelé que la dernière partie d'une boucle for se produit à la fin et une économie d'octets totale de 8 octets.

var n='\n',x=s=>s.split``.reverse().join``,i,j,f=a=>a.map(s=>s.split(n).map(y=>x(y))).reduce((a,b)=>{for(i=0;i<b.length;a[i]=b[i++].padStart(j.length,j))if(!(j=a[i]))j=b[i];return a}).map(s=>x(s)).join(n)

console.log(f(["aaaa\naaaa\naaaa\naaaa","bb\nbb\nbb","c"]));
console.log(f(["12345\n54321","00\n00\n00\n00","001\n011\n012"]));
console.log(f(["sm\noo\nmr\nee\nt!\nh_\ni_\nn_\ng_","!@#$%^\n&*()_+\nqwerty\nuiopas","this\nis_a\ntest"]));


1
Les deux ('')peuvent être deux `pour économiser quatre octets :)
Kevin Cruijssen

1
Vous pouvez également remplacer le for(i=0;i<b.length;i++){j=a[i];if(!j)j=b[i];a[i]=b[i].padStart(j.length,j)}par for(i=0;i<b.length;a[i]=b[i++].padStart(j.length,j))if(!(j=a[i]))j=b[i];.
Kevin Cruijssen

1
Le jest d'abord attribué à (j=a[i]), puis l'instruction if est effectuée avec if(!...)j=b[i];(où ...est le (j=a[i]), donc la valeur mise à jour de j), puis ;a[i]=b[i++].padStart(j.length,j))est effectuée à la fin de l'itération pour la boucle. Vous ne savez pas où se trouve le problème, et cela semble fonctionner?
Kevin Cruijssen

1
ooohhh .... * de grands yeux * qui ont déverrouillé quelque chose
Tschallacka

1
D'ailleurs, si vous ne les avez pas encore vus, des conseils pour jouer au golf dans <toutes les langues> et des conseils pour jouer au golf en JavaScript pourraient être intéressants à lire. :)
Kevin Cruijssen

1

C (gcc) , 51 47 octets

f(char**s){for(;*s;printf("\e[s%s\e[u",*s++));}

Essayez-le en ligne!

-4 octets grâce au plafond.

Utilise les séquences CSI pour enregistrer / restaurer la position du curseur. Itère simplement sur le tableau de chaînes passé (au même format que argv) et imprime<save position>string<restore position> pour chacun.

Cela laisse le curseur en haut à gauche, donc lors de l'exécution sur le terminal, il est important de laisser suffisamment de nouvelles lignes par la suite pour que l'invite n'encombre pas l'entrée.


1

Japt -P , 7 octets

Prend l'entrée comme un tableau de chaînes multi-lignes, produit une seule chaîne multi-lignes.

ú y_¸¬Ì

Essayez-le

ú y_¸¬Ì     :Implicit input of array
ú           :Right pad each line of each element with spaces to the length of the longest
  y         :Transpose
   _        :Map
    ¸       :  Split on spaces
     ¬      :  Join
      Ì     :  Last character
            :Implicitly join and output

1

Requête T-SQL, 297 295 octets

Utiliser ¶ comme séparateur et une variable de table comme entrée.

DECLARE @ table(a varchar(max),k int identity(1,1))
INSERT @ values('aaaa¶aaaa¶aaaa¶aaaa'),('bb¶bv¶bb'),('c');

WITH c as(SELECT k,row_number()over(partition
by k order by k)s,value v FROM @ CROSS APPLY
string_split(a,'¶')s),m(i,l,e)as(SELECT*FROM c
WHERE k=1UNION ALL
SELECT k,s,STUFF(e,1,len(v),v)FROM m
JOIN c ON-~i=k and s=l)SELECT
top 1with ties e FROM m
ORDER BY rank()over(partition by l order by-i)

Essayez-le en ligne


1

Javascript (navigateur), 129 124 octets

Ma première tentative de golf de code. J'ai lu les liens donnés dans les règles (failles, règles standard ...), donc j'espère avoir fait quelque chose de mal!


J'ai conservé les entrées telles qu'elles sont dans le premier message (sous forme de tableau plat).

_=o=>{o=o.map(i=>i.split`\n`),r=o.shift();for(a of o)for(l in a)b=a[l],r[l]=r[l]?b+r[l].slice(b.length):b;return r.join`\n`}

Merci à Kevin Cruijssen d' avoir économisé 5 octets.


Tests:


1
Bienvenue chez PPCG! Belle première réponse, +1 de ma part. Quelques petites choses au golf: for(a of o){for(l in a){b=a[l],r[l]=(r[l])?b+r[l].slice(b.length):b}}peut être for(a of o)for(l in a)b=a[l],r[l]=r[l]?b+r[l].slice(b.length):b;:)
Kevin Cruijssen

1
@KevinCruijssen - Merci, j'ai mis à jour mon message! J'ai lu ces deux guides avant de poster, ils étaient tous les deux utiles. Mais je manque peut-être quelques astuces qui pourraient encore améliorer ma tentative!
Kévin Bibollet

1
Une autre chose de mon premier commentaire que vous avez manquée est la parenthèse autour de =(r[l])?laquelle peut être supprimée =r[l]?:)
Kevin Cruijssen

1
@ KévinBibollet, c'est nécessaire pour rendre le résultat final de r. Sans cela, le résultat du mappage serait renvoyé à la place.
Shaggy

1
Si vous souhaitez conserver le format d'E / S utilisé dans les cas de test, vous pouvez néanmoins descendre à 85 octets, mais vous devez noter que les E / S sont flexibles.
Shaggy

1

Pyth , 18 octets

L.tb0VyQsme #dy #N

Essayez-le en ligne!(remarque: le code lui-même n'évalue qu'un seul bloc, le mode suite de tests de l'interpréteur exécute le programme une fois pour chaque ligne d'entrée)

Basé sur la solution Python 2 de TFeld .

Explication:

L.tb0         # define a lambda function called y which does a transpose, padding with integer 0's
VyQ           # loop over transposed first input line (Q = eval(input()) ) (loop index = N)
   s          # concatenate array of strings (implicitly printed)
    m         # map over
         y #N # transpose of non-falsy values of N
     e        # for each item: last element of array
       #d     # relevant space at the start! filter with identity function, removes falsy values

pour une explication des raisons pour lesquelles l'algorithme lui-même fonctionne, voir la réponse de TFeld.


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.