I thought I'd give #4 a try. With my generic script the config is:
{"challenge": ["with name 'D1' find 9 caches with unique terrain where type == 'Traditional Cache' and difficulty == '1.0'.",
"with name 'D5' find 9 caches with unique terrain where type == 'Traditional Cache' and difficulty == '5.0'.",
"with name 'T1.5' find 9 caches with unique difficulty where type == 'Traditional Cache' and terrain == '1.5'.",
"with name 'T2.5' find 9 caches with unique difficulty where type == 'Traditional Cache' and terrain == '2.5'.",
"with name 'T3.5' find 9 caches with unique difficulty where type == 'Traditional Cache' and terrain == '4.5'.",
"with name 'T4.5' find 9 caches with unique difficulty where type == 'Traditional Cache' and terrain == '4.5'.",
"output groups including empty with totals.",
"output table gccode, cache_name as 'Name', difficulty, terrain." ]}
Though I admit that the output doesn't make it easy to see which ones you still need to get (you could get that by listing each combination individually:
{"challenge": [
"with name '5/1' find a cache where type == 'Traditional Cache' and difficulty == '5.0' and terrain == "1.0".",
...
]}
But that would end up being 5Kb.