Computer search solution
A simple search of all combinations of even numbers in P and odd numbers in Q confirms that 8 is the most you can use, so 12 unused in set O is the best you can do. Symmetry between odds and evens means you can generate an odd/even solution from any even/odd solution by incrementing odds and decrementing evens. It's nice to note that there is a pair of arrangements with two elements in the 'short' list.
Solutions.
P1 Q7 sum 8 P (2) Q (1,3,5,9,11,15,17)
P1 Q7 sum 8 P (4) Q (1,3,7,9,13,15,19)
P2 Q6 sum 8 P (4,10) Q (1,3,7,9,13,19)
P7 Q1 sum 8 P (2,4,6,10,12,16,18) Q (1)
P6 Q2 sum 8 P (2,4,8,10,14,20) Q (3,9)
P7 Q1 sum 8 P (2,4,8,10,14,16,20) Q (3)
Code. Not a shining light for correct coding but it runs quickly until you hand it 32 instead of 20. Not much interesting happens with higher numbers. Algorithm is basically loop from 1 to 2^N where N is number of evens, then loop over 2^N again for odds, and for each, check which even and odd numbers are 'present' in the list by checking whether the loop number has that bit set.
// PrimePartition
// partition the numbers 1 to N into two lists such that all sums of one element from each list are prime
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define MaxLen 20
int primes[27]={2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53,59,61,67,71,73,79,83,89,97,101,103};
int odds[MaxLen+1];
int evens[MaxLen+1];
void Solve(int MaxList)
{
long i,j,ei,oi,k,pcount,qcount,thiseven,thisodd,thissum,failed,bestsofar=3;
// Loop over first group (evens)
for (i=1; i<(1 << MaxList); i++)
{
// Loop over second group (odds)
for (j=1; j<(1 << MaxList); j++)
{
failed = 0;
pcount = 0;
// check to see whether this group pair satisfies the condition
for (ei=0; ei<MaxList; ei++)
{
if ((1 << ei) & i)
{
pcount++;
thiseven = evens[ei];
qcount = 0;
for (oi=0; oi<MaxList; oi++)
{
if ((1 << oi) & j)
{
qcount++;
thisodd = odds[oi];
thissum = thiseven + thisodd;
// search for ei'th even number plus the oi'th odd number in the prime list
for (k=0; primes[k]<thissum && k<26; k++);
if (primes[k]>thissum || k >= 26)
{
failed=1;
goto failedprimesearch;
}
}
}
}
}
// ignore solutions not as good as best so far
if (pcount+qcount >= bestsofar)
{
bestsofar = pcount+qcount;
printf("P%ld Q%ld sum %ld\n", pcount,qcount,pcount+qcount);
pcount = 0;
// print out the solution
printf("Set P (");
for (ei=0; ei<MaxList; ei++)
{
if ((1 << ei) & i)
{
if (pcount)
printf(",");
pcount++;
printf("%ld", evens[ei]);
}
}
printf(")\n");
qcount = 0;
printf("Set Q (");
for (oi=0; oi<MaxList; oi++)
{
if ((1 << oi) & j)
{
if (qcount)
printf(",");
qcount++;
printf("%ld", odds[oi]);
}
}
printf(")\n\n");
}
failedprimesearch:;
}
}
}
void main(int argc, char **argv)
{
int i,high;
if (argc > 1)
{
high = atoi(argv[1]);
if (high < 5 || high > MaxLen*2)
goto usage;
}
else
{
usage:
printf("Usage: PrimePartition N\n");
printf(" where N is highest number (max %d)\n", 2*MaxLen);
exit(2);
}
for (i=0;i<MaxLen;i++)
{
evens[i] = i*2 + 2;
odds[i] = i*2 + 1;
}
Solve(high/2);
}