5
$\begingroup$

I'm looking to see if there's a more idiomatic/concise/neat solution than what I have for this.

I have a list of boxes with heights and I want to stack them; that is, add to each box the distance to its center from the origin. See below:

  |->|-----| -|   |
h1|  |  .  |<-|y1 |
  |->|_____|      |
  |->|-----|      |
  |  |     |      |
h2|  |  .  |<-----|y2
  |  |     |
  |->|_____|

My solution is this:

L = {
   {h -> 1},
   {h -> 2}
  };
(* measure distances *)
Y = y -> # & /@ ((h/2 /. L) + Most@Accumulate[h /. {{h -> 0}}~Join~L]);
(* append distances to elements *)
L = MapThread[Append[#1, #2] &, {L, Y}]

Out= {
      {h -> 1, y -> 1/2}, 
      {h -> 2, y -> 2}}

So I'm getting a list of the edges and a list of the local centers and adding those.

Is there a different/better way to modify each element in a list, depending on previous elements? I would especially appreciate a shorthand for MapThread[Append[...

Solution

Combining the first two responses gives us

L = {{h -> 1}, {h -> 2}};
Y = Thread[y -> Accumulate[h /. L] - (h/2 /. L)]
(* one of: *)
L = {L, Y}\[Transpose] // Map@Flatten
L = Flatten/@Transpose@{L,Y}
L = Flatten/@Thread@{L,Y}

where \[Transpose] is entered with :tr:, which I like a lot.

$\endgroup$
4
$\begingroup$
L = {{h -> 1}, {h -> 2}};

Y = Thread[y -> Flatten[Accumulate[Values@L ] - Values@L/2]];

Join[L, List /@ Y, 2]
 {{h -> 1, y -> 1/2}, {h -> 2, y -> 2}}

Or

MapThread[Append] @ {L, Y}
 {{h -> 1, y -> 1/2}, {h -> 2, y -> 2}}

Or

Flatten /@ Thread @ {L, Y}
 {{h -> 1, y -> 1/2}, {h -> 2, y -> 2}}
| improve this answer | |
$\endgroup$
  • $\begingroup$ Much better usage of Thread! Changing the + to -, I don't know how I missed that thanks. I like the currying in your second example too. $\endgroup$ – Matt Murphy Oct 23 at 2:03
2
$\begingroup$
Clear[h, y]
a = {1, 2};
b = Accumulate[a] - a/2;
Transpose[{Thread[h -> a], Thread[y -> b]}]

{{h -> 1, y -> 1/2}, {h -> 2, y -> 2}}

| improve this answer | |
$\endgroup$
  • $\begingroup$ I like the transpose a lot because I can use :tr:. I just have to map Flatten to finish this one off. Thanks! $\endgroup$ – Matt Murphy Oct 23 at 1:54

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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