Draft

Generic Mathematical Expressions

Description
Loading description...
Mathematics
Parsing
  • Please sign in or sign up to leave a comment.
  • G_kuldeep Avatar
    Expression: (--3!!^2//100//8)*0.01+-2
    Operators:  +(Infix, 6), *(Infix, 5), ^(Infix, 3), **(Infix, 3), -(Prefix, 2), !(Postfix, 1), //(Infix, 4)
    

    resolving :

     (--3!!^2//100//8)*0.01+-2
     (--6!^2//100//8)*0.01+-2
     (--720^2//100//8)*0.01+-2
     (--518400//100//8)*0.01+-2
     (--5184//8)*0.01+-2
     (-648)*0.01+-2
     648*0.01+-2
     648*0.01+-2
     6.48+-2
     4.48
    

    expected : 430 ??

    • Dr Gabo Avatar

      Please, see my response to ZED's question, this is because I assume all operators group from the left.

      Question marked resolved by Dr Gabo 5 years ago
  • Blind4Basics Avatar

    Hi,

    • the Complex fixed tests and edge cases should be a it block rather than a describe one
    • you definitely need more fixed tests, or at least, random tests with the usual operators, or... Let's see...:

    Currently, I pass all the fixed tests but fail every single random one. I get an error about identifying prefix/postfic/infix stuff correctly at some point, but since I actually don't know what ??? or lkjsdhfkjsdg operators are actually doing, I have actually no way to debug my code... :o Hence:

    • either put batches of random tests with usual/real operators, then another batch changing only the precedences, and only then start messing with the representations
    • or add something to your log to explain what computation will do each operator... Except that this way, it's an open door to string replacement, so I guess only the first point could work...?

    cheers (interesting, so far...)

    • Dr Gabo Avatar

      the Complex fixed tests and edge cases should be a it block rather than a describe one.

      Absolutely, I'll change that right away.

      either put batches of random tests with usual/real operators, then another batch changing only the precedences, and only then start messing with the representations.

      Seems reasonable. I'll prepare two batches of random tests. One of them with the usual operators and one of them with altered precedences.

    • Blind4Basics Avatar

      complement: seems that my solution doesn't handle properly postfix/prefix operators in the middle of the expression

    • Dr Gabo Avatar

      Alright, I've added some small random tests that should help with the debugging process. To make sure that there were no domain errors I had to put bitwise operators, but I think they are fine. Please, take a look and tell me if you think they are insufficient or lack something.

      Also, remember that you only have to take into account the prefixes and postfixes that are at the very beginning or end of an expression (see Hana1989's question for more info).

    • Blind4Basics Avatar

      Also, remember that you only have to take into account the prefixes and postfixes that are at the very beginning or end of an expression (see Hana1989's question for more info).

      I guess that's precisely the part of the description that I currently don't get... I'll keep you posted

    • Blind4Basics Avatar

      So, if I get it correctly, unary operators aren't actually following (like "at all"?) the same rules than the infix ones? :/

    • Dr Gabo Avatar

      this rule regarding unary operators is there just because it made sense to me at the moment. As I understand it (and I may be wrong here), there is no consensus on how to manage these precedences when you generalize this much and people tend to use parentheses in order not to be ambiguous. Also, this kata is hard enough as is.

      Imagine you have this expression:

      3 + 2! + 1
      

      Let's imagine that, for some reason, the ! suffix operator has a higher precedence than the + infix operator.

      If you allowed grouping of unary operators inside the expression, the grouping would be (3 + 2)! + 1. We say that we must prioritize the infix ones in these cases, so the grouping would be (3 + 2!) + 1. Like I said, this is just a simplification of the problem that arises from my understanding of operators and I may be wrong, but it's a little bit too late to change that now.

      In any case, people tend to be very confused with this, so I will allow these groupings in the next one.

    • Blind4Basics Avatar

      so, to summarize, all infix and prefix must be resolved before the infix opeartors, whatever their precedence is...? (just like if they were actually with higher priority == lowest precedence value)

    • Dr Gabo Avatar

      Not exactly. if the expression were like this 3 + 2 + 1! then the grouping would be (3 + 2 + 1)!. The more I repeat it, the more I begin to think it's even more difficult to grasp than the general rule.

      This was definitely a mistake xD

    • Blind4Basics Avatar

      This was definitely a mistake xD

      I guess so, yeah... x)

      but it's a little bit too late to change that now.

      na, that's what the beta phase is for! ;) => ?

    • Dr Gabo Avatar

      Well, I guess changing it is for the best. I will unpublish this for now and modify it later when I get the time (prob. around a day or two).

  • G_kuldeep Avatar

    I don;t find any note in description about what to do when two (in/post/pre)fix operators have same precedence!

    For example: precedence = {'*':3, '**':3} and expression = 2*3**4

    Do we have to follow from left to right or right to left?

    • Dr Gabo Avatar

      That's right, there is nothing talking about that case (I'll fix that). This is generally solved by using the left-grouping property. In this kata, if you have two infix operators with the same precedence you would just pick the first one from left to right.

      In any case, I'm positive this cannot happen in either the fixed tests nor the random tests.

  • hobovsky Avatar

    This kata will bring completely new aspect to this thread :)

    • Dr Gabo Avatar

      I really don't think this is a duplicate in any form (I guess it subsumes the others) :/

    • hobovsky Avatar

      I don't think it's a duplicate, It definitely is not. It's for sure more interesting than "regular" evaluation tasks, because it brings something totally new. But I sill don't think it's good enough :)

      What I mean is the fact that from all the kata collected in that thread, none is complete, and each differs from others in one aspect. As a result, each can be solved by a variant of shunting yard algorithm slightly modified between kata. I've already implemented parser and shunting yard algo in like 6 languages, every time with some little twist.

      Similarly, this kata has something which other do not have (postfix ops and variable priority) but also lacks something when compared to others: right associative ops, functions. And all I would like to have is one "complete, ultimate 'evaluate math expression' kata", with variety of ops, multi-arg functions, symbols like pi, and not 6 7 separate tasks, each with one additional requirement when compared to others. And each of them with different set of available languages.

      I am not saing your kata is bad. On the contrary, I think it's interesting and I will enjoy solving it. All I mean is that we will end up with yet another "evaluate expression" purple kata which has something new, but is missing something compared to others.

    • Dr Gabo Avatar

      I see your point. Maybe it would be cool to eventually further generalize this kata adding the things you said. I thought about it initially (right associativity is almost no extra effort and functions would be easy enough), but I thought this was difficult/daunting/boring enough as is for it not being solved for a long time, and I was right.

      If you think it would be for the best, I have no problem even retiring this one and going for the "full experience" :D

      Edit: now that you gave me the idea I will probably make the kata anyways, so the question is whether or not I should retire this one.

    • hobovsky Avatar

      No need to retire. If anything, I would retire all bunch of the other kata, and leave this one as unique compared to them. Also I am known for making things difficult, and complaining a lot, so you could just ignore me :) I just wanted to share my concers, that's all.

    • Dr Gabo Avatar

      Every criticism is welcome for me, and I really think you have a point here, so no need to think that. Thank you for taking your time to explain.

      Cheers :)

  • user9644768 Avatar
    ([c] (1 [a] (2 [b] 3))) [d]  # [b] < [a] < [c] < [d]
    [c] (((1 [a] 2) [b] 3) [d])  # [a] < [b] < [d] < [c]
    [c] (1 [a] (2 [b] (3 [d])))  # [d] < [b] < [a] < [c]
    

    This makes absolutely no-sense, what's the pattern here?

    • hobovsky Avatar

      It makes perfect sense as per this paragraph:

      Given a precendence value for each one, we can group them accordingly. To do this, we assume that when the precedence of an infix operator [a] is lower than the precedence of another infix operator [b], the following statement is true:

      1 [a] 2 [b] 3 = (1 [a] 2) [b] 3

      So, the lower the precedence, the stronger the operator

    • user9644768 Avatar

      Why? What's the point?(actually I skipped that part)

      Question marked resolved by user9644768 5 years ago
    • hobovsky Avatar

      So you would know what's the precedence of operators in expressions like 54 # 0.12 $ 33.1 @ 4, just like in 2 + 2 * 2 - 2.

    • user9644768 Avatar

      my point was that in general(AFAIK), higher precedence => "stronger"(used your term)

    • hobovsky Avatar

      Ah I see. Actually, I think it's pretty much just a matter of definition, and author defined it this way. I am not sure what is "general" approach, because I've seen priorities being expressed both ways: higher priority being smaller values, or larger values.

      It can depend on approach: if you sort by priority value in natural order, you get stronger first. If you compare priority values, then it can be more intuitive to have bigger priorities as larger values. None is better (or worse) than the other.

  • Hana1989 Avatar

    This comment has been hidden.

    • Hana1989 Avatar

      Are you still able to see my question when it is hidden...? :-/

    • hobovsky Avatar

      Author and users who solved it can still see it.

    • Hana1989 Avatar

      Thanks :) I still don't know what is wrong with my solution...

    • Dr Gabo Avatar

      Hello! I've run your example to see what the exact order of operations would be:

      1. First, you choose the : operator => (10´´´*´(8)##115):
      2. Then you have two possible operations: *, ##. We choose the second because it has a higher precedence => ((10´´´*´(8))##115):
      3. The only thing we can do here is a multiplication, so we do that => (((10´´´)*(´(8)))##115):

      If I'm not mistaken, the way you order the infix operators would be the problem. I suggest you use a translation of the approach I used here.

      I hope this is clear enough.

      Cheers :)

    • Hana1989 Avatar

      Sorry but I don't get it.

      1. Why did you choose : as the first step if it has the lowest priority?
      2. Let's focus on the 8: 10´´´*´(8)##115: It has operators from both sides. I have wrote that ## has higher priotity then ' - Understood. How come you add these brackets? In math, if you have this expression: 2-3^2 ^ has the higher priotity, so you calculate 3^2 and then you continue.... You don't add ( ) around 2-3 .... This will flip the priotities of all the operators .....
    • Hana1989 Avatar

      And I know that the operators must be "solveable", but you can see in my calculation steps that everything is also "solveable"... Thank you for the help :)

    • user9644768 Avatar

      by reading this:

      2-3^2; ^ has the higher priotity, so you calculate 3^2 and then continue.... You don't add () around 2-3 ...

      It seems that you're facing same problem due to non-conventional use of defintion, please see the question I've asked in the same discourse.

    • Dr Gabo Avatar

      I think that's the case @iaeliyen. The : operator is the one that has the highest precedence (23), and that means that it will be "chosen" first using the definition that I gave in my kata.

      Your approach is exactly the same as mine, but I solve recursively in the opposite order, so dont't worry about that.

    • Hana1989 Avatar

      Hi, Thanks you both for the help.. I thought I got it, but I don't...

      Expression: 323 [[ 5 ]]] [[ (597) Operators: [[(Infix, 1), ]]](Postfix, 18) [323.0, 'infix [[', 5.0, 'postfix ]]]', 'infix [[', '(', 597.0, ')']

      In your way: ( 323 [[ 5 ) ]]] [[ 597

      My calculation steps: 323.0, 'infix [[', 5.0 = 4278.0 4278, 'postfix ]]]' = 2139.5 2139.5, 'infix [[', 597.0 = 2568756.5

      Result: 2568756.5 should equal 7491177.0 :(

    • Dr Gabo Avatar

      If you see my answer to ZED's question, you will see the following:

      Because all operators are assumed to be left-grouping for simplicity [...]. This is only true when x//y//z = (x//y)//z (integer division is usually like that), but in this case the following holds: x//y//z = x//(y//z).

      In your grouping, you are asuming they are right-associative (please, use my definition for this concept).

      The correct grouping would be 323 [[ (5 ]]] [[ 597), and I'm guessing that's the problem here.

    • Hana1989 Avatar

      Sorry, but my problem is earlier. I've tried but sides of associativity.... ]]] has higher prec. Therefore, I create the forst grouping: (323 [[ 5) ]]] [[ 597 I would do the same if the first and the last operators was diffrent: (323 ~ 5) ]]] ! 597 Only in the next step, I "thought" about [[, but it was inside brackets alreaady.

    • Hana1989 Avatar

      Another example: Expression: 3¨9,,,¨!(8) Operators: !(Prefix, 1), ¨(Infix, 3), ,,,(Postfix, 15)

      Brackets: 3 ¨ 9 ,,, ¨ ! 8 ( 3 ¨ 9 ) ,,, ¨ ! 8 ( ( 3 ¨ 9 ) ,,, ) ¨ ( ! 8 ) 3.0 ¨ 9.0 = 246.0 (246.0 ,,, ) ¨ ( ! 8 )

      Calculation: 246.0 ,,, = 138.33333333333334 138.33333333333334 ¨ (! 8.0) ! 8.0 = 5.208333333333333 138.33333333333334 ¨ 5.208333333333333 = 3079.930555555555 3079.930555555555

      3079.930555555555 should equal 4514.180555555555

    • Dr Gabo Avatar

      Okay, I get the problem here. You are grouping by the operator with the highest precedence using different rules to the ones I define in the description.

      Prefixes and postfixes can only be grouped when they are at the very beginning or the very end of an expression (see my examples with [a], [b], [c] and [d]).

      In this case, the correct grouping would be: 3¨((9,,,)¨(!8)).

    • Hana1989 Avatar

      OK. It took me 5 minutes to fix my solution according to this rules and it works now :) Thanks!

      • I don't really understand why did you add this rule... Each operator has its prec. and it is possible to choose between operators from diffrent types, like I did in the example I've sent.
      • Anyway, I believe that ay rule you will chose is fine - you wrote this kata and it ok to chose any rule which clear, but at the moment the description isn't clear enught IMO.
      • I first though this kata should be 2ky, but some rules you add to make it more simple (like this one) make it 3kyu. It was fun :) Thanks!
    • Dr Gabo Avatar

      Thank you for taking your time! I will clarify this last rule in a technical note.

      Edit: this rule regarding unary operators is there just because it made sense to me at the moment. As I understand it (and I may be wrong here), there is no consensus on how to manage these precedences when you generalize this much and people tend to use parentheses in order not to be ambiguous. Also, this kata is hard enough as is (wait for the further generalized version that I'm preparing).

    • Hana1989 Avatar

      You are welcome! It was fun!!

      "there is no consensus" - Thie is right, but if you have prec. for each function, we can use it (no matter if it is in the middle or not..). Anyway, it doesn't really matter. It's just need to be clear.

      I am looking forward to the more generalized version. Please let me know once it is ready :-)

  • ZED.CWT Avatar

    Why is this 430?

    Expression: (--3!!^2//100//8)*0.01+-2
    Operators:  !(Postfix, 1), -(Prefix, 2), ^(Infix, 3), **(Infix, 3), //(Infix, 4), *(Infix, 5), +(Infix, 6)
    
    3!! = 6! = 720
    (--720^2//100//8)*0.01+-2
    
    --720 = 720
    -2 = -2
    (720^2//100//8)*0.01+(-2)
    
    720^2 = 518400
    (518400//100//8)*0.01+(-2)
    
    518400//100//8 = 648
    648*0.01+(-2)
    
    648*0.01 = 6.48
    6.48+(-2)
    
    4.48
    
    • Dr Gabo Avatar

      Because all operators are assumed to be left-grouping for simplicity (see technical notes). This is one of the examples that should teach this.

      518400//100//8 = 648

      This is only true when x//y//z = (x//y)//z (integer division is usually like that), but in this case the following holds: x//y//z = x//(y//z).

      If you calculate like this: 518400//100//8 = 518400//12 = 43200

    • ZED.CWT Avatar
      Question marked resolved by ZED.CWT 5 years ago
  • Blind4Basics Avatar

    mmmmh... We alreaydy have a LOT of those... Unless...

    I'm actually not sure about the context you put in there. Are you changing the precedences of the operators, at some point? Because THAT would make a cool kata, imo.

    • Dr Gabo Avatar

      I don't quite get what you mean. The precedences of the operators are not necessarily the same as in Python or any other languages, since they are an attribute of the Operator class. The idea is to make a parametric parser, and there are no katas that I'm aware of that ask for that.

      You can see what I mean if you execute the small random tests, I define a lot of different operators there.

      Edit: if Iunderstood you properly, then yes, I change the precedences of the operators.

    • Blind4Basics Avatar

      \o/

      :+1:

      edit: errr...well, might mean that the intent isn't pretty clear in the description, for now? (maybe I just missed the info. I read it pretty fast just to get an idea, for now)

    • Dr Gabo Avatar

      I think it's pretty clear (I know my descriptions tend to be long :p). If you find something confusing don't hesitate to open a suggestion or an issue, I will solve as quickly as possible :)

  • FArekkusu Avatar

    Suffix operators

    "Postfix", not "suffix".