Not sure if anyone's reading this, but here's where I'm at now.
Permutations are generated and selected for each resource.


# Warning! Running time is sensitive to changes in this number.
NumberOfTilesPerCity = 6

puts "Starting #{Time.now}"

# Generate tiles
NumArray = (1..NumberOfTilesPerCity).to_a
tiles = NumArray.inject([]) { |acc, node| acc + [[rand(4),rand(4), rand(4)]] }

# Calc food required to achieve a pop size
def inc(size)
	10 * 2 ** size - 20 # Or similar
end

# Given a total amount of food, calc current size
def currentSize(food)
	s = 1
	s += 1 while food > inc(s)
	s
end

# Generate combinations
Combinations = NumArray.inject([[]]) { |acc, node| # Combinations (ints)
	acc.inject([]) { |acc, injectedNodes| acc + [injectedNodes,
injectedNodes + [node]] }
}.map { |c|
	c.inject([0,2,1,2]) { |acc, node| # Combinations (tiles)
		(0..2).inject([acc[0].succ]) { |i,n| i + [acc[n.succ] + tiles[node-1][n]] }
	}
}.uniq.sort.inject([]) { |acc, node| # Tranches
	acc + [acc.size <= node[0] ? [node] : acc.pop + [node]]
}.each { |set|
	set.delete_if { |test| # Prune
		set.inject(false) { |acc, comp|
			acc or (!test.equal?(comp) and ((1..3).inject(true) { |i,n| test[n]
<= comp[n] and i } and acc = true))
		}
	}
}

# Generate permutations
class Array
	def permute(i = 0, *a)
		return [a] if i == size
		self[i].map { |x| permute(i+1, *(a + [x])) }.inject([]) { |m,x| m + x }
	end
end
Permutations = Combinations.permute

# Containers to store results
EmptyResult = [0,0,0,0]
bestResult = []
strings = "Pop,Food,Gold,Hammers".split(',')
4.times { |x| bestResult << (EmptyResult.dup << strings[x]) }

# Integrate across t
PermutationResults = Permutations.map { |p|
	result = [1,0,0,0]
	80.times { |t|
		result = [currentSize(result[1])] + (1..3).to_a.inject([]) { |i,n|
			i + [result[n] + p[result[0]][n]]
		}
		result[0] = NumArray.size if result[0] > NumArray.size # Cap size
	}
	result
}.inject(bestResult) { |acc, node|
	ret = acc
	(acc.size).times { |x| ret[x] = node + [ret[x][ret.size]] if node[x]
> ret[x][x] }
	ret
}

# Write results to disk
File::open("output.txt", "w") { |file|
	file << "# Combinations\n"
	Combinations.each { |set|
		set.each { |comb|
			file << " " << comb.join(" ") << "\n"
		}
		file << "\n"
	}

	file << "# Permutations\n"
	Permutations.each { |pset|
		pset.each { |p|
			file << " " << p.join(" ") << "\n"
		}
		file << "\n"
	}
	file << "# Results\n"
	PermutationResults.each { |res|
		file << " " << res.join(" ") << "\n"
	}
}

puts "Finished #{Time.now}"



On 11/2/06, spooq <spoooq / gmail.com> wrote:
> For reasons not clear even to myself, I'm trying to predict the growth and
> production of a city in CivIV (c.f. CivFanatics <http://www.civfanatics.com>
> ).
>
> Each city has an integer population and a number of tiles (actually 20 but
> reduced here to 10 to speed-up testing). Each population point (P) can work
> one tile in a given turn. Tiles have three attributes excitingly named
> F, G and H. I am attempting to enumerate all interesting combinations
> of worked tiles for any given city size. Output is in gnuplot format.
>
> Here's the code (fore!).
>
> puts "Starting #{Time.now}"
>
> numArray = (1..10).to_a
>
> # Generate tiles
> tiles = numArray.inject([]) { |acc, node| acc + [[rand(4),rand(4), rand(4)]]
> }
>
> # Generate unique combinations for given size
> File::open("output.txt", "w") { |file|
>   file << "#P F G H\n"
>   numArray.inject([[]]) { |acc, node|
>     acc.inject([]) { |acc, injectedNodes| acc + [injectedNodes,
> injectedNodes + [node]] }
>   }.collect { |c|
>     c.inject([0,0,0,0]) { |acc, node| [acc[0].succ, acc[1] +
> tiles[node-1][0], acc[2] + tiles[node-1][1], acc[3] + tiles[node-1][2]] }
>   }.uniq.sort.inject(1) { |acc, node|
>     file << "\n" if node[0] == acc
>     file << " " << node.join(" ") << "\n"
>     node[0] == acc ? acc.succ : acc
>   }
> }
>
> puts "Finished #{Time.now}"
>
> My problem is ensuring that only efficient combinations are output. If we
> look at a doctored example...
>
> #P A B C
> 0 0 0 0
>
> 1 0 0 0
> 1 2 0 0            <- This is not interesting,
> 1 2 0 3            <- when this is possible.
> 1 0 1 0            <- However this still is, even though A+B+C is less than
> the line above.
>
> Can anyone suggest a nice golfed algorithm to get rid of the useless
> combinations? Remember that any of the three resources might be deemed most
> important, e.g. 1 1 0 0 is still interesting when 1 0 9 9 exists.
>
> When this bit gets nailed down, the next step is integrating permutations of
> combinations over time and solving for maximum G and/or H, given that
> acquiring enough F will increase P. It's probably best to assume no
> micro-management, i.e. when a city grows, the combination chosen for the new
> size remains in place until the next growth.
>
> Thanks for getting this far, all comments welcome.
>
>