Ruby divide array in three equal sum

Write a program which has an array of diamonds with different value e.g. [1,2,3,4,5]. The program should distribute the diamonds equally to 3 people.

person 1 : 5
person 2 : 3,2
person 3 : 4,1

a = []
b = []
c = []

bag = [1,2,3,4,5]
bag = bag.sort { |a, b| b <=> a }

no = bag.len

sum = bag.sum
distribute = sum / 3
distribute

bag.each_with_index do val|index|

a = bag.each.with_index { |val,index|}

a = bag.each.with_index { |val,index|puts “index: #{index} for #{val}”}
for i in bag
if i == distribute
a.append(i)
bag.delete(i)
puts (a)
a = []
else
for i in bag.reverse do
a = a.sum + i
if a == distribute
a.append(i)
bag.delete(i)
puts (a)
a = []
end
end
end
end

The problem is not so easy o resolve :slight_smile:

Here a solution, with Simulated annealing algorithm.

############# Simulated annealing definitions
l=(1..20).to_a  # list of value
$size=l.size

#---------  make initial solution
aa=[[],[],[]]  # decompose l in 3 lists
aa[rand(0...aa.size)] <<  l.delete_at(rand(l.size)) while l.size>0

#-- add empty value (lists can have different size...)
aa.each {|a| a.concat([0]*(1+a.size/4))}

#--------- function to optimize :  sum of each listes should be near equals 
def performence(aa)
  res=aa.map {|l| l.reduce(0,:+) }
  -1.0*res.combination(2).map { |a,b|  (a-b)**2 }.reduce(0,:+)
end

#-------  Acceptance probabilities
# could be best :)
def opt(delta,temp)
 rand(100)<temp/2
end

############################################################
#   Simulated annealing Algorithm
############################################################

################## 
def choose(n,diff)
 i=diff
 i=rand(0...n) while i==diff
 i
end

def permute(array,from,to)
	array[from.first][from.last],array[to.first][to.last]=
		array[to.first][to.last],array[from.first][from.last]
end

last_perf=0
puts "initale perf=%f" % performence(aa)
100.downto(0) { |temp|
  (400*$size).times { |r|
	i1=choose(aa.size,-1)
	i2=choose(aa.size,i1)
	ii1=choose(aa[i1].size,-1)
	ii2=choose(aa[i2].size,-1)
	permute(aa,[i1,ii1],[i2,ii2])
	perf=performence(aa)
	delta=perf-last_perf
	if delta<0
		if opt(delta,temp) 
			#puts("xxtemp=%4d => perf=%6f" % [temp,perf]) if r%300>=0
			last_perf=perf
		else
			permute(aa,[i1,ii1],[i2,ii2]) # undo
		end
	else
		if delta>0
			#puts("**temp=%4d => perf=%6f/%6f" % [temp,perf,last_perf]) if r%300>=0
			last_perf=perf
		else
			permute(aa,[i1,ii1],[i2,ii2]) # undo
		end
	end
  }
}
puts "\n\nperf=%d" % performence(aa)
aa.each {|a| puts "(%4d) <= %s" % [a.reduce(0,:+),a.select {|x|x>0}.sort.inspect] }

Example of execution:

initale perf=-12462.000000


perf=0
(  70) <= [10, 11, 14, 15, 20]
(  70) <= [1, 3, 4, 5, 6, 8, 12, 13, 18]
(  70) <= [2, 7, 9, 16, 17, 19]

Please, use triple-backcote ( ``` ) for writing code n this forum :wink: