Subscribe to MentalFloss Minutes        RSS Feed
-----

Complex Logic And Matrices

Icon Leave Comment
So, let's say that you have some problem that involves pretty complex logic, and only two parameters. Instead of writing a bunch of if statements, you can construct an output matrix, and fetch the values that way. For an example, let's mix some paint.

We have our colors: Red, Yellow, Blue.
Red + Yellow = Orange
Red + Blue = Purple
Yellow + Blue = Green

This isn't complicated enough though is it? OR is it:

Paint mix(Paint p1, Paint p2)
{
    if((p1 == RED && p2 == YELLOW) || (p1 == YELLOW && p2 == RED))
        return ORANGE;
    // and so on for all combinations.
}



Or maybe we like this:

Paint mix(Paint p1, Paint p2)
{
    if(p1 == RED)
    {
        if(p2 == YELLOW)
            return ORANGE;
        if(p2 == BLUE)
            return PURPLE;
    }
    // and so on for each combination.
}



The important thing to consider is that p1=X and p2=Y == p1=Y and p2=X. And that makes things kind of unpleasant.

Just to show how awesome this technique is, let's add a lot more colors.

Paints: Red, Orange, Yellow, Green, Blue, Purple, Black, White, Pink, Tan, Cream, Lime, Cyan, Lavender, Grey, Brown

If you mix (Red, Orange, Yellow, Green, Blue, Purple, Black, White) with White, you get (Pink, tan, Cream, Lime, Cyan, Lavender, Grey, White).

If you mix (Pink, Tan, Cream, Lime, Cyan, Lavender, Grey) with Black, you get (Red, Orange, Yellow, Green, Blue, Purple, Black)

If you mix (Pink, Tan, Cream, Lime, Cyan, Lavender, Grey) with Grey you get that color.

If you mix (Pink, Tan, Cream, Lime, Cyan, Lavender, Grey) with white, you get White.

If you mix (Red, Orange, Yellow, Green, Blue, Purple, Black, Grey) with Black, you get Black.

If you mix (Red, Orange, Yellow, Green, Blue, Purple, Black) with the lighter colors that are not its lighter color, you get Brown.

If you mix a color with itself, you get the color back.

If you mix (Red, Yellow, Blue) with (Yellow, Blue, Red) you get (Orange, Green, Purple)

If you mix (Pink, Tan, Cream, Lime, Cyan, Lavender) with (Red, Orange, Yellow, Green, Blue, Purple) you get (Red, Orange...)

If you mix (Orange, Green, Purple) with any primary, you get Brown.

If you mix (Red, orange, yellow, green, blue, purple) with Grey you get grey.

Brown mixing just makes more brown.

So, to summarize, White makes it lighter, then white. Black makes it darker, then black. Light colors darken with their darker color.

I know it's not how that all works, but we can make our own rules here.

If you want a programming exercise, there you have it. Implement that.

So, with everything, let's create our enum:

#include <iostream>

using namespace std;

typedef enum
{
	RED,
	ORANGE,
	YELLOW,
	GREEN,
	BLUE,
	PURPLE,
	BLACK,
	WHITE,
	PINK,
	TAN,
	CREAM,
	LIME,
	CYAN,
	LAVENDER,
	GREY,
        BROWN

} Paint;

int main()
{
	return 0;
}



We want to map colors to strings, so we can see what's happening.

#include <iostream>

using namespace std;

typedef enum
{
	RED,
	ORANGE,
	YELLOW,
	GREEN,
	BLUE,
	PURPLE,
	BLACK,
	WHITE,
	PINK,
	TAN,
	CREAM,
	LIME,
	CYAN,
	LAVENDER,
	GREY,
        BROWN

} Paint;

string names[] = {
	"red",
	"orange",
	"yellow",
	"green",
	"blue",
	"purple",
	"black",
	"white",
	"pink",
	"tan",
	"cream",
	"lime",
	"cyan",
	"lavender",
	"grey",
        "brown"
};

int main()
{
	cout << names[RED] << endl;
	return 0;
}



We want a function that gives a paint back after providing two paints.

Paint mix(Paint p1, Paint p2)
{
	return BLACK;
}

int main()
{
	Paint paint = mix(RED, YELLOW);
	cout << names[paint] << endl;
	return 0;
}



Now, we define our matrix with rows being p1, and columns being p2. Sorry it's a garbled mess, but if you copy/paste it into a text editor with no word-wrap it will look fine.

