16
\$\begingroup\$

Given an expression matching the regex /^[-~]*x$/, evaluate it in terms of x and output a string matching the regex /^-?x[+-]\d+$/.

For example, the string -~x evaluates to x+1, while the string -~-x evaluates to -x+1, and the string -~-~--x evaluates to x+2.

We start from x and evaluate the string right to left. - negates the term, while ~ converts y to -y-1.

Testcases:

    x  x+0
   ~x -x-1
  -~x  x+1
 ~-~x -x-2
-~-~x  x+2
--~~x  x+0
  ~-x  x-1
 -~-x -x+1

This is . Shortest answer in bytes wins.

The input/output format is strict. The "x" is mandatory.

\$\endgroup\$
  • \$\begingroup\$ Can we output x+010 instead of x+10 for -~-~-~-~-~-~-~-~-~-~x? It matches the second regex. \$\endgroup\$ – user72349 Sep 15 '17 at 18:34
  • \$\begingroup\$ You can, though I see no reason why. \$\endgroup\$ – Leaky Nun Sep 15 '17 at 18:36
  • 3
    \$\begingroup\$ The tilde has different meaning in different languages. You should probably clarify that you intend the Python meaning \$\endgroup\$ – Luis Mendo Sep 15 '17 at 19:10
  • 3
    \$\begingroup\$ @LuisMendo read the last sentence of my third paragraph \$\endgroup\$ – Leaky Nun Sep 15 '17 at 19:15
  • 1
    \$\begingroup\$ @LeakyNun Ah, sorry, I didn't see that. Anyway, I think it should appear earlier on. The first two paragraphs and part of the third talk about ~ while it hasn't been defined \$\endgroup\$ – Luis Mendo Sep 15 '17 at 20:47
11
\$\begingroup\$

Python 2, 42 41 39 bytes

lambda s,x=0:'-x%+d'[len(s)%2:]%eval(s)

Try it online!

\$\endgroup\$
7
\$\begingroup\$

Retina, 47 44 bytes

+`--|~~

((~)|-)*x
$&+$#2
T`+`-`^~.*
~
-
--

Try it online! Edit: Saved 3 bytes thanks to @MartinEnder. Expanation:

+`--|~~

Delete pairs of adjacent duplicates.

((~)|-)*x
$&+$#2

Count the number of ~s which gives us the magnitude of the term.

T`+`-`^~.*

If the first character is a ~ then the term should be negative.

~
-
--

If the number of ~s and -s is odd then the x should be negative.

\$\endgroup\$
6
\$\begingroup\$

JavaScript, 59 bytes

x=>['-'[x.length&1]]+'x'+['+'[(x=eval(x.join` `))<0^0]]+~~x

Try it online!

\$\endgroup\$
  • 2
    \$\begingroup\$ Beat me by 16 secs and 38 bytes. Well done. \$\endgroup\$ – Luke Sep 15 '17 at 18:53
  • \$\begingroup\$ Fails for test cases containing multiple - in a row. (i.e. --~-~x) \$\endgroup\$ – Luke Sep 15 '17 at 18:59
  • \$\begingroup\$ @Luke. I'm not sure what do you mean. My script works for these test cases too. \$\endgroup\$ – user72349 Sep 15 '17 at 19:02
  • \$\begingroup\$ This survives my new testcase :D \$\endgroup\$ – Leaky Nun Sep 15 '17 at 19:22
  • \$\begingroup\$ @ThePirateBay: oops, nvm then... \$\endgroup\$ – Luke Sep 15 '17 at 19:27
1
\$\begingroup\$

Perl 5, 75 + 1 (-n)= 76 bytes

map{$y=-$y;$y--if/~/}reverse/-|~/g;printf"%sx%+d",((-1)**y/-~//)=~s/1//r,$y

Try it online!

\$\endgroup\$
1
\$\begingroup\$

C (gcc), 69 bytes

a;s;f(char*p){for(a=s=0;*p;a-=*p++%5*~-s)s^=2;printf("-x%+d"+!!s,a);}

Try it online!

-1 byte thanks to @ThePirateBay

\$\endgroup\$
0
\$\begingroup\$

Java 8, 186 bytes

s->{s=s.replaceAll("--|~~","");int l,i=(s.length()-(l=(s=s.replaceAll("-~","")).length()))/2,j=l-(s=s.replaceAll("~","")).length();return(j>0?"-"+s+"-"+-~i:s+"+"+i).replaceAll("--","");}

Definitely room for improvements..

Explanation:

Try it here.

s->{                              // Method with String as both parameter and return-type
  s=s.replaceAll("--|~~","");     //  Remove all "--" and "~~"
  int l,                          //  Temp integer to reduce bytes
      i=(s.length()-(l=(s=s.replaceAll("-~","")).length()))/2,
                                 //  Remove all "-~" and save count in `i`
      j=l-(s=s.replaceAll("~","")).length();
                                 //  Remove all remaining "~" and save count in `j`
   return(j>0?                   //  If `j` is larger than 0:
           "-"                   //   Start with a minus sign
           +s                    //   followed by the remaining `s`
           +"-"                  //   followed by another minus sign
           +-~i                  //   followed by `i+1`
          :                      //  Else:
           s                     //   Start with the remaining `s`
           +"+"                  //   followed by a plus sign
           +i                    //   followed by `i`
         ).replaceAll("--","");  //  And then remove all "--"
}                                // End of method
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.