37

When you have to spend two days inventing math formulas for work because google won't tell you how to sort every possible combination of an array of arrays into a zero based number list, or how to get a combination from just it's index.

Comments
  • 1
    I know that it's not exactly the same (or maybe I'm wrong) but you may be interested in Gray codes or de Brujin codes
  • 1
    @beriba
    Thanks, but i do not believe this is the same issue, same ish, but different.

    An example of my problem is this. lets say you sell boxes;
    They can have options like, size, color, weight, etc.

    You don't know how many options a brand of box will have, or how many values each option will use. But you want to output a list of every combination, and index those combinations so you can set a unique attribute to each group, like price.

    So
    Blue, red
    Big, small
    Will output
    0:bl/sm
    1:bl/bg
    3:r/sm
    4:r/bg

    I can then set;
    0: $1
    1: $7
    2:$6
    3: $10

    I can use the algorithm I came up with to get the values from the index, or the index from the values.

    I needed something dynamic because options and values can change, be added, or removed.
  • 4
    @nerd-san In that case it is easier to use a bitmask. Let's say you have 10 attributes. You can represent them as 0001010001, where 0 means no attribute and 1 means the attribute is present. Then you can convert this binary to decimal which in this case is 81 and this is your index. The only problem with this is large number of attributes but your algorithm will have the same problem
  • 1
    @beriba he said the attributes can be non-binary.
  • 1
    @beriba and you can't just use base 3 or 4 Etc because each attribute may have a different number of possible settings.
  • 2
    @thejohnhoffer But you can always make them binary. For example if you have 4 colors you represent them as 0010, which will be the part of the whole attribute binary, instead of representing it as 2 in the custom attribute string. The reason is that the binary has fixed number of values on a single position so adding new attribute on the most significant bit won't mess up backwards compatibility. If you use base-5 numeral system, 5 values may not be enough (there are much more colors), so how to choose the base? 10? 20? You don't know how business requirements will look like in the future. Maybe one attribute will have 25 values and other attributes will have 3-4 values. You don't have that problem with bitmask because you can add an attribute on demand. Of course you can use base-n system if you have too much attributes but that depends on what are the exact requirements
  • 0
    @beriba I think that this is a better approach. Instead of writing blue/red/yellow you just use a binary that holds x bits, one bit for each color possible.
  • 0
    @SirWindfield but you need to be aware to choose wisely the base of the system. Extending it in the future will be a pain
  • 1
    @beriba that is one solution, but why should we coerce everything into Binary?

    The Results for [2 hats, 3 hairstyles, 5 beardstyles, and 3 sunglasses]:
    0 : [0, 0, 0, 0]
    1 : [0, 0, 0, 1]
    2 : [0, 0, 0, 2]
    3 : [0, 0, 1, 0]
    4 : [0, 0, 1, 1]
    5 : [0, 0, 1, 2]
    6 : [0, 0, 2, 0]
    ....
    45 : [1, 0, 0, 0]
    ....
    89: [1,2,4,2]
  • 1
    @thejohnhoffer the gist is here using numpy arrays for performance and readability https://gist.github.com/thejohnhoff...
  • 1
    @thejohnhoffer

    Now that scales is a numpy array,

    # Get index from values
    def get_index(vals):
    #sum vals times scales
    return np.sum(vals*scales)
  • 1
    Thank God for python itertools
Add Comment