Qiang Li
Qiang Li

Reputation: 10865

a special Tally function in mathematica

I am wondering how one can write a special Tally function, which treats the following list {{{1,0},{2,1,3}},{{1,1},{0,1,1}},{{2,1,2},{3,2}},{{1,0},{2,1}}} as if:

  1. as long as dimensions match, it is equivalent. For example, {{1,0},{2,1,3}} and {{1,1},{0,1,1}} are equivalent, but not with {{1,0},{2,1}}.
  2. ordering also does not matter. For example, {{1,0},{2,1,3}} and {{2,1,2},{3,2}} are equivalent.

The elements of the level 1 list can be artitarily nested. How can I write such a function?

Many thanks.

Upvotes: 0

Views: 418

Answers (3)

rcollyer
rcollyer

Reputation: 10695

Using SelectEquivalents

SelectEquivalents[list, Dimensions, #&, {#2[[1]], Length@#2}&]

which gives the same thing as Michael's answer, or

SelectEquivalents[list, Dimensions, #&, {#2[[1]] /. _Integer -> 0, Length@#2}&]

which gives Daniel's answer. Or, my personal favorite

SelectEquivalents[list, Dimensions, #&, {#1, Length@#2}&]

which gives

{{{2},3}, {{2,2}, 1}}

But, that reveals a flaw in using Dimension, in that it does not know what to report when the sublists are of different dims, so if we replace Dimension with Sort@Map[Length,#,{1,Infinity}]&, we can begin to handle arbitrary dimensions. This gives

{{{2, 3}, 3}, {{2, 2}, 1}}

So, the dimensionality of each sublist is revealed. This does not sort below the first dimension, and I do not see how it can be immediately fixed.

Upvotes: 3

Michael Pilat
Michael Pilat

Reputation: 6520

Very similar to @Daniel's answer, but preserves a member of each class:

In[9]:= Tally[list, (Sort[Length /@ #] == Sort[Length /@ #2]) &]

Out[9]= {{{{1, 0}, {2, 1, 3}}, 3}, {{{1, 0}, {2, 1}}, 1}}

Upvotes: 4

Daniel Lichtblau
Daniel Lichtblau

Reputation: 6894

(1) Replace all integers with 0. (2) Sort at level one. This gives a unique representative for every class in the list.

 ll2 = Map[Sort, ll /. aa_Integer -> 0]

Out[9]= {{{0, 0}, {0, 0, 0}}, {{0, 0}, {0, 0, 0}}, {{0, 0}, {0, 0, 0}}, {{0, 0}, {0, 0}}}

Tally[ll2]

Out[10]= {{{{0, 0}, {0, 0, 0}}, 3}, {{{0, 0}, {0, 0}}, 1}}

Daniel Lichtblau Wolfram Research

Upvotes: 7

Related Questions