0votos

Ecuación de primer grado en C#

por josejuan hace 6 años

El tercer test del enunciado está mal (da 4/41). El parser es algo feo (aunque mucho más corto que un Shunting-yard). La clase de racionales ha sido modificada. ¿Nadie se anima a simplificar por árboles?.

Resolución de ecuación de primer grado

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
// La clase para los racionales (ya modificada) aquí: 
//      https://gist.github.com/3032730 
using System; 
using System.Linq; 
using System.Collections; 
 
using Number = ExifUtils.Rational<int>; 
using System.Text.RegularExpressions; 
 
namespace __test { 
 
    public class Program { 
 
        static Number EvalSimple( string Q ) { 
            var r = "*/+-".Select(o => new Regex(@"([\+\-]?[0-9\.]+)(\s*\" + o + @"\s*)([\+\-]?[0-9\.]+)", 
                                                    RegexOptions.Compiled)).ToArray(); 
            var f = new Func<Number, Number, Number> [] { 
                ((a, b) => a * b), ((a, b) => a / b), 
                ((a, b) => a + b), ((a, b) => a - b)  
            }; 
            var s = true; 
            var sn = new Func<string, string>(a => a.Replace("++", "+").Replace("--", "+"). 
                                                    Replace("-+", "-").Replace("+-", "-")); 
            while( s ) { 
                s = false; 
                for( var i = 0; i < r.Length; i++ ) 
                    if( r [ i ].IsMatch(Q) ) { 
                        s = true; 
                        Q = sn(r [ i ].Replace(Q, new MatchEvaluator(delegate( Match m ) { 
                            return f [ i ]( 
                                Number.fromDot(m.Groups [ 1 ].Value), 
                                Number.fromDot(m.Groups [ 3 ].Value)).toDot(); 
                        }))); 
            return Number.fromDot(Q); 
        static Number Eval( string Q ) { 
            Q = Regex.Replace(Regex.Replace(Q, @"\)([0-9])", ")*$1"), @"([0-9])\(", "$1*("); 
            var x = new Regex(@"\(([^\(\)]+)\)", RegexOptions.Compiled); 
            while( x.IsMatch(Q) ) 
                Q = x.Replace(Q, new MatchEvaluator(m => EvalSimple(m.Groups [ 1 ].Value).toDot())); 
            return EvalSimple(Q); 
        static Number SolveX( string Q ) { 
            Q = Q.Replace("=", "-(") + ")"; 
            var y0 = Eval(Regex.Replace(Q, "x", "(0)")); 
            var y1 = Eval(Regex.Replace(Q, "x", "(1)")); 
            return y0 / ( y0 - y1 ); 
 
        static void Main( string [] args ) { 
 
            string l; 
            while( true ) { 
                l = Console.ReadLine(); 
                if( l == "." ) 
                    break; 
                Console.WriteLine("RESULT: {0}", SolveX(l).Reduce()); 
 
 
 
1 comentario
0votos

Escrito por JCarles hace 6 años

He intentado un poco la simplificación mediante el parser ANTLR y luego reseguir el árbol AST pero me fastidia el tema de la falta del símbolo multiplicador que no sé añadir el token en el árbol, almenos, elegantemente. Y tampoco me convencía insertarlo antes de llegar al parser. Intentaré un rato más.

Y tienes razón en lo del anunciado. Estuve probando tu anterior solución Javascript y el caso 4 no coincidía. No supe ver la razón. La verdad es que no dediqué demasiado tiempo.

Comenta la solución

Tienes que identificarte para poder publicar tu comentario.