Paint mix_matrix[15][15] = 
{
	//	Red		Orange		Yellow		Green		Blue		Purple		Black		White		Pink		Tan			Cream		Lime		Cyan		Lavender		Grey
	{ RED,		BROWN,		ORANGE,		BROWN,		PURPLE,		BROWN,		BLACK,		PINK,		RED,		BROWN,		BROWN,		BROWN,		BROWN,		BROWN,			GREY 	}, 		// RED
	{ BROWN,	ORANGE,		BROWN,		BROWN,		BROWN,		BROWN,		BLACK,		TAN,		BROWN,		ORANGE,		BROWN,		BROWN,		BROWN,		BROWN,			GREY 	},		// ORANGE
	{ ORANGE,	BROWN,		YELLOW,		BROWN,		GREEN,		BROWN,		BLACK,		CREAM,		BROWN,		BROWN,		YELLOW,		BROWN,		BROWN,		BROWN,			GREY 	},		// YELLOW
	{ BROWN,	BROWN,		BROWN,		GREEN,		BROWN,		BROWN,		BLACK,		LIME,		BROWN,		BROWN,		BROWN,		GREEN,		BROWN,		BROWN,			GREY 	},		// GREEN
	{ PURPLE,	BROWN,		GREEN,		GREEN,		BLUE,		BROWN,		BLACK,		CYAN,		BROWN,		BROWN,		BROWN,		BROWN,		BLUE,		BROWN,			GREY 	},		// BLUE
	{ BROWN,	BROWN,		BROWN,		BROWN,		BROWN,		PURPLE,		BLACK,		LAVENDER,	BROWN,		BROWN,		BROWN,		BROWN,		BROWN,		PURPLE,			GREY 	},		// PURPLE
	{ BLACK,	BLACK,		BLACK,		BLACK,		BLACK,		BLACK,		BLACK,		GREY,		RED,		ORANGE,		YELLOW,		GREEN,		BLUE,		PURPLE,			BLACK	},		// BLACK
	{ PINK,		TAN,		CREAM,		LIME,		CYAN,		LAVENDER,	GREY,		WHITE,		WHITE,		WHITE,		WHITE,		WHITE,		WHITE,		WHITE,			GREY    },		// WHITE
	{ RED,		BROWN,		BROWN,		BROWN,		BROWN,		BROWN,		RED,		WHITE,		PINK,		BROWN,		BROWN,		BROWN,		BROWN,		BROWN,			PINK	},		// PINK
	{ BROWN,	ORANGE,		BROWN,		BROWN,		BROWN,		BROWN,		ORANGE,		WHITE,		BROWN,		TAN,		BROWN,		BROWN,		BROWN,		BROWN,			TAN		},		// TAN
	{ BROWN,	BROWN,		YELLOW,		BROWN,		BROWN,		BROWN,		YELLOW,		WHITE,		BROWN,		BROWN,		CREAM,		BROWN,		BROWN,		BROWN,			CREAM	},		// CREAM
	{ BROWN,	BROWN,		BROWN,		GREEN,		BROWN,		BROWN,		GREEN,		WHITE,		BROWN,		BROWN,		BROWN,		LIME,		BROWN,		BROWN,			LIME	},		// LIME
	{ BROWN,	BROWN,		BROWN,		BROWN,		BLUE,		BROWN,		BLUE,		WHITE,		BROWN,		BROWN,		BROWN,		BROWN,		CYAN,		BROWN,			CYAN	},		// CYAN
	{ BROWN,	BROWN,		BROWN,		BROWN,		BROWN,		PURPLE,		PURPLE,		WHITE,		BROWN,		BROWN,		BROWN,		BROWN,		BROWN,		LAVENDER,		LAVENDER},		// LAVENDER
	{ GREY,		GREY,		GREY,		GREY,		GREY,		GREY,		BLACK,		WHITE,		PINK,		TAN,		CREAM,		LIME,		CYAN,		LAVENDER,		GREY	}		// GREY					
};



And we write our function to fetch the value:

Paint mix(Paint p1, Paint p2)
{
	if(p1 == BROWN || p2 == BROWN)
		return BROWN;

	return mix_matrix[p1][p2];
}



Now, we have some test code:

int main()
{
	Paint paints[] = { RED, ORANGE, YELLOW, GREEN, BLUE, PURPLE, BLACK, WHITE, PINK, TAN, CREAM, LIME, CYAN, LAVENDER, GREY };
	for(Paint p1 : paints)
	{
		for(Paint p2 : paints)
		{
			cout << names[p1] << " + " << names[p2] << " = " << names[mix(p1, p2)] << endl;
		}
	}
	return 0;
}



And the output:

