8
$\begingroup$

For the list {1, 9, 3, 7, 8}, I want to find pairs whose sum is $10$. I would like the results shown as {{1, 9}, {9, 1}, {3, 7}, {7, 3}}. However, when I use:

IntegerPartitions[10, 2, {1, 9, 3, 7, 8}]

I get only {{7, 3}, {9, 1}}.

How can I get {{1, 9}, {9, 1}, {3, 7}, {7, 3}}?

$\endgroup$
1

9 Answers 9

11
$\begingroup$

As suggested by @JM, you can use Permutations.

list = Permutations[{1, 9, 3, 7, 8}, {2}];
Select[list, Total@# == 10 &]

Or

Pick[#, Unitize[10 - Total /@ #], 0] &@list

{{1, 9}, {9, 1}, {3, 7}, {7, 3}}

$\endgroup$
1
  • $\begingroup$ This is a good solution for the problem as stated, but would not be the best answer for long lists and large totals. I think that there are solutions that do not involve generating every possible permutation of the list. $\endgroup$
    – mikado
    Mar 3, 2019 at 13:01
4
$\begingroup$

I wonder if the OP has an interest in obtaining precisely the ordering indicated in the question, i.e. {{1, 9}, {9, 1}, {3, 7}, {7, 3}}. In that case, one would do best to feed the components to IntegerPartitions in reverse order:

IntegerPartitions[10, 2, Reverse@{1, 9, 3, 7, 8}];
Flatten[Permutations /@ %, 1]

(* Out: {{1, 9}, {9, 1}, {3, 7}, {7, 3}} *)
$\endgroup$
1
  • $\begingroup$ This is what I had in mind in the comments; thanks for posting it! $\endgroup$ Mar 4, 2019 at 0:56
3
$\begingroup$

Using Tuples and GroupBy:

lis = {1, 9, 3, 7, 8};

Tuples[lis, {2}] // GroupBy[Total] // #[10] &

{{1, 9}, {9, 1}, {3, 7}, {7, 3}}

$\endgroup$
3
$\begingroup$
l={1,9,3,7};
p=Position[DistanceMatrix[l, DistanceFunction->(#1+#2&)],10];
l[[#]]&/@p
$\endgroup$
2
$\begingroup$
list = {1, 9, 4, 4, 3, 7, 3, 0, 0};

Using SequenceCases

Join @@ Transpose[{#, Reverse /@ #}] & @
 SequenceCases[list, _?(Total[#] == 10 && Length[#] == 2 &)]

{{1, 9}, {9, 1}, {3, 7}, {7, 3}}

$\endgroup$
2
$\begingroup$
list = {1, 9, 3, 7, 8}; sum = 10;

Thread[{#, sum - #}] &@Intersection[#, sum - #] &@list

{{1, 9}, {3, 7}, {7, 3}, {9, 1}}

If order is relevant:

SortBy[Min]@Thread[{#, sum - #}] &@Intersection[#, sum - #] &@list

{{1, 9}, {9, 1}, {3, 7}, {7, 3}}

$\endgroup$
1
$\begingroup$
list = {1, 9, 4, 4, 3, 7, 3, 0, 0};

Using SequenceSplit and DeleteCases:

patt = s : {a_, b_} :> Splice@Permutations[s];

DeleteCases[SequenceSplit[list, patt], s_ /; Total[s] != 10]

(*{{1, 9}, {9, 1}, {3, 7}, {7, 3}}*)
$\endgroup$
0
$\begingroup$

I do not know how much you want to generalise, but the following seems to work. For numbers 1 to 10 (Range[10]),

ted = Partition[Range[10], 2]
bill = Reverse /@ Partition[Range[10], 2]
Riffle[ted, bill]

{{1, 2}, {3, 4}, {5, 6}, {7, 8}, {9, 10}}

{{2, 1}, {4, 3}, {6, 5}, {8, 7}, {10, 9}}

{{1, 2}, {2, 1}, {3, 4}, {4, 3}, {5, 6}, {6, 5}, {7, 8}, {8, 7}, {9, 10}, {10, 9}}

If I am missing something, please let me know.

Edit. Beaten by 39 seconds, well...

$\endgroup$
4
  • 1
    $\begingroup$ I believe we both got it wrong.She needs the numbers to sum up to 10 $\endgroup$
    – ZaMoC
    Mar 3, 2019 at 11:40
  • 3
    $\begingroup$ This would work.. s = IntegerPartitions[10,2,{1,9,3,7,8}];Riffle[s,Reverse /@ s] $\endgroup$
    – ZaMoC
    Mar 3, 2019 at 11:44
  • $\begingroup$ This may be the case, I thought that the odd number of elements would lead to an even number of partitions and the first couples of elements would sum to 10 anyway. Please feel free to post your comment as answer. $\endgroup$
    – Titus
    Mar 3, 2019 at 11:46
  • $\begingroup$ @J42161217 Thanks. It works $\endgroup$ Mar 3, 2019 at 11:50
0
$\begingroup$

A generalized solution might go something like this:

startingList = {1, 9, 3, 7, 8};
allowedSums = {2}; (* to get pairs only *)
desiredSum = 10;
(* trim duplicates created by IntegerPartitions *)

okMinimumSolution = 
   Select[minimumSolution, DeleteDuplicates[#] == # &];
maximalSolution = Flatten[Permutations[#] & /@ okMinimumSolution, 1];

The reason I say a generalized solution is imagine we have this:

startingList = {1, 9, 3, 7, 8, 12, 15};
allowedSums = {2, 3};(*to get solutions between 2 & 3 values*)
desiredSum = 17;

Running the code above on this new startingList and allowedSums gives this:

(* {{8, 9}, {9, 8}, {7, 9, 1}, {7, 1, 9}, {9, 7, 1}, {9, 1, 7}, {1, 7, 9}, {1, 9, 7}} *)

Now the point of this being generalized is clear. My assumption is that the initial list had no duplicates and that we have to "fix up" the result of IntegerPartitions since it may choose multiples of the given set and I said we don't want this.

Hope this is helpful to someone. It was fun to think of how to generalize the solution.

$\endgroup$

Your Answer

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

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