Reverse Polish Notation

Cette semaine, c'est Bertrand qui vous propose un #KataOfTheWeek : Reverse Polish Notation

Briefing du Kata : En notation polonaise inversée, les opérateurs suivent leurs opérandes. Par exemple, pour additionner 3 et 4, on écrirait « 3 4 + » plutôt que « 3 + 4 ».

S'il y a plusieurs opérations, l'opérateur est donné immédiatement après son deuxième opérande, ainsi l'expression écrite « 3 – 4 + 5 » en notation conventionnelle s'écrirait « 3 4 – 5 + » en RPN : 4 est d'abord soustrait de 3, puis 5 lui est ajouté.

Un avantage de RPN est qu'il évite le besoin de parenthèses qui sont requises par notation infixée. Alors que "3 - 4 * 5" peut également être écrit "3 - (4 * 5)", cela signifie quelque chose de très différent de "(3 - 4) * 5". En postfix, le premier pourrait s'écrire « 3 4 5 * - », ce qui signifie sans ambiguïté « 3 (4 5 *) - » ce qui se réduit à « 3 20 - », ce dernier pourrait être écrit « 3 4 – 5 * » (ou 5 3 4 – *, si vous conservez un formatage similaire), ce qui signifie sans ambiguïté « (3 4 -) 5 * ».

Le but de ce kata est bien sur de créer un programme qui effectue des calculs en utilisant la notation polonaise inverse.

Saurez-vous résoudre le problème ?

Bon courage !


Et voici une solution proposée par l'auteur en Java :

import java.util.Arrays;
import java.util.Stack;
import java.util.function.*;

public class ReversePolishNotation {

    public static Double calc(String input) {
        Stack<Double> numbers = new Stack<>();
        Arrays.asList(input.split(" ")).stream().forEach(number -> {
            switch(number) {
                case "+":
                    calcSign(numbers, (n1, n2) -> n2 + n1);
                    break;
                case "-":
                    calcSign(numbers, (n1, n2) -> n2 - n1);
                    break;
                case "*":
                    calcSign(numbers, (n1, n2) -> n2 * n1);
                    break;
                case "/":
                    calcSign(numbers, (n1, n2) -> n2 / n1);
                    break;
                default:
                    numbers.push(Double.parseDouble(number));
            }
        });
        return numbers.pop();
    }

    protected static Stack<Double> calcSign(Stack<Double> numbers, BiFunction<Double, Double, Double> operation) {
        numbers.push(operation.apply(numbers.pop(), numbers.pop()));
        return numbers;
    }

    public static void main(String[] args) {
        System.out.print(calc("-12.9 3 /"));
    }

}

Votre équipe TakiVeille

TakiVeille

TakiVeille