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

Inventory Compaction!

Started by Engineer, 28 February 2013 - 03:44 AM
Engineer #1
Posted 28 February 2013 - 04:44 AM
Hi,

I needed a program for myself so that the turtle can sort its inventory. I dont thinks it is optimal, but you guys should leave suggestions to optimize it!
I decided to release it because I havent found any inventory sorters, however I have found sorters, but those dont do what want them to do :)/>

A video to demonstrate what it actually does:

[media]http://www.youtube.com/watch?v=mVEnRNGJQps[/media]

Please leave suggestions and feedback

Thanks to theOriginalBIT and happydude11209 for recreating the code after losing it.
The code on pastebin: http://pastebin.com/pKjXFbjW

Hey, I have found the original code! : http://pastebin.com/DDtCXQm2

Thanks,

Engineer
Edited on 31 March 2013 - 09:42 PM
shiphorns #2
Posted 28 February 2013 - 05:28 AM
You might have been searching for the wrong key words. What your script is doing is not what people in computer science most commonly describe as 'sorting', because your program does not make an effort to put stacks of like items into adjacent slots. Your code preserves relative ordering. So, you could end up with a full stack of cobble in slot 1, then some gravel in slot 2, then more cobble in slot 3… which is not what people typically consider 'sorted'. You can't see this in your Youtube examples, only because you don't have more than 64 of any particular item.

What you're doing would be more accurately described as inventory compaction, or consolidation. You're consolidating to a minimum number of stacks, to get the most free inventory slots.
Engineer #3
Posted 28 February 2013 - 05:33 AM
You might have been searching for the wrong key words. What your script is doing is not what people in computer science most commonly describe as 'sorting', because your program does not make an effort to put stacks of like items into adjacent slots. Your code preserves relative ordering. So, you could end up with a full stack of cobble in slot 1, then some gravel in slot 2, then more cobble in slot 3… which is not what people typically consider 'sorted'. You can't see this in your Youtube examples, only because you don't have more than 64 of any particular item.

What you're doing would be more accurately described as inventory compaction, or consolidation. You're consolidating to a minimum number of stacks, to get the most free inventory slots.
Thanks for the input. I will rename the program :)/>
CupricWolf #4
Posted 29 March 2013 - 07:33 PM
pastebin link is broken
Engineer #5
Posted 30 March 2013 - 12:40 AM
pastebin link is broken
Thats unfortunate. I seem to have lost that code also :/
theoriginalbit #6
Posted 30 March 2013 - 01:10 AM
Thats unfortunate. I seem to have lost that code also :/
I'm assuming it would just be something along these lines?
Spoiler

function sortInv()
  for i = 1, 16 do
	if turtle.getItemSpace(i) > 0 then
	  turtle.select(i)
	  for j = i, 16 do
		if turtle.compareTo(j) then
		  turtle.transferTo(i, turtle.getItemCount(j))
		end
	  end
	end
  end
end
Engineer #7
Posted 30 March 2013 - 03:28 AM
Thats unfortunate. I seem to have lost that code also :/
I'm assuming it would just be something along these lines?
Spoiler

function sortInv()
  for i = 1, 16 do
	if turtle.getItemSpace(i) > 0 then
	  turtle.select(i)
	  for j = i, 16 do
		if turtle.compareTo(j) then
		  turtle.transferTo(i, turtle.getItemCount(j))
		end
	  end
	end
  end
end
Yup, I saw the a post the other day wich was basically that code. Wanted to post this.. but I deleted it on pastebin & pc :/
CupricWolf #8
Posted 31 March 2013 - 09:44 PM
:/ darn
theoriginalbit #9
Posted 31 March 2013 - 09:46 PM
:/ darn
what is darn?
CupricWolf #10
Posted 31 March 2013 - 10:09 PM
Thats unfortunate. I seem to have lost that code also :/
I'm assuming it would just be something along these lines?
Spoiler

function sortInv()
  for i = 1, 16 do
	if turtle.getItemSpace(i) > 0 then
	  turtle.select(i)
	  for j = i, 16 do
		if turtle.compareTo(j) then
		  turtle.transferTo(i, turtle.getItemCount(j))
		end
	  end
	end
  end
end
your code's a bit off, I added two lines to make it work
Spoiler

function sortInv()
  for i = 1, 16 do
	if turtle.getItemSpace(i) > 0 then
	  turtle.select(i)
	  for j = i, 16 do
		if turtle.compareTo(j) then
		  turtle.select(j)
		  turtle.transferTo(i, turtle.getItemCount(j))
		  turtle.select(i)
		end
	  end
	end
  end
end

darn is I was hoping to download this in pastebin lol, its a soft form of "damn" the curse word

EDIT: This post seems really condescending after reading it again, I'm sorry >_>
CupricWolf #11
Posted 31 March 2013 - 10:21 PM
http://pastebin.com/K0RUL27B
if you want to see my version, I think I got close to the original functionality from the video. Sorry if I am overstepping any lines, if you don't want me to have my version please let me know, no harm was meant by writing that code, I know I didn't really get permission.
theoriginalbit #12
Posted 31 March 2013 - 10:27 PM
your code's a bit off, I added two lines to make it work
you can remove the
turtle.select(i)
after transferring… the code I wrote will do the select(i) I had just forgotten the select(j). I wrote it in ~5 seconds should have proof read it first :P/> thanks. good pickup.
CupricWolf #13
Posted 31 March 2013 - 10:50 PM
your code's a bit off, I added two lines to make it work
you can remove the
turtle.select(i)
after transferring… the code I wrote will do the select(i) I had just forgotten the select(j). I wrote it in ~5 seconds should have proof read it first :P/> thanks. good pickup.
You're welcome :)/> thanks for telling me about select(i) I hope you don't mind that I used your function in my version of the program :)/>
theoriginalbit #14
Posted 31 March 2013 - 10:55 PM
You're welcome :)/> thanks for telling me about select(i) I hope you don't mind that I used your function in my version of the program :)/>
I don't mind. I posted it here for a reason. :P/>
CupricWolf #15
Posted 31 March 2013 - 11:05 PM
After removing that second turtle.select(i) I run in to some issues with multiple stacks of the same type of block, when I run it it compacts the first stack but since it's still inside the for j = i,16 loop it hasn't done turtle.select(i) and it does the rest of the comparisons to the empty slot that was just created. It seems that that second turtle.select(i) is needed.
theoriginalbit #16
Posted 31 March 2013 - 11:24 PM
After removing that second turtle.select(i) I run in to some issues with multiple stacks of the same type of block, when I run it it compacts the first stack but since it's still inside the for j = i,16 loop it hasn't done turtle.select(i) and it does the rest of the comparisons to the empty slot that was just created. It seems that that second turtle.select(i) is needed.
Ahh i see. nvm me then :P/>
Engineer #17
Posted 31 March 2013 - 11:29 PM
Edited OP, credits go to theOriginalBIT and happydude11209, thanks guys! :)/>
I guess I was just to lazy for recreating the code :P/>

Edit: Found original code, added to OP
theoriginalbit #18
Posted 01 April 2013 - 12:13 AM
Edit: Found original code, added to OP
Now make it sort. so similar items are grouped together as well :P/>
CupricWolf #19
Posted 01 April 2013 - 09:13 AM
Now make it sort. so similar items are grouped together as well :P/>
Shouldn't be too hard, move everything to the last slots rather than the first then move to one stack to the first, then check to see if there are other stacks like it, add each afterwards then repeat with all types. I'll get cracking on this right now!

EDIT: it was way harder then I thought it would be lol
Edited on 01 April 2013 - 11:58 AM
CupricWolf #20
Posted 01 April 2013 - 01:41 PM
I think I have it, it isn't very clean or optimized but it truly sorts the items together. I will try to optimize later but t took long enough to get working lol. Please give suggestions, and report bugs. Same pastebin link http://pastebin.com/K0RUL27B. I've only tested it with a small sample but it works with that, and I'm sure it will work with other things too, I'm not sure how well the program will work with a nearly full or full inventory.

EDIT: It doesn't like a full inventory, it also doesn't work very well when there are multiple stacks and the last stack isn't completely full. :/
It works the best when it is half full or less, otherwise there isn't enough spaces to move items around with. There are special cases that work with up to one open slot (all the same item). But for the most part this requires only a half full inventory or less :(/> but still sorting! :D/>
And because turtle.transferTo() returns true even if only part of the stack gets moved it leaves partial stacks behind during the clean up phase, which messes up the sort phase.

EDIT: EDIT: I changed the beginning of the if statement to be a while loop with the same condition in the clean up phase, and, taa-daa, the clean up makes sure that every part of the stack gets moved to the end of the inventory!

EDIT: EDIT: EDIT: I have an idea about how to get the program to work when it is more than half full, but it needs at least one open slot, and it will take a complete rewrite of my sorting phase :(/> I will make a new post once it is done.
theoriginalbit #21
Posted 01 April 2013 - 03:49 PM
I have an idea about how to get the program to work when it is more than half full, but it needs at least one open slot, and it will take a complete rewrite of my sorting phase :(/> I will make a new post once it is done.
Use turtle.dropUp() so that it drops onto itself (incase its over a hole or lava) then sort and use suck. granted the last item wont be sorted, but its harder with a full inv.
CupricWolf #22
Posted 01 April 2013 - 05:10 PM
I have an idea about how to get the program to work when it is more than half full, but it needs at least one open slot, and it will take a complete rewrite of my sorting phase :(/> I will make a new post once it is done.
Use turtle.dropUp() so that it drops onto itself (incase its over a hole or lava) then sort and use suck. granted the last item wont be sorted, but its harder with a full inv.
What if it's under lava? But I do like that Idea :)/>
theoriginalbit #23
Posted 01 April 2013 - 05:24 PM
What if it's under lava? But I do like that Idea :)/>
then you are doomed :P/>
CupricWolf #24
Posted 01 April 2013 - 06:36 PM
I keep running into problems, this is insanely difficult :(/>

EDIT: By this time I have already tried two different sort phases and still no luck, neither even work let alone work better than the current method :(/>

EDIT: EDIT: I think I may have it! Let me test out a few more cases and I will post the code to a new pastebin. From the tests I've done though, it's really slow :(/>

EDIT: EDIT: EDIT: Hmmm, it seems to only sort two stacks of the same block out, if there is a third or more those will be left in their place, this is even more obvious on already sorted inventories. But it's late here and I have school in the morning, plus it works way better than it used to so I'm gonna call it a night. pastebin for the code as it is now is http://pastebin.com/62YBW1y1 if anybody wants to take a look and see if they can fix it :)/>
Edited on 01 April 2013 - 06:42 PM
CupricWolf #25
Posted 01 April 2013 - 09:08 PM
I think I got it, there are still some random bugs to iron out but I can kill them in the morning when my mind is refreshed. Pastebin for the full inventory sorter http://pastebin.com/62YBW1y1. I've speed it up and it works up until the final steps, I will have to look tomorrow for where it is getting stuck in an infinite loop with the test inventory I was using (three stacks of each log type and a stack of each leaf type in random order, sometimes froze when sorting).
theoriginalbit #26
Posted 01 April 2013 - 09:10 PM
I think I got it, there are still some random bugs to iron out but I can kill them in the morning when my mind is refreshed. Pastebin for the full inventory sorter http://pastebin.com/62YBW1y1. I've speed it up and it works up until the final steps, I will have to look tomorrow for where it is getting stuck in an infinite loop with the test inventory I was using (three stacks of each log type and a stack of each leaf type in random order, sometimes froze when sorting).
Maybe Engineer can have a look and try fix it while you're asleep…
CupricWolf #27
Posted 01 April 2013 - 09:17 PM
I think I got it, there are still some random bugs to iron out but I can kill them in the morning when my mind is refreshed. Pastebin for the full inventory sorter http://pastebin.com/62YBW1y1. I've speed it up and it works up until the final steps, I will have to look tomorrow for where it is getting stuck in an infinite loop with the test inventory I was using (three stacks of each log type and a stack of each leaf type in random order, sometimes froze when sorting).
Maybe Engineer can have a look and try fix it while you're asleep…
Sounds good, it still has issues while trying to sort more than two stacks of an item. It properly does the first two stacks (inside the for loop) but only does the third stack if it is in the right place to be sorted next (outside the for loop). If you take a look at my code the for loop I'm talking about is in sortInv()


sortsMade = 0
while sortsMade <= 16 do
turtle.select(16)
openSlot = getNextUnsorted()
turtle.transferTo(openSlot, turtle.getItemCount(16))
slotsFinished[openSlot] = true
cleanInv(16, getNextUnsorted(), -1)
sortsMade = sortsMade + 1
for checkSlot = 16, openSlot, -1 do -- THIS IS THE FOR I WAS TALKING ABOUT
if checkSlot == (getNextUnsorted()) then
break
end
turtle.select(openSlot)
if turtle.compareTo(checkSlot) then
turtle.select(checkSlot)
while turtle.getItemCount(checkSlot) > 0 do
moveSlot = openSlot + 1
while not turtle.transferTo(moveSlot, turtle.getItemCount(checkSlot)) do
moveSlot = moveSlot + 1
end
end
slotsFinished[moveSlot] = true
cleanInv(checkSlot, getNextUnsorted(), -1)
sortsMade = sortsMade + 1
checkSlot = 16
end
end
punchin #28
Posted 03 April 2013 - 12:32 AM
About halfway through the thread (before you added sorting), I decided to take a stab at this. About an hour later, I was finished. Continued the thread and found out you had added sorting already. Downloaded yours and took a look at it. It's shorter than mine by 27 lines, but mine was a lot faster. I did find a part in yours that I found sped mine up a bit, too. Your line 3 where you check to see if there is anything in the slot before you check to see if anything stacks with it was genius. It added 2 lines to mine, but cut up to about 30 seconds off if the inventory is small.

Here's what I came up with: http://pastebin.com/AqukeQKf

Tested it with the following inventory randomized: 2 stacks of coal, 2.5 stacks of redwood logs, 2.75 stacks of bonemeal, and 2 stacks of redwood saplings.

Ran it through several times and it sorted it right each time.
CupricWolf #29
Posted 08 April 2013 - 07:07 AM
About halfway through the thread (before you added sorting), I decided to take a stab at this. About an hour later, I was finished. Continued the thread and found out you had added sorting already. Downloaded yours and took a look at it. It's shorter than mine by 27 lines, but mine was a lot faster. I did find a part in yours that I found sped mine up a bit, too. Your line 3 where you check to see if there is anything in the slot before you check to see if anything stacks with it was genius. It added 2 lines to mine, but cut up to about 30 seconds off if the inventory is small.

Here's what I came up with: http://pastebin.com/AqukeQKf

Tested it with the following inventory randomized: 2 stacks of coal, 2.5 stacks of redwood logs, 2.75 stacks of bonemeal, and 2 stacks of redwood saplings.

Ran it through several times and it sorted it right each time.
Thank you for trying this yourself :)/> it always helps to have multiple people trying to do the same thing. I'm glad your code benefited from mine :)/> I'll take a look at yours and see if I can use some of yours. I must say after running your program only once without looking at your code I am very impressed, it murdered the test inventory that I used to break my programs (2.5 stacks of each (vanilla) type of wood, plus one stack of 3 of the 4 types of leaves) about 30% faster (with no errors!)! I did run into a problem when the inventory had no open slots after compressing. It threw "attempt to call nil" on line 42 after I took out a stack and pressed enter.

EDIT: The error is thrown because lua needs functions to be defined earlier in the file than they are called and "space()" is called 3 lines above where it is defined when it is called on line 42

EDIT: EDIT: Your code is very effective and looking at is leaves me impressed. We took somewhat different approaches, yours being both faster and better working. I think I will stop developing my code and just use yours :)/> Sometime when I have more time I might eventually try to debug mine and optimise it.

EDIT: EDIT: EDIT: I see a catch 22, space() calls vSpace() and vSpace() calls space() I'm not sure how to alleviate this. If space is put first it will throw an error trying to call vSpace(). After thinking about it, why not put vSpace()'s code into space()? I know it's kind of a kludge but it works in tests I've run



local function space()
    print("Checking for available space")

    s = 0

    for i=1,16 do
        if turtle.getItemCount(i) == 0 then
            s = 1
            l = i-1
            break
        end
    end
    -- vSpace()
    if s == 1 then
        print("Verified space")
        return
    else
        print("Not enough space. Please clear at least 1 slot and press enter")
        read()
        space()
    end
end
Edited on 08 April 2013 - 05:25 AM