Next task to complete:
Count
*
-symbol in such expression asa + s^2*b - c/y + o^3 + n*m*u
(in this case count of*
should be 6)Powers such $o^3$ should be expand to $o*o*o$
I try, but my code is pretty ugly.
Next task to complete:
Count *
-symbol in such expression as a + s^2*b - c/y + o^3 + n*m*u
(in this case count of *
should be 6)
Powers such $o^3$ should be expand to $o*o*o$
I try, but my code is pretty ugly.
This doesn't give the result you are looking for exactly because it uses the full form of the expression you give it.
SetAttributes[countTimes, HoldAll];
countTimes[expr_] := Block[{Times, Power, power, times},
power[a_, b_ /; b > 0] := Nest[times[a, #] &, a, b - 1];
power[a_, b_ /; b < 0] := 1/power[a, -b];
power[a_, 0] := 1;
times[a___, b_times] := times[Sequence @@ b, a];
Total[(Length /@
Extract[#, Position[#, times[___]]] &[(expr /.
Power -> power) /. Times -> times]) - 1]
]
expr = a + s^2*b - c/y + o^3 + n*m*u
countTimes[expr]
(*8*)
The reason this gives 8 instead of 6 is because of the term -c/y
which in full form is Times[-1,c,Power[y,-1]]
. If you want to treat this specially you will need to add definitions to account for such patterns.
countTimes[a*b*c]
.
$\endgroup$
Commented
Jul 5, 2015 at 21:10
Accepting that in Mathematica -c/y
is automatically converted to -1*c*y^-1
and permitting the result shown in Andy's answer I believe we can use a simpler approach, at least for the kind of expression given in example.
Define rules
that determine how a Times
or Power
expression should be counted, then use Cases
to find all instances in you expression and total them with Tr
:
rules = {
_*x__ :> Length@{x},
_^n_?Positive :> n - 1
};
expr = a + s^2*b - c/y + o^3 + n*m*u;
Tr @ Cases[expr, #, -2] & /@ rules
Tr @ %
{5, 3} 8
As a single function:
fn[expr_] :=
Tr @ Cases[expr, #, -2] & /@ {_*x__ :> Length@{x}, _^n_?Positive :> n - 1} // Tr
If you prefer a string processing result, now accepting that the form Mathematica uses may seem rather arbitrary, I propose:
stringfn[expr_] :=
StringCases[
ToString[expr, InputForm],
{"*" :> 1, "^" ~~ d__?DigitQ :> FromDigits[d] - 1}
] // Tr
a + s^2*b - c/y + o^3 + n*m*u // stringfn
6
I think this is easier to do by working with strings.
First write a function that will expand strings of the form "Power(x,k)" where k is an integer in "xx...x" with k - 1 ""s.
f[x_, k_] :=
Module[{i = Abs[ToExpression[k]] - 1},
Nest[StringJoin[#, "*" <> x] &, x, i]]
A couple of tests for f
.
f["s", 2]
"s*s"
f["ab", "-3"]
"ab*ab*ab"
Next write a function that will use f
to transform powers and will count the stars in the expression after f
has done its transformation.
starCount[expr_] :=
StringCount[
StringReplace[
expr // CForm // ToString,
"Power(" ~~ v : WordCharacter .. ~~ "," ~~ k : NumberString ~~ ")" :> f[v, k]],
"*"]
starCount[a + s^2*b - c/y + o^3 + n*m*u]
6
starCount[1/(b s^3) + 1/t^4]
6
Note: I use CForm
to recover the /
s that represent division, which the OP apparently wants to preserve as a distinct operator.
1/(b s^3) + 1/t^4
and mine gets 6. Which do you think would be the value the OP would expect?
$\endgroup$
Commented
Jul 5, 2015 at 23:56