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

Bundle Math

Started by MR_nesquick, 03 August 2013 - 02:53 PM
MR_nesquick #1
Posted 03 August 2013 - 04:53 PM
when you are using rs.getBundledInput(<side>) you are getting a total sum of the color that is on.
is there a formula that's giving me the original color numbers instead off a total sum?


colours.white = 1
colours.orange = 2

if both of theme is turned on i'm getting number 3 as an input, but i want number 1 and 2
theoriginalbit #2
Posted 03 August 2013 - 05:34 PM
as it stands there is no way to get anything other than the number for the bundled cable and that is because of the way it works…

the way a bundled cable has been coded it means that it is on a binary scale of 1 - 32768 for a total of 16 colours… this means that figuring out which colour is turned on is quite easy. Luckily the ComputerCraft developers foresaw the need of us to do this and provided us with a function `rs.testBundledInput(side, colour)` this allows us to do a manual form of checking like so

if rs.testBundledInput( "left", colors.white) then
  print("White is on")
end
if rs.testBundledInput("left", colors.red) then
  print("Red is on")
--# etc for the other colours
end

There are a few other methods to achieve the same output as above, one being looping though 1-16 and using 2^(n-1) on them and then comparing that number (which is on the binary scale) against the input… but the above method is by far the easiest to use…
MR_nesquick #3
Posted 03 August 2013 - 05:42 PM
that's works if only one colour is active. but if there is two or more colours active at once the colour number is either 'red' or 'white'.
theoriginalbit #4
Posted 03 August 2013 - 05:45 PM
whoops sorry. there wasn't meant to be the `elseif ` there, it was meant to be an `if`. edited post :)/>
immibis #5
Posted 03 August 2013 - 08:30 PM

input = rs.getBundledInput("left")
isRedOn = colors.test(input, colors.red)
isBlackOn = colors.test(input, colors.black)
isGreenOn = colors.test(input, colors.green)
-- etc
MR_nesquick #6
Posted 03 August 2013 - 08:45 PM
immibis. what if the input is 'red' and 'green'?
isRedGreenOn = colors.test(input,(colors.red + colors.green))
and what if there is 3 colors active at the same time?
isRedGreenOn = colors.test(input,(colors.red + colors.green + colors.black))
​how many combination is there?
just have to be an easier way to solve this…
Bubba #7
Posted 03 August 2013 - 09:06 PM
SpoilerYou could easily get the colors that are on by doing something like this:

local function getInput(side)
  local input = {} --#Store our input here
  for i=1,16 do --#For every color
	input[2^(i-1)] = rs.testBundledInput(side, 2^(i-1))
  end
  return input
end

local bundledInput = getInput()
if bundledInput[colors.red] and bundledInput[colors.green] then
  print("Red &amp; green on.")
end
Edit: Derp. Just realized that the above function is 100% unnecessary.

Could just do:

if rs.testBundledInput("left", colors.red) and rs.testBundledInput("left",colors.blue) then
  print("Red and green on.")
end
MR_nesquick #8
Posted 03 August 2013 - 09:31 PM
would this work?

for i = 1,#input do
  for i2 = 1,#input do
	if bundledInput[input[i]] and bundledInput[input[i2]] then
	  print(input[i].." &amp; "..input[i2].." is on")
	end
  end
end
it may only print numbers right now, but doing something with that shouldn't be a problem
i have to test it out tomorrow..
immibis #9
Posted 03 August 2013 - 09:39 PM
immibis. what if the input is 'red' and 'green'?
isRedGreenOn = colors.test(input,(colors.red + colors.green))
and what if there is 3 colors active at the same time?
isRedGreenOn = colors.test(input,(colors.red + colors.green + colors.black))
​how many combination is there?
just have to be an easier way to solve this…
Well, you do it individually for each colour, and then you do

isRedGreenOn = isRedOn and isGreenOn
MR_nesquick #10
Posted 03 August 2013 - 10:22 PM
Well, you do it individually for each colour, and then you do

isRedGreenOn = isRedOn and isGreenOn
there is 148 of different color combination when there is 1 or 2 active. do the math for all 16
MR_nesquick #11
Posted 03 August 2013 - 10:45 PM
enigmius1 okey i'm confused. i understand that 1=on 0=off and the number to the left is black and the number to the right is white. but how do i use that i a code? do i save that in a table ? and run it threw a for loop to check if it's 1 or 0? and how do i get the binary code from the input number?
immibis #12
Posted 03 August 2013 - 11:14 PM
What do you actually want to find out from the bundled cable?
MR_nesquick #13
Posted 03 August 2013 - 11:20 PM
What do you actually want to find out from the bundled cable?

