PLM mission texts - en to fr translation catalogue (1576 entries)

note: type: Content of: <h1>
en: BuggleWorld
fr: Le monde des Buggles

note: type: Content of: outside any tag (error?)
en: This world was invented by Lyn Turbak, at Wellesley College. It is full of Buggles, little animals understanding simple orders, and offers numerous possibilities of interaction with the world: taking or dropping objects, paint the ground, hit walls, etc.
fr: Ce monde a été inventé par Lyn Turbak, du Wellesley College. Il est peuplé de Buggles, petites bêtes qui comprennent des ordres simples, et offre de nombreuses possibilités d'interaction avec le monde : prendre ou poser des objets, colorier le sol, se cogner à des murs, etc.

note: type: Content of: <h2>
en: Methods understood by buggles
fr: Méthodes comprises par les buggles

note: type: Content of: <table><tr><td>
en: <b>Moving</b>
fr: <b>Bouger</b>

note: type: Content of: <table><tr><td>
en: (See also the note on exceptions, below)
fr: (voir aussi la note sur les exceptions, plus bas)

note: type: Content of: <table><tr><td><b>
en: <b>Turn left
fr: <b>Tourner à gauche

note: type: Content of: <table><tr><td><b>
en: Turn right
fr: Tourner à droite

note: type: Content of: <table><tr><td><b>
en: Turn back
fr: Se retourner

note: type: Content of: <table><tr><td><b>
en: Moving forward
fr: Avancer

note: type: Content of: <table><tr><td>
en: Moving back</b>
fr: Reculer</b>

note: type: Content of: <table><tr><td>
en: [!java|c]void [/!]left()
fr: [!java|c]void [/!]gauche()

note: type: Content of: <table><tr><td>
en: [!java|c]void [/!]right()
fr: [!java|c]void [/!]droite()

note: type: Content of: <table><tr><td>
en: [!java|c]void [/!]back()
fr: [!java|c]void [/!]retourne()

note: type: Content of: <table><tr><td>
en: [!java|c]void [/!][!python|java|scala]forward()[/!][!c]stepForward()[/!] or [!java|c]void [/!]forward([!java|c]int [/!]steps[!scala]:Int[/!])
fr: [!java|c]void [/!][!python|java|scala]avance()[/!][!c]avancePas()[/!] or [!java|c]void [/!]avance([!java|c]int [/!]nbPas[!scala]:Int[/!])

note: type: Content of: <table><tr><td>
en: [!java|c]void [/!][!python|java|scala]backward()[/!][!c]stepBackward()[/!] or [!java]void [/!]backward([!java|c]int [/!]steps[!scala]:Int[/!])
fr: [!java|c]void [/!][!python|java|scala]recule()[/!][!c]reculePas()[/!] or [!java]void [/!]recule([!java|c]int [/!]nbPas[!scala]:Int[/!])

note: type: Content of: <table><tr><td><b>
en: <b>Get X coordinate
fr: <b>Obtenir l'abscisse

note: type: Content of: <table><tr><td><b>
en: Get Y coordinate
fr: Obtenir l'ordonnée

note: type: Content of: <table><tr><td><b>
en: Set X coordinate
fr: Changer l'abscisse

note: type: Content of: <table><tr><td><b>
en: Set Y coordinate
fr: Changer l'ordonnée

note: type: Content of: <table><tr><td>
en: Set position</b>
fr: Changer la position</b>

note: type: Content of: <table><tr><td>
en: Note that the point (0,0) is on the top left corner, as it is often the case in Computer Science.
fr: L'origine (0, 0) est dans le coin en haut à gauche, comme c'est souvent le cas en informatique.

note: type: Content of: <table><tr><td>
en: <b>Information on the buggle</b>
fr: <b>Informations sur la buggle</b>

note: type: Content of: <table><tr><td><b>
en: <b>Get the color of the body
fr: <b>Obtenir la couleur de la buggle</b>

note: type: Content of: <table><tr><td>
en: Set the color of the body</b>
fr: Changer la couleur de la buggle</b>

note: type: Content of: <table><tr><td>
en: [!java|c]Color [/!]getBodyColor()[!scala]:Color[/!]
fr: [!java|c]Color [/!]getCouleurCorps()[!scala]:Color[/!]

note: type: Content of: <table><tr><td>
en: [!java|c]void [/!]setBodyColor([!java|c]Color [/!]c[!scala]:Color[/!])
fr: [!java|c]void [/!]setCouleurCorps([!java|c]Color [/!]c[!scala]:Color[/!])

note: type: Content of: <table><tr><td><b>
en: <b>Look for a wall forward
fr: <b>Chercher un mur devant

note: type: Content of: <table><tr><td>
en: Look for a wall backward</b>
fr: Chercher un mur derrière</b>

note: type: Content of: <table><tr><td>
en: [!java]boolean [/!][!c]int [/!]isFacingWall()[!scala]:Boolean[/!]
fr: [!java]boolean [/!][!c]int [/!]estFaceMur()[!scala]:Boolean[/!]

note: type: Content of: <table><tr><td>
en: [!java]boolean [/!][!c]int [/!]isBackingWall()[!scala]:Boolean[/!]
fr: [!java]boolean [/!][!c]int [/!]estDosMur()[!scala]:Boolean[/!]

note: type: Content of: <table><tr><td><b>
en: <b>Get heading
fr: <b>Obtenir la direction

note: type: Content of: <table><tr><td>
en: Set heading</b>
fr: Changer la direction</b>

note: type: Content of: <table><tr><td>
en: valid directions are:
fr: Les directions valides sont :

note: type: Content of: <table><tr><td>
en: [!scala|java|python]Direction.[/!]NORTH, [!scala|java|python]Direction.[/!]EAST, [!scala|java|python]Direction.[/!]SOUTH and [!scala|java|python]Direction.[/!]WEST
fr: [!scala|java|python]Direction.[/!]NORTH (nord), [!scala|java|python]Direction.[/!]EAST (est), [!scala|java|python]Direction.[/!]SOUTH (sud) et [!scala|java|python]Direction.[/!]WEST (ouest)

note: type: Content of: <table><tr><td>
en: Check whether the buggle is currently <b>selected in the interface</b>
fr: Renvoi si la buggle est actuellement <b>sélectionnée dans l'interface</b>

note: type: Content of: <pre>
en: [!java]boolean [/!][!c]int [/!]isSelected()[!scala]:Boolean[/!]
fr: [!java]boolean [/!][!c]int [/!]estChoisie()[!scala]:Boolean[/!]

note: type: Content of: <table><tr><td>
en: <b>About the brush</b>
fr: <b>À propos de la brosse</b>

note: type: Content of: <table><tr><td><b>
en: <b>Brush down
fr: <b>Baisser la brosse

note: type: Content of: <table><tr><td><b>
en: Brush up
fr: Lever la brosse

note: type: Content of: <table><tr><td>
en: Get brush position</b>
fr: Obtenir la position de la brosse</b>

note: type: Content of: <table><tr><td>
en: [!java|c]void [/!]brushUp()
fr: [!java|c]void [/!]leveBrosse()

note: type: Content of: <table><tr><td>
en: [!java|c]void [/!]brushDown()
fr: [!java|c]void [/!]baisseBrosse()

note: type: Content of: <table><tr><td>
en: [!java]boolean [/!][!c]int [/!]isBrushDown()[!scala]:Boolean[/!]
fr: [!java]boolean [/!][!c]int [/!]estBrosseBaissee()[!scala]:Boolean[/!]

note: type: Content of: <table><tr><td><b>
en: <b>Change the brush color
fr: <b>Modifier la couleur de la brosse

note: type: Content of: <table><tr><td>
en: Get the color of the brush</b>
fr: Obtenir la couleur de la brosse</b>

note: type: Content of: <table><tr><td>
en: [!java|c]void [/!]setBrushColor([!java|c]Color [/!]c[!scala]:Color[/!])
fr: [!java|c]void [/!]setCouleurBrosse([!java|c]Color [/!]c[!scala]:Color[/!])

note: type: Content of: <table><tr><td>
en: [!java|c]Color [/!]getBrushColor()[!scala]:Color[/!]
fr: [!java|c]Color [/!]getCouleurBrosse()[!scala]:Color[/!]

note: type: Content of: <table><tr><td>
en: <b>Interacting with the world</b>
fr: <b>Interagir avec le monde</b>

note: type: Content of: <table><tr><td>
en: <b>Get the color of the ground</b>
fr: <b>Obtenir la couleur du sol</b>

note: type: Content of: <table><tr><td>
en: [!java|c]Color [/!]getGroundColor()[!scala]:Color[/!]
fr: [!java|c]Color [/!]getCouleurSol()[!scala]:Color[/!]

note: type: Content of: <table><tr><td><b>
en: <b>Look for a baggle on the ground
fr: <b>Vrai si biscuit par terre

note: type: Content of: <table><tr><td><b>
en: Look for a baggle in bag
fr: Vrai si on porte un biscuit

note: type: Content of: <table><tr><td><b>
en: Pickup a baggle
fr: Ramasse un biscuit

note: type: Content of: <table><tr><td>
en: Drop a baggle</b>
fr: Poser un biscuit</b>

note: type: Content of: <table><tr><td>
en: (see the note on exceptions)
fr: (voir la note sur les exceptions)

note: type: Content of: <table><tr><td>
en: [!java]boolean [/!][!c]int [/!]isOverBaggle()[!scala]:Boolean[/!]
fr: [!java]boolean [/!][!c]int [/!]estSurBiscuit()[!scala]:Boolean[/!]

note: type: Content of: <table><tr><td>
en: [!java]boolean [/!][!c]int [/!]isCarryingBaggle()[!scala]:Boolean[/!]
fr: [!java]boolean [/!][!c]int [/!]porteBiscuit()[!scala]:Boolean[/!]

note: type: Content of: <table><tr><td>
en: [!java]void [/!]pickupBaggle()
fr: [!java]void [/!]prendBiscuit()

note: type: Content of: <table><tr><td>
en: [!java]void [/!]dropBaggle()
fr: [!java]void [/!]poseBiscuit()

note: type: Content of: <table><tr><td><b>
en: <b>Look for a message
fr: <b>Chercher un message

note: type: Content of: <table><tr><td><b>
en: Add a message
fr: Ajouter un message

note: type: Content of: <table><tr><td><b>
en: Read the message
fr: Lire le message

note: type: Content of: <table><tr><td>
en: Erase the message</b>
fr: Effacer le message</b>

note: type: Content of: <table><tr><td>
en: [!java]boolean [/!][!c]int [/!]isOverMessage()[!scala]:Boolean[/!]
fr: [!java]boolean [/!][!c]int [/!]estSurMessage()[!scala]:Boolean[/!]

note: type: Content of: <table><tr><td>
en: [!java]void [/!]writeMessage([!java]String [/!][!c]char* [/!]msg[!scala]:String[/!])
fr: [!java]void [/!]ecritMessage([!java]String [/!][!c]char* [/!]msg[!scala]:String[/!])

note: type: Content of: <table><tr><td>
en: [!java]String [/!][!c]char* [/!]readMessage()[!scala]:String[/!]
fr: [!java]String [/!][!c]char* [/!]litMessage()[!scala]:String[/!]

note: type: Content of: <table><tr><td>
en: [!java]void [/!]clearMessage()
fr: [!java]void [/!]effaceMessage()

note: type: Content of: <h2>
en: Valid colors
fr: Couleurs valides

note: type: Content of: <table><tr><td>
en: Name
fr: Nom

note: type: Content of: <table><tr><td>
en: Color
fr: Couleur

note: type: Content of: <h2>
en: Note on exceptions
fr: Note sur les exceptions

note: type: Content of: outside any tag (error?)
en: Regular buggles throw a BuggleWallException exception if you ask them to traverse a wall.  They throw a NoBaggleUnderBuggleException exception if you ask them to pickup a baggle from an empty cell, or a AlreadyHaveBaggleException exception if they already carry a baggle.  Trying to drop a baggle on a cell already containing one throws an AlreadyHaveBaggleException exception.  Dropping a baggle when you have none throws a DontHaveBaggleException.
fr: Les buggles normales lèvent une exception BuggleWallException si on cherche à leur faire traverser un mur.
    Elles lèvent une exception NoBaggleUnderBuggleException si vous cherchez à prendre un biscuit dans une case qui n'en contient pas, ou une exception AlreadyHaveBaggleException si vous portez déjà un biscuit.
    Tenter de déposer un biscuit sur une case qui en contient déjà lève une exception AlreadyHaveBaggleException.
    Tenter de poser un biscuit alors qu'on n'en a pas lève une exception DontHaveBaggleException.

note: type: Content of: <p>
en: SimpleBuggles (ie, the one used in first exercises) display an error message on problem so that you don't need to know what an exception is.
fr: Les "SimpleBuggles" (c.-à-d., celles utilisées dans les premiers exercices) affichent un message d'erreur sans que vous ayez à vous soucier de ce qu'est une exception.

note: type: Content of: <p>
en: This world is a simplistic testing environment largely inspired from the http://codingbat.com invented by Nick Parlente.
fr: Ce monde contient un environnement simpliste de tests largement inspiré de http://codingbat.com inventé par Nick Parlente.

note: type: Content of: <p>
en: The typical exercises are very short ones, aiming at improving the tactical programming abilities of the students. That is to say that you will be presented a quite long list of very little exercises about rather simple things. The idea is to train you on these issues until they become automatic to you.
fr: Les exercices classiques sont très courts, et visent à améliorer les capacités de stratégie de programmation des étudiants. C'est pour vous prévenir que vous allez faire face à une très longue liste de très petits exercices à propos de choses très simples. L'idée est de vous entraîner sur ces problèmes jusqu'à ce que cela devienne automatique.

note: type: Content of: <p>
en: In contrary to the other worlds, the BatWorld does not provide any fancy abstraction nor visualization. You have to fill a function, which gets called for a bunch of parameter sets, and that's it.
fr: Contrairement aux autres mondes, le BatWorld ne fournit ni de belles abstractions ni de belles visualisations. Vous aurez à remplier une fonction qui sera appelée avec plusieurs ensembles différents de paramètres, et c'est tout.

note: type: Content of: <p>
en: For more information, you should refer to the CodingBat.com documentation, which contains for example a very useful documentation on boolean operators: http://codingbat.com/doc/ifboolean.html
fr: Pour plus d'informations, vous devriez consulter la documentation de CodingBat.com qui contient par exemple une documentation très utile sur les opérateurs booléens : http://codingbat.com/doc/ifboolean.html

note: type: Content of: <h3>
en: First steps
fr: Premiers pas

note: type: Content of: outside any tag (error?)
en: This first lesson will lead your first steps in programming. It is intended for beginners. List of seen notions per exercise:
fr: Cette première leçon va vous guider dans vos premiers pas en programmation. Elle est destinée aux débutants. Liste des notions vues par exercice :

note: type: Content of: <table><tr><td>
en: Comments
fr: Commentaires

note: type: Content of: <table><tr><td>
en: Conditionals/ Expressions
fr: Instructions conditionnelles et expressions

note: type: Content of: <h2>
en: While loops
fr: Boucles tant que <tt>(while)</tt>

note: type: Content of: <h2>
en: For loops
fr: Boucles pour <tt>(for)</tt>

note: type: Content of: <table><tr><td>
en: Do/While loops
fr: Boucles jusqu'à

note: type: Content of: <h2>
en: Methods
fr: Méthodes

note: type: Content of: <table><tr><td>
en: Arrays
fr: Tableaux

note: type: Content of: <table><tr><td>
en: Welcome in the Buggles' World
fr: Bienvenue dans le monde des buggles

note: type: Content of: <table><tr><td>
en: Java Instructions
fr: Les instructions Java

note: type: Content of: <h2>
en: Writing more complex programs
fr: Écrire des programmes plus complexes

note: type: Content of: <h2>
en: Conditional instructions
fr: Instructions conditionnelles

note: type: Content of: <h2>
en: Baggle Seeking
fr: Chercheur de baggles

note: type: Content of: <h2>
en: Storing and manipulating data
fr: Stocker et manipuler des données

note: type: Content of: <h2>
en: Do .. while loops
fr: Boucles jusqu'à<tt> (do ... while)</tt>

note: type: Content of: <h2>
en: Building methodically
fr: Construire avec méthode

note: type: Content of: <table><tr><td>
en: Methods returning a result
fr: Méthodes retournant un résultat

note: type: Content of: <h2>
en: Methods with parameters
fr: Méthodes avec paramètres

note: type: Content of: <h2>
en: Methodically drawing
fr: Dessiner avec méthode

note: type: Content of: <h2>
en: Methodically drawing (only bigger)
fr: Dessiner avec méthode (en plus grand)

note: type: Content of: <h2>
en: Drawing bigger and bigger
fr: Dessiner de plus en plus grand

note: type: Content of: <table><tr><td>
en: Even more pattern to draw
fr: Encore des motifs à dessiner

note: type: Content of: <h2>
en: Slug Hunting
fr: Chasse à la limace

note: type: Content of: <h2>
en: Slug Tracking
fr: Pistage de la limace

note: type: Content of: <h2>
en: Snake World
fr: Monde de serpents

note: type: Content of: <table><tr><td>
en: Knitting and Arrays
fr: Tricots et tableaux

note: type: Content of: <table><tr><td>
en: Knitting, Arrays and modulos
fr: Tricots, tableaux et modulos

note: type: Content of: <h2>
en: Traversal by column
fr: Parcours en colonne

note: type: Content of: <h2>
en: Traversal by line
fr: Parcours en ligne

note: type: Content of: <h2>
en: Zig-zag traversal
fr: Parcours en zig-zag

note: type: Content of: <h2>
en: Diagonal Traversal
fr: Parcours en diagonale

note: type: Content of: <h2>
en: Meaning of the symbols
fr: Légende

note: type: Content of: <table><tr><td>
en: Introducing the concept
fr: Le concept est introduit

note: type: Content of: <table><tr><td>
en: Working on the concept
fr: L'exercice travaille sur le concept

note: type: Content of: <table><tr><td>
en: Concept assumed mastered
fr: Le concept est supposé maîtrisé

note: type: Content of: <table><tr><td>
en: Concept not mandated by the exercise
fr: Le concept n'est pas indispensable à l'exercice

note: type: Content of: <h2>
en: What will I learn?
fr: Que vais-je apprendre ?

note: type: Content of: <p>
en: You will learn the very basics of programming. At least, you will be presented the most important concepts, allowing you to read most simple algorithms. You will not be able to write or read full programs because you will still not know about objects, but you will master what is called "Tactical programming", meaning that you will master the syntax enough to not have any issue with it, allowing you to focus on the fundamental problems of what you want to solve instead of struggling with syntactic difficulties.
fr: Vous allez apprendre les bases de la programmation. Disons au moins que les principaux concepts vous auront été présentés, vous permettant de lire et comprendre la plupart des algorithmes. Vous ne pourrez toujours pas écrire ou même lire des programmes complets en [!thelang] car la notion d'objet ne fait pas partie des objectifs de cette leçon, mais vous maîtriserez ce qu'on appelle la « programmation tactique », ce qui veut dire que votre maîtrise de la syntaxe vous permettra de vous concentrer sur les problèmes à résoudre sans vous battre contre le compilateur à propos de la syntaxe.

note: type: Content of: <p>
en: This first lesson will lead your first steps in programming. It is intended for beginners.
fr: Cette première leçon va vous guider dans vos premiers pas en programmation. Elle est destinée aux débutants.

note: type: Content of: <p>
en: If you are not sure, go for this lesson that will teach you the bases of programming.
fr: Dans le doute, faites cette leçon qui vous enseignera les bases de la programmation.

note: type: Content of: <h2>
en: Welcome to the PLM
fr: Bienvenus dans la PLM

note: type: Content of: <p>
en: The goal of this first exercise is to instruct your buggle to move forward by one step. Switch between the views on the right for more info. <i>World</i> depicts the world as it is now, while <i>Objective</i> depicts what you should get.
fr: L'objectif de ce premier exercice est de faire avancer votre buggle
    d'un pas. Alternez entre les vues à droite pour plus de détail:
    <i>Monde</i> montre le monde tel qu'il est pour l'instant, tandis que
    <i>Objectif</i> montre ce que vous devez obtenir.

note: type: Content of: <h3>
en: My <i>buggle</i>? What is this??
fr: Ma <i>buggle</i> ? Qu'est ce que c'est ??

note: type: Content of: <p>
en: Buggles are little animals obeying any order you may give them. Currently, you must use the [!thelang/] programming language for that, but you can change the language from the menu, or by clicking the icon in the status bar.
fr: Les buggles sont de petites bêtes qui obéissent aux ordres que vous
    leur donnez. Pour l'instant, vous devez utiliser le langage
    [!thelang/] pour cela, mais vous pouvez en changer dans le menu ou en
    cliquant sur l'icone dans la barre du bas.

note: type: Content of: <h3>
en: How to proceed?
fr: Comment faire ?

note: type: Content of: <p>
en: Write your program in the "Code" pane. It should read as follows:
fr: Écrivez votre programme dans l'onglet "Code". Il devrait ressembler à
    ceci :

note: type: Content of: <pre>
en: [!java|scala|python]forward()[!java];[/!][/!][!c]stepForward();[/!]
fr: [!java|scala|python]avance()[!java];[/!][/!][!c]avancePas();[/!]

note: type: Content of: <p>
en: Do not forget the final <code>;</code> which tells the compiler that the instruction is over (yes, computers are so dumb that they cannot <i>guess</i> obvious stuff like this).
fr: N'oubliez pas le <code>;</code> final, car cela indique au compilateur que l'instruction est terminée (oui, les ordinateurs sont si stupides qu'il <i>faut</i> leur préciser des choses aussi simples).

note: type: Content of: <p>
en: Once done, click on Run to execute your code.
fr: Une fois terminé, cliquez sur «Exécuter» pour lancer votre programme.

note: type: Content of: <p>
en: If your code contains errors, that's perfectly OK: Even talented programmers struggle on their code.  The computer will display error messages in the console to help you fixing them. These messages may sound scary at first glance, but don't panic. The compiler is only somehow limited in its communication abilities, but it's not mean. If you look closer, the solution to solve your issue is written somewhere in those cryptic messages. You will see, with a bit of habit, we get used to it.
fr: Si votre code contient des erreurs, c'est tout à fait normal : même
    les meilleurs programmeurs se creusent la tête sur leur
    code. L'ordinateur affichera les messages d'erreur sur la console pour
    vous aider à les résoudre. Les messages affichés peuvent paraître inquiétant au premier abord, mais pas de panique. Le compilateur est seulement pas très doué pour communiquer, il n'est pas fondamentalement méchant. En regardant de plus près, la solution pour corriger les problèmes est inscrite dans ces messages cryptiques. Vous verrez, avec un peu d'entraînement, vous vous y habituerez.

note: type: Content of: <h3>
en: But that's [!thelang]!
fr: Mais c'est du [!thelang] !

note: type: Content of: outside any tag (error?)
en: Currently, the PLM is configured to accept [!thelang] programs, but it can also accept [!java]Python or Scala[/!][!scala]Java or Python[/!][!python]Java or Scala[/!] programs.  Either click on the language icon at the very bottom right of the window, or head to the <tt>Language/Computer</tt> menu item to change it.
fr: Actuellement, la PLM est configurée pour traiter des programmes en [!thelang], mais elle peut aussi gérer des programmes en [!java]Python ou Scala[/!][!scala]Java ou Python[/!][!python]Java ou Scala[/!]. Pour changer, cliquez sur l'icône du langage tout en bas à droite ou utilisez le menu <tt>Langage/Ordinateur</tt>.

note: type: Content of: outside any tag (error?)
en: Congratulations! You just wrote your first program! You got the idea now: programming is nothing more than giving simple instructions to the computer that blindly apply them. The main difficulty is to explain stuff to something as stupid as a computer...
fr: Félicitations ! Vous venez d'écrire votre premier programme ! Vous avez compris l'idée maintenant : programmer, c'est simplement donner des instructions à l'ordinateur, qui les applique aveuglément. La plus grande difficulté est d'expliquer quoi faire à quelque chose d'aussi bête que l'ordinateur...

note: type: Content of: <p>
en: Our second program will be a bit more complicated, but not much. The goal for your buggle is simply to draw a house (a box), and hide inside. Check the objective world to see exactly what this means.
fr: Notre second programme sera un peu plus compliqué, mais pas tellement. L'objectif de votre buggle est simplement de se dessiner une maison (une boîte), et de se cacher dedans. Vérifiez le monde objectif pour voir exactement ce que cela veut dire.

note: type: Content of: <p>
en: For that, you will need <code>forward()</code>, <code>left()</code> and <code>right()</code>. Use your brush to mark the ground as you walk. Start marking the ground with <code>brushDown()</code>, and stop it with <code>brushUp()</code> afterward (e.g., to enter your house without marking its ground).
fr: Pour cela, vous aurez besoin de <code>avance()</code>,
    <code>gauche()</code> et <code>droite()</code>. Utilisez votre brosse pour marquer le sol en marchant. Commencez à marquer le sol avec <code>baisseBrosse()</code>, et arrêtez avec <code>leveBrosse()</code> (par exemple pour entrer dans votre maison sans marquer le sol).

note: type: Content of: <h3>
en: What exactly is a program?
fr: Qu'est exactement qu'un programme ?

note: type: Content of: <p>
en: Programs are mainly suites of method calls, which are no more than a list of simple orders given to the machine. It is very similar to a recipe stating <i>Melt the chocolate pieces, add sugar, cool the mix and serve</i>.  [!thelang] wants to have the instructions separated by semi-columns (;)[!python|scala] or by new lines[/!], and followed by parenthesis. Our little receipe would thus be written in the following way[!python|scala] (you can also add semi-columns at the end of the lines, but this is not mandatory)[/!].
fr: Les programmes sont des enchaînements d'appels de méthodes, qui
    forment des listes d'ordres simples donnés à la machine. C'est assez
    comparable à une recette de cuisine où l'on dit <i>cassez les œufs
    puis ajoutez du sel puis mélangez le tout puis faites
    cuire</i>. En [!thelang], il faut séparer ces instructions par des
    symboles point-virgule (;)[!python|scala] ou par des retours à la
    ligne[/!], et suivis de parenthèses. Notre recette s'écrirait de la
    façon suivante [!python|scala](vous pourriez aussi ajouter des
    points-virgules à la fin des lignes, mais c'est optionel)[/!] .

note: type: Content of: <pre>
en: meltTheChocolatePieces()[!java|c];[/!]
    addSugar()[!java|c];[/!]
    coolMix()[!java|c];[/!]
    serve()[!java|c];[/!]
fr: casserLesOeufs()[!java|c];[/!]
    ajouterDuSel()[!java|c];[/!]
    melangerLeTout()[!java|c];[/!]
    faireCuire()[!java|c];[/!]

note: type: Content of: <p>
en: Do not write it all on one line only even if the computer would accept it [!python|scala](provided that you don't omit the semi-columns)[/!]. This is a <b>really bad idea</b>, hindering the readability.  <i>Programs must be written for people to read, and only incidentally for machines to execute,</i> as said Harold Abelson.
fr: N'écrivez pas tout sur la même ligne, même si cela ne fait aucune
    différence pour l'ordinateur[!python|scala] (si vous ajoutez les
    points-virgules)[/!]. C'est une <b>très mauvaise idée</b> car cela
    rend le code plus difficile à relire. Comme disait Harold Abelson,
    <i>les programmes doivent surtout être écrits pour être lisibles par
    les humains, et accessoirement pour être exécutables par les
    machines</i>.

note: type: Content of: <p>
en: There is a limited set of instructions that buggles understand, and we will eventually learn how to define new ones. For now, there is a method for each button of the interactive control panel. To achieve the same effect than the <b>forward</b> button (making the buggle moving one step forward), you need to write the following in the editor:
fr: Les buggles peuvent comprendre un ensemble fini d'instructions (et
    nous verrons plus tard comment leur apprendre de nouveaux trucs). Il y
    a une méthode associée à chaque bouton du panneau de commande
    interactive.  Pour faire la même chose que le bouton <b>avance</b>
    (faire avancer la buggle d'un pas), il faut écrire dans l'éditeur :

note: type: Content of: <p>
en: Likewise, to achieve the same effect than the <b>[!java|scala|python]backward[/!][!c]stepBackward[/!]</b>, <b>left</b> and <b>right</b> buttons, you need to use respectively:
fr: De même, pour faire l'équivalent des boutons <b>[!java|scala|python]recule[/!][!c]reculePas[/!]</b>, <b>gauche</b> et <b>droite</b>, il faut utiliser respectivement :

note: type: Content of: <pre>
en: backward()[!java|c];[/!]
    left()[!java|c];[/!]
    right()[!java|c];[/!]
fr: recule()[!java|c];[/!]
    gauche()[!java|c];[/!]
    droite()[!java|c];[/!]

note: type: Content of: <p>
en: The <b>mark</b> button is a bit particular, since it correspond to two methods: the first one moves the pen up while the second moves it down.
fr: Le bouton <b>marquer</b> est un peu particulier, puisqu'il correspond à deux méthodes : la première lève le crayon, tandis que la seconde le baisse.

note: type: Content of: <pre>
en: brushUp()[!java|c];[/!]
    brushDown()[!java|c];[/!]
fr: leveBrosse()[!java|c];[/!]
    baisseBrosse()[!java|c];[/!]

note: type: Content of: <p>
en: The buggle offers other methods, that are presented from the "Help/about this world" menu and will be introduced on need.
fr: La buggle offre d'autres méthodes, présentées dans le menu "Aide/À propos de ce monde". Elles seront introduites au fur et à mesure des besoins.

note: type: Content of: outside any tag (error?)
en: Now that we know how to draw things on the board, we'll enjoy this ability and draw a beautiful G on the board (check Objective panel for details on what is expected).
fr: Maintenant que vous savez écrire des choses sur le sol, nous allons utiliser cette compétence pour dessiner un merveilleux G par terre. Consultez le panneau d'objectif pour les détails de ce qui est attendu.

note: type: Content of: <p>
en: When you write a quite complex program, it is sometimes useful to <b>add comments</b> to simplify the code reviews afterward. Here for example, it's quite easy to get lost in the drawing process, and you may want to add comments like <i>vertical bar done</i> or <i>finished drawing the G. Time to move back to initial position</i>. Commenting your code is almost mandatory if you (or someone else) want to read it afterward, although over-commenting (describing obvious stuff) is a bad idea as the important idea get lost in the noise.
fr: Quand vous écrivez un programme un peu complexe, il est souvent pratique d'ajouter des <b>commentaires</b> pour simplifier la relecture du code après coup. Ici par exemple, il est assez facile de se perdre dans les ordres nécessaires au dessin. Il peut être pratique d'ajouter des commentaires comme <i>fin de la barre verticale</i> ou <i>Fini de dessiner le G. Retournons à la position initiale</i>. Documenter votre code est presque toujours nécessaire si quelqu'un (vous ou quelqu'un d'autre) veut le lire après coup. Cependant, sur-commenter des choses triviales est une mauvaise idée car cela dilue les informations dans des commentaires trop verbeux.

note: type: Content of: <p>
en: There is [!java]three[/!][!python|scala|c]two[/!] types of comments in [!thelang], instructing the [!java|scala|c]compiler[/!][!python]interpreter[/!] to not read the text you add for humans:
fr: Il y a [!java]trois[/!][!python|scala|c]deux[/!] sortes de commentaires en [!thelang], indiquant [!java|scala|c]au compilateur[/!][!python]à l'interpréteur[/!] qu'il ne doit pas lire le texte ajouté pour les humains :

note: type: Content of: <ul><li>
en: <b>Comments on a single line</b>. When the [!java|scala|c]compiler[/!][!python]interpreter[/!] encounters the symbol [!java|scala|c]//[/!][!python]#[/!], it ignores the end of the line.
fr: <b>Commentaires sur une seule ligne</b>. Quand le [!java|scala|c]compilateur[/!][!python]interpréteur[/!] rencontre le symbole [!java|scala|c]//[/!][!python]#[/!], il ignore la fin de la ligne.

note: type: Content of: <ul><li>
en: <b>Comments on several lines</b>. The [!java|scala|c]compiler[/!][!python]interpreter[/!] ignores anything placed between [!java|scala|c]the symbols /* and */ even if they are placed on differing lines.[/!] [!python]a line beginning with ''' until the next line ending with '''.[/!]
fr: <b>Commentaires sur plusieurs lignes</b>. [!java|scala|c]Le compilateur[/!][!python]L'interpréteur[/!] ignore tout ce qui se trouve entre [!java|scala|c]les symboles /* et */, même s'ils sont sur des lignes différentes.[/!]
    [!python]une ligne commençant par ''' et la prochaine ligne terminant par '''.[/!]

note: type: Content of: <pre>
en: methodCallReadByThe[!java|scala|c]Compiler[/!][!python]Interpreter[/!]()[!java|c];[/!] <span class="comment">[!java|scala|c]//[/!][!python]#[/!] all this is ignored</span>
    otherCall()[!java|c];[/!] [!java|scala|c]<span class="comment">/* This is</span>
    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span class="comment"> also ignored */</span>[/!]
    [!python]<span class="comment">''' This is</span>
    <span class="comment">also ignored  '''</span>[/!]
    yetAnotherCall()[!java|c];[/!]
fr: methodeAppeleeParLe[!java|scala|c]Compilateur[/!][!python]Interpreteur[/!]()[!java|c];[/!] <span class="comment">[!java|scala|c]//[/!][!python]#[/!] tout ceci est ignoré</span>
    autreAppel()[!java|c];[/!] [!java|scala|c]<span class="comment">/* Ceci est</span>
    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span class="comment"> également ignoré */</span>[/!]
    [!python]<span class="comment">''' Ceci est</span>
    <span class="comment">également ignoré '''</span>[/!]
    encoreUneAutreAppel()[!java|c];[/!]

note: type: Content of: <p>
en: There is a third kind of comments in Java, between /** and */, which are read by a specific program called JavaDoc to generate automatically the documentation explaining how to use the code. These comments must follow a very precise formalism.
fr: Il existe une troisième forme de commentaires en Java, entre /** et */, qui sont lus par un programme nommé JavaDoc pour générer automatiquement la documentation expliquant comment utiliser le code. Ces commentaires doivent suivre un formalisme précis.

note: type: Content of: <p>
en: The comments on several lines are often used to document how to use the code, while others are more used to describe how this code works.
fr: Les commentaires sur plusieurs lignes sont souvent utilisés pour documenter
    comment utiliser le code, tandis que les autres types de commentaires sont
    souvent utilisés pour documenter comment le code fonctionne.

note: type: Content of: outside any tag (error?)
en: Programs made of simple suite of instructions similar to previous exercise are quite boring. They always do the same thing, and cannot react to external conditions. A <b>conditional</b> let the program adapt by doing something like <i>if it's raining, take an umbrella</i>.
fr: Les programmes faits d'une simple suite d'instructions comme celui de l'exercice précédent sont bien ennuyeux. Ils font toujours la même chose, et ne peuvent pas réagir aux conditions extérieurs. Une <b>instruction conditionnelle</b> permet au programme de s'adapter en disant quelque chose comme <i>S'il pleut, prend un parapluie</i>.

note: type: Content of: <p>
en: The [!thelang] syntax is the following:
fr: La syntaxe en [!thelang] est la suivante :

note: type: Content of: <pre>
en: [!java|scala|c]if (<b>condition</b>) {
    &nbsp;&nbsp;&nbsp;&nbsp;<b>whatToDoIfTrue();</b>
    &nbsp;&nbsp;&nbsp;&nbsp;<b>whatToDoNextIfTrue();</b>
    }[/!][!python]if <b>condition</b>:
    &nbsp;&nbsp;&nbsp;&nbsp;<b>whatToDoIfTrue()</b>
    &nbsp;&nbsp;&nbsp;&nbsp;<b>whatToDoNextIfTrue()</b>[/!]
    <b>whatToDoAnyway()[!java|c];[/!]</b>
fr: [!java|scala|c]if (<b>condition</b>) {
    &nbsp;&nbsp;&nbsp;&nbsp;<b>aFaireSiVraie();</b>
    &nbsp;&nbsp;&nbsp;&nbsp;<b>aFaireEnsuiteSiVraie();</b>
    }[/!][!python]if <b>condition</b>:
    &nbsp;&nbsp;&nbsp;&nbsp;<b>aFaireSiVraie()</b>
    &nbsp;&nbsp;&nbsp;&nbsp;<b>aFaireEnsuiteSiVraie()</b>[/!]
    <b>aFaireDansTousLesCas()[!java|c];[/!]</b>

note: type: Content of: <p>
en: If the condition is true, the code of the next block will be executed and then it will continue with the rest of the code.  If the condition is false, the next block is ignored and the execution continues after it.  The conditional block can contain several instructions, it can even contain other tests, along with their sub-blocks.
fr: Le mot <code>if</code> signifie «si» en anglais. Si la condition est vraie, alors le code du bloc suivant sera exécuté, puis l'exécution se poursuivra avec la suite du code, après le bloc. Sinon, si la condition est fausse, le bloc suivant sera ignoré et l'exécution passera directement au code placé après lui. Le bloc conditionnel peut contenir plusieurs instructions. Il peut même contenir d'autre tests, avec leurs sous-blocs associés.

note: type: Content of: <p>
en: In this example, the instructions <code>whatToDoIfTrue()</code> and <code>whatToDoNextIfTrue()</code> will be executed if and only if the condition is true, while the instruction <code>whatToDoAnyway()</code> will be executed whether or not the condition is true.
fr: Dans cet exemple, les instructions <code>aFaireSiVraie()</code> et <code>aFaireEnsuiteSiVraie()</code> seront exécutée si (et seulement si) la condition est vraie tandis que l'instruction <code>aFaireDansTousLesCas()</code> sera exécutée que la condition soit vraie ou fausse.

note: type: Content of: <p>
en: In [!thelang], the blocks of code are [!java|scala|c]enclosed between curly brackets: a { sign opens the block, while a } sign closes it.  White spaces are not important[/!][!java|c].[/!][!scala], provided that your instructions are still separated with a semi-column or an end of line.[/!] [!java|scala|c]It is still very important to correctly indent your code to keep it readable.[/!] [!python]marked by the indentation: every lines that are a bit shifted to the right with white spaces belong to the block. Quite often, people use 4 spaces for indentation, but it works if you use more or less spaces. Simply, any lines of the block must use the same amount of spaces.  The end of Python code blocks are not marked by any specific char.  Indenting lines starts a block and unindenting ends it. Do not forget the colon (:) at the end of the <code>if</code> line, python needs it to know that a new block begins. The fact that python relies on indentation to delimit blocks is a very good property for beginners: it will force you to adhere to strict code presentation standards.[/!] It is very easy to get lost in your own code if it's not properly indented, so you want to clean it up so that working on your code remains pleasant and productive.
fr: En [!thelang], les blocs sont 
    [!java|scala|c]délimités par des accolades : le symbole { commence un bloc tandis
    que le symbole } le ferme.  Les caractères blancs ne sont pas pris en 
    compte[/!][!java|c].[/!][!scala], tant que les instructions restent séparées soit par des points-virgules, soit par des retour à la ligne.[/!] 
    [!java|scala|c]Il reste très important d'indenter correctement votre code pour qu'il reste lisible.[/!] 
    [!python]marqués par l'indentation : toutes les lignes indentés (=décalées vers la droite par des espaces) font partie du bloc. Il est assez courant d'utiliser quatre espaces pour indenter le code, mais cela fonctionne quel que soit le nombre de caractères blancs utilisés pour cela. Simplement, toutes les lignes d'un bloc donné doivent utiliser le même nombre de blancs. La fin des blocs de code n'est pas marquée par un symbole particulier: il s'arrête dès que les lignes ne sont plus indentées. N'oubliez pas les deux points (:) à la fin de la ligne <code>if</code>, python en a besoin pour savoir qu'un nouveau bloc commence.
    Le fait que python utilise l'indentation pour marquer les blocs est un avantage pour les débutants: cela vous forcera à respecter des critères stricts de mise en forme de votre code.[/!] 
    Il est très facile de se perdre dans un code qui n'est pas correctement indenté. Il est donc important que vous fassiez en sorte que votre code reste clair et lisible pour que le relire et le modifier reste plaisant et productif.

note: type: Content of: <p>
en: All indentations of a given block must be consistent, and it is not possible to cut a block. The two following codes are incorrect and will raise errors.
fr: Toutes les instructions d'un bloc doivent avoir la même indentation, et il n'est pas possible de couper un bloc. Les deux exemples suivants de code sont incorrects et vont générer des erreurs.

note: type: Content of: <pre>
en: if <b>condition</b>:
    &nbsp;&nbsp;&nbsp;&nbsp;<b>whatToDo()</b>
    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<b>whatToDoNext()</b> <span class="comment"># one space too much </span>
    <b>whatToDoAnyway()</b>
fr: if <b>condition</b>:
    &nbsp;&nbsp;&nbsp;&nbsp;<b>quoiFaire()</b>
    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<b>quoiFaireEnsuite()</b> <span class="comment"># une espace de trop</span>
    <b>quoiFaireDansTousLesCas()</b>

note: type: Content of: <pre>
en: if <b>condition</b>:
    &nbsp;&nbsp;&nbsp;&nbsp;<b>whatToDo()</b>
    <b>whatToDoAnyway()</b>
    &nbsp;&nbsp;&nbsp;&nbsp;<b>whatToDoNext()</b> <span class="comment"># this block is not hanging to a condition line</span>
fr: if <b>condition</b>:
    &nbsp;&nbsp;&nbsp;&nbsp;<b>quoiFaire()</b>
    <b>quoiFaireDansTousLesCas()</b>
    &nbsp;&nbsp;&nbsp;&nbsp;<b>quoiFaireEnsuite()</b> <span class="comment"># Ce bloc n'est rattaché à aucune ligne de condition</span>

note: type: Content of: <p>
en: The condition must be a <code>[!c]int[/!][!java]boolean[/!][!scala|python]Boolean[/!]</code> expression.  The inner block of code will get executed if the expression is evaluated to <code>[!c]1[/!][!java|scala]true[/!][!python]True[/!]</code> and it will be ignored if it is <code>[!c]0[/!][!java|scala]false[/!][!python]False[/!]</code>.  [!python|scala|java]<code>[!java|scala]true[/!][!python]True[/!]</code> and <code>[!java|scala]false[/!][!python]False[/!]</code> are constant values defined by [!thelang] directly, just as 0 or 1 in mathematics.[/!]
fr: La condition doit être une expression de type <code>[!c]int[/!][!java]boolean[/!][!scala|python]Boolean[/!]</code> (expression booléenne).  Le sous-bloc sera exécuté seulement si cette expression vaut <code>[!c]1[/!][!java|scala]true[/!][!python]True[/!]</code> (vrai), et il sera ignoré si sa valeur est <code>[!c]0[/!][!java|scala]false[/!][!python]False[/!]</code> (faux).
    <code>[!java|scala]true[/!][!python]True[/!]</code> et <code>[!java|scala]false[/!][!python]False[/!]</code> sont des constantes définies directement par [!thelang], tout comme 0 ou 1 en mathématiques.

note: type: Content of: <p>
en: The condition can be a <code>[!c]int[/!][!java]boolean[/!][!scala|python]Boolean[/!]</code> variable (we will come back on variables in a later exercise, don't worry) or an arithmetic test, such as <code>x == 5</code>, which checks whether the current value of <code>x</code> is 5, or such as <b>!=</b> (checking inequality, that is, returning [!c]1[/!][!java|scala]true[/!][!python]True[/!] only if the left-hand side is different from the right-hand side), <b>&lt;</b> (smaller than), <b>&gt;</b> (larger than), <b>&lt;=</b> (smaller or equal to), <b>&gt;=</b> (larger or equal to).
fr: La condition peut aussi être une variable booléenne (nous reviendrons sur les variables dans un autre exercice, pas de panique) ou un test arithmétique,comme <code>x == 5</code>, qui teste si la valeur actuelle de <tt>x</tt> est 5, ou bien comme <b>!=</b> (teste l'inégalité, càd si le membre gauche a une valeur différente du membre droit), <b>&lt;</b> (inférieur à), <b>&gt;</b> (supérieur à), <b>&lt;=</b> (inférieur ou égal à), <b>&gt;=</b> (supérieur ou égal à).

note: type: Content of: <p>
en: Beware of the classical trap, which consists in testing the equality of a variable using = instead of ==. Hopefully, the [!java|scala|c]compiler[/!][!python]interpreter[/!] detects this problem most of the time, but it could get trapped is some cases (such as when you are affecting a [!c]int[/!][!java|python|scala]boolean[/!] variable). So you'd better to be careful...
fr: Attention au piège classique, qui consiste à tester l'égalité d'une variable avec = au lieu de ==. Heureusement, [!java|scala|c]le compilateur[/!][!python]l'interpréteur[/!] détecte le plus souvent ce problème et vous le signale, mais pas tout le temps. Si la variable est de type booléen, il peut se faire prendre au piège, et il convient donc d'être attentif...

note: type: Content of: <p>
en: The condition can also be a call to some particular methods returning a boolean. For example, the <code>isFacingWall()</code> method of the buggle returns [!c]1[/!][!java|python|scala]true[/!] if the buggle is facing a wall, and [!c]0[/!][!java|python|scala]false[/!] in the other case.
fr: La condition peut également être un appel à certaines méthodes particulières, dont le résultat est un booléen. Par exemple, la méthode <tt>estFaceMur()</tt> de la buggle renvoie [!c]1[/!][!java|python|scala]vrai[/!] si la buggle est face à un mur, et [!c]0[/!][!java|python|scala]faux[/!] sinon.

note: type: Content of: <p>
en: Finally, a condition can be composed of several sub-conditions connected by boolean operations:
fr: Enfin, il est possible de construire une condition composée de plusieurs sous-conditions reliées par des opérations booléennes:

note: type: Content of: <ul><li>
en: <code>cond1 [!java|scala|c]&&[/!][!python]and[/!] cond2</code> is true when <tt>cond1</tt> <b>and</b> <tt>cond2</tt> are both true (if <tt>cond1</tt> is false, <tt>cond2</tt> is not even evaluated as we already know that the conjunction of both propositions cannot be true).
fr: <code>cond1 [!java|scala|c]&&[/!][!python]and[/!] cond2</code> est vraie si <tt>cond1</tt> <b>et</b> <tt>cond2</tt> est vraie (d'ailleurs, si <tt>cond1</tt> est fausse, <tt>cond2</tt> n'est même pas évaluée puisqu'on sait déjà que la conjonction des deux propositions ne peut pas être vraie).

note: type: Content of: <ul><li>
en: <code>cond1 [!java|scala|c]||[/!][!python]or[/!] cond2</code> is true if <tt>cond1</tt> <b>or</b> <tt>cond2</tt> is true (if <tt>cond1</tt> is true, <tt>cond2</tt> is not even evaluated as we already know that the disjunction of both propositions cannot be false).
fr: <code>cond1 [!java|scala|c]||[/!][!python]or[/!] cond2</code> est vraie si <tt>cond1</tt> <b>ou</b> <tt>cond2</tt> est vraie (d'ailleurs, si <tt>cond1</tt> est vraie, <tt>cond2</tt> n'est même pas évaluée puisqu'on sait déjà que la disjonction des deux propositions ne peut pas être fausse).

note: type: Content of: <ul><li>
en: <code>[!java|scala|c]![/!][!python]not [/!]cond</code> is true if <tt>cond</tt> is false.
fr: <code>[!java|scala|c]![/!][!python]not [/!]cond</code> est vraie si <tt>cond</tt> ne l'est pas.

note: type: Content of: <ul><li>
en: When the expression becomes complicated, it is better to add parenthesis to force the order of evaluation.  Do not hesitate to add more parenthesis to remove any ambiguities that may appear in an expression.
fr: Quand les expressions deviennent compliquées, il est préférable d'ajouter quelques parenthèses pour lever toute ambiguïté sur l'ordre d'évaluation. N'hésitez pas à mettre suffisamment de parenthèses pour la rendre plus lisible.

note: type: Content of: <p>
en: Last, it is possible to specify what to do when the condition is false using the following syntax. In this case, the instruction <code>whatToDoIfItsFalse</code> will be executed only if the condition is false.
fr: Pour finir, il est possible de spécifier ce qu'il faut faire quand la condition est fausse, en utilisant la syntaxe suivante («else» signifie «sinon» en anglais). Dans ce cas, l'instruction <code>aFaireSiLaConditionEstFausse()</code> ne sera exécutée que si la condition est fausse.

note: type: Content of: <pre>
en: [!java|scala|c]if (<b>condition</b>) {
    &nbsp;&nbsp;&nbsp;&nbsp;<b>whatToDoIfTheConditionIsTrue();</b>
    } else {
    &nbsp;&nbsp;&nbsp;&nbsp;<b>whatToDoIfItsFalse();</b>
    }[/!][!python]if (<b>condition</b>):
    &nbsp;&nbsp;&nbsp;&nbsp;<b>whatToDoIfTheConditionIsTrue()</b>
    else:
    &nbsp;&nbsp;&nbsp;&nbsp;<b>whatToDoIfItsFalse()</b>[/!]
fr: [!java|scala|c]if (<b>condition</b>) {
    &nbsp;&nbsp;&nbsp;&nbsp;<b>aFaireSiLaConditionEstVraie();</b>
    } else {
    &nbsp;&nbsp;&nbsp;&nbsp;<b>aFaireSiElleEstFausse();</b>
    }[/!][!python]if (<b>condition</b>):
    &nbsp;&nbsp;&nbsp;&nbsp;<b>aFaireSiLaConditionEstVraie()</b>
    else:
    &nbsp;&nbsp;&nbsp;&nbsp;<b>aFaireSiElleEstFausse()</b>[/!]

note: type: Content of: <p>
en: Don't forget the colon (:) after the else, it is indicating that a new block is beginning.
fr: N'oubliez pas les deux points (:) après le else, ils indiquent qu'un nouveau bloc débute.

note: type: Content of: <h3>
en: Exercise goal
fr: Objectif de cet exercice

note: type: Content of: outside any tag (error?)
en: <a name="Objectives"/> If the buggle is facing a wall, you must move one step back. If not, you must move one step forward. To detect whether you are facing a wall, simply use the <code>isFacingWall()</code> built-in, that every buggle understands.
fr: <a name="Objectifs"/> Si la buggle est face à un mur, il faut reculer d'un pas; Sinon, il faut avancer d'un pas.
    Pour savoir si on est face à un mur, il suffit d'utiliser la méthode prédéfinie des buggles nommée <code>estFaceMur()</code>.

note: type: Content of: <p>
en: This exercise is a bit different: your code has to work for several buggles, each of them being in a specific initial condition. The same code will be executed for each of them.
fr: Cet exercice est un peu particulier : il faut que votre programme fonctionne pour plusieurs buggles, chacune étant dans une situation initiale différente. Le même code sera utilisé pour chacune d'entre elles.

note: type: Content of: <p>
en: When your program works, move forward to the next exercise, that is hidden in a sub-tree of the selection window.
fr: Quand votre programme fonctionne, passez à l'exercice suivant (qui est caché par défaut dans un sous-arbre de la fenêtre de sélection).

note: type: Content of: <p>
en: In addition to conditionals, another handy construction is the ability to repeat an action while a specific condition does not appear. A while loop is used for that, with the following syntax.
fr: En plus des instructions conditionnelles, une autre construction pratique est de pouvoir répéter une action tant qu'une condition particulière n'est pas arrivée. On utilise pour cela une boucle <tt>while</tt>, dont la syntaxe est la suivante :

note: type: Content of: <p>
en: The inner bloc is then executed again and again, as long as the condition remains true.  More specifically, the buggle tests the value of the condition. If it's false, it ignores the bloc and continue below.  If it's true, it executes the bloc.  After that, it tests the condition. If it's now false (for example because the moves of the block made us facing the wall), it now ignores the bloc and continue.  If it's still true, it execute the bloc and reevaluate the condition. It does so as long as the condition remains true.
fr: Le bloc est alors exécuté encore et encore, tant que la condition est vraie. Plus précisément, la buggle teste la valeur de la condition. Si elle est fausse, le bloc est ignoré et l'exécution continue avec la suite. Si la condition est vraie, le bloc est exécuté. Ensuite, la buggle réévalue la condition. Si elle est devenue fausse (par exemple parce que les déplacements du bloc nous ont mis face au mur), le bloc est maintenant ignoré et on continue avec la suite. Mais si la condition est toujours vraie, on exécute une nouvelle fois le bloc avant de réévaluer une fois de plus la condition. Cela continue ainsi tant que la condition reste vraie.

note: type: Content of: <p>
en: Naturally, if the chosen action does not modify the value of the condition, the buggle will do the action endlessly. The <b>stop</b> button of the interface becomes then handy. To test this, you can try to type the following code in the editor:
fr: Évidement, si l'action en question ne modifie pas la valeur de la condition, la buggle va exécuter l'action à l'infini. C'est dans ce genre de cas que le bouton <b>stop</b> de l'interface devient utile. Pour tester cela, vous pouvez essayer de taper le code suivant dans l'éditeur :

note: type: Content of: <pre>
en: [!java|scala]while (true) {
    &nbsp;&nbsp;&nbsp;&nbsp;left();
    }[/!][!c]while (1) {
    &nbsp;&nbsp;&nbsp;&nbsp;left();
    }[/!][!python]while True:
    &nbsp;&nbsp;&nbsp;&nbsp;left()[/!]
fr: [!java|scala]while (true) {
    &nbsp;&nbsp;&nbsp;&nbsp;gauche();
    }[/!][!c]while (1) {
    &nbsp;&nbsp;&nbsp;&nbsp;gauche();
    }[/!][!python]while True:
    &nbsp;&nbsp;&nbsp;&nbsp;gauche()[/!]

note: type: Content of: <p>
en: This will let the buggle turn left as long as <code>[!c]1[/!][!java|scala]true[/!][!python]True[/!]</code> remains true (ie, endlessly), or until you stop it manually using the stop button.
fr: La buggle va tourner vers la gauche tant que <code>[!c]1[/!][!java|scala]true[/!][!python]True[/!]</code> est vrai (sans fin donc) jusqu'à ce que vous l'arrêtiez manuellement avec le bouton stop.

note: type: Content of: outside any tag (error?)
en: You now have to write some code so that your buggles move forward until they encounter a wall. The idea is thus to do something like:
fr: Il vous faut maintenant écrire le code nécessaire pour que vos buggles avancent jusqu'à rencontrer un mur. L'idée est donc de faire :

note: type: Content of: <pre>
en: while we are not facing a wall, do:
    &nbsp;&nbsp;moveForward()
fr: tant que l'on est pas face à un mur, faire :
    &nbsp;&nbsp;avancer()

note: type: Content of: <p>
en: Look at the documentation (in "Help/About this world") for the full list of buggles' methods.
fr: Référez-vous à la documentation (dans le menu "Aide/À propos de ce monde") pour la liste complète des méthodes comprises par les buggles.

note: type: Content of: <p>
en: The buggle world can sometimes contain some <i>baggles</i>, which are little biscuits that buggles can carry from one point to another. For that, they have to use specific methods such as <code>isOverBaggle(), isCarryingBaggle(), pickupBaggle()</code> or <code>dropBaggle()</code>. Check their documentation in "Help/About this world" for more details.
fr: Le monde des buggles contient parfois des petits biscuits ronds que les buggles peuvent déplacer d'un endroit à un autre. Pour cela, elles peuvent utiliser des fonctions spécifiques : <code>estSurBiscuit(), porteBiscuit(), prendBiscuit()</code> et <code>poseBiscuit()</code>. Tous les détails se trouvent dans la documentation accessible depuis «Aide/À propos de ce monde».

note: type: Content of: <p>
en: Let each buggle find its baggle by adapting the code you wrote in previous exercise (copy/paste what you've done before if you want).
fr: Faites en sorte que chaque buggle trouve son baggle en adaptant le code que vous aviez écrit pour l'exercice précédent (vous êtes libre de faire un copie/colle de ce que vous aviez fait si vous le souhaitez).

note: type: Content of: <p>
en: The programs we wrote so far are missing a fundamental point in computing.  Actually, it is all about processing <b>data</b> through specific <b>instructions</b>. In the buggle world, the main data are a bit hidden behind the graphical representation, but that's no reason to never manipulate some data explicitly.
fr: Les programmes que nous avons écrit jusque là passent à coté d'un point fondamental en informatique. En effet, la science informatique est celle de traiter des <b>données</b> grâce à des <b>instructions</b>. Dans le monde des buggles, les principales données sont cachées derrière la représentation graphique, mais ce n'est pas une raison pour ne jamais manipuler explicitement des données.

note: type: Content of: <h3>
en: Data in [!thelang]
fr: Les données en [!thelang]

note: type: Content of: <p>
en: In a program, you can use several <i>types</i> of data, such as integers or strings of chars. If you want to use a data several times, you need to store it within a <i>variable</i>, which is a memory cell containing a value: you put your data (say the value '5') in the variable (say 'length'), and you can retrieve it later when you need it. That's very similar to a box of label 'gift' in which you would put some stuff, like a bottle of perfume "Channel N°5".
fr: Dans un programme, on peut utiliser différents <i>types</i> de données, tels que les entiers, les nombres à virgules ou les chaînes de caractères. Si on veut utiliser une donnée plusieurs fois, il faut la stocker dans une <i>variable</i>, qui est une sorte de case contenant une valeur: vous rangez votre donnée (disons '5') dans la variable (disons «longueur»), et vous pouvez la retrouver plus tard quand vous en avez besoin. C'est exactement comme prendre une boîte avec une étiquette (disons «cadeau») et d'y ranger quelque chose dedans (disons, un flacon de Channel Numéro 5).

note: type: Content of: <h3>
en: Variable declarations
fr: Déclaration de Variables

note: type: Content of: <p>
en: <b>Declaring</b> (ie, creating) a variable in [!thelang], is very simple. You just need to write [!java]its type, a space, and the variable name.[/!] [!scala]the <code>var</code> keyword, the variable name, a column (:) and the variable type an equal sign (=) and an initial value.[/!] [!python]the variable name, an equal sign (=) and an initial value.[/!] The variable name is the label to retrieve it afterward[!python].[/!] [!java|scala] while the type is the kind of data that this variable accepts to store.[/!] It is forbidden to use spaces in variable names. You can name a variable <code>stepAmount</code> if you want, but <code>step amount</code> is not a valid name.
fr: Il est très simple de <b>déclarer</b> (c'est-à-dire, créer) une variable en [!thelang]. Il suffit d'écrire
    [!java]son type, une espace et le nom de la variable.[/!] 
    [!scala]le mot-clé <code>var</code>, le nom de la variable, deux points (:), le type de la variable, un signe égal (=) et une valeur initiale.[/!] 
    [!python]le nom de la variable, un signe égal (=) et sa valeur initiale.[/!] 
    Le nom de la variable est un label pour la retrouver plus tard[!python].[/!] 
    [!java|scala] tandis que son type est le genre de données qu'on va pouvoir stocker dans cette variable.[/!] 
    Il est interdit de mettre des espaces dans les noms de variable. 
    On peut nommer une variable <code>dejaFait</code>, mais <code>deja fait</code> n'est pas un identificateur de variable valide.

note: type: Content of: <p>
en: So, to create a variable named <b>x</b> intended to contain integers, one should write:
fr: Ainsi, pour créer une variable nommée <b>x</b> contenant des entiers, on écrira :

note: type: Content of: <p>
en: If you want, you can specify the initial value of the variable by adding an equal sign (=) followed by the value after the declaration.
fr: Si vous le souhaitez, vous pouvez donner une valeur initiale à votre variable en ajoutant le symbole égal (=) suivi d'une valeur après la déclaration.

note: type: Content of: <p>
en: So, if you want that the variable contains 5 as initial value, you should type:
fr: Ainsi, pour une variable ayant la valeur initiale 5, il faut écrire :

note: type: Content of: <p>
en: So, to create a variable named <b>x</b> intended to contain integers with 42 as initial value, one should write:
fr: Ainsi, pour créer une variable nommée <b>x</b> contenant des entiers avec 42 en valeur initiale, on écrira :

note: type: Content of: <p>
en: In most cases, the compiler is able to guess the type of the variable from the initialization value, and you can omit it:
fr: Dans la plupart des cas, le compilateur est capable de deviner le type de la variable d'après la valeur initiale. On peut alors omettre le type de la variable:

note: type: Content of: <p>
en: You still have to specify if you use some generic values as an initialization, such as the very particular value <code>null</code>, which type happens to be ambiguous. Even when the type is clear, you can still specify it if you prefer.  So you want that the variable contains 5 as initial value, you should type:
fr: Il est nécessaire de spécifier le type de la variable lorsque l'on initialise ses variables avec des valeurs génériques, telles que la valeur très particulière <code>null</code>, dont le type se trouve être ambigu. Même quand le type est clair, vous pouvez le spécifier si vous le souhaitez. Ainsi, pour une variable contenant 5 en valeur initiale, on peut écrire:

note: type: Content of: <pre>
en: var x: Int =  5 <span class="comment">// I can define the type if I want to</span>
    var y =  10      <span class="comment">// or I can omit the type if I prefer</span>
fr: var x: Int =  5 <span class="comment">// je peux quand même donner le type si je veux</span>
    var y = 10       <span class="comment">// ou bien je peux l'omettre</span>

note: type: Content of: <p>
en: As you can see, the variables are <b>typed</b> in [!thelang], which means that they are somehow specialized: A given variable can only store data of a given type; Don't even think of storing numbers in a variable that is tailored for letters! The [!thelang] language is said to be <b>statically typed</b>.
fr: Comme vous pouvez le voir, les variables sont <b>typées</b> en [!thelang]. Cela veut dire qu'elles sont en quelque sorte spécialisées: une variable donnée ne peut stocker qu'un type de données spécifique. N'essayez même pas de ranger des nombres dans une variable faite pour recevoir des lettres ! On dit que [!thelang] est un langage <b>typé statiquement</b>.

note: type: Content of: <p>
en: Other languages (such as Python) are less picky and allow you to store any kind of data in any variable, without restriction (those languages are said to be <b>dynamically typed</b>).  This seems easier at the first glance, but this kind of restriction allows the compiler to catch more logic errors for you, which is also good. In some sense, Python is easier to write but errors can sneak in more easily than in [!thelang].
fr: D'autres langages (comme le python) sont moins regardants, et on peut ranger n'importe quel type de données dans n'importe quelle variable sans restriction. À première vue, cela semble plus simple, mais ce genre de restriction permet au compilateur de détecter plus d'erreurs de logiques pour vous, ce qui n'est pas dommage. En quelque sorte, il est plus facile d'écrire du python, mais le typage empêche certaines erreurs de se glisser dans vos programmes.

note: type: Content of: <p>
en: Here are some existing types in [!thelang]:
fr: Voici quelque uns des types de données existants en [!thelang] :

note: type: Content of: <ul><li>
en: <b>[!java|c]int[/!][!scala]Int[/!]</b>, for integers;
fr: <b>[!java|c]int[/!][!scala]Int[/!]</b>, pour les entiers;

note: type: Content of: <ul><li>
en: <b>[!java|c]double[/!][!scala]Double[/!]</b>, for dot numbers;
fr: <b>[!java|c]double[/!][!scala]Double[/!]</b>, pour les nombres à virgule;

note: type: Content of: <ul><li>
en: <b>[!c]int[/!][!java]boolean[/!][!scala]Boolean[/!]</b>, for booleans that are values being either [!c]1[/!][!java|scala]true[/!] or [!c]0[/!][!java|scala]false[/!];
fr: <b>[!c]int[/!][!java]boolean[/!][!scala]Boolean[/!]</b>, pour les booléens, c'est-à-dire les variables dont la valeur est soit "[!c]1[/!][!java|scala]vrai[/!]" soit "[!c]0[/!][!java|scala]faux[/!]";

note: type: Content of: <ul><li>
en: <b>[!c]char*[/!][!java|scala]String[/!]</b>, for char strings.
fr: <b>[!c]char*[/!][!java|scala]String[/!]</b>, pour les chaînes de caractères.

note: type: Content of: <p>
en: As you can see, the variables are not <b>typed</b> in Python, which means that they are not specialized in any type of data.  A given variable store any type of data of a given type: you can store a number in a variable and later on store a number in the same variable.  The values themselves are still typed, but not the variable. Python is said to be <b>dynamically typed</b>.
fr: Comme vous pouvez le voir, les variables ne sont pas <b>typées</b> en Python, ce qui veut dire qu'elles ne sont pas spécialisées sur un type de données particulier. Il est tout à fait envisageable de stocker des nombres dans une variable, puis d'y mettre des lettres un peu plus tard. Les valeurs elles-mêmes ont bien entendu un type, mais pas les variables. On dit alors que python est un langage <b>dynamiquement typé</b>.

note: type: Content of: <p>
en: Other languages (such as Java, Scala or C) are much more picky and prevent you to mix data types in a given variable (they are said to be <b>statically typed</b>).  This seems annoying at the first glance, but this kind of restriction allows the compiler to catch more logic errors for you, which is also good. In some sense, Python is easier to write but errors can sneak in more easily.
fr: D'autres langages (comme le Java, le Scala ou le C) sont plus restrictifs et imposent de spécialiser chaque variable pour un type donné (on dit que ce sont des langages <b>statiquement typés</b>). Cela semble bien plus contraignant à première vue, mais ce genre de restriction permet au compilateur de détecter plus d'erreurs de logique pour vous. D'une certaine manière, il est plus facile d'écrire du Python, mais le typage de ces langages empêche certaines erreurs de se glisser dans les programmes.

note: type: Content of: <p>
en: If you know that the value of your "variable" will never change (eg because it contains the screen size or some other constant value), then you should make it a <b>value</b> instead of a variable. Simply change the <code>var</code> keyword with the <code>val</code> one. The compiler can then check your actions and catch your error when you inadvertently modify the value. More interestingly, the compiler can produce faster code in some cases.
fr: Si vous savez que votre «variable» ne va jamais changer de valeur (par exemple parce qu'il s'agit de la taille de l'écran ou une autre constante du genre), alors vous devriez en faire une <b>valeur</b> plutôt qu'une variable.
    Utilisez simplement le mot-clé <code>val</code> au lieu de <code>var</code>. 
    Le compilateur pourra alors faire plus de vérifications pour aider les étourdis cherchant à modifier les constantes. Plus intéressant, le compilateur parvient également à produire du code plus rapide dans certains cas.

note: type: Content of: <p>
en: Variables work very similarly for strings, floating point numbers and boolean values.
fr: C'est la même histoire pour les chaînes, nombres à virgule flottante et les booléens.

note: type: Content of: <pre>
en: char* name = "Martin Quinson";
    double height=1.77; <span class="comment">// in meters</span>
    int married=1;<span class="comment">// 1 means "true"; "false" would be written 0</span>
fr: char* nom = "Martin Quinson";
    double taille=1.77; <span class="comment">// en mètres</span>
    boolean marie=1; <span class="comment">// Signifie vrai; le contraire (faux) s'écrirait 0</span>

note: type: Content of: <pre>
en: String name = "Martin Quinson";
    double height=1.77; <span class="comment">// in meters</span>
    boolean married=true;<span class="comment">// the contrary would be written "false"</span>
fr: String nom = "Martin Quinson";
    double taille=1.77; <span class="comment">// en mètres</span>
    boolean marie=true; <span class="comment">// Signifie vrai; le contraire (faux) s'écrirait "false"</span>

note: type: Content of: <pre>
en: val name:String = "Martin Quinson"; <span class="comment">// this cannot be modified (it's a value)</span>
    var height: Double = 1.77; <span class="comment">// in meters</span>
    var married = true; <span class="comment">// the contrary would be written "false"</span>
    <span class="comment">// Scala knows that 'true' is a Boolean value, no need to repeat it here</span>
fr: val nom:String = "Martin Quinson"; <span class="comment">// impossible de le modifier (c'est une valeur)</span>
    var taille: Double = 1.77; <span class="comment">// en metre</span>
    var marie = true; <span class="comment">// Signifie vrai; le contraire (faux) s'écrirait "false"</span>
    <span class="comment">// Scala sait que 'true' est une valeur de type Boolean, pas besoin de le répéter</span>

note: type: Content of: <pre>
en: firstName = "Martin"
    lastName = 'Quinson' <span class="comment"># both single and double quote work here</span>
    motto = "I never finish anyth' (but I keep trying)" <span class="comment"># having single quote within double quote is fine</span> 
    height=1.77 <span class="comment"># in meters</span>
    married=True <span class="comment"># the contrary would be written "False"</span>
fr: prenom = "Martin"
    nom = 'Quinson' <span class="comment"># les simples et les doubles quotes fonctionnent ici</span>
    devise = "Je ne finis jam' (mais je continue d'essayer)" <span class="comment"># avoir des quotes simples dans des doubles quotes fonctionne</span> 
    taille=1.77 <span class="comment"># en mètre</span>
    marie=True <span class="comment"># Signifie 'vrai'; le contraire (faux) serait marqué 'False'</span>

note: type: Content of: <p>
en: Once your variable is declared, you can <b>affect</b> a new value to it later in the program. That's really easy:
fr: Une fois que votre variable est déclarée, vous pouvez y <i>affecter</i> une nouvelle valeur plus tard dans votre programme. C'est vraiment très simple :

note: type: Content of: <p>
en: To the right of the equal symbol, you can put an arithmetic expression containing constants, variables and operations.
fr: À droite du signe égal, on peut mettre une expression quelconque, qui peut contenir des constantes, des variables et des opérations :

note: type: Content of: <pre>
en: x = 3 + 2[!java|c];[/!]
    x = 3 * x[!java|c];[/!]
    [!java|scala|python]greeting = "Hello "+name[!java];[/!] <span class="comment">[!python]#[/!][!scala|java]//[/!] + is (also) the operation to concatenate (ie, to join) strings[/!]</span>
fr: x = 3 + 2[!java|c];[/!]
    x = 3 * x[!java|c];[/!]
    [!java|scala|python]greeting = "Hello "+name[!java];[/!] <span class="comment">[!python]#[/!][!scala|java]//[/!] + est (également) l'opérateur pour concaténer les chaînes (càd pour les fusionner)[/!]</span>

note: type: Content of: outside any tag (error?)
en: It is now time to do more challenging exercises, don't you think? The objective is now to move forward until you find a baggle, pick it up, and then move back to your initial location before dropping the baggle.
fr: Il est temps de faire un exercice un peu plus dur, n'est ce pas ? L'objectif cette fois est d'avancer jusqu'au biscuit qui se trouve devant la buggle, le ramasser, revenir à la position initiale, puis de poser le biscuit.

note: type: Content of: <h3>
en: How to do this?
fr: Comment faire ?

note: type: Content of: <p>
en: To solve this problem, you have to decompose it in easier sub-parts. For example, you may want to do the following steps:
fr: Pour résoudre ce problème, il faut le décomposer en parties que vous savez résoudre. Par exemple, on peut vouloir faire les étapes suivantes :

note: type: Content of: <p><ol><li>
en: Move forward until located over a baggle
fr: Avancer jusqu'à se trouver sur un biscuit

note: type: Content of: <p><ol><li>
en: Pickup the baggle
fr: Ramasser le biscuit au sol

note: type: Content of: <p><ol><li>
en: Move backward of the same amount of steps than done in first step
fr: Reculer du même nombre de cases que ce qu'on a avancé

note: type: Content of: <p><ol><li>
en: Drop back the baggle
fr: Reposer le biscuit au sol

note: type: Content of: <p>
en: Naturally, it is impossible to do the right amount of steps backward at step 3 if you didn't count the amount of steps done in the first phase. You can use a variable for that, which can be named <code>stepAmount</code>.
fr: Bien entendu, il est impossible de reculer du bon nombre de case à l'étape 3 si l'on a pas compté le nombre de pas faits à la première étape. On va pour cela utiliser une variable, que l'on peut nommer <code>nbPas</code>.

note: type: Content of: <p>
en: Create an integer variable before phase 1, initialize it to 0, and each time you move one step forward, increment its value by one (<code>stepAmount = stepAmount + 1;</code>[!java|c] or <code>stepAmount++;</code>, both syntaxes being equivalent[/!]).  Such variable which takes every values of a given range is often called a <b>stepper</b>.
fr: On crée cette variable (de type <code>int</code>) avant l'étape 1, on l'initialise à 0, et chaque fois qu'on avance d'un pas, on l'incrémente de 1 (<code>nbPas = nbPas + 1;</code>[!java|c] ou <code>nbPas++;</code>, les deux écritures sont équivalentes[/!]).

note: type: Content of: <p>
en: If you know Java or other languages, you will probably try to use the <code>++</code> operator to increment the variable, but it's not allowed in [!thelang].  This is because it would be difficult to define this operator for every data types.  For example, what should ++ do when applied to a Complex value or to a String? The problem does not occur in Java as <code>int</code> is not an object but a primitive type.  (if you don't know the <code>++</code>, just ignore this paragraph: it does not exist in [!thelang])
fr: Si vous connaissez le Java ou d'autres langages du genre, vous serez probablement tenté d'utiliser l'opérateur <code>++</code> pour incrémenter la variable. Malheureusement, cet opérateur n'existe pas en [!thelang]. C'est parce qu'il serait difficile de savoir quoi faire quand on l'applique à un nombre complexe ou à une chaîne de caractères. Le problème ne se pose pas en Java, où ++ est défini pour le type <code>int</code> qui n'est pas un type d'objet mais un type primitif (si vous ne connaissez pas l'opérateur ++, ignorez simplement ce paragraphe : cela n'existe pas en [!thelang]).

note: type: Content of: <p>
en: Then, phase 3 consists in simply creating a new integer variable <code>doneSteps</code> initialized to 0, and do one step backward as long as <code>doneSteps</code> is not equal to <code>stepAmount</code>, incrementing <code>doneSteps</code> each time. The <code>!=</code> operator should be used to test the inequality (whether some values are NOT equal).
fr: Ensuite, l'étape 3 consiste simplement à créer une nouvelle variable entière <code>dejaFait</code> initialisée à zéro, et reculer d'un pas tant que <code>dejaFait</code> n'est pas égal à <code>nbPas</code>, en incrémentant <code>dejaFait</code> à chaque fois. Il faut utiliser l'opérateur <code>!=</code> pour tester l'inégalité entre deux valeurs.

note: type: Content of: <p>
en: It's your turn now!
fr: À vous de jouer !

note: type: Content of: <h2>
en: Run Four bases
fr: La course des quatre bases

note: type: Content of: <p>
en: Today is a great day for the buggles: the Big Buggles' Race begun. It's a traditional competition in which young buggles prove their value to the tribe. Both force and intelligence is exercised: you have to rush forward, but stop as soon as you reach your fourth baggle.  Please help the buggles to move forward while counting the baggles and to determine when to stop.
fr: Aujourd'hui est un grand jour : la Grande Course des Buggles a commencé. C'est une compétition traditionnelle par laquelle les jeunes buggles prouvent leur valeur à la tribu. C'est à la fois une épreuve de force et d'intelligence puisqu'il faut courir le plus vite possible, mais s'arrêter dès que vous avez rejoint votre quatrième biscuit. Il faut que vous aidiez les buggles à avancer tout en comptant les biscuits pour déterminer quand s'arrêter.

note: type: Content of: <h2>
en: The Four Halves run
fr: La course des quatre moitiés

note: type: Content of: <p>
en: Here is the second day of the Big Buggles' Race.  As previously, you have to run forward until you reach the right cell to stop on.  But this time, you have to reach the cell where the amount of baggles you saw is the double of the orange cells plus 1.  In other words, the following condition must become true: <code>2 * baggles = orangeCells + 1</code>.
fr: C'est le second jour de la Grande Course des Buggles. Comme d'habitude, il faut courir jusqu'à trouver la case où vous devez vous arrêter. Mais cette fois, vous devez vous arrêter quand vous aurez compté deux fois moins de biscuits que de cases oranges plus une. En d'autres termes, la condition d'arrêt est la suivante : <code>2 * biscuits = caseOrange + 1</code>.

note: type: Content of: <p>
en: You can determine whether you are over a orange cell with the <code>isOverOrange()</code> method.
fr: Vous pouvez déterminer si vous vous trouvez sur une case orange avec la méthode <code>estSurOrange()</code>.

note: type: Content of: <p>
en: While loops are well adapted to situations where you want to achieve an action while a condition stays true, but it is less adapted to achieve a given action a predetermined amount of time. For example, when we wanted to move <code>stepAmount</code> steps backward in a previous exercise, we had to create a new variable, initialize it, and move backward while incrementing this variable until it became equal to <code>stepAmount</code>.
fr: Les boucles <tt>while</tt> sont bien adaptées aux situations où l'on veut réaliser une action tant qu'une condition est réalisée, mais elles sont moins pratiques pour réaliser une action un nombre prédéterminé de fois. Par exemple, lorsque nous voulions reculer de <code>nbPas</code> dans l'exercice précédent, il fallait créer une nouvelle variable, l'initialiser, et demander à reculer tant que la nouvelle variable n'était pas égale à <code>nbPas</code>, en incrémentant cette variable à la main à la fin du corps de la boucle.

note: type: Content of: <p>
en: In such situations, <code>for</code> loops become handy. Their syntax is the following:
fr: Dans ce genre de cas, les boucles de type <code>for</code> sont plus pratique. Leur syntaxe est la suivante :

note: type: Content of: <pre>
en: [!java|c]for (<b>initializing</b>; <b>condition</b>; <b>incrementing</b>) {
        <b>action</b>();
    }[/!][!python]for <b>variable</b> in <b>sequence of values</b>:
        <b>action</b>()[/!][!scala] for (<b>variable</b> &lt;- <b>firstValue</b> to <b>lastValue</b>) { 
        <b>action</b>();
    }[/!]
fr: [!java|c]for (<b>initialisation</b>; <b>condition</b>; <b>increment</b>) {
        <b>action</b>();
    }[/!][!python]for <b>variable</b> in <b>sequence de valeurs</b>:
        <b>action</b>()[/!][!scala] for (<b>variable</b> &lt;- <b>premiereValeur</b> to <b>derniereValeur</b>) { 
        <b>action</b>();
    }[/!]

note: type: Content of: <p>
en: For example to repeat the loop body <code>n</code> times, [!python] it is handy to use the instruction <code>range(n)</code> to generate the sequence n integer value from 0 to n-1.[/!] [!java|scala|c] one should write:[/!]
fr: Par exemple, pour répéter le corps de boucle <code>n</code> fois, 
    [!python]il est pratique d'utiliser l'instruction <code>range(n)</code>
      pour générer la séquence de n entiers allant de 0 à n-1.[/!]
    [!java|scala|c]il faut écrire:[/!]

note: type: Content of: <pre>
en: [!java]for (int stepper=0; stepper&lt;n; stepper++) {
        <b>action</b>();
    }[/!][!c]int stepper;
    for (stepper=0; stepper&lt;n; stepper++) {
        <b>action</b>();
    }[/!][!python]for <b>stepper</b> in <b>range(n)</b>:
        <b>action</b>()[/!][!scala] for (<b>stepper</b> &lt;- <b>1</b> to <b>n</b>) { 
        <b>action</b>();
    }[/!]
fr: [!java]for (int compteur=0; compteur&lt;n; compteur++) {
        <b>action</b>();
    }[/!][!c]int compteur;
    for (compteur=0; compteur&lt;n; compteur++) {
        <b>action</b>();
    }[/!][!python]for <b>compteur</b> in <b>range(n)</b>:
        <b>action</b>()[/!][!scala] for (<b>compteur</b> &lt;- <b>1</b> to <b>10</b>) { 
        <b>action</b>();
    }[/!]

note: type: Content of: <p>
en: This code is then equivalent to the following one from the computer point of view. From the programmer point of view, one form or the other can make the source code easier to read, depending on the situation. You should chose wisely in each situation whether you want to use a for loop or a while loop. Your uttermost goal should remain to keep your code simple and easy to read, to ensure that your day remain pleasant and productive.
fr: Ce code est équivalent du point de vue de l'ordinateur, mais du point de vue du programmeur, ce n'est pas forcément la même chose. L'une ou l'autre forme peut rendre le code plus facile à lire, en fonction de la situation. C'est donc à vous, le programmeur, de choisir la forme de boucle est la plus adaptée à chaque cas. L'objectif absolu doit être de garder votre code aussi simple que possible en toute situation. De la sorte, vos journées resteront plaisantes et productives.

note: type: Content of: <pre>
en: [!java|c]int stepper = 0;
    while (stepper &lt; n) {
    &nbsp;&nbsp;&nbsp;&nbsp;<b>action</b>();
    &nbsp;&nbsp;&nbsp;&nbsp;<b>stepper++</b>;
    }[/!][!python]stepper=0
    while stepper &lt; n: 
        action()
        stepper = stepper + 1[/!][!scala]
    var stepper = 1
    while (stepper &lt;= n) {
        <b>action</b>()
        stepper = stepper + 1
    }[/!]
fr: [!java|c]int compteur = 0;
    while (compteur &lt; n) {
        <b>action</b>();
        <b>compteur++</b>;
    }[/!][!python]compteur=0
    while compteur &lt; n: 
        action()
        compteur = compteur + 1[/!][!scala]
    var compteur = 0
    while (compteur &lt; n) {
        <b>action</b>()
        compteur = compteur + 1
    }[/!]

note: type: Content of: <p>
en: In that case, the <code>for</code> loop is easier to read, don't you think?
fr: Dans ce cas, le code avec une boucle <code>for</code> est plus simple à lire, non?

note: type: Content of: <p>
en: It is possible to build more advanced <tt>for</tt> loops since any valid instruction can be used as initialization, condition and incrementing instruction. The following example is a bit extreme as there is no need for a loop body to move the buggle forward until it reaches the wall, but it works well: all the work is done in the condition and incrementing instruction.
fr: On peut imaginer des utilisations bien plus avancées des boucles <tt>for</tt> car toute instruction valide peut être utilisée comme initialisation, condition et incrémentation. L'exemple suivant est un peu extrême, puisqu'il n'y a même pas de corps de boucle. La buggle est avancée jusqu'à se retrouver face au mur dans la condition et l'incrémentation.

note: type: Content of: <pre>
en: for (; !isFacingWall() ; forward()) { 
       <span class="comment">/* nothing in the loop body */</span>
    }
    <span class="comment">/* the buggle now faces a wall */</span>
fr: for (; !estFaceMur() ; avance()) { 
       <span class="comment">/* rien dans le corps de boucle */</span>
    }
    <span class="comment">/* la buggle est maintenant face à un mur */</span>

note: type: Content of: <p>
en: If you want to nest several loops, you can do it on one line in Scala. This means that the two following chunks are equivalent:
fr: Si vous avez l'intention d'imbriquer plusieurs boucles, il est possible de l'écrire en une seule ligne en Scala. Les deux morceaux de code sont équivalents:

note: type: Content of: <pre>
en: for (stepper1 &lt;- 1 to n) {
        for (stepper2 &lt;- 1 to m) {
           actions()
        }
    }
fr: for (compteur1 &lt;- 1 to n) {
        for (compteur2 &lt;- 1 to m) {
           actions()
        }
    }

note: type: Content of: <pre>
en: for (stepper1 &lt;- 1 to n; stepper2 &lt;- 1 to m) { <span class="comment">// Simply separate both loop conditions with a semi-column</span>
        actions()
    }
fr: for (compteur1 &lt;- 1 to n; compteur2 &lt;- 1 to m) { <span class="comment">// Séparez simplement les deux conditions de boucle par un point-virgule (;)</span>
        actions()
    }

note: type: Content of: <p>
en: You now have to redo the same exercise than previously (move forward until being over a baggle, pick it up, move back to your original location, drop the baggle), but using a <code>for</code> loop instead of a <code>while</code> loop to move back to the initial location.
fr: Il s'agit maintenant de refaire le même exercice que précédemment (avancer jusqu'à trouver un baggle, le ramasser, revenir là où on était au début puis reposer le baggle), mais en utilisant une boucle <tt>for</tt> pour revenir au point de départ à la place d'une boucle <code>while</code>.

note: type: Content of: <p>
en: Once done, you can proceed to next exercise.
fr: Une fois ceci fait, vous pouvez passez à l'exercice suivant.

note: type: Content of: <h2>
en: Stairway to Heaven
fr: la voie du paradis

note: type: Content of: <p>
en: Your buggle feels a bit depressed today, but it's currently facing a magic stair: It leads directly to heaven, and each time you walk on it, joyful colors spur all around.
fr: Votre buggle est un peu déprimée aujourd'hui, mais elle est face à un escalier magique&nbsp;: il mène directement au paradis, et des couleurs joyeuses jaillissent de partout quand on l'emprunte.

note: type: Content of: <p>
en: Your goal is to take this stair, one step after the other.  First devise the four instructions you have to give you buggle to take one stair step, and then put them in a loop to take the whole stair.
fr: Votre objectif est de prendre cet escalier, une marche après l'autre. Commencez par trouver les quatre instructions à réaliser pour gravir une marche, puis placez-les dans une boucle pour gravir toutes les marches.

note: type: Content of: <p>
en: Before that, walk a bit forward to reach that stair, and ensure that you are in the right situation for your loop content to run properly. And once you reach the heaven, take some steps in your new home.  Meanwhile, you just have to walk your way, the colors appear automagically.
fr: Avant cela, vous devez marcher un peu pour atteindre l'escalier et vous assurer que vous êtes dans la bonne position pour que le contenu de votre boucle s'exécute correctement. 
    Une fois que vous avez atteint le paradis, faites quelques pas dans votre nouvelle demeure.
    Chemin faisant, les couleurs apparaissent d'elles-mêmes sans que vous n'ayez rien à faire.

note: type: Content of: <h2>
en: Training Buggle
fr: Entraînement de buggle

note: type: Content of: <p>
en: Today, your buggle wants to get some serious exercise: It wants to run 'till the track burns! Its super-shoes are just perfect to run like hell, but unfortunately, they can actually damage the track on the long run...
fr: Aujourd'hui, votre buggle veut s'entraîner sérieusement. Elle veut courir jusqu'à brûler la piste! Ses super-chaussures, sont parfaites pour courir comme une dingue, mais malheureusement, elles abîment un peu la piste à la longue...

note: type: Content of: <p>
en: Your goal is to run the track 10 times, no matter what happens.  Even if the track suffers, you <b>really HAVE</b> to take that run.  Remember, the track has four sides, that take eight steps each to run along.  Now go, and show them what these super shoes can do.
fr: Votre objectif est de faire 10 tours de piste, quel que soit le résultat. Même si la piste souffre un peu, vous <b>DEVEZ</b> le faire. Souvenez vous, la piste a 4 cotés, qui prennent chacun 8 pas à parcourir. Maintenant allez-y et montrez-leur ce dont ces super-chaussures sont capables.

note: type: Content of: <p>
en: You don't have to do anything particular with regard of the colors: your shoes will do it for you. Just take that run!
fr: Vous n'avez rien à faire de particulier à propos de la couleur de la piste : vos chaussures la changeront pour vous. Contentez vous de courir.

note: type: Content of: <h2>
en: Outdoor Training Buggle
fr: Course en forêt

note: type: Content of: <p>
en: Well, our last training didn't went that well. The track actually burned, and we are now banned from there.  This time, our buggle decided to practice outdoor, in the middle of the forest, with its good old shoes instead.  The problem is that you have to be careful to not fall into water. The track on which you can run is rather narrow: One side is now 4 steps forward, 2 steps to the left, 4 steps to the right, 2 steps to the right, 4 steps to the left, and you want to run 7 around.
fr: Bon, notre dernier entraînement ne s'est pas très bien passé. La piste a effectivement brûlé, et vous voilà banni des pistes d'athlétisme de la région. Cette fois, notre buggle a décidé de s'entraîner en forêt, et avec des chaussures normales pour être plus sûr. Le problème est qu'il faut faire attention à ne pas tomber dans l'eau. La piste sur laquelle on peut courir est plutôt étroite&nbsp;: pour un coté, il faut faire quatre pas en avant, deux pas à gauche, quatre pas à droite, deux pas à droite, et quatre pas à gauche. Il faut faire 7 tours de circuit.

note: type: Content of: <p>
en: Oh crap, running on the grass seems to destroy it too! So just take your 7 loops around the garden, and move along to the next exercise before anyone notices the damage you made...
fr: Raaah, mince. Courir sur l'herbe semble l'endommager également ! Bon, tant pis. Faites vos 7 tours, et passez vite à l'exercice suivant avant que quelqu'un ne constate les dégâts que vous avez fait...

note: type: Content of: <p>
en: Some cells of the world are yellow, but your buggle cannot stand being in such cells. Write the necessary code to move forward until the ground gets white. For that, use the provided method <code>isGroundWhite()</code>.
fr: Certaines cases du monde sont jaunes, mais les buggles ne supportent pas de s'y trouver. Écrivez le code nécessaire pour avancer jusqu'à ce que le sol devienne blanc. Vous pourrez utiliser la méthode <code>estSurBlanc()</code> qui retourne vrai si le sol est blanc..

note: type: Content of: <p>
en: The trick is that most buggles of this world are currently on this yellow ground that they dislike so much. That is why they are in panic, and every buggle rushes one cell forward, even the buggle that was not on a yellow cell at first. In other worlds, even if the ground is white on the first cell, you still want to move forward to the next cell.
fr: Le truc est que la plupart des buggles de ce monde se trouvent actuellement sur ce sol jaune qui les énerve tant. Cela explique sans doute leur état de panique, et le fait que toutes les buggles se ruent vers l'avant au début, même la buggle qui ne se trouve pas sur du jaune. En d'autres mots, même si le sol est blanc le premier coup, il faut quand même avancer d'un pas.

note: type: Content of: <p>
en: The general idea is to do something like:
fr: L'idée générale est donc de faire:

note: type: Content of: <pre>
en: move forward until located in a white cell
fr: avancer jusqu'à se trouver sur une case blanche

note: type: Content of: <p>
en: The main difficulty is that we want this loop body to be executed once, even we are already on a white cell.  It would be easy to do so by duplicating the loop content before the actual loop, but this would be a bad idea: code duplication is a <b>very</b> bad habit, and you should <b>always</b> avoid it.
fr: La principale difficulté est que nous voulons exécuter le corps de boucle au moins une fois, même si la buggle se trouve déjà sur une case blanche. Il serait facile de dupliquer le corps de la boucle avant la boucle pour cela, mais  ça serait une <b>très mauvaise idée</b>. Dupliquer du code est une <b>très mauvaise habitude</b> et il faut toujours éviter de le faire.

note: type: Content of: <p>
en: Code duplication easily turns code maintenance into a nightmare: reading the code becomes difficult as the reader must ensure that no slight difference exist between the versions. Debugging the code becomes difficult, as bugs have to be fixed in all versions. Actually, every modification of the code becomes difficult. So, really, you should <b>always</b> strive to not duplicate your code if you can avoid. And the good news is that you always can...
fr: Quand on duplique le code, sa maintenance tourne facilement au cauchemar : la lecture du code est très pénible puisque le lecteur doit s'assurer qu'il n'y a effectivement aucune différence, même minime, entre les versions du même code. Debugger le code devient plus long, puisqu'il faut corriger toutes les versions. En fait, toutes les modifications deviennent pénibles. Alors, vraiment, vous devrez <b>toujours</b> vous efforcer d'éviter la duplication du code quand c'est possible. Et la bonne nouvelle est que c'est toujours possible...

note: type: Content of: <h3>
en: Executing the loop body at least once
fr: Exécuter le corps de boucle au moins une fois

note: type: Content of: <p>
en: Some languages have specific constructs for that, but not the Python language. No problem, we can do it on our own! A good way is to have a dedicated variable indicating whether we are taking the loop for the first time or not, as follows.
fr: Certain langage ont une construction spécifique pour cela, mais pas Python. Qu'à cela ne tienne, on s'en sort très bien sans. Une bonne manière est d'avoir une variable dédiée indiquant si c'est la première fois que l'on rentre dans la boucle :

note: type: Content of: <pre>
en: firstTime = True
    while firstTime or (other conditions):
      firstTime = False
      (loop body)
fr: premiereFois = True
    while premiereFois or (les autres conditions):
      premiereFois = False
      (le corps de la boucle)

note: type: Content of: <p>
en: When <code>firstTime</code> is true, the loop body is executed even if the other conditions would imply the contrary.  Once the loop body has been executed once, it is set to false and never impact again the decision to enter the body or not.
fr: Quand <code>premiereFois</code> est vraie, le corps de la boucle est exécuté même si les autres conditions impliqueraient le contraire. Une fois que le corps de boucle a été exécuté, <code>premiereFois</code> est mis à faux et n'influe plus jamais la décision d'entrer dans le corps de boucle.

note: type: Content of: <p>
en: In a <tt>while</tt> loop, the condition is evaluated before anything else, and if it's false, the loop body is never evaluated. Sometimes (although not that often), you would prefer the loop body to get evaluated at least once, even if the condition is initially false. For that, a variation of the <tt>while</tt> loop gets used, using the following syntax in [!thelang].  [!java|c]Do not forget the semi-column (;) after the condition, it is mandatory.[/!]
fr: Dans une boucle <tt>while</tt>, la condition est évaluée avant toute chose, et si elle est fausse, le corps de la boucle n'est jamais exécuté. Il arrive parfois que l'on veuille que le corps de la boucle soit évalué au moins une fois, même si la condition est initialement fausse. On utilise pour cela une variante de la boucle <tt>while</tt>, dont la syntaxe est la suivante en [!thelang].[!java|c]Ne pas oublier le point virgule (;) après la condition, c'est obligatoire.[/!]

note: type: Content of: <h2>
en: Tracks of buggles
fr: La buggle Petite Poucette

note: type: Content of: <p>
en: Your buggle got lost in a strange maze, and you must help it to find the exit that is represented in orange.  You cannot simply explain the path to the exit in something like <code>right();forward();forward();forward()</code> because you have to save two buggles at the same time, that are lost in similar but not identical worlds.  You can switch to the other world by using the combobox above the world representation (where it's written 'Deep Forest' right now), and selecting the other entry (that should read 'Deeper Forest').
fr: Votre buggle est perdue dans un étrange labyrinthe, et elle a besoin de vous pour trouver la sortie (représentée par les cases orange). Vous ne pouvez pas lui donner son chemin tout simplement avec quelque chose comme <code>droite();avance();avance();</code> parce qu'il faut secourir deux buggles à la fois, perdues dans des labyrinthes similaires mais différents. Vous pouvez passer à l'autre monde en cliquant sur le menu défilant au dessus de l'endroit où est dessiné le monde. C'est là où il est écrit "Deep Forest" pour l'instant (forêt profonde), et si vous passez à "Deeper Forest" (forêt encore plus profonde), vous verrez l'autre monde.

note: type: Content of: <p>
en: The good news is that the path to the exit is written on the ground. As you can see, the world is made of several corridors, with baggles on the ground. After each corridor, you should turn left if the corridor contains three baggels or more, and you have to turn right if there is only 2 baggles or less.
fr: La bonne nouvelle est que le chemin vers la sortie est en quelque sorte écrit au sol. Ces mondes sont composés de plusieurs corridors, avec des baggles par terre. À chaque embranchement, il faut prendre à gauche si le corridor qu'on vient de parcourir contient 3 baggles ou plus, ou à droite s'il contient 2 baggles ou moins.

note: type: Content of: <p>
en: You should count exactly 5 cells per corridor, from intersection to intersection.  Consider in your count the intersection ending the corridor but not the intersection before the corridor.
fr: Vous devez compter exactement 5 cases par couloir, d'une intersection
    à l'autre. Ne comptez pas l'intersection placée avant le couloir, mais
    comptez celle qui termine le couloir.

note: type: Content of: <p>
en: So, the general form of your code must be something like "while I did not find the exit, take the next corridor to decide whether I should turn left or right at the next intersection". You can determine whether you are on the exit cell (that is orange) with the provided <code>exitReached()</code> method.
fr: La forme générale de votre code doit donc être quelque chose comme «tant que je n'ai pas trouvé la sortie, prendre le prochain couloir pour décider s'il faut tourner à gauche ou à droite au prochain embranchement». Vous pouvez déterminer si vous avez rejoint la sortie (indiquée en orange) avec la méthode <code>sortieTrouvee()</code> fournie.

note: type: Content of: <p>
en: To take one corridor, you simply have to run from one intersection to another while counting the baggles you see on your path. That's easy: there is 5 steps in each corridors so a simple <code>for</code> loop suffices.
fr: Pour prendre un couloir, il suffit de courir d'une intersection à l'autre tout en comptant les biscuits en chemin. C'est facile : il y a 5 cases dans chaque corridor, donc une simple boucle <code>for</code> fera l'affaire.

note: type: Attribute 'alt' of: <p><div>
en: I cannot imagine how to count the baggles I see.
fr: Je n'arrive pas à imaginer comment compter les baggles que je vois

note: type: Content of: <p><div>
en: You need a variable that is initialized to 0, and incremented each time you see a baggle on the ground. A variable used this way is often called <i>counter</i>.
fr: Il vous faut une variable initialisée à zéro et incrémentée à chaque fois que vous voyez un baggle. Une variable utilisée ainsi est souvent appelée un <i>compteur</i>.

note: type: Content of: <p><div>
en: Don't forget to reset your counter to 0 at the beginning of each corridor!
fr: N'oubliez pas de remettre le compteur à 0 au début de chaque couloir!

note: type: Content of: <p>
en: Oh, and when you reach the exit, don't forget to take an extra step to actually exit the maze!
fr: Oh, et quand vous parviendrez à trouver la sortie, n'oubliez pas de faire un pas de plus pour vous échapper effectivement.

note: type: Content of: <h2>
en: More buggles tracks
fr: Nouvelles pistes

note: type: Content of: <p>
en: Hu oh! Your buggle got lost again in the same kind of maze, but this time, the corridors are not always of the same size. Since there is no way to know the length of the corridor before taking it, a <code>for</code> will not suffice anymore. Instead, you will have to change your inner loop to use a <code>while</code> loop, using the method <code>crossing()</code> that tells whether your buggle currently stands on an intersection.
fr: Et mince ! Votre buggle s'est encore perdue dans le même genre de
    labyrinthes, mais cette fois les corridors ne sont pas tous de la même
    taille. Comme il n'y a aucun moyen de connaître à l'avance la longueur
    du corridor que l'on commence à explorer, une boucle <code>for</code>
    semble mal adaptée. Au lieu de cela, vous devriez changer votre boucle
    interne en un <code>while</code>. Utilisez la méthode
    <code>crossing()</code>, qui indique si votre buggle se trouve
    actuellement à un embranchement.

note: type: Content of: <p>
en: The extra complexity is that at the beginning of a corridor, you obviously stand on an intersection, but you still want to move on.  [!java|scala|c]For that, the easiest is to use a <code>do / while</code> loop instead of a regular <code>while</code> loop to move until the next intersection.[/!] [!python]For that, use an extra variable indicating whether you already entered the corridor, as follows. This will ensure that you execute the loop body at least once (when <code>firstTime</code> is true) before we actually use the value returned by <code>crossing()</code> to determine to continue or not.[/!]
fr: Le problème, c'est que lorsque vous commencez l'exploration d'un
    corridor, vous vous trouvez à une intersection mais vous voulez
    avancer quand même. [!java|scala|c]La solution la plus simple est
    alors d'utiliser une boucle <code>do / while</code> au lieu d'un
    simple <code>while</code> pour bouger <b>jusqu'à</b> la prochaine
    intersection.[/!] [!python]Utilisez pour cela une variable
    supplémentaire indiquant si vous êtes déjà entré dans un
    corridor. Cela vous permettra d'exécuter le core de boucle au moins
    une fois (quand <code>premiereFois</code> est vraie) avant de tester
    la valeur retournée par <code>crossing()</code>.[/!]

note: type: Content of: <pre>
en: firstTime = True
    while firstTime or not crossing():
      firstTime = False
      (loop body)
fr: premiereFois = True
    while premiereFois or not crossing():
      premiereFois = False
      (le corps de la boucle)

note: type: Content of: <p>
en: With that new trick, your buggle should exit this maze quite easily.
fr: Avec ces nouvelles astuces, votre buggle devrait parvenir à s'échapper
    assez facilement.

note: type: Content of: <h1>
en: [!java|scala]Arrays[/!][!python]Lists[/!] and Knotting
fr: [!java|scala]Tableaux[/!][!python]Listes[/!] et tricot

note: type: Content of: outside any tag (error?)
en: The goal of this exercise is to reproduce the pattern of the first row in the other rows with a shift of one cell (see the Objective tab for details). The biggest difference between this exercise and the others we had on patterns is that you have to read the pattern (on first row) before reproducing it. You cannot do otherwise because the same code will be executed on three different worlds, each of them having a specific pattern.
fr: L'objectif de cet exercice est de reproduire le motif de la première colonne en le décalant d'une case (voir l'onglet «Objectif» pour plus de détails). La grande différence entre cet exercice et les précédents sur les motifs, c'est qu'il faut maintenant lire (sur la première colonne) le motif souhaité, puis le reproduire ensuite. Il est impossible de faire autrement car votre programme sera exécuté par trois buggles dans trois mondes différents, chacune ayant un motif propre à reproduire.

note: type: Content of: <p>
en: One solution is to read the next cell, and go copy it in position before coming back to read the second cell. But since it is forbidden to use the methods to teleport the buggle to a specific position (<code>setPos()</code> and similar), this approach will be a pain to implement.
fr: Une possibilité est de lire la prochaine case, puis d'aller la recopier en position, avant de revenir lire la case suivante, etc. Mais comme vous n'avez pas le droit d'utiliser les méthodes permettant de téléporter la buggle à une case particulière (<code>setPos()</code> et autres), cette façon de faire va être très pénible à mettre en place.

note: type: Content of: <p>
en: The simplest is to store the sequence of colors that constitute the whole pattern in an [!java|scala]<b>array</b>[/!][!python]<b>list</b>[/!].  But before we can do so, we should learn a bit what [!java|scala]arrays[/!][!python]lists[/!] are.
fr: Le plus simple est de stocker l’enchaînement de couleurs constituant le motif dans 
    [!java|scala]un <b>tableau</b>[/!][!python]une <b>liste</b>[/!].  
    Mais avant de pouvoir faire cela, nous devons en apprendre un peu plus sur les [!java|scala]tableau[/!][!python]listes[/!].

note: type: Content of: <h2>
en: [!java|scala]Arrays[/!][!python]List[/!]
fr: [!java|scala]Les tableaux[/!][!python]Les listes[/!]

note: type: Content of: <p>
en: [!java|scala]An array[/!][!python]A list[/!] is an ordered sequence of variables that go together.  It is somehow similar to a shelve where each level can store a separate value. Each variable of the sequence is identified by its position, and can store a specific value. [!java|scala]All cells of the array must store values of the same type because arrays are homogeneous in [!thelang]. It is possible to trick this restriction by using the datatype <code>[!java]Object[/!][!scala]Any[/!]</code> that can contain [!java]almost[/!] any other datatype. [!java]Primitive types such as the ones we saw so far (int, boolean, double, char, etc) cannot be stored in an Object variable, but their objectified counter-part (Integer, Boolean, Double, Char, Boolean, etc) can.[/!] It is however a good practice to make the type of an array as specific as possible, i.e., if you plan to store some integers in your array, make it an array of integers, not of [!java]Object[/!][!scala]Any[/!].[/!] [!python]Lists can even mix values of differing types, such as integer values in some cells and colors in other cells.[/!]
fr: [!java|scala]Un tableau[/!][!python]Une liste[/!] est une séquence ordonnée de variables qui marchent ensemble. 
    C'est un peu similaire à une commode dont les différents tiroirs peuvent stocker des valeurs différentes. 
    Chaque variable de la séquence est identifiée par sa position et peut stocker une valeur spécifique.
    [!java|scala]Toutes les cellules d'un tableau doivent stocker des valeurs du même type de données parce que les tableaux sont homogènes en [!thelang]. 
    Il est cependant possible de contourner cette restriction en utilisant le type de données <code>[!java]Object[/!][!scala]Any[/!]</code> qui peut contenir [!java]presque[/!] tous les autres type de données[!scala] («any» veut dire «n'importe» en anglais)[/!].
    [!java]Les types primitifs comme ceux que nous avons utilisé jusqu'à présent (int, boolean, double, char, etc) ne peuvent pas être stockés dans une variable Object, mais leurs variantes objectifiées (Integer, Boolean, Double, Char, Boolean, etc) peuvent l'être.[/!] 
    Il est cependant raisonnable de rendre ses tableaux aussi spécifiques que possible. Si vous avez l'intention de stocker des entiers, faites en un tableau de [!java]integer[/!][!scala]Int[/!], pas de [!java]Object[/!][!scala]Any[/!].[/!] 
    [!python]Les listes peuvent contenir des données de différents types, en mélangeant par exemple quelques valeurs entières dans certaines cellules avec des entiers dans d'autres cellules.[/!]

note: type: Content of: <p>
en: T is the [!java|scala]array[/!][!python]list[/!]'s name, [!java|python]T[0][/!][!scala]T(0)[/!] is the name of the first cell, [!java|python]T[1][/!][!scala]T(1)[/!] the name of the second cell, [!java|python]T[2][/!][!scala]T(2)[/!] the third one, etc. And yes, the first cell is numbered [!java|python]T[0][/!][!scala]T(0)[/!] while the last one of [!java|scala]an array[/!][!python]a list[/!] of size N is [!java|python]T[N-1][/!][!scala]T(N-1)[/!]. It may seem funny to count starting from 0 and not from 1 as usual, but some historical reasons make it unavoidable here.
fr: T est le nom [!python]de la liste[/!][!scala|java]du tableau[/!], 
    [!java|python]T[0][/!][!scala]T(0)[/!] est le nom de la première case, 
    [!java|python]T[1][/!][!scala]T(1)[/!] de la deuxième case, 
    [!java|python]T[2][/!][!scala]T(2)[/!] de la troisième case, etc... 
    Et oui, la première case est [!java|python]T[0][/!][!scala]T(0)[/!] et la dernière case
    [!python]d'une liste[/!][!scala|java]d'un tableau[/!] de taille N est 
    [!java|python]T[N-1][/!][!scala]T(N-1)[/!]. 
    Cela peut sembler étrange de commencer à compter à partir de 0 et non de 1, mais c'est ainsi (et cela s'explique par des raisons historiques obscures).

note: type: Content of: <h3>
en: Basic usage
fr: Usage de base

note: type: Content of: <p>
en: We can use an integer variable <i>i</i> to access with [!java|python]T[i][/!][!scala]T(i)[/!] to the cells: when the value of <i>i</i> is 0, then [!java|python]T[i][/!][!scala]T(i)[/!] accesses [!java|python]T[0][/!][!scala]T(0)[/!]; when the value of <i>i</i> is 10, then [!java|python]T[i][/!][!scala]T(i)[/!] accesses [!java|python]T[10][/!][!scala]T(10)[/!].  <i>i</i> is said to be the <b>index</b> in T.  <code>[!java|python]T[i][/!][!scala]T(i)[/!]</code> can be used just like any variable. We can set a new value:
fr: On peut utiliser une variable entière <i>i</i> pour accéder avec [!java|python]T[i][/!][!scala]T(i)[/!] aux cases.
    Quand <i>i</i> vaut 0 alors [!java|python]T[i][/!][!scala]T(i)[/!] dénote la case [!java|python]T[0][/!][!scala]T(0)[/!]; 
    lorsque <i>i</i> vaut 10,  [!java|python]T[i][/!][!scala]T(i)[/!] dénote  [!java|python]T[10][/!][!scala]T(10)[/!].
    On dit alors que <i>i</i> est un <b>indice</b> dans [!java|scala]le tableau[/!][!python]la liste[/!] T.
    <code>[!java|python]T[i][/!][!scala]T(i)[/!]</code> peut être utilisé comme n'importe quelle variable.
    On peut lui affecter une nouvelle valeur:

note: type: Content of: <p>
en: We can retrieve and use its value:
fr: On peut réutiliser et tester cette valeur :

note: type: Content of: <p>
en: We can test this value:
fr: On peut tester cette valeur :

note: type: Content of: <p>
en: It is very easy to traverse the whole [!scala|java]array[/!][!python]list[/!], for example to initialize each cells.
fr: Il est également très simple de parcourir [!java|scala]tout le tableau[/!][!python]toute la liste[/!], par exemple pour initialiser chaque cellule.

note: type: Content of: <p>
en: [!java|scala]The notation <code>T.length</code> retrieves the length of the array T,[/!] [!python]The function <code>len()</code> retrieves the length of the list T,[/!] allowing to build a classical for loop easily.  [!python]Actually, the <code>len()</code> function is much more generic and can be used to retrieve the length of many objects.  Applied to strings for example, it returns the amount of chars in this string.[/!] [!scala]Don't forget to start at <code>0</code> and stop at <code>T.length-1</code> instead of <code>1</code> to <code>T.length</code> however.[/!]
fr: [!java|scala]La notation <code>T.length</code> permet d'accéder à la taille («length» en anglais) du tableau T,[/!]
    [!python]La fonction <code>len()</code> renvoie la longueur de la liste T,[/!] 
    ce qui permet de construire facilement la boucle.
    [!python]En fait, la fonction <code>len()</code> est bien plus générique et peut être utilisée pour calculer la taille de nombreux objets. Appliquée à une chaîne de caractères par exemple, elle retourne le nombre de caractères composant cette chaîne.[/!]
    [!scala]N'oubliez pas de commencer à <code>0</code> pour terminer à <code>T.length-1</code> au lieu de <code>1</code> to <code>T.length</code>![/!]

note: type: Content of: <p>
en: If you just want to iterate over the values of T without keeping track of their index, you can simply write:
fr: Si vous souhaitez simplement parcourir les valeurs de T sans avoir besoin de l'index de chaque valeur, vous pouvez écrire simplement :

note: type: Content of: <p>
en: [!java]This construct is called an <i>extended loop</i> in Java. The variable <i>i</i> takes all values of the set located to the right of the colon (:), one after the other.[/!] [!python|scala]This is actually very similar to the previous construct.  Simply, <code>[!python]range(n)[/!][!scala]i to j[/!]</code> returns a set of integers over which the for construct iterates.  Actually, [!thelang] offers much more elegant ways to traverse [!python]lists[/!][!scala]arrays[/!] and other data collections, but this should be the topic of a specific set of exercises (that are still to be written in PLM).[/!]
fr: [!java]Cette construction s'appelle une boucle <code>for</code> étendue en Java. 
    La variable <i>i</i> prend successivement toutes les valeurs de l'ensemble placé à droite des deux-points (:).[/!] 
    [!python|scala]Cette écriture est finalement très semblable à la précédente. 
    Simplement, <code>[!python]range(n)[/!][!scala]i to j[/!]</code> retourne un ensemble d'entiers sur lequel la boucle <code>for</code> itère.
    En fait, [!thelang] offre d'autres moyens très élégants de traverser des [!python]listes[/!][!scala]tableaux[/!] 
    et d'autres collections de données. Mais cela devrait être le sujet d'exercices spécifiques (qui restent à écrire dans PLM).[/!]

note: type: Content of: <h3>
en: Declaring [!python]a list[/!][!java|scala]an array[/!]
fr: Déclarer [!python]une liste[/!][!java|scala]un tableau[/!]

note: type: Content of: <p>
en: If you know beforehand the content of your list, you can affect these values all together.  Just put them between square braces and separated by commas as follows:
fr: Si vous connaissez à l'avance le contenu de votre liste, vous pouvez affecter ces valeurs directement. Placez-les simplement entre crochets et séparées par des virgules comme ceci&nbsp;:

note: type: Content of: <pre>
en: L = [1, 3, 5, 7, 9] 
    <span class="comment"># L is now an array of 5 values, all of them being integers</span>
fr: L = [1, 3, 5, 7, 9] 
    <span class="comment"># L est maintenant une liste de 5 valeurs, toutes des entiers</span>

note: type: Content of: <p>
en: Otherwise, you probably want to create an empty list and then append each values separately to the list:
fr: Dans le cas contraire, le plus simple est de créer une liste vide puis d'ajouter chaque valeur séparément à la liste&nbsp;:

note: type: Content of: <pre>
en: L2 = [] 
    <span class="comment"># L2 is now an empty list</span>
    L2.append(1)
    L2.append(3)
    L2.append(5)
    L2.append(7)
    L2.append(9) 
    <span class="comment"># Its content is now the same as L previously</span>
fr: L2 = [] 
    <span class="comment"># L2 est maintenant une liste vide</span>
    L2.append(1)
    L2.append(3)
    L2.append(5)
    L2.append(7)
    L2.append(9) 
    <span class="comment"># Son contenu est maintenant le même que celui de L ci-dessus</span>

note: type: Content of: <p>
en: To declare a variable named <b>T</b> that can store an array of integers, one should write:
fr: Pour créer une variable nommée <b>T</b> pouvant contenir un tableau d'entiers, on écrira :

note: type: Content of: <p>
en: [!java]<code>int</code> means that the elements of the array are of type integer; <code>[]</code> means that we are speaking of an array and <code>T</code> is the name of the variable.  For historical reasons, this can also be written as <code>int T[]</code> (with the [] after the variable name), but this is less readable and should probably be avoided.[/!] [!scala]The <code>[Int]</code> notation specializes the Array type (that is generic), specifying that each cell of this array is an integer. An array of booleans would simply by written <code>Array[Boolean]</code>.[/!]
fr: [!java]<code>int</code> indique que les éléments du tableau sont de type entier;
    <code>[]</code> indique que nous parlons d'un tableau tandis que <code>T</code> est le nom de la variable. 
    Pour des raisons historiques, cela peut également être écrit sous la forme <code>int T[]</code> (avec [] à droite du nom de la variable), 
    mais cette forme est moins lisible et devrait probablement être évitée.[/!]
    [!scala]La notation <code>[Int]</code> spécialise le type <code>Array</code> («tableau» en anglais), qui est générique. Cela spécifie que chaque case du tableau est un entier. Le type d'un tableau de booléens s'écrirait simplement <code>Array[Boolean]</code>.[/!]

note: type: Content of: <h3>
en: Allocating an array
fr: Allocation d'un tableau

note: type: Content of: <p>
en: Declaring a variable <code>T</code> that stores an array only reserve the <b>name</b> <code>T</code> for later use, but not the memory area to store the cells. The array is not initialized yet: it does not have any value. What would <code>[!java]T[4][/!][!scala]T(4)[/!]</code> mean if we didn't say that the array is 5 cells long?
fr: Déclarer un tableau <code>T</code> nous réserve juste le nom <code>T</code> pour l'utiliser plus tard, mais pas la place en mémoire pour stocker les cases. Le tableau n'est pas initialisé : il n'a pas de valeur. Que voudrait dire <code>T[4]</code> si nous n'avons pas encore dit que <code>T</code> est un tableau de 5 éléments ?

note: type: Content of: <p>
en: First and foremost, we have to give a value to <code>T</code>:
fr: Avant tout, il faut donc lui affecter une valeur à <code>T</code>:

note: type: Content of: <p>
en: <code>new</code> means that we want to create something, and <code>[!java]int[10][/!][!scala]Array[Int](10)[/!]</code> means that it is an array of 10 integer values.  In return, an array of 10 integer cells is created in memory, and the <code>T</code> variable <b>references</b> this array.
fr: <code>new</code> indique qu'il faut créer quelque chose, et 
    <code>[!java]int[10][/!][!scala]Array[Int](10)[/!]</code> indique qu'il s'agit d'un tableau de 10 valeur entières. En réponse, un tableau d'entiers de longueur 10 est crée en mémoire, et la variable <code>T</code> <b>référence</b> ce tableau.

note: type: Content of: <p>
en: The size of an array is fixed and cannot be changed after the creation of the array. The size of a <code>T</code> array can be retrieve by consulting the variable <code>T.length</code>.
fr: La taille d'un tableau est fixée et ne peut plus être changée après la création du tableau. Pour connaître la taille d'un tableau <code>T</code>, on peut consulter la variable <code>T.length</code>.

note: type: Content of: <p>
en: While allocating, you can specify the size with a variable: <code>[!java]int[] T = new int[i];[/!][!scala]var T = new Array[Int](i);[/!]</code> In this case, the array's size will be set to the value of <code>i</code> <i>when <code>new</code> gets called</i>.  The size of the array still cannot be modified: even if the variable <code>i</code> changes afterward, the size remains to the value given when it was allocated.  [!java]Also, it is forbidden to write something like <code>int T[10];</code> when declaring the variable.  You are required to use the <code>new</code> instruction to allocate it, as in <code>int[] T = new int[10];</code> [/!]
fr: Lors de l'allocation, vous pouvez spécifier la taille à utiliser avec une variable: 
    <code>[!java]int[] T = new int[i];[/!][!scala]var T = new Array[Int](i);[/!]</code> 
    Dans ce cas, la taille du tableau est fixée à la valeur de <code>i</code> <i>quand <code>new</code> a été appelé</i>. 
    La taille du tableau ne peut toujours pas être modifiée. Même si la valeur de <code>i</code> est modifiée ensuite, la taille reste la même.
    [!java]Enfin, il est interdit d'écrire quelque chose comme <code>int T[10];</code> pour déclarer la variable. Il faut absolument utiliser <code>new</code> pour l'allouer, comme dans <code>int[] T = new int[10];</code> [/!]

note: type: Content of: <h4>
en: Declaration and initialization
fr: Déclaration et initialisation

note: type: Content of: <p>
en: If you know beforehand the content of your array, you can declare, allocate and initialize it in one shoot:
fr: Si vous connaissez le contenu de votre tableau à l'avance, vous pouvez le déclarer, l'allouer et l'initialiser en un coup:

note: type: Content of: <p>
en: To know the size of the array to allocate, the compiler counts the provided values.  This code is equivalent to:
fr: Pour connaître la taille du tableau à allouer, le compilateur compte les valeurs données.  Ce code est équivalent à :

note: type: Content of: <p>
en: It is also equivalent to:
fr: C'est aussi équivalent au code :

note: type: Content of: <h3>
en: [!python]Lists[/!][!scala|java]Arrays[/!] and method parameters
fr: Les [!python]listes[/!][!scala|java]tableaux[/!] et les paramètres de méthodes

note: type: Content of: <p>
en: It is perfectly OK to pass [!python]a list[/!][!java|scala]an array[/!] to a method as a parameter.  This method can then use this parameter as if it were defined locally:
fr: On peut tout à fait passer [!java|scala]un tableau[/!][!python]une liste[/!] en paramètre d'une méthode. La méthode peut alors l'utiliser comme si la variable avait été définie localement:

note: type: Content of: <pre>
en: [!java]boolean has42First(int[] array) {
        return array[0] == 42;
    }[/!][!python]def has42First(list):
      return list[0] == 42[/!][!scala]def has42First(array:Array[Int]):Boolean = {
      return array(0) == 42
    }[/!]
fr: [!java]boolean a42Premier(int[] tableau) {
        return tableau[0] == 42;
    }[/!][!python]def a42Premier(liste):
      return liste[0] == 42[/!][!scala]def a42Premier(tableau:Array[Int]):Boolean = {
      return tableau(0) == 42
    }[/!]

note: type: Content of: <p>
en: On the caller side, that also very simple:
fr: Coté appelant, c'est aussi simple :

note: type: Content of: <pre>
en: [!java]int[] tab = new int[10];[/!][!scala]var tab = new Array[Int] (10)[/!][!python]tab = [1, 3, 5, 7, 9][/!]
    [!java|scala]<span class="comment">// Values initialization omitted</span>
    [/!]if (has42First(tab))[!java|scala] {[/!][!python]:[/!]
       <span class="comment">[!java|scala]//[/!][!python]#[/!] do something</span>
    [!java|scala]}[/!]
fr: [!java]int[] tab = new int[10];[/!][!scala]var tab = new Array[Int] (10)[/!][!python]tab = [1, 3, 5, 7, 9][/!]
    [!java|scala]<span class="comment">// Initialisation des valeurs omise</span>
    [/!]if (a42Premier(tab))[!java|scala] {[/!][!python]:[/!]
       <span class="comment">[!java|scala]//[/!][!python]#[/!] faire des choses</span>
    [!java|scala]}[/!]

note: type: Content of: <p>
en: If you want to allocate and initialize the array in one shoot, that's a bit more complicated as the compiler has to know the type of the parameter you are creating.  For that, use the following (ugly) construct:
fr: Si vous voulez allouer et initialiser le tableau au vol lors du passage de paramètre, c'est un peu plus compliqué car il faut dire au compilateur le type du paramètre que vous construisez. Il faut alors utiliser la construction suivante, même si elle n'est pas très belle.

note: type: Content of: <pre>
en: if (has42First(   new int[] {1, 3, 5, 7, 9}   ) {
       <span class="comment">// do something</span>
    }
fr: if (has42First(   new int[] {1, 3, 5, 7, 9}   ) {
       <span class="comment">// faire des choses</span>
    }

note: type: Content of: <p>
en: Methods can also return [!java|scala]arrays[/!][!python]lists[/!] as result without any complication.  Here is a method that returns [!java|scala]an array[/!][!python]a list[/!] of the requested size, filled with 42s.
fr: Les méthodes peuvent également retourner des [!java|scala]tableaux[/!][!python]listes[/!] comme résultat sans aucun problème.
    Voici une méthode retournant [!java|scala]un tableau[/!][!python]une liste[/!] de la taille demandée après avoir initialisé toutes les cases à la valeur 42.

note: type: Content of: <pre>
en: [!java]int[] fill42(int size) {
        int[] res = new int[size];
        for (int i=0; i&lt;size; i++) 
            res[i] = 42;
        return res;
    }[/!][!scala]def fill42(size:Int):Array[Int] = {
        var res = new Array[int] (size)
        for (i &lt;- 0 to size -1) {
            res(i) = 42;
        }
        return res;
    }[/!][!python]def fill42(size):
        res = []
        for i in range(size):
            res.append(42)
        return res[/!]
fr: [!java]int[] remplir42(int taille) {
        int[] res = new int[taille];
        for (int i=0; i&lt;taille; i++) 
            res[i] = 42;
        return res;
    }[/!][!scala]def remplir42(taille:Int):Array[Int] = {
        var res = new Array[int] (taille)
        for (i &lt;- 0 to taille -1) {
            res(i) = 42;
        }
        return res;
    }[/!][!python]def remplir42(taille):
        res = []
        for i in range(taille):
            res.append(42)
        return res[/!]

note: type: Content of: <h3>
en: Goal of this exercise
fr: Objectif de l'exercice

note: type: Content of: <p>
en: At least! After this long explanation, we can come back to the exercise.
fr: Enfin ! Après toutes ces explications, nous pouvons revenir à l'exercice.

note: type: Content of: <p>
en: Your mission is rather simple actually.  Your code should save the color pattern observed on the first row into [!java|scala]an array[/!][!python]a list[/!].  [!python]The easiest is to create an empty list, and then <code>append()</code> the colors one after the others as you read them (with <code>getGroundColor()</code>).[/!] [!java|scala]For that, you should declare and allocate an array of <code>Color</code>. Beware, there is several worlds, of differing size; use <code>getWorldHeight()</code> to retrieve the size of the current world.  Once the array allocated, fill it by reading the ground color in each locations (with <code>getGroundColor()</code>).[/!]
fr: Votre mission est plutôt simple au fond. Votre code doit sauvegarder le motif de couleurs observé sur la première colonne. Il faut bien entendu sauvegarder ces valeurs dans [!java|scala]un tableau[/!][!python]une liste[/!].  
    [!python]Le plus simple pour cela est de créer une liste vide puis d'y adjoindre (avec <code>append()</code> les différentes couleurs lues sur le sol de la première colonne (avec <code>getCouleurSol()</code>).[/!] 
    [!java|scala]Pour cela, il faut déclarer et créer un tableau de variables de type <code>Color</code>. Attention, les différents mondes ne sont pas tous de la même taille et il faut utiliser <code>getMondeHauteur()</code> pour trouver la taille du monde courant. Une fois créé, remplissez le tableau en lisant les couleurs au sol de la première colonne (avec <code>getCouleurSol()</code>).[/!]

note: type: Content of: <p>
en: Once you managed to read and save the pattern on the first row, you have to reapply the pattern on every rows, for example by executing <code>getWorldHeight()</code> times a method written specifically for this.
fr: Une fois le motif de la première colonne lu et sauvegardé, il faut le répliquer sur toutes les colonnes, par exemple en exécutant <code>getMondeLargeur()</code> fois une méthode écrite tout exprès.

note: type: Content of: <h1>
en: [!java|scala]Arrays[/!][!python]Lists[/!], Knotting and Modulos
fr: [!java|scala]Tableaux[/!][!python]Listes[/!], tricot et modulo

note: type: Content of: <p>
en: This exercise is similar to the previous one: you have to reproduce the color pattern of the first cell into the other ones.
fr: Cet exercice ressemble au précédent : il faut reproduire le motif de couleurs de la première colonne dans les colonnes suivantes.

note: type: Content of: <p>
en: The first difference is that the world is bordered of walls: you thus have to slightly modify your trajectory to ensure that the buggle does not crash into a wall. The simpler for that is to handle the first cell out of the <code>for</code> loop and do only <code>getWorldHeight()-1</code> steps in the loop.
fr: La première différence est que le monde est entouré d'un mur : il faut donc modifier légèrement les parcours pour s'assurer que la buggle ne se cogne pas sur les bords. Le plus simple est de traiter la première case de la colonne en dehors de la boucle <code>for</code> (avant la boucle), et faire seulement <code>getWorldHeight()-1</code> pas dans la boucle.

note: type: Content of: <p>
en: The other difference is that the offset to apply between columns is not fixed, but written on the first cell of each column. To get the info as an integer, we can use:
fr: La seconde différence est que le décalage à effectuer entre les colonnes n'est pas fixe, mais écrit sur la première case de chaque colonne. Pour obtenir l'information sous forme d'un entier, on peut utiliser:

note: type: Content of: <pre>
en: [!java]int offset = Integer.parseInt(readMessage())[/!][!python]offset = int( readMessage() )[/!][!scala]val offset = readMessage().toInt[/!]
fr: [!java]int decalage = Integer.parseInt(litMessage())[/!][!python]decalage = int( litMessage() )[/!][!scala]val decalage = litMessage().toInt[/!]

note: type: Content of: <p>
en: <code>readMessage()</code> gets the message on the ground as a [!java|scala]String[/!][!python]string[/!], while <code>[!java]Integer.parseInt(str)[/!][!scala]str.toInt[/!][!python]int(str)[/!]</code> transforms the string <code>str</code> into an integer by <i>reading</i> it.
fr: <code>litMessage()</code> lit l'indication au sol sous forme d'une chaîne de caractères, 
    tandis que <code>[!java]Integer.parseInt(ch)[/!][!scala]ch.toInt[/!][!python]int(ch)[/!]</code> 
    transforme la chaîne <code>ch</code> en un entier en la <i>lisant</i>.

note: type: Content of: <p>
en: Then, to pick the right color, the easier is to use the <code>%</code> (modulo) operator. For example, <code>(i + 5) % size</code> allows to retrieve the <code>i</code>th cell of an array of size <code>size</code> with an offset of <code>5</code>.
fr: Ensuite, pour trouver la bonne couleur à utiliser, le plus simple est d'utiliser l'opérateur <code>%</code> (modulo). Par exemple, <code>(i + 5) % taille</code> permet de trouver la <code>i</code>ieme case d'un tableau de taille <code>taille</code> quand on applique un décalage de <code>5</code> cases.

note: type: Content of: <p>
en: You're up.
fr: À vous de jouer.

note: type: Content of: <h1>
en: Searching for a given value
fr: Chercher une valeur donnée

note: type: Content of: <p>
en: The goal of this exercise is to search the cell of a given value, and return its position.
fr: L'objectif de cet exercice est de chercher la case contenant une valeur donnée, et de retourner sa position.

note: type: Content of: <p>
en: To that extend, you should fill the method <code>indexOf()</code>, which parameters are the array to explore, and the value to search. If the value <code>lookingFor</code> is not in the array <code>tab</code>, the method should return -1.
fr: Pour cela, il vous faut remplir le corps de la méthode <code>indexOf()</code>. Ses paramètres sont le tableau <code>tab</code> à explorer et la valeur <code>lookingFor</code> à chercher. Si la valeur <code>lookingFor</code> n'est pas dans le tableau <code>tab</code>, la méthode doit renvoyer -1.

note: type: Content of: <p>
en: The idea of the algorithm is to sweep over the whole array, checking the value of each cell. If it's the searched value, you should return the index of the cell currently checked.
fr: L'idée de l'algorithme est de parcourir tout le tableau en vérifiant la valeur
    contenue dans chaque case. S'il s'agit de la valeur cherchée, vous devez
    renvoyer l'indice de la case actuellement explorée.

note: type: Content of: <p>
en: Remember that indices begin at 0 and not at 1. So, if there is 3 cells, their indices will be 0, 1 and 2. There would not be any cell numbered 3.
fr: N'oubliez pas que les cases sont numérotées à partir de 0. Donc, si vous avez 3 cases, leurs indices seront 0, 1 et 2. Il n'y aura pas de case numérotée 3.

note: type: Content of: <p>
en: Remember also that the amount of cells in an array can be retrieved using the <code>length</code> attribute. So, if your array is called <code>tab</code>, its size can be retrieved as <code>tab.length</code>.  Note that there is no () after <code>length</code>. An attribute is a sort of variable embedded in another object (here, the array).
fr: Ensuite, souvenez vous que le nombre de cases d'un tableau peut être retrouvé
    grâce à l'attribut <code>length</code>. Donc, si votre tableau s'appelle
    <code>tableau</code>, sa taille sera <code>tableau.length</code>. Notez qu'il
    n'y a pas de () après <code>length</code>. Un attribut est une sorte de
    variable embarquée dans un autre objet (ici, le tableau).

note: type: Content of: <p>
en: So, the last value of an array is given by <code>tab[tab.length - 1]</code>.
fr: Donc, la dernière valeur d'un tableau est donnée par <code>tab[tab.length -1]</code>.

note: type: Content of: <p>
en: Remember also that the amount of cells in an array can be retrieved with the <code>len()</code> function. So, if your array is called <code>tab</code>, its size can be retrieved as <code>len(tab)</code>.
fr: Ensuite, souvenez vous que le nombre de cases d'un tableau peut être retrouvé
    grâce à la fonction <code>len()</code>. Donc, si votre tableau s'appelle
    <code>tableau</code>, sa taille sera <code>len(tableau)</code>.

note: type: Content of: <p>
en: So, the last value of an array is given by <code>tab[ len(tab) - 1]</code>.
fr: Donc, la dernière valeur d'un tableau est donnée par <code>tab[ len(tab) -1]</code>.

note: type: Content of: <h1>
en: Index of the maximum value
fr: Indice de la valeur maximale

note: type: Content of: <p>
en: In this exercise, you must compute the index of the tab cell containing the biggest value.
fr: Dans cet exercice, vous devez calculer l'indice de la case contenant la plus grande valeur du tableau.

note: type: Content of: <p>
en: For that, fill the <code>indexOfMaximum()</code> method. Its parameter is the array to explore. Should the array contain the searched value several times, you should return the index of the first occurrence.
fr: Pour cela, remplissez la méthode <code>indexOfMaximum()</code> dont le paramètre est le tableau à explorer. Si jamais la plus grande des valeurs du tableau est répétée plusieurs fois, votre méthode doit renvoyer la position de la première occurrence.

note: type: Content of: <p>
en: To solve this exercise, you should sweep over the whole array. For each value, if it's bigger than the biggest value you saw so far, you must save this new champion and its position.  You will thus need 2 extra variables; the initial value of the champion could be the value of the first cell.
fr: Pour résoudre cet exercice, vous devez parcourir le tableau. Pour chaque case,
    si sa valeur est plus grande que la plus grande des valeurs que vous avez
    rencontré jusque là, sauvegardez cette nouvelle championne et sa position. Il
    vous faut donc deux nouvelles variables; la valeur initiale de la championne
    pourrait être la valeur rangée dans la première case.

note: type: Content of: <h1>
en: Average value
fr: Valeur moyenne

note: type: Content of: <p>
en: The objective of this exercise is to compute the average value of the integer values stored in an array.
fr: L'objectif de cet exercice est de calculer la valeur moyenne d'un tableau de valeur entière.

note: type: Content of: <p>
en: You have to fill the body of the method <code>average()</code> which takes as parameter the array of integers of which it computes and returns the average value. Please note that this method must return an integer.
fr: Vous devez donc remplir le corps de la méthode <code>average()</code> qui prend en paramètre le tableau, et qui retourne en résultat la valeur moyenne. Notez bien que cette méthode doit renvoyer un entier.

note: type: Content of: <p>
en: To compute the average value of an integer, it is necessary to traverse the whole array and to compute the sum of all its values (so you will need a variable to store this temporary result), then you have to divide this sum by the size of the array.
fr: Pour calculer la valeur moyenne d'un tableau, il faut parcourir l'ensemble des valeurs du tableau, en faire la somme (vous aurez donc besoin d'une variable pour conserver le résultat intermédiaire), puis diviser cette somme par le nombre de valeur contenu dans le tableau.

note: type: Content of: <p>
en: In Java, you can get the size of an array <code>myarray</code> by consulting its <code>length</code> attribute (in other words, <code>myarray.length</code>). Notice that there is no parenthesis after <code>length</code>.
fr: En Java, vous pouvez retrouver la taille d'un tableau <code>monTableau</code> en consultant son attribut <code>length</code> (autrement dit, <code>monTableau.length</code>). Notez qu'il n'y a pas de parenthèses après <code>length</code>.

note: type: Content of: <p>
en: In python, retrieving the size of an array <code>myarray</code> is as easy as calling <code>len(myarray)</code>.
fr: En python, retrouver la taille d'un tableau est aussi simple qu'appeler <code>len(monTableau)</code>.

note: type: Content of: <h1>
en: Maximal value
fr: Valeur maximale

note: type: Content of: <p>
en: In this exercise, you must compute the maximal value contained in an array.  For that, fill the <code>maximum()</code> method, which parameter is the array to explore.
fr: Dans cet exercice, vous devez retrouver le maximum des valeurs stockées dans un tableau. Pour cela, remplissez le corps de la méthode <code>maximum()</code>, dont le paramètre est le tableau à explorer.

note: type: Content of: <p>
en: To compute this value, sweep over the whole parameter. For each value, if it's bigger than the biggest value you saw so far, you must save this value somewhere to remember it afterward. You thus need an extra variable, which can be initialized to the value of the first array cell.
fr: Pour résoudre cet exercice, parcourez le tableau. Pour chaque case, si sa
    valeur est plus grande que la plus grande des valeurs que vous avez rencontré
    jusque là, sauvegardez cette nouvelle championne pour retrouver sa valeur plus
    tard. Il vous faut donc une nouvelle variable, dont la valeur initiale peut être
    la valeur de la première case du tableau.

note: type: Content of: <h1>
en: Occurrence of a value
fr: Occurrences d'une valeur

note: type: Content of: <p>
en: In this exercise, you must compute the amount of occurrences of a given value in an array (that is, the amount of time that this value appears in the array). For that, fill the <code>occurrences()</code> method, which returns the number of occurrence of <code>lookingFor</code> in <code>tab</code>.
fr: Dans cet exercice, il vous faut calculer le nombre d'occurrences d'une valeur donnée, c'est à dire le nombre de fois que cette valeur apparaît dans le tableau. Pour cela, remplissez le corps de la méthode <code>occurrences()</code>, qui retourne le nombre d'occurrences de la valeur <code>lookingFor</code> dans le tableau <code>tab</code>.

note: type: Content of: <p>
en: To compute this value, simply sweep over the array counting for the amount of cells containing the searched value. You thus need an extra variable for that.
fr: Pour calculer cette valeur, parcourez simplement le tableau en comptant le
    nombre de cases contenant la valeur cherchée que vous rencontrez. Il vous faut
    donc un paramètre supplémentaire pour cela.

note: type: Content of: <h1>
en: Maxima and Minima
fr: Maximum et minimum

note: type: Content of: outside any tag (error?)
en: In this exercise, you must return the difference between the maxima (i.e., the largest value of the array) and the minima (i.e., its smallest value). The returned value is then a positive number.  Beware, you can only do one traversal of the array to gather all informations that you need.
fr: Dans cet exercice, vous devez renvoyer la différence entre le maximum (c'est à dire la plus grande valeur du tableau) et le minimum (c'est à dire la plus petite des valeurs). La valeur renvoyée est donc un nombre positif. Attention, vous ne pouvez balayer les valeurs qu'une seule fois pour récupérer toutes les informations dont vous avez besoin.

note: type: Content of: <h1>
en: Second Biggest Value
fr: La seconde plus grande valeur

note: type: Content of: <p>
en: As usual, you should gather the information in only one traversal of the array.  You can assume that the second biggest value actual exists (there is at least two distinct values in the array), and that all values in the array are greater than [!python] -100000000.[/!] [!java|scala]<code>Integer.MIN_VALUE</code> (which is the smallest representable integer existing in [!thelang]).[/!]
fr: Comme d'habitude, vous ne devez effectuer qu'un seul parcours pour obtenir les informations nécessaires. Vous pouvez supposer que la seconde plus grande valeur existe effectivement (qu'il y a au moins deux valeurs dans le tableau) et que toutes les valeurs du tableau sont plus grandes que [!python] -100000000.[/!] [!java|scala]<code>Integer.MIN_VALUE</code> (qui est le plus petit entier existant en [!thelang]).[/!]

note: type: Content of: <h1>
en: Array123
fr: Tableau123

note: type: Content of: outside any tag (error?)
en: Given an array of integers, return true if .. 1, 2, 3, .. appears in the array somewhere.
fr: Soit un tableau d'entiers, renvoyez vrai si .. 1, 2, 3, .. apparaissent quelque part dans le tableau.

note: type: Content of: <p>
en: This exercise was converted to PLM from the excellent exercising site http://codingbat.com/
fr: Cet exercice a été extrait pour PLM depuis l'excellent site d'exercices http://codingbat.com/

note: type: Content of: <h1>
en: Array667
fr: Tableau667

note: type: Content of: outside any tag (error?)
en: Given an array of integers, return the number of times that two 6's are next to each other in the array. Also count instances where the second "6" is actually a 7.
fr: Soit un tableau d'entiers, renvoyez le nombre de fois que deux 6 sont l'un à la suite de l'autre dans le tableau. Comptez également le nombre de fois où le deuxième "6" est en fait un 7.

note: type: Content of: <h1>
en: ArrayCount9
fr: Comptage de 9

note: type: Content of: outside any tag (error?)
en: Given an array of integers, return the number of 9's in the array.
fr: Soit un tableau d'entiers, renvoyez le nombre de 9 dans ce tableau.

note: type: Content of: <h1>
en: ArrayFront9
fr: Tableau commençant par 9

note: type: Content of: outside any tag (error?)
en: Given an array of integers, return true if one of the first 4 elements in the array is a 9. The array length may be less than 4.
fr: Soit un tableau d'entiers, renvoyez vrai si l'un des 4 premiers éléments dans ce tableau est un 9. Le tableau peut contenir moins de 4 éléments.

note: type: Content of: <h1>
en: NoTriples
fr: Pas de triplet

note: type: Content of: outside any tag (error?)
en: Given an array of integers, we'll say that a triple is a value appearing 3 times in a row in the array. Return true if the array does not contain any triples.
fr: Soit un tableau d'entiers, on dira qu'un triplet est une valeur qui apparaît 3 fois à la suite dans le tableau. Renvoyez vrai si le tableau ne contient pas de triplet.

note: type: Content of: <h1>
en: Has271
fr: Contient 271

note: type: Content of: <p>
en: Given an array of integers, return true if it contains a 2, 7, 1 pattern -- a value, followed by the value plus 5, followed by the initial value minus 1.  So, 2,7,1 is such a pattern because 7 is 5+2 and 1 is 2-1. 3,8,2 is also such a pattern.
fr: Soit un tableau d'entiers, renvoyez vrai si il contient un motif 2,7,1 -- une valeur, suivie de cette valeur plus 5, suivie par cette valeur moins 1. 
    Par exemple, 2,7,1 est un tel motif car 7=5+2 et 1=2-1. 3,8,2 est un autre motif correspondant.

note: type: Content of: <p>
en: Additionally the 271 counts even if the "1" differs by 2 or less from the correct value.
fr: De plus, le 271 compte même si le "1" diffère de 2 ou moins de la valeur correcte.<

note: type: Content of: <h1>
en: Golomb sequence
fr: La suite de Golomb

note: type: Content of: outside any tag (error?)
en: The Golomb sequence is a non-decreasing integer sequence where a(n) is the number of times that n occurs in the sequence, with a(1) = 1.
fr: La suite de Golomb est une suite d'entiers non décroissante où a(n) indique le nombre de fois où n apparaît dans la suite, avec a(1)=1.

note: type: Content of: <p>
en: Since a(1)=1, it means that 1 occurs only once in the sequence, so a(2) must be different. Since the sequence is non-decreasing, a(2)  must be greater than 1. Since a(2)>1, the digit 2 must appear more than one time in the sequence. So a(2)=2.
fr: Puisque a(1)=1, nous savons que 1 n'apparaît qu'une seule fois dans la suite, ce qui impose à a(2) d'avoir une autre valeur. Comme a(2) est non-décroissante, cette autre valeur doit être plus grande que 1. Puisque a(2)>1, le chiffre 2 apparaît plus d'une fois dans la suite. Donc, a(2)=2.

note: type: Content of: <p>
en: Since a(2)=2, there is two 2 in the sequence, so we know the value of a(3). And so on for the other values of the sequence.
fr: Puisque a(2)=2, le chiffre 2 apparaît deux fois dans la suite, ce qui nous donne la valeur de a(3). Et ainsi de suite pour les valeurs suivantes de la suite.

note: type: Content of: <p>
en: Write a function that computes the Nth element of the sequence.
fr: Écrivez une fonction calculant le Nième élément de la suite.

note: type: Content of: <h1>
en: Buggles' Island
fr: L'île des Buggles

note: type: Content of: outside any tag (error?)
en: You just received the traveling notes of your old aunt who traveled accross the country of the Buggles' Islands. She wrote down the altitude every kilometer during her trip, resulting in a sequence of numbers as follows.
fr: Vous venez de recevoir les notes de voyage que votre vieille tante a rédigé lors de ses visites aux Îles des Buggles. Elle a noté l'altitude à chaque kilomètre pendant son voyage, ce qui donne des suites de nombres comme suit.

note: type: Content of: <p>
en: Here is a cut of the islands on that path:
fr: Voici une vue en coupe de l'île sur le parcours de votre tante :

note: type: Content of: <pre>
en:        /***\       /*\         &lt;-- 2 meters above the see level
       /***********\ /*******\     &lt;-- 1 meter above the see level
    ***************************    &lt;-- see level
    | | | | | | | | | | | | | |
    0 0 1 1 2 2 1 1 0 1 2 1 1 0    &lt;-- altitude on each point
fr:        /***\       /*\         &lt;-- 2 mètres au dessus du niveau de la mer
       /***********\ /*******\     &lt;-- 1 mètre au dessus du niveau de la mer
    ***************************    &lt;-- niveau de la mer
    | | | | | | | | | | | | | |
    0 0 1 1 2 2 1 1 0 1 2 1 1 0    &lt;-- altitude en chaque point

note: type: Content of: <p>
en: This example is constituted of four levels of island:
fr: Cet exemple est constitué de quatre niveaux d'île :

note: type: Content of: <ul><li>
en: 1 1 2 2 1 1 (the island on the left)
fr: 1 1 2 2 1 1 (l'île sur la gauche)

note: type: Content of: <ul><li>
en: 2 2 (the mountain topping the left island)
fr: 2 2 (la montagne au sommet de l'île à gauche)

note: type: Content of: <ul><li>
en: 1 2 1 1 (the right island)
fr: 1 2 1 1 (l'île de droite)

note: type: Content of: <ul><li>
en: 2 (the mountain on the right)
fr: 2 (la montagne sur l'ile à droite)

note: type: Content of: <p>
en: This can also be visualized this way:
fr: Cela peut également être visualisé ainsi :

note: type: Content of: <p>
en: Could you write a little program to compute the amount of levels in a given sequence of altitudes? Actually, there is an iterative and a recursive solution to that problem.
fr: Pourriez vous écrire un petit programme calculant le nombre de niveaux d'îles dans une séquence d'altitudes donnée ? En fait, il existe une solution itérative et une solution récursive à ce problème.

note: type: Content of: <p>
en: We will now write our own methods. It somehow comes down to extending the buggle vocabulary by teaching it new tricks.
fr: Nous allons maintenant voir comment écrire nos propres méthodes. Il s'agit en quelque sorte d'étendre le vocabulaire de la buggle en lui apprenant à faire de nouvelles choses.

note: type: Content of: <p>
en: For example, we saw in a previous exercise how to ask the buggle to go get the baggle in front of it, and bring it back. If there is several baggles on the board, and if we want to bring all of them on the bottom line, you have to repeat this code several times, or include it in a loop. In any case, you should avoid to duplicate your code to keep it pleasant to read and easily understandable.  It would be better if the buggle could obey an <code>goAndGet()</code> order just like it understands a <code>[!c]stepForward()[/!][!scala|java|python]forward()[/!]</code> one.
fr: Par exemple, nous avons vu dans un exercice précédent comment demander à la buggle d'aller chercher le biscuit qui se trouve devant elle, et la ramener à sa position initiale. S'il y a maintenant plusieurs biscuits sur le plateau, et que nous voulons tous les ramener sur la ligne du bas, il faut soit répéter ce code plusieurs fois, soit l'inclure dans une boucle. Dans les deux cas, il faut que vous évitiez de dupliquer votre code pour qu'il reste simple et lisible. Il serait mieux que la buggle comprenne un ordre de type <code>vaChercher()</code> tout comme elle comprend un <code>[!c]avancePas()[/!][!scala|java|python]avance()[/!]</code>.

note: type: Content of: <h3>
en: Defining methods
fr: Définir des méthodes

note: type: Content of: <p>
en: The [!thelang] syntax to write a simple method called <code>goAndGet</code> is the following:
fr: La syntaxe [!thelang] pour écrire une méthode simple nommée <code>vaChercher</code> est la suivante:

note: type: Content of: <pre>
en: [!java|c]void goAndGet() {[/!][!python]def goAndGet():[/!][!scala]def goAndGet() {[/!]
      actions()[!java|c];[/!]
      to()[!java|c];[/!]
      do()[!java|c];[/!]
    [!java|scala|c]}[/!]
fr: [!java|c]void vaChercher() {[/!][!python]def vaChercher():[/!][!scala]def vaChercher() {[/!]
      actions()[!java|c];[/!]
      encoreDesActions()[!java|c];[/!]
      dautresTrucs()[!java|c];[/!]
    [!java|scala|c]}[/!]

note: type: Content of: <p>
en: The method body [!java|scala|c](between curly braces)[/!][!python](the indented block)[/!] will be executed when we call the method later on (that is, when we write <code>goAndGet()</code> somewhere in our code). This method body can contain as many instructions as you want, and any construction we saw so far (for, while, if, etc).  [!java|c]The <code>void</code> keyword means that this method does not return any result. For example, the <code>isOverBaggle()</code> method does return a result, which is a [!c]int[/!][!java]boolean[/!] indicating whether or not the buggle is located over a baggle. We will soon learn to define such methods too. For now, just write <code>void</code> at this location.[/!]
fr: Le corps de la méthode
    [!java|scala|c](c'est-à-dire le bloc entre accolades)[/!]
    [!python](c'est-à-dire le bloc indenté)[/!]
    sera exécuté à chaque appel de cette méthode (c'est-à-dire à chaque fois que nous écrirons <code>vaChercher()</code> quelque part dans notre code).
    Ce corps de boucle peut contenir autant d'instructions que l'on veut, et toutes les constructions que nous avions vu jusque là (comme les boucles et les conditionnelles).
    [!java]Le mot-clé <code>void</code> («néant» en anglais) signifie que cette méthode ne renvoie pas de résultat. Au contraire, la méthode <code>estSurBiscuit()</code> renvoie un résultat booléen indiquant si nous nous trouvons oui ou non sur un biscuit. Nous apprendrons bientôt à faire de telles méthodes. En attendant, écrivez juste <code>void</code> à cet endroit.[/!]

note: type: Content of: <h3>
en: Documenting methods
fr: Documenter les méthodes

note: type: Content of: <p>
en: You should strive to document your code to keep it readable. When you write it, its purpose and limitations are clear to you, but most of the time, this does not last for long. You will soon forget about the details of every specific method, and this day you will be happy to read its documentation. In the following example, we use the specific formalism of [!java]javadoc[/!][!scala]scaladoc[/!][!python]pydoc[/!], a program that extracts the documentation of [!thelang] source code to produce html pages. The main advantage is that it allows to keep the documentation near to the code.  So, when you change your code, you have less chances to forget to update the documentation.
fr: Vous devez toujours vous efforcer de documenter votre code pour qu'il reste lisible. À l'instant où vous l'écrivez, son objectif et ses limitations vous semblent clairs, mais la plupart du temps, ça ne dure pas. On oublie vite les détails d'une méthode particulière, et quand cela arrive, on est content de pouvoir lire sa documentation. 
    Dans l'exemple ci-dessous, nous utilisons le formalisme spécifique de [!java]javadoc[/!][!scala]scaladoc[/!][!python]pydoc[/!], un programme qui extrait la documentation du code source pour en faire de belles pages web. Le principal avantage de cette approche est que la documentation se trouve à coté du code. Donc, quand on change le code, il y a un peu plus de chance pour qu'on pense à mettre la documentation à jour.

note: type: Content of: <p>
en: [!java|scala][!java]javadoc[/!][!scala]scaladoc[/!] comments begin with the <code>/**</code> marker (with two asterisks). They must be placed right before the method they document for the tool to find them.[/!] [!python]pydoc comments should be placed at the beginning of the method body so that the tool finds them. They should be placed between <code>"""</code>, which mark multi-line strings in python.[/!] The first line should be a brief description of what this method does while any subsequent lines should provide any important details about the method.
fr: [!java|scala]Les commentaires [!java]javadoc[/!][!scala]scaladoc[/!] commencent avec le marqueur <code>/**</code> (avec deux étoiles). Ces commentaires doivent être placés juste avant la méthode qu'ils documentent pour que l'outil les trouve[/!]
    [!python]Les commentaire pydoc doivent être placés au début du corps de la méthode pour que l'outil les trouve. Ils doivent être placés entre <code>"""</code>, qui marquent les chaînes de caractères sur plusieurs lignes en python.[/!]
    La première ligne devrait décrire brièvement la méthode tandis que le reste de la documentation devrait donner tous les points importants de la méthode.

note: type: Content of: <pre>
en: [!java|scala]/**
     *  Go, retrieves the baggle in front of the buggle, and brings it back 
     *
     *   Does not check for walls, so be careful to not call it when walls are present.
     */[/!]
    [!java]void goAndGet() {[/!]
    [!scala]def goAndGet() {[/!]
    [!python]def goAndGet():
      """Go, retrieves the baggle in front of the buggle, and brings it back.
    
      Does not check for walls, so be careful to not call it when walls are present."""[/!]
      actions()[!java];[/!]
      to()[!java];[/!]
      do()[!java];[/!]
    [!java|scala]}[/!]
fr: [!java|scala|c]/**
     *  Avance, récupère le biscuit, et le ramène à la position d'origine
     *
     *  Ne vérifie pas la présence de mur; à ne pas l'utiliser en cas de risques de mur.
     */[/!]
    [!java|c]void goAndGet() {[/!]
    [!scala]def goAndGet() {[/!]
    [!python]def goAndGet():
      """Avance, récupère le biscuit, et le ramène à la position d'origine
    
      Ne vérifie pas la présence de mur; à ne pas l'utiliser en cas de risques de mur."""[/!]
      actions()[!java|c];[/!]
      a()[!java|c];[/!]
      faire()[!java|c];[/!]
    [!java|scala|c]}[/!]

note: type: Content of: <h3>
en: Naming conventions
fr: Conventions de nommage

note: type: Content of: <p>
en: Most programming language forbid the use of spaces in method and variable identifiers (=their names).  Accented letters are sometimes allowed (as in [!thelang]), but they can lead to portability issues between operating systems and should thus be avoided when possible.
fr: La plupart des langages de programmation interdisent d'utiliser des espaces dans les noms de variables et de méthodes. Certains langages (comme le [!thelang]) autorisent l'usage des caractères accentués dans ces identificateurs, mais cela pose parfois des problèmes de portabilité entre les systèmes d'exploitation. C'est pourquoi PLM n'utilise pas d'accents dans les identificateurs, même si c'est parfois désagréable en français.

note: type: Content of: <p>
en: Across all programming languages, there is two main conventions to name variables and methods. The first one, consists in concatenating all words with only the first letter of each word in upper case. "go and get" becomes goAndGet().  It is called CamelCase because identifiers written this way graphically remind of a camel back. The other convention, called snake_case, is to write every words in lower case, separated with underscores symbols (_). "go and get" becomes go_and_get().
fr: Parmi tous les langages de programmation, il y a deux conventions de nomage majeures. La première consiste à concaténer tous les mots en ne laissant que la première lettre de chaque mot en majuscule. «va chercher le biscuit» devient VaChercherLeBiscuit(). Cette convention est nommée CamelCase en anglais, c'est-à-dire casse du chameau, car les identificateurs écrits de cette façon font un peu penser au dos d'un chameau. L'autre convention, nommée snake_case (casse du serpent), consiste à concaténer tous les mots en minuscule en les séparant du caractère souligné (_). «va chercher le biscuit» devient va_chercher_le_biscuit().

note: type: Content of: <p>
en: Which convention to use is the topic of heated discussion across developers, but each programming language has its own habits. In Python, Perl and the C language, the snake_case is often used for methods and variables. Java and Scala prefer the lowerCamelCase (the very first letter is lower case) for that.
fr: Le choix de la convention de nommage est le sujet de «discussions» très animées entre programmeurs, mais certaines habitudes prédominent pour chaque langage. En Python, Ruby, Perl ou en langage C, la casse_du_serpent prédomine pour les noms de variables et de méthodes. En Java et en Scala, on préfère habituellement la casseDuChameau, en laissant la toute première lettre en minuscule.

note: type: Content of: <p>
en: The CamelCase convention is used everywhere in PLM because this program is written in Java itself, so we kept our habits when adding new languages. But the fact that the Python bindings of PLM use the CamelCase instead of the snake_case is considered as a bug that we will fix in further releases.
fr: La casseDuChameau est utilisé partout dans PLM car c'est un programme écrit en Java à la base, et que nous avons gardé nos habitudes en écrivant le support pour d'autres langages. Mais nous considérons le fait Python ne soit pas en casse_du_serpent comme un bug, que nous corrigerons dans une version future.

note: type: Content of: <p>
en: The goal of this exercise is to write a method called <code>goAndGet()</code> which does the same than in a previous exercises (move forward until over a baggle, pick it up, move back to initial position, drop baggle).
fr: L'objectif de cet exercice est donc d'écrire une méthode nommée <code>goAndGet()</code> (va chercher) et qui fait la même chose que dans un exercice précédent (avance tant qu'on ne trouve pas de baggle, ramasser le baggle, reculer à la case départ, poser le baggle).

note: type: Content of: <p>
en: This exercise is a bit different because you will not write all of the code executed by the buggle. Instead, you should only write one method that get called automagically added when you click on <b>Start</b>. Your buggle calls your <code>goAndGet()</code> method on each row, until the baggle is found. [!python|scala]The code for that is already provided under the <code>goAndGet()</code> method, but you probably don't want to change it.[/!] [!java]You don't need to write the code calling <code>goAndGet()</code> yourself. It's automagically there already, even if you cannot see it.[/!]
fr: Cet exercice est un peu différent : vous n'allez pas écrire tout le code exécuté par la buggle, mais juste une méthode qui sera invoquée automagiquement quand vous exécutez l'exercice. Votre buggle va alors appeler votre méthode <code>goAndGet()</code> sur chaque colonne du monde, jusqu'à trouver le biscuit. [!python|scala]Le code pour cela est déjà donné (en anglais) sous la méthode <code>goAndGet()</code> qui reste à écrire, mais vous ne devriez pas le modifier.[/!] [!java]Vous n'avez pas à écrire vous-même le code qui va appeler<code>goAndGet()</code>. Il est automagiquement donné, même si vous ne pouvez pas le voir.[/!]

note: type: Content of: <p>
en: But for that to work, you have to actually write this <code>goAndGet()</code> method now.
fr: Mais pour que cela fonctionne, il faut que vous écriviez maintenant cette fonction <code>goAndGet()</code>...

note: type: Content of: outside any tag (error?)
en: We now would like to teach the buggle to build a doghouse. The naive approach consists in directly writing the needed code as follows.  This works because the buggle of this exercise leaves a red path as it moves.
fr: Nous souhaitons maintenant apprendre à la buggle à se faire une niche.  La première approche, la plus simple au premier abord, est d'écrire directement le code permettant de le faire, comme ci-dessous (cela marche car la buggle de cet exercice laisse une traînée rouge dans son sillage quand elle se déplace).

note: type: Content of: <pre>
en: [!c]stepForward()[/!][!python|java|scala]forward()[/!][!java|c];[/!]
    [!c]stepForward()[/!][!python|java|scala]forward()[/!][!java|c];[/!]
    left()[!java|c];[/!]
    [!c]stepForward()[/!][!python|java|scala]forward()[/!][!java|c];[/!]
    [!c]stepForward()[/!][!python|java|scala]forward()[/!][!java|c];[/!]
    left()[!java|c];[/!]
    [!c]stepForward()[/!][!python|java|scala]forward()[/!][!java|c];[/!]
    [!c]stepForward()[/!][!python|java|scala]forward()[/!][!java|c];[/!]
    left()[!java|c];[/!]
    [!c]stepForward()[/!][!python|java|scala]forward()[/!][!java|c];[/!]
    [!c]stepForward()[/!][!python|java|scala]forward()[/!][!java|c];[/!]
    left()[!java|c];[/!]
fr: [!c]avancePas()[/!][!python|java|scala]avance()[/!][!java|c];[/!]
    [!c]avancePas()[/!][!python|java|scala]avance()[/!][!java|c];[/!]
    left()[!java|c];[/!]
    [!c]avancePas()[/!][!python|java|scala]avance()[/!][!java|c];[/!]
    [!c]avancePas()[/!][!python|java|scala]avance()[/!][!java|c];[/!]
    left()[!java|c];[/!]
    [!c]avancePas()[/!][!python|java|scala]avance()[/!][!java|c];[/!]
    [!c]avancePas()[/!][!python|java|scala]avance()[/!][!java|c];[/!]
    left()[!java|c];[/!]
    [!c]avancePas()[/!][!python|java|scala]avance()[/!][!java|c];[/!]
    [!c]avancePas()[/!][!python|java|scala]avance()[/!][!java|c];[/!]
    left()[!java|c];[/!]

note: type: Content of: <p>
en: It becomes harder when we want to draw two doghouses: we have to rewrite the same code twice, which is not really handy. When the code becomes a bit long as this one, it becomes easier to see why we insist since a while on the pure evilness that code duplication represents. Indeed, if you realize that an error sneaked into a code that you copied at several locations, you will have to fix it several times. And mind your back if you forget one of these locations.
fr: Les problèmes commencent quand nous voulons faire faire deux cabanes à la buggle : Il faut réécrire le code deux fois, ce qui n'est pas très pratique. Quand le code devient un peu long comme dans ce cas, on voit mieux pourquoi il faut toujours éviter de dupliquer du code. En effet, si vous vous rendez compte que vous vous êtes trompé dans votre code, et que vous l'avez recopier à plusieurs endroits, il va falloir le corriger plusieurs fois. Et gare si vous oubliez de corriger un exemplaire.

note: type: Content of: <p>
en: There is even a name to this good principle in programming: DRY/SPOT, which means "Don't Repeat Yourself / Single Point Of Truth". The latter part means that each information must be written in only one location of your program to avoid the differing locations to get out of synch when you modify your code.
fr: Ce principe de programmation a même un nom en anglais : DRY/SPOT (qui signifie «point sec»). C'est l'acronyme de «Don't Repeat Yourself» (ne vous répétez pas) et «Single Point Of Truth» (point unique de vérité). Chaque information doit se trouver à un seul endroit de votre programme pour éviter que les différentes copies ne se désynchronisent quand vous modifiez votre programme.

note: type: Content of: <p>
en: So, let's apply this good principle and <b>factorize our code</b>, ie to write it only once, for example in a method. You should even to go further by factorizing the method body with a <code>for</code> loop, as seen previously.  If you do it correctly (what you should), you can use the method <code>left()</code> only once.
fr: Nous allons donc appliquer ce beau principe et <b>factoriser le code</b>, c'est-à-dire écrire le code une seule fois, par exemple dans une méthode. Vous devriez même aller plus loin en factorisant le code de la méthode avec une boucle <code>for</code> comme vu précédemment. Si vous vous y prenez bien (ce que vous devriez faire), vous n'écrirez qu'un seul appel à la méthode <code>gauche()</code> dans votre programme.

note: type: Content of: <p>
en: The goal of this exercise is to write a method called <code>dogHouse</code> achieving the same result than the code above, but with a for loop to keep it short.  The buggle will call your creation to create several dog houses around its world.
fr: L'objectif de cet exercice est d'écrire une méthode nommée <code>dogHouse()</code> et ayant un comportement identique au code ci-dessus. La buggle invoquera plusieurs fois votre œuvre afin de dessiner des cabanes un peu partout.

note: type: Content of: outside any tag (error?)
en: In this exercise, we will reproduce the geometric drawing that you can see in the "Objective" tab.
fr: Dans cet exercice, nous allons reproduire un dessin géométrique, que vous pouvez voir en cliquant sur l'onglet «Objectif».

note: type: Content of: <p>
en: Your goal (here and in any well written program) is to write the simplest possible code. For that, you have to decompose your work in sub-steps, and write a specific method for each sub-step.
fr: Votre objectif (ici, et dans tous les programmes bien faits) est d'écrire le code le plus simple possible. Pour cela, vous veillerez à décomposer le travail à faire en sous-étape, et à faire réaliser chaque sous-étape par une méthode particulière.

note: type: Content of: <p>
en: If you observe carefully the picture to draw, it is constituted of four parts depicting a sort of V. A possible decomposition is to write a method in charge of drawing a V from the current position. Its prototype can be: <code>[!java|c]void [/!]makeV()</code>
fr: Si on observe attentivement le modèle à dessiner, on remarque qu'il est composé de quatre formes en sorte de V à des positions différentes.  Un découpage possible est d'écrire une fonction chargée de faire un V à partir de la position courante. Son prototype peut être : <code>[!java|c]void [/!]faireV()</code>

note: type: Content of: <p>
en: In this method, you should use the methods <code>brushUp()</code> and <code>brushDown()</code> to mark the ground (you may want to factorize this in another method). It may be wise to write the <code>makeV()</code> so that it places directly the buggle in position for the next V.
fr: Dans cette méthode, vous devez utiliser les méthodes <code>baisseBrosse()</code> et <code>leveBrosse()</code> pour marquer le sol. Peut-être que marquer le sol devrait faire l'objet d'une méthode séparée? Il faudrait également que  méthode <code>faireV()</code> place directement la buggle en position pour dessiner le prochain V.

note: type: Content of: <p>
en: Your turn. Your code should not be longer than 4 lines (not counting <code>makeV</code>)...
fr: À vous de jouer. Votre code ne devrait pas prendre plus de quatre lignes (sans compter <code>faireV</code>)...

note: type: Content of: outside any tag (error?)
en: We will now reproduce an even bigger geometrical drawing. Once again, you can see the model by clicking on the "Objective" tab.
fr: Nous allons maintenant reproduire un dessin géométrique plus grand. Encore une fois, vous pouvez voir le modèle en cliquant sur l'onglet «Objectif».

note: type: Content of: <p>
en: You can naturally reuse all the code you typed in previous exercise (select the other exercise, do Ctrl-C, come back to the code of this exercise, do Ctrl-V).
fr: Vous pouvez bien entendu réutiliser tout le code que vous aviez tapé à l'exercice précédent (sélectionnez l'autre exercice, allez dans le code, sélectionner tout, faites Ctrl-C, revenez dans le code de l'exercice courant, faites Ctrl-V).

note: type: Content of: <p>
en: But you want to keep your code as simple as possible. For that, define new methods to deal simply with the repetitions in the pattern. For example, a method <code>makePattern()</code> achieving the pattern of previous example seems to be a good idea (but this may not be enough).
fr: Mais pour que votre méthode principale reste aussi simple que possible, il faudra définir de nouvelles méthodes afin de gérer simplement les répétions du motif. Par exemple, une méthode <code>faireMotif()</code> réalisant le motif de l'exercice précédent semble être un bon départ (mais ce n'est sans doute pas suffisant).

note: type: Content of: <p>
en: Why don't you give it a shot? The main code method shouldn't take more than 2 lines (included in a for loop)
fr: À vous de jouer. Le code principal ne devrait pas prendre plus de 2 lignes ( incluses dans une boucle for).

note: type: Content of: outside any tag (error?)
en: As you can imagine, you have to reproduce the geometric drawing depicted in the "Objectives" tab. As you can see, it is even bigger than the previous one.
fr: Vous vous en doutez, il vous faut encore une fois reproduire un dessin géométrique dont le modèle se trouve dans l'onglet «Objectif». Comme vous le voyez, il est encore plus grand que le précédent.

note: type: Content of: <p>
en: You thus have to declare even more methods to use the repetitions of the pattern and factorize your code.  Your turn...
fr: Il va donc falloir définir encore plus de méthodes afin de tirer partie des répétitions du motif pour factoriser votre code. À vous de jouer...

note: type: Content of: <h1>
en: Functions
fr: Fonctions

note: type: Content of: <p>
en: Quite often, you want to write a method that compute some value and returns it. Methods returning results are called <b>functions</b>.  Writing a function is not really harder than writing a simple method.  [!java|c]You simply have to specify the data type of expected results before the function name (where we previously had <code>void</code>).[/!] [!scala]You simply have to add a colon (:) after the parenthesis and write the type of data that your function will return, and add an equal sign (=). This syntax is actually rather close to defining a variable, with its type, that is actually a function.[/!] You can use the <code>return</code> instruction anywhere in your function body to specify that the computation is done (the function is not further executed), and that the result is the value following the <code>return</code> keyword.
fr: Souvent, on souhaite écrire une méthode calculant une valeur donnée, et qui la retourne. On appelle <b>fonctions</b> ces méthodes qui renvoient un résultat.Écrire une fonction n'est pas tellement plus dur que pour les méthodes sans résultat.
    [!java|c]Il suffit d'écrire le type de données renvoyées par votre fonction avant son nom (là où nous écrivions <code>void</code> avant).[/!] 
    [!scala]Il suffit d'ajouter deux points (:), le type de données renvoyées par votre fonction et le signe égal (=) entre  les parenthèses de la déclaration et l'accolade du bloc. Cette syntaxe est assez proche de la définition d'une variable (avec son type) dont la valeur serait une fonction.[/!]
    Vous pouvez utiliser l'instruction <code>return</code> n'importe ou dans le corps de votre fonction pour spécifier que le calcul est fini (la suite de la fonction n'est pas exécutée) et donner la valeur à donner à l'appelant après le mot-clé <code>return</code>.

note: type: Content of: <p>
en: Actually, you can also use that <code>return</code> keyword in methods that do not return any result, to interupt the computation. Of course, you should not provide any value to return in that case.
fr: En fait, vous pouvez également utiliser le mot-clé <code>return</code> dans les méthodes ne renvoyant pas de résultat, pour interrompre leur exécution. Dans ce cas, il ne faut bien entendu pas donner de valeur à droite du <code>return</code>.

note: type: Content of: <p>
en: It is possible to have several <code>return</code> instructions in several branches of a conditional. In fact, it is forbidden to have any execution path of your body without any <code>return</code>, or to write some code after the <code>return</code> instruction. Indeed, if the machine reaches the end of the function without finding any <code>return</code>, it cannot know what actual value to give back to the function caller.  Moreover, <code>return</code> interrupts immediately the function execution (why bother looking further when you know the function result?). So, if there is some code after a <code>return</code>, it must be an error and the compiler warns you.
fr: Il est possible d'avoir plusieurs instructions <code>return</code> dans différentes branches de <code>if</code>. Ce qui est interdit, c'est d'avoir une branche du code qui n'est pas terminée par un <code>return</code>, ou d'écrire du code après le <code>return</code>.
    En effet, si la machine arrive à la fin de la fonction sans avoir rencontré de <tt>return</tt>, elle ne peut pas savoir quelle valeur communiquer à celui qui a appelé la fonction. De plus, le <tt>return</tt> interrompt immédiatement l'exécution de la fonction (pourquoi continuer à chercher quand on a déjà trouvé le résultat de la fonction?). Donc, s'il y a du code après un <tt>return</tt>, c'est sans doute une erreur, et le compilateur vous l'indique.

note: type: Content of: <pre>
en: [!java|scala|c][!java]boolean [/!][!c]int [/!][!scala]def [/!]isFrontFree()[!scala]:Boolean =[/!] {
        if (isFacingWall() == [!java|scala]true[/!][!c]1[/!]) {
            return [!java|scala]false[/!][!c]0[/!];
            <span class="comment">/* no code allowed here */</span>
        } else {
            return [!java|scala]true[/!][!c]1[/!];
            <span class="comment">/* here neither */</span>
        }
        <span class="comment">/* even here, forget it */</span>
    }[/!][!python]def isFrontFree():
        if isFacingWall() == True:
            return False
            <span class="comment"># no code allowed here</span>
        else
            return True
            <span class="comment"># here neither</span>
    <span class="comment"># even here, forget it</span>[/!]
fr: [!java|scala|c][!java]boolean [/!][!c]int [/!] [!scala]def [/!]estDevantLibre()[!scala]:Boolean =[/!] {
        if (estFaceMur() == [!java|scala]true[/!][!c]1[/!]) {
            return [!java|scala]false[/!][!c]0[/!];
            <span class="comment">/* interdit d'écrire du code ici */</span>
        } else {
            return [!java|scala]true[/!][!c]1[/!];
            <span class="comment">/* pareil ici */</span>
        }
        <span class="comment">/* même ici, oubliez */</span>
    }[/!][!python]def estDevantLibre():
        if estFaceMur() == True:
            return False
            <span class="comment"># interdit d'écrire du code ici</span>
        else
            return True
            <span class="comment"># pareil ici</span>
    <span class="comment"># même ici, oubliez</span>[/!]

note: type: Content of: outside any tag (error?)
en: You will once again write a function that the buggle will use. Its name must be <code>haveBaggle</code>, and it returns a boolean value indicating whether the row in front of the buggle contains a baggle or not. The buggle will use it to search the first row containing a baggle, and stop here.
fr: Vous allez encore une fois écrire une fonction qui sera utilisée par la buggle. Son nom doit être <code>haveBaggle</code>, et elle doit renvoyer un booléen indiquant si la colonne face à la buggle contient un biscuit ou non. Votre buggle va s'en servir pour chercher la première colonne contenant un biscuit et s'y arrêter.

note: type: Content of: <p>
en: The easier for this function is to use a boolean variable called <code>seenBaggle</code> indicating whether or not we saw a baggle so far. Its initial value is '[!python]False[/!][!scala|java]false[/!][!c]0[/!]'.
fr: Le plus simple pour écrire cette fonction est peut être d'utiliser une variable booléenne <code>vuBiscuit</code> indiquant si on a vu un biscuit jusque là. Initialement, elle contient faux («[!python]False[/!][!scala|java]false[/!][!c]0[/!]»).

note: type: Content of: <p>
en: Then, move 6 steps forward (the world contains 7 cells and we already are on one of them). For each cell, if it contains a baggle, we store true in <code>sawBaggle</code> (and we don't do anything but moving forward if not).
fr: Ensuite, on avance de 6 cases (le monde contient 7 cases, et on est déjà sur l'une d'entre elles). Pour chaque case, si elle contient un biscuit, on range la valeur vrai dans <tt>vuBiscuit</tt> (et on ne fait rien d'autre qu'avancer si non).

note: type: Content of: <p>
en: At the end, we move back by 6 steps, and we return the value of <code>seenBaggle</code> to the caller.
fr: Quand on est arrivé à la fin, on recule de 6 cases, et on retourne le contenu de <tt>vuBiscuit</tt> à l'appelant.

note: type: Content of: <p>
en: Note that the used buggle provides some hidden code that will call your <code>haveBaggle</code> function on each column, moving automatically between columns. It is thus very important that your <code>haveBaggle</code> function have no side effect: the position (and orientation) at the end of your code must be the one observed at the beginning of this code. It will move in between to seek for the baggle, but come back to the column start.
fr: Notez que la buggle utilisée contient du code caché, qui va utiliser votre fonction <code>haveBaggle</code> sur chaque colonne en déplaçant la buggle automatiquement entre les colonnes. Il est donc très important que votre fonction <code>haveBuggle</code> n'ait pas d'effet de bord. La position (et l'orientation) à la fin de votre code doit être celle observée au début de ce code. La buggle va naturellement se déplacer pour chercher le baggle, mais elle doit revenir au début de la colonne.

note: type: Content of: <p>
en: Also, this exercise is a bit different since there is two initial worlds, each with a specific objective. Your code must work for each of them. Observe that the world selection scrolling menu (right below the speed slider)  allows to switch the observed world.
fr: De plus, cet exercice est un peu particulier, puisqu'il a deux mondes initiaux, chacun ayant un objectif particulier. Votre code doit fonctionner pour chacun d'entre eux. Remarquez que le menu déroulant de sélection du monde (juste sous la barre de réglage de la vitesse) permet de spécifier le monde que vous souhaitez observer.

note: type: Content of: <p>
en: When your function <code>haveBaggle</code> works, proceed to next exercise.
fr: Quand votre fonction <tt>haveBaggle</tt> fonctionne, passez à l'exercice suivant.

note: type: Content of: <p>
en: Don't you get tired of writing again and again the code to move by a fixed amount of steps? On the other hand, writing <tt>forward2()</tt>, <tt>forward3()</tt>, <tt>forward4()</tt>, as well as <tt>backward2()</tt>, <tt>backward3()</tt>, <tt>backward4()</tt>, and so on does not really help, to say the less.
fr: N'êtes vous pas fatigué d'écrire encore et encore le code qui permet d'avancer ou de reculer d'un nombre prédéterminé de pas ? Oui, mais écrire les méthode <tt>avance2()</tt>, <tt>avance3()</tt>, <tt>avance4()</tt>, et <tt>recule2()</tt>, <tt>recule3()</tt>, <tt>recule4()</tt>, et ainsi de suite, ça ne constitue pas un réel gain de temps. Et puis, c'est carrément moche !

note: type: Content of: <p>
en: Luckily, it is possible to pass <b>parameters</b> to your methods. You have to specify their type and name between the parenthesis after the method name. Then, you can use them in the method body as if it were variables defined in there, and which initial value is what the caller specified.
fr: Heureusement, il est possible de donner des <b>paramètres</b> à vos méthodes. Il faut marquer leur type et leur nom entre les parenthèses qui suivent le nom de la méthode. Ensuite, on peut les utiliser dans le corps de la fonction comme s'il s'agissait de variables définies ici.

note: type: Content of: <pre>
en: [!java|c]double [/!]divideByTwo([!java|c]double [/!]x[!scala]: Double[/!])[!scala]: Double =[/!] [!java|scala|c]{[/!][!python]:[/!]
         return x / 2[!java|c];[/!]
    [!scala|java|c]}[/!]
fr: [!java|c]double [/!]diviseParDeux([!java|c]double [/!]x[!scala]: Double[/!])[!scala]: Double =[/!] [!java|scala|c]{[/!][!python]:[/!]
         return x / 2[!java|c];[/!]
    [!scala|java|c]}[/!]

note: type: Content of: <p>
en: As caller, you have to specify the initial value of this "variables" between the call's parenthesis.
fr: À l'usage, il faut indiquer les valeurs qu'elles doivent prendre entre les parenthèses de l'appel.

note: type: Content of: <pre>
en: [!java|c]double [/!][!scala]val [/!]result = divideByTwo(3.14)[!java|c];[/!]
fr: [!java|c]double [/!][!scala]val [/!]resultat = diviseParDeux(3.14)[!java|c];[/!]

note: type: Content of: <p>
en: If you want several parameters, you need to separate them with comas (,)  both in the declaration and calls.
fr: Si on veut avoir plusieurs paramètres, il faut les séparer par des virgules, lors de la déclaration comme lors de l'appel.

note: type: Content of: <pre>
en: [!java|c]double divide(double x, double y) {[/!]
    [!scala]def divide(x:Double, y:Double): Double = {[/!]
    [!python]def divide(x, y):[/!]
         return x / y[!java|c];[/!]
    [!java|scala|c]}[/!]
fr: [!java|c]double divise(double x, double y) {[/!]
    [!scala]def divise(x:Double, y:Double): Double = {[/!]
    [!python]def divise(x, y):[/!]
         return x / y[!java|c];[/!]
    [!java|scala|c]}[/!]

note: type: Content of: <pre>
en: [!java|c]double res = divide(3.14 , 1.5);[/!]
    [!scala]val res = divide(3.14 , 1.5)[/!]
    [!python]res = divide(3.14 , 1.5)[/!]
fr: [!java|c]double res = divise(3.14 , 1.5);[/!]
    [!scala]val res = divise(3.14 , 1.5)[/!]
    [!python]res = divise(3.14 , 1.5)[/!]

note: type: Content of: <p>
en: In [!thelang], you can declare several methods of the same name as long as they don't have the same <b>signature</b>, that is, the same amount of parameters and the same parameters' types.
fr: En [!thelang], il est possible d'avoir plusieurs méthodes du même nom, à condition qu'elles n'aient pas la même <b>signature</b>, c'est à dire le même nombre de paramètres et les mêmes types de paramètres.

note: type: Content of: <p>
en: Observe that we omitted the <tt>else</tt> branches of each <tt>if</tt>. It works anyway because a <tt>return</tt> interrupts the method execution. If we arrive to the last line of <code>[!java]max(int,int)[/!][!scala]max(Int,Int):Int[/!]</code>, we know that <code>x&lt;=y</code> because otherwise, the <tt>return</tt> of line 2 would have stopped the execution.
fr: Remarquez que nous avons ici laissé de coté les <tt>else</tt> de chaque alternative. Cela fonctionne tout de même car un <tt>return</tt> interrompt l'exécution de la méthode. Si on arrive à la dernière ligne de <code>[!java]max(int,int)[/!][!scala]max(Int,Int):Int[/!]</code>, on est donc sûr que <code>x&lt;=y</code> car dans le cas contraire, le <tt>return</tt> de la deuxième ligne aurait arrêté l'exécution de la fonction.

note: type: Content of: <p>
en: This time, you have to write a <code> [!java|c]move(int stepCount,[!java]boolean[/!][!c]int[/!] forward)[/!] [!scala]move(stepCount: Int,forward: Boolean)[/!] [!python]move(stepCount,forward)[/!] </code> method which moves forward by <code>stepCount</code> steps if <code>forward</code> is true, and moves back of that amount of steps if the boolean is false.
fr: Cette fois, vous devez écrire une méthode 
    <code>[!java|c]move(int nbPas,[!java]boolean[/!][!c]int[/!] versLAvant)[/!] [!scala]move(nbPas: Int,versLAvant: Boolean)[/!] [!python]move(nbPas,versLAvant)[/!] </code> qui se déplace de <code>nbPas</code> pas. Si <code>versLAvant</code> est vrai, il faut avancer de ce nombre de pas; dans le cas contraire, il faut reculer.

note: type: Content of: <p>
en: This time, there is only one world but seven buggles, all sharing the same code.  This code should not be really problematic for you to write, actually.
fr: Cette fois, il y a un seul monde, et sept buggles, qui exécutent toutes le code que vous allez écrire.
    Cet exercice ne devrait pas vous poser de problème particulier.

note: type: Content of: <h2>
en: Flower Pot
fr: Pot de fleur

note: type: Content of: <p>
en: Your buggle decided to flower a bit the pot it lives in. You have to help it reproducing the drawing of its dreams (check the "Objective" tab to see it).
fr: Votre buggle a décidé de fleurir un peu le pot de fleur dans lequel elle vit. Vous devez l'aider à reproduire le motif dont elle rêve (vous pouvez le voir dans l'onglet «Objectif»).

note: type: Content of: <p>
en: For that, you have to write a <code>growFlowers()</code> method that does not take any parameter and does not return any result. You could probably make it without defining this method, but this is part of the assignment.
fr: Pour cela, vous devez écrire une méthode nommée
    <code>growFlowers()</code> («fait pousser les fleurs» en
    anglais). Cette méthode ne prend aucun paramètre et ne renvoie aucun
    résultat. Vous pourriez probablement réaliser ce motif sans cette
    méthode, mais l'écrire fait partie de l'exercice.

note: type: Content of: <p>
en: Also, you should try to decompose this complex drawing in sub-steps so that your code remains short and easy to read. A method to draw one flower of the color passed in parameter sounds like a good start, but it is probably not enough.
fr: De plus, vous devriez décomposer ce dessin complexe en sous-motifs pour que votre code reste simple et agréable à lire. Une méthode dessinant une fleur est un bon début, même si ce n'est probablement pas assez.

note: type: Content of: <p>
en: For your information, this drawing uses five colors that are listed below.  [!java|scala|c]The data type of these constants is <code>Color</code>, that naturally describes a particular color.[/!]
fr: Pour information, ce dessin utilise les cinq couleurs ci-dessous. 
    [!java|scala|c]Le type de données de ces constantes est <code>Color</code>, qui décrit naturellement une couleur donnée[/!]

note: type: Content of: <ul><li>
en: <code>[!scala|java|python]Color.[/!]RED</code>
fr: <code>[!scala|java|python]Color.[/!]RED</code> pour le rouge

note: type: Content of: <ul><li>
en: <code>[!scala|java|python]Color.[/!]PINK</code>
fr: <code>[!scala|java|python]Color.[/!]PINK</code> pour le rose

note: type: Content of: <ul><li>
en: <code>[!scala|java|python]Color.[/!]CYAN</code>
fr: <code>[!scala|java|python]Color.[/!]CYAN</code> pour le bleu clair

note: type: Content of: <ul><li>
en: <code>[!scala|java|python]Color.[/!]ORANGE</code>
fr: <code>[!scala|java|python]Color.[/!]ORANGE</code> pour le orange

note: type: Content of: <ul><li>
en: <code>[!scala|java|python]Color.[/!]GREEN</code>
fr: <code>[!scala|java|python]Color.[/!]GREEN</code> pour le vert

note: type: Content of: <ul><li>
en: <code>[!scala|java|python]Color.[/!]YELLOW</code>
fr: <code>[!scala|java|python]Color.[/!]YELLOW</code> pour le jaune

note: type: Content of: <h2>
en: Flower Display Case
fr: Jardinière de fleurs

note: type: Content of: <p>
en: Whao! That's not a little pot anymore! That's a huge large flower display case! Your buggle can't help but starts flowering this gorgeous place. You should help it to prevent that it bumps into a wall...
fr: Whaou! Ce n'est plus un petit pot de fleurs, c'est carrément une énorme jardinière! Votre buggle est déjà partie la fleurir, et vous devriez aller l'aider pour éviter qu'elle ne se cogne à une bordure...

note: type: Content of: <p>
en: PS: the newly used color is <code>Color.BLUE</code>.
fr: PS: La nouvelle couleur utilisée (pour le bleu) est <code>Color.BLUE</code>

note: type: Content of: <h2>
en: Colorful drawing
fr: Dessins colorés

note: type: Content of: <p>
en: If you observe carefully the picture to draw, it is constituted of four parts depicting a sort of V using a different color. A possible decomposition is to write a method in charge of drawing a V of the specified color from the current position. Its prototype can be:
fr: Si on observe attentivement le modèle à dessiner, on remarque qu'il est composé de quatre formes en sorte de V de couleurs différentes, et à des positions différentes.  Un découpage possible est d'écrire une fonction chargée de faire un V de la couleur indiquée à partir de la position courante. Son prototype peut être :

note: type: Content of: <pre>
en: [!java|c]void [/!]makeV([!java|c]Color [/!]c[!scala]: Color[/!])[!python]  <span class="comment"># parameter c is of type Color</span>[/!]
fr: [!java|c]void [/!]faireV([!java|c]Color [/!]c[!scala]: Color[/!])[!python]  <span class="comment"># le paramètre c est de type Color</span>[/!]

note: type: Content of: <p>
en: The <code>Color</code> data type naturally describes a particular color. Your code should probably call <code>makeV</code> with the following arguments (a different color for each call):
fr: Le type de données <code>Color</code> représente naturellement une couleur en particulier.  Votre code invoquera sans doute <code>faireV</code> avec les arguments suivants (une couleur différente à chaque appel) :

note: type: Content of: <p>
en: In <code>makeV()</code>, you should use the <code>setBrushColor()</code> method (predefined in the buggle) to change the color of the buggle's brush, as well as <code>brushUp()</code> and <code>brushDown()</code> to change the brush position.
fr: Dans la méthode <code>faireV()</code>, il faut utiliser la méthode <code>setCouleurBrosse()</code>, qui est prédéfinie dans la buggle, pour changer la couleur du pinceau, ainsi que <code>leveBrosse()</code> et <code>baisseBrosse()</code> pour lever et baisser le pinceau.

note: type: Content of: <p>
en: It may be wise to write the <code>makeV()</code> so that it places directly the buggle in position for the next V.
fr: Il faudrait également que la méthode <code>faireV()</code> place la buggle en position pour dessiner le prochain V directement.

note: type: Content of: <p>
en: Your turn now. I'm sure you can imagine the other methods you need to keep your code simple and pleasant to read.  Complete the method <code>run()</code> that should be called automatically (once).  [!java]the <code>public</code> keyword means more or less that anybody can call this method, which is good because the PLM infrastructure calls it directly.[/!]
fr: À vous de jouer. Je suis sûr que vous parviendrez à trouver d'autres méthodes à ajouter pour décomposer ce problème et faire en sorte que votre code reste simple et agréable à lire. Complétez la méthode <code>run()</code> qui sera appelée automatiquement une fois. 
    [!java]Le mot-clé <code>public</code> signifie plus ou moins que tout le monde a le droit d'invoquer cette méthode. Ça tombe bien, l'infrastructure de la PLM va l'invoquer directement.[/!]

note: type: Content of: <h2>
en: Larger colorful drawing
fr: Grand dessin coloré

note: type: Content of: <p>
en: You thus have to declare even more methods to use the repetitions of the pattern and factorize your code. Another solution is to <i>parametrize</i> your functions to reuse the code you wrote previously by changing the size.
fr: Il va donc falloir définir encore plus de méthodes afin de tirer partie des répétitions du motif pour factoriser votre code. Ou alors, il va falloir <i>paramétrer</i> vos fonctions pour réutiliser ce que vous aviez écrit en changeant les tailles.

note: type: Content of: <p>
en: Your turn...
fr: À vous de jouer...

note: type: Content of: <h2>
en: Another Colorful Pattern
fr: Autre motif coloré

note: type: Content of: outside any tag (error?)
en: Here is yet another exercise where you have to reproduce the pattern provided in the "Objective" tab.
fr: Voici de nouveau un exercice où il faut reproduire un motif donné dans l'onglet «Objectif».

note: type: Content of: <p>
en: This one is a bit more difficult than the one seen previously. Look for repeating patterns, even if the color changes, and write a method drawing each of them.
fr: Celui-ci est un peu plus difficile que ceux vus précédemment. Cherchez les motifs qui se répètent, même si la couleur change, et faites une méthode dessinant chacun d'entre eux.

note: type: Content of: <p>
en: Good luck!
fr: Bon courage !

note: type: Content of: <p>
en: Now that your <code>isFacingTrail()</code> method is working, it's time to write the code to organize the hunting party. Copy/paste your code from the previous exercise, and complete the <code>hunt()</code> method.
fr: Maintenant que votre méthode <code>isFacingTrail()</code> fonctionne, il est temps d'écrire le code de la chasse à proprement parler. Copie/collez le code que vous aviez fait pour l'exercice précédent, et complétez la méthode <code>hunt()</code> (<i>hunt</i> signifie <i>chasse</i> en anglais).

note: type: Content of: <p>
en: Following a track is not very difficult: move forward as long as you have the track in front of you.  If there is not track in front of you anymore, check whether the rest of the track is on your left or on your right, and follow it further.
fr: Suivre une piste n'est pas très difficile : avancez tant que vous êtes face à la piste. Si la piste n'est plus devant vous, cherchez si elle se trouve à gauche ou à droite, et suivez-la encore.

note: type: Content of: <p>
en: To ensure that you don't mix the track you come from with the one in front of you, the easier is to erase the track when you follow it. Use the method <code>brushDown()</code> to put your brush down and mark the ground, and <code>brushUp()</code> to move it up again.
fr: Pour ne pas confondre la partie de la trace à suivre avec celle que votre buggle a déjà suivie, il est conseillé d'effacer la piste derrière vous. Pour cela, utilisez la méthode <code>baisseBrosse()</code> pour baisser votre brosse, et <code>leveBrosse()</code> pour la relever.

note: type: Content of: <p>
en: Finally, do not forget to capture your prey once you found it (using <code>pickupBaggle()</code>).
fr: Enfin, n'oubliez de capturer votre proie une fois que vous l'aurez débusquée (avec <code>prendBiscuit()</code>).

note: type: Content of: outside any tag (error?)
en: <a name="Objectives"> Complete the <code>hunt()</code> method. You probably want to copy over the <code>isFacingTrail()</code> method that you wrote in previous exercise.  </a>
fr: <a name="Objectifs"> Complétez la méthode <code>hunt()</code>. Vous voulez probablement copier votre méthode <code>isFacingTrail()</code> de l'exercice précédent.</a>

note: type: Content of: <p>
en: Your buggle is super happy! It just found the green dribbling trail, certainly left by a big yummy slug.  At its end, the buggle is certain to entertain itself with this appetizing slug (represented as a baggle).
fr: Votre buggle est super contente ! Elle vient de trouver une grosse traînée baveuse sur le sol, certainement laissée par une grosse limace. Au bout de cette piste, la buggle est sûre de se régaler d'un bon jus de limace (représentée par un baggle).

note: type: Content of: <p>
en: To reach that goal, you had to write a method <tt>isFacingTrail</tt> that will be called automatically by the buggle on each step. Your method should return [!python]True[/!][!java|scala]true[/!] if facing a green cell, or [!python]False[/!][!java|scala]false[/!] if not. Of course, if we are facing a wall, it should return false without bumping into it. You should make sure that this method has no <b>side effect</b>, i.e. that it does not change the state of the calling buggle nor of its world.
fr: Pour arriver au résultat, vous devez écrire la méthode <code>isFacingTrail()</code>, qui sera appelée automatiquement par la buggle à chaque pas. Votre méthode doit renvoyer [!python]True[/!][!java|scala]true[/!] (vrai) si on est face à une case verte, ou [!python]False[/!][!java|scala]false[/!] (faux) sinon. Bien sûr, si on est face à un mur, elle doit répondre faux sans se cogner. Il faut de plus que cette méthode soit <b>sans effet de bord</b>, c'est-à-dire qu'elle ne modifie ni la buggle qui l'appelle, ni le monde environnant.

note: type: Content of: <p>
en: Your tool to that end is the <code>getGroundColor()</code> that returns the color of the current cell. Just go to the cell you want to test and run that function.  [!java]You cannot test whether this color is equal to <code>Color.green</code> with an <code>==</code> sign but instead you have to write something like <code>getGroundColor().equals(Color.green)</code>. This is because green is an <i>object</i> in Java, and <code>.equals()</code> is the way to go to test equality between Java objects.[/!] [!python|scala|c]So you just have to test whether the returned color is equal to the value <code>[!scala|python]Color.green[/!][!c]GREEN[/!]</code>, that represents the green color.[/!]
fr: Votre outil pour cela est la méthode <code>getCouleurSol()</code> qui retourne la couleur du sol dans la case où se trouve la buggle. Il vous faut vous rendre dans la case à tester avant d'appeler cette méthode. 
    [!java]Vous ne pouvez pas simplement utiliser <code>==</code> pour tester si la couleur retournée est le vert, mais vous devez plutôt écrire quelque chose comme <code>getCouleurSol().equals(Color.green)</code>. C'est parce que les couleurs sont des <i>objets</i> en Java, et que <code>.equals()</code> est la marche à suivre pour tester l'égalité d'objets Java.[/!]
    [!python|scala|c]Il suffit ensuite de tester si la couleur renvoyée par cette fonction est égale à la valeur <code>[!scala|python]Color.green[/!][!c]GREEN[/!]</code>, qui représente la couleur verte.[/!]

note: type: Content of: <p>
en: Complete the <code>isFacingTrail()</code> method (which gets called automatically).
fr: Complétez la méthode <code>isFacingTrail()</code> qui sera appelée automatiquement comme il faut.

note: type: Content of: <h2>
en: Slugs and Snails
fr: Limaces et escargots

note: type: Content of: <p>
en: Yuhu! This time, your buggle found the tracks of much more preys! In the first world, that's a yummy Kitty Slug (leaving a pink trail) while on the second world, that's a big fat snail that awaits your buggle at the end of the orange trail.
fr: YES! Cette fois encore, votre buggle a débusqué de bonnes proies! Dans le premier monde, c'est une délicieuse limace Kitty (qui laisse des traces rose) tandis que dans le second monde, un bon gros escargot du désert attend la buggle au bout de sa piste orange.

note: type: Content of: <p>
en: You have to copy/paste your code again, and change it so that your methods take the color of the trail to follow as a parameter. Beside of this, your code should work as earlier.
fr: Il vous faut copie/coller votre code encore une fois, et le modifier pour que vos méthodes prennent la couleur de piste à suivre en paramètre. À part cela, votre code devrait faire comme avant.

note: type: Content of: <p>
en: Don't get lost on false leads! <code>The hunt()</code> method was given a parameter to tell you which color to follow (and it is not the same in all worlds). Add a parameter to your <code>isFacingTrail()</code> method to only follow the requested color, as the other colors lead to dead ends...
fr: Attention aux fausses pistes ! La méthode <code>hunt()</code> a un paramètre qui indique la colueur à suivre (et ce n'est pas la même dans tous les mondes). Ajoutez un paramètre à votre méthode <code>isFacingTrail()</code> et assurez-vous de ne suivre que cette couleur. Les autres couleurs mènent à des impasses...

note: type: Content of: <p>
en: After these races, it's time to party! For that, we will teach the buggles to play Dance Revolution, this game beloved of some students: The player has to move the feet on the carpet according to the instructions presented on the screen, and following the music. But before that, we have some details to study first.
fr: Après toutes ces courses, il est temps de faire la fête ! Pour cela, nous allons apprendre à nos buggles à jouer à Dance Revolution, ce jeu très prisé de certains étudiants où le joueur doit bouger sur un tapis prévu à cet effet en fonction des consignes présentées à l'écran en rythme avec la musique. Mais avant cela, nous avons quelques détails à étudier.

note: type: Content of: <h3>
en: Conditionals without curly braces
fr: Conditionnelles sans accolades

note: type: Content of: <p>
en: There is one detail we omitted about the conditional syntax: if a branch contains only one instruction, then the curly braces become optional. So, the two chunk of code are equivalent:
fr: Il y a un détail que nous avons omis à propos de la syntaxe des conditionnelles : si une branche ne contient qu'une seule instruction, les accolades sont optionnelles. Ainsi, les deux extraits suivants sont équivalents:

note: type: Content of: <pre>
en: if (<b>condition</b>) {
        <b>whatToDoIfTheConditionIsTrue();</b>
    } else {
        <b>whatToDoElse();</b>
    }
fr: if (<b>condition</b>) {
        <b>quoiFaireSiLaConditionEstVraie();</b>
    } else {
        <b>quoiFaireSinon();</b>
    }

note: type: Content of: <pre>
en: if (<b>condition</b>) 
        <b>whatToDoIfTheConditionIsTrue();</b>
    else
        <b>whatToDoElse();</b>
fr: if (<b>condition</b>)
        <b>quoiFaireSiLaConditionEstVraie();</b>
    else
        <b>quoiFaireSinon();</b>

note: type: Content of: <p>
en: Actually, you can do the same for loops body that are reduced to one instruction only.  But beware, this becomes dangerous if you chain the <tt>if</tt> instructions like this:
fr: Vous pouvez faire de même avec les boucles dont le corps se réduit à une seule instruction. Mais attention, ceci peut être dangereux si on enchaîne les <tt>if</tt> comme dans l'exemple suivant.

note: type: Content of: <pre>
en: if (isOverBaggle())    
         if (x == 5)
              left();
    else // Do not write it this way, it's misleading!
         right(); 
    [!c]stepForward();[/!][!java|scala]forward();[/!]
fr: if (estSurBiscuit())    
         if (x == 5)
              gauche();
    else // N'écrivez pas les choses ainsi, c'est trompeur
         droite();
    [!c]avancePas();[/!][!java|scala]avance();[/!]

note: type: Content of: <p>
en: You think that <code>right()</code> refers to the first <code>if</code> and get executed when <code>isOverBaggle()</code> returns false, but in fact, it refers to the second one <code>if</code> and will be executed when <code>isOverBaggle()</code> returns true and <code>x != 5</code>. Yes, despite the indentation, the buggle understands the previous code as follows:
fr: Vous pensez que <code>droite()</code> se réfère au premier
    <code>if</code> et qu'il sera exécuté quand
    <code>estSurBiscuit()</code> renvoie faux, mais en fait il se ratache
    au premier <code>if</code> et sera exécuté quand
    <code>estSurBiscuit()</code> renvoie vrai et que <code>x !=
    5</code>. Oui, malgré l'indentation, la buggle comprend le code
    précédent comme suit:

note: type: Content of: <pre>
en: if (isOverBaggle())    
            if (x == 5)
                left();
            else
                right();
    [!c]stepForward();[/!][!java|scala]forward();[/!]
fr: if (estSurBiscuit())    
            if (x == 5)
                gauche();
            else
                droite();
    [!c]avancePas();[/!][!java|scala]avance();[/!]

note: type: Content of: <p>
en: In [!thelang] the computer connects a <tt>else</tt> branch to the closest <tt>if</tt>. If you find it ambiguous, you should add more braces than strictly necessary. Computers don't even look at the indentation in [!thelang]. The previous code could even be written as follows and lead to the same result.
fr: En [!thelang], l'ordinateur connecte une branche <code>else</code> au
    <code>if</code> le plus proche. Si vous trouvez cela ambigu, n'hésitez
    pas à mettre plus de parenthèses que strictement nécessaire pour
    rendre votre code lisible. Les ordinateurs ne regardent même pas
    l'indentation en [!thelang], et le code précédent pourrait même être
    écrit de la manière suivante :

note: type: Content of: <pre>
en: if (isOverBaggle()) if (x == 5) left(); else right(); [!c]stepForward();[/!][!java|scala]forward();[/!]
fr: if (estSurBiscuit()) if (x == 5) gauche(); else droite(); [!c]avancePas();[/!][!java|scala]avance();[/!]

note: type: Content of: <p>
en: But for humans, <b>you really want to indent your code correctly correctly</b>. For example if you want a professor to review or even grade your code, if you want to reuse your own code later, or even if you need to debug it. That is right: you need to write readable code for your own comfort.
fr: Mais pour les humains, <b>il est indispensable d'indenter son code
    correctement</b>. Cela vaut si vous voulez qu'un enseignant relise
    voire note votre code, si vous comptez réutiliser votre code plus
    tard, ou même si vous devez debugger votre propre code après l'avoir
    écrit. Exactement. Vous devez écrire du code lisible pour votre propre
    confort.

note: type: Content of: <h3>
en: Chaining conditionals
fr: Enchaînements de conditionnelles

note: type: Content of: <p>
en: You sometimes want to ask the buggle something similar to:
fr: Il arrive que l'on veuille demander à la buggle quelque chose similaire à :

note: type: Content of: <pre>
en: if it's raining, take an umbrella;
    if not, and if it's a hot day, take a bottle of water;
    if not and if it's July 4th, take an American flag
fr: s'il pleut, prend un parapluie; 
    si non, s'il fait chaud, prend une bouteille d'eau; 
    si non, si nous sommes le 14 juillet, prend un drapeau français

note: type: Content of: <p>
en: The trap is that we want at most one of these actions to be taken. That is to say, if it's raining a very hot July 4th, we don't want the buggle to get outside with an umbrella, some water and a flag, but simply with an umbrella. The following code is thus WRONG.
fr: Le piège étant que nous voudrions qu'au plus l'une de ces actions soient réalisées. C'est à dire, que s'il pleut un 14 juillet très chaud, on ne veut pas que la buggle sorte avec un parapluie, de l'eau et un drapeau, mais juste avec un parapluie. Le code suivant est donc faux.

note: type: Content of: <pre>
en: [!scala|c|java]if (rainy())
        takeUmbrella();
    if (hot())
        takeWater();
    if (todayIsJuly4th())
        takeFlag();[/!][!python]if rainy():
        takeUmbrella()
    if hot():
        takeWater()
    if todayIsJuly4th():
        takeFlag()[/!]
fr: [!java|c|scala]if (ilPleut())
        prendreParapluie();
    if (ilFaitChaud())
        prendreDeLEau();
    if (sommes14Juillet())
        prendreDrapeau();[/!][!python]if ilPleut():
        prendreParapluie()
    if ilFaitChaud():
        prendreDeLEau()
    if sommes14Juillet():
        prendreDrapeau()[/!]

note: type: Content of: <p>
en: Indeed, since the conditions are evaluated one after the other, there is a risk that you go to the July 4th march on a rainy day. Instead, we should use something like this to ensure that once we found a true condition, we won't evaluate the next ones.
fr: En effet, toutes les conditions sont évaluées les unes après les autres, et on risque donc d'aller au défilé un jour de pluie. À la place, il faut donc écrire quelque chose comme ce qui suit pour s'assurer que si l'on trouve une condition vraie, on n'évalue pas les suivants.

note: type: Content of: <pre>
en: [!java|scala|c]if (rainy()) {
        takeUmbrella();
    } else {
        if (hotDay()) {
            takeWater();
        } else {
            if (todayIsJuly4th()) {
                takeFlag();
            }
        }
    }[/!][!python]if rainy():
        takeUmbrella()
    else:
        if hotDay():
            takeWater()
        else:
            if todayIsJuly4th():
                takeFlag()[/!]
fr: [!java|scala|c]if (ilPleut()) {
        prendreParapluie();
    } else {
        if (ilFaitChaud()) {
            prendreDeLEau();
        } else {
            if (sommes14Juillet()) {
                prendreDrapeau();
            }
        }
    }[/!][!python]if ilPleut():
        prendreParapluie()
    else:
        if ilFaitChaud():
            prendreDeLEau()
        else:
            if sommes14Juillet():
                prendreDrapeau()[/!]

note: type: Content of: <p>
en: Unfortunately, such a cascade of conditionals is quite difficult to read. It is better to [!java|scala|c]omit the curly braces for the <tt>else</tt> statements. Some languages even introduce a specific construct for these <tt>else if</tt>, but not [!thelang].[/!] [!python]change the sub-blocks using the <code>elif</code> keyword to mark explicitly these "else if" branches.[/!]
fr: Une telle cascade de conditionnelles est un peu difficile à lire, et il est préférable
    [!java|scala|c] d'omettre les accolades associées aux <tt>else</tt> comme suit. Il y a même certains langages qui introduisent un mot-clé spécial pour ces <tt>else if</tt> (mais pas [!thelang]).[/!]
    [!python] d'introduire les sous-blocs avec le mot-clé <code>elif</code> (abréviation de «else if») pour expliciter ces branches «sinon si».[/!]

note: type: Content of: <pre>
en: [!c|java|scala]if (rainy()) { 
        takeUmbrella();
    } else if (hotDay()) {
        takeWater();
    } else if (todayIsJuly4th()) {
        takeFlag();
    }[/!][!python]if rainy():
        takeUmbrella()
    elif hotDay():
        takeWater()
    elif todayIsJuly4th():
        takeFlag()[/!]
fr: [!c|java|scala]if (ilPleut()) { 
        prendreParapluie();
    } else if (ilFaitChaud()) {
        prendreDeLEau();
    } else if (sommes14Juillet()) {
        prendreDrapeau();
    }[/!][!python]if ilPleut():
        prendreDrapeau()
    elif ilFaitChaud():
        prendreDeLEau()
    elif sommes14Juillet():
        prendreDrapeau()[/!]

note: type: Content of: <h3>
en: Graffiti in the Buggle World
fr: Les graffitis dans le monde des buggles

note: type: Content of: <p>
en: Buggles can tag graffitis on the ground of their world. For that, they use the four following methods:
fr: Les buggles peuvent écrire des choses par terre dans leur monde. Pour ce faire, elles utilisent les quatre méthodes suivantes:

note: type: Content of: <ul><li>
en: <code>[!c]int[/!][!java]boolean[/!] isOverMessage()[!scala]:Boolean[/!]</code>: returns <code>[!c]1[/!][!java|scala]true[/!][!python]True[/!]</code> if and only if there is a message on the ground.
fr: <code>[!c]int[/!][!java]boolean[/!] estSurMessage()[!scala]:Boolean[/!]</code>: renvoie <code>[!c]1[/!][!java|scala]true[/!][!python]True[/!]</code> si et seulement s'il y a un message écrit par terre.

note: type: Content of: <ul><li>
en: <code>[!c]char*[/!][!java]String[/!] readMessage()[!scala]: String[/!]</code>: returns the message written on the ground (or an empty string if nothing is written).
fr: <code>[!c]char*[/!][!java]String [/!]litMessage()[!scala]: String[/!]</code> : renvoie le message qu'il y a écrit par terre (s'il y a rien, on obtient une chaîne vide).

note: type: Content of: <ul><li>
en: <code>[!java|c]void[/!] writeMessage([!c]char*[/!][!java]String [/!]msg[!scala]: String[/!])</code>: writes the specified message down on the ground. If there is already a message on the ground, the new content is added at the end of the existing message.
fr: <code>[!java|c]void[/!] ecritMessage([!c]char*[/!][!java]String [/!]msg[!scala]: String[/!])</code> : écrit le message spécifié en argument par terre. S'il y a déjà quelque chose écrit par terre, on ajoute le nouveau message à la fin du précédent.

note: type: Content of: <ul><li>
en: <code>[!java|c]void [/!]clearMessage()</code>: clears what is written on the ground.
fr: <code>[!java|c]void [/!]clearMessage()</code> : efface ce qui est écrit par terre.

note: type: Content of: outside any tag (error?)
en: The goal is then to organize a BDR game between the buggles by teaching them to move according to the instructions written on the ground. These instructions are messages written on the ground, with the following signification:
fr: L'objectif est donc d'organiser une partie de BDR entre les buggles en leur apprenant à bouger en fonction des indications écrites par terre.  Ces indications sont des messages au sol, avec le code suivant:

note: type: Content of: <table><tr><td>
en: Message
fr: Indication

note: type: Content of: <table><tr><td>
en: What to do
fr: Quoi faire

note: type: Content of: <table><tr><td>
en: Mnemonic
fr: Mnémotechnique

note: type: Content of: <table><tr><td>
en: Turn right and move one step forward
fr: Tourner à droite et avancer d'une case

note: type: Content of: <table><tr><td>
en: Right
fr: Right (signifie «droite» en anglais)

note: type: Content of: <table><tr><td>
en: Turn left and move one step forward
fr: Tourner à gauche et avancer d'une case

note: type: Content of: <table><tr><td>
en: Left
fr: Left (signifie «gauche» en anglais)

note: type: Content of: <table><tr><td>
en: Turn back (U-turn) and move one step forward
fr: Se retourner (demi-tour) et avancer d'une case

note: type: Content of: <table><tr><td>
en: Move one step forward
fr: Avancer d'une case

note: type: Content of: <table><tr><td>
en: First letter of the alphabet
fr: Première lettre de l'alphabet

note: type: Content of: <table><tr><td>
en: Move two steps forward
fr: Avancer de deux cases

note: type: Content of: <table><tr><td>
en: Second letter of the alphabet
fr: Deuxième lettre de l'alphabet

note: type: Content of: <table><tr><td>
en: Move three steps forward
fr: Avancer de trois cases

note: type: Content of: <table><tr><td>
en: Third letter of the alphabet
fr: Troisième lettre de l'alphabet

note: type: Content of: <table><tr><td>
en: Move one step backward
fr: Reculer d'une case

note: type: Content of: <table><tr><td>
en: One letter before the end of the alphabet
fr: A une lettre de la fin de l'alphabet

note: type: Content of: <table><tr><td>
en: Move two steps backward
fr: Reculer de deux cases

note: type: Content of: <table><tr><td>
en: Two letters before the end of the alphabet
fr: A deux lettres de la fin de l'alphabet

note: type: Content of: <table><tr><td>
en: Move three steps backward
fr: Reculer de trois cases

note: type: Content of: <table><tr><td>
en: Three letters before the end of the alphabet
fr: A trois lettres de la fin de l'alphabet

note: type: Content of: <table><tr><td>
en: <i>(anything else)</i>
fr: <i>(n'importe quoi d'autre)</i>

note: type: Content of: <table><tr><td>
en: Stop dancing.
fr: Arrêter de danser.

note: type: Content of: outside any tag (error?)
en: This exercise may seem a bit complex at the first glance, but it comes down to summarizing the information of the table in a sequence of conditionals.
fr: Cet exercice peut sembler un peu compliqué, mais il s'agit principalement de traduire le contenu du tableau ci-dessus dans un enchaînement de conditionnelles.

note: type: Content of: <p>
en: You have to keep dancing as long as there is some dancing steps to do, i.e., as long as we are in a cell which content is described in the table.  The easier for that is to use a boolean variable (<code>finished</code>)  as termination condition to a <code>while</code> loop.  It should be initialized to <code>[!c]0[/!][!java|scala]false[/!][!python]False[/!]</code>, and switched to <code>[!c]1[/!][!java|scala]true[/!][!python]True[/!]</code> as soon as the buggle find a cell with a value not described in the table.  Thus, the loop will stop and the program will terminate.
fr: Vous devez continuer à danser tant qu'il reste des pas de danse à faire. c-à-d tant qu'on est sur une case décrite dans le tableau. Le plus simple pour cela est d'utiliser une variable booléenne (<code>fini</code>) en condition d'arrêt d'une boucle while. Cette variable est initialisée à la valeur faux (<code>[!c]0[/!][!java|scala]false[/!][!python]False[/!]</code>). Si on trouve une case ne répondant à aucune ligne du tableau, on change la valeur de cette variable à vrai (<code>[!c]1[/!][!java|scala]true[/!][!python]True[/!]</code>). Cela arrête la boucle, et le programme.

note: type: Content of: <p>
en: Another subtlety is that detecting if strings are equals is a bit annoying in [!thelang].  So, we use the <code>char getIndication[!c]Bdr[/!]()</code> instead of <code>[!java]String[/!][!c]char*[/!] readMessage()</code>.  This method, only known by the buggles of this exercise, returns the first char of the message written on the ground (or ' ' -- the space char -- if nothing is written down). It enables to work with chars instead of strings, that is much simpler in [!thelang].
fr: Une autre subtilité est qu'il est un peu pénible en Java de déterminer si deux chaînes de caractères sont identiques. Nous utiliserons donc la méthode <code>char getIndication[!c]Bdr[/!]()</code> à la place de <code>[!java]String[/!][!c]char*[/!] litMessage()</code>. Cette méthode, qui n'est connue que des buggles des exercices BDR, renvoie le premier caractère du message au sol (ou ' ' --une espace-- s'il n'y a rien d'écrit au sol). Cela nous permet de travailler avec des caractères (<code>char</code>), qui sont moins pénibles que les chaînes en [!thelang].

note: type: Content of: <h3>
en: Tips and Hints
fr: Trucs et astuces

note: type: Content of: outside any tag (error?)
en: If you fail to understand why the buggle does not execute the expected steps, try adding <code>brushDown()</code> in your method. This asks the buggle to put down a brush leaving a trail when it moves. It should help you understanding its trajectory, but do not forget to remove this call when you want to test whether your code is a valid solution to the exercise: you are asked to let the buggle dance, not to vandalize the dance floor.
fr: Si vous ne parvenez plus à comprendre pourquoi votre buggle n'exécute pas les pas de danse demandés, essayez d'ajouter <code>baisseBrosse()</code> dans votre méthode. Cela demandera à la buggle de poser une brosse par terre, laissant une trace au sol quand elle avance. Cela devrait vous aider à suivre sa trajectoire, mais pensez à retirer cette appel lorsque vous voulez tester si votre solution marche : on vous demande de faire danser les buggles, pas de dégrader le dance floor.

note: type: Content of: <p>
en: When your program finally works, move on to the next exercise.
fr: Quand votre programme fonctionne enfin, passez à l'exercice suivant.

note: type: Content of: <p>
en: BDR is cool, but it's a bit chaotic. First, the buggles giggle in any directions, and then the code you had to write to let them move is rather difficult to read. Here is a new BDR world where the buggle will dance a gentle circle. We will benefit this tranquillity to clean up a bit our code thanks to the new constructs we will introduce.
fr: Le BDR, c'est cool, mais c'est un peu le chaos. Tout d'abord, les buggles gigotent en tout sens, et en plus, le code que vous avez écrit pour les faire bouger est très difficile à lire. Voici un nouveau monde de BDR, où les buggles vont faire une gentille petite ronde plus reposante. Nous profiterons de cette accalmie pour nettoyer un peu le code grâce aux nouveaux éléments que nous allons maintenant étudier.

note: type: Content of: <h3>
en: [!java|c]<code>switch</code> conditionals[/!][!scala]Pattern matching[/!]
fr: [!java|c]Conditionnelle <code>switch</code>[/!][!scala]Les filtrages[/!]

note: type: Content of: <p>
en: The hardest part of previous code is certainly the conditional cascading. Somewhere in your code, you certainly had something similar to:
fr: Le plus difficile à lire du code précédent est certainement la cascade de conditionnelles. Quelque part dans votre programme, vous avez sans doute écrit quelque chose comme:

note: type: Content of: <pre>
en: if ([!java|c]getIndication() == 'R'[/!][!scala]readMessage() == "R"[/!]) {
      right();
      [!c]stepForward()[/!][!java|scala]forward()[/!];
    } else if ([!java|c]getIndication() == 'L'[/!][!scala]readMessage() == "L"[/!]) {
      left();
      [!c]stepForward()[/!][!java|scala]forward()[/!];
    } else if ([!java|c]getIndication() == 'I'[/!][!scala]readMessage() == "I"[/!]) {
      back();
      [!c]stepForward()[/!][!java|scala]forward()[/!];
    <span class="comment">/* other else if */</span>
    } else {
      finished = [!c]1[/!][!java|scala]true[/!];
    }
fr: if ([!java|c]getIndication() == 'R'[/!][!scala]litMessage() == "R"[/!]) {
      droite();
      avance();
    } else if ([!java|c]getIndication() == 'L'[/!][!scala]litMessage() == "L"[/!]) {
      gauche();
      avance();
    } else if ([!java|c]getIndication() == 'I'[/!][!scala]litMessage() == "I"[/!]) {
      retourne();
      avance();
    <span class="comment">/* d'autre if */</span>
    } else {
      fini = true;
    }

note: type: Content of: <p>
en: When you review this code, it may not be clear at the first glance that it is simply a choice with 4 branches depending on the value of [!java|c]getIndication()[/!][!scala]readMessage()[/!].  To improve this, we will use a [!java|c]<code>switch</code> construct, which Java syntax is the following:[/!] [!scala] pattern matching, which is a very powerful construct that greatly generalizes the <code>if</code>. It is arguably one of the major advantages of Scala when compared to languages such as Java or python.  It is not new either, as other languages such as OCaml or Haskell offer this feature since long, but still.  It's really cool![/!]
fr: À la première lecture du code, il n'est pas évident qu'il ne s'agit que d'un choix avec 4 branches en fonction du résultat de [!java]getIndication()[/!][!scala]litMessage()[/!].
    Pour améliorer ceci, nous allons utiliser [!java]un <code>switch</code>, dont la syntaxe est la suivante en Java.[/!]
    [!scala] un filtrage (pattern matching en anglais), qui est une construction très agréable généralisant le <code>if</code>. Il s'agit sans aucun doute de l'un des avantages majeurs du langage Scala par rapport à d'autres tels que le Java ou le Python. Cette construction n'est cependant pas révolutionnaire puisqu'elle existe depuis assez longtemps dans des langages comme OCaml ou Haskell, mais il n'empêche. Elle est carrément cool![/!]

note: type: Content of: <pre>
en: switch (<b>expression</b>) {
      case <b>firstValue</b>: 
        <b>whatToDoIfExpressionEqualsFirstValue();</b>
        break;
      case <b>secondValue</b>: 
        <b>whatToDoIfExpressionEqualsSecondValue();</b>
        break;
      case <b>thirdValue</b>: 
        <b>whatToDoIfExpressionEqualsThirdValue();</b>
        break;
        /* as much similar cases as you want */
      default: 
        <b>whatToDoIfExpressionDoesNotEqualsAnySeenValues();</b>
    }
fr: switch (<b>expression</b>) {
      case <b>premierValeur</b>: 
        <b>queFaireSiExpressionVautPremiereValeur();</b>
        break;
      case <b>deuxiemeValeur</b>: 
        <b>queFaireSiExpressionVautDeuxiemeValeur();</b>
        break;
      case <b>troisiemeValeur</b>: 
        <b>queFaireSiExpressionVautTroisiemeValeur();</b>
        break;
        /* autant de cas sur le même modèle qu'on le souhaite */
      default: 
        <b>queFaireSiExpressionVautAucuneDesValeursProposees();</b>
    }

note: type: Content of: <p>
en: Observe that each branch of a <tt>switch</tt> must be ended by a <code>break</code>. If you forget this, the machine keeps going and execute the next branch in the list after the branch it jumped to. There is even some <b>rare</b> cases where this behavior reveals helpful.
fr: Remarquez que chaque branche du <tt>switch</tt> doit être terminée par un <code>break</code>. Si on l'oublie, la machine continue d'exécuter le cas suivant dans la liste quand elle a fini le code du cas où elle a sauté dans le switch. Il y a même quelques <b>très rares</b> cas où ce comportement est pratique.

note: type: Content of: <p>
en: It is then possible to rewrite previous BDR code in a cleaner way using the <tt>switch</tt> construct:
fr: On peut réécrire le code BDR précédent bien plus clairement grâce à la construction <tt>switch</tt> de la façon suivante.

note: type: Content of: <pre>
en: switch (getIndication()) {
      case 'R':
        right(); 
        [!c]stepForward()[/!][!java]forward()[/!]; 
        break;
      case 'L':
        left();
        [!c]stepForward()[/!][!java]forward()[/!]; 
        break;
      case 'I':
        back();
        [!c]stepForward()[/!][!java]forward()[/!];
        break;
      default: 
        return;
    }
fr: switch (getIndication()) {
      case 'R':
        droite(); 
        [!c]avancePas()[/!][!java]avance()[/!]; 
        break;
      case 'L':
        gauche();
        [!c]avancePas()[/!][!java]avance()[/!]; 
        break;
      case 'I':
        retourne();
        [!c]avancePas()[/!][!java]avance()[/!];
        break;
      default: 
        return;
    }

note: type: Content of: <pre>
en: <i>expression</i> <b>match</b> {
      <b>case</b> <i>possible value</i> <b>=></b> instructions
      <b>case</b> <i>other value</i>     <b>=></b> other instructions
      <b>case</b> <i>another value</i> <b>=></b> yet another instructions
      <b>case _                 =></b> default instructions
    }
fr: <i>expression</i> <b>match</b> {
      <b>case</b> <i>valeur possible</i>  <b>=></b> instructions
      <b>case</b> <i>autre valeur</i>     <b>=></b> d'autres instructions
      <b>case</b> <i>troisième valeur</i> <b>=></b> encore d'autres instructions
      <b>case _                 =></b> instructions par défaut
    }

note: type: Content of: <p>
en: The expression provided before the keyword <code>match</code>, and then the branches are evaluated one after the other until we find one which value provided between <code>case</code> and <code>=&gt</code> is equal to the expression's value.  The <code>_</code> symbol acts as a wildcard, so the <code>_</code> branch <i>always</i> matches.  Here is an example where a variable <code>name</code> is matched.
fr: L'expression fournie avant le mot-clé <code>match</code> est évaluée, et ensuite, les branches sont évaluées les unes après les autres jusqu'à en trouver une où la valeur entre le <code>case</code> et le <code>=&gt;</code> correspond à la valeur de l'expression. Le symbole <code>_</code> agit comme un joker qui correspond à tout. Cela veut dire que la dernière ligne telle qu'elle est écrite correspond toujours à la valeur fournie, quelle qu'elle soit. Voici un petit exemple où une variable <code>nom</code> est mis en correspondance.

note: type: Content of: <pre>
en: name match {
      case "Martin" => println("Hello Martin, how are you?")
      case "Gerald" => println("Hey Gerald! How are you doing?")
      case _            => println("Welcome stranger.")
    }
fr: nom match {
      case "Martin" => println("Salut Martin, comment vas-tu?")
      case "Gerald" => println("He Gerald! Ça va?")
      case _            => println("Bonjour, étranger.")
    }

note: type: Content of: <p>
en: It is possible to have more than one instruction per branch, and merge branches when the values are separated by a | symbol.
fr: Il est aussi possible d'avoir plusieurs instructions par branches, et même d'avoir plusieurs valeurs sur une branche donnée, séparées par le caractère <code>|</code>.

note: type: Content of: <pre>
en: name match {
      case "Martin" | "Gerald" => println("Hello "+name+", how are you?"); openTheDoor()
      case _                            => println("Hello stranger. Please do not pass."); lockTheDoor()
    }
fr: nom match {
      case "Martin" | "Gerald" => println("Bonjour "+nom+", entre."); ouvreLaPorte()
      case _                            => println("Bonjour étranger. Passe ton chemin sans entrer."); fermeLaPorte()
    }

note: type: Content of: <p>
en: You can even add guards to your branches. These are extra conditions that must be respected for the branch to get applied. This is handy if you want match on value ranges, as follows.
fr: Il est même possible d'ajouter des gardes à vos branches. Il s'agit de conditions supplémentaires qui doivent être respectées pour que la branche soit appliquée. C'est par exemple pratique pour faire du filtrage sur un ensemble de valeurs.

note: type: Content of: <pre>
en: age match {
      case i if i&lt;10 => println("Hey kid!")
      case i if i&lt;20 => println("Hey dude!")
      case i if i&lt;30 => println("Hello young man")
      case _           => println("Hello Sir")
    }
fr: age match {
      case i if i&lt;10 => println("Salut gamin!")
      case i if i&lt;20 => println("Salut mec")
      case i if i&lt;30 => println("Bonjour jeune homme")
      case _           => println("Bonjour monsieur")
    }

note: type: Content of: <p>
en: Note that there is no need to check whether the value is higher than 10 on the second line because the first matching branch is used. So, if the second branch gets evaluated, then the first one did not match.
fr: Remarquez qu'il n'est pas nécessaire de vérifier à la seconde ligne que la valeur est supérieure à 10 puisque les lignes sont considérées dans l'ordre. Si la seconde ligne est considérée, c'est que la première ne correspondait pas.

note: type: Content of: <p>
en: Finally, it is possible also to match several variables in one shoot!
fr: Enfin, il est même possible de filtrer sur plusieurs variables à la fois!

note: type: Content of: <pre>
en: (x,y) match {
     case (0,0) => println("that's the origin")
     case (_,0) => println("On the ordinate")
     case (0,_) => println("On the abscissa")
     case (_,_) => println("Some random point")
    }
fr: (x,y) match {
     case (0,0) => println("C'est le point origine")
     case (_,0) => println("C'est un point de l'ordonnée")
     case (0,_) => println("C'est un point de l'abscisse")
     case (_,_) => println("C'est un point quelconque")
    }

note: type: Content of: <p>
en: I told you that scala's pattern matching is very powerful! I actually love this feature!
fr: Je vous avais bien dit que le filtrage scala était une construction surpuissante ! Je l'adore !

note: type: Content of: <p>
en: [!java|scala|c]Apply the improvement we just saw to rewrite your buggle code with the following dance steps. [/!] [!python]Let's teach a new dance step to the buggles. It is slightly more complex but actually better looking. Beside of that, that's the same old story.[/!] Note that we can now move up to 6 cells in one dance step.
fr: [!java|scala|c]Appliquez les améliorations que nous venons de voir pour adapter le code de votre buggle au nouveau pas de danse explicité ci-dessous.[/!] 
    [!python]Nous allons maintenant apprendre un nouveau pas de danse à nos buggles. Il est un peu plus complexe, mais sinon, c'est toujours la même histoire.[/!] 
    Remarquez qu'il est maintenant possible d'avancer jusqu'à 6 cases à la fois.

note: type: Content of: <table><tr><td>
en: Turn back and move one step forward
fr: Se retourner (faire demi-tour) et avancer d'une case

note: type: Content of: <table><tr><td>
en: Move four cells forward
fr: Avancer de quatre cases

note: type: Content of: <table><tr><td>
en: Move five cells forward
fr: Avancer de cinq cases

note: type: Content of: <table><tr><td>
en: Move six cells forward
fr: Avancer de six cases

note: type: Content of: <table><tr><td>
en: Move four cells backward
fr: Reculer de quatre cases

note: type: Content of: <table><tr><td>
en: Move five cells backward
fr: Reculer de cinq cases

note: type: Content of: <table><tr><td>
en: Move six cells backward
fr: Reculer de six cases

note: type: Content of: <p>
en: When you program works again, proceed to next exercise.
fr: Quand votre programme fonctionne de nouveau, passez à l'exercice suivant.

note: type: Content of: <p>
en: We will now teach the buggle to explore its world. Its initial position is the bottom left corner, and it should visit any cells up to the top (coloring the ground on its path. The main loop of your code is something like:
fr: Nous allons maintenant apprendre à la buggle à explorer son monde. Sa position de départ est en bas à gauche, et elle doit visiter toutes les cases jusqu'en haut (en coloriant le sol sur son passage).  La boucle principale de votre code doit être de la forme :

note: type: Content of: <pre>
en:  move brush down
     while we did not reach the final position
       move like a snake
fr:  baisser le crayon
     tant que l'on est pas à la position finale
       avancer comme un serpent

note: type: Content of: <p>
en: We thus have to write two specific methods: The first one returns a boolean indicating whether we are on a final position while the second moves one snake step forward.
fr: Il faut donc écrire deux méthodes spécifiques. L'une renvoie un booléen indiquant si l'on se trouve à la position finale, tandis que l'autre avance d'un pas de serpent.

note: type: Content of: <p>
en: We reached the final position if and only if both conditions are true:
fr: On se trouve sur une position finale si et seulement si les deux conditions suivantes sont vraies.:

note: type: Content of: <ul><li>
en: We are facing a wall
fr: On est face à un mur

note: type: Content of: <ul><li>
en: There is a wall on the north of the buggle. So, if the buggle is facing east, you should check whether there is a wall on the left, and if the buggle is facing west, you should check on the right side.
fr: Il y a un mur au nord de la buggle. Donc, si la buggle regarde à l'est, il faut vérifier s'il y a un mur à gauche, et si la buggle regarde à l'ouest, il faut vérifier s'il y a un mur à droite.

note: type: Content of: <ul><li>
en: We can get the current heading of the buggle using the <code>getDirection()</code>, and we know whether it looks east using <code>getDirection() == [!scala|python|java]Direction.[/!]EAST</code> (WEST for west).
fr: On obtient la direction actuelle de la buggle avec la méthode <code>getDirection()</code>, et on sait si elle regarde à l'est avec le test <code>getDirection() == [!scala|python|java]Direction.[/!]EST</code> (ou bien OUEST).

note: type: Content of: <ul><li>
en: To check, nothing magical: you have to turn the buggle and check whether it is facing a wall afterward.
fr: Pour la vérification elle-même, rien de magique : il faut se tourner et regarder si on est face à un mur une fois tourné.

note: type: Content of: <p>
en: Then, a snake step can be achieved by moving one step forward if we are not facing a wall, and moving to the upper line else (i.e., if you look to the west facing a wall, you have to turn right, forward and turn right).
fr: Ensuite un pas de serpent se fait en avançant d'un pas si l'on est pas face à un mur, et en montant à la ligne du dessus sinon (dit autrement, si on regarde à l'ouest face à un mur, il faut tourner à droite, avancer, tourner à droite).

note: type: Content of: <p>
en: Hint: the main loop of your code must continue while the testing function returns false. There is two ways of writing it:
fr: Indication: la boucle principale de votre code doit continuer tant que la fonction adéquate renvoie faux. On peut l'écrire de deux façons:

note: type: Content of: <pre>
en: while (testingFunction() == [!c]0) {[/!][!java|scala]false) {[/!][!python]False):[/!]
fr: while (fonctionTest() == [!c]0) {[/!][!java|scala]false) {[/!][!python]False):[/!]

note: type: Content of: <p>
en: [!python]You may prefer to write it as:[/!] [!java|scala|c]Since the exclamation mark (!) denotes the boolean negation in [!thelang], you may write it as:[/!]
fr: [!python]Vous pouvez préférer l'écrire ainsi:[/!] 
    [!java|scala|c]Comme le point d'exclamation (!) dénote la négation booléenne en [!thelang], vous pouvez aussi l'écrire:[/!]

note: type: Content of: <pre>
en: while ([!java|scala|c]![/!][!python]not [/!]testingFunction())[!java|scala|c] {[/!][!python]:[/!]
fr: while ([!java|scala|c]![/!][!python]not [/!]fonctionTest())[!java|scala|c] {[/!][!python]:[/!]

note: type: Content of: <p>
en: The goal of this serie of exercises is to let the buggle traverse its world. It must number the cells it walks on to show its traversal order.
fr: L'objectif de cette série d'exercices est de faire parcourir le monde à la buggle.  Elle doit de plus numéroter les différentes cases rencontrées pour montrer son ordre de parcours.

note: type: Content of: <p>
en: The main loop of your code should be something like:
fr: La boucle principale du code que vous devez écrire est de la forme :

note: type: Content of: <pre>
en:  while we are not on the final position
       go to the next position
       label the cell with its number
fr:  tant que l'on n'est pas à la position finale
       aller à la prochaine position
       marquer le numéro de case au sol

note: type: Content of: <p>
en: In contrary to the exercises we saw so far, we won't use the <code>forward()</code>, <code>backward()</code> and similar methods. Instead, we will compute the coordinate of the next buggle position and use the <code>setPos(x, y)</code> method to <i>teleport</i> the buggle directly to this position. For example, <code>setPos(3, 5)</code> teleports the buggle to the cell where x=3 and y=5.
fr: À la différence des exercices vus jusque là, nous n'allons pas utiliser les méthodes <code>avance()</code>, <code>recule()</code> et autres, mais nous allons calculer les coordonnées de la prochaine position de la buggle, et utiliser la méthode <code>setPos(x, y)</code> pour <i>téléporter</i> la buggle directement à cette position. Par exemple, <code>setPos(3, 5)</code> téléporte la buggle sur la case où x=3 et y=5.

note: type: Content of: <p>
en: Your first task is thus to write a boolean function indicating whether the buggle reached the final position or not, ie if it reached the bottom right corner of the world. For this, you can use <code>getWorldWidth()</code> and <code>getWorldHeight()</code> which return respectively the world's width and height. Your test is about comparing the buggle's current position (that you can access with <code>getX()</code> and <code>getY()</code>) to the world dimensions.
fr: Le premier objectif est donc d'écrire une fonction booléenne indiquant si la buggle a atteint la position finale ou non, càd si elle est arrivée en bas à droite du monde.  Vous utiliserez pour cela les méthodes <code>getMondeHauteur()</code> et <code>getMondeLargeur()</code> qui retournent respectivement la hauteur et la largeur du monde.  Votre test est de comparer les coordonnées actuelles de votre buggle (que vous pouvez retrouver avec les méthodes <code>getX()</code> et <code>getY()</code>) aux dimensions du monde.

note: type: Content of: <p>
en: Beware, the first line and column are numbered 0 and not 1, and the point (0,0)  is on the top left corner. This may seem surprising, but it is very often so in Computer Science.
fr: Attention, la première ligne et la première colonne sont numérotées 0 au lieu de 1, et l'origine (0, 0) est dans le coin en haut à gauche. Cela peut sembler étonnant, mais ces choses sont traditionnelles en informatique.

note: type: Content of: <p>
en: Then, you have to write the code to reach the next position. In this exercise, you have to traverse the world row after row. So, if you are at the bottom of a row, you have to move to the top of next row. Else, you have to move to the cell below.
fr: Ensuite, il faut écrire le code pour aller à la position suivante. Dans cet exercice, il faut parcourir le monde colonne par colonne. Donc, si on est tout en bas d'une colonne, il faut aller en haut de la colonne suivante. Sinon, il faut aller à la case du dessous.

note: type: Content of: <p>
en: At this point, you can launch your program to check that the buggle correctly traverse the world in the expected order, and that it stops when it has to. Use the <b>stop</b> button if the buggle does not stop correctly.
fr: À ce point, vous pouvez lancer votre programme pour vérifier que la buggle parcours bien le monde dans l'ordre souhaité, et s'arrête bien quand il faut. Pensez à utiliser le bouton <b>stop</b> pour arrêter l'exécution si votre programme ne se termine pas correctement.

note: type: Content of: <p>
en: It is now time to write down the cell numbers. For that, you will need a counter initialiser to zero at the beginning of your code, and incremented by one at each step (for example with <code>counter += 1;</code>).  Then, you have to use <code>writeMessage()</code> to write the value on the ground.
fr: Il est temps d'écrire au sol les numéros de case. Pour cela, vous aurez besoin d'un compteur initialisé à zéro au début de votre code, et incrémenté à chaque pas (par exemple avec <code>cpt += 1;</code>). Ensuite, il faut écrire cette valeur au sol (avec <code>ecritMessage()</code>).

note: type: Content of: <p>
en: You probably need to write the first [!java|scala|c]or last [/!]value out of the main loop [!java|scala|c], depending on whether you prefer to use a <code>while</code> or a <code>do/while</code> one[/!].
fr: Il est sans doute nécessaire d'écrire la valeur de la première[!java|scala|c] ou dernière[/!] case en dehors de la boucle principale[!java|scala|c], selon que vous utilisez une boucle <code>while</code> ou <code>do/while</code>[/!].

note: type: Content of: outside any tag (error?)
en: You once again have to let the buggle traverse the world numbering the cells on its way, but the goal of this exercise is to write a line traversal. Most of the code you wrote for previous exercise remains usable here. Simply, the method computing the coordinates of the next buggle position has to be correctly updated: if you are at the right of a line, you have to go to the beginning of the next one. If not, you have to go to the right cell.
fr: Il faut encore faire parcourir le monde à la buggle en numérotant les cases au passage, mais l'objectif de cet exercice est d'écrire un parcours ligne par ligne. La plupart du code écrit à l'exercice précédent reste utilisable, mais la méthode calculant les prochaines coordonnées de la buggle doit être modifiée en conséquence : si l'on est tout à droite d'une ligne, il faut aller au début de la ligne précédente. Si non, il faut aller sur la case à droite.

note: type: Content of: <p>
en: This time, you are asked to traverse the world one diagonal after the other. Have a look at the objective world for more details on the requested traversal order.
fr: Cette fois, il faut parcourir le monde en diagonale. Regardez le monde objectif pour voir les détails de l'ordre de parcours demandé.

note: type: Content of: <p>
en: You may find useful to use an integer variable <code>diag</code> storing the number of the diagonal you are traversing.
fr: Il vous est recommandé d'utiliser une variable entière <code>diag</code> conservant le numéro de la diagonale que la buggle est en train de parcourir.

note: type: Content of: outside any tag (error?)
en: This time, you have to zigzag on the way up. Have a look at the objective world for more details on the requested traversal order.
fr: Cette fois, il faut parcourir le monde en zig-zag. Regardez le monde objectif pour voir les détails de l'ordre de parcours demandé.

note: type: Content of: <h2>
en: Lost in the Moria
fr: Perdu dans la Moria

note: type: Content of: <p>
en: You buggles got stuck in the mines of Moria! Some rocks are blocking the exit, and you will have to clear your way to the exit. Well of course these are only baggles and you could simply walk away, but it will be easier to program the buggles so that they move those "rocks" than convincing them to walk away without solving the problem. Dwarfs are sometimes really stubborns...
fr: Vos buggles sont coincées dans la mine de la Moria ! Des rochers bloquent la sortie, et il va falloir dégager le chemin pour passer. Bon, ok, ce ne sont pas vraiment des rochers mais juste des biscuits, et vos buggles pourraient facilement passer au dessus sans se fatiguer. Mais il est probablement plus simple de programmer vos buggles pour qu'elles déplacent ces «rochers» plutôt que de tenter de les convaincre de passer à la suite sans avoir résolu le problème. Les nains sont souvent un peu têtus...

note: type: Content of: <p>
en: So, you have to find the first baggle blocking the exit (simply walk to the east until you are over a baggle), take it and move it back to the other side of the tunnel (walk to the west while you are not over a baggle, and then move back one step to the east and drop your baggle), and iterate until you find the exit (that is, the wall to the east side). Afterward, move out as in the objective world. That's only a few more steps away.
fr: Donc, il vous faut trouver le premier biscuit en travers de votre chemin (marchez vers l'est jusqu'à vous trouver au dessus d'un biscuit), le ramasser, et retourner à l'autre extrémité du couloir pour le déposer (marchez vers l'ouest jusqu'à vous trouver au dessus d'un biscuit puis reculez d'un pas). Il faut ensuite faire de même pour tous les biscuits jusqu'à trouver la sortie. Une fois ceci fait, marchez vers l'air frais comme dans le monde objectif, cela ne sera plus qu'à quelques pas de là.

note: type: Content of: <p>
en: To make things worse, you have to write a program that works for every buggle, even if writing a specific program for each of them would be easier. It seems that using <code>while</code> loops is the only solution to move the buggles correctly.
fr: Pour compliquer encore les choses, vous devez écrire un programme qui fonctionne pour toutes les buggles, même si écrire un programme spécifique à chacune serait peut-être un peu plus simple. Il semblerait qu'utiliser une boucle <code>while</code> soit la seule solution pour déplacer vos buggles correctement.

note: type: Content of: <p>
en: Once you manage to escape this trap, you can move forward to the next exercise.  This exercise is a bit more complex, so you can also leave it for now and come back later if you don't get it right now.
fr: Quand vous serez parvenu à sortir de ce piège, vous pouvez passez à l'exercice suivant. Cet exercice est un peu plus difficile que les autres, et vous pouvez tout à fait le laisser momentanément de coté pour y revenir plus tard si vous n'y parvenez pas pour l'instant.

note: type: Content of: <h3>
en: The turmites
fr: Les turmites

note: type: Content of: <p>
en: This set of activities lets you play with Langton's ants, that are 2D turing machines. They constitute very simple application problems, achievable by beginners, and open the door to an amazing world.
fr: Cet ensemble d'activités vous permet de jouer avec les fourmis de Langton, qui sont des machines de Turing à deux dimensions. Il s'agit d'exercices d'application très simple, à la portée de débutants, mais ils ouvrent la porte sur un univers fascinant.

note: type: Content of: <p>
en: This mechanism were invented in 1986 by Chris Langton, and later generalized in several ways (as we shall see in the next exercises). It was proven that Turmites and Turing machines are of equal power: An ant's trajectory can be used to compute any boolean circuit, and thus that an ant is capable of universal computation. Put simply, any possible computation can be achieved using a turmite as a computing device. Yet another subject of fascination...
fr: Ce mécanisme a été inventé en 1986 par Chris Langton, et généralisé après de plusieurs façons (comme nous le verrons dans les prochains exercices). Il a été prouvé que les turmites et les machines de Turing sont aussi puissantes les unes que les autres : une trajectoire de  fourmi peut être utilisée pour calculer n'importe quel circuit booléen, et la fourmi est donc capable de calcul universel (dit autrement, n'importe quel calcul possible peut être réalisé en utilisant la fourmi comme instrument de calcul). Encore un autre sujet de fascination...

note: type: Content of: <p>
en: Multicolor Langton's ants were discovered in 1995 by Propp et Al. Another funny fact is that the ants which name is a list of consecutive pair of identical letters (LL and RR) produce symmetric patterns. This fact was even formally proved.
fr: Les fourmis de Langton multicolores ont été découvertes en 1995 par Propp et Al. Un fait amusant est que les fourmis dont le nom est une paire de lettres identiques (LL et RR) produisent des dessins symétriques. Ce fait a même été prouvé formellement.

note: type: Content of: <p>
en: Check the corresponding wikipedia web page, of which this exercise is inspired, for further details.
fr: Consultez la page correspondante sur Wikipedia, à partir de laquelle cet exercice est inspiré, pour d'avantages de détails.

note: type: Content of: <h3>
en: What can I do to improve this PLM universe?
fr: Que puis-je faire pour améliorer cet univers de PLM?

note: type: Content of: <p>
en: As usual, there are several things that could be done in the code of this universe to improve it:
fr: Comme souvent, plusieurs points pourraient être améliorés dans le code de cet univers pour l'améliorer&nbsp;:

note: type: Content of: <ul><li>
en: We are probably missing some good exercises. The turmite creator exercise is a bit harsh: we could introduce the patterns in a more friendly manner.
fr: Il nous manque probablement quelques exercices progressifs. Celui sur la création de turmites est particulièrement aride. Nous devrions probablement introduire les motifs de façon plus pédagogique.

note: type: Content of: <ul><li>
en: We may want to write an exercise on the busy beaver, maybe?
fr: Il serait peut-être amusant d'introduire un exercice sur les castors occupés (busy beavers)?

note: type: Content of: <p>
en: Discover the Langton's ants, that are 2D turing machines.
fr: Découvrez les fourmis de Langton, qui sont des machines de Turing à deux dimensions.

note: type: Content of: <p>
en: These activities are very simple application problems, achievable by beginners, and open the door to an amazing world.
fr: Ces activités sont très simples, à la portée de débutants, et elles ouvrent la porte sur un univers fascinant.

note: type: Content of: <h2>
en: Langton's ant
fr: La fourmi de Langton

note: type: Content of: <p>
en: In this exercise, you will turn your buggle into a <i>Langton's ant</i>. These artificial little animals are very interesting because they are given simple rules that depend only on their local environment, and after a period of apparent chaotic behavior, a general pattern <i>emerges</i>.
fr: Dans cet exercice, vous aller métamorphoser votre buggle en une <i>fourmi de Langton</i>. Ces petits animaux artificiels sont très intéressants parce qu'ils suivent des règles simples qui dépendent seulement de leur environnement local, et qu'après une période d'un comportement d'apparence chaotique, un schéma général <i>apparaît</i>

note: type: Content of: <p>
en: The rules are absolutely trivial: to compute what the next step should be, you should check the current color of the ground (using <code>getGroundColor()</code>). If it's white, change it to black, turn right and move forward by one cell. If the ground is currently black, change it to white, turn left and move forward by one cell.
fr: Les règles sont absolument triviales: pour calculer quel sera le prochain pas, vous devez regarder la couleur actuelle du sol ( en utilisant <code>getCouleurSol()</code>). Si c'est blanc, changez la en noir, tournez à droite et avancez d'une case. Si la couleur du sol est le noir, changez la en blanc, tournez à gauche et avancez d'une case.

note: type: Content of: <p>
en: It's hard to come up with simpler rules isn't it? Well, let's go and code it now. You have to complete the <code>step()</code> method, which encodes the behavior of the ant at each step. You will probably use the <code>getGroundColor()</code> method to retrieve the color of the cell on which the ant is currently.  Colors of interest are simply named <code>Color.black</code> and <code>Color.white</code>.
fr: Il est difficile de trouver des règles plus simples, n'est-ce pas ? Et bien, allons-y et codons-les maintenant. Vous avez à compléter la méthode <code>step()</code>, qui définit le comportement de la fourmi à chaque pas. Vous utiliserez probablement la méthode <code>getCouleurSol()</code> pour récupérer la valeur de la case sur laquelle la fourmi se trouve. Les couleurs intéressantes sont tout simplement <code>Color.black</code> pour le noir ou <code>Color.white</code> pour le blanc.

note: type: Content of: <p>
en: To compare colors, you cannot use the equal signs (==), because these things are not scalar values but objects. Instead, you need to write something like the following:
fr: Pour comparer les couleurs, il n'est pas possible d'utiliser le double signe égal (==) parce ces choses ne sont pas des valeurs scalaires normales mais des objets. À la place, vous devez écrire quelque chose comme cela&nbsp;:

note: type: Content of: <pre>
en: Color c /* = some initialization */;
    if (c.equals(Color.black)) {
      /* that's equal */
    } else {
      /* that was not equal */
    }
fr: Color c /* = une initialisation*/;
    if (c.equals(Color.black)) {
      /* c'était égal */
    } else {
      /* ce n'était pas égal */
    }

note: type: Content of: <p>
en: Changing the ground color is not difficult, but a bit long: you have to change the brush color of your buggle, set the brush down (to mark the current cell -- with <code>brushDown()</code>), and set the brush back up (with <code>brushUp()</code>) to avoid further issues when the buggle will move. You are naturally free of organizing your code the way you want, but you may want to write a <code>setGroundColor(color)</code> method to factorize things a bit.
fr: Changer la couleur du sol n'est pas difficile, seulement un peu long : vous avez à changer la couleur de la brosse de votre buggle, l'abaisser (pour marquer la case courante -- avec <code>baisseBrosse()</code>), et relever la brosse (avec <code>leveBrosse()</code>) pour éviter des problèmes lorsque la buggle va se déplacer. Vous êtes naturellement libre d'organiser votre code comme vous le souhaitez, mais vous pouvez vouloir écrire une méthode <code>setCouleurSol(couleur)</code> pour factoriser le tout.

note: type: Content of: <p>
en: As you can see from the execution of this exercise, the interest in this algorithm is that after about 10000 steps of relative chaotic behavior, the ant start building a regular pattern. This emergence of a regular pattern from the chaos is rather fascinating, isn't it? Move on to the next exercise to see more of them.
fr: Comme vous pouvez le constater avec l'exécution de cet exercice, l'intérêt dans cet algorithme est qu'après environ 10 000 pas de comportement relativement chaotique, la fourmi commence à suivre un schéma régulier. L'émergence de ce schéma régulier à partir du chaos est réellement fascinant, n'est-ce pas ? Passez à l'exercice suivant pour en voir plus.

note: type: Content of: <h2>
en: Multicolor Langton's ant
fr: La fourmi de Langton multicolore

note: type: Content of: <p>
en: There is several ways to extend the concept of Langton's ant. In this exercise, we explore first one, using more than two colors. It remains very similar to the base case: the behavior at each step still depends on the ground color, but you have more than 2 possibilities. It allows to have more than one kind of ant, depending on what you decide to do for each color. For example, the ant LRL takes 3 colors. It turns left on the first color, right on the second one and left on the third color. According to this definition, the basic ant is a RL (since it turns right on white cells and left on black ones).
fr: Il y a plusieurs façons de changer le concept de la fourmi de Langton. Dans cet exercice, nous allons tout d'abord étudier le fait d'utiliser plus de deux couleurs. Cela reste très similaire au cas de base : le comportement à chaque pas dépendra toujours de la couleur du sol, mais vous aurez plus de deux possibilités. Cela permet d'avoir plus qu'une seule sorte de fourmi, selon ce que l'on décide de faire pour chaque couleur. Par exemple, la fourmi LRL reconnaît trois couleurs. Elle tourne à gauche sur la première, à droite sur la seconde et à gauche sur la troisième. Selon cette définition, la fourmi de base est de type RL ( puisqu'elle tourne à droite sur les cases blanches et à gauche sur les noires).

note: type: Content of: <p>
en: Some of these ants draw fascinating patterns (switch the world to see them): LLRR build a symmetric figure resembling loosely to a ball, LRRRRRLLR draws a square, LLRRRLRLRLLR draws a convoluted regular pattern after a period of seemingly chaotic behavior, and RRLLLRLLLRRR seems to fill a hour glass...
fr: Certaines de ces fourmis dessinent des schémas fascinants ( changez de monde pour les voir ):LLRR construit une figure symétrique ressemblant vaguement à une balle. LRRRRRLLR dessine un carré, LLRRRLRLRLLR dessine un schéma régulier tordu après une période ressemblant à un comportement chaotique, et RRLLLRLLLRRR semble remplir un sablier...

note: type: Content of: <p>
en: Changing your buggle into a generic Langton's ant is not very complicated, although it is not completely trivial. As previously, you have to write a <code>step</code> function. But this time, it receives two arrays as parameters.  The first one defines the rules to follow depending on the ground color while the second one gives the sequence of colors to use. For example, the basic ant would have [!java]<code>{'R', 'L'}</code> and <code>{Color.white, Color.black}</code>[/!] [!python]<code>['R', 'L']</code> and <code>[Color.white, Color.black]</code>[/!] [!scala]<code>Array('R', 'L')</code> and <code>Array(Color.white, Color.black)</code>[/!] as arguments.
fr: Métamorphoser votre buggle en une fourmi de Langton générique n'est pas très compliqué, même si ce n'est pas complètement trivial. Comme précédemment, vous avez à écrire une fonction <code>step</code>. Mais cette fois, elle reçoit deux tableaux comme paramètres. Le premier définit les règles à suivre selon la couleur du sol tandis que le deuxième donne la séquence de couleurs à utiliser. Par exemple, la fourmi de base aurait 
    [!java]<code>{'R', 'L'}</code> et <code>{Color.white, Color.black}</code>[/!]
    [!python]<code>['R', 'L']</code> et <code>[Color.white, Color.black]</code>[/!]
    [!scala]<code>Array('R', 'L')</code> et <code>Array(Color.white, Color.black)</code>[/!]
    comme arguments.

note: type: Content of: <p>
en: At each step, you thus have to apply the following pseudo-code:
fr: A chaque pas, vous avez toujours à appliquer le pseudo-code suivant :

note: type: Content of: <ul><li>
en: Find the position of the ground color in the color sequence;
fr: Trouver la position de la couleur du sol dans la séquence de couleur;

note: type: Content of: <ul><li>
en: Turn left or right depending on the content of the rule array at that position;
fr: Tourner à gauche ou à droite selon le contenu du tableau de règle à cette position;

note: type: Content of: <ul><li>
en: Mark the current ground with the next color in the sequence (the last color being followed by the first one);
fr: Marquer le sol de la case courante avec la prochaine couleur dans la séquence ( la dernière couleur est suivie par la première);

note: type: Content of: <ul><li>
en: Move forward by one step.
fr: Avancer d'un pas

note: type: Content of: <p>
en: You now should have enough information to succeed.
fr: Vous devriez maintenant avoir assez d'informations pour réussir.

note: type: Content of: <p>
en: This exercise explores a new way to extend the concept of Langton's ant. Now, the behavior of the ant not only depends on the color on the ground, but also on its internal state (represented by an integer value). The idea of changing the ant into such an automata naturally comes from the Turing machine concept. This explains the name of these new animals, which is a portemanteau of <i>Turing</i> and <i>Termite</i> (if you don't know what a Turing machine is, you should run to wikipedia, because it is simply impossible to be a real computer scientist before that).
fr: Cette exercice explore une nouvelle façon d'étendre le concept de la fourmi de Langton. Maintenant, le comportement de la fourmi ne dépend plus seulement de la couleur du sol, mais aussi de son état interne (représenté par une valeur entière). L'idée de changer la fourmi en un automate découle naturellement du concept de la machine de Turing. Ceci explique le nom de ces nouveaux animaux, qui est un mélange de <i>Turing</i> et de <i>Termite</i> (si vous ne savez pas ce qu'est une machine de Turing, vous devriez vous jeter sur Wikipedia parce qu'il est tout simplement impossible d'être un vrai informaticien sans le savoir).

note: type: Content of: <p>
en: Once again, you just have to write the <code>step()</code> method, in charge of doing one turmite's step. Once again, you should first find the rank of the current's cell ground color in the color sequence. But this time, the <code>rule</code> data depends both on the current color and the current state.  <code>rule</code> actually contains 3 information in each situation: the color to write, the move to do, and the next state value. For example, [!java|python]rule[1][0][/!][!scala]rule(1)(0)[/!] contains the informations to use when <code>state==1</code> and <code>color==0</code>.  In other worlds, you can retrieve the information relative to your current situation by using <code>[!java|python]rule[state][currentColor][/!][!scala]rule(state)(currentColor)[/!]</code>.
fr: Une fois encore, vous devez seulement écrire la méthode <code>step()</code>, qui s'occupe de faire faire un pas à la turmite. Une fois encore, vous devez tout d'abord trouver le rang de la couleur actuelle du sol dans la liste des couleurs. Mais cette fois, <code>rule</code> dépend à la fois de la couleur courante et de l'état courant. <code>rule</code> contient en fait trois informations dans chaque situation : la couleur à mettre, le mouvement à effectuer, et la valeur du prochain état. 
    Par exemple, [!java|python]rule[1][0][/!][!scala]rule(1)(0)[/!] contient l'information à utiliser quand <code>state==1</code> et <code>color==0</code>. En d'autres mots, vous pouvez récupérer l'information relative à votre situation actuelle en utilisant 
    <code>[!java|python]rule[etatCourant][couleurActuelle][/!][!scala]rule(etatCourant)(couleurActuelle)[/!]</code>

note: type: Content of: <p>
en: Each such information set contains 3 values. The first one is the rank of the color to write on the ground. The second is the move to do, with the following notation: 0=stop, 1=noturn, 2=left, 4=u-turn, 8=right. Note that if the command is stop, you shouldn't even move forward on that step (but you shouldn't stop your program either: the next steps can do something else in a future state). Finally, the third integer is the next <code>state</code> value to go into after this iteration.
fr: Chaque ensemble d'informations contient trois valeurs.
    La première est le rang de la couleur à mettre sur le sol.
    La deuxième est le mouvement à effectuer, avec la notation suivante : 0=stop, 1=pas de virage, 2=gauche, 4=demi-tour, 8=droite. Veuillez noter que si l'instruction est stop, vous ne devez même pas avancer sur cette étape (mais vous ne devez pas arrêter votre programme pour autant : les prochains pas peuvent faire quelque chose d'autre). Finalement, le troisième entier est la valeur du prochain <code>state</code> à avoir après cette itération.

note: type: Content of: <p>
en: Since these arbitrary notations are somehow difficult to remember, you should define a set of constants that you should use instead of the direct numerical values.  Their names could be NOTURN, LEFT, RIGHT and so on.  [!scala]Just declare them using the keyword <code>val</code> instead of <code>var</code>.  You should always use <code>val</code> instead of <code>var</code> when possible anyway.[/!] [!java]The modifiers <code>final static</code> before their type is the way to mark variables as constant in Java.  You should write for example <code>static final int NOTURN=1;</code> Sorry for the complexity of this notation. [/!] [!python]By convention, such constant variables are written in upper case in python.  Technically, you can still modify them, but that would be a very bad idea.[/!] You should write them out of any method so that they are globally visible.
fr: Puisque ces notations arbitraires sont parfois difficiles à mémoriser, vous devriez définir un ensemble de constantes que vous pouvez utiliser à la place des valeurs numériques. Leurs noms pourraient être GAUCHE, DROITE, etc.
    [!scala]Déclarez simplement ces valeurs avec le mot-clé <code>val</code> au lieu de <code>var</code>. De toute façon, on devrait toujours utiliser <code>val</code> au lieu de <code>var</code> quand on peut.[/!]
    [!java]Les modificateurs <code>final static</code> devant le nom du type est la façon Java de marquer des constant en Java. 
      Vous devriez écrire par exemple <code>static final int TOUTDROIT=1;</code>
      Désolé de la complexité de cette notation. [/!]
    [!python]Par convention, de telles «variables constantes» sont écrites tout en majuscule en Python.
      Rien ne vous empêche d'un point de vue technique de les modifier, mais ca serait une très mauvaise idée.[/!]
    Vous devriez les écrire en dehors de toute méthode pour les rendre visible de partout.

note: type: Content of: <p>
en: Using such constants greatly help making the code easier to read. Compare the next two code chunks:
fr: Utilisez de telles constantes aident beaucoup à rendre le code plus lisible.
    Comparez les deux morceaux de code suivant:

note: type: Content of: <pre>
en: [!java]if (rule[state][currentColor][NEXT_MOVE] == LEFT) {[/!][!python]if rule[state][currentColor][NEXT_MOVE] == LEFT:[/!][!scala]if (rule(state)(currentColor)(NEXT_MOVE) == LEFT) {[/!]
        left()[!java];[/!]
    [!java|scala]}[/!]
fr: [!java]if (rule[etat][couleurActuelle][MVT_SUIVANT] == GAUCHE) {[/!][!python]if rule[etat][couleurActuelle][MVT_SUIVANT] == GAUCHE:[/!][!scala]if (rule(etat)(couleurActuelle)(MVT_SUIVANT) == GAUCHE) {[/!]
        gauche()[!java];[/!]
    [!java|scala]}[/!]

note: type: Content of: <p>
en: This is much more easier to read (although longer) than the following:
fr: C'est un peu plus long, mais bien plus agréable à lire que ceci&nbsp;:

note: type: Content of: <pre>
en: [!java]if (rule[i][j][1] == 2) {[/!][!python]if rule[i][j][1] == 2:[/!][!scala]if (rule(i)(j)(1) == 2) {[/!]
        left()[!java];[/!]
    [!java|scala]}[/!]
fr: [!java]if (rule[i][j][1] == 2) {[/!][!python]if rule[i][j][1] == 2:[/!][!scala]if (rule(i)(j)(1) == 2) {[/!]
        gauche()[!java];[/!]
    [!java|scala]}[/!]

note: type: Content of: <p>
en: Finally, you probably want to write a <code>elif</code> branch for the <code>STOP</code> condition too. Having a <code>else</code> branch displaying an error message such as "unknown case" is a good practice: it makes your assumptions about your code more explicit, and you will get an error message if they fall short. When doing so, the next problem is that you have nothing to do in the <code>STOP</code> case, but python do not allows you to write empty <code>elif</code> branches. You should use the <code>pass</code> instruction as a placeholder: it says python that you have a branch here, and that it does not contain anything.
fr: Enfin, vous devriez également écrire une branche <code>elif</code> pour la condition <code>STOP</code>. Avoir une branche <code>else</code> qui affiche un message d'erreur tel que "situation inattendue" est une bonne pratique. Celà permet d'expliciter les présupposés du code, et assure un message d'erreur plus explicite si ces suppositions s'avèrent erronées. Le problème suivant est que nous n'avons rien à faire faire dans la branche du cas <code>STOP</code>, mais que python n'autorise pas de branche <code>else</code> vide. Il faut alors utiliser l'instruction <code>pass</code> là où il n'y a rien à faire. Cela indique à Python qu'il y a bien une branche à cet emplacement, mais qu'elle ne fait rien.

note: type: Content of: <p>
en: You should probably use a [!java]switch case[/!][!scala]pattern matching[/!] construct to keep your code readable.  If you can't remember what it is, check <a href="plm://lessons.welcome/bdr.BDR2">this exercise</a>.
fr: Vous devriez probablement utiliser un [!java]switch[/!][!scala]filtrage[/!] pour que votre code reste lisible. Si vous avez oublié ce que c'est, retournez à <a href="plm://lessons.welcome/bdr.BDR2">cet exercice</a>.

note: type: Content of: <h2>
en: Bibliographical notes
fr: Notes bibliographiques

note: type: Content of: <p>
en: According to wikipedia, turmites were invented independently by the end of the eighties. It has been shown that turmites in general are exactly equivalent in power to one-dimensional Turing machines with an infinite tape, as either can simulate the other. This means that absolutely any program that you can think of could theoretically be computed on this device...
fr: D'après Wikipedia, les turmites ont été inventés indépendamment à la fin des années 80. Il a été démontré que les turmites en général sont exactement équivalent en terme de puissance à des machines de Turing à une dimension avec un ruban infini, et peut donc simuler les autres. Cela signifie qu'absolument tous les programmes auxquels vous pouvez penser peuvent théoriquement être calculé sur cet outil.

note: type: Content of: <h2>
en: Creating Turmites
fr: Créer des Turmites

note: type: Content of: <p>
en: This exercise allows you to build your own turmites. To pass the exercise, you should simply write a <code>init()</code> method which initializes the <code>rule</code> to use the following transitions table (from wikipedia), set the buggle initial position at (8;33), and ask for 8342 steps.
fr: Cet exercice vous permet de construire vos propres turmites. Pour réussir cet exercice, vous devez simplement écrire une méthode <code>init()</code> qui initialise <code>rule</code> pour utiliser les tables de transitions suivantes (de Wikipedia), met la position initiale de la buggle à (8;33), et demande de faire 8342 pas.

note: type: Content of: <table><tr><th>
en: Current color
fr: Couleur actuelle

note: type: Content of: <table><tr><th>
en: Write color
fr: Couleur à mettre

note: type: Content of: <table><tr><th>
en: Turn
fr: Virage

note: type: Content of: <table><tr><th>
en: Next state
fr: État suivant

note: type: Content of: <table><tr><th>
en: Current state
fr: État courant

note: type: Content of: <p>
en: where the direction to turn is one of <b>L</b> (90° left), <b>R</b> (90° right), <b>N</b> (no turn) and <b>U</b> (180° U-turn).
fr: Où les virages à effectuer sont 
    <b>L</b> (90° vers la gauche -- left), 
    <b>R</b> (90° vers la droite -- right), 
    <b>N</b> (rien -- no turn),
    <b>U</b> (demi tour de 180° -- U-turn).

note: type: Content of: <h2>
en: Going further
fr: Aller plus loin

note: type: Content of: <p>
en: This exercise is naturally an excuse to let you experiment with your own turmites.  Feel free to change the transition table and the amount of steps to experiment by yourself. To that extend, you may find the Ed Pegg Jr's library useful. If you find new interesting patterns, send them per email so that we can integrate them to this list!
fr: Cet exercice est naturellement une excuse pour vous laisser expérimenter vos propres turmites. Vous êtes libres de changer la table de transition et le nombre de pas pour expérimenter par vous-même. A ce propos, vous pouvez trouver la bibliothèque Ed Pegg Jr's utile. Si vous trouvez de nouveaux schémas intéressants, envoyez-les nous pas email afin que nous les puissions les ajouter à cette liste.

note: type: Content of: <p>
en: In addition, wikipedia is desperately missing some good looking colorful turmites: only black and white ones are depicted.  You should consider submitting your creations directly to the free encyclopedia.
fr: De plus, Wikipedia manque désespérément de quelques beaux et colorés turmites : seuls des noirs et blancs sont décrits. Vous pouvez considérer l'idée de soumettre vos créations directement à l'encyclopédie libre.

note: type: Content of: <p>
en: Here are some 2-color turmites, extracted from http://demonstrations.wolfram.com/Turmites/ [!python|scala]They are not written using the [!thelang] syntax, but converting them should be easy.[/!]
fr: Voici quelques turmites bicolores, issues de http://demonstrations.wolfram.com/Turmites/ 
    [!scala|python]Elles n'ont pas été écrites avec la syntaxe [!thelang], mais les convertir ne devrait pas poser beaucoup de problèmes.[/!]

note: type: Content of: <pre>
en: {{{1, RIGHT , 0}, {0, LEFT  , 0}}}  # 1: Langton's ant
    {{{1, RIGHT , 0}, {0, NOTURN, 0}}}  # 2: binary counter
    {{{0, LEFT  , 1}, {1, RIGHT , 1}}, {{1, NOTURN, 0}, {1, NOTURN, 1}}} # 3: (filled triangle)
    {{{0, NOTURN, 1}, {0, LEFT  , 1}}, {{1, RIGHT , 0}, {0, NOTURN, 1}}} # 4: spiral in a box
    {{{0, RIGHT , 1}, {0, LEFT  , 0}}, {{1, LEFT  , 1}, {0, RIGHT , 0}}} # 5: stripe-filled spiral
    {{{0, RIGHT , 1}, {0, LEFT  , 0}}, {{1, LEFT  , 1}, {1, NOTURN, 0}}} # 6: stepped pyramid
    {{{0, RIGHT , 1}, {0, NOTURN, 1}}, {{1, RIGHT , 1}, {1, LEFT  , 0}}} # 7: contoured island
    {{{0, RIGHT , 1}, {0, RIGHT , 1}}, {{1, NOTURN, 0}, {0, RIGHT , 1}}} # 8: woven placemat
    {{{0, RIGHT , 1}, {1, RIGHT , 1}}, {{1, LEFT  , 1}, {1, LEFT  , 0}}} # 9: snowflake-ish
    {{{1, LEFT  , 0}, {0, NOTURN, 1}}, {{0, LEFT  , 0}, {0, LEFT  , 1}}} # 10: slow city builder
    {{{1, LEFT  , 0}, {1, RIGHT , 1}}, {{0, RIGHT , 0}, {0, LEFT  , 1}}} # 11: framed computer art
    {{{1, LEFT  , 0}, {1, RIGHT , 1}}, {{0, RIGHT , 1}, {1, LEFT  , 0}}} # 12: balloon bursting (makes a spreading highway)
    {{{1, LEFT  , 1}, {0, LEFT  , 0}}, {{1, NOTURN, 0}, {0, NOTURN, 0}}} # 13: makes a horizontal highway
    {{{1, LEFT  , 1}, {0, LEFT  , 0}}, {{1, RIGHT , 1}, {1, RIGHT , 0}}} # 14: makes a 45 degree highway
    {{{1, LEFT  , 1}, {0, LEFT  , 1}}, {{1, RIGHT , 1}, {0, LEFT  , 0}}} # 15: makes a 45 degree highway
    {{{1, LEFT  , 1}, {0, NOTURN, 0}}, {{1, NOTURN, 0}, {1, RIGHT , 0}}} # 16: spiral in a filled box
    {{{1, LEFT  , 1}, {0, RIGHT , 0}}, {{0, LEFT  , 0}, {0, LEFT  , 0}}} # 17: glaciers
    {{{1, LEFT  , 1}, {1, LEFT  , 1}}, {{1, RIGHT , 1}, {0, NOTURN, 0}}} # 18: golden rectangle!
    {{{1, LEFT  , 1}, {1, RIGHT , 0}}, {{0, LEFT  , 0}, {0, LEFT  , 0}}} # 19: fizzy spill
    {{{1, LEFT  , 1}, {1, RIGHT , 1}}, {{1, NOTURN, 0}, {0, NOTURN, 1}}} # 20: nested cabinets
    {{{1, NOTURN, 1}, {0, LEFT  , 1}}, {{1, RIGHT , 0}, {1, NOTURN, 1}}} # 21: (cross)
    {{{1, NOTURN, 1}, {0, NOTURN, 0}}, {{0, RIGHT , 0}, {1, LEFT  , 0}}} # 22: saw-tipped growth
    {{{1, NOTURN, 1}, {0, NOTURN, 1}}, {{1, RIGHT , 1}, {0, NOTURN, 0}}} # 23: curves in blocks growth
    {{{1, NOTURN, 1}, {0, RIGHT , 0}}, {{0, LEFT  , 0}, {0, LEFT  , 0}}} # 24: textured growth
    {{{1, NOTURN, 1}, {0, RIGHT , 1}}, {{1, LEFT  , 0}, {1, RIGHT , 0}}} # 25: (diamond growth)
    {{{1, NOTURN, 1}, {1, LEFT  , 0}}, {{1, RIGHT , 1}, {0, NOTURN, 0}}} # 26: coiled rope
    {{{1, RIGHT , 0}, {0, LEFT  , 1}}, {{1, LEFT  , 0}, {0, NOTURN, 1}}} # 27: (growth)
    {{{1, RIGHT , 0}, {0, LEFT  , 1}}, {{1, LEFT  , 0}, {0, RIGHT , 1}}} # 28: (square spiral)
    {{{1, RIGHT , 0}, {1, RIGHT , 1}}, {{0, NOTURN, 0}, {0, NOTURN, 1}}} # 29: loopy growth with holes
    {{{1, RIGHT , 1}, {0, LEFT  , 1}}, {{1, NOTURN, 0}, {0, NOTURN, 0}}} # 30: Lanton's Ant drawn with squares
    {{{1, RIGHT , 1}, {0, RIGHT , 0}}, {{0, LEFT  , 1}, {1, LEFT  , 0}}} # 31: growth with curves and blocks
    {{{1, RIGHT , 1}, {0, RIGHT , 0}}, {{0, NOTURN, 0}, {1, RIGHT , 1}}} # 32: distracted spiral builder
    {{{1, RIGHT , 1}, {0, RIGHT , 1}}, {{1, NOTURN, 0}, {1, NOTURN, 1}}} # 33: cauliflower stalk (45 deg highway)
    {{{1, RIGHT , 1}, {1, LEFT  , 1}}, {{1, RIGHT , 1}, {0, RIGHT , 0}}} # 34: worm trails (eventually turns cyclic!)
    {{{1, RIGHT , 1}, {1, NOTURN, 0}}, {{1, NOTURN, 0}, {0, NOTURN, 1}}} # 35: eventually makes a two-way highway!
    {{{1, RIGHT , 1}, {1, RIGHT , 0}}, {{0, NOTURN, 0}, {0, NOTURN, 0}}} # 36: almost symmetric mould bloom
    {{{1, RIGHT , 1}, {1, RIGHT , 0}}, {{0, RIGHT , 0}, {1, NOTURN, 1}}} # 37: makes a 1 in 2 gradient highway
    {{{1, RIGHT , 1}, {1, RIGHT , 1}}, {{1, LEFT  , 1}, {0, RIGHT , 0}}} # 38: immediately makes a 1 in 3 highway
    {{{0, RIGHT , 1}, {1, RIGHT , 1}}, {{0, LEFT  , 2}, {0, LEFT  , 0}}, {{1, RIGHT , 2}, {1, LEFT  , 0}}} # 39: squares and diagonals growth
    {{{1, LEFT  , 1}, {0, NOTURN, 0}}, {{0, RIGHT , 2}, {1, LEFT  , 0}}, {{1, RIGHT , 1}, {1, NOTURN, 0}}} # 40: streak at approx. an 8.1 in 1 gradient
    {{{1, LEFT  , 1}, {0, NOTURN, 2}}, {{0, RIGHT , 2}, {1, NOTURN, 1}}, {{1, RIGHT , 1}, {1, NOTURN, 0}}} # 41: streak at approx. a 1.14 in 1 gradient
    {{{1, LEFT  , 1}, {1, LEFT  , 1}}, {{1, NOTURN, 0}, {0, NOTURN, 2}}, {{0, LEFT  , 1}, {1, NOTURN, 1}}} # 42: maze-like growth
    {{{1, LEFT  , 2}, {0, RIGHT , 0}}, {{1, LEFT  , 0}, {0, RIGHT , 0}}, {{0, LEFT  , 0}, {0, LEFT  , 1}}} # 43: growth by cornices 
    {{{1, RIGHT , 0}, {0, RIGHT , 2}}, {{0, LEFT  , 0}, {0, RIGHT , 0}}, {{0, NOTURN, 1}, {1, LEFT  , 0}}} # 44: makes a 1 in 7 highway
    {{{1, RIGHT , 1}, {0, LEFT  , 0}}, {{1, RIGHT , 2}, {0, NOTURN, 0}}, {{1, LEFT  , 0}, {0, LEFT  , 0}}} # 45: makes a 4 in 1 highway
fr: {{{1, RIGHT , 0}, {0, LEFT  , 0}}}  # 1: La fourmi de Langton
    {{{1, RIGHT , 0}, {0, NOTURN, 0}}}  # 2: Compteur binaire
    {{{0, LEFT  , 1}, {1, RIGHT , 1}}, {{1, NOTURN, 0}, {1, NOTURN, 1}}} # 3: Triangle rempli
    {{{0, NOTURN, 1}, {0, LEFT  , 1}}, {{1, RIGHT , 0}, {0, NOTURN, 1}}} # 4: Spirale dans une boite
    {{{0, RIGHT , 1}, {0, LEFT  , 0}}, {{1, LEFT  , 1}, {0, RIGHT , 0}}} # 5: Spirale rayurée
    {{{0, RIGHT , 1}, {0, LEFT  , 0}}, {{1, LEFT  , 1}, {1, NOTURN, 0}}} # 6: Pyramide à étages
    {{{0, RIGHT , 1}, {0, NOTURN, 1}}, {{1, RIGHT , 1}, {1, LEFT  , 0}}} # 7: Île entourée
    {{{0, RIGHT , 1}, {0, RIGHT , 1}}, {{1, NOTURN, 0}, {0, RIGHT , 1}}} # 8: Set tissé
    {{{0, RIGHT , 1}, {1, RIGHT , 1}}, {{1, LEFT  , 1}, {1, LEFT  , 0}}} # 9: Sorte de flocon de neige
    {{{1, LEFT  , 0}, {0, NOTURN, 1}}, {{0, LEFT  , 0}, {0, LEFT  , 1}}} # 10: Constructeur de ville lent
    {{{1, LEFT  , 0}, {1, RIGHT , 1}}, {{0, RIGHT , 0}, {0, LEFT  , 1}}} # 11: Art informatisé en boîte
    {{{1, LEFT  , 0}, {1, RIGHT , 1}}, {{0, RIGHT , 1}, {1, LEFT  , 0}}} # 12: Décollage de ballon (fait une autoroute)
    {{{1, LEFT  , 1}, {0, LEFT  , 0}}, {{1, NOTURN, 0}, {0, NOTURN, 0}}} # 13: Autoroute horizontale
    {{{1, LEFT  , 1}, {0, LEFT  , 0}}, {{1, RIGHT , 1}, {1, RIGHT , 0}}} # 14: Autoroute à 45 degrés
    {{{1, LEFT  , 1}, {0, LEFT  , 1}}, {{1, RIGHT , 1}, {0, LEFT  , 0}}} # 15: Autoroute à 45 degrés
    {{{1, LEFT  , 1}, {0, NOTURN, 0}}, {{1, NOTURN, 0}, {1, RIGHT , 0}}} # 16: Spirale dans une boîte remplie
    {{{1, LEFT  , 1}, {0, RIGHT , 0}}, {{0, LEFT  , 0}, {0, LEFT  , 0}}} # 17: glaciers
    {{{1, LEFT  , 1}, {1, LEFT  , 1}}, {{1, RIGHT , 1}, {0, NOTURN, 0}}} # 18: Rectangle doré!
    {{{1, LEFT  , 1}, {1, RIGHT , 0}}, {{0, LEFT  , 0}, {0, LEFT  , 0}}} # 19: Fontaine pétillante
    {{{1, LEFT  , 1}, {1, RIGHT , 1}}, {{1, NOTURN, 0}, {0, NOTURN, 1}}} # 20: Armoires imbriquées
    {{{1, NOTURN, 1}, {0, LEFT  , 1}}, {{1, RIGHT , 0}, {1, NOTURN, 1}}} # 21: Croix
    {{{1, NOTURN, 1}, {0, NOTURN, 0}}, {{0, RIGHT , 0}, {1, LEFT  , 0}}} # 22: Croissance en dents de scie
    {{{1, NOTURN, 1}, {0, NOTURN, 1}}, {{1, RIGHT , 1}, {0, NOTURN, 0}}} # 23: Croissance par blocs
    {{{1, NOTURN, 1}, {0, RIGHT , 0}}, {{0, LEFT  , 0}, {0, LEFT  , 0}}} # 24: Croissance texturée
    {{{1, NOTURN, 1}, {0, RIGHT , 1}}, {{1, LEFT  , 0}, {1, RIGHT , 0}}} # 25: Croissance en diamands
    {{{1, NOTURN, 1}, {1, LEFT  , 0}}, {{1, RIGHT , 1}, {0, NOTURN, 0}}} # 26: Corde enroulée
    {{{1, RIGHT , 0}, {0, LEFT  , 1}}, {{1, LEFT  , 0}, {0, NOTURN, 1}}} # 27: (croissance)
    {{{1, RIGHT , 0}, {0, LEFT  , 1}}, {{1, LEFT  , 0}, {0, RIGHT , 1}}} # 28: (spirale carrée)
    {{{1, RIGHT , 0}, {1, RIGHT , 1}}, {{0, NOTURN, 0}, {0, NOTURN, 1}}} # 29: Croissance ébourifée
    {{{1, RIGHT , 1}, {0, LEFT  , 1}}, {{1, NOTURN, 0}, {0, NOTURN, 0}}} # 30: La fourmi de Langton en carrés
    {{{1, RIGHT , 1}, {0, RIGHT , 0}}, {{0, LEFT  , 1}, {1, LEFT  , 0}}} # 31: Croissance avec des courbes et des blocs
    {{{1, RIGHT , 1}, {0, RIGHT , 0}}, {{0, NOTURN, 0}, {1, RIGHT , 1}}} # 32: Constructeur de spirales distrait
    {{{1, RIGHT , 1}, {0, RIGHT , 1}}, {{1, NOTURN, 0}, {1, NOTURN, 1}}} # 33: Tige de choux-fleur (autoroute à 45 degrés)
    {{{1, RIGHT , 1}, {1, LEFT  , 1}}, {{1, RIGHT , 1}, {0, RIGHT , 0}}} # 34: Piste de vers (croissance cyclique!)
    {{{1, RIGHT , 1}, {1, NOTURN, 0}}, {{1, NOTURN, 0}, {0, NOTURN, 1}}} # 35: Fini par faire une autoroute à deux voies!
    {{{1, RIGHT , 1}, {1, RIGHT , 0}}, {{0, NOTURN, 0}, {0, NOTURN, 0}}} # 36: Éclosion de moisissure presque symétrique
    {{{1, RIGHT , 1}, {1, RIGHT , 0}}, {{0, RIGHT , 0}, {1, NOTURN, 1}}} # 37: Fait un 1 dans une autoroute à deux gradients
    {{{1, RIGHT , 1}, {1, RIGHT , 1}}, {{1, LEFT  , 1}, {0, RIGHT , 0}}} # 38: Fait immédiatement un 1 dans une autoroute à 3
    {{{0, RIGHT , 1}, {1, RIGHT , 1}}, {{0, LEFT  , 2}, {0, LEFT  , 0}}, {{1, RIGHT , 2}, {1, LEFT  , 0}}} # 39: Croissance de carrés et diagonales
    {{{1, LEFT  , 1}, {0, NOTURN, 0}}, {{0, RIGHT , 2}, {1, LEFT  , 0}}, {{1, RIGHT , 1}, {1, NOTURN, 0}}} # 40: streak at approx. an 8.1 in 1 gradient
    {{{1, LEFT  , 1}, {0, NOTURN, 2}}, {{0, RIGHT , 2}, {1, NOTURN, 1}}, {{1, RIGHT , 1}, {1, NOTURN, 0}}} # 41: streak at approx. a 1.14 in 1 gradient
    {{{1, LEFT  , 1}, {1, LEFT  , 1}}, {{1, NOTURN, 0}, {0, NOTURN, 2}}, {{0, LEFT  , 1}, {1, NOTURN, 1}}} # 42: Croissance en labyrinthe
    {{{1, LEFT  , 2}, {0, RIGHT , 0}}, {{1, LEFT  , 0}, {0, RIGHT , 0}}, {{0, LEFT  , 0}, {0, LEFT  , 1}}} # 43: Croissance en corniches
    {{{1, RIGHT , 0}, {0, RIGHT , 2}}, {{0, LEFT  , 0}, {0, RIGHT , 0}}, {{0, NOTURN, 1}, {1, LEFT  , 0}}} # 44: makes a 1 in 7 highway
    {{{1, RIGHT , 1}, {0, LEFT  , 0}}, {{1, RIGHT , 2}, {0, NOTURN, 0}}, {{1, LEFT  , 0}, {0, LEFT  , 0}}} # 45: makes a 4 in 1 highway

note: type: Content of: <p>
en: Langton's ants may not share the expressiveness power of the turmites, but they remain fascinating too. You can experiment with them using the initLangton() method, provided in your template, that allows to build a Turmite transition table from a Langton's ant name. Tiny changes in the ant may result huge changes. For example, "RRL" does not seem to lead to any constructed pattern, even after a million steps, but "RLL" starts building a very simple highway pattern after less than 100 steps!
fr: Les fourmis de Langton ne partagent peut être pas la capacité d'expression des turmites, mais elles restent fascinantes elles aussi. Vous pouvez expérimenter avec elles en utilisant la méthode initLangton(), fournie dans le code de base, qui vous permet de construire une table de transition pour Turmite a partir du nom d'une fourmi de Langton. De petits changements peuvent engendrer de grandes choses. Par exemple, "RRL" ne semble pas mener à un quelconque schéma, même après un million de pas, mais "RLL" commence à construire un dessin très simple de route au bout de moins de 100 pas !

note: type: Content of: <p>
en: Quite a lot of Langton's ants build highways: RL, of course, but also RLRLRLLRLR (about 2500 steps).  The chaotic behavior of ants before the highway can be very short (as with RLL that only need 100 steps to converge) or very long, as with LLLLLLRRLRRR which seems chaotic for more than 500,000 steps before build the highway or even RRLLLRRRLRRR which needs 1170000 to start converging. Some are narrow, and others are very large, such as RRLRLLRLRR (200,000 steps). This ant is also notable since it is somehow squarish even before the highway start where most others do not show anything notable before their highway.
fr: Beaucoup de fourmis de Langton construisent des routes: RL, bien entendu, mais aussi RLRLRLLRLR (environ 2500 pas). Le comportement chaotique des fourmis avant la route peut être très court (comme avec RLL qui a seulement besoin de 100 pas pour converger) ou très long, comme avec LLLLLLRRLRRR qui semble chaotique jusqu'à plus de 500 000 pas avant de construire la route ou encore RRLLLRRRLRRR qui nécessite 1 170 000 pour commencer à converger. Certaines sont étroites, d'autres très larges, comme avec RRLRLLRLRR (200 000 pas). Cette fourmi est aussi notable puisque c'est quelque peu carré avant même que la route commence, là où d'autres ne montrent rien de transcendant avant leur route.

note: type: Content of: <p><p><p>
en: Some ants fill solid sectors, such as RRLLLRLLLRRR (16,000 steps), RRLLLRLLLRRR (30,000 steps), RRLLLRRRRRLR (125,000 steps) or RRLRLLRRRRRR (20,000 steps). Some even fill the whole space (RRLRR after 3000 steps). Some of my personal favorite ones are the ones where the ant seem to be bouncing within a box that gets bigger on each bump, such as LRRRRRLLR (30,000 steps). LRRRRLLLRRR is even more impressing since the bounces within the box are regular and since it converges more rapidly to its stable behavior (15,000 steps are enough).
fr: Certaines fourmis remplissent des secteurs entiers, comme avec RRLLLRLLLRRR (16 000 pas), RRLLLRLLLRRR (30 000 pas), RRLLLRRRRRLR (125 000 pas) ou RRLRLLRRRRRR (20 000 pas). D'autres encore remplissent tout l'espace (RRLRR après 3000 pas). Certaines de mes favorites sont celles où la fourmi semble rebondir dans une boite qui devient plus grande à chaque rebond, comme avec LRRRRRLLR (30 000 pas). LRRRRLLLRRR est encore plus impressionnant puisque les rebonds dans la boite sont réguliers et puisque la fourmi atteint rapidement son comportement stable (15 000 pas suffisent).

note: type: Content of: <p><p><p>
en: Finally, some ants are just build artistic patterns. You should check this video for some beautiful ones: http://www.youtube.com/watch?v=1X-gtr4pEBU. If you want to convert them into your code, you have to shift them by one: For example, the one depicted at 3:42 is not RRLRLRLLRL, but RLRLRLLRLR (the first visible move should be read as last one).
fr: Enfin, certaines fourmis construisent juste des schémas artistiques. Vous devriez regarder cette vidéo pour un bel aperçu : http://www.youtube.com/watch?v=1X-gtr4pEBU .
    Si vous voulez les implémenter dans votre code, vous devez les permuter de un : Par exemple, celle décrite à 3:42 n'est pas RRLRLRLLRL, mais RLRLRLLRLR (le premier mouvement visible doit être vu comme le dernier).

note: type: Content of: <p><p><p>
en: As you can see by exploring the above set of turmites, they are usually not as colorful as the ants, but this may be because very few colors suffice to exhibit complex behaviors. For example, there is a specific class of turmites called <i>busy beavers</i> which are turmites that write a lot of things before stopping (busy beavers are usually classical turing machines, but the idea fits perfectly to turmites too). There is a sort of international competition where people strive to find the turmite that covers the biggest area before stopping. The web page is here: http://code.google.com/p/ruletablerepository/wiki/TwoDimensionalTuringMachines
fr: Comme vous pouvez le constater en explorant l'ensemble ci-dessus de turmites, elles ne sont généralement pas aussi colorées que les fourmis, mais c'est peut-être car très peu de couleurs sont nécessaires pour expliciter des comportements complexes. Par exemple, il y a un classe spécifique de turmites appelée <i>busy beavers</i> qui sont des turmites qui écrivent énormément de choses avant de s'arrêter ( les <i>busy beavers</i> sont généralement des machines de Turing classiques, mais l'idée correspond parfaitement aux turmites). Il y a une sorte de compétition internationale où les participants font tout leur possible pour trouver le turmite qui couvre la plus grande surface avant de s'arrêter.
    La page web est ici : http://code.google.com/p/ruletablerepository/wiki/TwoDimensionalTuringMachines

note: type: Content of: <h1>
en: Turmite universe
fr: L'univers des turmites

note: type: Content of: <p>
en: This universe is very similar to the buggle one, but you will probably not use all buggles methods.  So, this page only recap the buggle methods that you will use.
fr: Cet univers est très semblable à celui des buggles, mais vous n'utiliserez probablement pas toutes les méthodes des buggles. Cette page résume donc les quelques méthodes que vous serez amenés à utiliser.

note: type: Content of: <table><tr><td>
en: [!java|c]void [/!][!c]stepForward()[/!][!java|python|scala]forward()[/!] or [!java|c]void [/!]forward([!java|c]int [/!]steps[!scala]:Int[/!])
fr: [!java|c]void [/!][!c]avancePas()[/!][!java|python|scala]avance()[/!] or [!java|c]void [/!]avance([!java|c]int [/!]nbPas[!scala]:Int[/!])

note: type: Content of: <table><tr><td>
en: [!java|c]void [/!][!c]stepBackward()[/!][!java|python|scala]backward()[/!] or [!java|c]void [/!]backward([!java|c]int [/!]steps[!scala]:Int[/!])
fr: [!java|c]void [/!][!c]reculePas()[/!][!java|python|scala]recule()[/!] or [!java|c]void [/!]recule([!java|c]int [/!]nbPas[!scala]:Int[/!])

note: type: Content of: <h1>
en: Sorting World
fr: Monde des tris

note: type: Content of: outside any tag (error?)
en: This world provides tools to experiment with the sorting algorithms. It can be used in two different ways: the first one is naturally to write the required sorting algorithms. But it is also possible to simply use the demo mode of each exercise to observe the behavior of sorting algorithms. It helps understanding the differences between each of them.
fr: Ce monde vous donne les outils pour expérimenter les algorithmes de tris. On peut l'utiliser de deux manières différentes : la première est bien sûr d'écrire les algorithmes de tri demandés. Mais on peut aussi se contenter dans un premier temps de lancer la démo de chaque exercice et observer les algorithmes de tri fonctionner. Cela permet de mieux se rendre compte des différences d'efficacité entre eux.

note: type: Content of: <h2>
en: Methods available to sorting algorithms
fr: Méthodes disponibles pour les algorithmes de tri

note: type: Content of: <table><tr><td>
en: <b>Method</b>
fr: <b>Méthode</b>

note: type: Content of: <table><tr><td>
en: <b>Cost</b>
fr: <b>Coût</b>

note: type: Content of: <table><tr><td>
en: [!java|c]int [/!]getValueCount() [!scala]:Int[/!]
fr: [!java|c]int [/!]getNombreValeurs() [!scala]:Int[/!]

note: type: Content of: <table><tr><td>
en: Returns the amount of values in the array
fr: Retourne le nombre de valeurs dans le tableau

note: type: Content of: <table><tr><td>
en: none
fr: aucun

note: type: Content of: <table><tr><td>
en: [!java]boolean [/!][!c]int [/!]isSmaller([!java|c]int [/!]i[!scala]:Int[/!], [!java|c]int [/!]j[!scala]:Int[/!]) [!scala]:Boolean[/!]
fr: [!java]boolean [/!][!c]int [/!]plusPetit([!java|c]int [/!]i[!scala]:Int[/!], [!java|c]int [/!]j[!scala]:Int[/!]) [!scala]:Boolean[/!]

note: type: Content of: <table><tr><td>
en: Returns true if the content of cell i is strictly smaller than the one of cell j
fr: Retourne vrai si le contenu de la case i est strictement inférieur à celui de la case j

note: type: Content of: <table><tr><td>
en: two reads
fr: deux lectures

note: type: Content of: <table><tr><td>
en: [!java]boolean [/!][!c]int [/!]isSmallerThan([!java|c]int [/!]i[!scala]:Int[/!], [!java|c]int [/!]value[!scala]:Int[/!])[!scala] :Boolean[/!]
fr: [!java]boolean [/!][!c]int [/!]plusPetitQue([!java|c]int [/!]i[!scala]:Int[/!], [!java|c]int [/!]value[!scala]:Int[/!])[!scala] :Boolean[/!]

note: type: Content of: <table><tr><td>
en: Returns true if the content of cell i is strictly smaller than the <code>value</code>
fr: Retourne vrai si le contenu de la case i est strictement inférieur à la valeur <code>value</code>

note: type: Content of: <table><tr><td>
en: one read
fr: une lecture

note: type: Content of: <table><tr><td>
en: [!java|c]void [/!]swap([!java|c]int [/!]i[!scala]:Int[/!], [!java|c]int [/!]j[!scala]:Int[/!])
fr: [!java|c]void [/!]echange([!java|c]int [/!]i[!scala]:Int[/!], [!java|c]int [/!]j[!scala]:Int[/!])

note: type: Content of: <table><tr><td>
en: Swaps the content of cell i and the one of cell j
fr: Échange le contenu de la case i avec celui de la case j

note: type: Content of: <table><tr><td>
en: two reads, two writes
fr: deux lectures, deux écritures

note: type: Content of: <table><tr><td>
en: [!java|c]void [/!]copy([!java|c]int [/!]from[!scala]:Int[/!], [!java|c]int [/!]to[!scala]:Int[/!])
fr: [!java|c]void [/!]copie([!java|c]int [/!]depuis[!scala]:Int[/!], [!java|c]int [/!]vers[!scala]:Int[/!])

note: type: Content of: <table><tr><td>
en: Copy the content of cell 'from' into the cell 'to'
fr: Copie le contenu de la case 'depuis' dans la case 'vers'

note: type: Content of: <table><tr><td>
en: one read, one write
fr: une lecture, une écriture

note: type: Content of: <table><tr><td>
en: [!java|c]int [/!]getValue([!java|c]int [/!]idx[!scala]:Int[/!])
fr: [!java|c]int [/!]getValeur([!java|c]int [/!]idx[!scala]:Int[/!])

note: type: Content of: <table><tr><td>
en: Returns the value of cell idx
fr: Retourne la valeur de la case idx

note: type: Content of: <table><tr><td>
en: [!java|c]void [/!]setValue([!java|c]int [/!]idx[!scala]:Int[/!], [!java|c]int [/!]value[!scala]:Int[/!])
fr: [!java|c]void [/!]setValeur([!java|c]int [/!]idx[!scala]:Int[/!], [!java|c]int [/!]valeur[!scala]:Int[/!])

note: type: Content of: <table><tr><td>
en: Sets cell 'idx' to the <code>value</code>
fr: Affecte la valeur '<code>valeur</code>' à la case 'idx'

note: type: Content of: <table><tr><td>
en: one write
fr: une écriture

note: type: Content of: <table><tr><td>
en: [!java]boolean [/!][!c]int [/!]isSelected() [!scala]:Boolean[/!]
fr: [!java]boolean [/!][!c]int [/!]estSelectionne() [!scala]:Boolean[/!]

note: type: Content of: outside any tag (error?)
en: Returns whether the current world is selected in the graphical interface.
fr: Renvoi si le monde actuel est sélectionné dans l'interface graphique.

note: type: Content of: <h2>
en: History view
fr: Vue de l'historique du monde

note: type: Content of: <p>
en: It is not enough to sort the array to pass the exercises. Your solution must strictly follow the expected behavior of each exercise. This is enforced by checking that your algorithm needs the same amount of read and write operations to sort the array. When they don't match, understanding the difference between your code and the expected solution can reveal very difficult.
fr: Il ne suffit pas de trier le tableau pour passer les exercices. Votre solution doit suivre scrupuleusement le comportement attendu de chaque exercice. Ceci est vérifié en comptant le nombre d'opérations de lecture et d'écriture sur le tableau effectuées lors de ce tri. En cas de problème, il est souvent assez difficile de comprendre la différence entre le comportement attendu et le comportement effectif.

note: type: Content of: <p>
en: To help in this process, it is possible to graphically explore the history of your sorting algorithm. Switch to the Objective view and use the contextual menu (right click) to switch from the view of the current state to the view of its history.
fr: Pour cela, il est possible d'explorer graphiquement l'historique de n'importe quel monde de tri. Passez par exemple au monde Objectif et utilisez son menu contextuel (clic droit) pour choisir entre la vue de l'état courant du monde et la vue de son histoire.

note: type: Content of: <p>
en: The history view is a bit hairly at the first glance, but actually rather simple: The time flows from left to right on this graph, and each row is a cell of your array. The curved lines that go navigate between rows represent a given data value. When two lines cross, this means that two values were swapped at this time stamp; A line fork represent a value copy; When a value is magenta and followed by an interrogation mark (?), it was read using getValue(); If the value is red and followed with an exclamation point (!), it was written using setValue().
fr: La vue de l'historique n'est pas aussi complexe qu'elle en a l'air à première vue. Le temps s'écoule de gauche à droite, et les cases du tableau sont représentée de haut en bas. Les lignes de différentes couleurs qui serpentent représentent les différentes valeurs contenues dans le tableau. Quand deux lignes se croisent, cela signifie que les valeurs du tableau ont été échangées à ce moment de l'historique; un embranchement signifie que la valeur a été copiée; une valeur en violet suivie d'un point d'interrogation a été lue avec getValeur() et une valeur en rouge suivie d'un point d'exclamation a été écrite avec setValeur().

note: type: Content of: <p>
en: This view, inspired from Aldo Cortesi, reveals very helpful understand the inner behavior of sorting algorithms.
fr: Cette vue, inspirée d'Aldo Cortesi, est très pratique pour comprendre le comportement des algorithmes de tri.

note: type: Content of: <h3>
en: Sorting Algorithms
fr: Algorithmes de tri

note: type: Content of: outside any tag (error?)
en: This lesson allows to experiment with some classical sorting algorithms (and some less common variant of them). The goal is two fold: you can first better understand the idea of these algorithms by writing them yourself. But even if you don't code the algorithms, you can use the demo mode to organize "races" between these algorithms to experiment in practice what the different asymptotical complexity mean.
fr: Cette leçon vous permet d'expérimenter avec les algorithmes de tri classiques (et certaines optimisations moins courantes de ceux-ci). L'objectif est double: il s'agit tout d'abord de mieux comprendre le principe de ces algorithmes en les codant vous-même.  Mais même si vous ne codez pas les algorithmes, vous pouvez utiliser le mode démo pour organiser des "courses" entre ces algorithmes afin d'expérimenter en pratique ce qu'implique la différence de complexité asymptotique entre deux algorithmes.

note: type: Content of: <p>
en: More exercises are planned for the future, on recursive sorting algorithms (such as QuickSort and MergeSort) or using other microworlds to apply these algorithms to other contexts.
fr: Plus d'exercices sont prévus à l'avenir. Certain porteront sur les tris
    récursifs (en particulier QuickSort et MergeSort) tandis que d'autres
    s'appuieront sur d'autres micro-mondes pour appliquer ces algorithmes à d'autres
    situations.

note: type: Content of: <ul><li>
en: Other graphical representations could be proposed, such as the ones presented at <a href="http://sorting.at/">http://sorting.at/</a>.
fr: D'autres représentations graphiques pourraient être proposées, telles que celles
    présentées sur le site <a href="http://sorting.at/">http://sorting.at/</a>.

note: type: Content of: <p>
en: This lesson allows to experiment with some classical sorting algorithms (and some less common variant of them :)
fr: Cette leçon vous permet d'expérimenter avec des algorithmes de tri classiques (ainsi qu'avec certaines variantes moins classiques :)

note: type: Content of: <p>
en: You are supposed to master the bases of programming to take this lesson.
fr: Vous êtes supposé maîtriser les bases de la programmation avant de tenter cette leçon.

note: type: Content of: <h1>
en: BubbleSort
fr: Tri à bulle

note: type: Content of: <p>
en: Welcome to the sorting universe. It allows you to experiment with the existing sorting algorithms. The list of buildins that you can use in your algorithms is available in the world reference documentation ("Help"-&gt;"About this world").
fr: Bienvenue dans l'univers des tris. Il permet d'expérimenter avec les algorithmes de tri existants. La liste des primitives que vous pouvez utiliser dans vos programmes est disponible dans la documentation de référence du monde (Aide / À propos de cet univers).

note: type: Content of: <p>
en: It is not enough to sort the array to pass the exercises. Your solution must strictly follow the expected behavior of each exercise. This is enforced by checking that your algorithm needs the same amount of read and write operations to sort the array.
fr: Il ne suffit pas de trier le tableau pour passer les exercices. Votre solution doit suivre scrupuleusement le comportement attendu de chaque exercice. Ceci est vérifié en comptant le nombre d'opérations de lecture et d'écriture sur le tableau effectuées lors de ce tri.

note: type: Content of: <p>
en: When your algorithm diverges from the expectation, understanding the difference between your code and the expected solution can reveal very difficult. To help in this process, it is posible to graphically explore the history of your sorting algorithm. Switch to the Objective view and use the contextual menu (right click)  to switch from the the view of the current state to the view of its history.
fr: Quand votre algorithme diverge de l'attendu, il peut être difficile de comprendre la différence de comportement. Pour cela, il est possible d'explorer graphiquement l'historique de n'importe quel monde de tri. Passez par exemple au monde Objectif et utilisez son menu contextuel (clic droit) pour choisir entre la vue de l'état courant du monde et la vue de son histoire.

note: type: Content of: <h2>
en: First attempt at BubbleSort
fr: Première tentative pour le tri à bulle

note: type: Content of: <p>
en: This first sorting algorithm is the most simple one: Bubble sort consists in progressively moving up the smaller elements of the array, as if they were air bubbles moving up to the surface of a liquid. The algorithm traverse the array, and compare any pair of adjacent elements. If two adjacent elements are wrongly sorted, they are swapped. Once the array was completely traversed, the operation starts again from the beginning. When no elements were sorted after a full traversal, it means that the array is completely sorted: the algorithm can stop.  Bubble sort is studied because of its simplicity, but it is almost never used in practice because of its bad performance (O(n^2) on average).
fr: Le premier algorithme de tri est le plus simple existant : le tri à bulles ou tri par propagation consiste à faire remonter progressivement les plus petits éléments d'une liste, comme les bulles d'air remontent à la surface d'un liquide. L'algorithme parcourt la liste, et compare les couples d'éléments successifs. Lorsque deux éléments successifs ne sont pas dans l'ordre croissant, ils sont échangés. Après chaque parcours complet de la liste, l'algorithme recommence l'opération. Lorsque aucun échange n'a lieu pendant un parcours, cela signifie que la liste est triée : l'algorithme peut s'arrêter.  La simplicité de cet algorithme justifie son étude, mais ses piètres performances (O(n^2) en moyenne) font qu'il n'est quasiment jamais utilisé en pratique.

note: type: Attribute 'alt' of: <div>
en: Show Tip (Pseudo-code)
fr: Montrer l'indice (le pseudo-code)

note: type: Content of: <div><p>
en: The pseudo-code of the BubbleSort algorithm is the following:
fr: Le pseudo-code de l'algorithme du tri à bulles est donc le suivant :

note: type: Content of: <div><pre>
en: do: 
            For each i in [0,len-2]
              If cells i and i+1 must be swapped, do it
    while we swapped something during last traversal
fr: faire: 
            Pour tout i dans [0,lgr-2]
              Si les cases i et i+1 doivent être inversées, le faire
         tant qu'on a inversé des choses lors du dernier parcours

note: type: Content of: <h1>
en: BubbleSort (take 2)
fr: Tri à bulle (deuxième version)

note: type: Content of: <p>
en: If you look carefully at the behavior of BubbleSort, a first easy optimization appears: after one traversal, the last element of the array must be the biggest of all since the traversal moved it up like a bubble to its position. More generally, after N traversal, we know that the N last elements of the array are already sorted. It is thus not necessary to compare them again during the subsequent traversals. For now, we will have as many traversal as there is in the array.
fr: En étudiant le comportement du tri à bulle, on peut voir une première optimisation facile à effectuer: Après un parcours, le dernier élément du tableau est forcément le plus grand d'entre tous car le parcours l'a fait remonter comme une bulle à sa position. Plus généralement, après N parcours, on sait que les N derniers éléments du tableau sont déjà triés. En conclusion, il n'est pas utile de les recomparer sur les parcours suivants. Dans un premier temps, nous ferons autant de parcours qu'il y a d'éléments dans le tableau.

note: type: Content of: <div><p>
en: The pseudo-code of the BubbleSort2 algorithm is the following:
fr: Le pseudo-code de l'algorithme BubbleSort2 est le suivant :

note: type: Content of: <div><pre>
en: For all i in [len-2,0] (traversing from biggest to smallest)
           For all j in [0, i]
              If cells j and j+1 must be swapped, do it
fr: Pour tout i dans [lgr-2,0] (parcours du plus grand au plus petit)
           Pour tout j dans [0, i]
              Si les cases j et j+1 doivent être inversées, le faire

note: type: Content of: <p>
en: When we run this algorithm, it is quite disappointing to see that it runs approximately at the same speed than the basic version of BubbleSort. This is a graphical effect only since only value changes are graphically represented. Since this variation avoids some useless comparisons, it does exactly the same amount of swaps that the basic version. It is thus quite logical that the graphical interface draws this version at the same pace than the base version. But the statistics on the amount of reads show that we saved about the fourth of the amount of reads, which is not bad.
fr: Lorsqu'on exécute cet algorithme, il peut être un peu décevant de constater qu'il s'exécute à la même vitesse que la version de base de BubbleSort. C'est un effet graphique seulement puisque seules les changements de valeurs dans le tableau sont représentées. Comme cette variante consiste à éviter des comparaisons inutiles, elle effectue très exactement le même nombre d'échanges que la version de base. Il est donc normal que notre interface graphique la représente à la même vitesse que la version de base. Mais les statistiques sur le nombre de lectures montrent bien que l'on a économisé plus d'un quart du nombre de lectures, ce qui n'est pas si mal.

note: type: Content of: <p>
en: From the asymptotic complexity point of view, there is absolutely no difference: this variation is still in O(n^2) on average (our gain is only on the constant term, ignored when computing the asymptotic complexity).
fr: D'un point de vue complexité algorithmique, cela ne change rien: cette variante est toujours en O(n2) en moyenne (on ne gagne que sur la constante).

note: type: Content of: <h1>
en: BubbleSort (take 3)
fr: Tri à bulle (troisième version)

note: type: Content of: <p>
en: Let's now reintroduce the little optimization we removed at previous step: if a traversal does not swap any element, it means that the array is already sorted. In that case, we want to stop the whole sorting process.
fr: Réintroduisons maintenant la petite optimisation que nous avions retiré à l'étape précédente : Si un parcours n'a rien inversé, c'est que le tableau est maintenant trié. Dans ce cas, il faut arrêter le processus de tri.

note: type: Content of: <p>
en: [!java|python|c]For that, simply use the <code>break</code> keyword, which breaks the current loop.  Beware, if you have several nested loops, this will apply to the internal one.[/!] [!scala]For that, simply quit the current function by calling <code>return</code> with no associated value.[/!]
fr: [!java|python|c]Pour cela, utilisez simplement le mot-clé <code>break></code>, qui coupe l'exécution de la boucle englobante. Attention, si vous avez plusieurs boucles imbriquées, c'est celle situé tout au fond (au plus près du mot-clé break) qui est cassée.[/!]
    [!scala]Pour cela, quittez simplement la fonction courante en appelant <code>return</code> sans lui associer de valeur.[/!]

note: type: Attribute 'alt' of: <div>
en: If you want, this tip shows the pseudo-code.
fr: Si vous le désirez, cet indice montre le pseudo-code.

note: type: Content of: <div><pre>
en: For all i in [len-2,0] (traversing from biggest to smallest)
           For all j in [0, i]
              If cells j and j+1 must be swapped, do it
           If traversal on j did not swap anything, break the for loop
fr: Pour tout i dans [lgr-2,0] (parcours du plus grand au plus petit)
           Pour tout j dans [0, i]
              Si les cases j et j+1 doivent être inversées, le faire
           Si le parcours sur les j n'a rien inversé, casser la boucle

note: type: Content of: <p>
en: This optimization is even more disappointing: it only provide a gain of a few percents on the amount of reads over BubbleSort2.
fr: Cet optimisation est encore plus décevante : on ne gagne que quelques pour-cents en nombre de lectures sur BubbleSort2.

note: type: Content of: <h1>
en: CocktailSort
fr: Tri Cocktail

note: type: Content of: <p>
en: To improve further the BubbleSort algorithm, we need to look closer its behavior. One can notice that big elements are moved very quickly in position while small ones move very slowly to their destination. They are thus traditionally referred to as "rabbits" and "turtles" respectively for big fast values and small slow ones.
fr: Pour améliorer encore notre algorithme, il faut regarder un peu plus en détail son comportement. On peut constater que les grands éléments sont très rapidement mis en place tandis que les petits éléments se déplacent très lentement vers leur destination. On parle classiquement de lièvres et de tortues pour désigner respectivement les grandes valeurs et les petites valeurs.

note: type: Content of: <p>
en: To help the turtles moving faster, the cocktail sort traverse alternatively the array from right to left and from left to right. Here is the pseudo-code:
fr: Pour permettre aux tortues d'aller plus vite, le tri cocktail parcours alternativement le tableau de gauche à droite et de droite à gauche. Voici son pseudo-code:

note: type: Content of: <pre>
en: Do
      For all i in [0,len-2], do:
        if i and i+1 must be swapped, do it
      For all i in [len-2,0] (downward), do:
        if i and i+1 must be swapped, do it
    while at least one of the traversal swapped an element
fr: Faire
      Pour tout i dans [0,lgr-2], faire:
        si i et i+1 doivent être échangées, le faire
      Pour tout i dans [lgr-2,0] en descendant, faire:
        si i et i+1 doivent être échangées, le faire
    tant qu'au moins l'un des parcours a inversé un élément

note: type: Content of: <p>
en: One can see that cocktail sort achieves exactly the same amount of swaps than the bubble sort, but improves slightly on read amount. It is however still worse than BubbleSort2 to that extend.
fr: On constate que le tri cocktail fait très exactement le même nombre d'échanges que le tri à bulle, mais qu'il améliore les choses sur le nombre de lectures. Il reste cependant moins bon que BubbleSort2 en la matière.

note: type: Content of: <h1>
en: CocktailSort (take 2)
fr: Tri Cocktail (seconde version)

note: type: Content of: <p>
en: We will now apply to CocktailSort the same optimization than BubbleSort2 did to BubbleSort. We must remember the limits of the array part not being sorted yet, and traverse it alternatively from left to right and from right to left:
fr: Nous allons appliquer la même optimisation que BubbleSort2 à CocktailSort. Il nous faut nous souvenir des bornes du tableau pas encore trié, et le parcourir alternativement de droite à gauche et de gauche à droite:

note: type: Content of: <pre>
en: beg=0; end=len-2
    do
      For all Pour i in [beg,end], do:
          If cells i and i+1 must be swapped, do it    
      end -= 1 (this means end = end - 1)
      For all Pour i in [beg,end] (downwards), do:
          If cells i and i+1 must be swapped, do it    
      beg += 1 (this means beg = beg + 1)
    while at least one of the traversal swapped an element
fr: debut=0; fin=lgr-2
    Faire
      Pour tout i dans [debut,fin], faire:
        si i et i+1 doivent être échangées, le faire
      fin -= 1 (cela veut dire fin = fin -1)
      Pour tout i dans [fin, debut] en descendant, faire:
        si i et i+1 doivent être échangées, le faire
      debut += 1 (ce qui veut dire debut = debut + 1)
    tant qu'au moins l'un des parcours a inversé un élément

note: type: Content of: <h1>
en: CocktailSort (take 3)
fr: Tri Cocktail (troisième version)

note: type: Content of: <p>
en: Even if the asymptotic complexity of CocktailSort2 is the same than the one of BubbleSort, it seem to perform better in practice. It is even possible to improve a bit further by stopping it if the first traversal didn't found anything to swap, without achieving the downwards traversal. Likewise, we can stop if the upward traversal found something to swap, but not the downwards one.
fr: Même si la complexité algorithmique de CocktailSort2 est la même que le tri à bulle, il semble bien mieux s'en tirer en pratique. On peut encore l'améliorer un tout petit peu en arrêtant tout si le parcours dans l'ordre croissant n'a rien inversé, sans faire le parcours dans l'ordre décroissant. De même, on peut quitter si le parcours croissant a inversé des choses, mais pas le parcours décroissant.

note: type: Content of: <h1>
en: InsertionSort
fr: Tri par insertion

note: type: Content of: <p>
en: This sorting algorithm is quite simple to understand and write, even if it is not as efficient as possible. Its asymptotic complexity is in O(n2), but it is more efficient in practice (linear in best case, ie when the array is already sorted, and N2/4 on average).
fr: Ce tri est relativement simple à comprendre et à écrire, même s'il n'offre pas les meilleures performances possibles.  Il s'agit d'un algorithme quadratique (complexité asymptotique en O(n2)), mais il est plus efficace en pratique (linéaire dans le meilleur des cas, ie quand le tableau déjà trié et N2/4 en moyenne).

note: type: Content of: <p>
en: The idea is to traverse all elements of the array, and to insert each of them into its proper position in the already sorted part of the array. When we look at an element x, the situation is the following: any elements to the left of the array are already sorted, and we have to insert x at its position in the array.
fr: L'idée est de parcourir tous les éléments du tableau, et d'insérer chacun à sa place dans la partie du tableau déjà triée.  Lorsque l'on regarde un élément x du tableau, on est dans la situation suivante : tous les éléments à gauche du tableau sont déjà triés, et il faut insérer x à sa place dans le tableau.

note: type: Content of: <p>
en: Once this is done, the situation is the following:
fr: Une fois ceci fait, on se retrouve dans la situation suivante:

note: type: Content of: <p>
en: The pseudo-code of this algorithm is thus the following:
fr: Le pseudo-code de cet algorithme est donc le suivant :

note: type: Content of: <pre>
en: For each i in [1,len-1]
      store the value of i in a variable v
      copy the cell i-1 into i if i-1 contains a value bigger than v
      copy the cell i-2 into i-1 if i-2 contains a value bigger than v
      copy the cell i-3 into i-2 if i-3 contains a value bigger than v
      copy the cell i-4 into i-3 if i-4 contains a value bigger than v
      ...
      copy v into the last cell copied above
fr: Pour tout i dans [1,lgr-1]
      stocker la valeur de la case i dans une variable v
      recopier la case i-1 dans i, si i-1 contient une valeur plus grande que v
      recopier la case i-2 dans i-1, si i-2 contient une valeur plus grande que v
      recopier la case i-3 dans i-2, si i-3 contient une valeur plus grande que v
      recopier la case i-4 dans i-3, si i-4 contient une valeur plus grande que v
      ...
      recopier v dans la dernière case recopiée plus haut

note: type: Content of: <p>
en: Naturally, you should use a loop to write the big permutation within the given loop. Writing it this way would be really ... counter-productive.
fr: Bien entendu, il faut utiliser une boucle pour écrire la grosse permutation circulaire au cœur de la boucle.  L'écrire explicitement de la sorte serait vraiment ... contre-productif.

note: type: Content of: <p>
en: If you've always wondered what computer science researchers do nowadays, here is part of the answer: They improve fundamental algorithms so that others can write efficient programs.
fr: Si vous vous étiez toujours demandé ce que font les chercheurs en informatique à notre époque, voici un élément de réponse: certains d'entre eux améliorent des algorithmes fondamentaux pour permettre à d'autres de faire des programmes efficaces...

note: type: Content of: <h2>
en: Other variation of insertion sort
fr: D'autres variantes du tri par insertion

note: type: Content of: <p>
en: TreeSort builds a binary search tree to sort them. It leads to a O(n log(n))  on average, but O(n^2) in worst cases. We won't study this algorithm here since understanding its behavior requires to know what a binary tree is, what is beyond our present goals.
fr: TreeSort construit un arbre binaire équilibré des données pour les trier. Cela lui permet d'être en O(nlog n) en moyenne (mais O(n^2) dans le pire cas). Nous n'étudierons pas cet algorithme ici puisque comprendre son fonctionnement demande de savoir ce qu'est un arbre binaire, ce qui est au delà de nos objectifs présents.

note: type: Content of: <p>
en: There is other variations over the insertion sort, such as PatienceSort which builds piles of values and sort each pile afterward. This algorithm presents a 0(n log(n)) timing worst case and a 0(n) space complexity. LibrarySort (proposed in 2004) also trades a bit space in exchange for time since it provide a time complexity of O(n log(n)) but needs to store some more data.
fr: Il existe d'autres variantes du tri par insertion, comme PatienceSorting, qui fait des paquets des valeurs et trie ensuite chaque paquet. Cet algorithme présente un pire cas en O(nlog n), et une complexité spatiale en O(n).  LibrarySort (proposé en 2004) échange également un peu d'espace pour du temps puisqu'il présente une complexité moyenne en O(n log n), mais nécessite de stocker des données supplémentaires.

note: type: Content of: <p>
en: Wikipedia provides a detailled description of all these algorithms we cannot present here because of time constraints.
fr: Wikipedia (en anglais) propose une description détaillée de tous ces algorithmes que nous n'avons pas le temps de détailler ici.

note: type: Content of: <h2>
en: ShellSort
fr: Tri Shell

note: type: Content of: outside any tag (error?)
en: This algorithm is named after its author, Donald Shell, who published it in 1959. It can be seen as an application of the CombSort idea (let elements having a long path to travel take shortcuts) to the insertion sort (CombSort is a variation of BubbleSort). Instead of comparing adjacent values during the insertion sort, it compares values separated by a bigger gap. The bigger the gap, the faster the elements are moved to their final destination, but also the less precise is this move. It is thus mandatory to apply the algorithm with a serie of decreasing gaps. At the last step, when the gap is one, InsertionSort is used, but onto an array which is almost already sorted by previous steps.
fr: Cet algorithme porte le nom de son auteur, Donald Shell, qui l'a publié en 1959. Son principe peut être vu comme une application de l'idée du CombSort (faire prendre des raccourcis aux éléments ayant beaucoup de chemin à faire) au tri par insertion (le CombSort est une variante du tri à bulle).  Au lieu de comparer les valeurs adjacentes lors du tri par insertion, on compare des valeurs séparées par un <i>écart</i> plus grand. Plus l'écart est grand et plus les éléments sont déplacés rapidement vers leur position finale, mais aussi plus le déplacement est imprécis. Il faut donc appliquer l'algorithme avec une séquence d'écarts décroissante vers un. Ainsi, à la dernière étape quand l'écart vaut un, on applique l'algorithme de tri par insertion de base, mais sur un tableau déjà presque trié par les étapes précédentes.

note: type: Content of: <p>
en: Donald Shell propose <code>len/2</code> as initial value of the gap, and then to divide it by 2 at each step. The pseudo-code is thus the following:
fr: Donald Shell propose d'utiliser <code>lgr/2</code> comme première valeur de l'écartement, puis de le diviser par deux à chaque étape.  Le pseudo-code est donc le suivant:

note: type: Content of: <p><pre>
en: gap=len/2
    while gap>0:
      apply InsertionSort, comparing i-gap and i, then i-2gap and i-gap, then i-3gap and i-2gap, etc.
fr: ecart=lgr/2
    tant que ecart>0:
      appliquer l'algorithme de tri par insertion en comparant i-ecart et i, puis i-2ecart et i-ecart, puis i-3ecart et i-2ecart, etc.

note: type: Content of: <p><p>
en: Just like in CombSort, the sequence of values taken by the gap is crucial for Shell sort performance. In some rare pathological cases, the sequence we used above can lead to a O(n^2) performance. Other sequences were proposed: the Hibbard's increments of 2k − 1 lead to a complexity of O(n^(3/2)) in worst cases. Pratt's increments 2^i3^j lead to a O(nlog(n)log(n) performance in worst cases. The existance of a sequence leading to a O(n log(n)) was precluded by Poonen, Plaxton, and Suel. Thanks to this performance, ShellSort is a valid candidate for array of several hundred thousands when correctly implemented.
fr: Comme dans le cas du CombSort, la séquence des valeurs prises par l'écart se révèle être d'une importance capitale pour les performances du tri de Shell. Il existe des cas pathologiques qui font que la séquence que nous avons utilisée ici présente une complexité en O(n^2) dans le pire des cas. D'autres séquences ont été proposé: la séquence des incréments de Hibbard (2^k − 1) permet une complexité dans le pire des cas de O(n^(3/2)), les incréments de Pratt (2^i*3^j) permettent un pire cas en O(n log(n)log(n)).  Ces résultats font du tri de Shell un candidat tout à fait valide pour des instances de tableau de quelques centaines de milliers d'éléments quand il est correctement implémenté.

note: type: Content of: <p><p>
en: In our case, the array are ways too small to benefit of these optimizations. If you ever need to do so, take as initial gap the biggest value of the targeted serie still smaller than the array size, and then use decreasing values of the serie.
fr: Dans notre cas, les instances de tableaux que nous utilisons sont trop petites pour que ces optimisations présentent un réel avantage. Si on voulait le faire, il faudrait prendre en valeur initiale de l'écart la plus grande valeur de la suite utilisée, puis prendre les valeurs successives en descendant ensuite.

note: type: Content of: <p><p>
en: Interestingly enough, determining the best gap sequence for shell sort turns into a research issue of our century in computer science. For example, an article of 2001 introduces the following sequence, which seems to be optimal in practice for arrays of size up to 10^5: {1, 4, 10, 23, 57, 132, 301, 701, 1750} (Marcin Ciura, Best Increments for the Average Case of Shellsort, 13th International Symposium on Fundamentals of Computation Theory, LNCS 2001; Vol. 2138).
fr: De façon intéressante, déterminer la meilleure séquence d'écart pour le shell sort s'avère être un problème de recherche de notre siècle en informatique. Par exemple, un article publié en 2001 propose la suite suivante, qui semble optimale en pratique pour des tailles de tableau allant jusqu'à 10^5: {1, 4, 10, 23, 57, 132, 301, 701, 1750} (Marcin Ciura, Best Increments for the Average Case of Shellsort, 13th International Symposium on Fundamentals of Computation Theory, LNCS 2001; Vol. 2138).

note: type: Content of: <h1>
en: Selection Sort
fr: Tri par sélection

note: type: Content of: outside any tag (error?)
en: In this exercise we will implement another classical algorithm: selection sort.
fr: Cet exercice est l'occasion d'implémenter un autre algorithme très classique : le tri par sélection.

note: type: Content of: <p>
en: The idea is simply to select for each cell of the array the smallest value from the part not already sorted. Thus for the first cell, it takes the smallest value over the whole array. For the second one, it takes the second smallest value, which is the smallest value from the cell not already sorted. You of course don't have to sort the last cell of the array, that is already sorted when you consider it.
fr: Son principe est simplement de sélectionner pour chaque case du tableau la plus petite valeur de la partie pas encore triée. Ainsi, pour la première case, je prend la plus petite valeur du tableau. Pour la seconde, je prend la seconde plus petite valeur, qui se trouve être la plus petite des cases n'étant pas encore triées. Bien entendu, il n'est pas nécessaire de trier la dernière case du tableau, puisqu'elle est déjà triée lorsque vous la considérez.

note: type: Content of: <p><p>
en: More generally, for the cell N, it looks the cell M in [N;len] containing the smallest possible value of the interval. Then, it swaps the content of cell N with the one of cell M.
fr: Plus généralement, pour la case N, je cherche la case M de [N;lgr] contenant la plus petite valeur possible. Ensuite, j'inverse le contenu de la case N et celui de la case M.

note: type: Content of: <p><p><h2>
en: Existing variations
fr: Variantes possibles

note: type: Content of: <p><p>
en: Another classical algorithm which idea is based on the selection of good elements is HeapSort, but it uses a heap data structure which we did not see yet. Simply remember that HeapSort provides a O(n log n) performance in worst case, which is why it is a very interesting algorithm in practice.
fr: Un autre algorithme classique dont le principe repose sur la sélection des bons éléments est le tri par tas, mais il utilise une structure de données en tas, que nous n'avons pas encore introduite. Sachez simplement que ce tri présente un coût en O(n log n) dans le pire des cas, ce qui en fait un algorithme très intéressant en pratique.

note: type: Content of: <h1>
en: CombSort
fr: Tri à peigne

note: type: Content of: <p>
en: We saw that CocktailSort improve a bit for turtles (i.e. small values near to the end of the array), but it is still possible to achieve better. ComboSort comes down to providing them a short cut: instead of comparing adjacent values, we compare values separated by a gap bigger than 1. That way, turtles will traverse <i>gap</i> cells at each traversal. Naturally, we have to apply the algorithm with decreasing gaps, and finish with <i>gap=1</i> to ensure that the array is correctly sorted afterward. Choosing the right gap and how to decrease it is a difficult question, but in practice, dividing it by 1.3 after each traversal leads to good performance. Here is the corresponding pseudo-code:
fr: Nous avons vu que le tri cocktail permet d'améliorer un peu les choses pour les tortues (ie, les petites valeurs près de la fin du tableau), mais on peut faire mieux. Le tri à peigne revient à leur faire prendre un raccourci&nbsp;: Au lieu de comparer les valeurs adjacentes, on compare des valeurs séparés par un écart plus grand que 1. Ainsi, les tortues vont se déplacer de <i>ecart</i> cases à chaque parcours. Bien entendu, il faut appliquer l'algorithme avec des écarts de plus en plus petit et terminer avec <i>ecart=1</i> pour s'assurer que le tableau est entièrement trié à la fin. Choisir comment réduire l'écart entre les parcours est une question difficile (voir Wikipedia), mais en pratique, le diviser par 1.3 à chaque fois amène de bons résultats. Voici le pseudo-code correspondant :

note: type: Content of: <pre>
en: gap = len;
    do
       if gap>1 then
         gap = gap / 1.3
       i = O
       while i+gap &lt; len do:
         if i and i+gap must be swapped, do it
         increase i by one
    while the gap is bigger than 1 or the last traversal swapped at least one pair
fr: ecart = lgr;
    faire 
      si ecart>1 alors
        ecart = ecart / 1.3
      i = O
      tant que i+ecart &lt; lgr faire:
        si i et i+ecart doivent être inversés, le faire
        incrémenter i de 1
    tant que l'écart est plus grand que 1 ou que le dernier parcours a inversé au moins un élément

note: type: Content of: <p>
en: One tricky part is that we want to divide gap, that is an integer (of type Int), by 1.3, that is a Double.  The type system of scala won't let us do this, because such discrepancy usually denotes a programmer error.  As this is not an error this time, we have to convert gap to Double for the time of the operation, and then convert the result back to Int to store it into gap. This should be written this way:
fr: L'un des problèmes à résoudre est que la variable <code>ecart</code> est entière (de type <code>Int</code>), et que nous voulons la diviser par 1.3, qui est un nombre à virgule (de type <code>Double</code>). Le système de types de scala ne vous laissera pas faire une chose pareil sans broncher. C'est que ce genre de disparité est souvent le signe de problèmes que le programmeur n'a pas vu. Comme ce n'est pas une erreur dans notre cas, nous allons devoir convertir <code>ecart</code> en double pour le temps de l'opération, puis convertir le résultat de retour en entier pour le stocker dans <code>ecart</code>. Cela s'écrit de la manière suivante:

note: type: Content of: <pre>
en: gap = (gap.asInstanceOf[Double] / 1.3).asInstanceOf[Int]
fr: ecart = (ecart.asInstanceOf[Double] / 1.3).asInstanceOf[Int]

note: type: Content of: <p>
en: This is rather verbose, but actually, this notation is not very complex. And remember that the type checker is your friend. It's picky and sometimes annoying (as on this one), but it often catches weird bugs that would have been a pain to debug if not catch by the type checker. And since the Scala's authors are pragmatic, the previous expression can be simplified:
fr: C'est un peu bavard, mais finalement, cette écriture n'est pas très complexe. Et n'oubliez pas que le système de types est votre ami. Il est un peu tatillon et parfois un peu pénible (comme aujourd'hui), mais au fond, il trouve souvent des bugs bizarres qui auraient été très pénibles à débugger s'il ne les avait pas attrapé à la source. Et comme de plus les auteurs de Scala sont pragmatiques, cela peut aussi s'écrire de manière simplifiée :

note: type: Content of: <pre>
en: gap = (gap.toDouble / 1.3).toInt
fr: ecart = (ecart.toDouble / 1.3).toInt

note: type: Content of: <p>
en: <code>toDouble</code> and <code>toInt</code> are just shortcuts for the corresponding expressions <code>asInstanceOf[Double]</code> and <code>asInstanceOf[Int]</code>. It's not very generic, but it's very handy.
fr: <code>toDouble</code> et <code>toInt</code> sont simplement des raccourcis pour les expressions équivalentes <code>asInstanceOf[Double]</code> et <code>asInstanceOf[Int]</code>. Ce n'est pas très générique, mais c'est extrêmement pratique.

note: type: Content of: <p>
en: This algorithm was invented by Wlodek Dobosiewicz in 1980, and later rediscovered and popularized by Stephen Lacey and Richard Box, who described it in Byte Magazine in April 1991.
fr: Cet algorithme a été inventé par Wlodek Dobosiewicz en 1980 et redécouvert et popularisé par Stephen Lacey et Richard Box, qui l'ont décrit dans le magazine Byte d'avril 1991.

note: type: Content of: <h1>
en: CombSort11
fr: Tri à peigne 11

note: type: Content of: <p>
en: The authors of this algorithm observed that the performance is increased if we make sure that the last values of the gap are (11, 8, 6, 4, 3, 2, 1)  rather than (9, 6, 4, 3, 2, 1) or (10, 7, 5, 3, 2, 1). Rework the code of CombSort to ensure just after the gap update that if it is 9 or 10, we should use 11 instead.
fr: Les auteurs de l'algorithme du tri à peigne ont constaté que l'on améliore les performances en s'assurant que les dernières valeurs de l'écart sont (11, 8, 6, 4, 3, 2, 1) plutôt que (9, 6, 4, 3, 2, 1) ou (10, 7, 5, 3, 2, 1). Reprenez donc le code du tri à peigne, et indiquez juste après la mise à jour de l'écart que si la valeur est 9 ou 10, il faut utiliser 11 à la place.

note: type: Content of: <h1>
en: GnomeSort
fr: Tri du gnome

note: type: Content of: <p>
en: The Gnome sort is similar to insertion sort, but the elements are moved in position by a serie of swaps just like in bubble sort. It is named after the supposed behavior of garden gnomes when they sort flower pots. Here is a description of the algorithm by its author:
fr: Le tri du gnome s'apparente au tri par insertion, à ceci près que les éléments sont déplacés par une série d'échange comme dans le tri à bulle. Le nom vient du comportement supposé des gnomes des jardins quand ils rangent une série de pots de fleurs. Voici la description de l'algorithme par son auteur:

note: type: Content of: <p>
en: Gnome Sort is based on the technique used by the standard Dutch Garden Gnome (Du.: tuinkabouter). Here is how a garden gnome sorts a line of flower pots. Basically, he looks at the flower pot next to him and the one immediately after ; if they are in the right order he steps one pot forward, otherwise he swaps them and steps one pot backwards. Boundary conditions: if there is no previous pot, he steps forwards; if there is no pot next to him, he is done.  <i>—Dick Grune</i>
fr: L'algorithme de tri du gnome repose sur la manière habituelle de travailler des nains de jardin pour trier une ligne de pots de fleurs: Le nain regarde le pot de fleur qui est à côté de lui et il regarde également le pot de fleurs juste après&nbsp;; si ces deux pots sont alignés dans le bon ordre, le nain se déplace en avant d'un pot de fleurs, sinon il les échange et se déplace en arrière d'un pot de fleur. Condition aux limites&nbsp;: si il n'y a pas de pot de fleurs précédent, le nain avance ; si il n'y a pas de pot suivant alors il a terminé sa tâche.

note: type: Content of: <h1>
en: The Dutch Flag Problem
fr: Le problème du drapeau hollandais

note: type: Content of: <p>
en: This problem was first proposed by E.W Dijkstra in 1976 (in the chapter 14 of his book "A Discipline of Programming").  It is a very classical variation of the sorting algorithms since then. It is sometimes useful in real life, but it became famous for its pedagogical properties: its complexity is not trivial, but not complex either.  It can easily be formally proven, but it's not absolutely trivial either.
fr: Ce problème a été proposé pour la première fois par E.W.Dijkstra en 1976 (dans le chapitre 14 de son livre «A discipline of Programming»). C'est une variation très étudiée du tri par insertion depuis. Ce tri est parfois utile dans la vraie vie, mais il est surtout célèbre pour ses vertus pédagogiques : calculer sa complexité n'est ni trop simple ni trop dur, démontrer sa correction est très accessible sans être complètement trivial.

note: type: Content of: <ul><li>
en: A temporal view could be welcomed.
fr: Une vue temporelle serait bienvenue.

note: type: Content of: <ul><li>
en: Other exercises, for example with 2 colors only or with more than 3 colors, could generalize the proposed approach.
fr: D'autres exercices, par exemple avec seulement deux couleurs ou avec plus de 3 couleurs, pourraient généraliser l'approche.

note: type: Content of: <ul><li>
en: This problem could be solved recursively.
fr: Ce problème peut être résolu récursivement.

note: type: Content of: <p>
en: This is a classical sorting problem, constituting a variation over the insertion sort.
fr: C'est un problème classique, qui constitue une variation du tri par insertion.

note: type: Content of: <p>
en: Your work is to sort all the colors of the Dutch flag, and the only provided primitive is to exchange two given lines.  In addition, you should not create any additional variables (but a few indices).
fr: Votre travail est de trier les couleurs du drapeau hollandais. La seule primitive à votre disposition permet d'échanger deux lignes données. De plus, vous ne devez pas créer de nouvelles variables (à l'exception de quelques indices).

note: type: Content of: <p>
en: If you think carefully, this can be done in linear time, where you sort a line at each iteration of the loop.  You may want to check again the <a href="plm://lessons.sort.basic/insertion.AlgInsertionSort">insertion sort</a>, of which the Dutch Flag sort is a variation. The main difference is that you have 3 insertion points, not only one...
fr: À la réflexion, on peut le faire en temps linéaire, en triant un élément à chaque étape de la boucle. Vous devriez peut-être réviser comment se passe le <a href="plm://lessons.sort.basic/insertion.AlgInsertionSort">tri par insertion</a>, car le tri du drapeau hollandais est une variation sur le thème. La principale différence est que vous n'avez pas un seul point d'insertion, mais 3...

note: type: Attribute 'alt' of: <div>
en: I need an hint to start
fr: J'ai besoin d'un indice pour commencer.

note: type: Content of: <div>
en: Do a traversal over your data, saving 3 indices:
fr: Traversez vos données, en maintenant trois indices :

note: type: Content of: <div><ul><li>
en: <code>afterBlue</code> is initialized to 0. Make sure that every cell below <code>afterBlue</code> is filled with blue elements.
fr: <code>apresBleu</code> est initialisé à 0. Assurez vous de n'avoir que des cellules bleues entre 0 et <code>apresBleu</code> à tout moment.

note: type: Content of: <div><ul><li>
en: <code>whiteRed</code> is initialized to size-1. Make sure that every cell after <code>whiteRed</code> is filled with red elements.
fr: <code>blancRouge</code> est initialisé à taille-1. Assurez vous de n'avoir que des cellules rouges après <code>blancRouge</code>.

note: type: Content of: <div><ul><li>
en: <code>beforeWhite</code> is initialized to size-1. Make sure that every cell after <code>beforeWhite</code> and before <code>whiteRed</code> is filled with white elements.
fr: <code>avantBlanc</code> est initialisé à taille-1. Assurez vous de n'avoir que des cellules blanches entre <code>avantBlanc</code> et <code>blancRouge</code>.

note: type: Content of: <div>
en: Note that the unsorted cells are always between <code>afterBlue</code> and <code>beforeWhite</code>.
fr: Remarques que les cellules non triées sont toujours entre <code>apresBleu</code> et <code>avantBlanc</code>.

note: type: Content of: <div>
en: At each step of your traversal, check the color of the cell at <code>afterBlue</code> and do the required exchanges.  The loop ending condition is when <code>afterBlue</code> becomes larger than <code>beforeWhite</code>.
fr: À chaque étape de votre traversée, regardez la couleur de la case pointée par <code>apresBleu</code> et effectuez les échanges qui s'imposent. La boucle s'arrête quand <code>apresBleu</code> devient plus grand que <code>avantBlanc</code>.

note: type: Content of: <h2>
en: Provided values
fr: Valeurs fournies

note: type: Content of: <p>
en: The colors are represented through the following constants: BLUE, WHITE and RED.  You can use them directly in your code.
fr: Les couleurs sont représentées par les constantes suivantes : BLEU, BLANC et ROUGE. Vous pouvez les utiliser directement dans votre code.

note: type: Content of: <h2>
en: Provided functions
fr: Fonctions fournies

note: type: Content of: <p>
en: This world is very simple, with only 5 provided functions.
fr: Cet univers est très simple, avec seulement cinq fonctions fournies.

note: type: Content of: <pre>
en: [!java|c]void [/!]swap([!java|c]int [/!]x[!scala]:Int[/!], [!java|c]int [/!]y[!scala]:Int[/!])
fr: [!java|c]void [/!]echange([!java|c]int [/!]x[!scala]:Int[/!], [!java|c]int [/!]y[!scala]:Int[/!])

note: type: Content of: outside any tag (error?)
en: Swap the lines number <code>x</code> and <code>y</code>.
fr: Échange les lignes numéros <code>x</code> et <code>y</code>.

note: type: Content of: <pre>
en: [!java|c]int [/!]getSize() [!scala]:Int[/!]
fr: [!java|c]int [/!]getTaille()  [!scala]:Int[/!]

note: type: Content of: outside any tag (error?)
en: Returns the amount of lines on this flag.
fr: Retourne le nombre de lignes sur ce drapeau.

note: type: Content of: <pre>
en: [!java|c]int [/!]getColor([!java|c]int [/!]line[!scala]:Int[/!])  [!scala]:Int[/!]
fr: [!java|c]int [/!]getCouleur([!java|c]int [/!]ligne[!scala]:Int[/!])  [!scala]:Int[/!]

note: type: Content of: outside any tag (error?)
en: Returns the color of the given line.
fr: Retourne la couleur d'une ligne donnée.

note: type: Content of: <pre>
en: [!java]boolean [/!][!c]int [/!]isSorted()  [!scala]:Boolean[/!]
fr: [!java]boolean [/!][!c]int [/!]estTrie() [!scala]:Boolean[/!]

note: type: Content of: outside any tag (error?)
en: Returns whether the flag is sorted.
fr: Renvoie si le drapeau est correctement trié.

note: type: Content of: <pre>
en: [!java]boolean [/!][!c]int [/!]isSelected()  [!scala]:Boolean[/!]
fr: [!java]boolean [/!][!c]int [/!]estSelectionne() [!scala]:Boolean[/!]

note: type: Content of: outside any tag (error?)
en: Returns whether the current world is selected in the interface.
fr: Renvoi si le monde actuel est sélectionné dans l'interface graphique.

note: type: Content of: <h1>
en: PancakeWorld
fr: Monde des crêpes

note: type: Content of: <p>
en: This universe is very simple, with only five functions provided.
fr: Cet univers est très simple, avec seulement cinq fonctions fournies.

note: type: Content of: <pre>
en: [!java|c]int [/!]getStackSize()  [!scala]:Int[/!]
fr: [!java|c]int [/!]getTaillePile()  [!scala]:Int[/!]

note: type: Content of: outside any tag (error?)
en: Returns the size of the stack, that is the amount of pancakes it contains.
fr: Renvoie la taille du tas de crêpes, c'est à dire le nombre de crêpes qui le compose.

note: type: Content of: <pre>
en: [!java|c]int [/!]getPancakeRadius([!java|c]int [/!]rank[!scala]:Int[/!])  [!scala]:Int[/!]
fr: [!java|c]int [/!]getRayonCrepe([!java|c]int [/!]rang[!scala]:Int[/!])  [!scala]:Int[/!]

note: type: Content of: outside any tag (error?)
en: Returns the radius of the pancake passed as argument, with the rank of the top-most pancake being 0.
fr: Renvoie le rayon de la crêpe passée en argument, sachant que le rang de la crêpe du haut est 0.

note: type: Content of: <pre>
en: [!java]boolean [/!][!c]int [/!]isPancakeUpsideDown([!java|c]int [/!]rank[!scala]:Int[/!])   [!scala]:Boolean[/!]
fr: [!java]boolean [/!][!c]int [/!]estCrepeRetournee([!java|c]int [/!]rang[!scala]:Int[/!])   [!scala]:Boolean[/!]

note: type: Content of: outside any tag (error?)
en: Returns whether the pancake passed as argument upside-down, that is, if its burned side is on top. As usual, the top-most pancake is of rank 0.
fr: Renvoie si la crêpe passée en paramètre (la crêpe du haut étant de rang 0) est à l'envers, c'est-à-dire si sa face brûlée est en haut.

note: type: Content of: <pre>
en: [!java|c]void [/!]flip([!java|c]int [/!]amount[!scala]:Int[/!])
fr: [!java|c]void [/!]retourne([!java|c]int [/!]quantité[!scala]:Int[/!])

note: type: Content of: outside any tag (error?)
en: Flips the <code>amount</code> first pancakes composing the stack, from the top of it.
fr: Retourne les <code>quantité</code> premières crêpes de la pile, en partant du sommet de celle-ci.

note: type: Content of: <pre>
en: [!java]boolean [/!][!c]int [/!]isSorted()   [!scala]:Boolean[/!]
fr: [!java]boolean [/!][!c]int [/!]estTriee()   [!scala]:Boolean[/!]

note: type: Content of: outside any tag (error?)
en: Returns whether the pancake stack is correctly sorted.
fr: Renvoie si la pile de crêpes est correctement triée.

note: type: Content of: <pre>
en: [!java]boolean [/!][!c]int [/!]isSelected()   [!scala]:Boolean[/!]
fr: [!java]boolean [/!][!c]int [/!]estSelectionne() [!scala]:Boolean[/!]

note: type: Content of: <h1>
en: Pancake Sorting
fr: Trier des crêpes

note: type: Content of: <p>
en: This activity is inspired by a problem first introduced in 1975 by Harry Dweighter in the American Mathematical Monthly. The question is not only to sort the pancakes, but to determine <code>f(n)</code> the <i>minimal</i> amount of flips mandated to sort any stack of size <code>n</code>.
fr: Cette activité est inspirée d'un problème introduit pour la première fois en 1975 par Harry Dweighter dans le journal de mathématique «American Mathematical Monthly». La question n'est pas tant de trier les crêpes que de déterminer <code>f(n)</code>, le nombre <i>minimal</i> de retournements nécessaires pour trier n'importe quelle pile de taille <code>n</code>.

note: type: Content of: <p>
en: This problem is now famous because Bill Gates authored (with C. Papadimitriou) his only scientific publication in 1979 on this topic, providing a faster algorithm and proving that <code>17n/16 ≤ f(n) ≤ (5n+5)/3</code>.  This was the only publication of Bill Gates before he invented Windows and became rich.
fr: Ce problème est maintenant célèbre car Bill Gates a publié son seul article scientifique sur ce sujet (avec C. Papadimitriou). Ils ont proposé un algorithme plus rapide et démontré ainsi que <code>17n/16 ≤ f(n) ≤ (5n+5)</code>. Ce fut la seule publication de Bill Gates avant qu'il n'invente Windows et devienne riche.

note: type: Content of: <p>
en: Then, David X. Cohen, the inventor of the Futurama comics with many mathematical references, introduced the variant with burnt pancakes and studied its complexity with Manuel Blum in 1993.
fr: Par la suite, David X. Cohen, l'inventeur du dessin animé Futurama aux nombreuses références mathématiques, introduit en 1993 la variante des crêpes brûlées et étudie sa complexité avec Manuel Blum.

note: type: Content of: <p>
en: An article of 2011 (by L. Bulteau, G. Fertin and I. Rusu) proved that determining the minimal amount of flips to sort the stack is a NP-complete problem. Naturally, the stack sorting problem is not NP-complete since it can be solved in 2n-3 steps with the naive algorithm and (5n+5)/3 steps with the Gates algorithm.  That's determining the minimal amount of steps that is NP.
fr: Un article de 2011 (par L. Bulteau, G. Fertin and I. Rusu) a prouvé que ce problème est NP-Complet, c'est à dire qu'il n'existe pas d'algorithme efficace pour déterminer le nombre minimal de retournements pour toute taille de pile. Naturellement, le problème du tri de la pile n'est pas NP-complet en lui-même puisqu'on peut le résoudre en 2n-3 étapes avec l'algorithme naïf et (5n+5)/3 étapes avec l'algorithme de Gates. C'est la détermination du nombre minimal de coups qui est NP.

note: type: Content of: <p>
en: Further information can be found on the wikipedia page, as usual.
fr: Pour plus d'information, référez vous à la page anglophone de Wikipedia (http://en.wikipedia.org/wiki/Pancake_sorting) ou à cette page, très bien faite: http://eljjdx.canalblog.com/archives/2013/02/03/26309722.html

note: type: Content of: <p>
en: This activity is also integrated to CSIRL (my repository of <i>free</i> unplugged activities to introduce computer science, available at http://www.loria.fr/~quinson/Mediation/SMN/), and it may be interesting to run the unplugged activities before implementing these algorithms in PLM.
fr: Cette activité est également intégrée à SMN (mon dépôt d'activités débranchées <i>libres</i> pour introduire la science informatique, disponible à l'adresse http://www.loria.fr/~quinson/Mediation/SMN/), et il peut être intéressant de faire les activités débranchées avant d'implémenter ces algorithmes dans PLM.

note: type: Content of: <ul><li>
en: A temporal view similar to the sorting universe could be helpful
fr: Une vue temporelle comme celle de l'univers des tris pourrait être pratique.

note: type: Content of: <ul><li>
en: Other exercises, for example on the Roti sorting, with a pile of Roti that have to touch the grill on each face (see http://en.wikipedia.org/wiki/Pancake_sorting#The_identical_pancake_stack).
fr: D'autres exercices, comme le tri des cheese nans, avec une pile de nans qui doivent chacun toucher le grill sur les deux faces pour être bien grillés (voir  http://en.wikipedia.org/wiki/Pancake_sorting#The_identical_pancake_stack).

note: type: Content of: <h3>
en: The pancake problem
fr: Le crêpier psychorigide

note: type: Content of: <p>
en: Help the poor psychorigid pancakes' chef to sort its pancake stack!
fr: Aidez le pauvre crêpier psychorigide à trier sa pile de crêpes !

note: type: Content of: <p>
en: This funny problem leads to algorithms that are somewhat more challenging to implement. You are supposed to master the bases of programming and some sorting algorithms to take this lesson.
fr: Ce problème amusant débouche sur des algorithmes un peu plus compliqués à implémenter. Vous devez maîtriser les bases de la programmation ainsi que quelques algorithmes de tri avant de tenter cette leçon.

note: type: Content of: <p>
en: The pancake sorting problem is a simple puzzle where you have a set of pancakes, each of differing size. The chef cooking the pancake is a bit psychorigid: he hates when the pancakes are not correctly sorted on the plate. He loves when they are correctly ordered, with the small ones over the larger ones. As every pancake maker, he masters the pancake flipping with his spatula. He can flip the pancake on top of the stack, or even several pancakes at once. The thing is that he has only one plate and the table is too dirty to place pancakes on it, even temporary. The only allowed operation is to flip some pancakes that are on top of the stack.
fr: Le problème du tri des crêpes est un puzzle simple où vous avez une pile de
    crêpes, toutes de taille différente. Le crêpier étant légèrement psychorigide,
    il déteste quand ses crêpes ne sont pas bien ordonnées dans l'assiette. Il ne se
    sent bien que quand elles sont bien rangées, avec les petites au dessus des
    grandes. Comme tous les crêpiers, il est passé maître dans l'art du retournement
    de crêpes à la spatule. Il peut retourner une crêpe au sommet de la pile, ou
    même plusieurs à la fois. Le truc est qu'il n'a qu'une seule assiette et que la
    table est trop sale pour poser des crêpes dessus, même temporairement. La seule
    opération autorisée est alors de retourner un certain nombre de crêpes au sommet
    de la pile.

note: type: Content of: <p>
en: Your work is to help this poor guy sorting his stack by flipping the pancakes. Each pancake is defined by its radius and rank within the stack, with the top-most pancake is at rank 0, and the one below at rank 1.
fr: Vous devez aider ce pauvre homme à trier sa pile en retournant des crêpes. Chaque crêpe est définie par son rayon et son rang dans la pile. La pile la plus haute est de rang 0, et celle placée au dessous d'elle est de rang 1.

note: type: Content of: <p>
en: Note that you can play physically with pieces of paper or wood at first to get the grasp on this problem. This is even one of the activities that I use in my CS-IRL (computer science in real life) project to introduce the concept of algorithm to absolute beginners that wonder about our science. More information at http://www.loria.fr/~quinson/Mediation/SMN/ (in French).
fr: Il est conseillé de commencer par jouer physiquement avec des bouts de papier ou de carton pour bien comprendre le problème. C'est même l'une des activités que j'utilise dans mon projet SMN (Sciences Manuelles du Numérique) pour introduire le concept d'algorithme aux débutants curieux de notre science. Pour plus d'information, allez visiter le site du projet: http://www.loria.fr/~quinson/Mediation/SMN/

note: type: Attribute 'alt' of: <p><div>
en: I don't get it. I need some help.
fr: Je suis perdu, j'ai besoin d'aide.

note: type: Content of: <p><div>
en: You should try to first move the largest pancake to the bottom, and then the largest but one pancake on top of it, and then the one just smaller on top, and so on.
fr: Vous devez tout d'abord parvenir à placer la plus grande crêpe en bas de la pile et ensuite placer celle juste plus petite au dessus, puis celle plus petite et ainsi de suite.

note: type: Attribute 'alt' of: <p><p><div>
en: The first tip was not enough. I need another one.
fr: Ce premier indice n'était pas suffisant, j'ai besoin de plus d'aide.

note: type: Content of: <p><div>
en: So first, you need to move the largest pancake at the bottom of the stack.
fr: Il vous faut donc amener la plus grande des crêpes tout en bas de la pile.

note: type: Content of: <p><div>
en: Can you imagine a situation in which you can easily bring this damn large pancake to the bottom?
fr: Est ce que vous pouvez imaginer une situation où il est facile d’emmener cette satanée grande crêpe tout en bas ?

note: type: Content of: <p><div>
en: How could you reach this situation from the current one?
fr: Et comment pourriez vous parvenir à cette situation à partir de la situation courante?

note: type: Content of: <h1>
en: Bubble Pancakes
fr: Crêpes et bulle

note: type: Content of: <p>
en: This problem is similar to the previous: you have to sort the pancakes, the smallest at the top and the biggest at the bottom, except you can only flip them to sort.
fr: Cet exercice ressemble au précédent: il faut que vous triiez les crêpes, la plus petite en haut de la pile, et la plus grande en bas de la pile, sauf que vous ne pouvez seulement en retourner qu’un certain nombre.

note: type: Content of: <p>
en: The purpose here is to sort them using the bubble algorithm, where one pancake is moved to the bottom until it encounters a bigger one. In graphical representations, it looks like a bubble takes the element and move them through the pile. This is where its name comes from.
fr: L'objectif ici est de trier les crêpes en utilisant l'algorithme du tri à bulle, où une crêpe est déplacée vers le bas de la pile jusqu'à qu'elle en rencontre une plus grande. Dans les représentations graphiques, cela se matérialise par une bulle qui prend un élément et le déplace sur toute la pile, d'où le nom de "tri à bulle".

note: type: Content of: <p>
en: Now, using pancakes makes it a little more difficult to write, because you have to find a way to swap only two pancakes at a time.
fr: Maintenant, l'utilisation de crêpes rend l'algorithme un peu plus difficile à écrire, car vous devez trouver un moyen d'échanger de place seulement deux crêpes à la fois.

note: type: Content of: <p><div>
en: The bubble algorithm consists in browsing the whole pile from top to bottom, and making a comparision between two pancakes. Each time the top pancake is bigger than the one below, you have to swap them, then compare the bigger pancake you just swapped with one below, and so on. You have to browse through the entire pile until no swap has occurred, in which case the pile is sorted.
fr: Le tri à bulle consiste à parcourir la pile entière, de haut en bas, et d'effectuer des comparaisons entre deux crêpes. Chaque fois que la crêpe du dessus est plus grande que celle du dessous, il faut que vous les échangiez, puis que vous compariez la crêpe que vous venez de déplacer avec celle du dessous, et ainsi de suite. Vous devez continuer à parcourir toute la pile jusqu'à que vous ne déplaciez plus aucune crêpe, auquel cas la pile est triée.

note: type: Content of: <p><p><div>
en: If you don't understand the basic bubble sorting algorithm, you should try the exercises within the “Sorting algorithms” lesson. If you do, but can't figure a way to swap only two pancakes at a time, think of a situation where only two pancakes are swapped at a time, and find a way to reach that situation.
fr: Si vous ne comprenez pas l'algorithme de tri à bulle de base, vous devriez d'abord essayer les exercices le concernant dans la leçon "Algorithmes de tri". Si c'est plutôt le fait d'échanger seulement deux crêpes à la fois qui vous pose problème, cherchez une situation où seulement deux crêpes sont échangées, et trouver un moyen d'arriver à cette situation.

note: type: Content of: <h1>
en: Burned Pancakes
fr: Crêpes brûlées

note: type: Content of: <p>
en: Hard blow for the chef! The pancakes got burnt on one side! There is no way he can deliver a stack of pancakes with visibly burnt pancakes! You've got to help him ensuring that no pancake is upside-down while sorting his stack.
fr: Coup dur pour le crêpier! Les crêpes ont brûlé sur une face! Il est strictement impossible qu'il serve une pile de crêpes où l'on voit la face brûlée! Vous devez absolument l'aider à s'assurer qu'aucune face visible ne soit brûlée tandis qu'il trie sa pile.

note: type: Content of: <h1>
en: Faster Pancake Sorting
fr: Tri rapide de crêpes

note: type: Content of: <p>
en: Unlike others sorting problem, the expensive operation is not the comparison of values, but the flipping of pancakes. In this exercise, we will explore another algorithm that attempt to reduce the amount of stack flipping. The funny side is that this algorithm was first introduced by Bill Gates, before invented Windows.
fr: Contrairement aux problèmes classiques de tri, l'opération coûteuse à économiser n'est pas la comparaison des valeurs, mais le retournement des crêpes. Dans cet exercice, nous allons explorer un autre algorithme permettant de réduire le nombre de retournements nécessaires pour trier la pile. Fait amusant, cet algorithme a été proposé pour la première fois par Bill Gates, avant qu'il n'invente Windows.

note: type: Content of: <p>
en: The basic idea is to grow sequences of sorted pancakes, not necessarily starting from the bottom.  We say that a sequence of ordered pancakes constitute a <b>block</b> while a pancake that is not part of a block is said to be <b>free</b>. The algorithm then considers the topmost pancake (of radius <code>t</code>) and search for the <code>t+1</code> or <code>t-1</code> pancakes (the considered neighbor is noted <code>t+o</code>). Eight cases may happen:
fr: L'idée de base est de faire grandir des séquences de crêpes triées, pas forcément en commençant du bas de la pile. On dira qu'un ensemble de crêpes dans l'ordre constitue un <b>block</b> tandis qu'une crêpe qui n'est pas dans un bloc est dite <b>libre</b>. L'algorithme considère la crêpe tout en haut de la pile, dont la taille est notée <code>t</code>, et cherche les deux crêpes de taille <code>t-1</code> et <code>t+1</code> (le voisin ainsi considéré est noté <code>t+o</code>). Huit cas sont possibles alors&nbsp;:

note: type: Content of: <ul><li>
en: <b>Case a</b>: Both <code>t</code> and <code>t+o</code> are free. They are then merged in one flip.
fr: <b>Cas a</b>: <code>t</code> et <code>t+o</code> sont tous les deux libres. Ils sont alors fusionnés en un retournement.

note: type: Content of: <ul><li>
en: <b>Case b</b>: <code>t</code> is free, and <code>t+o</code> is the first of a block. They are merged in one flip.
fr: <b>Cas b</b>: <code>t</code> est libre, et <code>t+o</code> est le premier élément d'un bloc. Ils sont fusionnés en un bloc.

note: type: Content of: <ul><li>
en: <b>Case c</b>: <code>t</code> is free but both <code>t-1</code> and <code>t+1</code> are the last elements of blocks.  Both blocks and <code>t</code> are merged all together in 4 flips.  Beware, if either <code>t-1</code> or <code>t+1</code> does not exist (because <code>t</code> is 0 or max), only two flips are mandated.
fr: <b>Cas c</b>: <code>t</code> est libre, mais <code>t-1</code> et <code>t+1</code> sont tous les deux les derniers éléments de blocs. Ces deux blocs ainsi que <code>t</code> sont tous fusionnés en 4 retournements. Prenez garde, si <code>t-1</code> ou <code>t+1</code> n'existe pas (parce que <code>t</code> est 0 ou max), seulement deux de ces retournements sont nécessaires.

note: type: Content of: <ul><li>
en: <b>Case d</b>: <code>t</code> is in a block but <code>t+o</code> is free. They are merged in one flip.
fr: <b>Cas d</b>: <code>t</code> est dans un bloc, mais <code>t+o</code> est libre. Ils sont fusionnés en un retournement.

note: type: Content of: <ul><li>
en: <b>Case e</b>: <code>t</code> is in a block and <code>t+o</code> is the first element of a block. They are merged in one flip.
fr: <b>Cas e</b>: <code>t</code> est dans un bloc, et <code>t+o</code> est le premier élément d'un bloc. Ils sont fusionnés en un retournement.

note: type: Content of: <ul><li>
en: <b>Case f</b>: <code>t</code> is in a block and <code>t+o</code> is the last element of another block.  They are merged in 3 flips as follows.
fr: <b>Cas f</b>: <code>t</code> est dans un bloc, et <code>t+o</code> est le dernier élément d'un autre bloc. Ils sont fusionnés en trois retournements comme suit.

note: type: Content of: <ul><li>
en: <b>Case g</b>: <code>t</code> is in a block of length k+1 (the last element is <code>t+ko</code>), <code>t+(k+1)o</code> is either free or the last element of another block. Both blocks are merged in 2 flips:
fr: <b>Cas g</b>: <code>t</code> est dans un bloc de taille k+1 (le dernier élément est <code>t+ko</code>), <code>t+(k+1)o</code> est soit libre soit le dernier élément d'un autre bloc. Les deux blocs sont fusionnés en deux retournements:

note: type: Content of: <ul><li>
en: <b>Case h</b>: <code>t</code> is in a block of length k+1 (the last element is <code>t+ko</code>), <code>t+(k+1)o</code> is the first element of another block (the difference with case g is that <code>t+(k+1)o</code> is now the <i>first</i> element of its block). Both blocks are merged in 2 flips:
fr: <b>Cas h</b>: <code>t</code> est dans un bloc de taille k+1 (le dernier élément est <code>t+ko</code>), <code>t+(k+1)o</code> est le premier élément d'un autre bloc (la différence avec le cas g est que <code>t+(k+1)o</code> est maintenant le <i>premier</i> élément de son bloc). Les deux blocs sont fusionnés en deux retournements:

note: type: Content of: <ul><li>
en: <b>Case i</b>: <code>t</code> is in a block of length <code>n</code> (this block contains all pancakes).  If <code>t</code> is not 1, the whole stack is fliped. The algorithm then stops.
fr: <b>Cas i</b>: <code>t</code> est dans un bloc de taille <code>n</code>, qui contient donc toutes les crêpes. Si <code>t</code> n'est pas 1, toute la pile est retournée. Ensuite, l'algorithme s'arrête.

note: type: Content of: <p>
en: Each iteration increases the size of the blocks, so the algorithm eventually halts in all cases. A finer analysis would show that it takes at most <code>(5n+5)/3</code> steps to sort the stack. That's better than the naïve algorithm, that requires 2n-3 steps.
fr: Chaque itération augmente la taille des blocs, donc la terminaison de l'algorithme est certaine. Une analyse plus fine montre qu'il prend au plus <code>(5n+5)/3</code> étapes pour trier la pile. C'est mieux que l'algorithme naïf, qui nécessite <code>2n-3</code> étapes pour cela.

note: type: Content of: <h2>
en: Your turn
fr: À vous de jouer

note: type: Content of: <p>
en: You now have almost enough information to implement this algorithm on your own. We just have to remove the last remaining ambiguities to ensure that you implement exactly the same algorithm that the correction. If several cases apply to your situation, then you should use the first given one. For example, if both cases a and b apply (e.g., with <code>t-1</code> on case <b>a</b> and <code>t+1</code> on case <b>b</b>), then you should apply the flips of case <b>a</b>. If a given case applies for both <code>t+1</code> and <code>t-1</code>, then you should apply it to <code>t+1</code>.
fr: Vous avez maintenant quasi assez d'informations pour implémenter cet algorithme par vous-même. Il faut juste lever les dernières ambiguïtés pour que vous implémentiez exactement le même algorithme que la correction. Si plusieurs cas s'appliquent à la situation courante, appliquez le premier. Par exemple, si les cas a et b s'appliquent (avec <code>t-1</code> pour le cas a et <code>t+1</code> pour le cas b), vous devez appliquer les instructions du cas <b>a</b>. Si un cas donné s'applique à la fois pour <code>t+1</code> et <code>t-1</code>, appliquez le pour <code>t+1</code>.

note: type: Content of: <p>
en: Note that it is somehow harder than the other exercises we did so far, so don't be surprised if you need more time to achieve this.  But do not give up hope, you can do it!
fr: Cet exercice est plus difficile que ceux que nous avons fait jusque là, et il ne serait pas choquant que vous ayez besoin d'un peu plus de temps que les autres pour le résoudre. Mais n'abandonnez pas, vous pouvez le faire !

note: type: Attribute 'alt' of: <p><div>
en: Well, I need some help to start.
fr: Heu, j'ai besoin d'un peu d'aide pour commencer.

note: type: Content of: <p><div>
en: First write some helper functions such as <code>isFirst()</code> or <code>isFree()</code>. This will simplify your main algorithm afterward, that can be written very similarly to the explication above with a bunch of if conditions. Factorizing code this way often helps making your code more readable.
fr: Commencez par écrire des fonctions d'aide, comme <code>estLibre()</code> ou <code>estPremier()</code>. Cela simplifiera l'écriture de votre algorithme, qui peut être écrit sous une forme très similaire à l'énoncé si vous faites les bonnes fonctions d'aide. Factoriser ainsi votre code aide très souvent à améliorer la lisibilité du code.

note: type: Attribute 'alt' of: <p><div>
en: My code keeps failing and I don't know how to debug it.
fr: Mon code ne fonctionne pas, et je ne sais pas comment le débugger

note: type: Content of: <p><div>
en: To debug one world after the other and avoid that the messages of all worlds get intermixed, you can write your debug function only if the method <code>isSelected()</code> returns true. It will be so only for the entity that is currently selected in the graphical interface, that is probably the world you are currently debugging. This will help breaking the difficulty in parts by debugging the situation one after the other.
fr: Pour débugger un monde après l'autre, il est préférable d'éviter que les affichages de tous les mondes se mélangent. Le plus simple pour cela est d'utiliser la méthode <code>isSelected()</code> qui ne renvoi vrai que si le monde courant est celui sélectionné dans l'interface. Cela aidera à réduire la complexité en résolvant les problèmes les uns après les autres.

note: type: Content of: <p><div>
en: In particular, it may help to print textually the state of the world each time you enter the main loop.
fr: En particulier, afficher l'état du monde sous forme textuelle à chaque fois que vous rentrez dans la boucle principale peut aider.

note: type: Content of: <h1>
en: Faster Burned Pancake Sorting
fr: Tri rapide de crêpes brûlées

note: type: Content of: <p>
en: The Gates' algorithm that we saw in the previous exercise quickly sort a stack of unburned pancakes by increasing the size of the blocks of sorted pancakes. This is much faster that the naive algorithm which moves at each step the largest pancake to the bottom of still unsorted pancakes. Gates' algorithm manages to sort a stack of <i>n</i> pancakes in less than <i>(5n + 5)/3</i> steps in the worst case, while the naive algorithm requires at most <i>2n</i> steps. Gates is thus about one third faster in the worst case.
fr: L'algorithme de Gates que nous avons vu dans l'exercice précédent trie rapidement les crêpes non brûlées en augmentant constamment la taille de sous-séquences triées dans la pile. Cela va bien plus vite que l'algorithme naïf qui déplace à chaque étape la plus grande crêpe en bas de la pile non-triée. L'algorithme de Gates trie une pile de <i>n</i> crêpes en moins de  <i>(5n + 5)/3</i> étapes dans le pire des cas là où l'algorithme naïf nécessite <i>2n</i> étapes. L'algorithme de Gates est donc un tiers plus rapide dans le pire des cas.

note: type: Content of: <p>
en: In this exercise, we will explore an adaptation of the same idea to burnt pancakes. This was first published by David X. Cohen and Manuel Blum. David Cohen co-founded a few years later the Futurama TV show full of mathematical jokes. Definitively, interesting people studied that little pancake problem...
fr: Dans cet exercice, nous allons explorer une adaptation de la même idée aux crêpes brûlées. Cet algorithme fut tout d'abord publié par David X. Cohen et Manuel Blum. Quelques années après, David Cohen lançait avec un ami la série Futurama, remplie de blagues mathématiques. Décidément, ce petit problème de crêpes a inspiré des gens intéressant...

note: type: Content of: <p>
en: The Cohen's algorithm is slightly easier than the Gates' one since it distinguishes less cases:
fr: L'algorithme de Cohen est un peu plus simple que celui de Gates, car il distingue moins de cas :

note: type: Content of: <p>
en: <b>Case 1:</b> At least one pancake is rightside up in the stack. Let <i>p</i> be the largest such pancake.  Note that <i>p + 1</i> must therefore be upside down, unless <i>p = n</i> (in which case there is no <i>p + 1</i> pancake).
fr: <b>Cas 1 :</b> Au moins une crêpe est à l'endroit dans la pile. Soit <i>p</i> la plus grande des crêpes à l'endroit. Notez que <i>p + 1</i> est donc forcément à l'envers, à moins que <i>p = n</i> (auquel cas il n'y a pas de crêpe <i>p + 1</i>).

note: type: Content of: <ul><li>
en: <b>Case 1.a:</b> <i>p+1</i> is lower in the stack than <i>p</i>.
fr: <b>Cas 1.a :</b> <i>p+1</i> est placée plus bas que <i>p</i> dans la pile.

note: type: Content of: <ul><li>
en: <b>Case 1.b:</b> <i>p+1</i> is higher in the stack than <i>p</i>.
fr: <b>Cas 1.b :</b> <i>p+1</i> est placée plus haut que <i>p</i> dans la pile.

note: type: Content of: <ul><li>
en: <b>Case 1.c:</b> There is no <i>p+1</i> because <i>p</i> is the largest pancake in stack, that is because <i>p = n</i>.  If pancake <i>p</i> is already in position, there is nothing to do. If not, you can move it to the bottom of the stack in 2 flips:
fr: <b>Cas 1.c :</b> Il n'y a pas de crêpe <i>p + 1</i> car <i>p</i> est la plus grande crêpe de la pile (c'est à dire que <i>p = n</i>). Si la crêpe <i>p</i> est déjà en position, il n'y a rien à faire. Dans le cas contraire, on peut l'amener en bas de la pile en deux opérations :

note: type: Content of: <ul><li>
en: <b>The trick is that the pancake <i>p</i> should never be considered again.</b> Otherwise, you will consider that pancake again and again since it's rightside up, and since that's the largest pancake. To leave that pancake alone, you should keep track of the stack size that is still to be sorted. Any traversal of the stack must then only consider these pancakes, leaving alone the ones that are already in position at the bottom of the stack.
fr: <b>Le truc est que la crêpe <i>p</i> ne doit plus jamais être considérée après cela.</b> Dans le cas contraire, vous allez considérer cette crêpe encore et encore puisqu'elle est à l'endroit et que c'est la plus grande des crêpes. Pour la laisser en paix, vous devez garder trace de la taille de la pile restant à trier. Tout balayage de la pile de crêpes doit se limiter aux crêpes restant à trier, sans considérer celles étant déjà en position en bas de la pile.

note: type: Content of: <p>
en: <b>Case 2:</b> All pancakes are downside. Again, we distinguish two sub-cases.
fr: <b>Cas 2 :</b> Toutes les crêpes sont à l'envers. À nouveau, nous distinguons deux sous-cas.

note: type: Content of: <ul><li>
en: <b>Case 2.a:</b> There is at least one <i>p</i> for which <i>p+1</i> is higher than <i>p</i> (if there is several such <i>p</i>, take the largest one).
fr: <b>Cas 2.a :</b> Il y a au moins une crêpe <i>p</i> pour laquelle <i>p+1</i> est placée au dessus de <i>p</i> dans la pile (s'il y a plusieurs tels <i>p</i>, prenez le plus grand).

note: type: Content of: <ul><li>
en: <b>Case 2.b:</b> Any pancake <i>p</i> is lower than pancake <i>p+1</i>. In that case, we must have that setting:
fr: <b>Cas 2.b:</b> Chaque crêpe <i>p</i> est placée plus bas que sa crêpe <i>p+1</i>. Dans ce cas, nous avons forcément la situation suivante :

note: type: Content of: <p>
en: As you can see, we achieve one join in 2 flips in the cases 1 or 2.a. Since we need to achieve n joins to sort the stack, we can sort the stack in <i>2n</i> steps if case 2.b does not occurs.
fr: Dans les cas 1 ou 2.a, nous pouvons fusionner deux crêpes qui doivent se suivre en deux opérations. Puisque nous devons réaliser n fusions de ce genre pour trier la pile, nous pouvons trier la pile en <i>2n</i> opérations si le cas 2.b n'arrive jamais.

note: type: Content of: <p>
en: That case 2.b requires a very different handling as it is obviously not possible to achieve a join in only 2 flips.  But fortunately, we can leverage the very specific setting of the stack in that case to provide the following algorithm.  It sorts a stack in that exact configuration after exactly <i>2n</i> steps.
fr: Ce cas 2.b nécessite un traitement particulier puisqu'il est impossible de fusionner deux crêpes qui doivent se suivre en deux étapes seulement. Fort heureusement, une seule configuration de pile rentre dans ce cas de figure. Nous pouvons alors utiliser l'algorithme suivant, conçu pour tirer partie de cette configuration. Cet algorithme trie alors toute la pile en exactement <i>2n</i> opérations.

note: type: Content of: <pre>
en: Repeat n times
        Flip the whole stack of n pancakes
        Flip the top (n-1) pancakes
fr: Répéter n fois
        Inverser toute la pile de n crêpes 
        Inverser les (n-1) crêpes placées au sommet de la pile

note: type: Content of: <p>
en: It may sound somehow magic, but it actually works, as depicted on an example below.
fr: Cela peut sembler un peu magique, mais cela fonctionne. Le dessin ci-dessous montre même comment.

note: type: Content of: <p>
en: So, all in all, the Cohen algorithm manages to sort the stack of burnt pancakes in <i>2n</i> steps in all cases.  Quite a win over the naive algorithm for burnt pancakes that requires <i>3n</i> steps.
fr: Donc, dans tous les cas, l'algorithme de Cohen parvient à trier une pile de crêpes brûlées en <i>2n</i> étapes, dans tous les cas. C'est mieux que l'algorithme naïf pour crêpes brûlées, qui nécessite <i>3n</i> étapes.

note: type: Attribute 'alt' of: <p><div>
en: I cannot get it right.
fr: Je n'y arrive pas.

note: type: Content of: <p><div>
en: Don't worry. This exercise is very difficult, so it's ok if it does not work right away for you.  Add some relevant logging to your code to understand where it stop performing correctly.  Make sure to use the method <code>isSelected()</code> so that your logs only appears in the currently displayed world. In particular, it may help to print textually the state of the world each time you enter the main loop.
fr: Pas de panique, cet exercice est très difficile, et il est donc normale de ne pas y parvenir du premier coup. Ajouter des affichages à votre code pour voir les différentes étapes, et ainsi comprendre le moment où votre algorithme cesse de se comporter correctement. Assurez vous d'utiliser la méthode <code>isSelected()</code> pour que vos affichages n'aient lieu que pour le monde en cours d'affichage. En particulier, cela peut aider d'afficher textuellement l'état du monde à chaque fois que vous entrez dans la boucle principale.

note: type: Content of: <h1>
en: The Rainbow Baseball Game
fr: Le jeu du baseball multicolore

note: type: Content of: <p>
en: This activity is inspired from the orange game, from the "Computer Science Unplugged" activities repository.  It was however heavily since then, first for the CSIRL (my repository of <i>free</i> unplugged activities to introduce computer science, available at http://www.loria.fr/~quinson/Mediation/SMN/) and now for PLM.
fr: Cette activité est inspirée du jeu de l'orange dans le recueil d'activités «Computer Science Unplugged». Elle a cependant été profondément réarrangée depuis, d'abord pour SMN (mon recueil d'activités <i>libres</i> pour introduire la science informatique, disponible depuis http://www.loria.fr/~quinson/Mediation/SMN/), et maintenant pour PLM.

note: type: Content of: <p>
en: In the literature, the generalized form of this problem is known as the pebble motion problem (the bases can be connected by any kind of graph, and the affinity of pebbles with bases may be different). Another variant of this problem is the well known 15-puzzle, with one player per base, and a two dimensional square grid. Much more information about these problems can be found on wikipedia, as usual.
fr: Dans la littérature scientifique, la forme généralisée de ce problème se nomme «le problème du déplacement des galets» (Pebble motion problem). Les bases peuvent être connectées par un graphe quelconque, et les affinités entre les galets et les bases peuvent être différentes. La plus connue des variantes de ce problème est le jeu du taquin, avec un seul joueur par base et une grille carrée à deux dimensions. On trouve énormément d'informations sur ces problèmes sur les pages Wikipedia anglophones, comme d'habitude.

note: type: Content of: <h3>
en: How do you know that the naive algorithm won't loop on that initial situation?
fr: Comment pouvez vous être sûr que l'algorithme naïf ne boucle pas sur cette situation initiale ?

note: type: Content of: <p>
en: Well, we simply tested all possible situations to see when this algorithm loops and when it finds the correct solution. We found that it works for all situations where no player is at home (there is 84 such situations for 4 bases, once you take the symmetries into account). It obviously works for some situations that do not respect this criteria (such as all situations it encounters from one of those 84 boards to the final state), but that's another story. Having such a criteria allows us to generate pseudo-random initial situations for the first exercise for which the algorithm we propose is guarenteed to work.
fr: Et bien, nous avons testé toutes les situations initiales possibles pour étudier les cas où l'algorithme boucle et ceux où l'algorithme termine correctement. Nous avons trouvé qu'il fonctionne pour toutes les situations où aucun joueur ne se trouve dans sa base (il y a 84 situations de ce genre pour 4 bases, si on élimine les symétries). Bien entendu, l'algorithme fonctionne correctement pour de nombreuses situations ne respectant pas ce critère (telles que toutes les situations rencontrées quand on commence de l'une de ces 84 situations), mais c'est une autre histoire. Avoir un tel critère nous permet de générer des situations initiales pour ce premier exercice de manière pseudo-aléatoire tout en étant sûrs que l'algorithme proposé se comportera correctement.

note: type: Content of: <p>
en: We also explored bigger instances of the problem, and unfortunately, we have no such criteria for them.  With 5 bases, the algorithm wrongly loops for 24 of the 1824 possible boards where no player is home (that's 1.31%).  With 6 bases, it fails on 1251 of the 58860 such boards (2.12%). With 7 bases, it fails for 84444 out of 2633940 (that's 3.2%). I am still looking for a criteria ensuring that the algorithm won't loop. If you discover one, please report it. Ideally, it would be simple to enforce manually so that we can use it during our unplugged activities.
fr: Nous avons également exploré des instances plus grande de ce problème, et malheureusement, nous ne connaissons pas de critère sûr dans ce cas. Avec 5 bases, l'algorithme part en boucle infinie pour 24 des 1824 plateaux possibles où aucun joueur n'est à la maison (cela représente 1,31%). Avec 6 bases, il boucle pour 1251 des 58860 plateaux respectant ce critère (2,12%). Avec 7 bases, il boucle dans 84444 cas sur 2633940 (càd 3,2%). Nous cherchons encore un critère permettant de garantir que l'algorithme ne bouclera pas. Si vous en découvrez un, merci de nous l'indiquer. Ce serait encore mieux s'il était possible de vérifier le critère de tête afin que les animateurs puissent s'en servir pendant les activités débranchées.

note: type: Content of: <ul><li>
en: Other graphical representations could be proposed, such as a linear one (for the existing exercises) or other ones (such as a grid or a tree, if an exercise on this kind of graph proves interesting).
fr: D'autres représentations graphiques pourraient être proposées, comme une représentation linéaire (pour les exercices proposés) ou d'autres comme une grille ou un arbre, si un exercice sur ce type de graphe s'avère intéressant.

note: type: Content of: <ul><li>
en: Other exercises on other algorithms on this variant, or on other variants such as the 15-puzzle.
fr: D'autres exercices à propos d'autres algorithmes pour cette variante du problème, ou bien d'autres variantes comme le jeu du taquin.

note: type: Content of: <h3>
en: Rainbow baseball
fr: Baseball multicolore

note: type: Content of: <p>
en: This is another funny variation on the sorting problem, adapting the main sorting algorithms on an unusual context.
fr: Il s'agit d'un autre problème amusant autour des algorithmes de tri, adaptant les principaux algorithmes de tri à un contexte inhabituel.

note: type: Content of: <h1>
en: Rainbow Baseball
fr: Baseball multicolore

note: type: Content of: <p>
en: The colors are represented by integers, between <code>0</code> and <code>amount of bases -1</code>.  The hole is represented by the special value <code>-1</code>.  The color of each base is its rank. So base <code>1</code> is of color <code>1</code>.  In the graphical interface, the base <code>0</code> is the dark blue one while the base <code>1</code> is the fuscia one.
fr: Les couleurs sont représentées comme des entiers, entre <code>0</code> et <code>nombre de bases - 1</code>. Le trou est représenté par la valeur spéciale <code>-1</code>. La couleur de chaque base est son rang, ce qui fait que la base <code>1</code> est de couleur <code>1</code>. Dans l'interface graphique, la base <code>0</code> est la bleue foncée tandis que la base <code>1</code> est celle fuscia.

note: type: Content of: <p>
en: Once every players on the field are in their home base, the hole should be in the last base, that is of rank <code>getBasesAmount()-1</code>.
fr: Une fois que tous les joueurs du terrain sont chez eux, le trou se trouve dans la dernière base, celle de rang <code>getNombreBases()-1</code>.

note: type: Content of: <h2>
en: Functions to retrieve the world's dimensions
fr: Fonctions pour découvrir les dimensions du monde

note: type: Content of: <pre>
en: [!java|c]int [/!]getBasesAmount() [!scala]:Int[/!]
fr: [!java|c]int [/!]getNombreBases() [!scala]:Int[/!]

note: type: Content of: outside any tag (error?)
en: Returns the amount of bases on this field.
fr: Retourne le nombre de bases dans le terrain.

note: type: Content of: <pre>
en: [!java|c]int [/!]getPositionsAmount() [!scala]:Int[/!]
fr: [!java|c]int [/!]getNombrePositions() [!scala]:Int[/!]

note: type: Content of: outside any tag (error?)
en: Returns the amount of player's positions per base on this field.
fr: Retourne le nombre de positions disponibles par base.

note: type: Content of: <h2>
en: Functions to retrieve the world's state
fr: Fonctions pour découvrir l'état du monde

note: type: Content of: <pre>
en: [!java|c]int [/!]getHoleBase() [!scala]:Int[/!]
fr: [!java|c]int [/!]getTrouBase() [!scala]:Int[/!]

note: type: Content of: outside any tag (error?)
en: Returns the base in which the hole is located.
fr: Retourne l'index de la base où se trouve le trou.

note: type: Content of: <pre>
en: [!java|c]int [/!]getHolePosition() [!scala]:Int[/!]
fr: [!java|c]int [/!]getTrouPosition() [!scala]:Int[/!]

note: type: Content of: outside any tag (error?)
en: Returns the hole position within its base
fr: Retourne la position du trou dans sa base.

note: type: Content of: <pre>
en: [!java|c]int [/!]getPlayerColor([!java|c]int [/!]base[!scala]:Int[/!], [!java|c]int [/!]position[!scala]:Int[/!])  [!scala]:Int[/!]
fr: [!java|c]int [/!]getCouleurJoueur([!java|c]int [/!]base[!scala]:Int[/!], [!java|c]int [/!]position[!scala]:Int[/!])  [!scala]:Int[/!]

note: type: Content of: outside any tag (error?)
en: Returns the color of the player at a given location.
fr: Retourne la couleur d'un joueur donné à partir de sa position.

note: type: Content of: outside any tag (error?)
en: Returns whether all players of the field are at home.
fr: Retourne si tous les joueurs présents sur le terrain sont chez eux.

note: type: Content of: <pre>
en: [!java]boolean [/!][!c]int [/!]isBaseSorted([!java|c]int [/!]base)  [!scala]:Boolean[/!]
fr: [!java]boolean [/!][!c]int [/!]estBaseTriee([!java|c]int [/!]base)  [!scala]:Boolean[/!]

note: type: Content of: outside any tag (error?)
en: Returns whether all players of a given base are at home.
fr: Retourne si tous les joueurs d'une base donnée sont chez eux.

note: type: Content of: <h2>
en: Functions to change the world
fr: Fonctions pour changer le monde

note: type: Content of: <pre>
en: [!java|c]void [/!]move([!java|c]int [/!]base[!scala]:Int[/!], [!java|c]int [/!]position[!scala]:Int[/!])
fr: [!java|c]void [/!]deplace([!java|c]int [/!]base[!scala]:Int[/!], [!java|c]int [/!]position[!scala]:Int[/!])

note: type: Content of: outside any tag (error?)
en: Moves a given player into the hole. This throws an IllegalArgumentException if the specified player is not near the hole (at most one base away).
fr: Déplace un joueur dans le trou. Une exception IllegalArgumentException est levée si le joueur indiqué n'est pas suffisamment près du trou. Il peut être au plus à une base du trou.

note: type: Content of: <h1>
en: Naive Rainbow Baseball
fr: Baseball multicolore naïf

note: type: Content of: <p>
en: Today, the buggles decided to play a baseball game, but they are rather out of luck, actually.  First, kinda forgot the rules, and ... well ... they cannot find the ball and bats again.  So they decided to "adapt a bit" the rules. As the are no ball, the buggles can only running around the field, what they do happily: for a while, all attending buggle run at full speed in all directions around the field.
fr: Aujourd'hui, les buggles ont décidé de faire une partie de baseball, mais il faut avouer que ce n'est pas très bien engagé : elles ne se souviennent plus très bien des règles, et ... euh ... elles ont perdu les battes et les balles. Elles ont donc décidé «d'adapter un peu» les règles. Comme il n'y a plus de balle, la seule chose qu'elles peuvent faire est de courir sur le terrain. C'est d'ailleurs ce qu'elles ont fait pendant un moment : toutes les buggles présentes se sont mises à courir en tous sens sur le terrain.

note: type: Content of: <p>
en: But after a few collisions, they decide to invent new rules to organize a bit the game: They make one team per base and two players per team. One of the teams has only one player so that its base has an empty location. Then, the players are dispatched randomly around the bases, and the game for them is to reach their home base. The whole game stops when all players are home.  There is no winning team: either all players win, or they all lose. Actually, this game is very different from the original baseball. The only rule that remains is that you can only run around the field, from one base to the next one, without crossing middle of the field.
fr: Mais après quelques collisions plus ou moins douloureuses, elles décident d'inventer de nouvelles règles pour organiser la partie. Elles décident de faire une équipe par base sur le terrain et deux joueurs par équipes. L'une des équipes n'a qu'un seul joueur pour que l'une des bases ait un emplacement vide. Ensuite, les joueurs se répartissent aléatoirement sur les bases, et le jeu est de faire en sorte que chaque joueur retourne sur sa base. La partie s’arrête quand tous les joueurs sont chez eux. Il n'y a pas d'équipe gagnante : soit tous les joueurs remportent la partie, soit ils la perdent tous. Oui, c'est vrai, ce jeu est très différent du baseball habituel. La seule règle qui reste est qu'il faut courir autour du terrain, de base en base, sans jamais passer au centre du terrain.

note: type: Content of: <p>
en: Now, they are asking you to help them deciding who and when should move so that each player returns to its base. Only one buggle can move at each round, from its position to the empty spot.  The maximal distance that a buggle can cover in one round is of one base.
fr: Maintenant, les buggles ont besoin de vous pour décider qui doit bouger à quel moment de façon à ce que chacune rejoigne sa base. Une seule buggle peut bouger à chaque tour, de sa position jusqu'à l'emplacement vide. De plus, la distance maximale qu'une buggle peut parcourir en un tour est de une seule base.

note: type: Content of: <p>
en: So, at each round, the empty spot is on one base (say <code>B</code>), and you should decide which buggle enters that empty spot. There is four candidates (two from base <code>B-1</code> and two from base <code>B+1</code>). Actually, there is a fifth candidate since the buggle that is on the same base than the empty spot can change its position, but that's not really helping.
fr: Ainsi, à chaque tour, l'emplacement vide se trouve sur une base (disons <code>B</code>), et vous devez décider quelle buggle occupera cette place. Il y a quatre candidates : deux de la base <code>B-1</code>, et deux de la base <code>B+1</code>. En fait, il y a une cinquième candidate puisque la buggle qui se trouve sur la même base que le trou peut aller l'occuper, mais ça ne fait pas vraiment avancer le problème.

note: type: Content of: <h3>
en: The Naïve algorithm
fr: Algorithme naïf

note: type: Content of: <p>
en: In this exercise, we will first explore a very simple algorithm. To decide which of the four candidate buggles should enter the empty spot, we first restrict ourselves and decide that buggles can only turn clockwise. Then, from the two remaining candidates, we pick the one that has the largest distance to cover to reach its base (turning clockwise). Click on the demo button: this works rather well in practice.
fr: Dans cet exercice, nous allons explorer un premier algorithme très simple. Pour décider laquelle des quatre candidates doit aller occuper l'emplacement vide, nous commençons par nous restreindre à tourner dans le sens des aiguilles d'une montre. Ensuite, parmi les deux candidates restantes, nous prenons celle qui a encore le plus de chemin à parcourir jusqu'à sa base (dans le sens des aiguilles d'une montre). Essayez la démonstration : cela marche plutôt bien en pratique.

note: type: Content of: <p>
en: It's hard to find a simpler algorithm for this problem: While it's not sorted, search for the base containing the candidate buggles: if the hole is in base <code>B</code>, it's the base <code>B+1</code>, modulo the amount of bases. Then, compute the distance that each buggle of that base still has to run to reach its base (0 if it's already home). Once you found the buggle that should enter the empty spot, just use the <code>move</code> method on it, and iterate.
fr: Il est difficile d'imaginer un algorithme plus simple pour ce problème : tant que ce n'est pas trié, chercher la base contenant les candidates. Si le trou est sur la base <code>B</code>, il s'agit de la base <code>B+1</code> (modulo le nombre de bases). Ensuite, il faut calculer la distance que chacune des buggles de cette base doit encore parcourir (0 si elle est déjà chez elle). Une fois que vous avez sélectionné l'heureuse élue, utilisez la méthode <code>deplace</code> pour la faire bouger, avant de passer à l'itération suivante.

note: type: Content of: <p>
en: The main difficulty should be to get the few equations right: determining the base next to the hole should be easy, but determining the distance that a player has to cover may reveal a bit more challenging. Don't hesitate to draw pictures on a paper to cover all possible cases. It should not be that difficult either: there is not that many cases after all.
fr: La principale difficulté est peut-être d'écrire les quelques équations nécessaires sans se tromper. Trouver quelle est la base après le trou devrait être assez facile, mais calculer la distance que chaque joueur doit encore parcourir peut s'avérer plus problématique. N'hésitez pas à faire des dessins pour vérifier que votre équation marche dans tous les cas, il n'y a pas tant de cas possibles que cela après tout.

note: type: Content of: <h1>
en: Selection Baseball
fr: Baseball par sélection

note: type: Content of: <p>
en: The previous algorithm is very pleasant: it's rather simple and rather fast to implement, but unfortunately, it is also rather wrong! In some cases, it never stops, which is obviously bad. If you don't believe it, just copy paste your previous code, and hit the run button. The first world of this exercise is one of these unfortunate situations that drives our previous algorithm crazy.
fr: L'algorithme précédent est très plaisant : il est plutôt simple, assez rapide à implémenter, mais malheureusement, il est également carrément faux. Dans certains cas, il ne s'arrête jamais, ce qui n'est pas très bon. Si vous ne le croyez pas, copie/collez votre code et appuyez sur le bouton «Exécuter». Le premier monde de cet exercice est l'un de ces cas malheureux où notre algorithme devient fou.

note: type: Content of: <p>
en: So we have to find another algorithm, preferably one that works in all cases.
fr: Il nous faut donc trouver un autre algorithme. De préférence un qui marche dans tous les cas.

note: type: Content of: <p>
en: For that, the best solution is to start from a well known algorithm instead of trying to invent a new one from scratch as we just did. When you think a bit about this problem, this can is very similar to a sorting problem: Just make sure that the players are sorted by their colors and you're set. And while we are at it, let's generalize the game to allow more that 4 bases.
fr: Pour cela, la meilleure solution est d'adapter un algorithme connu au lieu de tenter de partir de zéro comme nous venons de faire. Quand on réfléchi un peu à ce problème, on reconnaît un certain air de famille avec le problème du tri : il suffit de <b>trier</b> les joueurs en fonction de leur couleur pour le résoudre. Et tant que nous y sommes, nous pouvons généraliser un peu le problème en utilisant plus de quatre bases.

note: type: Content of: <p>
en: Let's adapt the selection sort to our situation. The big lines of the algorithm is then "for each base, select the players that should occupy this base and make sure that they come to their position". This way, we will grow an sorted area where all players are already sorted (and never changed) while the unsorted area shrinks.
fr: Adaptons le tri par sélection à notre situation. Les grandes lignes de cet algorithme sont les suivantes : «pour chaque base, trouver dans la zone pas encore triée les joueurs qui doivent occuper cette base, puis les y placer». De la sorte, on va faire grandir une zone triée qu'on ne modifie plus jamais, tout en faisant réduire la taille de la zone pas encore triée.

note: type: Content of: <p>
en: Selecting the player should be no problem; Do not hesitate to define some methods such as <code>findPlayer()</code> or <code>findPlayerBase()</code>. This will ensure that your code remains understandable.
fr: Choisir les joueurs à déplacer ne devrait pas poser de problème. N'hésitez pas à définir quelques fonctions comme <code>trouveJoueur</code> ou <code>trouveBaseJoueur()</code>. Cela améliorera la lisibilité de votre code, ce qui est toujours une bonne chose.

note: type: Content of: <p>
en: The most problematic aspect is to move the selected players into position. For that, you have to move the hole to the position where the player is, and then move both the player and the hole to the base that is next to the player's goal (probably in a loop), and finally put the player in the right position of its target base.
fr: L'aspect le plus problématique est de déplacer les joueurs sélectionnés jusqu'à leur position. Pour cela, il vous faut déplacer le trou jusqu'à la base où se trouve le joueur, puis bouger ensuite le trou et le joueur de base en base jusqu'à celle avant la cible (au moyen d'une boucle). Enfin, on peut mettre le joueur dans la bonne case de sa base de prédilection.

note: type: Content of: <p>
en: As often in programming, the devil is in the details: there is a bunch of corner cases that you should detect and deal with correctly, such as the cases where the player is already in the base (but not in the position that you would like), or when the hole is on the right of the player (probably when you sort the first base). But you will find and hunt these while debugging your code.
fr: Comme souvent en programmation, le diable est dans les détails, et il y a un certain nombre de cas particuliers à détecter et à gérer correctement, comme quand le joueur est déjà dans sa base de prédilection (mais pas dans la bonne position), ou quand le trou se trouve en fait à droite du joueur (probablement quand vous triez la première base). Mais vous allez trouver et résoudre ces problèmes quand vous débugguerez votre code.

note: type: Content of: <h1>
en: Insertion Baseball
fr: Baseball par insertion

note: type: Content of: <p>
en: The good point of adapting the selection sort to the baseball problem is that we know that it works (provided that our adaptation is correct). That's much better than the first naive algorithm, that was unable to converge to the solution in some situations. But actually, the selection sort is not perfect either as it requires a lot of swaps: we have to bring the hole to the selected player and then both the player and hole in position, and more. We can do better.
fr: Le coté positif d'adapter le tri par sélection à notre problème est que nous savons que cela fonctionne (à condition que notre adaptation soit correcte). C'est bien mieux que notre premier algorithme naïf, qui était incapable de converger vers la solution dans certains cas. Cependant, le tri par sélection n'est pas parfait non plus, puisqu'il requiert beaucoup d'échanges : il faut amener le trou jusqu'au joueur sélectionné puis amener le joueur ET le trou vers la bonne base. On doit pouvoir faire mieux.

note: type: Content of: <p>
en: For example, each player can run quite a long way from its initial position to its target solution.  Instead, it may be more interesting to split the field in two parts: one on the left where all players are sorted relatively to each others, and one on the right where the players are still at their initial positions. Then, at each iteration, we take the player at the border between the sorted and unsorted areas (that is, the left-most player of the unsorted area) and move it to the left (within the sorted area) until it reaches its position (that is, until the position where it's bigger that its left neighbor). This would at least reduce the travel of players to the sorted area as we use the first one on the border.
fr: Par exemple, chaque joueur peut avoir à parcourir un chemin relativement long pour arriver à sa position finale. Au lieu de cela, il serait peut-être intéressant de couper le terrain en deux parties : l'une à gauche où tous les joueurs sont triés relativement les uns aux autres, et une autre à droite où les joueurs n'ont pas encore bougé de leur position de départ. Ensuite, à chaque itération, on prend le joueur à la frontière entre les deux zones (c'est à dire, le joueur le plus à gauche de la zone non triée) et on le déplace vers la gauche jusqu'à sa position dans la zone triée (c'est à dire, jusqu'à ce qu'il soit plus grand que son voisin de gauche). Cela réduirait au moins la distance que les joueurs doivent parcourir pour rentrer dans la zone triée, puisqu'on prend systématiquement le joueur à la frontière.

note: type: Content of: <p>
en: Actually, that's exactly what an insertion sort would do: maintain a sorted area on the left, and put iteratively the player on the border to its position within the sorted area. This is good, as we know that our algorithm is not inherently flawed since we adapt a well known one.
fr: En fait, c'est exactement ce qu'un tri par insertion ferait: maintenir une zone triée à gauche, et y insérer à chaque itération l'élément qui se trouve à la frontière en le décalant vers la gauche jusqu'à sa position dans la zone triée. C'est une bonne chose, car cela veut dire que notre algorithme n'est pas fondamentalement faux, puisqu'il s'agit d'une adaptation d'un algorithme connu.

note: type: Content of: <p>
en: The easiest to adapt the insertion sort to the baseball problem is to consider all positions as adjacent and forget about bases. For that, we define the methods <code>getColor[!c]Insert[/!](pos)</code>, <code>move[!c]Insert[/!](pos)</code> and <code>getHole[!c]Insert[/!]()</code> that all use a unique integer to designate a given position. These functions simply convert between the way to specify a position and then call the usual functions to interact with the world. If you have an <code>index</code> and want to convert it into a <code>base,pos</code>, then <code>base=index/2</code> and <code>pos=index%2</code>. To compute the reverse, <code>index=base*2+pos</code> (this works because <code>getPositionsAmount()</code> always returns 2).
fr: Le plus simple pour adapter le tri par insertion au problème du baseball est de considérer toutes les positions comme adjacentes sans tenir compte des différentes bases. Pour cela, il faut définir les méthodes <code>couleurJoueur[!c]Insert[/!](pos)</code>, <code>deplace[!c]Insert[/!](pos)</code> et <code>trouveTrou[!c]Insert[/!]()</code> qui utilisent un seul entier pour désigner une position donnée et appellent les fonctions de base de cet univers pour faire leur travail. Pour convertir une position encodée sur un seul entier <code>index</code> en une position encodée sur deux entiers <code>base,pos</code>, il faut appliquer les formules suivantes: <code>base=index/2</code> et <code>pos=index%2</code>. Pour faire le calcul inverse, il faut utiliser <code>index=base*2+pos</code> (qui fonctionne car il y a deux positions par base).

note: type: Content of: <p>
en: For the algorithm itself, you should first move the hole to the position 1. The position 0 is considered to be the sorted area (of size 1 for now) while the area above 2 is the unsorted area.  Then comes an iteration to sort each element of the unsorted area. Since this iteration is a bit complex, you should think of its loop invariant, that is, the condition that is true before and after the loop and which explains that the loop fulfills its goal. Here, the loop invariant is twofold: First, the hole is between the sorted area and the unsorted area, and then, the every elements of the sorted area are ... well sorted relatively to their neighbors.
fr: Pour l'algorithme lui-même, vous devriez tout d'abord bouger le trou en position 1. On considère alors que la zone triée se limite pour l'instant à la position 0 (elle est alors de taille 1) tandis que la zone non triée commence à partir de la position 2. Ensuite, on fait une itération par élément à trier. Comme le corps de cet itération est un peu plus compliqué que ce que nous avons écrit jusque là, vous devriez réfléchir à l'invariant de cette boucle, c'est à dire à la condition qui est vraie avant et après un passage dans la boucle, et qui fait que la boucle fait son travail. Ici, l'invariant a deux parties : tout d'abord, l'emplacement vide se trouve entre les parties triées et non triées, et ensuite, la zone triée est ... triée, c'est à dire que tous les éléments de cette zone sont bien triés par rapport à leurs voisins.

note: type: Content of: <p>
en: Then, the loop body to sort an element should first descend the hole and the elements within the sorted area until the element is larger than the element before in the sorted area (2 moves per position to travel), and then move the hole back to its position between the sorted and unsorted areas (1 move per position).
fr: Ensuite, le corps de la boucle devrait trier un élément en descendant cet élément et le trou dans la zone triée jusqu'au point où l'élément est à sa place dans la zone triée (cela demande deux déplacements par case à parcourir), avant de remonter le trou à sa place à la frontière (un déplacement par case à parcourir).

note: type: Content of: <p>
en: Once you insert the last element within the sorted area, your whole set is sorted and you're done.  I preserve the surprise of the border cases that will require some little adjustments to your algorithm to make it work properly :)
fr: Une fois que vous avez inséré le dernier élément dans la zone triée, tout votre ensemble est trié et vous avez fini. Je vous laisse la surprise des cas limites nécessitant de petits ajustements à votre algorithme pour lui permettre de fonctionner dans tous les cas :)

note: type: Content of: <h1>
en: Bubble Baseball
fr: Baseball à bulle

note: type: Content of: <p>
en: Crap, we adapted the insertion sort because our selection sort required too much moves to get the selected players to their position, but the insertion sort requires an inordinate amount of changes to get the border elements to their position within the sorted area without mixing the already sorted elements. At the end of the day, our selection variant was more efficient with at most <code>3*amountOfBase</code> moves to sort one element (1 to get the hole alongside with the player, and 2 to get the hole+player in position) while our insertion variant requires at most <code>3*amountOfPlayers</code> to sort one element (2 to descend the hole and player in position, 1 to get the hole back to its position). That's twice as bad as there is two players per base. It may be possible to improve the insertion sort by moving by more than one element when descending, but it seems uneasy (at least, while not mixing the already sorted elements) and it would probably only ensure that our insertion variant becomes as efficient as our selection variant, not dramatically better.
fr: Zut, nous avions adapté le tri par insertion parce que notre tri par sélection nécessitait trop de déplacements pour mener les joueurs sélectionnés à leur position, mais le tri par insertion impose une quantité déraisonnable de déplacements pour déplacer les joueurs de la frontière jusqu'à leur place dans la section triée. Au final, notre variante par sélection était plus efficace, avec au pire <code>3*nombre de bases</code> déplacement par élément à trier (1 pour apporter le trou jusqu'au joueur à bouger, et 2 pour amener le joueur et le trou jusqu'à leur position finale).  De son coté, notre variante par insertion nécessite au pire <code>3*nombre de joueurs</code> déplacements pour trier un élément (2 pour descendre le joueur et le trou à leur place, et 1 pour remonter le trou). C'est deux fois pire puisqu'il y a deux joueurs par base. Il serait probablement possible d'améliorer un peu notre variante par insertion en descendant plus vite le trou et le joueur, mais cela semble assez difficile (il ne faut pas mélanger les éléments déjà triés pendant la descente), et cela ne permettrait que de rendre cette variante aussi efficace que celle par sélection, pas de faire vraiment mieux.

note: type: Content of: <p>
en: If we cannot make the sort faster, we can make it easier. If you think about it, it seems rather natural to adapt the bubble sort to this problem: the hole becomes the bubble that moves up and down, sorting a bit the array during each traversal. The big lines are simply: "while it's not sorted, move the hole down to base 0 (moving the biggest player of each base at each step) and then back to the maximal base (moving the smallest player of each base)". After a while, <code>isSorted()</code> will return true and your algorithm will stop.
fr: Si nous ne pouvons pas rendre ce tri plus rapide, au moins nous pouvons le faire plus simplement. Quand on y pense, il semble assez naturel d'adapter le tri à bulle à ce problème : le trou devient la bulle qui monte et qui descend, en sortant peu à peu le tableau. Les grandes lignes de l'algorithme sont très simples : «tant que ce n'est pas trier, déplacer le trou vers le bas puis vers le haut. À chaque pas, c'est le plus petit des deux joueurs de la base qui descend, et le plus grand des deux qui monte (en fonction du sens de déplacement).». Après un moment, <code>estTrie()</code> devient vrai, et votre algorithme s'arrête.

note: type: Content of: <p>
en: This is so easy that we introduce another variant of the problem, with more than two players per base.  But actually, that shouldn't block you very long, should it?
fr: C'est tellement simple que nous pouvons nous payer le luxe d'une autre variante du problème, avec plus de deux joueurs par base. Mais cela ne va pas vous ralentir longtemps, n'est ce pas?

note: type: Content of: <p>
en: Surprisingly, the bubble sort variant requires ways less moves than the other variants. This is astonishing because usually, the bubble sort performs much worse than the others sorts, but it comes from the very good match between its big lines and the baseball universe. It actually happens rather often that a pleasantly written algorithm performs very decently. But this is not an universal rule either, as demonstrated by the naive algorithm of the first exercise, that was nice, simple and wrong ;)
fr: De manière étonnante, la variante à bulle semble nécessiter beaucoup moins de déplacements que les autres variantes. C'est assez surprenant car habituellement, le tri à bulle est la pire des variantes possibles, mais cela s'explique sans peine par les analogies entre cet algorithme et le problème du baseball multicolore. Il est relativement courant qu'un algorithme écrit simplement et naturellement se comporte bien en pratique. Il ne s'agit cependant pas d'une règle absolue, comme prouvé par l'algorithme simple et faux du premier exercice !

note: type: Content of: <h1>
en: The universe of turtles
fr: L'univers des tortues

note: type: Content of: <p>
en: This is an adaptation of LOGO for the Programmer's Learning Machine.
fr: Cet univers est une adaptation de LOGO pour la Programmer's Learning Machine.

note: type: Content of: <p>
en: It is directly inspired from the work of the mathematician Seymour Papert in the 60's. Inspired from the swiss psycholog Jean Piaget, he came up with a learning method called LOGO to teach programming to young childs. The world is full of turtles which leave a painting where they go and which respond to simple orders.
fr: Il est directement inspiré des travaux du mathématicien Seymour Papert dans les années 60. Inspiré par le psychologue suisse Jean Piaget, il a inventé une méthode d'apprentissage de la programmation accessible aux jeunes enfants nommée LOGO. Le monde est peuplé de tortues qui laissent une trace là où elles marchent et à qui on peut donner des ordres simples.

note: type: Content of: <h2>
en: Functions to move the turtle
fr: Fonctions pour déplacer la tortue

note: type: Content of: <pre>
en: [!java|c]void [/!]forward([!java|c]double [/!]steps[!scala]:Double[/!])
    [!java|c]void [/!]backward([!java|c]double [/!]steps[!scala]:Double[/!])
fr: [!java|c]void [/!]avance([!java|c]double [/!]nbPas[!scala]:Double[/!])
    [!java|c]void [/!]recule([!java|c]double [/!]nbPas[!scala]:Double[/!])

note: type: Content of: outside any tag (error?)
en: Moves forward or backward of the requested amount of steps.
fr: Avance ou recule du nombre de pas demandé.

note: type: Content of: <pre>
en: [!java|c]void [/!]right([!java|c]double [/!]angle[!scala]:Double[/!])
    [!java|c]void [/!]left([!java|c]double [/!]angle[!scala]:Double[/!])
fr: [!java|c]void [/!]droite([!java|c]double [/!]angle[!scala]:Double[/!])
    [!java|c]void [/!]gauche([!java|c]double [/!]angle[!scala]:Double[/!])

note: type: Content of: outside any tag (error?)
en: Turns left or right of the given angle (in degrees).
fr: Tourne à gauche ou à droite de l'angle indiqué (en degrés).

note: type: Content of: outside any tag (error?)
en: Returns the current position of the turtle.  Note that the point (0,0) is on the top left corner, as it is often the case in Computer Science.
fr: Renvoie la position courante de la tortue. L'origine (0; 0) est dans le coin en haut à gauche, comme c'est souvent le cas en informatique.

note: type: Content of: outside any tag (error?)
en: Teleports the turtle to a new position (without leaving any trace).
fr: Téléporte la tortue à une nouvelle position (sans laisser de trace).

note: type: Content of: <pre>
en: [!java|c]void [/!]moveTo([!java|c]double [/!]x[!scala]:Double[/!], [!java|c]double [/!]y[!scala]:Double[/!])
fr: [!java|c]void [/!]allerVers([!java|c]double [/!]x[!scala]:Double[/!], [!java|c]double [/!]y[!scala]:Double[/!])

note: type: Content of: outside any tag (error?)
en: Moves the turtle to a new position.
fr: Déplace la tortue à une nouvelle position.

note: type: Content of: <pre>
en: [!java|c]void [/!]circle([!java|c]double [/!]radius[!scala]:Double[/!])
fr: [!java|c]void [/!]cercle([!java|c]double [/!]rayon[!scala]:Double[/!])

note: type: Content of: outside any tag (error?)
en: Draw a circle of the specified radius centered on the turtle.
fr: Dessine un cercle du rayon demandé et centré sur la tortue.

note: type: Content of: <pre>
en: [!java|c]void [/!]hide()
fr: [!java|c]void [/!]cache()

note: type: Content of: outside any tag (error?)
en: Hides the turtle.
fr: Cache la tortue.

note: type: Content of: <pre>
en: [!java|c]void [/!]show()
fr: [!java|c]void [/!]montre()

note: type: Content of: outside any tag (error?)
en: Shows the turtle back.
fr: Montre la tortue.

note: type: Content of: <pre>
en: [!java]boolean [/!][!c]int [/!]isVisible()[!scala]:Boolean[/!]
fr: [!java]boolean [/!][!c]int [/!]estVisible()[!scala]:Boolean[/!]

note: type: Content of: outside any tag (error?)
en: Returns whether the turtle is currently visible.
fr: Renvoie vrai si la tortue est actuellement visible.

note: type: Content of: <pre>
en: [!java|c]void [/!]clear()
fr: [!java|c]void [/!]efface()

note: type: Content of: outside any tag (error?)
en: Removes any trail on the sheet.
fr: Efface toutes les traces de la feuille.

note: type: Content of: <pre>
en: [!java|c]double [/!]getHeading()[!scala]:Double[/!]
fr: [!java|c]double [/!]getCap()[!scala]:Double[/!]

note: type: Content of: outside any tag (error?)
en: Returns the current heading of the turtle (in degrees).
fr: Retourne le cap actuel de la tortue (en degrés).

note: type: Content of: <pre>
en: [!java|c]void [/!]setHeading([!java|c]double [/!]angle[!scala]:Double[/!])
fr: [!java|c]void [/!]setCap([!java|c]double [/!]angle[!scala]:Double[/!])

note: type: Content of: outside any tag (error?)
en: Sets a new heading to the turtle (in degrees).
fr: Change le cap de la tortue à l'angle indiqué (en degrés).

note: type: Content of: <h2>
en: Functions about the pen
fr: Fonctions à propos du stylo

note: type: Content of: <pre>
en: [!java|c]void [/!]penUp()
fr: [!java|c]void [/!]leveCrayon()

note: type: Content of: outside any tag (error?)
en: Moves the pen up (turtles have pens, not brushes as buggles). The turtle will not leave any trace during its subsequent moves.
fr: Remonte le crayon de la tortue (les tortues ont des crayons, pas des brosses comme les buggles). La tortue ne laissera plus de trace lors de ses déplacements suivants.

note: type: Content of: <pre>
en: [!java|c]void [/!]penDown()
fr: [!java|c]void [/!]baisseCrayon()

note: type: Content of: outside any tag (error?)
en: Moves the pen down. The turtle will leave a trace during its subsequent moves.
fr: Descend le stylo. La tortue laissera une trace lors de ses prochains déplacements.

note: type: Content of: <pre>
en: [!java]boolean [/!][!c]int [/!]isPenDown()[!scala]:Boolean[/!]
fr: [!java]boolean [/!][!c]int [/!]estCrayonBaisse()[!scala]:Boolean[/!]

note: type: Content of: outside any tag (error?)
en: Returns the current pen position as a boolean.
fr: Retourne si le stylo est actuellement baissé ou non.

note: type: Content of: <pre>
en: [!java|c]Color [/!]getColor()[!scala]:Color[/!]
fr: [!java|c]Color [/!]getCouleur()[!scala]:Color[/!]

note: type: Content of: outside any tag (error?)
en: Returns the current pen color.
fr: Retourne la couleur actuelle du stylo.

note: type: Content of: <pre>
en: [!java|c]void [/!]setColor([!java|c]Color [/!]color[!scala]:Color[/!])
fr: [!java|c]void [/!]setCouleur([!java|c]Color [/!]couleur[!scala]:Color[/!])

note: type: Content of: outside any tag (error?)
en: Changes the pen color.
fr: Modifier la couleur du stylo.

note: type: Content of: <h2>
en: Other functions
fr: Autres fonctions

note: type: Content of: outside any tag (error?)
en: Returns whether the current turtle is selected in the graphical interface.
fr: Renvoie si la tortue actuelle est sélectionnée dans l'interface graphique.

note: type: Content of: <h3>
en: Turtle Art
fr: L'art de la tortue

note: type: Content of: <p>
en: Since its inception in the 60's, the LOGO turtle fascinates by its ability to draw nice figures on computer.  This lesson allows you to explore some of the classical figures, and draw your own.
fr: Dès sa conception dans les années 60, la tortue LOGO s'est révélé être un outil fascinant pour dessiner sur ordinateur. Cette leçon vous permet d'explorer certaines des figures les plus classiques, et de dessiner les vôtres.

note: type: Content of: <p>
en: The language's syntax is absolutely not presented, but if you know a bit of it or if someone tells you, you can take these exercises even if you are an absolute beginner in programming.
fr: La syntaxe du langage n'est absolument pas présentée, mais si vous connaissez les bases (ou si quelqu'un peut répondre à vos questions), vous pouvez faire ces exercices même si vous êtes un débutant absolu en programmation.

note: type: Content of: <p>
en: Please send us your best contributions so that they get added to this gallery to inspire the next ones.
fr: Envoyez nous vos plus belles contributions pour que nous les ajoutions à cette galerie afin d'inspirer les futurs utilisateurs.

note: type: Content of: <ul><li>
en: Other exercises should be added. A whole lot of exercises are available from <a href="http://neoparaiso.com/logo/#sect4">http://neoparaiso.com/logo/#sect4</a> or from <a href="http://billkerr2.blogspot.fr/2009/08/40-maths-shapes-challenges.html.">http://billkerr2.blogspot.fr/2009/08/40-maths-shapes-challenges.html</a>.
fr: D'autres exercises devraient être ajoutés. Une mine d'inspiration quasi inépuisable se trouve à l'adresse <a href="http://neoparaiso.com/logo/#sect4">http://neoparaiso.com/logo/#sect4</a>, tandis que d'autres challenges intéressants se trouvent à l'adresse <a href="http://billkerr2.blogspot.fr/2009/08/40-maths-shapes-challenges.html.">http://billkerr2.blogspot.fr/2009/08/40-maths-shapes-challenges.html</a>.

note: type: Content of: <ul><li>
en: Missing: the built-ins arc() and arcTo(), that draw an arc, either w/o moving or by moving to the end of the arc.
fr: Il manque des primitives arc() et arcVers() pour dessiner un arc de cercle, en restant sur place ou en bougeant jusqu'à la fin de l'arc.

note: type: Content of: <p>
en: Draw beautiful figures with the Logo turtle, and learn programming while playing.
fr: Dessinez de belles figures avec la tortue Logo, et apprenez la programmation en jouant.

note: type: Content of: <p>
en: You should know the basic syntax of the programming language you will choose, but no exhaustive programming practice is required to take this lesson.
fr: Vous devez connaître la syntaxe de base du langage que vous allez choisir, mais aucune expérience n'est nécessaire pour entreprendre cette leçon.

note: type: Content of: <h1>
en: ConsWorld
fr: Monde des listes récursives

note: type: Content of: <p>
en: This world allows you to experiment with the recursive lists, as they were first introduced in Lisp. It is very similar to the BatWorld, but you are supposed to write recursive functions working on [!python|java]recursive strings. Since [!thelang] does not provide such a construct natively, the ConsWorld defines recursive lists of type <code>RecList</code>.[/!] [!scala]lists of integers (<code>List[Int]</code>).[/!]
fr: Ce monde vous permettra d'expérimenter avec les listes récursives, telles qu'elles ont été définies en Lisp à l'origine. Ce monde est assez similaire au BatWorld, mais vous êtes supposé écrire des fonctions récursives agissant sur des [!python|java]listes récursives. Comme [!thelang] ne propose rien de tel en natif, ce monde défini un nouveau type nommé <code>RecList</code> pour cela.[/!] [!scala]listes d'entiers (<code>List[Int]</code>).[/!]

note: type: Content of: <p>
en: Any given such list is either the empty list (noted <code>[!scala]Nil[/!][!java]null[/!][!python]None[/!]</code>), or an integer followed by a list. If a list is not empty, you can retrieve its first integer with <code>list.head</code> and the list containing its other parameters with <code>list.tail</code>. Of course, the empty list has no head nor the tail, so trying to access these elements will result in an (unpleasant) error message.
fr: Une telle liste peut être soit la liste vide (notée <code>[!scala]Nil[/!][!java]null[/!][!python]None[/!]</code>), soit un entier suivi d'une liste. Si une liste n'est pas vide, vous pouvez retrouver son premier entier avec <code>list.head</code>. On dit qu'on extrait alors la tête de la liste.La liste contenant ses autres éléments (tous sauf la tête) peut être retrouvée avec <code>list.tail</code>. On dit qu'on extrait la suite de la liste.Bien entendu, la liste vide n'a ni tête ni suite, et vous ne devriez pas tenter d'accéder à ces éléments sous peine d'obtenir un message d'erreur (particulièrement déplaisant).

note: type: Content of: <p>
en: To build your own list, you need to concatenate a head and a tail as follows: [!java|python]<code>cons(head, tail)</code>[/!] [!scala]<code>head::tail</code> Note that <code>::</code> is a generic operator in Scala to build lists.[/!]
fr: Pour construire votre propre liste, vous devez concaténer une tête et une suite comme suit : [!java|python]<code>cons(tête, suite)</code>[/!] [!scala]<code>tête::suite</code>. Il se trouve que <code>::</code> est un opérateur générique du langage Scala pour construire des listes.[/!]

note: type: Content of: <p>
en: So, in summary, you can solve every exercises of this lesson with the following constructs.
fr: En résumé, vous pouvez résoudre tous les exercices de cette leçon avec les constructions suivantes :

note: type: Content of: <ul><li>
en: <b>The empty list:</b>
fr: <b>La liste vide:</b>

note: type: Content of: <ul><li><pre>
en: [!java]null[/!][!scala]Nil[/!][!python]None[/!]
fr: [!java|c]null[/!][!scala]Nil[/!][!python]None[/!]

note: type: Content of: <ul><li>
en: <b>Get the first element of <code>l</code></b>
fr: <b>Obtenir le premier élément de <code>l</code></b>

note: type: Content of: <ul><li>
en: <b>Get the rest of the list</b>, when the first element is removed:
fr: <b>Obtenir la suite de la liste</b>, privée de son premier élément:

note: type: Content of: <ul><li>
en: <b>Build a list</b> from a <code>value</code> and a <code>list</code>: [!java|python]
fr: <b>Construire une liste</b> à partir d'une <code>valeur</code> et d'une <code>liste</code>: [!java|python]

note: type: Content of: <ul><li><pre>
en: cons(value, list)
fr: cons(valeur, liste)

note: type: Content of: <ul><li><pre>
en: value::list
fr: valeur::liste

note: type: Content of: <h1>
en: Recursive Lists
fr: Listes récursives

note: type: Content of: <p>
en: This lesson contains a bunch of classical exercises on recursive lists.  It is certainly not the most pleasant lesson to do, but I think that it is the easiest of the PLM lessons dealing with recursion.
fr: Cette leçon propose un paquet d'exercices classiques sur les listes récursives. Il ne s'agit certainement pas de la leçon la plus drôle de la PLM, mais il s'agit certainement de la plus simple des leçons PLM sur la récursivité.

note: type: Content of: <ul><li>
en: New exercises could be proposed, such as http://webloria.loria.fr/~quinson/Teaching/TOP/02-td-recursivite-enonce.pdf If you know some others, please report them as an issue.
fr: De nouveaux exercices pourraient être proposés, par exemple inspirés de http://webloria.loria.fr/~quinson/Teaching/TOP/02-td-recursivite-enonce.pdf Si vous en connaissez d'autres, nous vous serions reconnaissant de nous en parler dans un rapport d'anomalie.

note: type: Content of: <ul><li>
en: It would be interesting to check the asymptotic complexity of the student's code, but that does not sound easy to do. In Python and Java (where we provide a hand-made RecList class), we could count the amount of cons per exercise, but it won't be easy to relate this to the right BatTest. For Scala, it sounds even more difficult as we use the classical :: operators of the language. That will be difficult to override to add a counting mechanism. Another solution would be to ensure that the call stack does not pass a given threshold, but that sounds very difficult too. Any idea is welcome.
fr: Il serait intéressant de vérifier la complexité algorithmique du code proposé par les étudiants, mais cela semble assez difficile à faire. En Python et Java, nous proposons un type de donnée spécifique (les <code>RecList</code>) alors nous pourrions compter le nombre de cons réalisés dans chaque exercice, mais il risque d'être compliqué de trouver le test auquel rattacher chaque opération. En Scala, cela s'annonce encore plus difficile car nous utilisons directement des mots-clés du langage. Il serait probablement difficile d'y injecter un mécanisme comptant les opérations. On pourrait vouloir assurer que la pile d'appel ne dépasse pas une profondeur donnée, mais cela semble également difficile à implémenter. Si vous avez des idées, merci de nous en faire part.

note: type: Content of: <h1>
en: Length
fr: Longueur

note: type: Content of: outside any tag (error?)
en: Given a [!scala]List[Int][/!][!java|python]recursive list[/!], return its length[!scala] (without using its <code>size</code> method, of course)[/!].  [!java|python]
fr: Étant donnée une [!scala]List[Int][/!][!java|python]liste récursive[/!] retournez sa longueur[!scala], sans utiliser la méthode <code>size</code> de la liste, bien entendu[/!].[!java|python]

note: type: Content of: <p>
en: [!python]Be careful, you are not supposed to use the Python lists, but the specific type defined in this exercise. [/!] Please refer to the world's documentation for more information about recursive lists.
fr: [!python]Attention, vous n'êtes pas supposé utiliser les listes classiques de Python, mais celles définies dans cet exercice. [/!] Veuillez vous référer à la documentation de ce monde pour plus d'information sur les listes récursives.

note: type: Content of: <p>
en: Your solution should be linear in time.
fr: Votre solution devrait être linéaire en temps.

note: type: Content of: <h1>
en: IsMember
fr: EstMembre

note: type: Content of: outside any tag (error?)
en: Given a [!scala]List[Int][/!][!java|python]recursive list[/!] and an integer, return true if the given integer is one of the elements of the list, or false if it cannot be found.
fr: Étant donnée une [!scala]List[Int][/!][!java|python]liste récursive[/!] et un entier, retournez <code>true</code> si cet entier fait partie des éléments de la liste, et <code>false</code> sinon.

note: type: Content of: outside any tag (error?)
en: Given a [!scala]List[Int][/!][!java|python]recursive list[/!] and an integer, return the amount of occurrences of the given integer in the list. If the integer is not a member of the list, the function should thus return 0.
fr: Étant donnée une [!scala]List[Int][/!][!java|python]liste récursive[/!] et un entier, retournez le nombre d'occurences de cet entier dans la liste. Si l'entier n'est pas membre de la liste, la fonction doit renvoyer 0.

note: type: Content of: <h1>
en: Last
fr: Dernier

note: type: Content of: outside any tag (error?)
en: Given a [!scala]List[Int][/!][!java|python]recursive list[/!], return its last element.  You can assume that the list is not empty.
fr: Étant donnée une [!scala]List[Int][/!][!java|python]liste récursive[/!], retournez son dernier élément. Vous pouvez supposer que la liste n'est pas vide.

note: type: Content of: outside any tag (error?)
en: Given a [!scala]List[Int][/!][!java|python]recursive list[/!], return the smallest of its values.  You will probably need an extra function, even if you can assume that the list is not empty.
fr: Étant donnée une [!scala]List[Int][/!][!java|python]liste récursive[/!], retournez la plus petite de ses valeurs. Vous aurez probablement besoin d'une fonction supplémentaire, mais vous pouvez supposer que la liste n'est pas vide.

note: type: Content of: <h1>
en: Increasing
fr: Croissante

note: type: Content of: outside any tag (error?)
en: Given a [!scala]List[Int][/!][!java|python]recursive list[/!], return whether its elements form an increasing sequence (i.e., if the elements are sorted from the smallest to the largest one).
fr: Étant donnée une [!scala]List[Int][/!][!java|python]liste récursive[/!], retournez <code>true</code> si ses éléments forment une suite croissante (c'est-à-dire si ses éléments sont classés du plus petit au plus grand).

note: type: Content of: <h1>
en: But Last
fr: Sauf Dernier

note: type: Content of: outside any tag (error?)
en: Given a [!scala]List[Int][/!][!java|python]recursive list[/!], return the list containing every elements but the last one.  You can assume that the list is not empty.
fr: Étant donnée une [!scala]List[Int][/!][!java|python]liste récursive[/!], retournez la liste contenant tous ses éléments sauf le dernier. Vous pouvez supposer que la liste n'est pas vide.

note: type: Content of: <h1>
en: PlusOne
fr: PlusUn

note: type: Content of: outside any tag (error?)
en: Given a [!scala]List[Int][/!][!java|python]recursive list[/!], return a new list containing all elements of your parameter incremented by one.
fr: Étant donnée une [!scala]List[Int][/!][!java|python]liste récursive[/!], retournez une nouvelle liste dont les éléments sont ceux de votre paramètre, incrémentés de un.

note: type: Content of: <h1>
en: Remove
fr: Retire

note: type: Content of: outside any tag (error?)
en: Given a [!scala]List[Int][/!][!java|python]recursive list[/!] <code>L</code>and an integer, return a new list containing all elements of <code>L</code> that are not equal to the value received as parameter.
fr: Étant donnée une [!scala]List[Int][/!][!java|python]liste récursive[/!] <code>L</code> et un entier, retournez une nouvelle liste contenant tous les éléments de <code>L</code> n'étant pas égaux à l'entier passé en paramètre.

note: type: Content of: <h1>
en: Nth
fr: Nième

note: type: Content of: outside any tag (error?)
en: Given a [!scala]List[Int][/!][!java|python]recursive list[/!] and an integer <code>N</code>, return the <code>N</code>th element of the list.
fr: Étant donnée une [!scala]List[Int][/!][!java|python]liste récursive[/!] et un entier <code>N</code>, retournez le <code>N</code>ième élément de la liste.

note: type: Content of: <p>
en: You can assume that the list is long enough, i.e. that there is at least <code>N</code> elements.  Your solution should be linear in time.
fr: Vous pouvez supposer que la liste est suffisamment longue, c'est à dire qu'elle contient au moins <code>N</code> éléments. Votre solution devrait être linéaire en temps.

note: type: Content of: <h1>
en: Nfirst
fr: nPremiers

note: type: Content of: outside any tag (error?)
en: Given a [!scala]List[Int][/!][!java|python]recursive list[/!] and an integer <code>N</code>, return the list constituted of the first <code>N</code> elements. You can assume that the list is long enough, i.e. that there is at least <code>N</code> elements.
fr: Étant donnée une [!scala]List[Int][/!][!java|python]liste récursive[/!] et un entier <code>N</code>, retournez la liste constituée de ses <code>N</code> premiers éléments. Vous pouvez supposer que la liste est suffisamment longue, c'est à dire qu'elle contient au moins <code>N</code> éléments.

note: type: Content of: <h1>
en: Nlast
fr: nDerniers

note: type: Content of: outside any tag (error?)
en: Given a [!scala]List[Int][/!][!java|python]recursive list[/!] and an integer <code>N</code>, return the list with only the <code>N</code> last elements.
fr: Étant donnée une [!scala]List[Int][/!][!java|python]liste récursive[/!] et un entier <code>N</code>, retournez la liste constituée de ses <code>N</code> derniers éléments.

note: type: Content of: <p>
en: Your solution should be linear in time, but you will probably need to define several functions to achieve that complexity.
fr: Votre solution devrait être linéaire en temps, mais vous aurez probablement besoin de définir plusieurs fonctions pour atteindre cette complexité.

note: type: Attribute 'alt' of: <div>
en: I cannot do it in linear time
fr: Je n'arrive pas à le faire en temps linéaire

note: type: Content of: <div>
en: The trick is to compute only once (and beforehand) how many elements you should keep.
fr: L'astuce est de calculer une seule fois (et à l'avance) combien d'éléments il faut garder.

note: type: Content of: <h1>
en: But Nfirst
fr: Sauf nPremiers

note: type: Content of: outside any tag (error?)
en: Given a [!scala]List[Int][/!][!java|python]recursive list[/!] and an integer <code>N</code>, return the list without the <code>N</code> first elements.
fr: Étant donnée une [!scala]List[Int][/!][!java|python]liste récursive[/!] et un entier <code>N</code>, retournez la liste privée de ses <code>N</code> premiers éléments.

note: type: Content of: <h1>
en: But Nlast
fr: Sauf nDerniers

note: type: Content of: outside any tag (error?)
en: Given a [!scala]List[Int][/!][!java|python]recursive list[/!] and an integer <code>N</code>, return the list without the <code>N</code> last elements.
fr: Étant donnée une [!scala]List[Int][/!][!java|python]liste récursive[/!] et un entier <code>N</code>, retournez la liste privée de ses <code>N</code> derniers éléments.

note: type: Content of: <h1>
en: Reverse
fr: Inverse

note: type: Content of: outside any tag (error?)
en: Given a [!scala]List[Int][/!][!java|python]recursive list[/!], return a new list with all elements in reverse order.
fr: Étant donnée une [!scala]List[Int][/!][!java|python]liste récursive[/!], retournez la liste constituée de ses éléments en ordre inverse.

note: type: Content of: <p>
en: This function is very important and you should not pass that challenge.  Your solution should be linear in time, with the help of helper functions.
fr: Cette fonction est très importante et vous ne devriez pas passer ce défi sans trouver la réponse, qui doit être linéaire grâce à l'aide de fonctions supplémentaires.

note: type: Content of: <div>
en: You need an helper function in which the result is accumulated (built) at each step.
fr: Il faut réaliser une fonction d'aide dont le résultat est accumulé (construit) à chaque étape.

note: type: Content of: <h1>
en: Concat
fr: Concaténation

note: type: Content of: outside any tag (error?)
en: Given two [!scala]List[Int][/!][!java|python]recursive list[/!] <code>l1</code> and <code>l2</code>, return a new list with all elements of <code>l1</code> followed by the elements of <code>l2</code>.
fr: Étant donnée deux [!scala]List[Int][/!][!java|python]listes récursives[/!] <code>l1</code> et <code>l2</code>, retournez la liste constituée de tous les éléments de <code>l1</code> suivis de tous les éléments de <code>l2</code>.

note: type: Content of: <div>
en: You need to modify <code>l1</code> beforehand so that the computations at each step of the recursion are in constant time.
fr: Il faut modifier <code>l1</code> au préalable pour s'assurer que chaque étape récursive soit en temps constant.

note: type: Content of: <h1>
en: All Different
fr: Tous différents

note: type: Content of: outside any tag (error?)
en: Given a [!scala]List[Int][/!][!java|python]recursive list[/!], return true if any two elements of the list are different (ie, if no element appears more than once in the list).
fr: Étant donnée une [!scala]List[Int][/!][!java|python]liste récursive[/!], retournez <code>false</code> si deux éléments ont la même valeur, et <code>true</code> si tous les éléments sont différents deux à deux.

note: type: Content of: <p>
en: The simplest solution is in O(n²), meaning that it runs in quadratic time.  You will probably have to define one extra function for that.  Another much more complex solution runs in O(n log(n)).
fr: La solution la plus simple est en O(n²), ce qui veut dire qu'elle s'exécute en temps quadratique. Vous aurez probablement besoin de définir une fonction supplémentaire pour cela. Une autre solution bien plus complexe s'exécute en O(n log(n)).

note: type: Content of: <h1>
en: Recursive algorithms
fr: Algorithmes récursifs

note: type: Content of: outside any tag (error?)
en: This lesson allows to experiment with recursive algorithms.
fr: Cette leçon vous permet d'expérimenter avec des algorithmes récursifs.

note: type: Content of: <p>
en: If you need more recursive algorithms, an exercise on recursive sorting algorithms (in particular QuickSort and MergeSort) is planned in the future within the sorting lesson.
fr: Si vous cherchez d'autres algorithmes récursifs, un exercice sur les tris récursifs (en particulier QuickSort et MergeSort) est prévu à l'avenir dans la leçon sur les tris.

note: type: Content of: <h3>
en: What can I do to improve this lesson?
fr: Que puis-je faire pour améliorer cette leçon ?

note: type: Content of: <p>
en: As usual, there are several things that could be done in this lesson to improve it further:
fr: Comme souvent, plusieurs points pourraient être améliorés dans cette leçon&nbsp;:

note: type: Content of: <ul><li>
en: The Sierpinski triangle can be drawn using a simpler L-system. See http://jpvallon.free.fr/recursivite.html
fr: Le triangle de Sierpinski peut être tracé de façon bien plus simple en utilisant un L-système. Voir http://jpvallon.free.fr/recursivite.html

note: type: Content of: <ul><li>
en: The arrowhead curve is also interesting: http://www.mathcurve.com/fractals/sierpinski/sierpinskitriangle.shtml
fr: la courbe de Sierpinski est également intéressante: http://www.mathcurve.com/fractals/sierpinski/sierpinskitriangle.shtml

note: type: Content of: <ul><li>
en: The dragon curve could be explained as a L-system: http://ecademy.agnesscott.edu/~lriddle/ifs/heighway/heighway.htm
fr: La courbe du dragon pourrait être expliquée comme un L-système. http://ecademy.agnesscott.edu/~lriddle/ifs/heighway/heighway.htm

note: type: Content of: <ul><li>
en: The dragon2 curve is called the twin dragon: http://ecademy.agnesscott.edu/~lriddle/ifs/heighway/twindragon.htm
fr: La courbe du dragon2 s'appelle la courbe des dragons jumeaux: http://ecademy.agnesscott.edu/~lriddle/ifs/heighway/twindragon.htm

note: type: Content of: <ul><li>
en: The space filling curves could be added (Peano, Hildebert, etc).  See: http://teachout1.net/village/fill.html
fr: Les courbes remplissant l'espace (Peano, Hildebert, etc) pourraient être ajoutées. http://teachout1.net/village/fill.html

note: type: Content of: <ul><li>
en: We could do another exercise on embeeded polygons: http://www.inrialpes.fr/helix/people/genoud/ENSJAVA/tds/sujets/dessinsReccursifs/actionsrecursives.html
fr: Un exercice sur les polygones inscrits serait intéressant: http://www.inrialpes.fr/helix/people/genoud/ENSJAVA/tds/sujets/dessinsReccursifs/actionsrecursives.html

note: type: Content of: <h3>
en: Bases of recursion
fr: Les bases de la récursion

note: type: Content of: <p>
en: Discover the recursive way of thinking by drawing trees and other figures with the Logo turtle.
fr: Découvrez la récursion en dessinant des arbres et d'autres figures avec la tortue Logo.

note: type: Content of: <h2>
en: The small cousines of Buggles
fr: Les petites cousines des Buggles

note: type: Content of: <p>
en: Today, we will meet the small cousines of the buggles: the turtles. In fact, turtles are much olders than the buggles. They were invented in the 70's by a scientific from MIT called Seymour Papert to help teaching programming, and the buggles are a variation on the idea invented by Lyn Turbak from Wellesley College later.
fr: Aujourd'hui, nous allons faire la connaissance des petites cousines des buggles : les tortues. En fait, les tortues sont bien plus vieilles que les buggles. Elles ont été inventées dans les années 70 par un scientifique du MIT nommé Seymour Papert pour aider à l'enseignement de la programmation, et les buggles sont une variation sur le thème inventée par Lyn Turbak du Wellesley College plus tard.

note: type: Content of: <p>
en: Turtles are thus a bit like buggles, but smaller. Just like buggles, you can order them to move forward, to turn, to move backward, etc. Just like buggles, they leave a line on their path when they move (but the line is much smaller).
fr: Les tortues sont donc un peu comme les buggles, en plus petit.  Comme les buggles, vous pouvez leur demander d'avancer, de tourner, de reculer, etc. Comme les buggles, elles laissent une trace sur leur passage quand elles avancent (simplement, le trait est bien plus fin).

note: type: Content of: <p>
en: The main difference is that where buggles can only move of right angles, turtles can move of any arbitrary angles specified by a real number (a double). This gives them much more liberty in their movings. The buggles can do several other tricks, like reading and writting messages, picking or dropping objects, and there is sometimes walls in their worlds (but all this is completely above the capacities of turtles).
fr: La principale différence est que là où les buggles ne peuvent tourner que de quarts de tour, les tortues peuvent tourner d'un angle quelconque précisé par un nombre réel (double). Cela leur donne bien plus de liberté dans leur mouvement. Les buggles savent faire plusieurs trucs qui échappent aux tortues, comme lire et écrire des messages sur le sol ou ramasser des objets, et il y a parfois des murs dans leur univers, mais tout cela dépasse complètement les tortues.

note: type: Content of: <p>
en: From a practical point of view, most of the methods you knew about buggles still work with turtles, with some minor adaptations. In particular, the <code>forward()</code> method takes the amount of steps to do not as an integer, but as a [!python]point number[/!][!java|scala|c]double[/!] (see "About this world" for more details).
fr: D'un point de vue pratique, la plupart des méthodes que vous connaissez à propos des buggles fonctionnent également avec les tortues, à quelques variantes près. En particulier, la méthode <code>avance</code> prend en argument le nombre de pas donné comme un [!python]nombre à virgule[/!][!java|scala|c]double[/!] (voir «Aide / À propos de ce monde» dans le menu pour plus de détails).

note: type: Content of: <h3>
en: Doubles? But what is it?
fr: Des doubles ? Mais qu'est ce que c'est ?

note: type: Content of: outside any tag (error?)
en: It's simply a point number. Example:
fr: C'est simplement un nombre à virgule. Exemple:

note: type: Content of: <pre>
en: double x = 3.72;
    x + 1.234 // Value = 4.954
    x + 2. // Value = 5.72 (2. means 2.0)
    x + 2 // [!java|c]Value = 5.72 (2 automatically converted to 2.0)[/!][!scala]Type error (+ operator don't mix Double and Int); manual conversion mandatory[/!]
    x * 2. // Value = 7.44 
    x / 2. // Value = 1.86 
    [!java|c](int) x[/!][!scala]x.asInstanceOf[Int][/!] // Value = 1 (“casting to int”, converted to integer by truncating)
    Math.round(x) // Value = 2 (1.86 rounded to nearest integer)
    Math.floor(x) // Value = 1 (1.86 rounded toward minus infinity)
    Math.floor(-5.12) // Value = -6 (rounded toward minus infinity)
    Math.ceiling(x) // Value = 2 (1.86 rounded toward plus infinity)
    Math.ceiling(-5.12) // Value = -5 (rounded toward plus infinity)
    [!java|c](double) 17[/!][!scala]17.asInstanceOf[Double][/!] // Value = 17.0 (“casted to double”, converted to double)
fr: double x = 3.72;
    x + 1.234 // Valeur = 4.954
    x + 2. // Valeur = 5.72 (2. signifie 2.0)
    x + 2 // [!java|c]Valeur = 5.72 (2 converti en 2.0 automatiquement)[/!][!scala]Erreur de typage (l'opérateur + operator ne mélange pas les Double avec les Int). Il faut convertir explicitement[/!]
    x * 2. // Valeur = 7.44
    x / 2. // Valeur = 1.86 (2 converti en 2.0 automatiquement)
    [!java|c](int) x[/!][!scala]x.asInstanceOf[Int][/!] // Valeur = 1 (“transtypage en int”, converti en entier en tronquant)
    Math.round(x) // Valeur = 2 (1.86 arrondi à l'entier le plus proche)
    Math.floor(x) // Valeur = 1 (1.86 arrondi en direction de moins l'infini)
    Math.floor(-5.12) // Vale = -6 (Arrondi en direction de moins l'infini)
    Math.ceiling(x) // Value = 2 (1.86 arrondi en direction de plus l'infini)
    Math.ceiling(-5.12) // Value = -5 (Arrondi en direction de plus l'infini)
    [!java|c](double) 17[/!][!scala]17.asInstanceOf[Double][/!] // Value = 17.0 (“transtypage en double”, converti en double)

note: type: Content of: <p>
en: Even if this is the first exercise on the recursivity lesson, the code you have to write is not recursive. The goal is to get familiar with the turtle world before getting on serious matter.
fr: Bien que ce soit le premier exercice de la leçon sur la récursivité, le code que vous devez écrire n'est pas récursif. L'objectif est de se familiariser avec le monde des tortues avant d'attaquer les choses sérieuses.

note: type: Content of: <p>
en: You must reproduce a simple geometrical painting constituted of four 100 steps long squares (see the objective world for more details). It is obviously a good idea to write a method to draw a square, and then use it in your code.
fr: Vous devez reproduire une forme géométrique simple faite de quatre carrés de longueur 100 de coté (voir le monde objectif pour plus de détails). C'est sans doute une bonne idée d'écrire une méthode pour faire un carré, et de la réutiliser lors de l'écriture de votre code.

note: type: Content of: <h2>
en: Fractal of polygons
fr: Fractales de polygones

note: type: Content of: outside any tag (error?)
en: The fractal we will now draw is formed of a polygon, with little polygons on each corner. The prototype of the method drawing it is the following:
fr: La fractale que nous allons dessiner maintenant est formée d'un polygone auquel sont ajoutés des petits polygones sur chaque angle. Le prototype de la fonction le traçant est le suivant:

note: type: Content of: <pre>
en: [!java|c]void [/!]polygonFractal ([!java|c]int [/!]levels[!scala]:Int[/!], [!java|c]int [/!]sides[!scala]:Int[/!], [!java|c]double [/!]length[!scala]:Double[/!], [!java|c]double [/!]shrink[!scala]:Double[/!])
fr: [!java|c]void [/!]polygonFractal ([!java|c]int [/!]niveaux[!scala]:Int[/!], [!java|c]int [/!]cotés[!scala]:Int[/!], [!java|c]double [/!]longueur[!scala]:Double[/!], [!java|c]double [/!]multiplicateur[!scala]:Double[/!])

note: type: Content of: <p>
en: Have a look at each world's objective view to understand how to write the function.
fr: Consultez les objectifs de chaque monde pour comprendre comment écrire la fonction.

note: type: Content of: <h2>
en: Snow flake
fr: Flocons de neige

note: type: Content of: outside any tag (error?)
en: We will now draw snow flakes using the Koch fractal. A fractal is a geometric pattern repeated at every scale.
fr: Nous allons maintenant dessiner des flocons de neige en utilisant la fractale de Koch.  Une fractale est un dessin géométrique dont le motif se reproduit à n'importe quelle échelle.

note: type: Content of: <p>
en: The general form is a triangle, with each side given by several recursive calls. Your work is only to write the code of the <code>snowSide</code> method so that it draws one side of the triangle. To make it easier, each sides are represented in a specific color. Just draw the red things (without changing your pen color), and the other colors will be drawn automatically.
fr: La forme générale est une sorte de triangle, dont chaque coté est généré par des appels récursifs.
    Vous ne devez dessiner qu'un coté de ce triangle dans la fonction <code>snowSide</code>. 
    Pour simplifier les choses, chaque coté a une couleur particulière. Contentez vous de dessiner les choses en rouge (sans changer votre couleur), et les autres couleurs seront dessinées automatiquement.

note: type: Content of: <p>
en: Observe the drawing in each world's objective to understand the pattern's logic, and then reproduce it. At level 0, the Koch curve is just a straight line.  At level 1, the curve is divided in three thirds, and the middle part is replaced by the two sides of an equilateral triangle of the same length as the segment being removed.  At level 2, the process is repeated, whith each segments split in three parts and the middle part being replaced by the two sides of an equilateral triangle.
fr: Observez l'objectif de chaque monde pour comprendre la logique du motif à dessiner, puis reproduisez-le.
    Au niveau 0, la courbe de Koch est une simple ligne droite.
    Au niveau 1, elle est divisée en trois tiers, et la partie du milieu est remplacée par deux cotés d'un triangle équilatéral de même longueur que le segment supprimé.
    Au niveau 2, le processus est répété avec le tiers central de chaque segment remplacé par un petit triangle équilatéral.

note: type: Content of: <p>
en: The pseudo-code of the general case is the following:
fr: Le pseudo-code du cas général est le suivant :

note: type: Content of: <pre>
en:   Draw recursively a smaller segment
      Turn 60 degrees to the left
      Draw recursively a smaller segment  
      Turn 120 degrees to the right
      Draw recursively a smaller segment
      Turn 60 degrees to the left
      Draw recursively a smaller segment
fr:   Dessiner récursivement un segment plus petit
      Tourner à 60 degrés vers la gauche
      Dessiner récursivement un segment plus petit
      Tourner à 120 degrés vers la droite
      Dessiner récursivement un segment plus petit
      Tourner à 60 degrés vers la gauche
      Dessiner récursivement un segment plus petit

note: type: Content of: <p>
en: As you can see, the function forward() is not called from the recursive case, only in the base case when there is no recursive call.
fr: Comme vous pouvez le constater, la fonction avance() n'est pas appelée dans le cas récursif, mais seulement dans le cas de base, quand il n'y a plus d'appel récursif.

note: type: Attribute 'alt' of: <p><div>
en: Too much letters. Please picture it.
fr: TL;DR. Vous pouvez me dessiner tout ça ?

note: type: Content of: <p><div><p>
en: Here are the results of the first levels of recursion.
fr: Voici le résultat des premiers niveaux de récursion.

note: type: Content of: <p>
en: You must write the <code>snowSide()</code> method, which is recursive but <b>do not call snowFlake from snowSide</b>, or you will get very strange and unexpected behaviors.
fr: Vous devez écrire la fonction snowSide, qui est récursive. Mais <b>n'appelez pas snowFlake depuis snowSide</b>, car sinon le résultat sera vraiment étrange et inattendu.

note: type: Content of: <h2>
en: Snow square
fr: Carrés de neige

note: type: Content of: <p>
en: This exercise is a variation over the snow flake that we saw previously.  The main difference is that we are growing little squares instead of triangles on the sides of the figure.
fr: Cet exercice est une variation sur le flocon de neige vu précédemment. 
    La principale différence est qu'il faut maintenant faire pousser des petits carrés au lieu des triangles sur les segments de cette figure.

note: type: Attribute 'alt' of: <p><div>
en: I don't see it, sorry. Please picture it.
fr: Je ne vois pas. Je peux voir un dessin ?

note: type: Content of: <p>
en: As previously, your <code>squareSide</code> function should only draw one side of the figure, and the template will call it for all sides automatically (with one color per side).
fr: Comme précédemment, votre fonction <code>squareSide</code> doit seulement dessiner un coté de la figure, et le code fourni l'appellera 4 fois pour dessiner tous les cotés (chacun avec sa couleur).

note: type: Content of: <h2>
en: Snow pentagon
fr: Pentagone de neige

note: type: Content of: <p>
en: Here comes yet another variation of the Koch curve. This time, we grow little pentagons (ie, polygons with five sides each). I'm sure you get it now.
fr: Voici une autre variation de la courbe de Koch. Cette fois, ce sont de petits pentagones (c'est à dire des polygones à 5 cotés) qui doivent pousser sur les faces de la figure. Je suis sûr que vous commencez à prendre le truc.

note: type: Content of: <p>
en: Another difference with earlier is that the length is not divided by three at each step anymore, but multiplied by 0.4. The curve looks better this way :)
fr: Une autre différence avec les exercices précédents est que cette fois, vous ne devez pas diviser la taille du segment par 3 à chaque niveau de récursion, mais vous devez le multiplier par 0,4. La courbe est plus jolie ainsi :)

note: type: Content of: <p>
en: We draw only one side in this exercise so your code will be called only once this time.
fr: Nous dessinons un seul coté dans cet exercice, donc votre code ne sera appelé qu'une seule fois.

note: type: Content of: <h2>
en: Snow hexagon
fr: Hexagone de neige

note: type: Content of: <p>
en: This time, we will draw the curve that is known as the (6, 0.14)-Koch curve. This means that you have to grow 6-sided polygons on the segments, and that the length should be multiplied by 0.14 at each recursion level.
fr: Cette fois, nous allons dessiner une courbe surnommée la courbe de Koch-(6; 0,14). Cela signifie que nous allons faire pousser des hexagones (des polygones à 6 faces) sur les segments, et que les longueurs doivent être multipliées par 0,14 à chaque étage de la récursion.

note: type: Content of: <p>
en: For the record, the original Koch curve is the (3, 1/3)-Koch curve, the Snow square would be (4,1/3)-Koch curve while the Snow pentagon is also called the (5, 0.4)-Koch curve. If you want, you can switch to the creative mode in the menu and explore freely other Koch curves. Just change the initial call to hexaKoch to what you want.
fr: Pour info, la courbe de Koch originale est la (3; 1/3). Le carré de neige est la courbe (4; 1/3). Le pentagone de neige est la courbe (5; 0,4). Si vous le souhaitez, vous pouvez passer en mode créatif pour explorer d'autres courbes de Koch. Remplacez simplement l'appel à hexaKoch par ce que vous voulez.

note: type: Content of: <p>
en: For further reference, please see <a href="http://ecademy.agnesscott.edu/~lriddle/ifs/kcurve/kcurve.htm">http://ecademy.agnesscott.edu/~lriddle/ifs/kcurve/kcurve.htm</a>.
fr: Pour plus d'informations, référez vous à <a href="http://ecademy.agnesscott.edu/~lriddle/ifs/kcurve/kcurve.htm">http://ecademy.agnesscott.edu/~lriddle/ifs/kcurve/kcurve.htm</a>.

note: type: Content of: <h2>
en: Fractal Crab
fr: La fractale du crabe

note: type: Content of: <p>
en: The Crab curve is not exactly a Koch curve, but that's still a fractal and it's built rather similarly.  This time, we grow square triangle on the side of the figure: the angle is 45 degrees, and the length is divided by [!java|scala]Math.sqrt(2)[/!][!python]math.sqrt(2)[/!][!c]sqrt(2);[/!] at each step.
fr: La courbe du crabe n'est pas exactement une courbe de Koch, mais cette fractale est construite de façon très similaire. Cette fois, nous ne remplaçons pas le tiers central de chaque segment, mais le segment entier. À la place, il faut faire pousser des triangles isocèles et rectangles. L'angle initial est de 45°, et la longueur est divisée par [!java|scala]Math.sqrt(2)[/!][!python]math.sqrt(2)[/!][!c]sqrt(2);[/!] à chaque étape.

note: type: Content of: <p>
en: Check the figures produced by the first steps of recursion to understand the pattern.
fr: Vérifiez les figures produites par les premiers niveaux de récursivité pour comprendre le motif.

note: type: Content of: <h3>
en: Bibliographical note
fr: Note bibliographique

note: type: Content of: <p>
en: This curve, also called the Lévy C curve was invented in 1938 by the French mathematician Paul Lévy.  As usual, the wikipedia page is very instructive, and the page provide very good additions: <a href="http://www.mathcurve.com/fractals/c/c.shtml">http://www.mathcurve.com/fractals/c/c.shtml</a>.
fr: Cette courbe, également appelée la courbe C de Lévy, a été inventée en 1938 par le mathématicien Français Paul Lévy. Comme souvent, la page Wikipedia sur le sujet est très instructive. La page suivante apporte également des compléments intéressants : <a href="http://www.mathcurve.com/fractals/c/c.shtml">http://www.mathcurve.com/fractals/c/c.shtml</a>.

note: type: Content of: <h2>
en: Trees
fr: Arbres

note: type: Content of: <p>
en: We will now draw trees. For that, we will write a method using double recursion following this prototype
fr: Nous allons maintenant dessiner des arbres. Pour cela, nous allons écrire une fonction doublement récursive de prototype

note: type: Content of: <pre>
en: [!java|c]void [/!]tree([!java|c]int [/!]steps[!scala]:Int[/!], [!java|c]double [/!]length[!scala]:Double[/!], [!java|c]double [/!]angle[!scala]:Double[/!], [!java|c]double [/!]shrink[!scala]:Double[/!])
fr: [!java|c]void [/!]tree([!java|c]int [/!]nbPas[!scala]:Int[/!], [!java|c]double [/!]longueur[!scala]:Double[/!], [!java|c]double [/!]angle[!scala]:Double[/!], [!java|c]double [/!]multiplicateur[!scala]:Double[/!])

note: type: Content of: <p>
en: To draw a tree of four levels, you have to draw a trunk of the given length, turn right of the given angle, draw a tree of level 3, turn left twice of the given angle, draw another tree of level 3, and come back to your initial location. Don't forget to come back to the initial location!
fr: Pour dessiner un arbre à quatre étages, il faut dessiner un tronc de la taille indiquée, tourner à droite de l'angle indiqué, faire un arbre à 3 étages, tourner à gauche de deux fois l'angle indiqué, faire un autre arbre à 3 étages, puis revenir à sa position initiale. N'oubliez pas de revenir à la position initiale !

note: type: Content of: <p><p><p>
en: If a tree's trunk is of length 'len', the trunk of the next level tree will be of length 'len*shrink'.
fr: Si le tronc d'un arbre mesure length à l'étage N, il mesure shrink*length à l'étage N+1.

note: type: Content of: <p><p><p><p><p>
en: At the end, here is the pseudo-code of the general case (you should add the base case yourself):
fr: Au final, voici le pseudo-code du cas général de la récursivité (il manque bien sûr le cas de base, laissé en exercice).

note: type: Content of: <p><p><p><p><pre>
en:   Move forward of the desired length
      Draw (recursively) the right subtree
      Draw (recursively) the left subtree
      Move back to your initial position
fr:   Avancer de la longueur désirée
      Dessiner (récursivement) le sous-arbre de droite
      Dessiner (récursivement) le sous-arbre de gauche
      Reculer de la longueur désirée pour retourner au point de départ

note: type: Content of: <p><p><p><p><p>
en: Don't forget to add the base case to your code, or your buggle will enter an infinite loop.  Then, drawing the right subtree comes down to turn right and then draw the subtree.
fr: N'oubliez pas d'ajouter le cas de base dans votre code, ou la buggle va entrer en boucle infinie. De plus, dessiner le sous-arbre droit revient à tourner à droite puis dessiner un sous-arbre.

note: type: Content of: <p><p><p><p><p>
en: As you can see, each recursion level is represented by a distinctive color. For that, you have to call the <code>current(step)</code>, passing the current recursion level as a parameter. This will pick the right color for you.  Don't erase your great colors when you move back to your initial location.
fr: Comme vous pouvez le voir, chaque étage de la récursion est représenté par une couleur distinctive. Pour cela, appelez la fonction <code>current(step)</code> en lui passant en paramètre l'étage actuel de la récursion. Elle se chargera de choisir la couleur adéquate. N'effacez pas vos couleurs quand vous retournez à votre position initiale.

note: type: Content of: <p><p><p><p><p>
en: If you get your function wrong, this can easily become hairly to debug as your errors will appear at each level of the recursion, completely changing the drawing.  For debugging purpose, you can use the <code>subtree()</code> that will draw a correct subtree. This function is then very similar to the one you are trying to write. The only difference is that <code>subtree()</code> only draws in black. So, you can use it instead of a recursive call to debug your code, but you have to change for a proper recursive call to your own code (once it works)  to get the colors right, and pass the exercise.
fr: Si vous vous trompez dans votre fonction, il peut facilement devenir très compliqué de debugger votre code. Vos erreurs se produisant à tous les étages de la récursion, le dessin peut vite devenir illisible. Pour vous aider à debugger, vous pouvez utiliser la fonction <code>subtree()</code> qui dessine un sous-arbre correct. Cette fonction est très (très) semblable par ailleurs à la fonction que vous tentez d'écrire. La seule différence est que <code>subtree()</code> ne dessine qu'en noir. Vous pouvez donc l'utiliser à la place de vos appels récursifs pendant le debug, mais vous devez changer pour des appels récursifs à votre propre code (quand il marche) pour avoir les couleurs justes, et donc pour passer l'exercice.

note: type: Content of: <h2>
en: Sierpinski's Triangle
fr: Triangle de Sierpinski

note: type: Content of: <p>
en: The fractal we will now draw is formed of a big triangle inside which several smaller triangles are embedded. The prototype of the function to draw it is the following:
fr: La fractale que nous allons dessiner maintenant est formée d'un triangle dans lequel sont imbriqués des triangles plus petits.  Le prototype de la fonction le traçant est le suivant :

note: type: Content of: <pre>
en: [!java|c]void [/!]sierpinski([!java|c]int [/!]level[!scala]:Int[/!], [!java|c]double [/!]length[!scala]:Double[/!])
fr: [!java|c]void [/!]sierpinski([!java|c]int [/!]niveau[!scala]:Int[/!], [!java|c]double [/!]longueur[!scala]:Double[/!])

note: type: Content of: <p>
en: Have a look at each world's objective view to understand how to write the function.  To draw one side of the triangle, draw a smaller recursive triangle (halve the length) and move forward by the requested length.  Globally, you have to draw 3 such sides and turn by 120 between each side.
fr: Consultez les objectifs des différents mondes pour comprendre le code que vous devez écrire. Pour dessiner un coté du triangle, vous devez dessiner un triangle récursif plus petit (avec la moitié de la taille) et avancer de la longueur demandée. Au total, vous devez dessiner 3 cotés de la sorte en tournant de 120 entre chaque.

note: type: Content of: <h2>
en: Spirals
fr: Spirales

note: type: Content of: outside any tag (error?)
en: We will now draw our first recursive function with the turtle. The goal is to draw different kind of spirals with the same function, which prototype is the following:
fr: Nous allons maintenant écrire notre première fonction récursive avec les tortues. L'objectif est de dessiner des spirales de différentes formes avec la même fonction, dont le prototype est le suivant:

note: type: Content of: <pre>
en: [!java|c]void [/!]spiral([!java|c]int [/!]steps[!scala]:Int[/!], [!java|c]int [/!]angle[!scala]:Int[/!], [!java|c]int [/!]length[!scala]:Int[/!], [!java|c]int [/!]increment[!scala]:Int[/!])
fr: [!java|c]void [/!]spiral([!java|c]int [/!]nbPas[!scala]:Int[/!], [!java|c]int [/!]angle[!scala]:Int[/!], [!java|c]int [/!]longueur[!scala]:Int[/!], [!java|c]int [/!]increment[!scala]:Int[/!])

note: type: Content of: outside any tag (error?)
en: To help you understanding how to write it, here is an example of how the parameters change during one specific call:
fr: Pour vous aider à comprendre comment l'écrire, voici un exemple de la suite des différentes valeurs prises par les paramètres dans un cas:

note: type: Content of: <pre>
en: spiral(5, 90, 0, 3);
      forward(0);
      left(90);
      spiral(4,90,3,3);
        forward(3);
        left(90);
        spiral(3,90,6,3);
          forward(6);
          left(90);
          spiral(2,90,9,3);
            forward(9);
            left(90);
            spiral(1,90,12,3);
              forward(12);
              left(90);
              spiral(0,90,12,3);
fr: spiral(5, 90, 0, 3);
      avance(0);
      gauche(90);
      spiral(4,90,3,3);
        avance(3);
        gauche(90);
        spiral(3,90,6,3);
          avance(6);
          gauche(90);
          spiral(2,90,9,3);
            avance(9);
            gauche(90);
            spiral(1,90,12,3);
              avance(12);
              gauche(90);
              spiral(0,90,12,3);

note: type: Content of: outside any tag (error?)
en: Note that you only have to write the function, not the initial call.  Each world will provide a specific set of initial parameters (use the combobox to switch to other worlds). For example, the "Square Pyramid" world will call your function as follows:
fr: Notez que vous n'avez que cette fonction à écrire, pas l'appel initial. Chaque monde fournira un ensemble spécifique de paramètres pour votre fonction. Utilisez le combobox en haut à droite pour voir les autres mondes. Par exemple, le monde "Pyramide carrée" appellera votre fonction de la manière suivante :

note: type: Content of: <h2>
en: Drawing spirals
fr: Faire des spirales

note: type: Content of: <p>
en: This exercise is not really an exercise in that sense that you just have to click on the Execute button to get the reward: All the needed code is already provided. Instead, you can here explore the possibilities of the code you just wrote by changing the parameters of the call to the <code>spiral</code> function. You can move on to the next exercise if you are short on time, and come back later to play around.
fr: Cet exercice est un peu particulier, car vous n'avez rien à faire pour le passer. Tout le code nécessaire pour le passer est fourni, et il suffit de cliquer sur le bouton «Exécuter». Il est là pour vous permettre d'explorer les possibilités du code que vous venez d'écrire en changeant les paramètres de l'appel à la fonction <code>spiral</code>. Vous pouvez passer à l'exercice suivant si le temps vous manque, puis revenir jouer ici plus tard.

note: type: Content of: <p>
en: Here are some of the figures that you can produce with your <code>Spiral</code> function, provided that you come with the right parameters. You can switch to the creative mode (from the Exercise menu)  to disable the world comparison when you explore with these spirals.
fr: Voici quelques figures que l'on peut produire avec votre fonction <code>spiral</code> en lui passant les bons paramètres. Passez en mode créatif (dans le menu Exercice) pour désactiver la correction de votre code quand vous explorez ces spirales.

note: type: Content of: <p>
en: If you discover a cool figure, don't forget to send your parameters (menu Help/feedback) so that we can add it to the list!
fr: Si vous découvrez une figure sympa n'oubliez pas de nous envoyer vos paramètres (menu Aide/envoyer une anomalie) pour que nous puissions l'ajouter à la liste!

note: type: Content of: <h2>
en: Dragon curve (1)
fr: Courbe du Dragon (1)

note: type: Content of: <p>
en: The dragon curve is a classical example of recursive method.
fr: Un exemple classique de la méthode récursive est la courbe du Dragon.

note: type: Content of: <p>
en: The definition of this curve is the following:
fr: La définition de cette courbe est la suivante :

note: type: Content of: <p>
en: the dragon curve of order 1 is a vector between to arbitrary points P and Q,
fr: la courbe du Dragon d'ordre 1 est un vecteur entre deux points quelconques P et Q,

note: type: Content of: <p>
en: the dragon curve of order n is the dragon curve of order n-1 between P and R, followed by the same curve of order n-1 between Q and R, where PRQ is an isosceles triangle with angle R being a right angle, and R being at the right of the PQ vector. Thus, if P and Q coordinates are (x, y)  and (z, t), the coordinate (u, v) of R are given by:
fr: la courbe du Dragon d'ordre n est la courbe du Dragon d'ordre n-1 entre P et R suivie de la même courbe d'ordre n-1 entre Q et R, où PRQ est le triangle isocèle rectangle en R, et R est à droite du vecteur PQ.  Donc, si P et Q sont les points de coordonnées (x, y) et (z,t), les coordonnées (u, v) de R sont les suivantes:

note: type: Content of: <p>
en: The prototype of the method drawing the curve is the following:
fr: Le prototype de la méthode traçant la courbe est le suivant :

note: type: Content of: <pre>
en: [!java|c]void [/!]dragon([!java|c]int [/!]order[!scala]:Int[/!], [!java|c]double [/!]x[!scala]:Double[/!], [!java|c]double [/!]y[!scala]:Double[/!], [!java|c]double [/!]z[!scala]:Double[/!], [!java|c]double [/!]t[!scala]:Double[/!])
fr: [!java|c]void [/!]dragon([!java|c]int [/!]ordre[!scala]:Int[/!], [!java|c]double [/!]x[!scala]:Double[/!], [!java|c]double [/!]y[!scala]:Double[/!], [!java|c]double [/!]z[!scala]:Double[/!], [!java|c]double [/!]t[!scala]:Double[/!])

note: type: Content of: <p>
en: You should use the method <code>setPos(x,y)</code> to put your turtle at coordinates (x,y) and the method <code>moveTo(z,t)</code> to draw a line between the turtle position and the point(z,t).
fr: Vous utiliserez la méthode <code>setPos(x,y)</code> pour déplacer votre tortue aux coordonnées (x,y) et la méthode <code>allerVers(z,t)</code> pour tracer un trait depuis le point où la tortue est positionnée vers le point de coordonnées (z,t)

note: type: Content of: <h2>
en: The dragon curve (2)
fr: Courbe du Dragon (2)

note: type: Content of: <p>
en: Previous solution induce that the turtle teleports to other location, or at the very least, that it moves its pen up during the drawing. Indeed, the end of the drawing of the first recursive call does not match the beginning of the second recursive call. That is why we had to use the method <code>setPos()</code>
fr: La solution précédente nécessite que la tortue se téléporte ou qu'elle lève parfois le crayon pour tracer la courbe.  En effet, entre la destination du trait tracé par le premier appel récursif ne correspond pas à la source du trait qui doit être tracé par le second appel récursif.  C'est pourquoi il était nécessaire d'utiliser la méthode <code>setPos()</code>

note: type: Content of: <p>
en: In this lesson, you will write a recursive method allowing to draw the dragon curve without taking the pen up. For that, we need another recursive method drawing the mirror side of the curve.
fr: Dans cette leçon, vous allez donc réaliser une méthode récursive qui permet de tracer la courbe du dragon sans lever le crayon. Pour ce faire, vous définirez une seconde méthode récursive qui trace la courbe à l'envers.

note: type: Content of: <p>
en: The method <code>dragon()</code> is then recursively defined using itself and <code>dragonReverse()</code>. Likewise, the method <code>dragonReverse()</code> is defined recursively using itself and <code>dragon()</code>. This is thus an example of <i>mutual recursion</i>.
fr: La méthode <code>dragon()</code> sera définie récursivement en fonction des méthodes <code>dragon()</code> et <code>dragonInverse()</code>. De même, la méthode <code>dragonInverse()</code> sera définie récursivement en terme de <code>dragon()</code> et de <code>dragonInverse()</code>. Voici un bien bel exemple de <i>récursivité croisée</i>.

note: type: Content of: <p>
en: The prototype of the <code>dragon()</code> method remains unchanged from previous exercise:
fr: Le prototype de la méthode <code>dragon()</code> reste le même que précédemment :

note: type: Content of: <p>
en: The new point's coordinate (u, v) introduced by the <code>dragon()</code> are:
fr: Les coordonnées (u, v) du nouveau point introduit par la méthode <code>dragon()</code> seront :

note: type: Content of: <p>
en: The prototype of the method <code>dragonReverse</code> is similar:
fr: Le prototype de la méthode <code>dragonInverse()</code> est identique : :

note: type: Content of: <pre>
en: [!java|c]void [/!]dragonReverse([!java|c]int [/!]order[!scala]:Int[/!], [!java|c]double [/!]x[!scala]:Double[/!], [!java|c]double [/!]y[!scala]:Double[/!], [!java|c]double [/!]z[!scala]:Double[/!], [!java|c]double [/!]t[!scala]:Double[/!])
fr: [!java|c]void [/!]dragonReverse([!java|c]int [/!]ordre[!scala]:Int[/!], [!java|c]double [/!]x[!scala]:Double[/!], [!java|c]double [/!]y[!scala]:Double[/!], [!java|c]double [/!]z[!scala]:Double[/!], [!java|c]double [/!]t[!scala]:Double[/!])

note: type: Content of: <p>
en: The new point's coordinate (u, v) introduced by the <code>dragonReverse()</code> are:
fr: Les coordonnées (u, v) du nouveau point introduit par la méthode <code>dragonInverse()</code> seront :

note: type: Content of: <p>
en: To make the work of each method recursiv more visible, the line painted by the <code>dragon()</code> must be red (<code>Color.red</code>) while the line painted by the <code>dragonReverse()</code> must be blue (<code>Color.blue</code>).
fr: Afin de rendre, plus visible le travail de chacune des deux méthodes récursives, le trait tracé par la méthode <code>dragon()</code> devra être rouge (<code>Color.red</code>) et le trait tracé par la méthode <code>dragonInverse</code> devra être bleu (<code>Color.blue</code>).

note: type: Content of: <h3>
en: Hanoi towers
fr: Les tours de Hanoï

note: type: Content of: <p>
en: Here comes the super classical exercise on recursion along with some variations. If you have any other nice variations, please submit them.  At some point, someone should also probably contribute these variations to wikipedia, as only the base problem is nicely described there.
fr: Voici le problème ultra classique des tours de Hanoï, accompagné de quelques variantes moins courantes. Si vous connaissez d'autres variantes intéressantes, n'hésitez pas à nous en faire part. Un jour, quelqu'un devrait probablement rédiger ces variantes sur wikipédia. Pour l'instant, seul le problème de base est décrit sur l'encyclopédie libre (même en anglais).

note: type: Content of: <p>
en: The Interleaved and Split variations come from the following article: "Exploring Recursion with Variations on the Towers of Hanoi", Daniel W. Palmer. Available at http://www.ccscjournal.willmitchell.info/Vol12-96/No2a/Daniel%20W%20Palmer.pdf
fr: Les variantes au sujet des tours interclassées et séparées sont issues de l'article suivant : "Exploring Recursion with Variations on the Towers of Hanoi", Daniel W. Palmer. Il est disponible (en anglais) depuis l'adresse suivante http://www.ccscjournal.willmitchell.info/Vol12-96/No2a/Daniel%20W%20Palmer.pdf

note: type: Content of: <p>
en: The Linear Hanoi is briefly discussed in the article presenting the Linear Twin Towers of Hanoi: "The Linear Twin Towers of Hanoi Problem", Steven Minsker (ACM SIGCSE Bulletin Volume 39 Issue 4, December 2007). This article can only be accessed through the paywall of the editor, sorry.
fr: Les tours de Hanoï linéaires sont rapidement décrites dans l'article présentant les tours jumelles linéaires : "The Linear Twin Towers of Hanoi Problem", Steven Minsker (ACM SIGCSE Bulletin Volume 39 numéro 4, Décembre 2007). Cet article n'est disponible que derrière le paywall de l'éditeur, désolé.

note: type: Content of: <p>
en: The 3-colors Towers of Hanoi problem was presented on this web page: http://www.cut-the-knot.org/recurrence/TricolorHanoiAuto.shtml
fr: Le problème des tours de Hanoï tricolores est présenté à l'adresse suivante : http://www.cut-the-knot.org/recurrence/TricolorHanoiAuto.shtml (en anglais)

note: type: Content of: <p>
en: The Cyclic Towers of Hanoi was proposed by M.D. Atkinson in an article of 1981 titled "The cyclic towers of Hanoi" (Information Processing Letters, Volume 13:3).  The article is available at http://www.cs.otago.ac.nz/staffpriv/mike/Papers/Hanoi/CyclicHanoi.pdf.
fr: Le problème des tours de Hanoï cycliques a été proposé par M.D. Atkinson dans un article de 1981 intitulé "The cyclic towers of Hanoi" (Information Processing Letters, Volume 13:3).  Cet article est disponible (en anglais) à l'adresse http://www.cs.otago.ac.nz/staffpriv/mike/Papers/Hanoi/CyclicHanoi.pdf.

note: type: Content of: <p>
en: Here comes the super classical exercise on recursion.
fr: Voici l'exercice ultra classique de récursivité.

note: type: Content of: <p>
en: This is an application exercise of recursion, that you should master to take this lesson.
fr: C'est un exercice d'application de la récursivité, que vous devez maîtriser avant de tenter cette leçon.

note: type: Content of: <h2>
en: Tower of Hanoi
fr: Les tours de Hanoï

note: type: Content of: <p>
en: The Tower of Hanoi or Towers of Hanoi, also called the Tower of Brahma or Towers of Brahma, is a mathematical game or puzzle. It consists of three pegs, and a number of disks of different sizes which can slide onto any peg. The puzzle starts with the disks in a neat stack in ascending order of size on one peg, the smallest at the top, thus forming a pyramid.
fr: La tour de Hanoï, ou les tours de Hanoï, aussi appelé la Tour de Brahma ou les tours de Brahma, est un jeu ou puzzle mathématique. Il consiste en trois tours, et un nombre de disques de différentes tailles qui peuvent glisser sur n'importe quelle tour. Le puzzle commence avec tous les disques en une belle pile selon l'ordre croissant de la taille, le plus petit en haut, sur une tour, formant donc une pyramide. L'objectif du puzzle est de déplacer la pile entière jusqu'à une autre tour, en respectant les règles suivantes :

note: type: Content of: outside any tag (error?)
en: The objective of the puzzle is to move the entire stack to another peg, obeying the following rules:
fr: Le but de ce puzzle est de déplacer tous les disques de la pile vers un autre piquet en respectant les règles suivantes :

note: type: Content of: <ul><li>
en: Only one disk may be moved at a time.
fr: Seul un disque peut être bougé à la fois.

note: type: Content of: <ul><li>
en: Each move consists of taking the upper disk from one of the pegs and sliding it onto another peg, on top of the other disks that may already be present on that peg.
fr: Chaque mouvement consiste à prendre le disque supérieur de l'une des tours et à le déposer sur une autre tour, au sommet des autres disques qui peuvent déjà être présents sur cette tour.

note: type: Content of: <ul><li>
en: No disk may be placed on top of a smaller disk.
fr: Aucun disque ne peut être placé au dessus d'un disque plus petit.

note: type: Content of: outside any tag (error?)
en: Write the core of the method: <code>[!java|c]void [/!]hanoi[!c]Rec[/!]([!java|c]int [/!]height[!scala]:Int[/!], [!java|c]int [/!]src[!scala]:Int[/!], [!java|c]int [/!]other[!scala]:Int[/!],[!java|c]int [/!]dst[!scala]:Int[/!])</code>
fr: Écrivez le corps de la méthode : <code>[!java|c]void [/!]hanoi[!c]Rec[/!]([!java|c]int [/!]height[!scala]:Int[/!], [!java|c]int [/!]src[!scala]:Int[/!], [!java|c]int [/!]other[!scala]:Int[/!],[!java|c]int [/!]dst[!scala]:Int[/!])</code>

note: type: Content of: <p>
en: This method will recursively solve the presented problem. The first parameter named <code>height</code> is the height of the tower to move; The second parameter <code>src</code> is the index of the initial tower, the third parameter <code>other</code> is the index of the unused peg while the fourth parameter <code>dst</code> is the index of the expected final tower.
fr: Cette méthode résout récursivement le problème. 
    Le premier paramètre (nommé <code>hauteur</code>) est la taille de la pile à déplacer.
    Le second paramètre (nommé <code>src</code>) est l'index de la pile initiale.
    Le troisième paramètre (nommé <code>other</code>) est l'index du piquet inutilisé,
    tandis que le quatrième paramètre (nommé <code>dst</code>) est l'index du piquet vers lequel la pile doit être déplacée.

note: type: Content of: <p>
en: A key to solving this puzzle is to recognize that it can be solved by breaking the problem down into a collection of smaller problems and further breaking those problems down into even smaller problems until a solution is reached.
fr: La clé pour résoudre de puzzle est de reconnaître qu'il peut être résolu en cassant le problème en un ensemble de problèmes de plus petites tailles et de continuer cette réduction de la taille du problème jusqu'à atteindre une solution.

note: type: Attribute 'alt' of: <div>
en: I don't get it, please give me some extra indications
fr: Je suis perdu, je voudrais plus d'indications

note: type: Content of: <div>
en: Here is the pseudo-code of the solution:
fr: Voici le pseudo-code de la solution :

note: type: Content of: <div><ul><li>
en: label the pegs A, B, C (these labels may move at different steps)
fr: Étiquetons les tours A, B, C (ces étiquettes peuvent changer à différentes étapes)

note: type: Content of: <div><ul><li>
en: let n be the total number of discs (the height of the initial tower)
fr: Soit n le nombre total de disques (la hauteur de la tour initiale)

note: type: Content of: <div><ul><li>
en: number the discs from 1 (smallest, topmost) to n (largest, bottommost)
fr: Numérotez les disques de 1 (le plus petit, le plus en haut) à n (le plus large, le plus en bas)

note: type: Content of: <div>
en: To move n discs from peg A to peg C:
fr: Pour déplacer n disques du poteau A au poteau C :

note: type: Content of: <div><ul><li>
en: move n−1 discs from A to B. This leaves disc number n alone on peg A
fr: déplacer n-1 disques de A vers B. Cela laisse le disque numéro n seul sur le poteau A

note: type: Content of: <div><ul><li>
en: move disc number n from A to C
fr: déplacer le disque numéro n de A vers C

note: type: Content of: <div><ul><li>
en: move n−1 discs from B to C so they sit on disc number n
fr: déplacer n-1 disques de B vers C afin qu'ils reposent sur le disque numéro n

note: type: Content of: <h2>
en: Interleaved Towers of Hanoi
fr: Les tours de Hanoï interclassées

note: type: Content of: <p>
en: In this classical variation of the Towers of Hanoi, you are given 4 pegs with 2 stacks, one white and one black. You should mix the two stacks as depicted in the Objective world.  As previously, you cannot move a disk on a smaller disk.
fr: Cette variante classique des Tours de Hanoï comporte deux piles de disques sur quatre piquets. Vous devez interclasser les deux piles de la façon représentée sur le monde objectif. Comme précédement, vous ne pouvez pas placer un disque sur un disque plus petit.

note: type: Content of: <p>
en: You will probably need to reuse the <code>hanoi()</code> method that you wrote in the previous exercise.
fr: Vous aurez probablement besoin de la méthode <code>hanoi()</code> que vous avez écrite dans l'exercice précédent.

note: type: Attribute 'alt' of: <div>
en: Please show me an intermediate step
fr: Je voudrais voir une étape intermédiaire

note: type: Content of: <div>
en: If your initial situation is as follows:
fr: Si votre situation initiale est la suivante :

note: type: Content of: <div>
en: then you have the following situation right before the main recursive call:
fr: alors vous avez la situation suivante juste avant l'appel récursif principal :

note: type: Content of: <h2>
en: Split Towers of Hanoi
fr: Les tours de Hanoï séparées

note: type: Content of: <p>
en: Given one interleaved stack (e.g. resulting from the previous exercise), you should build two separate stacks.  In other words, your code should revert the operations done to solve the previous exercise.
fr: Étant donnée le résultat de l'exercice précédent (càd une pile interclassée), vous devez construire deux tours séparées. Votre code doit donc inverser les opérations réalisées à l'exercice précédent.

note: type: Content of: <p>
en: You will need an extra function that can move an interleaved stack of n pairs of disks, without changing the relative positions of disks of the same size.
fr: Vous aurez besoin d'une fonction supplémentaire pour déplacer une pile de n paires de disques sans changer les positions relatives des disques de même taille.

note: type: Content of: <h2>
en: Better Split Towers of Hanoi
fr: De meilleures tours de Hanoï séparées

note: type: Content of: <p>
en: Surprisingly, our solution to split the towers generates much more moves than our solution to interleave them. As both problems are symmetric, this should not be.
fr: Étonnamment, notre solution pour séparer les tours génère beaucoup plus de mouvements que notre solution pour les interclasser. Comme les deux problèmes sont symétriques, cela ne devrait pas être le cas.

note: type: Content of: <br><table><tr><td>
en: Disks amount
fr: Nombre de disques

note: type: Content of: <br><table><tr><td>
en: Interleaved
fr: Interclassement

note: type: Content of: <table><tr><td>
en: Split
fr: Séparation

note: type: Content of: <br><table><tr><td>
en: 5 pairs
fr: 5 paires

note: type: Content of: <br><table><tr><td>
en: 62 moves
fr: 62 mouvements

note: type: Content of: <br><table><tr><td>
en: 88 moves
fr: 88 mouvements

note: type: Content of: <br><table><tr><td>
en: 6 pairs
fr: 6 paires

note: type: Content of: <br><table><tr><td>
en: 126 moves
fr: 126 mouvements

note: type: Content of: <br><table><tr><td>
en: 183 moves
fr: 183 mouvements

note: type: Content of: <br><table><tr><td>
en: 7 pairs
fr: 7 paires

note: type: Content of: <br><table><tr><td>
en: 254 moves
fr: 254 mouvements

note: type: Content of: <br><table><tr><td>
en: 374 moves
fr: 374 mouvements

note: type: Content of: <p>
en: Can you make the split tower as efficient as the interleaved one?
fr: Pouvez-vous rendre la séparation des tours aussi efficace que l'interclassement ?

note: type: Attribute 'alt' of: <div>
en: I need a starter hint
fr: J'ai besoin d'un indice pour commencer.

note: type: Content of: <div>
en: The source of discrepancy is an inefficient problem decomposition.  Satisfied that it merely worked, we looked no futher for a better solution.  Keeping the disks of the interleaved tower in the correct order during every move is unnecessary.  In fact, we can avoid moving the interleaved tower at all.  A better problem decomposition splits the pair of disks into two colored towers as they are removed from the interleaved tower.
fr: La différence vient du fait que notre décomposition du problème n'est pas la bonne. Contents d'avoir trouvé une solution fonctionnelle, nous n'avons pas cherché à l'améliorer. Préserver l'ordre des disques interclassés à chaque déplacement est inutile. En fait, on peut même éviter de déplacer la tour interclassée et simplement séparer les paires de disques en tours colorées au fur et à mesure qu'ils sont retirés de la tour interclassée.

note: type: Attribute 'alt' of: <br><br><div>
en: The starter hint was not enough
fr: Le premier indice n'était pas suffisant

note: type: Content of: <br><br><div>
en: If someone could split the (n-1) pairs of disks beforehand, could you split the remaining pair?
fr: Si quelqu'un pouvait séparer les (n-1) paires de disques auparavent, sauriez-vous séparer la paire restante ?

note: type: Attribute 'alt' of: <br><br><br><br><div>
en: You need to be more explicit
fr: Il va falloir être plus explicite

note: type: Content of: <br><br><br><br><div><ul><li>
en: First split the first (n-1) pairs of disks from the interleaved stack into a white tower and a black tower (calling recursively your main function).
fr: Séparez tout d'abord les (n-1) premières paires de disques de la tour interclassée en une tour blanche et une tour noire (grâce à un appel récursif de votre fonction principale).

note: type: Content of: <br><br><br><br><div><ul><li>
en: Then move the large white disk on its target pole.
fr: Déplacez ensuite le grand disque blanc à la position où il doit finir.

note: type: Content of: <br><br><br><br><div><ul><li>
en: Then move the (n-1) smaller white disks on top of the large one.
fr: Déplacez ensuite les (n-1) disques blancs plus petits sur le grand disque blanc.

note: type: Content of: <br><br><br><br><div><ul><li>
en: Then move the large black disk on its target pole.
fr: Déplacez ensuite le grand disque noir jusqu'à sa destination.

note: type: Content of: <br><br><br><br><div><ul><li>
en: Then move the smaller black disks in position.
fr: Déplacez enfin les petits disques noirs en position.

note: type: Content of: <h2>
en: Fast Split Towers of Hanoi
fr: Les tours de Hanoï séparées rapides

note: type: Content of: <p>
en: Again, our previous solution is working, but it is far from being optimal.  When moving the towers, we use the algorithm for 3 pegs even if we have 4 pegs.  Of course, movements to the last peg are restricted since it contains the other stack, but we can always store the smallest disk on top of the other stack before moving our stack.
fr: Une fois encore, notre solution est fonctionnelle, mais elle est loin d'être optimale. Nous utilisons l'algorithme classique de déplacement des tours, celui inventé pour la situation avec trois piquets, alors que nous avons quatre piquets. Bien entendu, on ne peut pas disposer librement de ce quatrième piquet puisqu'il contient l'autre pile, mais nous pouvons toujours placer le plus petit disque au sommet de l'autre pile avant d'en déplacer une.

note: type: Content of: <p>
en: For that, we need to devise a new function <code>hanoi_fast(height, src, free, full, dst)</code> that moves the stack from <code>src</code> to <code>dst</code> using <code>free</code>, but storing the smallest disk onto <code>full</code> beforehand.
fr: Pour cela, il faut écrire une nouvelle fonction <code>hanoi_rapide(hauteur, src, libre, plein, dst)</code> qui déplace une pile depuis <code>src</code> vers <code>dst</code> en utilisant <code>libre</code> pour le stockage temporaire, après avoir placé le plus petit disque sur le piquet <code>plein</code>.

note: type: Attribute 'alt' of: <div>
en: I'm lost
fr: Je suis perdu

note: type: Content of: <div>
en: The <code>hanoi_fast(height, src, free, full, dst)</code> function is not recursive.  It moves the first disk and then call the regular <code>hanoi()</code> function.
fr: La fonction <code>hanoi_rapide(hauteur, src, libre, plein, dst)</code> n'est pas récursive. Elle place le petit disque, puis appelle la fonction <code>hanoi()</code> classique.

note: type: Content of: <br><p>
en: This change greatly improve the performance, as you can see below. Of course, this trick could also be used for the interleaved algorithm, leading as expected to the exact same performance.
fr: Ce changement améliore considérablement les performances, comme vous pouvez le constater dans le tableau. Bien entendu, cette astuce pourrait être utilisée pour l'algorithme d'interclassement, ce qui boosterait les performances exactement de la même façon.

note: type: Content of: <br><table><tr><td>
en: Slow Split
fr: Séparation lente

note: type: Content of: <br><table><tr><td>
en: Fast Split
fr: Séparation rapide

note: type: Content of: <br><table><tr><td>
en: 46 moves
fr: 46 mouvements

note: type: Content of: <br><table><tr><td>
en: 82 moves
fr: 82 mouvements

note: type: Content of: <br><table><tr><td>
en: 150 moves
fr: 150 mouvements

note: type: Content of: <br><p>
en: As a conclusion, most of us are satisfied with a working solution and we easily overlook possibilities to improve the problem decomposition. <b>You</b> should not do that ;)
fr: En conclusion, nous nous contentons souvent d'une solution fonctionnelle, et nous manquons souvent des occasions d'améliorer la décomposition du problème. <b>Vous</b> ne devriez pas faire cela ;)

note: type: Content of: <h2>
en: Linear Towers of Hanoi
fr: Les tours de Hanoï linéaires

note: type: Content of: <p>
en: This is a classical variation over the Towers of Hanoi where some moves are forbidden.  Specifically, disks cannot move directly between the left-most and the right-most pegs.  The middle peg must be involved in every moves.
fr: Voici une variante classique des tours de Hanoï où certains mouvements sont interdits. Plus précisément, les disques ne peuvent plus passer directement du piquet le plus à gauche au piquet le plus à droite. Le piquet central doit être utilisé dans tous les déplacements.

note: type: Content of: <p>
en: Beside of that extra complexity, the problem remains unchanged: you are requested to move the whole stack of disks from one extremity peg to the other one. You can only move one disk at a time, and a bigger disk cannot be placed over a smaller one.
fr: À part cela, le problème reste inchangé : vous devez déplacer toute la pile de disques d'une extrémité à une autre. Vous ne pouvez déplacer qu'un seul disque à la fois, et il est interdit de placer un grand disque sur un disque plus petit.

note: type: Content of: <p>
en: As with the classical version, it is much easier to produce a recursive solution, and you are absolutely able to devise this solution if you think hard enough about it.
fr: Comme dans la version classique, ce problème se résout plus facilement de manière récursive, et vous êtes tout à fait capable de trouver cette solution récursive si vous y réfléchissez suffisamment.

note: type: Attribute 'alt' of: <div>
en: I tried, but I don't get it
fr: J'ai essayé, mais je n'y arrive pas

note: type: Content of: <div>
en: The standard recursive algorithm for classical Hanoi is of complexity <i>2^n-1</i> where the standard recursive algorithm for this variation is of complexity <i>3^n-1</i>.
fr: L'algorithme récursif habituel pour le problème classique des tours de Hanoï est de complexité <i>2^n-1</i> tandis que l'algorithme récursif habituel pour cette variante est de complexité <i>3^n-1</i>.

note: type: Attribute 'alt' of: <div>
en: That first tip was not enough
fr: Ce premier indice n'était pas suffisant

note: type: Content of: <div>
en: The standard recursive algorithm for classical Hanoi involves two recursive calls sandwiching one movement of the largest disk, the standard recursive algorithm for Linear Hanoi involves three recursive calls sandwiched around two movements of the same disk.
fr: L'algorithme récursif habituel pour le problème classique des tours de Hanoï implique deux appels récursifs enveloppant un mouvement du grand disque. L'algorithme récursif habituel pour les tours linéaires de Hanoï implique trois appels récursifs enveloppant deux mouvement de ce disque.

note: type: Content of: <h2>
en: Linear Twin Towers of Hanoi
fr: Les tours jumelles de Hanoï linéaire

note: type: Content of: <p>
en: This is a mix between both the Split and Interleaved problems, and the linear problem.  We are given two stacks of disks, on three pegs. We are expected to swap the stacks' position while respecting the classical Hanoi movement restrictions (one disk at a time, and no large disk over smaller disks) and the linear movement restriction (no direct exchange between the left-most and right-most pegs).
fr: Cette variante est un mélange entre d'une part les tours séparées et interclassées, et d'autre part les tours linéaires. Nous avons deux piles de disques, et trois piquets. Il faut inverser la position des piles en respectant les règles de mouvement habituelles des tours de Hanoï (un seul disque à la fois, et pas de grand disque sur les petits disques) ainsi que les restrictions du mouvement linéaire (pas d'échange direct entre les piquets des extrémités).

note: type: Content of: <p>
en: You will use three recursive functions:
fr: Vous aurez besoin de trois fonctions récursives :

note: type: Content of: <ul><li>
en: <b>moveDouble(k,from, to)</b>: moves an interleaved stack of k pairs of disks, without changing the relative positions of disks of the same size. As in the Split Hanoi problem, an interleaved stack alternates white and black disks of each sizes. This function is not completely new: you wrote a version with 4 pegs (but using only 3 of them) for the first version of the Split Hanoi problem.
fr: <b>deplaceInterclassee(k, src,dst)</b> : déplace une pile interclassée de k paires de disques, sans changer l'ordre relatif des disques de même taille. Comme dans le problème des tours séparées, une tour interclassée alterne des disques blancs et noirs de chaque taille. Cette fonction n'est pas entièrement nouvelle : vous avez écrit une version avec quatre piquets (mais en n'en utilisant que trois) dans la première version des tours séparées.

note: type: Content of: <ul><li>
en: <b>gather(k)</b>: from the initial split situation, build on peg #2 an interleaved stack of k pairs of disks. You may parametrize your function so that it can be used to gather the disk on any peg passed as parameter, but in practice, your function will only be used to gather on the last peg.
fr: <b>rassemble(k)</b> : à partir d'une situation séparée, construire sur le piquet n°2 une pile interclassée de k paires de disques. Vous pouvez rendre votre fonction paramétrable afin qu'elle puisse rassembler les disque sur n'importe quel piquet passé en paramètre, mais en pratique, elle ne sera utilisée que pour rassembler les disques sur le dernier piquet.

note: type: Content of: <ul><li>
en: <b>scatter(k)</b>: from a situation where k pairs of disks are interleaved on peg #0, split it down by moving the white disks to peg #1 and black ones to peg #2.
fr: <b>repartis(k)</b> : à partir d'une situation où k paires de disques sont interclassés sur le piquet n°0, séparez là en déplaçant les disques blancs sur le piquet n°1 et les noirs sur le piquet n°2.

note: type: Content of: <p>
en: In <code>gather()</code>, the recursive call comes before two calls to <code>moveDouble()</code> while in <code>scatter()</code>, the calls to <code>moveDouble()</code> come before the recursive call.  The main function that you should write is not recursive, but simply gather almost all disks, moves directly the remaining disks, and then scatters back the small disks.
fr: Dans <code>rassemble()</code>, l'appel récursif vient avant deux appels à <code>deplaceInterclassee</code> tandis que dans <code>repartis()</code> les appels à <code>deplaceInterclassee</code> arrivent avant l'appel récursif. La fonction principale que vous devez écrire n'est pas récursive, mais rassemble simplement la plupart des disques, déplace les disques restants, puis répartit de nouveau les petits disques.

note: type: Content of: <p>
en: The linearity naturally induces some extra complexity as you have to decompose every move between pegs 0 and 2. I am still confident in your ability to overcome the challenge :)
fr: La linéarité ajoute certainement un peu de complexité puisqu'il faut décomposer tous les mouvements entre les piquets n°0 et n°2, mais je reste confiant dans votre capacité à résoudre cette épreuve :)

note: type: Content of: <p>
en: Note that the requested algorithm was proved optimal for that problem, so you don't need to fiddle the performance this time.
fr: Remarquez que l'algorithme demandé a été prouvé optimal pour ce problème. Il n'est donc pas utile aujourd'hui de chercher à optimiser plus que demandé.

note: type: Content of: <h2>
en: Tricolor Hanoi: stack move
fr: Tours de Hanoï tricolores : déplacer

note: type: Content of: <p>
en: In this set of exercises, we will devise an algorithm for the Tricolor Hanoi problem.  There will be 3 stacks on 3 pegs, each stack of a differing color, and the problem is to exchange the stacks' positions under the classical move rules (one disk at a time, and no bigger disk over smaller disk).
fr: Dans cette série d'exercices, nous allons mettre au point un algorithme pour le problème des tours de Hanoï tricolores. Il y aura trois piles de couleurs différentes sur trois piquets, et il s'agira d'échanger la position des piles en respectant les règles de mouvement habituelles (un disque à la fois, et pas de gros disques sur des petits disques).

note: type: Content of: <p>
en: As in previous exercises, our solution will use three functions:
fr: Comme précédement, notre solution sera basée sur trois fonctions :

note: type: Content of: <ul><li>
en: <code>move3(n, src, mid, dst)</code>: moves a stack of interleaved disks, ie a stack of (n*3) disks of alternating colors from peg <code>src</code> to peg <code>dst</code>.
fr: <code>move3(n, src, mid, dst)</code>: déplace une pile de disques interclassée, c'est-à-dire une pile de (n*3) disques de couleurs alternées, depuis le piquet <code>src</code> jusqu'au piquet <code>dst</code>.

note: type: Content of: <ul><li>
en: <code>gather()</code>: builds an interleaved stack from the regular split ones.
fr: <code>rassemble()</code> : construit une pile interclassée à partir de trois piles séparées.

note: type: Content of: <ul><li>
en: <code>scatter()</code>: splits an interleaved stack into several regular ones.
fr: <code>repartis()</code> : démonte une pile interclassée en trois piles normales.

note: type: Content of: <p>
en: The goal of this first exercise in the series is to devise the <code>move3()</code> function.  This starter task should not block you for too long, actually. It is ok if your function changes the order of the bottom triplet of disks, but it must preserve the order of the other triplets.
fr: L'objectif de ce premier exercice de la série est d'écrire la fonction <code>move3()</code>. Cet échauffement ne devrait pas vous bloquer très longtemps. Cela ne pose pas de problème si votre fonction change l'ordre des disques du triplet du bas, mais les autres triplets doivent rester dans le même ordre.

note: type: Content of: <h2>
en: Tricolor Hanoi: the Gathering
fr: Tours de Hanoï tricolores : rassembler

note: type: Content of: <p>
en: It is now time to write the second function required by the Tricolor Hanoi problem.  <code>gather()</code> builds an interleaved stack from the regular split ones. This function takes four arguments, the last one being the target peg where the interleaved stack must be assembled.  As you can see in the examples, the colors of must be in the same order for each triplet of disks.
fr: Il est maintenant temps d'écrire la seconde fonction nécessaire pour les tours de Hanoï tricolores. La fonction <code>gather()</code> construit une pile interclassée à partir de piles séparées (gather veut dire «rassembler» en anglais). Cette fonction prend quatre arguments, le dernier étant le numéro du piquet où il faut construire la pile interclassée. Comme vous pouvez voir dans les exemples, l'ordre des couleurs doit être le même pour tous les triplets de disques.

note: type: Content of: <p>
en: That function actually uses the <code>move3()</code> that you wrote just before. Simply copy/paste your code over to reuse it. If you're lost, please refer to the Interleaved Hanoi exercise. Gathering 3 stacks on 3 pegs is rather similar to gathering 2 stacks on 4 pegs. You can find that exercise <a href="plm://lessons.recursion.hanoi/InterleavedHanoi">here</a>.
fr: Cette fonction utilise la fonction <code>move3()</code> que vous venez d'écrire. Faites un copie/colle de votre code pour le réutiliser ici. Si vous avez besoin de plus d'explications, référez vous à l'exercice des tours interclassées. Rassembler 3 piles sur 3 piquets est assez similaire à rassembler 2 piles sur 4 piquets. Vous trouverez cet exercice <a href="plm://lessons.recursion.hanoi/InterleavedHanoi">ici</a>.

note: type: Content of: <h2>
en: Tricolor Hanoi: the Final
fr: Tours de Hanoï tricolores : séparer et terminer

note: type: Content of: <p>
en: We are almost ready to write the whole tricolor algorithm. We just need the <code>scatter()</code> function, very inspired from the first one that we wrote for the <a href="plm://lessons.recursion.hanoi/SplitHanoi1">Split Hanoi problem</a>. Assuming that your interleaved stack is placed on the <code>mid</code> peg, spread the disks over all pegs. Make sure to use <code>move3()</code> an even amount of time at each recursive level to ensure that the bottom disks are in the correct order.
fr: Nous sommes presque prêts à écrire l'algorithme entier des tours tricolores. Il ne nous manque plus qu'une fonction <code>separe()</code>, très inspirée de la première que nous avions écrite pour le problème des <a href="plm://lessons.recursion.hanoi/SplitHanoi1">Tours de Hanoï séparées</a>. En supposant que votre tour interclassée se trouve sur le piquet <code>mid</code>, il faut répartir les disques sur tous les piquets. Assurez-vous d'utiliser la fonction <code>move3</code> un nombre pair de fois à chaque étage récursif afin que les disques du triplet du bas soient dans le bon ordre.

note: type: Content of: <p>
en: As you can see, the initial situation is not the one expected by <code>scatter()</code>. You first have to apply <code>gather()</code> and <code>move3()</code> (twice to get the bottom triplet in the right order). These few steps plus the new <code>scatter()</code> function are enough to entirely solve the Tricolor Hanoi problem.
fr: Comme vous pouvez le voir, la situation initiale n'est pas celle attendue par la méthode <code>separe()</code>. Il faut auparavant utiliser les méthodes <code>gather()</code> puis <code>move3()</code> (deux fois pour que le triplet du bas soit dans le bon ordre). Ces quelques étapes suivies de la fonction <code>separe()</code> suffisent à résoudre intégralement le problème des tours tricolores de Hanoï.

note: type: Content of: <h2>
en: Cyclic Towers of Hanoi
fr: Les tours de Hanoï cycliques

note: type: Content of: <p>
en: This variation of the Towers of Hanoi is very similar to the regular problem: you are given one stack of disks and three pegs, and you cannot move a larger disk over a smaller one.  The change is that you can only move disks clockwise: 0->1 or 1->2 or 2->0, but never in the other direction.
fr: Cette variante des tours de Hanoï est très similaire au problème de base : vous avez une pile de disques, trois piquets et il est interdit de placer un gros disque sur un disque plus petit. La nouveauté est que vous ne pouvez bouger les disques que dans un seul sens : 0->1 ou 1->2 ou 2->0, mais jamais dans l'autre sens.

note: type: Content of: <p>
en: Obviously, the movements are not symmetric anymore. Moves from A to B are now very different from moves to B to A.  As a result, you need two recursive functions depending on whether you are moving the stack clockwise or counterclockwise.
fr: Manifestement, les mouvements ne sont plus symétriques. Déplacer un disque de A vers B est maintenant très différent de le déplacer de B vers A. Du coup, vous aurez besoin de deux fonctions récursives permettant respectivement de déplacer la pile dans le sens indiqué (<code>clockwise</code>), ou dans l'autre sens.

note: type: Content of: <p>
en: That being said, the problem decomposition is very similar to the classical Hanoi. The twist is that each function call the other one, constituting a nice example of mutual recursion.
fr: Ceci étant, la décomposition récursive du problème est très similaire à celle du problème classique. Simplement, chacune des deux fonctions appelle l'autre, constituant un bel exemple de récursivité mutuelle.

note: type: Content of: <h2>
en: Iterative Towers of Hanoi
fr: Les tours de Hanoï itératives

note: type: Content of: <p>
en: In this last exercise of the series, we will implement an iterative algorithm for the base problem of the Towers of Hanoi (one stack, 3 pegs, no extra movement restriction).
fr: Dans ce dernier exercice de la série, nous allons implémenter une solution itérative au problème de base des tours de Hanoï (une pile, trois piques, pas de restriction de mouvement particulière).

note: type: Content of: <p>
en: This algorithm is actually very simple: On odd moves, the smallest disk is moved in a given direction (either increasing 0-&gt;1-&gt;2-&gt;0 or decreasing 2-&lt;1-&lt;0-&lt;2) while on even moves, the only possible move that does not imply the smallest disk is made. You stop as soon as the stack is rebuilt on another location.
fr: Cet algorithme est très simple, en fait : Lors des déplacements pairs, le plus petit disque se déplace dans une direction donnée (soit dans le sens ascendant 0-&gt;1-&gt;2-&gt;0 soit dans le sens descendant 2-&gt;1-&gt;0-&gt;2). Lors des déplacements impaires, on fait le seul mouvement possible n'impliquant pas le petit disque. On s'arrête dès que la pile est reconstruite quelque part.

note: type: Content of: <p>
en: The function that you now need to write takes two parameters: the initial position of the smallest disk (i.e., the peg initially containing the stack) and a boolean indicating whether the smallest disk should move in the increasing order or not.
fr: La fonction que vous devez écrire pour cela prend deux paramètres : la position initiale du petit disque (càd le numéro du piquet contenant initialement la pile) et un booléen indiquant si le petit disque doit se déplacer dans le sens ascendant ou non.

note: type: Content of: <p>
en: The simplicity of this algorithm is actually almost deceiving. One could wonder on the interest of the recursive algorithms when such a simple iterative algorithm exists. My personal feeling is that this solution is nice to execute, but almost impossible to devise in the first place (I even suspect that the authors built this iterative solution from observations of the recursive execution)...
fr: La simplicité de cet algorithme est presque décevante ! On peut s'interroger sur l'intérêt des solutions récursives que nous avons construit jusqu'ici alors qu'il existe un algorithme itératif aussi simple. Mon avis personnel est que cette solution est facile à exécuter une fois qu'on l'a, mais pratiquement impossible à découvrir par soit-même (je soupçonne même les auteurs de l'avoir découverte en observant les effets de la solution itérative)...

note: type: Content of: <p>
en: Predicting the effect of this function is also difficult: When the small disk moves in the increasing order, the stack is reconstructed on the right peg with 5 disks but on the left with 6 disks.
fr: Il est également malaisé de prédire le résultat de cet algorithme : quand le petit disque se déplace dans l'ordre ascendant, la pile est reconstruite à droite pour cinq disques, mais à gauche pour six disques.

note: type: Content of: <p>
en: An interesting question is whether such simple iterative algorithms exist for the other variation of the problem. Some were given in the literature (e.g. for the cyclic variation). I would happily integrate your solutions to the PLM, especially if you can hint (without spoiling) the solution to guide the next ones.
fr: Une question intéressante est de savoir s'il existe des algorithmes itératifs aussi simples pour les différentes variantes du problème. Certains ont été proposés dans la littérature (en particulier pour la variante cyclique). J'intégrerais vos solutions avec plaisir dans la PLM, surtout si vous trouvez des indications permettant de guider la réflexion sans donner la solution.

note: type: Content of: <h1>
en: HanoiWorld
fr: Le monde des tours de Hanoï

note: type: Content of: <p>
en: This world implements the ultra-classical Hanoi problem. You are asked to move the disk pile from the stick where they are to the target stick (given as second parameter in the world's name -- number 1 for the default world). There is some extra constraint: you can only move one disk at a time, and you cannot move a big disk over a smaller one.
fr: Ce monde implémente le problème ultra classique de Hanoï. Il vous est demandé de déplacer une pile de disques du piquet où ils se trouvent vers un piquet cible (passé comme second paramètre dans le nom du monde -- numéro 1 pour le monde par défaut). Il y a quelques contraintes supplémentaires: il est interdit de déplacer plus d'un disque à la fois, ainsi que de placer un disque plus grand sur un disque plus petit.

note: type: Content of: <p>
en: Only 4 functions are provided:
fr: Seules quatre fonctions sont fournies&nbsp;:

note: type: Content of: <pre>
en: [!java|c]void [/!]move([!java|c]int [/!]src, [!java|c]int [/!]dst)
fr: [!java|c]void [/!]deplace([!java|c]int [/!]src, [!java|c]int [/!]dst)

note: type: Content of: outside any tag (error?)
en: Moves one disk from the stick <code>src</code> onto the stick <code>dst</code>. If you try to do an invalid move (like laying a disk over a smaller one), an IllegalArgumentException is thrown.
fr: Elle déplace un disque d'un piquet <code>src</code> vers le piquet <code>dst</code>. Si vous demandez un déplacement invalide (comme le placement d'un disque sur un disque plus petit), une exception IllegalArgumentException est levée.

note: type: Content of: <pre>
en: [!java|c]int [/!]getSlotSize([!java|c]int [/!]slot)[!scala]:Int[/!]
fr: [!java|c]int [/!]getTaillePiquet([!java|c]int [/!]slot)[!scala]:Int[/!]

note: type: Content of: outside any tag (error?)
en: Returns the amount of disks placed on the specified slot. This is mainly used to initialize the recursion and set the amount of recursive call to execute.
fr: Retourne le nombre de disques placés sur un piquet donné. Cette fonction est surtout utile pour initialiser la récursion et déterminer le nombre d'appels récursifs à réaliser.

note: type: Content of: <pre>
en: [!java|c]int [/!]getSlotRadius([!java|c]int [/!]slot)[!scala]:Int[/!]
fr: [!java|c]int [/!]getRayonPiquet([!java|c]int [/!]slot)[!scala]:Int[/!]

note: type: Content of: outside any tag (error?)
en: Returns the radius of the top-most disk of the specified slot.
fr: Retourne le rayon du disque placé en haut du piquet spécifié.

note: type: Content of: <h3>
en: Labyrinths
fr: Labyrinthes

note: type: Content of: <p>
en: This lesson proposes several exercises about labyrinths in the buggle world.
fr: Cette leçon propose divers exercices à propos des labyrinthes dans le monde des buggles.

note: type: Content of: <h2>
en: The crazy mouse
fr: La souris folle

note: type: Content of: <p>
en: The day of your buggle starts badly. Out of luck, it got trapped into a maze. Help it finding its path out of there.
fr: La journée de votre buggle commence mal. Elle n'a pas eu de chance. Elle est tombée dans un piège.  Aidez-la à sortir de ce labyrinthe.

note: type: Content of: <p>
en: The exit is represented by a baggle and you need to pick this baggle in order to exit the maze.
fr: La sortie est représentée par un baggle et vous devez le ramasser afin de vous échapper du labyrinthe.

note: type: Content of: <p>
en: Since the maze is so small, we can write the dumbest possible algorithm to do so. It relies on randomness and proves quite inefficient.
fr: Nous allons profiter du fait que le labyrinthe ne soit pas trop grand pour écrire l'algorithme le plus bête possible.  Cet algorithme repose sur le hasard et est très inefficace.

note: type: Content of: <p>
en: While the buggle didn't find the path to the escape, it must proceed the following way: pick a random integer between 0 and 2 by using the provided <code>random3()</code> method and make one of the following actions: moving forward if possible, turn left or turn right.
fr: Tant que notre buggle n'a pas trouvé la sortie, elle doit progresser de la façon suivante&nbsp;: choisir un entier entre 0 et 2 au hasard à l'aide de la méthode <code>random3()</code> fournie et prendre l'une des décisions suivantes selon l'entier choisi&nbsp;: avancer si elle le peut, tourner à droite ou bien tourner à gauche.

note: type: Content of: <p>
en: You don't believe that it could work? Well, give it a try, you will see...  Don't forget to pick up the baggle once you've reached it.
fr: Vous ne croyez pas qu'une méthode aussi stupide puisse fonctionner ? Et bien, essayez, vous verrez bien.
    N'oubliez pas de ramasser le biscuit quand vous l'avez trouvé.

note: type: Content of: <h2>
en: Following the walls
fr: Longer les murs

note: type: Content of: <p>
en: This time, the maze is a bit more complicated. Random won't be enough, we ough to be smart!
fr: Cette fois-ci le labyrinthe est beaucoup plus compliqué. Le hasard ne sera pas suffisant, il va falloir être intelligent !

note: type: Content of: <p>
en: The good news is that this maze is simpler that it seems at the first glance: every wall are connected to each other. To get out of this kind of maze, the buggle only have to follow a wall (the one on its left or the one on its right, it doesn't matter).  While keeping a paw on the wall, the buggle must move forward until it finds the maze exit and this biscuit it loves so much.
fr: Heureusement, ce labyrinthe est plus simple qu'il n'y paraît: tous les murs sont connectés les uns aux autres. Pour sortir de ce genre de labyrinthe, il suffit à votre buggle de longer un mur (celui à sa droite, ou celui à sa gauche: c'est sans importance). Tout en gardant sa patte posée sur ce mur, votre buggle doit avancer jusqu'à ce qu'elle trouve la sortie du labyrinthe et ce biscuit qu'il apprécie tant.

note: type: Content of: <p>
en: This works here because there is no island of isolated walls, so our buggle cannot loop around for ever without encountering its baggle.
fr: Cet algorithme fonctionne ici car il n'y a pas d'île de murs isolés, ce qui fait que la buggle ne peut pas boucler autour des murs sans rencontrer le biscuit qu'elle cherche.

note: type: Content of: outside any tag (error?)
en: The goal of this exercise is to write an algorithm allowing the buggle to get out of this maze.
fr: L'objectif de cet exercice est d'écrire un algorithme permettant à votre buggle de sortir du labyrinthe.

note: type: Content of: <p>
en: As said earlier, it does not matter whether you decide to follow the left wall or the right one. Simply, the demo follows the left one, so you should do the same in your solution to ease the comparison of your solution and the demo.
fr: Comme dit précédemment, le mur choisi n'a pas d'importance. Simplement, la démo suit le mur gauche, et il serait donc avisé d'en faire de même pour simplifier la comparaison de votre solution et de la démo.

note: type: Content of: <p>
en: Write a method <code>keepHandOnSideWall()</code> which lets the buggle move one step forward while keeping the paw on the wall of the selected side. You must ensure that the buggle always keep the paw on the wall, but also that it won't crash into a wall. You can check the tip for more info on this, but only do so if you're stuck. Try to do it without the tip first.
fr: Écrivez une méthode <code>keepHandOnSideWall()</code> qui fait avancer votre buggle d'une case tout en gardant la patte sur le mur du côté choisi. Vous devez vous assurer que votre buggle garde toujours la patte sur le mur et également qu'elle ne risque pas de percuter un mur. Vous pouvez regarder l'indice (hint) si vous êtes coincé, mais vous devriez d'abord essayer de le faire par vous-même.

note: type: Content of: <p>
en: Then, write the whole algorithm to traverse the maze step by step (using <code>keepHandOnSideWall()</code>) until it finds the biscuit and the exit. Don't forget to pick the baggle up once you've found it.
fr: Enfin, écrivez l'algorithme complet qui parcourt le labyrinthe pas à pas jusqu'à trouver le biscuit et la sortie. N'oubliez pas de prendre le baggle.

note: type: Attribute 'alt' of: <div>
en: I'm lost, please give me some extra indications
fr: Je suis perdu, je voudrais plus d'indications

note: type: Content of: <div><p>
en: When your buggle has a wall on the left, there is three situations to consider, depending on the surrounding walls. The following table depicts each initial situation, and where you should let your buggle end after one step.
fr: Quand votre buggle a un mur à sa gauche, il faut considérer trois situations possibles, qui dépendent des murs alentours. Le tableau suivant représente graphiquement chaque situation initiale, et où vous devez placer votre buggle à la fin de l'étape.

note: type: Content of: <div><table><tr><td>
en: Case 1
fr: Cas 1

note: type: Content of: <div><table><tr><td>
en: Case 2
fr: Cas 2

note: type: Content of: <div><table><tr><td>
en: Case 3
fr: Cas 3

note: type: Content of: <div><table><tr><td>
en: Initial situation
fr: Situation initiale

note: type: Content of: <div><table><tr><td>
en: Where is the next step
fr: Étape suivante

note: type: Content of: <div><p>
en: If you do a <code>right()</code> in any case at the end of your function, it's possible to write it in 3 lines with a <code>while</code> loop.
fr: Si vous faites un <code>right()</code> dans tous les cas à la fin de votre fonction, il est possible de l'écrire en trois lignes avec une boucle <code>while</code>.

note: type: Content of: <h2>
en: Pledge algorithm
fr: Algorithme de Pledge

note: type: Content of: <p>
en: Once again, you thought that your algorithm were good enough to escape the maze, and once again, you buggle is now in a maze where your previous algorithm fails. Just give it a try: copy/paste your code and hit the "Run" button and see your creation fail. The trap is shaped like an upper case "G". The buggle enters the trap and follows the inner border. At some point, it finds the north direction free, run into that direction, and falls again in the trap.
fr: Une fois de plus, vous pensiez que votre algorithme vous permettait de vous échapper des labyrinthes, et une fois de plus, votre buggle est prise dans un labyrinthe mettant votre algorithme en défaut. Essayez de copier votre code et de l'exécuter pour voir : votre création précédente échoue lamentablement. Le piège a la forme d'un «G» majuscule : la buggle entre dans le piège, suit le bord interne. Au bout d'un moment, la direction nord est libre et votre buggle se met donc à courir dans cette direction. Pour retomber dans le piège...

note: type: Content of: <p>
en: The Pledge's algorithm (named after Jon Pledge of Exeter) can solve this maze.
fr: L'algorithme de Pledge (nommé d'après Jon Pledge d'Exeter) peut sortir de ce labyrinthe.

note: type: Content of: <p>
en: This algorithm is a modification of the previous one thought to avoid obstacles. It randomly picks a heading and let the buggle move in that direction. When it encounters an obstacle, a paw (for example the left one)  is kept on the wall following the obstacle while counting the turns. When the buggle is back to its original heading and when the sum of the turns is 0, the buggle leaves the obstacle and continues keeping its original heading.
fr: Cet algorithme est une version modifiée de l'algorithme précédent conçu pour éviter les obstacles. Il nécessite de choisir de manière arbitraire une direction vers laquelle la buggle se dirigera. Quand un obstacle est rencontré, une patte (disons la patte de gauche) est gardée le long des obstacles tandis que les virages sont comptabilisés. Quand la buggle est face à nouveau à la direction originale, et que la somme des virages est égale à 0, la buggle quitte l'obstacle et continue de se déplacer dans sa direction d'origine.

note: type: Content of: <p>
en: Note that the use of "total turning" rather than just the "current direction" allows the algorithm to avoid G-shapped traps. If one proceeds left into the trap, one gets turned around a full 360 degrees by the walls. As we said before, the naive "current direction" algorithm gets into a limit cycle as it leaves the lower rightmost wall heading left and runs into the curved section on the left again.
fr: Notez que l'utilisation de la "somme des virages" à la place de la "direction courante" permet à l'algorithme d'éviter les pièges tel que les formes en "G" majuscule. Si l'on rentre par la gauche dans le piège, on tourne de 360 degrés autour des murs. Un algorithme qui se contenterait naïvement de se retrouver dans la même direction qu'à l'origine rentre dans un cycle infini puisque qu'il quitte le mur le plus à droite en étant dirigé vers la gauche, et entre à nouveau dans la section incurvée.

note: type: Content of: <p>
en: The Pledge's algorithm does not leave the rightmost wall due to the total turning not being zero at that point. It follows the wall all the way around, finally leaving it heading left on the bottom outside
fr: L'algorithme de Pledge ne quitte pas le mur en bas à droite puisque la somme des virages ne vaut pas zéro à ce moment. Il continue de suivre le mur jusqu'à avoir complètement fait le tour, et le quitte en regardant à gauche une fois parvenu sous l'obstacle.

note: type: Content of: <p>
en: <a name="Objective"/>You now have to modify your solution to implement the Pledge algorithm to escape this maze.
fr: <a name="Objectifs"/> L'objectif de cet exercice est d'écrire une implémentation de l'algorithme de Pledge qui permettra à votre buggle de sortir du labyrinthe.

note: type: Content of: <p>
en: Change your <code>keepHandOnSideWall()</code> method to count the amount of turns done by the buggle (+1 when it turns left, and -1 when it turns right). This counting may require the addition of an <code>angleSum</code> integer value in your program.
fr: Reprenez la méthode <code>keepHandOnSideWall()</code> de l'exercice précédent. Modifiez cette méthode pour compter les virages pris par votre buggle (+1 lorsqu'il a tourné à gauche par rapport à son origine, -1 lorsqu'il a tourné à droite). Pour comptabiliser vous aurez besoin d'ajouter une variable <code>sommeAngle</code> de type entière à votre programme.

note: type: Content of: <p>
en: Write a boolean method <code>isDirectionFree(dir)</code> indicating if the provided direction is free, ie, if you can move in that direction (Note that the demo uses the NORTH direction for that).  You can retrieve the current direction of the buggle using the method <code>getDirection()</code>. You can change your direction (without moving) using <code>setDirection(dir)</code>. Don't forget to store the previous direction of your buggle (in a dedicated variable) before checking if your favorite direction is free in order to restore your state afterward.
fr: Écrivez une méthode booléenne <code>isDirectionFree(dir)</code> indiquant si la direction fournie en paramètre est libre, c'est-à-dire si vous pouvez vous déplacer dans cette direction. Notez que la démo utilise la direction NORD pour cela. Vous pouvez retrouver la direction courante de la buggle en utilisant la méthode <code>Direction getDirection()</code>.  Vous pouvez diriger (sans se déplacer) votre buggle dans une direction en utilisant la méthode <code>setDirection(dir)</code>.  Pensez à mémoriser (dans une variable dédiée) la direction courante de votre buggle avant de vérifier si votre buggle peut se diriger vers sa direction de prédilection pour pouvoir restaurer l'état après coup.

note: type: Content of: <p>
en: You may have to change the rest of your code also, but these changes should remain limited.
fr: Vous pouvez être amenés à modifier également le reste de votre code, mais ces changements devraient rester limités.

note: type: Content of: <p>
en: Don't forget that if you have a method modifying a global variable (such as angleSum), you should ensure that it declares this variable as global. Without it, the method creates a new variable of the same name, and the global never gets modified.
fr: N'oubliez pas que si l'une de vos méthodes modifie une variable globale (telle que sommeAngles), vous devez vous assurer qu'elle définie cette globale correctement. Sinon, la méthode crée une nouvelle variable locale de même nom, et la globale n'est jamais modifiée.

note: type: Content of: <pre>
en: def myMethod():
      global angleSum
      ...
      angleSum = angleSum + 1
fr: def myMethod():
      global sommeAngle
      ...
      sommeAngle = sommeAngle + 1

note: type: Attribute 'alt' of: <div>
en: Show an additional tip
fr: Montrer un indice supplémentaire

note: type: Content of: <div>
en: You should set your direction to your favorite one (NORTH is advised). Then, you should write the algorithm main loop. In other words, while your buggle did not find its biscuit, you have to move forward until next obstacle in the favorite direction. Then, put a paw on a wall (using <code>keepHandOnSideWall()</code>) while the sum of turns is not null and the favorite direction is not free. Do that until you find your baggle.
fr: Vous devez changer votre cap vers votre direction favorite (probablement le nord -- Direction.NORD). Il vous faut ensuite écrire la boucle principale de votre algorithme. Tant que votre buggle n'a pas trouvé son biscuit, il faut avancer jusqu'à un obstacle dans la direction de prédilection. Quand un obstacle est rencontré, il faut garder la patte sur un mur (en utilisant <code>keepHandOnSideWall()</code>) tant que la somme des virages n'est pas nulle et que la direction de prédilection n'est pas libre. Faites cela jusqu'à trouver votre biscuit.

note: type: Content of: <h2>
en: Lost between islands
fr: Perdu dans les îles

note: type: Content of: <p>
en: You thought that your algorithm was enough to escape mazes? Well, not every mazes...
fr: Vous pensiez que votre algorithme était suffisant pour échapper de tous les labyrinthes ? Et bien, pas tous les labyrinthes...

note: type: Content of: <p>
en: The <i>wall follower algorithm</i> we used so far only works if the entry and the exit are placed near to walls connected to the external wall. But if the buggle begins in the middle of the maze, it may exist wall sections disconnected from the external wall.
fr: L'algorithme de suivi de mur que nous avons utilisé jusqu'à présent fonctionne seulement si l'entrée et la sortie sont placées à côté de murs connectés à un mur externe. Mais si la buggle commence au milieu du labyrinthe, il peut exister des pans de mur déconnectés du mur externe.

note: type: Content of: <p><p>
en: That is why the previous strategy would let the buggle round around for ever. Indeed, the maze you should now escape from contains islands, and the buggle does not start along one of the external walls. Just give it a try if you want: copy your code over, push the run button and see your previous solution failing miserabily.
fr: Dans cette situation, notre précédente stratégie ferait notre buggle tourner en rond pour toujours sur l'un de ces îlots. En effet, le labyrinthe dont vous devez vous échapper maintenant contient des îles, et la buggle ne commence pas sur un des murs externes. Vous pouvez essayer si vous voulez : Copie/collez votre code et appuyez sur le bouton 'Exécuter' pour admirez votre solution précédente échouer lamentablement.

note: type: Content of: <p><p>
en: The method of following a wall is still good and allow to escape very efficiently some sections of the maze, so we do not want to remove it entierely. Instead, we want to stop following the wall under some conditions. Notice that the baggle lays near to the external border of the maze. So, we want to reach the border and then follow that wall. We need for example to search for the north wall before following it to the baggle.
fr: Cette méthode de suivre un mur est toujours efficace est permet d'échapper de manière assez efficace à certaines parties du labyrinthe, on ne va donc pas la supprimer entièrement. À la place, nous allons cesser de suivre le mur sous certaines conditions. Notez que le baggle repose près d'un mur externe du labyrinthe. Donc nous voulons atteindre un mur externe et ensuite le suivre. Nous avons par exemple de rechercher le mur nord avant de le suivre jusqu'au baggle.

note: type: Content of: <p><p><p>
en: To find the north wall, you simply run to the north as long as it's possible, and when facing an obstacle, you avoid it (using previous method).
fr: Pour trouver le mur nord, vous avez tout simplement à foncez vers le nord tant que c'est possible, et quand vous faites face à un obstacle, vous l'évitez (en utilisant la méthode précédente).

note: type: Attribute 'alt' of: <p><p><div>
en: I'm lost now, please give me some extra indications
fr: Je suis perdu, je voudrais plus d'indications

note: type: Content of: <p><p><div>
en: Our new run() method will consist in two modes: our buggle will alternate between the "north runner mode" and the "left follower mode". You begin in "north runner mode", and switch to "left follower" when you have a wall at the north (do not forget to make sure you have a wall at your left before switching to "left follower" mode). You switch to "north runner" as soon as your buggle is facing north and is not in front of a wall during its trip around its left wall. The easiest way to write such a state machine is something like
fr: Notre nouvelle méthode run() va consister en deux états: notre buggle va alterner entre le mode «coureur au nord» et le mode «suiveur à gauche». Vous commencez dans le mode «coureur au nord», et vous passerez au mode «suiveur à gauche» quand il y aura un mur au nord (n'oubliez pas de vous assurez d'avoir un mur à votre gauche avant de changer de passer au mode «suiveur à gauche»). Vous repasserez au mode «coureur au nord» dès que votre buggle fera face au nord et qu'elle n'est pas face à un mur. La manière la plus simple d'écrire une telle machine à état est quelque chose de ce type:

note: type: Content of: <p><p><div><pre>
en: [!scala]var state=0;
    state match  {
      case 0 => // North runner
         ...
         state = 1;
      case 1 => // Left follower
         ...
         state = 0;
      case _ => println("This case should not happen. Please fix me")
    }[/!][!java|c]int state=0;
    switch (state) {
      case 0: // North runner
         ...
         state = 1;
         break;
      case 1: // Left follower
         ...
         state = 0;
         break;
    }[/!][!python]northRunner = True
    if northRunner:
         ...
         northRunner = False
    else: # left follower
         ...
         northRunner = True[/!]
fr: [!scala]var etat=0;
    etat match  {
      case 0 => // courir au nord
         ...
         etat = 1;
      case 1 => // suivre à gauche
         ...
         etat = 0;
      case _ => println("Ce cas ne devrait pas arriver. Corrigez ce problème svp.")
    }[/!][!java|c]int etat=0;
    switch (etat) {
      case 0: // courir au nord
         ...
         etat = 1;
         break;
      case 1: // suivre à gauche
         ...
         etat = 0;
         break;
    }[/!][!python]coureurNord = True
    if coureurNord:
         ...
         coureurNord = False
    else: # suiveur à gauche
         ...
         coureurNord = True[/!]

note: type: Content of: <p><p><div>
en: Don't forget the default case (matching _), or scala will issue an error since your matching would be incomplete.[/!]
fr: N'oubliez pas le cas par défaut (qui accepte _), ou scala vous donnera un message d'erreur en échange de votre filtrage incomplet.[/!]

note: type: Content of: <p><p><p>
en: Don't forget to let the buggle pick the baggle at the end of your code.
fr: N'oubliez pas de faire ramasser le baggle par votre buggle à la fin de votre code.

note: type: Content of: <p><p><p>
en: You're up. That should be enough for you to figure out how to escape this maze, but if not, you can always request for the tip. But you do not need any more help, do you?
fr: Vous êtes prêts. Tout ceci devrait suffire pour vous permettre de trouver comment sortir de ce labyrinthe, mais si ce n'est pas le cas, vous pouvez toujours demander l'astuce. Mais vous n'avez plus besoin d'aide, n'est-ce pas ?

note: type: Content of: <h2>
en: Basic Shortest Path algorithm
fr: Algorithme basique de recherche du plus court chemin

note: type: Content of: <p>
en: To conclude with this introductory lesson to maze solving algorithms, we will investigate another way to find the exit. The buggle in this lesson is a special buggle: he is a jedi. He can feel the Force. This means he is able to feel his environment.
fr: Pour conclure avec cette leçon d'introduction aux algorithmes de sortie de labyrinthe, nous allons étudier un autre moyen de trouver la sortie. La buggle de cette leçon est spéciale : c'est une jedi. Elle peut ressentir la Force. Cela signifie qu'elle peut ressentir son environnement.

note: type: Content of: <p>
en: Without even leaving his position, he can retrieve information about the world he is leaving in, with the following functions:
fr: Sans même changer de place, elle peut retrouver des informations sur le monde qui l'entoure, avec les instructions suivantes&nbsp;:

note: type: Content of: <ul><li>
en: <code>getWorldWidth()</code> gives the width of its world.
fr: <code>getMondeLargeur()</code> pour connaître la largeur du monde

note: type: Content of: <ul><li>
en: <code>getWorldHeight()</code> gives the height of its world.
fr: <code>getMondeHauteur()</code> pour connaître la hauteur du monde.

note: type: Content of: <ul><li>
en: <code>hasTopWall(x,y)</code> tells whether the cell (x,y) of this world has a wall on top.
fr: <code>aMurNord(x,y)</code> indique si la cellule (x,y) de ce monde est fermée par un mur en haut.

note: type: Content of: <ul><li>
en: <code>hasLeftWall(x,y)</code> tells whether the cell (x,y) of this world has a wall on the left.
fr: <code>aMurOuest(x,y)</code> indique si la cellule (x,y) de ce monde est fermée par un mur à gauche.

note: type: Content of: <ul><li>
en: <code>hasBaggle(x,y)</code> tells whether the cell (x,y) of this world has a baggle.
fr: <code>aBiscuit(x,y)</code> indique si un baggle se trouve dans la cellule (x,y) de ce monde.

note: type: Content of: <ul><li>
en: <code>setIndication(x,y,i)</code> adds the integer indication <code>i</code> to the cell (x,y).
fr: <code>setIndication(x,y,i)</code> ajoute une indication entière <code>i</code> sur le sol de la cellule (x,y).

note: type: Content of: <ul><li>
en: <code>getIndication(x,y,i)</code> retrieves the integer indication of the cell (x,y) (or 9999 if there is no indication).
fr: <code>getIndication(x,y)</code> retourne l'indication entière qui se trouve dans la cellule (x,y) (ou bien la valeur 9999 s'il n'y a pas d'indication à l'endroit indiqué).

note: type: Content of: <p>
en: It has to be noted that it is not possible to build a wall on the bottom edge or on the right edge of a cell.  Therefore when such wall exists, it means it was built on a sibling cells -- as a top (respectively left) wall on the cell that is located below (respectively at the right of) the current cell.
fr: Il est bon de noter qu'il n'est pas possible de construire un mur sur le côté inférieur ou le coté droit d'une case. Néanmoins, quand de tels murs existent, cela signifie qu'il a été construit sur une case voisine -- comme mur supérieur (respectivement gauche) sur la case qui est située en dessous (respectivement sur à droite) de la case courante.

note: type: Content of: <p>
en: Your buggle should first write the distance to the exit on each cell (or at least the useful ones).
fr: Votre buggle devrait tout d'abord écrire sur chaque case importante la distance qui la sépare de la sortie.

note: type: Content of: <p>
en: For that, find the exit and write 0 there.  Then, write 1 on every neighboring cells that is not separated from the exit with a wall.  And then mark every cells from which you can reach the exit in 2 steps, and iterate for all cells until all cells are marked.
fr: Pour cela, trouvez la sortie et écrivez 0 dessus. Ensuite, écrivez 1 sur toutes les cases adjacentes à la sortie qui n'en sont pas séparées par un mur. Ensuite, écrivez 2 sur toutes les cases à partir desquelles on peut atteindre une case marquée 1, puis faites de même pour toutes les cases jusqu'à avoir numéroté toutes les cases du monde.

note: type: Content of: <p>
en: Once the cells are marked, get your jedi buggle to follow the shortest path.  Basically the buggle has only to walk on each case with the lesser distance from the exit. You can use the method <code>setDirection(direction)</code> to make your buggle look at the specific direction such as <code>[!scala|java|python]Direction.[/!]NORTH</code> or <code>[!scala|java|python]Direction.[/!]EAST</code>.
fr: Une fois que toutes les cases sont marquées, faites en sorte que votre buggle jedi trouve le plus court chemin en suivant les indications écrites au sol. Pour cela, il lui suffit à chaque pas d'aller sur la case de plus petite distance parmi celles accessibles. Vous pouvez utiliser la méthode <code>void setDirection(Direction d)</code> pour faire regarder votre buggle dans une direction spécifique comme <code>[!scala|java|python]Direction.[/!]NORD</code>, <code>[!scala|java|python]Direction.[/!]SUD</code>, <code>[!scala|java|python]Direction.[/!]EST</code> ou <code>[!scala|java|python]Direction.[/!]OUEST</code>, qui correspondent respectivement au nord, sud, est et ouest.

note: type: Attribute 'alt' of: <div>
en: I'm lost now. Please give me some extra indications.
fr: Je suis perdu, je voudrais plus d'indications

note: type: Content of: <div>
en: Use the Force, Luke!
fr: Utilises la Force Luke !

note: type: Content of: <h2>
en: Finding the walls to follow
fr: Trouver les murs à longer

note: type: Content of: <p>
en: This is exactly the same maze than before, but the buggle does not start at the same location. In particular, it does not have any wall to its left at the beginning.
fr: C'est exactement le même labyrinthe que précédemment, mais la buggle ne commence plus au même emplacement. En particulier, elle n'a plus de mur à sa gauche dès le départ.

note: type: Content of: <p>
en: As a result, the method you wrote for the previous exercise probably don't work for this one. If you use it here with no modification, your buggle probably start looping over the four free cells around its start position (if that's not the case, well, you didn't really stick to the mission on previous exercise. Feel lucky and proceed to the next :)
fr: Ceci fait que la méthode écrite à l'exercice précédent ne fonctionne plus. Si vous l'utilisez ici sans modification, votre buggle va probablement commencer à tourner sur les quatre cases à côté de sa position de départ (si ça n'est pas le cas, et bien, vous n'avez pas réellement suivi la mission de l'exercice précédent. Sentez vous chanceux et passez à l'exercice suivant une fois que vous aurez lu ce texte).

note: type: Content of: <p>
en: This is because your <code>keepHandOnSideWall()</code> method has an implicit <b>pre-condition</b>: it works well if and only if the buggle has a wall to its left when you call it. Such pre-condition are very heavily used when programming. Specifying them explicitly helps understanding the code written by other, and they even allow sometimes to prove that the code works correctly.
fr: C'est parce que votre méthode <code>keepHandOnSideWall()</code> a une <b>pré-condition</b> implicite : la méthode marche bien si et seulement si la buggle a un mur sur sa gauche quand vous appelez cette méthode. De telles pré-conditions sont très utilisées en programmation. Les spécifier explicitement aide à comprendre le code écrit par d'autres personnes, et peuvent même parfois prouver que le code marche correctement.

note: type: Content of: <p>
en: Fixing the problem should be very easy. Simply make sure that the pre-condition of <code>keepHandOnSideWall()</code> is verified before calling it. For that, update your code to first look for a wall on its left before the big <code>while</code> loop.
fr: Réparer le problème devrait être très facile. Assurez-vous simplement que la pré-condition de <code>keepHandOnSideWall()</code> est vérifiée avant de l'appeler. Pour ce faire, mettez à jour votre code pour tout d'abord rechercher à avoir un mur à sa gauche avant de rentrer dans la grande boucle <code>while</code>.

note: type: Content of: outside any tag (error?)
en: This universe introduces a little programming puzzle which can somehow be used to introduce programmation to non-reading kids since it is programmed graphically.  The goal of each board is to light up all the lights. Your robot understands the following orders:
fr: Cet univers introduit un petit puzzle de programmation qui peut être utilisé pour introduire la programmation aux enfants ne sachant pas lire. En effet, il est programmé de manière graphique. L'objectif de chaque niveau est d'allumer toutes les lumières du plateau en utilisant le petit robot. Celui-ci comprend les ordres suivants :

note: type: Content of: <table><tr><td>
en: <b>Order</b>
fr: <b>Ordre</b>

note: type: Content of: <table><tr><td>
en: <b>Meaning</b>
fr: <b>Signification</b>

note: type: Content of: <table><tr><td>
en: <b>Move forward</b>
fr: <b>Avancer</b>

note: type: Content of: <table><tr><td>
en: Cannot be done if the destination cell is of another height than source cell
fr: Ne peut être utilisé que si la case d'arrivée est à la même altitude que la case de départ.

note: type: Content of: <table><tr><td>
en: <b>Jump forward</b>
fr: <b>Sauter en avant</b>

note: type: Content of: <table><tr><td>
en: Can only be done if the destination cell is one step higher than source cell, or if destination is lower than source. Cannot be used for plain moves.
fr: Ne peut être utilisé que si la case d'arrivée est un étage plus haute que la case de départ, ou si l'arrivée est plus basse que le départ. Il est impossible de sauter sur un terrain plat.

note: type: Content of: <table><tr><td>
en: <b>Turn left</b>.
fr: <b>Tourner à gauche</b>.

note: type: Content of: <table><tr><td>
en: <b>Turn right</b>.
fr: <b>Tourner à droite</b>.

note: type: Content of: <table><tr><td>
en: <b>Switch the light</b>.
fr: <b>Allumer ou éteindre</b>

note: type: Content of: <table><tr><td>
en: Turn it on if it was off, and off if it was on. No effect if the cell does not contain any light.
fr: Allumer l'ampoule si elle était éteinte, et éteindre si elle était allumée. Sans effet s'il n'y a pas d'ampoule dans la case courante.

note: type: Content of: <table><tr><td>
en: <b>Call function 1</b>.
fr: <b>Appeler la fonction 1</b>.

note: type: Content of: <table><tr><td>
en: <b>Call function 2</b>.
fr: <b>Appeler la fonction 2</b>.

note: type: Content of: <p>
en: Please note that this world is not completely suited to small kids since the main difficulty comes from the fact that your are highly limited in the amount of instructions you can give to your robot. Advanced levels thus require to write sound functions, and are often above the capacities of small kids.
fr: Veuillez noter que ce jeu n'est pas vraiment adapté aux jeunes enfants puisque la principale difficulté vient de la limitation du nombre d'instructions utilisable dans chaque programme. Les niveaux avancés ne peuvent être résolus sans écrire des fonctions pour factoriser le code, ce qui est souvent au delà des capacités des jeunes enfants.

note: type: Content of: <p>
en: This game is heavily inspirated from a flash game of the same name, which can for example be played on kongregate.com. It was written by Danny Yaroslavski (Coolio-Niato), the original idea being of Matt Chase.
fr: Ce jeu est très largement inspiré d'un jeu en flash du même nom, que l'on peut par exemple trouver sur kongregate.com. Il a été écrit par Danny Yaroslavski (Coolio-Niato), d'après une idée originale de Matt Chase.

note: type: Content of: outside any tag (error?)
en: This lesson introduces a little programming puzzle inspired from a flash game.
fr: Cette leçon introduit un petit jeu de programmation inspiré d'un jeu en flash.

note: type: Content of: <p>
en: See the <i>About this world</i> dialog for more details.
fr: Référez vous à l'aide <i>À propos de ce monde</i> pour plus de détails.

note: type: Content of: <p>
en: This lesson constitutes a little brain teaser for programmers. You have to instruct your robot to turn off all lights. The trick is that you program your robot graphically, and that you are limited in the amount of instructions.
fr: Cette leçon constitue un casse-tête pour programmeurs, où vous devez apprendre à votre robot à éteindre toutes les lumières. Le truc est que vous le programmez graphiquement, et que vous n'avez droit qu'à un nombre limité d'instructions.

note: type: Content of: <p>
en: No previous experience is expected to take this lesson.
fr: Aucune expérience préalable n'est nécessaire pour tenter cette leçon.

note: type: Content of: <h1>
en: Welcome
fr: Bienvenue

note: type: Content of: <p>
en: Welcome to the lightbot world. This is merely a programmer puzzle rather than a real lesson (although some use it to teach programming).  The robot is not programmed in Java, but rather graphically. You can see the existing orders in the documentation using the <i>About this world</i> menu.
fr: Bienvenue dans le monde de LightBot. Il s'agit plus d'une sorte de puzzle pour programmeur que d'une vraie leçon (bien qu'il puisse être utilisé pour enseigner la programmation). Le robot n'est pas programmé en Java, mais graphiquement. Vous trouverez les ordres disponibles dans la documentation en utilisant le menu <b>À propos de ce monde</b>.

note: type: Content of: <p><</p><p>
en: The goal of each board is simply to switch on every lights of the board using your little robot.
fr: L'objectif de chaque niveau est simplement de faire allumer toutes les ampoules du tableau à votre petit robot.

note: type: Content of: <p><</p><p>
en: This is a introduction exercise, which should be solvable by only moving forward and switching the light, using respectively
fr: Ce premier exercice est une simple mise en bouche. Vous devriez pouvoir le résoudre simplement en avançant et en allumant la lampe, grâce aux ordres suivants :

note: type: Content of: <p>
en: and
fr: et

note: type: Content of: <h1>
en: Turn around
fr: Se retourner

note: type: Content of: <p>
en: Now, you probably need to turn in addition (using
fr: Maintenant, vous avez probablement besoin de tourner (en utilisant

note: type: Content of: <h1>
en: Jump
fr: Sauter

note: type: Content of: <p>
en: You can also jump using
fr: Vous pouvez également sauter en utilisant

note: type: Content of: <p>
en: to pass obstacles. You can either jump one level up or any amount of levels down, but you cannot jump to go on a cell of the same height.
fr: pour passer les obstacles. Vous pouvez soit sauter un étage vers le haut, ou vers le bas (même de plusieurs étages), mais vous ne pouvez pas sauter pour vous déplacer à plat.

note: type: Content of: <h1>
en: Stairs
fr: Escaliers

note: type: Content of: <p>
en: Can you pass these stairs?
fr: Parviendrez vous à passer ces escaliers ?

note: type: Content of: <h1>
en: Higher
fr: Toujours plus haut

note: type: Content of: <p>
en: Let's go higher
fr: Il est temps de nous élever de plus en plus haut.

note: type: Content of: <p>
en: You can use
fr: Vous pouvez utiliser

note: type: Content of: <p>
en: to call respectively the first and second functions. Define their code in their own tab.
fr: Pour appeler respectivement la première et la seconde fonction. Définissez leur code dans leur boîte respective.

note: type: Content of: <p><p>
en: This is great if you get out of space in your main function
fr: Cela peut s'avérer pratique si vous n'avez plus assez d'espace dans votre fonction principale.

note: type: Content of: <h1>
en: Repetitive tasks
fr: Des tâches répétitives

note: type: Content of: <p>
en: Functions are also of great use for repetitive tasks
fr: Les fonctions sont également très pratique pour les tâches répétitives

note: type: Content of: <h1>
en: Calling functions from functions
fr: Invoquer des fonctions depuis les fonctions

note: type: Content of: <p>
en: It is perfectly okay to call a function from within a function!
fr: Rien ne vous interdit d'invoquer une fonction depuis une autre fonction !

note: type: Content of: <h1>
en: Castle
fr: Château

note: type: Content of: <p>
en: You're getting good at this...
fr: Vous vous en sortez de mieux en mieux...

note: type: Content of: <h1>
en: Wall
fr: Mur

note: type: Content of: <p>
en: Ready to climb the wall?
fr: Êtes-vous prêt à escalader ce mur ?

note: type: Content of: <h1>
en: Sea
fr: Mer

note: type: Content of: <p>
en: You now have to surf these waves of lamps.
fr: Vous devez maintenant surfer sur cette mer de lampes.

note: type: Content of: <h1>
en: Escher Castle
fr: Le château d'Escher

note: type: Content of: <p>
en: This one aint easy.
fr: Celui-ci est loin d'être facile.

note: type: Content of: <h1>
en: Close to 10
fr: Proche de 10

note: type: Content of: <p>
en: Given 2 int values, return whichever value is nearest to the value 10, or return 0 in the event of a tie.  [!java|scala]Note that Math.abs(n) returns the absolute value of a number.[/!] [!python]Note that math.fabs(n) returns the absolute value of a number.  This function can only be used if you imported the math module.[/!]
fr: Étant donné deux nombres entiers, retourner la valeur la plus proche de 10, ou 0 en cas de match nul.
    [!java|scala]Remarquez que Math.abs(n) retourne la valeur absolue d'un nombre.[/!] 
    [!python]Remarquez que math.fabs(n) retourne la valeur absolue d'un nombre. Remarquez également que vous ne pouvez utiliser cette fonction que si vous avez importé le module math.[/!]

note: type: Content of: <h1>
en: Count Teen
fr: Compter les ados

note: type: Content of: <p>
en: We'll say that a number is "teen" if it is in the range 13..19 inclusive. Given 4 int values, return the amount of teen ones.
fr: On dira qu'un nombre est "ado" s'il appartient est entre 13 et 19 (inclus). Étant donné quatre nombres entiers, retournez combien d'entre eux sont ados.

note: type: Content of: outside any tag (error?)
en: Given an int n, return the absolute difference between n and 21, except return double the absolute difference if n is over 21.
fr: Étant donné un entier n, retournez la différence absolue entre n et 21, sauf si n est plus grand que 21. Dans ce cas, doublez la différence absolue.

note: type: Content of: <h1>
en: Has Teen
fr: A des ados

note: type: Content of: outside any tag (error?)
en: We'll say that a number is "teen" if it is in the range 13..19 inclusive. Given 3 int values, return true if 1 or more of them are teen.
fr: On dira qu'un nombre est "ado" s'il appartient à l'intervalle [13;19]. Étant donné trois nombres entiers, retournez vrai seulement si un ou plusieurs d'entre eux sont ados.

note: type: Content of: <h1>
en: Icy Hot
fr: Feu glacé

note: type: Content of: outside any tag (error?)
en: Given two temperatures, return true if one is less than 0 and the other is greater than 100.
fr: Étant donné deux températures, retournez vrai si l'une est inférieure à zéro et l'autre supérieure à 100.

note: type: Content of: <h1>
en: In [10;20]
fr: Dans [10;20]

note: type: Content of: outside any tag (error?)
en: Given 2 int values, return true if either of them is in the range 10..20 inclusive.
fr: Étant donné deux nombres entiers, retournez vrai si l'un d'entre eux est dans l'intervalle [10;20].

note: type: Content of: <h1>
en: In [30;50]
fr: Dans [30;50]

note: type: Content of: outside any tag (error?)
en: Given 2 int values, return true if they are both in the range 30..40 inclusive, or they are both in the range 40..50 inclusive.
fr: Étant donné deux nombres entiers, retournez vrai s'ils sont tous les deux dans l'intervalle [30;40], ou s'ils sont tous les deux dans l'intervalle [40;50].

note: type: Content of: <h1>
en: LastDigit
fr: Dernier chiffre

note: type: Content of: outside any tag (error?)
en: Given two non-negative int values, return true if they have the same last digit, such as with 27 and 57. Note that the % "mod" operator computes remainders, so 17 % 10 is 7.
fr: Étant donné deux nombres entiers positifs, retournez vrai s'ils ont le même dernier chiffre, comme 27 et 57. Remarquez que l'opérateur % (modulo) calcule le reste de la division entière (donc 17 % 10 vaut 7).

note: type: Content of: <p>
en: This exercise was converted to PLM from the excellent exercising site http://javabat.com/
fr: Cet exercice a été extrait pour PLM depuis l'excellent site d'exercices http://javabat.com/

note: type: Content of: <h1>
en: Lone Teen
fr: Ado solitaire

note: type: Content of: outside any tag (error?)
en: We'll say that a number is "teen" if it is in the range 13..19 inclusive. Given 2 int values, return true if one or the other is teen, but not both.
fr: On dira qu'un nombre est "ado" s'il appartient à l'intervalle [13;19]. Étant donné deux nombres entiers, retournez vrai si l'un d'entre eux est ado, mais pas les deux.

note: type: Content of: <h1>
en: Boolean fun
fr: Jeux booléens

note: type: Content of: <p>
en: Boolean operations are one of the very basic task in programming.  As long as you cannot write a not so simple boolean test under the minute, you probably will have a very bad time writing a real program.
fr: Les opérations booléennes sont l'une des fondements de la programmation. Tant que vous ne pourrez pas écrire des tests booléens (même non triviaux) en moins d'une minute, il vous sera difficile d'écrire un vrai programme.

note: type: Content of: <p>
en: That is why this lesson provides you a bunch of such exercises, so that you can get trained in this.
fr: C'est pourquoi cette leçon vous propose une certaine quantité de tels exercices pour vous permettre de vous entraîner.

note: type: Content of: <h1>
en: Makes 10
fr: Font 10

note: type: Content of: outside any tag (error?)
en: Given 2 ints, a and b, return true if one of them is 10 or if their sum is 10.
fr: Étant donné deux nombres entiers, retournez vrai si l'un d'entre eux vaut 10, ou si leur somme vaut 10.

note: type: Content of: <p>
en: Given 2 positive int values, return the larger value that is in the range 10..20 inclusive, or return 0 if neither is in that range.
fr: Étant donné deux nombres entiers, retournez la plus grande valeur dans l'intervalle 10..20 inclus, ou retournez 0 si aucun des nombres n'est dans cet intervalle.

note: type: Content of: <p>
en: Note that Math.max(Int,Int):Int and Math.min(Int,Int):Int return the maximum and minimum of two integers
fr: Notez que Math.max(Int,Int):Int et Math.min(Int,Int):Int retournent respectivement le maximum et le minimum de deux entiers.

note: type: Content of: <h1>
en: MonkeyTrouble
fr: Problème de singe

note: type: Content of: outside any tag (error?)
en: We have two monkeys, a and b, and the parameters aSmile and bSmile indicate if each is smiling.  We are in trouble if they are both smiling or if neither of them is smiling.  Return true if we are in trouble.
fr: Nous avons deux singes, a et b, et les paramètres aSmile et bSmile indiquent s'ils sourient. Nous avons un problème s'ils sourient tous les deux en même temps, ou si aucun des deux ne sourit. Retournez vrai si nous avons un problème.

note: type: Content of: <h1>
en: Near Hundred
fr: Presque 100

note: type: Content of: <p>
en: Given an int n, return true if it is within 10 of 100 or 200.  [!java|scala]Note that Math.abs(n) returns the absolute value of a number.[/!] [!python]Note that math.fabs(n) returns the absolute value of a number.  This function can only be used if you imported the math module.[/!]
fr: Étant donné deux nombres entiers, retourner vrai si et seulement si la valeur est à moins de 10 de la valeur 100 ou de la valeur 200.
    [!java|scala]Remarquez que Math.abs(n) retourne la valeur absolue d'un nombre.[/!] 
    [!python]Remarquez que math.fabs(n) retourne la valeur absolue d'un nombre. Remarquez également que vous ne pouvez utiliser cette fonction que si vous avez importé le module math.[/!]

note: type: Content of: <h1>
en: Parot Trouble
fr: Problème de perroquet

note: type: Content of: outside any tag (error?)
en: We have a loud talking parrot. The "hour" parameter is the current hour time in the range 0..23. We are in trouble if the parrot is talking and the hour is before 7 or after 20. Return true if we are in trouble.
fr: Nous avons un perroquet très bruyant. Le paramètre "hour" indique l'heure courante (dans l'intervalle [0;23]). Nous avons un problème si le perroquet parle avant 7h ou après 20h. Retournez vrai si nous avons un problème.

note: type: Content of: <h1>
en: Positive Negative
fr: Positif Négatif

note: type: Content of: outside any tag (error?)
en: Given 2 int values, return true if one is negative and one is positive. Unless negative is true, then they both must be negative.
fr: Étant donné deux entiers, retournez vrai si l'un d'entre eux est positif et l'autre négatif. Sauf si le paramètre négative est vrai, auquel cas il faut que les deux nombres soient négatifs.

note: type: Content of: <h1>
en: SleepDay
fr: Grasse matinée

note: type: Content of: outside any tag (error?)
en: The parameter weekday is true if it is a weekday, and the parameter vacation is true if we are on vacation. We sleep in if it is not a weekday or we're on vacation. Return true if we sleep in.
fr: Le paramètre weekday est vrai si nous sommes un jour de semaine, et le paramètre vacation est vrai si nous sommes en vacances. Nous pouvons dormir ce matin s'il ne s'agit pas d'un jour de semaine ou si nous sommes en vacances. Retournez vrai si nous pouvons faire la grasse matinée.

note: type: Content of: <h1>
en: Sum Double
fr: Somme doublée

note: type: Content of: outside any tag (error?)
en: Given two int values, return their sum. Unless the two values are the same, then return double their sum.
fr: Étant donné deux entiers, retournez leur somme. Sauf si les valeurs sont égales, auquel cas vous devez retourner le double de leur somme.

note: type: Content of: <h1>
en: AlarmClock
fr: Radio réveil

note: type: Content of: outside any tag (error?)
en: Given a day of the week encoded as 0=Sun, 1=Mon, 2=Tue, ...6=Sat, and a boolean indicating if we are on vacation, return a string of the form "7:00" indicating when the alarm clock should ring. Weekdays, the alarm should be "7:00" and on the weekend it should be "10:00". Unless we are on vacation -- then on weekdays it should be "10:00" and weekends it should be "off".
fr: Étant donné le jour de la semaine, codé de la façon suivante : 0=Dimanche, 1=Lundi, 2=Mardi, ... 6=Samedi, et un booléen vacation indiquant si nous sommes en vacances, retournez une chaîne de caractères de la forme "7:00" indiquant à quelle heure nous devons régler le radio-réveil. Les jours de la semaine, nous devons nous réveiller à 7h tandis que nous pouvons dormir jusqu'à 10h le week-end. Pendant les vacances, il nous faut nous lever à 10h la semaine tandis que le réglage pour le radio-réveil doit être "off" le week-end.

note: type: Content of: <h1>
en: AnswerCell
fr: Répondeur

note: type: Content of: outside any tag (error?)
en: Your cell phone rings. Return true if you should answer it. Normally you answer, except in the morning you only answer if it is your mom calling. In all cases, if you are asleep, you do not answer.
fr: Votre téléphone sonne. Renvoyez vrai si vous décrochez. Vous le faites habituellement, sauf le matin où vous ne répondez que si votre mère appelle. Dans tous les cas, vous ne répondez pas si vous dormez.

note: type: Content of: <h1>
en: BlueTicket
fr: Ticket bleu

note: type: Content of: outside any tag (error?)
en: You have a blue lottery ticket, with ints a, b, and c on it. This makes three pairs, which we'll call ab, bc, and ac. Consider the sum of the numbers in each pair. If any pair sums to exactly 10, the result is 10.  Otherwise if the ab sum is exactly 10 more than either bc or ac sums, the result is 5. Otherwise the result is 0.
fr: Vous avez un ticket de loterie bleu, avec des entiers a, b et c inscrits dessus. Cela fait trois paires que l'on appellera ab, bc et ac. Considérez la somme des nombres de chaque paire. Si la somme de l'une des paires vaut exactement 10, le résultat est 10. Sinon, si la somme ab vaut exactement 10 de plus que les sommes bc ou ac, le résultat est 5. Sinon, le résultat est 0.

note: type: Content of: <h1>
en: CaughtSpeeding
fr: Radar de vitesse

note: type: Content of: outside any tag (error?)
en: You are driving a little too fast, and a police officer stops you. Write code to compute the result, encoded as an int value: 0=no ticket, 1=small ticket, 2=big ticket. If speed is 60 or less, the result is 0. If speed is between 61 and 80 inclusive, the result is 1. If speed is 81 or more, the result is 2. Unless it is your birthday -- on that day, your speed can be 5 higher in all cases.
fr: Vous conduisez un peu trop vite et un officier de police vous arrête. Écrivez le code pour calculer le résultat, encodé sous forme d'un entier : 0=pas d'amende, 1=petite amende, 2=grosse amende. Si votre vitesse est inférieure à 60, le résultat est 0. Si la vitesse est incluse entre 61 et 80 (inclus), le résultat est 1. Si la vitesse est 81 ou plus, le résultat est 2. Tout ceci ne vaut que si ce n'est pas votre anniversaire aujourd'hui, car sinon, votre vitesse peut être supérieure de 5 dans tous les cas.

note: type: Content of: <h1>
en: CigarParty
fr: Cigares de fête

note: type: Content of: outside any tag (error?)
en: When squirrels get together for a party, they like to have cigars. A squirrel party is successful when the number of cigars is between 40 and 60, inclusive. Unless it is the weekend, in which case there is no upper bound on the number of cigars. Return true if the party was successful.
fr: Quand les écureuils font la fête, ils aiment avoir des cigares. Une fête d'écureuils est réussie si le nombre de cigares est entre 40 et 60 (inclus). Sauf si c'est le week-end, auquel cas il n'y a pas de limite supérieure au nombre de cigares. Renvoyez vrai si la fête est réussie.

note: type: Content of: <h1>
en: DateFashion
fr: Rendez-vous élégant

note: type: Content of: outside any tag (error?)
en: You and your date are trying to get a table at a restaurant. The parameter "you" is the stylishness of your clothes, in the range 0..10, and "date" is the stylishness of your date's clothes. The result getting the table is encoded as an int value with 0=no, 1=maybe, 2=yes. If either of you is very stylish, 8 or more, then the result is 2 (yes). With the exception that if either of you has style of 2 or less, then the result is 0 (no). Otherwise the result is 1 (maybe).
fr: Vous et votre compagne/compagnon essayez d'obtenir une table au restaurant. Le paramètre "you" est l'élégance de vos vêtements, dans l'intervalle [0,10], et "date" est l'élégance des vêtements de votre compagne/compagnon. Le résultat à obtenir la table est encodé comme une valeur entière avec 0=non, 1=peut-être et 2=oui. Si l'un de vous deux est très élégant (8 ou plus) alors le résultat est 2 (oui). Avec l'exception que si l'un de vous deux a un style de 2 ou moins, alors le résultat est 0 (no). Sinon, le résultat est 1 (peut-être).

note: type: Content of: <p>
en: According to Wikipedia, Fizz buzz is a group word game for children to teach them about division.  Players take turns to count incrementally, replacing any number divisible by three with the word "Fizz", and any number divisible by five with the word "Buzz". Any number that is divisible by both three and five is replaced with the string "Fizz Buzz".
fr: D'après Wikipedia, Fizz Buzz est un jeu collectif visant à entraîner les enfants à la division. Les joueurs comptent chacun à leur tour, en remplaçant tous les nombres divisibles par trois par le mot « Fizz ». Tous les nombres divisibles par cinq sont remplacés par le mot « Buzz ». Les nombres divisibles à la fois par trois et par cinq sont remplacés par la chaîne « Fizz Buzz ».

note: type: Content of: <p>
en: Unchanged numbers are simply returned as a string.  [!java|scala]The easiest for that is to use that [!thelang] idiomatic: <code>""+a</code>[/!] [!python]The function <code>str(a)</code> changes an integer <code>a</code> into a string.[/!]
fr: Les nombres inchangés sont simplement renvoyés sous forme d'une chaîne de caractères.  
    [!java|scala]Le plus simple pour cela est d'utiliser l'idiomatisme suivant du [!thelang] : <code>""+a</code>[/!] 
    [!python]La fonction <code>str(a)</code> change l'entier <code>a</code> en une chaîne.[/!]

note: type: Content of: <h1>
en: GreenTicket
fr: Ticket vert

note: type: Content of: outside any tag (error?)
en: You have a green lottery ticket, with ints a, b, and c on it. If the numbers are all different from each other, the result is 0. If all of the numbers are the same, the result is 20. If two of the numbers are the same, the result is 10.
fr: Vous avez un ticket de loterie vert, avec des entiers a, b et c inscrits dessus. Si les nombres sont tous différents les uns des autres, le résultat est 0. Si tous les nombres sont identiques, le résultat est 20. Si deux des nombres sont les mêmes, le résultat est 10.

note: type: Content of: <h1>
en: In1To10
fr: De 1 à 10

note: type: Content of: outside any tag (error?)
en: Given a number n, return true if n is in the range 1..10, inclusive. Unless "outsideMode" is true, in which case return true if the number is less or equal to 1, or greater or equal to 10.
fr: Soit un nombre n, renvoyez vrai si n est dans l'intervalle [1,10]. Sauf si "outsideMode" est vrai, auquel cas renvoyez vrai si le nombre est plus petit ou égal à 1 ou bien s'il est plus grand ou égal à 10

note: type: Content of: <h1>
en: InOrderEqual
fr: Dans l'ordre croissant

note: type: Content of: outside any tag (error?)
en: Given three ints, a b c, return true if they are in strict increasing order, such as 2 5 11, or 5 6 7, but not 6 5 7 or 5 5 7. However, with the exception that if "equalOk" is true, equality is allowed, such as 5 5 7 or 5 5 5.
fr: Soit trois entiers, a b c, renvoyez vrai si ils sont dans un ordre croissant strict, tel que 2 5 11, ou 5 6 7, mais pas 6 5 7 ou 5 5 7. Cependant, avec l'exception que si "equalOk" est vrai, alors l'égalité est permise, comme 5 5 7 ou 5 5 5.

note: type: Content of: <h1>
en: InOrder
fr: Dans l'ordre

note: type: Content of: outside any tag (error?)
en: Given three ints, a b c, return true if b is greater than a, and c is greater than b. However, with the exception that if "bOk" is true, b does not need to be greater than a.
fr: Soit trois entiers, a b c, renvoyez vrai si b est plus grand que a, et si c est plus grand que b. Cependant, avec l'exception que si "bOk" est vrai, b n'a pas besoin d'être plus grand que a.

note: type: Content of: <h1>
en: LastDigit 2
fr: L'autre dernier chiffre

note: type: Content of: outside any tag (error?)
en: Given three ints, a b c, return true if two or more of them have the same rightmost digit. The ints are non-negative. Note: the % "mod" operator computes the remainder, e.g. 17 % 10 is 7.
fr: Soit trois entiers, a b c, renvoyez vrai si deux ou plus d'entre eux ont le même chiffre le plus à droite. Les entiers sont positifs. Note: l'opérateur % "mod" calcule le reste, i.e. 17 % 10 vaut 7.

note: type: Content of: <h1>
en: LessBy10
fr: Plus petit par 10

note: type: Content of: outside any tag (error?)
en: Given three ints, a b c, return true if one of them is 10 or more less than one of the others.
fr: Soit trois entiers, a b c, renvoyez vrai si l'un d'entre eux est plus petit de 10 ou plus que l'un des autres.

note: type: Content of: <h1>
en: Boolean (even more) fun
fr: Encore des jeux booléens

note: type: Content of: <p>
en: A very good introduction to this type is available here: http://codingbat.com/doc/java-if-boolean-logic.html
fr: Une très bonne introduction à ce type est disponible ici : http://codingbat.com/doc/java-if-boolean-logic.html

note: type: Content of: <h1>
en: MaxMod5
fr: Maximum Mod 5

note: type: Content of: outside any tag (error?)
en: Given two int values, return whichever value is larger. However if the two values have the same remainder when divided by 5, then the return the smaller value. However, in all cases, if the two values are the same, return 0.  Note: the % "mod" operator computes the remainder, e.g. 7 % 5 is 2.
fr: Soit deux valeurs entières, renvoyez la plus grande des deux. Cependant, si les deux valeurs ont le même reste quand elles sont divisées par 5, alors renvoyez la plus petite des deux. Cependant, dans tous les cas, si les deux valeurs sont égales, renvoyez 0. Note: l'opérateur % "mod" calcule le reste, i.e. 7 % 5 vaut 2.

note: type: Content of: <h1>
en: NearTen
fr: Près de dix

note: type: Content of: outside any tag (error?)
en: Given a non-negative number "num", return true if num is within 2 of a multiple of 10. Note: (a % b) is the remainder of dividing a by b, so (7 % 5) is 2.
fr: Soit un entier positif "num", renvoyez vrai si num est à distance 2 ou moins d'un multiple de 10. Note: ( a % b ) est le reste de la division de a par b, donc (7 % 5) vaut 2.

note: type: Content of: <h1>
en: RedTicket
fr: Ticket rouge

note: type: Content of: outside any tag (error?)
en: You have a red lottery ticket showing ints a, b, and c, each of which is 0, 1, or 2. If they are all the value 2, the result is 10. Otherwise if they are all the same, the result is 5. Otherwise so long as both b and c are different from a, the result is 1. Otherwise the result is 0.
fr: Vous avez un ticket de loterie rouge comportant trois entiers a, b et c. Chacun d'entre eux est 0, 1, ou 2. Si ils ont tous comme valeur 2, le résultat vaut 10. Sinon, si ils sont égaux, le résultat vaut 5. Sinon, tant que b et c sont différents de a, le résultat vaut 1. Sinon, le résultat est 0.

note: type: Content of: <h1>
en: ShareDigit
fr: Chiffre partagé

note: type: Content of: outside any tag (error?)
en: Given two ints, each in the range 10..99, return true if there is a digit that appears in both numbers, such as the 2 in 12 and 23. (Note: division, e.g. n/10, gives the left digit while the % "mod" n%10 gives the right digit.)
fr: Soit deux entiers, chacun étant dans l'intervalle [10,99], renvoyez vrai si il y a un chiffre qui apparaît dans les deux nombres, comme 2 dans 12 et 23. (Note: division, i.e.  n/10, renvoie le chiffre à gauche tant que le % "mod" n%10 renvoie le bon chiffre.)

note: type: Content of: <h1>
en: SortaSum
fr: Sommes d'entiers

note: type: Content of: outside any tag (error?)
en: Given 2 ints, a and b, return their sum. However, sums in the range 10..19 inclusive, are forbidden, so in that case just return 20.
fr: Soit deux entiers, a et b, renvoyez leur somme. Cependant, les sommes entre 10 et 19 inclus sont interdites, dans ce cas, renvoyez 20.

note: type: Content of: <h1>
en: SquirrelPlay
fr: Jeu de l'écureuil

note: type: Content of: outside any tag (error?)
en: The squirrels in Palo Alto spend most of the day playing. In particular, they play if the temperature is between 60 and 90 (inclusive). Unless it is summer, then the upper limit is 100 instead of 90. Given an int temperature and a boolean isSummer, return true if the squirrels play and false otherwise.
fr: Les écureuils dans Palo Alto passent la majorité de leurs journées à jouer. En particulier, ils jouent si la température est entre 60 et 90 (inclus). A moins que ce soit l'été, alors la limite supérieure est de 100 au lieu de 90. Soit une température entière et un booléen isSummer.
    Renvoyez vrai si les écureuils jouent et faux sinon.

note: type: Content of: <h1>
en: TeaParty
fr: Goûter

note: type: Content of: outside any tag (error?)
en: We are having a party with amounts of tea and candy. Return the int outcome of the party encoded as 0=bad, 1=good, or 2=great. A party is good (1) if both tea and candy are at least 5. However, if either tea or candy is at least double the amount of the other one, the party is great (2).  However, in all cases, if either tea or candy is less than 5, the party is always bad (0).
fr: Nous avons un goûter avec quantité de thé et de bonbons. Renvoyez l'entier 'outcome' du goûter encodé comme 0=mauvais, 1=bien, ou 2=excellent. Un goûter est bien (1) si le thé et les bonbons sont à 5 au moins. Cependant, si soit le thé soit les bonbons est à au moins le double de la quantité de l'autre, le goûter est excellent (2). Cependant, dans tous les cas, si soit le thé soit les bonbons sont à moins de 5, le goûter est toujours mauvais (0).

note: type: Content of: <h1>
en: TeenSum
fr: Somme d'ados

note: type: Content of: outside any tag (error?)
en: Given 2 ints, a and b, return their sum. However, "teen" values in the range 13..19 inclusive, are extra lucky. So if either value is a teen, just return 19.
fr: Étant donné deux nombres entiers (a et b), renvoyez leur somme. Cependant, les valeurs ados (dans l'intervalle [13;19]) sont particulièrement chanceuses. Donc, si l'un des nombres est ado, renvoyez simplement 19.

note: type: Content of: <h1>
en: TwoAsOne
fr: Deux pour un

note: type: Content of: outside any tag (error?)
en: Given three ints, a b c, return true if it is possible to add two of the ints to get the third.
fr: Soit trois entiers, a b c, renvoyez vrai si il est possible d'en additionner deux d'entre eux pour obtenir le troisième.

note: type: Content of: <h1>
en: WithoutDoubles
fr: Sans double

note: type: Content of: outside any tag (error?)
en: Return the sum of two 6-sided dice rolls, each in the range 1..6. However, if noDoubles is true, if the two dice show the same value, increment one die to the next value, wrapping around to 1 if its value was 6.
fr: Renvoyez la somme du jet de deux dés à six faces. Cependant, si noDoubles est vrai et que les deux dés ont la même valeur, incrémentez l'un des dés à la valeur suivante, en le mettant à 1 si sa valeur était 6.

note: type: Content of: <h1>
en: String fun
fr: Jouer avec les chaînes

note: type: Content of: <p>
en: Strings are the simplest of the complex data types :) They provide several operations, such as getting the length of the string, or a substring of it.
fr: Les chaînes de caractères ("String") sont les plus simples des types de données complexes :) Elles fournissent différentes opérations, comme obtenir la longueur de la chaîne ou une sous-chaîne.

note: type: Content of: <p>
en: A very good introduction to this type is available here: http://codingbat.com/doc/java-string-introduction.html
fr: Une très bonne introduction à ce type est disponible ici : http://codingbat.com/doc/java-string-introduction.html

note: type: Content of: <h3>
en: Small exercises about strings
fr: Petits exercices sur les chaînes

note: type: Content of: <p>
en: These are some training exercises around strings. But unfortunately, its integration within PLM is still ongoing.
fr: Il s'agit d'exercices d'entraînement au sujet des chaînes de caractères. Mais malheureusement, leur intégration à PLM est encore en cours.

note: type: Content of: <p>
en: Please be patient with us.
fr: Merci de votre patience.

note: type: Content of: <h1>
en: AltPairs
fr: Sans les paires

note: type: Content of: outside any tag (error?)
en: Given a string, return a string made of the chars at indexes 0,1, 4,5, 8,9 ... so "kittens" yields "kien".
fr: Soit une chaîne de caractères, renvoyez la chaîne composée des caractères  aux index 0,1,4,5,8,9 ... par exemple "kittens" devient "kien".

note: type: Content of: <h1>
en: FrontTimes
fr: Multiplication de début

note: type: Content of: outside any tag (error?)
en: Given a string and a non-negative int n, we'll say that the front of the string is the first 3 chars, or whatever is there if the string is less than length 3. Return n copies of the front;
fr: Soit une chaîne de caractère et un entier n.
    On définit le début d'une chaîne de caractère comme les trois premiers caractères, ou tout ce qu'il y a si la chaîne a une longueur de moins de 3.
    Renvoyez n copies du début de la chaîne.

note: type: Content of: <h1>
en: Last2
fr: Deux derniers

note: type: Content of: <p>
en: Given a string, return the amount of times that the two last letters appear as a substring of the string. So "hixxxhi" yields 1 (we won't count the end substring) while "aaaNaa" yields 2 (substrings may overlap).
fr: Étant donné une chaîne de caractères, retournez le nombre de fois que les deux
    dernières lettres apparaissent. Par exemple, "hixxxhi" renvoie 1 (on ne compte pas la dernière sous-chaîne) tandis que "aaaNaa" renvoie 2 (les occurences peuvent se chevaucher partiellement).

note: type: Content of: <h1>
en: StringBits
fr: Éclats de chaîne

note: type: Content of: outside any tag (error?)
en: Given a string, return a new string made of every other char starting with the first, so "Hello" yields "Hlo".
fr: Étant donné une chaîne de caractères, retournez une nouvelle chaîne formée en
    prenant un caractère sur deux dans le paramètre, en commençant avec le premier
    caractère. Ainsi, "Bonjour" donne "Bnor".

note: type: Content of: <h1>
en: StringMatch
fr: Comparaison de chaînes

note: type: Content of: outside any tag (error?)
en: Given 2 strings, a and b, return the number of the positions where they contain the same length 2 substring. So "xxcaazz" and "xxbaaz" yields 3, since the "xx", "aa", and "az" substrings appear in the same place in both strings.
fr: Soit deux chaînes de caractères a et b.
    Renvoyez le nombre de position où elles contiennent la même sous-chaîne de longueur 2.
    Ainsi, "xxcaazz" et "xxbaaz" renvoient 3, puisque les sous-chaînes "xx", "aa", et "az" apparaissent dans les mêmes emplacement dans les deux chaînes.

note: type: Content of: <h1>
en: StringSplosion
fr: Explosion de chaîne

note: type: Content of: outside any tag (error?)
en: Given a non-empty string like "Code" return a string like "CCoCodCode".
fr: Soit une chaîne de caractères non vide comme "Code".
    Renvoyez une chaîne de caractères comme "CCoCodCode".

note: type: Content of: <h1>
en: StringTimes
fr: Multiplication de chaînes

note: type: Content of: outside any tag (error?)
en: Given a string and a non-negative int n, return a larger string that is n copies of the original string.
fr: Soit une chaîne et un entier n positif.
    Renvoyez une chaîne plus grande qui consiste en n copies de la chaîne originale.

note: type: Content of: <h1>
en: StringX
fr: Chaîne X

note: type: Content of: outside any tag (error?)
en: Given a string, return a version where all the "x" have been removed. Except an "x" at the very start or end should not be removed.
fr: Soit une chaîne de caractère, renvoyez une version où tous les "x" ont été supprimés.
    Seuls les "x" au tout début ou en toute fin ne doivent pas être supprimés.

note: type: Content of: <h1>
en: StringYak
fr: String Yak

note: type: Content of: outside any tag (error?)
en: Suppose the string "yak" is unlucky. Given a string, return a version where all the "yak" are removed, but the "a" can be any char. The "yak" strings will not overlap.
fr: La chaîne "yak" n'a pas de chance. Soit une chaîne de caractères, renvoyez une version où tous les "yak" sont supprimées (quel que soit le caractère à la place du 'a'). Les différentes chaînes "yak" ne se chevauchent pas.

note: type: Content of: <h2>
en: Lunar Lander
fr: Alunisseur

note: type: Content of: <p>
en: In this lesson you pilot a lunar landing module in increasingly complex situations.
fr: Dans cette leçon, vous pilotez un alunisseur dans des situations de plus en plus complexes.

note: type: Content of: <p>
en: At each step of the simulation, the player issues a command controlling how much the angle and thrust of the lander should change
fr: À chaque pas de la simulation, le joueur donne des commandes contrôlant l'angle et la poussée du module d'alunissage.

note: type: Content of: <p>
en: Ideas concerning the progression of exercises:
fr: Idées d'exercices à ajouter à la progression proposée :

note: type: Content of: <ul><li>
en: A lander in vertical position above flat ground, the player can only control thrust (done)
fr: Un alunisseur en position verticale au dessus d'un sol plat. Le joueur ne peut régler que la poussée (c'est fait).

note: type: Content of: <ul><li>
en: A lander in vertical position not above flat ground, the player control thrust and angle (done)
fr: Un alunisseur en position verticale pas au dessus d'un sol plat. Le joueur peut régler la poussée et l'angle (c'est fait).

note: type: Content of: <ul><li>
en: A lander with difficult angle and speed not above flat ground, the player control thrust and angle
fr: Un alunisseur avec un angle et une vitesse difficile, pas au dessus d'un sol plat. Le joueur contrôle la poussée et l'angle.

note: type: Content of: <ul><li>
en: A lander with difficult angle and speed not above flat ground, with difficult ground, the player control thrust and angle
fr: Un alunisseur avec un angle et une vitesse difficile, pas au dessus d'un sol plat dans une configuration difficile. Le joueur contrôle la poussée et l'angle.

note: type: Content of: <ul><li>
en: Same with wind?
fr: La même chose avec du vent ?

note: type: Content of: <p>
en: This lesson assumes some basic programming and physics skills.
fr: Vous êtes supposé maîtriser les bases de la programmation et posséder quelques notions de mécanique du point avant de tenter cette leçon.

note: type: Content of: <p>
en: In this universe you pilot a lunar lander. At each simulation step you're given the lander's position, speed, angle and thrust and must issue a command adjusting its angle and thrust.
fr: Dans cet univers, vous contrôlez un module d'alunissage. À chaque pas de la simulation, vous avez accès à la position du module, sa vitesse, son angle et la poussée de son moteur. Vous devez alors décider de l'angle et de la poussée pour l'étape suivante.

note: type: Content of: outside any tag (error?)
en: Get the X and Y position of the lander.
fr: Retourne la position en X et Y du module d'alunissage.

note: type: Content of: <pre>
en: [!java|c]double [/!]getSpeedX()[!scala]:Double[/!]
    [!java|c]double [/!]getSpeedY()[!scala]:Double[/!]
fr: [!java|c]double [/!]getVitesseX()[!scala]:Double[/!]
    [!java|c]double [/!]getVitesseY()[!scala]:Double[/!]

note: type: Content of: outside any tag (error?)
en: Get the horizontal and vertical speed of the lander.
fr: Obtenir les vitesses horizontale et verticale du module.

note: type: Content of: <pre>
en: [!java|c]double [/!]getAngle()[!scala]:Double[/!]
    [!java|c]void [/!]setDesiredAngle([!java|c]double [/!]desiredAngle[!scala]:Double[/!])
fr: [!java|c]double [/!]getAngle()[!scala]:Double[/!]
    [!java|c]void [/!]setAngleDesire([!java|c]double [/!]angle[!scala]:Double[/!])

note: type: Content of: outside any tag (error?)
en: Get or set the angle of the lander.
fr: Retourne ou fixe l'angle du module d'alunissage.

note: type: Content of: outside any tag (error?)
en: An angle of 0° denotes a vertical position where the "head" of the lander points up.  This is the angle you must land with. A positive angle denotes a left-leaning lander, a negative angle a right-leaning one. You cannot lean more than by ±90°, and the angle can vary by at most ±5° in one step.
fr: Un angle de O° dénote une position verticale, avec le sommet du module dirigé vers le haut. C'est l'angle avec lequel vous devez vous poser. Un angle positif indique que le module penche vers la gauche tandis qu'un angle négatif indique au contraire qu'il penche à droite. Il est impossible de se pencher à plus de ±90°, et on ne peut pas pencher le module de plus de ±5° en une fois.

note: type: Content of: <pre>
en: [!java|c]int [/!]getThrust()[!scala]:Int[/!]
    [!java|c]void [/!]setDesiredThrust([!java|c]int [/!]thrust[!scala]:Int[/!])
fr: [!java|c]int [/!]getPoussee()[!scala]:Int[/!]
    [!java|c]void [/!]setPousseeDesiree([!java|c]int [/!]poussée[!scala]:Int[/!])

note: type: Content of: outside any tag (error?)
en: Get or set the thrust of the lander.
fr: Retourne ou fixe la poussée du module.

note: type: Content of: outside any tag (error?)
en: You can only increment or decrement the thrust by 1 between two simulation steps, so if the current thrust is 2 and you ask for 4, you'll only get 3 in the next step. If you ask for less than 0 (resp. more than 4), everything will be as if you had asked for 0 (resp. 4).
fr: Vous ne pouvez incrémenter ou décrémenter la poussée que d'une unité à chaque fois. Si votre poussée actuelle est de 2 et que vous demandez une poussée de 4, vous n'obtiendrez que 3 au prochain pas de temps. Si vous demandez moins que 0 (ou plus que 4), tout se passera comme si vous demandiez 0 (ou 4).

note: type: Content of: outside any tag (error?)
en: Get the remaining fuel in the lander.  At each step of the simulation the lander consumes as many fuel units as the current thrust. Once you run out of fuel you're in free fall so beware!
fr: Obtient la quantité de fuel restant dans le réservoir. À chaque pas de simulation, le module consomme entre 0 et 4 unités de fuel, en fonction de sa poussée. Une fois que vous avez utilisé tout votre carburant, vous êtes en chute libre alors prenez garde !

note: type: Content of: <pre>
en: [!java]List&lt;Point&gt; [/!]getGround() [!scala]:List[Point][/!]
fr: [!java]List&lt;Point&gt; [/!]getSol() [!scala]:List[Point][/!]

note: type: Content of: outside any tag (error?)
en: Get the vertices of the ground's profile from left to right.  [!java|scala]You can retrieve the X and Y coordinates of each point with the corresponding methods of your point: <code>p.x()</code> and <code>p.y()</code>.[/!] [!python]Each point is an array of two integers denoting respectively the X and Y coordinates of that point.[/!]
fr: Obtenir les points du sol de gauche à droite. [!java|scala]Vous pouvez retrouver les coordonnées X et Y de chaque point avec les méthodes correspondantes de votre point : <code>p.x()</code> et <code>p.y()</code>.[/!] [!python]Chaque point est un tableau de deux entiers représentant respectivement les coordonnées X et Y de chaque point.[/!]

note: type: Content of: <h1>
en: Lander 101
fr: Se poser pour les nuls

note: type: Content of: <p>
en: Congratulations! You won a (one-way) trip to Mars in a cereal box. NASA was kind enough to donate the Lunar Excursion Module for this mission, so that's what you'll be flying.
fr: Bravo ! Vous avez gagné dans une boîte de céréales un voyage (aller simple) pour Mars. La NASA vous a même fourni un module d'excursion lunaire pour l'occasion, et c'est donc avec ce véhicule que vous voyagerez.

note: type: Content of: <p>
en: Before you take off, you must go through some basic landing simulation. You shouldn't have to fly the lander if all goes as planned but, as they say, "better safe than sorry".
fr: Avant le décollage, vous devez vous entraîner sur simulateur aux bases de l'alunissage. Si tout se passe comme prévu, vous ne devriez pas avoir à voler en mode manuel, mais mieux vaut prévenir que guérir, comme ils disent.

note: type: Content of: <p>
en: Your mission is to <b>land the lander with a vertical speed of at most 10 m/s.</b> There are two ways you can influence the lander's course: by adjusting its angle or by adjusting its thrust. In this simulation we only care about adjusting the thrust, expressed in m/s².
fr: Votre mission est de <b>poser le module avec une vitesse verticale inférieure à 10 m/s</b>. Il y a deux façons d'influer sur la trajectoire du module : en modifiant son angle, ou en réglant la poussée de son moteur. Dans cette simulation, nous ne nous intéressons qu'à la poussée, exprimée en m/s².

note: type: Content of: <p>
en: The [!python]<code>step()</code> function[/!][!scala|java|c]code[/!] that you should write now will be called every 0.1 second during the simulation. Make sure that your code does not last too long, with no while loop! It should only set the desired thrust of the next simulation step, by calling <code>[!java]void [/!]setDesiredThrust([!java]int [/!]desiredThrust[!scala]:Integer[/!])</code> where <code>desiredThrust</code> is some integer between 0 and 4 (that is, a thrust between 0 m/s² and 4 m/s²). You can only increment or decrement the thrust by 1 between two simulation steps, so if the current thrust is 2 and you ask for 4, you'll only get 3 in the next step. If you ask for less than 0 (resp. more than 4), everything will be as if you had asked for 0 (resp. 4).
fr: Vous devez écrire le [!python]corps de la fonction <code>step()</code>, qui sera appelée[/!][!scala|java|c]code qui sera appellé[/!] tous les dixièmes de seconde pendant la simulation. Assurez vous que votre code ne dure pas trop longtemps, et évitez en particulier les boucles <code>while</code>. Il faut juste ajuster la poussée du moteur en utilisant la fonction <code>[!java]void [/!]setPousseeDesiree([!java]int [/!]poussee[!scala]:Integer[/!])</code> où <code>poussee</code> est un entier entre 0 et 4 (représentant une poussée entre 0 m/s² et 4 m/s²). Vous ne pouvez incrémenter ou décrémenter la poussée que de 1 entre deux pas de la simulation. Ainsi, si la poussée du moteur est actuellement de 2 et que vous demandez 4, vous n'aurez que 3 à la prochaine étape. Si vous demandez une valeur inférieure à 0 (ou supérieure à 4), tout se passera comme si vous aviez demandé 0 (ou 4).

note: type: Content of: <p>
en: In order to take informed decisions, you can query the lander's state. In this simulation you'll probably be interested in its vertical position: <code>[!java]double [/!]getY()[!scala]:Double[/!]</code>, and its vertical speed: <code>[!java]double [/!]getSpeedY()[!scala]:Double[/!]</code>. You can also ask for the thrust via <code>[!java]int [/!]getThrust()[!scala]:Integer[/!]</code> in case you don't remember what you asked for. Remember that Mars' gravity is 3.711 m/s², it might come in handy.
fr: Afin de prendre des décisions informées, vous pouvez demander des informations sur l'état actuel du module. Dans cette simulation, vous ne serez probablement intéressé que par sa position verticale (accessible grâce à <code>[!java]double [/!]getY()[!scala]:Double[/!]</code>) et sa vitesse verticale (accessible grâce à <code>[!java]double [/!]getVitesseY()[!scala]:Double[/!]</code>). Vous pouvez également demander la poussée actuelle du moteur (avec <code>[!java]int [/!]getPoussee()[!scala]:Integer[/!]</code>) si vous avez oublié ce que vous avez demandé. Rappelez vous que la gravité martienne est de 3.711 m/s², cela peut vous être utile.

note: type: Content of: <p>
en: One last thing: the lander is pretty small so you don't have much fuel. At each step of the simulation the lander consumes as many fuel units as the current thrust. Once you run out of fuel you're in free fall so beware! You can consult the remaining amount of available fuel units using <code>[!java]int [/!]getFuel()[!scala]:Integer[/!]</code>.
fr: Une dernière chose : le module est plutôt petit, et vous n'avez pas tant de carburant que cela. À chaque pas de simulation, il consomme autant d'unité de carburant que la poussée actuelle du moteur. Si vous tombez en panne sèche, vous serez en chute libre alors attention ! Vous pouvez consulter le niveau du réservoir avec <code>[!java]int [/!]getFuel()[!scala]:Integer[/!]</code>.

note: type: Content of: <h2>
en: Locate a Landing Zone
fr: Repérer une zone plate

note: type: Content of: <p>
en: After 200 days of traveling space and eating cereals you finally reach Mars. Time to land at last!
fr: Après 200 jours de voyage intersidéral à manger des céréales, vous êtes enfin parvenu à la planète rouge. Il est enfin temps de se poser !

note: type: Content of: <p>
en: The lander is on autopilot and all you have to do is look around and tell it where to land. The lander must <b>land on a flat zone</b> if you want to remain in one piece. You indicate the lander where to land by modifying the <code>getLandingZone</code> function so that it returns a [!java|scala]<code>Segment</code> representing the zone of your choice.
fr: Le module est en pilote automatique, et vous n'avez qu'à regarder autour de vous pour sélectionner une zone d'alunissage. Vous devez vous poser sur <b>une zone plate</b> si vous ne voulez pas vous scratcher. Vous indiquez au pilote automatique où se poser en modifiant la fonction <code>getLandingZone</code> de façon à ce qu'elle retourne [!java|scala]un Segment représentant la zone de votre choix.

note: type: Content of: <p><p>
en: A segment is composed of two <code>Point</code>s, each of them composed of two <code>double</code>s. A segment is built via the <code>Segment([!java]Point [/!]start[!scala]:Point[/!], [!java]Point [/!]end[!scala]:Point[/!])</code> constructor.  A point is built via the <code>Point([!java]double [/!]x[!scala]:Double[/!], [!java]double [/!]y[!scala]:Double[/!])</code> constructor. A point's coordinates are accessible via its <code>[!java]double [/!]x()[!scala]:Double[/!]</code> and <code>[!java]double [/!]y()[!scala]:Double[/!]</code> methods.
fr: Un Segment est composé de deux <code>Point</code>s, chacun composé de deux doubles. On construit un nouveau segment de la façon suivante : <code>Segment([!java]Point [/!]debut[!scala]:Point[/!], [!java]Point [/!]fin[!scala]:Point[/!])</code>. Pour créer de nouveaux points, il faut utiliser le constructeur <code>Point([!java]double [/!]x[!scala]:Double[/!], [!java]double [/!]y[!scala]:Double[/!])</code>. Les coordonnées d'un point sont accessibles grâce à ses méthodes <code>[!java]double [/!]x()[!scala]:Double[/!]</code> et <code>[!java]double [/!]y()[!scala]:Double[/!]</code>.

note: type: Content of: <p>
en: [/!] [!python]tuple of two X coordinates representing the zone of your choice.[/!]
fr: [/!] [!python]tuple de deux coordonnées X délimitant la zone de votre choix.[/!]

note: type: Content of: <p><p>
en: In order to determine which zone to return, you'll need to call <code>[!java]List&lt;Point&gt; [/!]getGround()[!scala]List[Point][/!]</code>, which returns the vertices of the ground's profile as a list of [!java|scala]<code>Point</code>[/!] [!python]tuples (x,y)[/!].
fr: Pour déterminer la zone cible, vous devez appeler <code>[!java]List&lt;Point&gt; [/!]getSol()[!scala]:List[Point][/!]</code>, qui retourne les points qui composent la surface sous la forme d'une list de [!java|scala]<code>Point</code>[/!] [!python]tuples (x,y)[/!].

note: type: Content of: <p><p>
en: One more thing: your function should return a valid flat zone in any kind of situation, not just for the currently visualized one. That's because it will be not only tested against that world, but also against the one we had in the previous exercise. As usual, you can see the other existing worlds with the appropriate combobox.
fr: Une dernière chose : votre fonction doit retourner une zone valide dans toutes les situations, pas seulement celle que l'on voit en ce moment. C'est que votre code sera utilisé dans ce cas, mais également dans la configuration que nous avions dans l'exercice précédent. Comme d'habitude, vous pouvez voir les autres mondes en les sélectionnant dans le combobox au dessus de la vue du monde.

note: type: Content of: <p><p>
en: Have a safe landing! Don't forget to put on your space suit on your way out.
fr: Bon alunissage ! N'oubliez pas de mettre votre combinaison spatiale en sortant.

note: type: Content of: <h1>
en: Fly the Lander!
fr: Aux commandes du module

note: type: Content of: <p>
en: After 30 days of staring at rocks and eating cereals you decide it's time to go explore other parts of the planet.
fr: Après 30 jours à regarder des cailloux en mangeant des céréales, vous décidez qu'il est temps d'aller explorer d'autres coins de cette planète.

note: type: Content of: <p>
en: You fly for a while and suddenly realize you're almost out of fuel.  Unfortunately you're in a delicate situation and the autopilot is helpless.  You will have to pilot the lander yourself. Your mission is to <b>land the lander on a flat zone with a vertical speed less than 10 m/s, an horizontal speed less than 5 m/s and an angle of 0°.</b>
fr: Vous volez un moment, avant de réaliser soudain que vous êtes presque à court d'essence. Le pilote automatique est malheureusement inutile dans ce genre de situation périlleuse, et vous allez devoir vous poser en mode manuel. Votre mission et de vous <b>poser sur une zone plate, avec une vitesse verticale inférieure à 10 m/s, une vitesse horizontale inférieure à 5 m/s et un angle de 0°</b>.

note: type: Content of: <p>
en: You must define two functions: <code>[!java]void [/!]initialize()</code> and <code>[!java]void [/!]step()</code>. <code>initialize()</code> is called once just after you press "Run". You can use it to chose some flat zone. As before, <code>step()</code> is called every 0.1 second and is used for adjusting the lander's thrust and angle. As in the first exercise the lander's thrust is adjusted via <code>[!java]void [/!]setDesiredThrust([!java]int [/!]desiredThrust[!scala]:Integer[/!])</code>.  But you can also control its angle via <code>[!java]void [/!]setDesiredAngle([!java]double [/!]desiredAngle[!scala]:Double[/!])</code>.  An angle of 0° denotes a vertical position where the "head" of the lander points up.  This is the angle you must land with. A positive angle denotes a left-leaning lander, a negative angle a right-leaning one. You cannot lean more than by ±90°, and the angle can vary by at most ±5° in one step.
fr: Vous devez définir deux fonctions : <code>[!java]void [/!]initialize()</code> et <code>[!java]void [/!]step()</code>. <code>initialize()</code> est appelée au moment où l'on appuie sur le bouton «Exécuter». Vous pouvez l'utiliser pour choisir une zone plate. Comme avant, <code>step()</code> est appelée tous les dixièmes de seconde pour vous permettre d'ajuster la poussée (avec la fonction  <code>[!java]void [/!]setPousseedesiree([!java]int [/!]poussee[!scala]:Integer[/!])</code>). Vous pouvez également contrôler l'angle du module avec la fonction <code>[!java]void [/!]setAngleDesire([!java]double [/!]angle[!scala]:Double[/!])</code>. Un angle de O° dénote une position verticale, avec le sommet du module dirigé vers le haut. C'est l'angle avec lequel vous devez vous poser. Un angle positif indique que le module penche vers la gauche tandis qu'un angle négatif indique au contraire qu'il penche à droite. Il est impossible de se pencher à plus de ±90°, et on ne peut pas pencher le module de plus de ±5° en une fois.

note: type: Content of: <p>
en: As in the previous exercise, <code>[!java]List&lt;Point&gt; [/!]getGround()[!scala]:List[Point][/!]</code> returns the vertices of the ground's profile from left to right.  Please refer to the documentation (Help/About this world) for a reference manual of your lunar lander.
fr: Comme dans les exercices précédents, <code>[!java]List&lt;Point&gt; [/!]getSol()[!scala]:List[Point][/!]</code> retourne les points qui composent l'horizon. Le manuel de référence de votre module est disponible dans la documentation (Aide/À propos de ce monde).

note: type: Content of: <p>
en: As before, your program must safely land the lander in all the situations encountered so far in addition to this new one.
fr: Comme d'habitude, votre programme doit se poser sans heurt dans toutes les situations que nous avons rencontré jusqu'à présent, ainsi que dans ce nouveau cas.

note: type: Content of: <p>
en: Good luck, try not to crash!
fr: Bonne chance. Essayez de ne pas vous scratcher ;)

note: type: Content of: <h2>
en: The PLM Main Window
fr: La fenêtre principale de PLM

note: type: Content of: outside any tag (error?)
en: The PLM working environment should be self-explanatory, in particular with the tool tips appearing when your mouse is over the elements.  Here is a little explanation of the components in case you fail to understand something. The main window is made of 5 main components:
fr: L'environnement de travail de PLM devrait être immédiat à maîtriser, en particulier avec les bulles d'aide qui apparaissent quand votre souris survole les éléments. Voici une petite explication des composants au cas où quelque chose vous échappe. La fenêtre principale est faite de 5 composants majeurs :

note: type: Content of: <ul><li>
en: <b>The menu:</b> Placed on top of the window, it gives you access to some advanced commands such as exiting the program, and some other that we will detail later.
fr: <b>Le menu :</b> Placé en haut de la fenêtre, il vous permet de quitter le programme, et d'accéder à certaines commandes avancées que nous détaillerons plus tard.

note: type: Content of: <ul><li>
en: <b>The tool bar:</b> Placed just below the menu, it gives you access to the four main commands:
fr: <b>La barre de commandes : </b> Placée juste en dessous du menu, celle-ci vous donne accès aux quatre commandes principales :

note: type: Content of: <ul><li><ul><li>
en: The <b>Start</b> button, which begins the compilation and execution of the code you may have typed in the editor. At the end of the execution, it verifies whether you reach the situation constituting the objective of the exercise or not. If yes, you gain access to the next exercise using the <b>Exercise</b> menu. If not, you need to rework your code.
fr: Le bouton <b>Exécuter</b> qui lance la compilation et l'exécution du code que vous aurez tapé dans l'éditeur.  A la fin de l'exécution, il vérifie que vous arrivez bien à la situation finale de l'exercice. Si c'est le cas, vous aurez accès à l'exercice suivant par le menu <b>Exercise</b>.  Sinon, il vous faudra corriger votre code.

note: type: Content of: <ul><li><ul><li>
en: The <b>Stop</b> button allows you to interupt the execution of your code, what may reveal useful if you encounter an <i>infinite loop</i>.
fr: Le bouton <b>Stop</b> permet d'interrompre l'exécution de votre code, ce qui est pratique si vous avez une <i>boucle infinie</i>.

note: type: Content of: <ul><li><ul><li>
en: The <b>Reset</b> button can be used to reset the world into its initial state.
fr: Le bouton <b>Réinitialiser</b> permet de remettre le monde dans son état initial.

note: type: Content of: <ul><li><ul><li>
en: The <b>Demo</b> button shows you the execution of the expected solution. During its execution, you may want to switch the seen world to see the different expected solutions.
fr: Le bouton <b>Démo</b> vous montre l'exécution de la solution attendue. Pendant l'exécution, vous êtes autorisés à changer de monde afin de voir les différentes exécutions attendues.

note: type: Content of: <ul><li><ul><li>
en: Please note that there is often several ways of achieving the awaited solution, and that the one presented during the demo is not more or less correct than the others. You are completely free to not follow strictly the process shown by the demo, as long as your final solution matches the exercise expectations.
fr: Notez qu'il y a souvent plusieurs moyens d'atteindre la solution escomptée, et que celle présentée lors de la démo n'est pas plus ou moins correcte que les autres. Libre à vous de ne pas suivre à la lettre le procédé de la démo, à condition que le résultat final corresponde bien à ce qui est demandé.

note: type: Content of: <ul><li>
en: <b>Mission and editor tabs:</b> this is were you read this very text. This area contains several tabs to which you can access by clicking on their name on the top left. The first tab (which is always named <b>Mission</b>)  contains a presentation of the current exercise. To solve an exercise, you need to write your code in the other tabs. For example, you can now clic on the <b>Source Code</b> tab to see the actual source. If it is empty, that's because you did not write any code yet.
fr: <b>Les onglets de consigne et d'édition :</b> C'est ici que vous lisez le texte actuel.  Cette zone contient plusieurs onglets, auxquels on peut accéder en cliquant sur leur nom en haut à gauche.  Le premier onglet (qui est toujours intitulé <b>Mission</b>)  contient une présentation de l'exercice en cours.  Pour résoudre un exercice, vous devez écrire votre code dans les autres onglets.  Par exemple, vous pouvez maintenant cliquer sur l'onglet <b>Source Code</b> pour voir le code actuel.  S'il est vide, c'est que vous n'avez pas encore écrit de code.

note: type: Content of: <ul><li>
en: <b>The console:</b> Placed under the tabs, this is where any messages of the application will appear. This area is initially empty and white.
fr: <b>La console :</b> Placée sous les onglets, c'est ici que s'afficheront tous les messages de l'application. Cette zone est initialement vide et blanche.

note: type: Content of: <ul><li>
en: <b>World view</b> Placed on the right of the tabs, it is constituted of five elements:
fr: <b>La vue du monde :</b> Placée à droite des onglets, elle est constituée de cinq éléments:

note: type: Content of: <ul><li><ul><li>
en: A scrolling menu allows to choose the world. Indeed, the program you write may be executed in several worlds to test it in differing conditions. This menu allows you to choose the world you want to see. Note that this scrolling menu is hidden if there is only one world in your exercise.
fr: Un menu déroulant permettant de choisir un monde. En effet, le programme que vous devez écrire sera parfois exécuté dans plusieurs monde pour vous confronter à différentes situations. Ce menu déroulant vous permettra de choisir le monde que vous souhaitez voir. Notez que ce menu est masqué si l'exercice courant n'offre qu'un seul monde.

note: type: Content of: <ul><li><ul><li>
en: A slider placed right bellow allows to choose the animation speed of the world. More precisely, it allows to choose the delay (in milliseconds) that the buggles must wait after each action to allow you to see what they are doing.
fr: Un réglet placé en dessous permet de choisir la vitesse d'animation du monde. Plus exactement, il permet de choisir le délai (en millisecondes) que les buggles doivent attendre après chaque action afin que vous ayez le temps de voir ce qu'elles font.

note: type: Content of: <ul><li><ul><li>
en: A tab <b>World</b> represents the view of the world currently selected (from the scrolling menu). This view is thus constitued of a grid forming the several cells of the world, as well as several <i>buggles</i> awaiting for your orders.
fr: Un onglet <b>Monde</b> qui représente la vue du monde actuellement sélectionné (dans le menu déroulant). Cette vue est constituée d'une grille représentant les différentes cases du monde, ainsi que d'une ou plusieurs <i>buggles</i> qui attend vos ordres.

note: type: Content of: <ul><li><ul><li>
en: An <b>Objective</b> tab displaying the world as it must be by the end of the exercise.
fr: Un onglet <b>Objectif</b> qui permet d'afficher la vue du monde tel qu'il doit être à la fin de l'exercice.

note: type: Content of: <ul><li><ul><li>
en: <b>The interactive controls</b>. Placed under the world view, these buttons allows you to interactively control the buggles. This way, you can try to <i>manually</i> bring your buggle to the scenario objective before writting the needed code in the editor.
fr: <b>Les contrôles interactifs</b> Placés sous la vue du monde, ces boutons vous permettent de contrôler interactivement les buggles.  Vous pouvez ainsi essayer d'amener la buggle à l'objectif du scénario <i>à la main</i> avant d'écrire le code nécessaire dans l'éditeur.

note: type: Content of: <ul><li><ul><li><ul><li>
en: A scrolling menu allows to select the buggle you want to control.
fr: Un menu déroulant permettant de sélectionner la buggle que vous souhaitez contrôler.

note: type: Content of: <ul><li><ul><li><ul><li>
en: The <b>Forward</b> button let your buggle do one step forward.
fr: Le bouton <b>avance</b> fait avancer votre buggle d'un pas.

note: type: Content of: <ul><li><ul><li><ul><li>
en: The <b>Backward</b> button let it do one step backward.
fr: Le bouton <b>recule</b> fait reculer votre buggle d'un pas.

note: type: Content of: <ul><li><ul><li><ul><li>
en: The <b>Turn left</b> button ask your buggle to turn of 90° to its left.
fr: Le bouton <b>gauche</b> demande à votre buggle de tourner vers la gauche.

note: type: Content of: <ul><li><ul><li><ul><li>
en: The <b>Turn right</b> button asks the buggle to turn to the right (isn't this amazing?).
fr: Le bouton <b>droite</b> demande à votre buggle de tourner vers la droite (incroyable, non?).

note: type: Content of: <ul><li><ul><li><ul><li>
en: The <b>Mark</b> button requests your buggle to leave a mark behind it when it goes.
fr: Le bouton <b>marquer</b> demande à votre buggle de faire un trait au sol quand elle avance.
