# Using Count and Rotate left

Q. Use RotateLeft and Count to find the number of planets detected by each method, presenting the result in a list of the form {{D, n1}, {R, n2}, {T, n3}}.

planets = {{Beta Pictoris B, D, {7, 1.6}}, {WASP52B,
T, {0.453, 1.270}}, {Kepler426b, T, {1.0, 1.090}}, {CoRoT6b,
T, {2.95, 1.166}}, {Kepler34b, R, {0.220, 0.784}}, {Kepler367b,
R, {0.0037, 0.116}}, {Kepler200c, R, {0.0119, 0.142}}};


I have got this far with it;

new = RotateLeft[planets, {1, 4}]
new2 = new[[All, 1]]
Count[new2, T]


But I'm not sure if this is the correct way. Bare in mind I need to use these two functions to answer, so although I'm sure there are other ways to solve this please use Count and RotateLeft.

Thank you!

– ciao
Jan 25, 2020 at 21:02
• "But I'm not sure if this is the correct way." There's not exactly an objectively correct way of solving this problem that actually uses RotateLeft. Count and Map would make more sense, and Tally and RotateLeft or Part would make sense, but Count and RotateLeft is definitely an X-Y problem. While I can't speak for the graders, I would hope that any solution that returns the correct form would be considered correct. Also, if you're using Part (as [[]]) then you can omit the rotate entirely: new2=planets[[All, 2]]. Jan 25, 2020 at 21:11

Tally[planets[[All, 2]]]


{{D, 1}, {T, 3}, {R, 3}}

If you want the result ordered:

Sort @ Tally[planets[[All, 2]]]


{{D, 1}, {R, 3}, {T, 3}}

If you have to use RotateLeft:

Tally[Map[First] @ RotateLeft[planets, {0, 1}]]


{{D, 1}, {T, 3}, {R, 3}}

or

Tally[Map[First] @ Map[RotateLeft] @ planets]


{{D, 1}, {T, 3}, {R, 3}}

Using level specs and a pattern you can do it with Count and skip the RotateLeft.

methods = {D, T, R};

AssociationMap[Count[planets, #, {2}]&, methods]
(* <|D -> 1, T -> 3, R -> 3|> *)


If you do use RotateLeft with a level spec, you can do this rather interesting if weird thing:

rotated = RotateLeft[planets, {0, 1}]
(*
{{D, {7, 1.6}, "Beta Pictoris B"},
{T, {0.453, 1.27}, "WASP52B"},
{T, {1., 1.09}, "Kepler426b"},
{T, {2.95, 1.166}, "CoRoT6b"},
{R, {0.22, 0.784}, "Kepler34b"},
{R, {0.0037, 0.116}, "Kepler367b"},
{R, {0.0119, 0.142}, "Kepler200c"}}
*)
tests = AssociationMap[List /* Append[___] /* Count]
(*
<|D -> Count[{D, ___}], T -> Count[{T, ___}], R -> Count[{R, ___}]|>
*)
counts = Map[Curry[Construct][rotated], tests]
(* <|D -> 1, T -> 3, R -> 3|> *)


Hmm. I think I may have suffered brain damage due to excessive Haskell consumption.

Anyway, if you just want to do it in a single line of idiomatic Mathematica, here you go:

CountsBy[planets, Extract[{2}]]
(* <|D -> 1, T -> 3, R -> 3|> *)


In these circumstances, though, I find it's often best to use Replace instead of Extract, as it lets me be explicit about what the data I'm destructuring means:

CountsBy[planets, Replace[{name_, method_, coords_} :> method]]
(* <|D -> 1, T -> 3, R -> 3|> *)