witch color is turned on or off, but it have to accept multiple colors
Bubba #14
Posted 03 August 2013 - 11:25 PM
What do you actually want to find out from the bundled cable?

witch color is turned on or off, but it have to accept multiple colors

So what's wrong with this:

if rs.testBundledInput("left", colors.green) and rs.testBundledInput("left", colors.blue) then
  --#stuff
elseif rs.testBundledInput("left", colors.white) then
  --#stuff
end

Or, if you have to respond to each one individually:

if rs.testBundledInput("left", colors.blue) then
 --#stuff
end
if rs.testBundledInput("left", colors.green) then
  --#stuff
end

Or if want to get rid of all those ugly if statements (my favorite):

local response = {
  [colors.green] = function(state)
    --#respond to the state variable, which will be a bool
  end;
  [colors.blue] = function(state)

  end;
}

for i=1,16 do
  if response[2^(i-1)] then --#If the response table has a function corresponding to the color
    response[2^(i-1)](rs.testBundledInput("left", 2^(i-1))) --#Run the function with the cable state as an argument
  end
end
MR_nesquick #15
Posted 03 August 2013 - 11:31 PM

if rs.testBundledInput("back",colors.blue) then
  print("blue")
elseif rs.testBundledInput("back",colors.brown) then
  print("brown")
elseif rs.testBundledInput("back",colors.brown) and rs.testBundledInput("back",colors.blue) then
  print("blue,brown")
else
  print("noop")
end
the problem with this is, as long blue is active it will only print 'blue' because it is the first ting it checks

and how can i make this under 100 lines and still cover all possible color combinations?

if rs.testBundledInput("left", colors.blue) then
--#stuff
end
if rs.testBundledInput("left", colors.green) then
  --#stuff
end
immibis #16
Posted 03 August 2013 - 11:41 PM
If I'm understanding you right, you want a function that:
If white is on and everything else is off, returns white
If orange is on and everything else is off, returns orange
<same for all the other colours>
If white is on, orange is on, and everything else is off, returns ??????
<same for all the other combinations>

What's the ??????
MR_nesquick #17
Posted 03 August 2013 - 11:52 PM
If I'm understanding you right, you want a function that:
If white is on and everything else is off, returns white
If orange is on and everything else is off, returns orange
<same for all the other colours>
If white is on, orange is on, and everything else is off, returns ??????
<same for all the other combinations>

What's the ??????

close. if white is on and everything else is off. i want it to print whats on and whats off on a screen
Bubba #18
Posted 03 August 2013 - 11:58 PM
and how can i make this under 100 lines and still cover all possible color combinations?

if rs.testBundledInput("left", colors.blue) then
--#stuff
end
if rs.testBundledInput("left", colors.green) then
  --#stuff
end
Or if want to get rid of all those ugly if statements (my favorite):

local response = {
  [colors.green] = function(state)
    --#respond to the state variable, which will be a bool
  end;
  [colors.blue] = function(state)

  end;
}

for i=1,16 do
  if response[2^(i-1)] then --#If the response table has a function corresponding to the color
    response[2^(i-1)](rs.testBundledInput("left", 2^(i-1))) --#Run the function with the cable state as an argument
  end
end
MR_nesquick #19
Posted 03 August 2013 - 11:59 PM

binary = {0,0,0,0,0,0,0,0.....}

if rs.testBundledInput("left", colors.white) then
  binary[16] = 1
else
  binary[16] = 0
end

if rs.testBundledInput("left", colors.orange) then
  binary[15] = 1
else
  binary[15] = 0
end

for i = 1,#binary do
  if binary[i] = 1 then
   --do stuff
  end
end



something like this?
immibis #20
Posted 04 August 2013 - 12:01 AM
If I'm understanding you right, you want a function that:
If white is on and everything else is off, returns white
If orange is on and everything else is off, returns orange
<same for all the other colours>
If white is on, orange is on, and everything else is off, returns ??????
<same for all the other combinations>

What's the ??????

close. if white is on and everything else is off. i want it to print whats on and whats off on a screen

Well then, what's wrong with what I said before, and then printing the result?


input = rs.getBundledInput("left")
isRedOn = colors.test(input, colors.red)
isBlackOn = colors.test(input, colors.black)
-- repeat for other colours
if isRedOn then print("red: on") else print("red: off") end
if isBlackOn then print("black: on") else print("black: off") end
-- repeat for other colours

