Take the 2-minute tour ×
Mathematica Stack Exchange is a question and answer site for users of Mathematica. It's 100% free, no registration required.

I am trying to write a function which operates on an array with subscripted elements.

As an example i have the array a={$1_3$,$2_2$,$4_1$}, which means i have 3 amounts of value 1, 2 amounts of value 2 and 1 amount of value 4. If the subscripted amount reaches 0, then the element has to be dropped from the array.

Now i need a function

edit[a_,lower_,raise_]:=...

with lower_ being an array of elements which shall be decreased by 1 and raise_ being the array of elements which should be increased by 1. These two arrays have to contain the value and not the position of the element which should be changed.

So if i would call the function with

edit[{Subscript[1, 3], Subscript[2, 2], Subscript[4, 1]}, {1, 1, 4}, {2, 5}]

the output should be

{Subscript[1, 1],Subscript[2, 3], Subscript[5, 1]}

because

  • the value 1 has to be decreased 2 times, leaving it with the amount 1
  • the value 4 has to be decreased once, thus the amount reaches 0 and it has to be dropped
  • the value 2 has to be increased once, increasing the amount to a total of 3
  • the value 5 has to be increased once, and since its not in the list yet, it has to be added

I want to use subscript because it makes it easy to read and seems to behave like a normal 2 dimensional array, but i am open to good alternatives.

share|improve this question

3 Answers 3

Here is an approach using Association for Version 10+.

edit[a_, lower_, raise_] := Subscript @@@ Normal@DeleteCases[#, 0] &@
         Merge[{#, #2, #3}, Total] &[<|Rule @@@ a|>, -Counts[lower], Counts[raise]]

Use:

edit[{Subscript[1, 3], Subscript[2, 2], Subscript[4, 1]}, {1, 1, 4}, {2, 5}]

$\left\{1_1,2_3,5_1\right\}$

share|improve this answer
    
Is Association already implemented in Mathematica 8.0? Or which Version do i need to run it? –  kon 16 hours ago
    
@kon. This is for Version 10 and above. Sorry, I didn't know you were on Version 8. –  RunnyKine 16 hours ago
    
Actually its my fault for not mentioning it, but unfortunately i cant use it and i dont think i can convince my university to upgrade to version 10 for me. –  kon 16 hours ago
    
@kon. You can download a trial version which is free for 30 days and try it out or use the Wolfram programming cloud. –  RunnyKine 16 hours ago
1  
Very nice code! I also thought to use associations but my code is not nearly as good. (I forgot entirely about Counts for one thing.) –  Mr.Wizard 5 hours ago

You can do it with "classic" functions Tally and GatherBy

edit[a_, lower_, raise_] := 
 DeleteCases[#, _[_, 0]] &[
  Subscript[#[[1, 1]], Total@#[[All, 2]]] & /@ GatherBy[#, First] &@
   Join[a, Subscript @@@ (-Tally[-lower]), Subscript @@@ Tally@raise]]

edit[{Subscript[1, 3], Subscript[2, 2], Subscript[4, 1]}, {1, 1, 4}, {2, 5}]
(* {Subscript[1, 1], Subscript[2, 3], Subscript[5, 1]} *)
share|improve this answer
    
@RunnyKine I thought that it is invalid input. Anyway, one can add c_ /; c <= 0 instead of 0 in DeleteCases. –  ybeltukov 16 hours ago
    
You're probably right that it's invalid input. +1 –  RunnyKine 16 hours ago
lst = {Subscript[1, 3], Subscript[2, 2], Subscript[4, 1]};

$\left\{1_3,2_2,4_1\right\}$

ClearAll[foo, editFX];
foo = Flatten[GatherBy[Join[#1, Subscript @@@ Tally[#2] ], First] /.
     {Subscript[x_, a_], Subscript[x_, b_]} :>
                  (Subscript[x, a + #3 b] /. Subscript[_, 0] :> Sequence[])] &;
editFX[lst_, arg1 : {___}, arg2 : {___}] := With[{t = foo[lst, arg1, -1]}, foo[t, arg2, 1]];

editFX[lst, {1, 1, 4}, {2, 5}]

$\left\{1_1,2_3,5_1\right\}$

Or

ClearAll[editFX2];
editFX2 = Fold[foo[#1, First@#2, Last@#2] &, #, {{#2, -1}, {#3, 1}}] &;
editFX2[lst, {1, 1, 4}, {2, 5}]

$\left\{1_1,2_3,5_1\right\}$

share|improve this answer
    
Nice. I like it. +1 –  RunnyKine 15 hours ago
    
Thank you @RunnyKine. –  kguler 15 hours ago

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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