This is a read-only snapshot of the ComputerCraft forums, taken in April 2020.
Things's profile picture

Evenly distributing items

Started by Things, 29 April 2014 - 03:11 AM
Things #1
Posted 29 April 2014 - 05:11 AM
Hi all, I'm working on a pretty handy turtle program that I hope will be useful to people, but I'm having a hard time figuring out the most efficient way to go about something.

Basically, I want the turtles inventory to evenly distribute items between slots. Say if you have an iron ingot in slots 2, 3 and 5, and any number of ingots in any of those slots, I'd like to be able to distribute them evenly between all the slots already containing iron ingots. Round robin fashion, basically how the Auto crafting tables would do it.

I have some code already that creates a 2D array of which slots contain items the same as other slots, here:


for i=1,3 do
  if turtle.getItemCount(i) > 0 then
numItems[i] = turtle.getItemCount(i)
for k=1,3 do
  turtle.select(i)
  if turtle.compareTo(k) == true and i ~= k then
   sameItems[i][k] = 1
  else
   sameItems[i][k] = 0
  end
end
for k=5,7 do
  turtle.select(i)
  if turtle.compareTo(k) == true and i ~= k then
   sameItems[i][k] = 1
  else
   sameItems[i][k] = 0
  end
end
for k=9,11 do
  turtle.select(i)
  if turtle.compareTo(k) == true and i ~= k then
   sameItems[i][k] = 1
  else
   sameItems[i][k] = 0
  end
end
  end
end
for i=5,6 do
  if turtle.getItemCount(i) > 0 then
numItems[i] = turtle.getItemCount(i)
for k=1,3 do
  turtle.select(i)
  if turtle.compareTo(k) == true and i ~= k then
   sameItems[i][k] = 1
  else
   sameItems[i][k] = 0
  end
end
for k=5,7 do
  turtle.select(i)
  if turtle.compareTo(k) == true and i ~= k then
   sameItems[i][k] = 1
  else
   sameItems[i][k] = 0
  end
end
for k=9,11 do
  turtle.select(i)
  if turtle.compareTo(k) == true and i ~= k then
   sameItems[i][k] = 1
  else
   sameItems[i][k] = 0
  end
end
  end
end
for i=9,11 do
  if turtle.getItemCount(i) > 0 then
numItems[i] = turtle.getItemCount(i)
for k=1,3 do
  turtle.select(i)
  if turtle.compareTo(k) == true and i ~= k then
   sameItems[i][k] = 1
  else
   sameItems[i][k] = 0
  end
end
for k=5,7 do
  turtle.select(i)
  if turtle.compareTo(k) == true and i ~= k then
   sameItems[i][k] = 1
  else
   sameItems[i][k] = 0
  end
end
for k=9,11 do
  turtle.select(i)
  if turtle.compareTo(k) == true and i ~= k then
   sameItems[i][k] = 1
  else
   sameItems[i][k] = 0
  end
end
  end
end

So in my example with the iron ingots above, the array would contain:

[2][3], [2][5], [3][2], [3][5], [5][2], [5][3] would all be 1, everything else = 0.

Can anyone think of an efficient way of doing this? :)/>
HometownPotato #2
Posted 29 April 2014 - 05:26 AM
Why not just add them all up and divide them by the amount of slots and distribute by that number?
Lyqyd #3
Posted 29 April 2014 - 05:28 AM
This should create a table (matches) wherein each subtable contains a set of slot numbers whose contents all match each other:


local slots = {}
--# fill a table with the sixteen slot IDs.
for i = 1, 16 do
    slots[i] = i
end

local matches = {}

while #slots > 0 do
    --# get the next slot number from the slot ID table
    local current = table.remove(slots, 1)
    --# create a new match set including it.
    local match = {current}
    turtle.select(current)
    --# check the contents of that slot against the remaining unmatched slots.
    for i = #slots, 1, -1 do
        if turtle.compareTo(slots[i]) then
            table.insert(match, table.remove(slots, i))
        end
    end
    --# sort the slot IDs in the current set of matches (optional)
    table.sort(match)
    --# add the current set of matches to the final table.
    table.insert(matches, match)
end
Things #4
Posted 29 April 2014 - 05:39 AM
Hmm, much better way of doing the table, thanks :)/>

Why not just add them all up and divide them by the amount of slots and distribute by that number?

This is what I was thinking, though having a hard time actually putting it into code :(/>
Things #5
Posted 29 April 2014 - 10:56 AM
This should create a table (matches) wherein each subtable contains a set of slot numbers whose contents all match each other:

So I've been messing with your code, and it seems to be doing exactly what I want, however I seem to be having some issues accessing the arrays. The code (set to ingore empty slots)


local slots = {}
--# Fill a table with the sixteen slot IDs.
for i = 1, 16 do
	slots[i] = i
end
local matches = {}
while #slots > 0 do
	--# Get the next slot number from the slot ID table
	local current = table.remove(slots, 1)
	--# Create a new match set including it.
if turtle.getItemCount(current) > 0 then
	local match = {current}
	turtle.select(current)
	--# Check the contents of that slot against the remaining unmatched slots.
	for i = #slots, 1, -1 do
		if turtle.compareTo(slots[i]) then
			table.insert(match, table.remove(slots, i))
		end
	end
	--# Sort the slot IDs in the current set of matches (optional)
	table.sort(match)
	--# Add the current set of matches to the final table.
	table.insert(matches, match)
end
end
for i = 1,#matches do
for k = 1,#matches[1] do
print(string.format("Match %d: %d", i, matches[i][k]))
end
end

Which, with this inventory config, gives me:



Not sure why it's getting stuck on the single entries?

EDIT: Oops, I'm an idiot.


for k = 1,#matches[1] do

should be


for k = 1,#matches[i] do
Edited on 29 April 2014 - 10:18 AM