12
\$\begingroup\$

Everyone knows, that you can leave out the multiplication symbol (\$\times\$, or *) in

  • a*b
  • 23*a
  • (2+3)*a
  • a^(b*c)
  • (a+b)*(c+d)

but not in

  • 2*3 => you don't want it to be 23
  • a*23 => most mathematicians just don't do it
  • a^2*b => now it's (a^2)*b, if you remove the *, it's a^(2b)
  • a/2*b => now it's (a/2)*b, if you remove the *, it's a/(2b)
  • a*(2+3) => most mathematicians just don't do it

But does a program know it to?

Notes

  • The input is an equation which has the basic operations (+, -, *, /, ^), parentheses ((, )) and sometimes some 1-letter variables
  • The output should be the input with unnecessary *s removed where possible

Examples

a*b
> ab

2+3*a
> 2+3a

23+67/(56+7)
> 23+67/(56+7)

2t
> 2t

2*3+5/6*b
> 2*3+5/6*b

2*a*3
> 2a*3

2*-3
> 2*-3

a*-3
> a*-3

a^2*b
> a^2*b

a/2*b
> a/2*b

a*(2+5)
> a*(2+5)

(2+5)*a
> (2+5)a

23+(2*a)^(45*b)-c/5+24d+(2a)*(2b)
> 23+(2a)^(45b)-c/5+24d+(2a)(2b)

(a-b)*(2+e)
> (a-b)(2+e)

a*b*c
> abc

2*(3)
> 2(3)

(2)*(3)
> (2)(3)

2(3)
> 2(3)

(2)*3
> (2)3
\$\endgroup\$
9
  • \$\begingroup\$ @Arnauld Thanks, it got a bit messed up. \$\endgroup\$
    – math scat
    Commented Jul 1, 2021 at 9:54
  • 5
    \$\begingroup\$ 5th case 2*3+5/6*b can't be 2*3+5/6b \$\endgroup\$ Commented Jul 1, 2021 at 10:15
  • \$\begingroup\$ @NahuelFouilleul done \$\endgroup\$
    – math scat
    Commented Jul 1, 2021 at 10:53
  • 7
    \$\begingroup\$ Maybe it's country-specific, but I've definetly seen and used expressions like a(2+5) \$\endgroup\$
    – Kaddath
    Commented Jul 1, 2021 at 11:15
  • 1
    \$\begingroup\$ And may we get a single number parenthesized, i.e. 2*(3)? If so, what should be the output here? (I find it kinda weird, but we do use 2(3) sometimes.) What about (2)*3 and (2)*(3)? \$\endgroup\$
    – FZs
    Commented Jul 1, 2021 at 12:26

4 Answers 4

9
\$\begingroup\$

Wolfram Language (Mathematica), 5 bytes

Defer

Defer displays the expression in unevaluated form, leaving out the asterisks.

enter image description here

If you don't mind that Mathematica automatically combines some terms, and just want to eliminate the asterisks, no function is needed, giving the following 0-byte solution:

enter image description here

When it strips out the asterisks, Defer will usually remove mathematically unnecessary parentheses; however, they are sometimes retained for clarity:

enter image description here

When Defer removes a mathematically necessary asterisk, it will replace it with either parentheses or a × glyph:

enter image description here

For an additional 14 bytes (19 bytes total), Mathematica will dispense with both the asterisks and the times glyphs, using spaces instead.

To accomplish this, we need to operate OutputForm on HoldForm. Here HoldForm is needed instead of Defer, because while Defer displays the unevaluated form, it does not actually return the unevaluated form. To produce the desired result, OutputForm needs to operate on the unevaluated expression:

OutputForm@HoldForm

enter image description here

\$\endgroup\$
2
  • 1
    \$\begingroup\$ typical mathematica \$\endgroup\$
    – math scat
    Commented Jul 1, 2021 at 16:24
  • \$\begingroup\$ would be good to see an output screenshot. \$\endgroup\$
    – Razetime
    Commented Jul 1, 2021 at 16:38
5
\$\begingroup\$

Perl 5 (-p), 41 bytes

s;([/^]\d+\*)|\*(?=[a-z]|(?<=\).)\();$1;g

A regex substitution which validates all the test cases.

Try it online!

Perl 5 (-p), 79 bytes

$_=reverse;s;([a-z]|\((?=.\)))\K\*(?!(\)([^()]|(?2))*\(|\w+)[/^]);;g;$_=reverse

Handling tsh's case Try it online!

\$\endgroup\$
3
  • 3
    \$\begingroup\$ Then what would 2^(3+5)*a be? \$\endgroup\$
    – tsh
    Commented Jul 1, 2021 at 10:45
  • \$\begingroup\$ @tsh, well it wasn't in the test cases, as this is code golf, it will be a little harder and longer because of recursive structure with parentheses \$\endgroup\$ Commented Jul 1, 2021 at 10:51
  • \$\begingroup\$ @tsh, test case handled \$\endgroup\$ Commented Jul 1, 2021 at 12:14
4
\$\begingroup\$

Python 3, 77 76 bytes

Regex solution :

lambda x:re.sub("(?<![\^/].)\*(?=[A-z])","",x).replace(")*(",")(")
import re

Try it online!

Regex are ugly. Useful but ugly

Thanks to @ovs for -1 byte

\$\endgroup\$
1
  • 1
    \$\begingroup\$ 76 bytes by doing the )*( -> )( replacement with str.replace \$\endgroup\$
    – ovs
    Commented Jul 1, 2021 at 20:00
2
\$\begingroup\$

Python 3, 214 bytes

def f(x):
 s=''
 for i,c in enumerate(x):
  if(c=='*'):
   if ((x[i-1:i+2]==")*(")or(x[i-1].isalpha() and x[i+1].isalpha())or( x[i+1].isalpha())and(x[i-2]not in"^/"and x[i+1]not in"-+") ):
    c=''
  s+=c
 return s

Try it online!

ok this is really bad lol, sorry I'm new, any suggestion would be awesome!

EDIT: Ok, I think that's the shortest I can do lol, and FINALLY it works!

thanks to Kateba and Jakque for tips and ideas EDIT2: not doing lambda because I don't fully understand how it works lol

\$\endgroup\$
5
  • \$\begingroup\$ I golfed it to 101 bytes. But then I realized that test cases 5 to 11 fail with your submission, so please look at the failing testcases and improve your submission \$\endgroup\$
    – Kateba
    Commented Jul 1, 2021 at 11:57
  • 1
    \$\begingroup\$ Some stuff I noticed: You don't need to indent everything with 4 spaces, 1 is enough and saves you a lot of bytes. The list q is unnecessary, you could just write for i in range(len(x)) and x[i]. If you need i and q[i] in your loop, it is best to write for i,c in enumerate(q). In line 5 you write q[i], even if q[i] is the same as c. The two if statements can be written together as one, if you connect them with and. And finally, you can rewrite the if statement to check for the opposite case and only do s+=c then, which saves you a few bytes of indentation and some nots. \$\endgroup\$
    – Kateba
    Commented Jul 1, 2021 at 12:05
  • \$\begingroup\$ @Kateba Try it online! for 77 \$\endgroup\$
    – Jakque
    Commented Jul 1, 2021 at 12:33
  • \$\begingroup\$ @Jakque I'm still impressed by your skills at golfing. Tried upgrading your code to make it pass the testcases, made it much longer tho for 140 bytes. f = lambda x:''.join([c*(not((x[i+1].isalpha()or')('==x[i-1:i+2:2])and x[i-2]not in['/','^'])or'*'!=c)for i,c in enumerate(x[:-1])]+[x[-1]]) \$\endgroup\$
    – Ubikuity
    Commented Jul 1, 2021 at 14:48
  • \$\begingroup\$ ok I may have something (105 bytes): Try it online! \$\endgroup\$
    – Jakque
    Commented Jul 1, 2021 at 15:43

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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