item resource var stats algorithm .

06/25/2014 17:29 TheSuperKiller#1
while digging in itemresource table especially the stats "varX_X" columns

I can see that the stats are combination of base stats id's .

524288, 8192, 65536, 512, 1024, 128, 256, 2048, 4096, 131072, 262144, 268435457, 134217728, 16777216, 268435456, 33554432, 1048576, 16384, 32768, 1, 2, 16, 32, 4, 8, 2097152, 4194304, 64


and each one represents a stat value in game .
for example .
mdef + pdef = 1536
that means 1024 (mdef) + 512 (pdef)

and so on ,

my goal isn't the combination itself ... it's how to reverse it in seconds .

I used this algorithm and it is so slow for large numbers .

Code:
public class Solver {

    private List<List<decimal>> mResults;

    public List<List<decimal>> Solve(decimal goal, decimal[] elements) {

        mResults = new List<List<decimal>>();
        RecursiveSolve(goal, 0.0m, 
            new List<decimal>(), new List<decimal>(elements), 0);
        return mResults; 
    }

    private void RecursiveSolve(decimal goal, decimal currentSum, 
        List<decimal> included, List<decimal> notIncluded, int startIndex) {

        for (int index = startIndex; index < notIncluded.Count; index++) {

            decimal nextValue = notIncluded[index];
            if (currentSum + nextValue == goal) {
                List<decimal> newResult = new List<decimal>(included);
                newResult.Add(nextValue);
                mResults.Add(newResult);
            }
            else if (currentSum + nextValue < goal) {
                List<decimal> nextIncluded = new List<decimal>(included);
                nextIncluded.Add(nextValue);
                List<decimal> nextNotIncluded = new List<decimal>(notIncluded);
                nextNotIncluded.Remove(nextValue);
                RecursiveSolve(goal, currentSum + nextValue,
                    nextIncluded, nextNotIncluded, startIndex++);
            }
        }
    }
}
Code:
class Program {
    static void Main(string[] args) {

        string input;
        decimal goal;
        decimal element;

        do {
            input = "IN COMBINATION";
        }
        while (!decimal.TryParse(input, out goal));

        input = "524288 8192 65536 512 1024 128 256 2048 4096 131072 262144 268435457 134217728 16777216 268435456 33554432 1048576 16384 32768 1 2 16 32 4 8 2097152 4194304 64";
        string[] elementsText = input.Split(' ');
        List<decimal> elementsList = new List<decimal>();
        foreach (string elementText in elementsText) {
            if (decimal.TryParse(elementText, out element)) {
                elementsList.Add(element);
            }
        }

        Solver solver = new Solver();
        List<List<decimal>> results = solver.Solve(goal, elementsList.ToArray());
        foreach(List<decimal> result in results) {
            foreach (decimal value in result) {
                Console.Write("{0}\t", value);
            }
            Console.WriteLine();
        }


        Console.ReadLine();
    }
}
any ideas ?

*knapsack problem*


btw: I'm interested in raskim new db manager hoping that he has a solution in it :D
06/26/2014 22:54 MrStubborn#2
i think you should look into RappelzItemModder's source
06/26/2014 23:22 TheSuperKiller#3
rappelz item modder takes the info from xml file , that xml file has some basic stats and it doesn't read it from the db reversing the numbers that was taken from ...
that's why it doesn't load stats like 1064960 etc because its not identified in the xml file .
or the solution would be to make a program that takes forever to make the full xml file .
06/27/2014 11:17 mongreldogg#4
Quote:
Originally Posted by TheSuperKiller View Post
rappelz item modder takes the info from xml file , that xml file has some basic stats and it doesn't read it from the db reversing the numbers that was taken from ...
that's why it doesn't load stats like 1064960 etc because its not identified in the xml file .
or the solution would be to make a program that takes forever to make the full xml file .
stats are made as 2^x not as randomly as seems.
you can count combined stat with the following algorithm:

if you have, for example, stat no. 1536, it appears between 1024 and 2048.
and there is a simple math: [combined stat] - [previous non-combined stat] = [second stat].
1536 - 1024 = 512. so you have 1024 (mdef) and 512 (pdef).