(note: this code is deliberately simple and inefficiently long [as in, it would take a while to type, and doesn't use loops or tables to be smaller, but shows the concept well])
Bubba #21
Posted 04 August 2013 - 12:08 AM

binary = {0,0,0,0,0,0,0,0.....}

if rs.testBundledInput("left", colors.white) then
  binary[16] = 1
else
  binary[16] = 0
end

if rs.testBundledInput("left", colors.orange) then
  binary[15] = 1
else
  binary[15] = 0
end


something like this?

No… How would that help you at all? That would practically be the same as just checking every single one individually.

Okay so I think I understand what you want now. You want to be able to respond to different combinations of inputs, not just each individual input. In that case, maybe you can have a combination table like this:

local combos = {
  [1] = {
    colors.red, colors.blue, colors.green,  --#So these would be stored as numerical indexes, meaning that we could unpack them without issue
    func = function() --#This is not a numerical index, so it would not be unpacked
      print("red blue and green on")
    end
  };
  [2] = {
    colors.white, colors.orange, colors.yellow,
    func = function()
      print("white orange and yellow on")
    end
  };
}

And then parse it like this:

local function testMultipleInputs(...) --#Takes any number of arguments and tests whether the 
  --#inputs are true or not. If any one of them is false, the function returns false.
  local args = {...}
  for i=1,#args do
   if not rs.testBundledInput(args[i]) then
     return false
   end
  end
  return true
end

for i=1,#combos do --#For every combo
  if testMultipleInputs(unpack(combos[i])) then --Check if all the inputs are true
    combos[i]["func"]() --#If they are then execute the function associated with the combo.
  end
end
MR_nesquick #22
Posted 04 August 2013 - 12:19 AM
what i want is. you got 2 levers. one is on color white the other one is on color orange. if you flip the lever on white cable i want the computer to say 'white is active'. and when i flip the lever on the orange cable i want the computer to say 'white and orange is active'. if you turning off the lever on the white cable, the computer will show 'orange is active'….. if you got a 3rd lever it will show as a different color on the computer.
that's basically what i want

well going too bed..
Bubba #23
Posted 04 August 2013 - 12:26 AM
Okay. So essentially combos, but not predefined combos. Gotcha'.


local currentlyActive = {}
local colorCodes = {
  [1] = "white";
  [2] = "orange";
  [4] = "magenta";
  [8] = "lightBlue";
  --#You get the gist. You can see the rest of these under rom/apis/colors
}

for i=1,16 do
  if rs.testBundledInput("left", 2^(i-1)) then
    table.insert(currentlyActive, colorCodes[2^(i-1)])
  end
end

local function printInput()
  for i=1,#currentlyActive do
   write(currentlyActive[i].." is active, ")
  end
end

printInput()
reububble #24
Posted 04 August 2013 - 08:01 AM

-- there should be an API for this
function parts(bin)
  ret = {}
  for i=1,16 do
   if bin%2^i>=2^i then
	table.insert(ret,i)
   end
  end
  return ret
end
-- you would want to call this
parts(rs.getBundledInput('left'))
-- and get this
{1,2}

Or something like that?
ZagKalidor #25
Posted 04 August 2013 - 02:10 PM
Why not do it on a mathematical way, since every color can be on just once, you could substract the next lower color value of the sum. If there is a rest above zero the color is on. Lets take maybe 33537. You sub the next lower that is 32768. Now rest is 769. Now you know - black is on. Next lower to 769 is 512. Rest is 257. Ok, we know 512 is on, whatever the hell this color is. Now we come to 256 is on and one is on. Color 32768 is true and so on…

Edit: when finally zero is reached, you know you got them all..
immibis #26
Posted 04 August 2013 - 07:15 PM
Why not do it on a mathematical way, since every color can be on just once, you could substract the next lower value of the sum. If there is a rest above zero the color is on. Lets take maybe 33537. You sub the next lower that is 32768. Now rest is 769. Now you know - black is on. Next lower to 769 is 512. Rest is 257. Ok, we know 512 is on, whatever the hell this color is. Now we come to 256 is on and one is on. Color 32768 is true and so on…

Edit: when finally zero is reached, you know you got them all..
Why not do it in an understandable way, and use colors.test?
ZagKalidor #27
Posted 04 August 2013 - 07:52 PM
What is inunderstandable with my thought?

You ask for something to be true or not and i count for the same. I think we both have the same lag…
immibis #28
Posted 04 August 2013 - 07:56 PM
You're overcomplicating things. colors.test exists. Use it.
ZagKalidor #29
Posted 04 August 2013 - 08:18 PM
Your checking something to be something and if it is so, print something. This would take 32 lines of code. Maybe it can be done in less lines?
immibis #30
Posted 05 August 2013 - 02:13 AM
Yes, it could be done with a loop. I was going for simplicity as usual. If the OP understands loops he can translate it into a loop himself.