2
$\begingroup$

I have

list1={10, 3, 25, 6, 28, 21, 17, 22, 1, 24, 16, 7, 9, 15, 2, 18, 5, 27, 30, 8}
list2={17, 11, 24, 22, 20, 27, 1, 21, 25, 30, 2, 18, 9, 29, 10, 23, 8, 26, 15, 28}

I want to create a list of multiply a member of list1 to a member of list2 in the order: 10*28, 3*15, 25*26, 6*8 .... for example with Do[list1[[i]].list2[[21 - i]], {i, 1, 20}]]] After that I want to sort the last result from smaller to larger. and determine the first of the final list

The psudo-code:

First[Sort[Do[list1[[i]].list2[[21 - i]], {i, 1, 20}],, #1 < #2 &]]

I can write it with define another (third) list for Do[list1[[i]].list2[[21 - i]], But how can I write this code without defining third list. and how can I recognize the first element of the sorted final list (which is determined with First, is relate to which i (which element of the list1)

$\endgroup$
  • $\begingroup$ First@Sort[list1*Reverse@list2]. $\endgroup$ – march Aug 3 '15 at 16:24
  • $\begingroup$ OK, And how can I find the relation of the first element of the sorted and list1 $\endgroup$ – Unbelievable Aug 3 '15 at 16:27
7
$\begingroup$
First@Sort[{Times @@ #, #} & /@ Transpose[{list1, Reverse@list2}]]
(* {15, {15, 1}} *)

The first number is the minimum of the multiplications (15), which was obtained from multiplying (15) from list1 by (1) from list2.
The following:

Sort[{Times@##, ##} & @@@ Transpose[{list1, Reverse@list2}]] // First

also performs the same thing.

If you want the parent only

Ordering[list1 Reverse@list2, 1]
(*14*)

gives you the position of the parent on list1. And

list1[[Ordering[list1 Reverse@list2, 1]]]
(* {15} *)

gives you its value.

$\endgroup$
  • $\begingroup$ Thanks a bunch for your answer, both your answer and March's answer are so fruitful. really I don't know which answer should be accepted. $\endgroup$ – Unbelievable Aug 3 '15 at 18:14
  • $\begingroup$ @mr.0093. It doesn't matter. $\endgroup$ – march Aug 3 '15 at 18:16
  • 1
    $\begingroup$ @mr.0093, if you're having a hard time picking between two equally excellent answers, toss a coin… :) $\endgroup$ – J. M. is away Aug 4 '15 at 0:23
  • $\begingroup$ @Guess, It is a good comment, thanks $\endgroup$ – Unbelievable Aug 4 '15 at 1:38
  • 2
    $\begingroup$ @Guesswhoitis. I believe RandomChoice[{"ans1", "ans2"}] is more appropriate $\endgroup$ – Dr. belisarius Aug 4 '15 at 1:40
6
$\begingroup$

Here is a somewhat verbose and strange way of getting your answer:

Function[{x}, {#, list1[[#]], x[[#]]} & @@ Ordering[x, 1]] @ Times[list1, Reverse@list2]

Times[list1, Reverse@list2] gets your third list.

This function:

Function[{x}, {#, list1[[#]], x[[#]]} & @@ Ordering[x, 1]]

takes Times[list1, Reverse@list2] as the argument x. Ordering[x, 1] returns a list containing the index of the smallest value of the list x as a list. Then,

{#, list1[[#]], x[[#]]} & @@ Ordering[x, 1]

returns a list of three elements: the first is the index at which the smallest value in the third list appears, the second is the value of list1 appearing at that index, and the third is the value of the third list (which is the smallest value in this third list).

Therefore,

list1={10, 3, 25, 6, 28, 21, 17, 22, 1, 24, 16, 7, 9, 15, 2, 18, 5, 27, 30, 8};
list2={17, 11, 24, 22, 20, 27, 1, 21, 25, 30, 2, 18, 9, 29, 10, 23, 8, 26, 15, 28};

Function[{x}, {#, list1[[#]], x[[#]]} & @@ Ordering[x, 1]] @ Times[list1, Reverse@list2]
(* {14, 15, 15} *)

Simplification if you only want the "parent"

If all you want is the value of list1 that makes the smallest value of the third list, you can do

Part[list1, First@Ordering@Times[list1, Reverse@list2]]
(* 15 *)

or

list1[[First@Ordering@Times[list1, Reverse@list2]]]]

or, using Infix notation,

list1 ~Part~ First@Ordering@Times[list1, Reverse@list2]
$\endgroup$
  • $\begingroup$ Thank you so much for your answer and your explanation, both your answer and Belisarius's answer are so good. really I don't know which answer should be accepted. $\endgroup$ – Unbelievable Aug 3 '15 at 18:15
  • $\begingroup$ however your explanation was so good to me but based on Guess's comment I tossed a coin! $\endgroup$ – Unbelievable Aug 4 '15 at 1:40
6
$\begingroup$

I notice no one is using an association to map to positions nor allowing the sort to use a one-element heap instead of building up an entire sorted array ...

PositionIndex[#] @@ 
    TakeSmallestBy[#, Times @@ # &, 1] & 
[
    Transpose[{list1, Reverse@list2}]
]

In the example, the result is {14}, the index of 15 in list1 that gets paired with 1 in list2. Perhaps more easily understood (but doing essentially the same thing):

PositionIndex[#][
   Sort[
       #,
       OrderedQ[{#1[[1]] #1[[2]], #2[[1]] #2[[2]]}] &
   ][[1]]
] & [
    Transpose[{list1, Reverse@list2}]
]
$\endgroup$

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.