1
$\begingroup$

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!

$\endgroup$
2
  • 1
    $\begingroup$ Is this homework? If so, please add the appropriate tag. $\endgroup$
    – ciao
    Jan 25, 2020 at 21:02
  • 1
    $\begingroup$ "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]]. $\endgroup$
    – eyorble
    Jan 25, 2020 at 21:11

2 Answers 2

4
$\begingroup$
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}}

$\endgroup$
1
$\begingroup$

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|> *)
$\endgroup$

Your Answer

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

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