example in LUA:
06/27/2014 15:34 TheSuperKiller#5
what about 3 or more stats combined :D that will never work :O
06/27/2014 16:18 mongreldogg#6
Quote:
Originally Posted by TheSuperKiller View Post
what about 3 or more stats combined :D that will never work :O
simple ^_^
make a loop!


and list of general stats as a LUA table is everything you get as well as everything you want:


P.S. youll never get 1 stat twice, thats why every general stat is previous_stat*2
06/20/2018 22:31 TheSuperKiller#7
Just passing by and dropping this after 4 years.

So I decided to revisit this and do something about it.

This is a waaaay more efficient algorithm that uses bitwise operations in lua because loops are very inefficient in this case:

Code:
require "table"
function dump(o)
   if type(o) == 'table' then
      local s = '{ '
      for k,v in pairs(o) do
         if type(k) ~= 'number' then k = '"'..k..'"' end
         s = s .. '['..k..'] = ' .. dump(v) .. ','
      end
      return s .. '} '
   else
      return tostring(o)
   end
end

local tab = {
  {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, },
  {1, 0, 3, 2, 5, 4, 7, 6, 9, 8, 11, 10, 13, 12, 15, 14, },
  {2, 3, 0, 1, 6, 7, 4, 5, 10, 11, 8, 9, 14, 15, 12, 13, },
  {3, 2, 1, 0, 7, 6, 5, 4, 11, 10, 9, 8, 15, 14, 13, 12, },
  {4, 5, 6, 7, 0, 1, 2, 3, 12, 13, 14, 15, 8, 9, 10, 11, },
  {5, 4, 7, 6, 1, 0, 3, 2, 13, 12, 15, 14, 9, 8, 11, 10, },
  {6, 7, 4, 5, 2, 3, 0, 1, 14, 15, 12, 13, 10, 11, 8, 9, },
  {7, 6, 5, 4, 3, 2, 1, 0, 15, 14, 13, 12, 11, 10, 9, 8, },
  {8, 9, 10, 11, 12, 13, 14, 15, 0, 1, 2, 3, 4, 5, 6, 7, },
  {9, 8, 11, 10, 13, 12, 15, 14, 1, 0, 3, 2, 5, 4, 7, 6, },
  {10, 11, 8, 9, 14, 15, 12, 13, 2, 3, 0, 1, 6, 7, 4, 5, },
  {11, 10, 9, 8, 15, 14, 13, 12, 3, 2, 1, 0, 7, 6, 5, 4, },
  {12, 13, 14, 15, 8, 9, 10, 11, 4, 5, 6, 7, 0, 1, 2, 3, },
  {13, 12, 15, 14, 9, 8, 11, 10, 5, 4, 7, 6, 1, 0, 3, 2, },
  {14, 15, 12, 13, 10, 11, 8, 9, 6, 7, 4, 5, 2, 3, 0, 1, },
  {15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0, },
}


function bxor (a,b)
  local res, c = 0, 1
  while a > 0 and b > 0 do
    local a2, b2 = a%16, b%16
    res = res + tab[a2+1][b2+1]*c
    a = (a-a2)/16
    b = (b-b2)/16
    c = c*16
  end
  res = res + a*c + b*c
  return res
end

local ff = 2^32 - 1
function bnot (a) return ff - a end
function band (a,b) return ((a+b) - bxor(a,b))/2 end
function bor (a,b) return ff - band(ff - a, ff - b) end

function getStatsList(combinedStats)
  if combinedStats < 1 or combinedStats > ff then
   return {}
  end
  local num = 1
  local returnTable = {}
  while(num < ff) do
    local andOp = band(num, combinedStats)
    if(andOp == num) then
      table.insert(returnTable, num)
    end
    num = num * 2
  end
  return returnTable
end

print(dump(getStatsList(156849865)))
It took a college degree to get it from O(n^2) to a roughly ~O(1) lol.
06/24/2018 22:37 thund22222#8
ya! the super killer

It's been a long time and you have one of the best servers.

Good luck in your life. :cool: