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

Check For Closest Number

Started by valithor, 01 September 2013 - 01:29 PM
valithor #1
Posted 01 September 2013 - 03:29 PM
I was wondering if there is a way to compare multiple numbers to see which is closest to a target number. If there is not a single command if someone can point me in the direction of something that would work. Or if nothing of this sort exists that i will just have to come up with something creative to solve this problem.
theoriginalbit #2
Posted 01 September 2013 - 03:37 PM
There is no already implemented solution. As such you would need to create something… But first things first, how would you deal 2 or 3 numbers being the same distance apart? Assume we have this

num = 3
other = 1, 2, 2, 2, 3
What would be the closest? 2 or 2,2,2?

Now assume we also have the following
num = 3
other = 1, 2, 4
What would be the closest? 2 or 4?

And lastly
num = 3
other = 1, 2, 3, 4, 5
What would be the closest? 3?
valithor #3
Posted 01 September 2013 - 03:57 PM
There is no already implemented solution. As such you would need to create something… But first things first, how would you deal 2 or 3 numbers being the same distance apart? Assume we have this

num = 3
other = 1, 2, 2, 2, 3
What would be the closest? 2 or 2,2,2?
all 3 of them

Now assume we also have the following
num = 3
other = 1, 2, 4
What would be the closest? 2 or 4?
2 and 4 would be closest for what i am trying to do

And lastly
num = 3
other = 1, 2, 3, 4, 5
What would be the closest? 3?
3 would be closest

The way i am doing this shortly described below deals with numbers much higher than those, and there will be very little repetition or 2 numbers being the same distance from the target.

What i am attempting to make is error checking function for my better edit program. The way i am doing this is using the string.byte built in api then gathering the top 5 or so results with the closest being on the top, if 2 are equal distance then it will just be the first one that occurs in the table that it is comparing to. There is probably a better way to do what i am trying to do but i feel as if i should write my own code and figure it out for myself if i am making it for my program.

Thx for the response i highly doubted the something like that existed
theoriginalbit #4
Posted 01 September 2013 - 04:03 PM
Yeh you're definitely going to have to write your own. Make a function, that accepts varargs

local function someName(...)
  --# code here
end
Varargs can be accessed via the predefined table `args` or by making it yourself via `{…}`

then just loop through this table, and return the closest value (keeping in mind the rules you just stated above to my quote).
valithor #5
Posted 01 September 2013 - 04:46 PM
Yeh you're definitely going to have to write your own. Make a function, that accepts varargs

local function someName(...)
  --# code here
end
Varargs can be accessed via the predefined table `args` or by making it yourself via `{…}`

then just loop through this table, and return the closest value (keeping in mind the rules you just stated above to my quote).

I just thought of this, I have not tested it and do not even know if it will work. Whatever i post here will almost 100% not be the final product.


starting = {
"124",
"15",
}
target = 90
temp = 0
temp2 = 0
function findDistance() -- finds distance from target
  for i = 1, #starting do
	if starting[i] > target then
	  while starting~= target do
		temp = temp+1
		starting = starting-1
		temp2 = temp2+1
	  end
	elseif starting[i] < target then
	  while starting ~= target do
		temp = temp+1
		starting = starting+1
		temp2=temp2+1
	elseif starting[i] == target then
	  temp = 0
	  temp2=temp2+1
	end
	table.insert(distance,temp2,temp)
  end
end

This is only partially finished but that will find the distance from the target number I am probably going to use the table.sort command to be able to see which is closest. In order to use the sort function i will have to use ALOT of comparing in a inefficient way. None of that code above has been tested and probably does have errors.

This after editing has ALOT of errors i have fixed them and this part of the code works exactly as wanted
Edited on 01 September 2013 - 04:48 PM
Vilsol #6
Posted 01 September 2013 - 06:19 PM
I am writing a code for this right now.
I will edit this post when done!

Here is my version:


number = 32
others = {1, 432, 30, 432, 234, 65, 42, 76, 73}

function findClosest(num, other)
	if(type(other) == "number")then
		return other;
	end
	closest = other[1]
	closeamount = num - closest
	for id, tar in pairs(other) do
		if(num - tar < closeamount)then
			if(num - tar > 0)then
				closest = tar
				closeamount = num - tar
			else
				check = (num - tar) * -1
				if(check < closeamount)then
					closest = tar
					closeamount = check
				end
			end
		end
	end
	return closest 
end

print(findClosest(number, others))
Edited on 01 September 2013 - 04:35 PM
H4X0RZ #7
Posted 01 September 2013 - 06:22 PM
Here, this is my idea (sorry if there are typos, i'm on my mobile):

local function getNearest(target, list)
  local tempLNearest, tempRNearest = 0,1000000
  for k,v in pairs(list) do
    if v > tempLNearest and v <= target then
      tempLNearest = v
    elseif v < tempRNearest and v >= target then
      tempRNearest = v
    end
  end
  return tempLNearest,tempRNearest
end

--Example usage
local list = {1,3,5,7,9,11,13}
local target = 6
term.clear()
print("LIST")
print(table.concat(list,","))
print("")
print("TARGET")
print(target)
print("")
print("FOUND")
local n1,n2 = getNearest(target,list)
print(n1,",",n2)
theoriginalbit #8
Posted 01 September 2013 - 07:15 PM
Ok since Freack posted a solution, I may as well post one too. So here it is.

local function getClosest(target, ...)
  --# temp variable which will store the number and its distance from the target
  local info = {}
  --# loop through the numbers supplied
  for _,v in ipairs(arg) do
	--# insert it into the table with the distance it is from the target, in whole positive numbers
	table.insert(info, {v, math.abs(target-v)})
  end
  --# sort the table, based on the distances from the target
  table.sort(info, function(a,B)/>/> return a[2] < b[2] end)
  --# create a new table for the return values
  local ret = {}
  --# loop through the newly sorted info table
  for i,v in ipairs(info) do
	--# put the value into the ret table in the same order it was in the sorted table
	ret[i] = v[1]
  end
  --# unpack the table into the return results
  return unpack(ret)
end

And it would be used like so

--# get just the one closest number
local c1 = getClosest(5, -10, 15, -5, -1, -2, 11, -3, 10, 15, 30)

--# get 3 of the closest numbers
local c1, c2, c3 = getClosest(5, -10, 15, -5, -1, -2, 11, -3, 10, 15, 30)

--# get all the numbers in order based on the distance
local order = { getClosest(5, -10, 15, -5, -1, -2, 11, -3, 10, 15, 30) }