red + red = red
red + orange = brown
red + yellow = orange
red + green = brown
red + blue = purple
red + purple = brown
red + black = black
red + white = pink
red + pink = red
red + tan = brown
red + cream = brown
red + lime = brown
red + cyan = brown
red + lavender = brown
red + grey = grey
orange + red = brown
orange + orange = orange
orange + yellow = brown
orange + green = brown
orange + blue = brown
orange + purple = brown
orange + black = black
orange + white = tan
orange + pink = brown
orange + tan = orange
orange + cream = brown
orange + lime = brown
orange + cyan = brown
orange + lavender = brown
orange + grey = grey
yellow + red = orange
yellow + orange = brown
yellow + yellow = yellow
yellow + green = brown
yellow + blue = green
yellow + purple = brown
yellow + black = black
yellow + white = cream
yellow + pink = brown
yellow + tan = brown
yellow + cream = yellow
yellow + lime = brown
yellow + cyan = brown
yellow + lavender = brown
yellow + grey = grey
green + red = brown
green + orange = brown
green + yellow = brown
green + green = green
green + blue = brown
green + purple = brown
green + black = black
green + white = lime
green + pink = brown
green + tan = brown
green + cream = brown
green + lime = green
green + cyan = brown
green + lavender = brown
green + grey = grey
blue + red = purple
blue + orange = brown
blue + yellow = green
blue + green = green
blue + blue = blue
blue + purple = brown
blue + black = black
blue + white = cyan
blue + pink = brown
blue + tan = brown
blue + cream = brown
blue + lime = brown
blue + cyan = blue
blue + lavender = brown
blue + grey = grey
purple + red = brown
purple + orange = brown
purple + yellow = brown
purple + green = brown
purple + blue = brown
purple + purple = purple
purple + black = black
purple + white = lavender
purple + pink = brown
purple + tan = brown
purple + cream = brown
purple + lime = brown
purple + cyan = brown
purple + lavender = purple
purple + grey = grey
black + red = black
black + orange = black
black + yellow = black
black + green = black
black + blue = black
black + purple = black
black + black = black
black + white = grey
black + pink = red
black + tan = orange
black + cream = yellow
black + lime = green
black + cyan = blue
black + lavender = purple
black + grey = black
white + red = pink
white + orange = tan
white + yellow = cream
white + green = lime
white + blue = cyan
white + purple = lavender
white + black = grey
white + white = white
white + pink = white
white + tan = white
white + cream = white
white + lime = white
white + cyan = white
white + lavender = white
white + grey = grey
pink + red = red
pink + orange = brown
pink + yellow = brown
pink + green = brown
pink + blue = brown
pink + purple = brown
pink + black = red
pink + white = white
pink + pink = pink
pink + tan = brown
pink + cream = brown
pink + lime = brown
pink + cyan = brown
pink + lavender = brown
pink + grey = pink
tan + red = brown
tan + orange = orange
tan + yellow = brown
tan + green = brown
tan + blue = brown
tan + purple = brown
tan + black = orange
tan + white = white
tan + pink = brown
tan + tan = tan
tan + cream = brown
tan + lime = brown
tan + cyan = brown
tan + lavender = brown
tan + grey = tan
cream + red = brown
cream + orange = brown
cream + yellow = yellow
cream + green = brown
cream + blue = brown
cream + purple = brown
cream + black = yellow
cream + white = white
cream + pink = brown
cream + tan = brown
cream + cream = cream
cream + lime = brown
cream + cyan = brown
cream + lavender = brown
cream + grey = cream
lime + red = brown
lime + orange = brown
lime + yellow = brown
lime + green = green
lime + blue = brown
lime + purple = brown
lime + black = green
lime + white = white
lime + pink = brown
lime + tan = brown
lime + cream = brown
lime + lime = lime
lime + cyan = brown
lime + lavender = brown
lime + grey = lime
cyan + red = brown
cyan + orange = brown
cyan + yellow = brown
cyan + green = brown
cyan + blue = blue
cyan + purple = brown
cyan + black = blue
cyan + white = white
cyan + pink = brown
cyan + tan = brown
cyan + cream = brown
cyan + lime = brown
cyan + cyan = cyan
cyan + lavender = brown
cyan + grey = cyan
lavender + red = brown
lavender + orange = brown
lavender + yellow = brown
lavender + green = brown
lavender + blue = brown
lavender + purple = purple
lavender + black = purple
lavender + white = white
lavender + pink = brown
lavender + tan = brown
lavender + cream = brown
lavender + lime = brown
lavender + cyan = brown
lavender + lavender = lavender
lavender + grey = lavender
grey + red = grey
grey + orange = grey
grey + yellow = grey
grey + green = grey
grey + blue = grey
grey + purple = grey
grey + black = black
grey + white = white
grey + pink = pink
grey + tan = tan
grey + cream = cream
grey + lime = lime
grey + cyan = cyan
grey + lavender = lavender
grey + grey = grey



So, there you have it. Maybe you'll find this technique useful. Maybe you'll think it's terrible. Either way, it works, and we avoided debugging a ton of if statements.

0 Comments On This Entry

 

November 2018

S M T W T F S
    123
45678910
11121314151617
18192021 22 2324
252627282930 

Tags

    Recent Entries

    Recent Comments

    Search My Blog

    0 user(s) viewing

    0 Guests
    0 member(s)
    0 anonymous member(s)