Skip to content

Instantly share code, notes, and snippets.

@killerstorm
Created September 30, 2012 15:46
Show Gist options
  • Save killerstorm/3807220 to your computer and use it in GitHub Desktop.
Save killerstorm/3807220 to your computer and use it in GitHub Desktop.
interactive output coloring demo
<html>
<head>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.8.2/jquery.min.js"></script>
</head>
<body>
<div id="inputs">
Inputs:<br />
<select><option>---</option><option>Red</option><option>Blue</option><option>Uncolored</option><option>Mixed</option></select><input> <br />
<select><option>---</option><option>Red</option><option>Blue</option><option>Uncolored</option><option>Mixed</option></select><input> <br />
<select><option>---</option><option>Red</option><option>Blue</option><option>Uncolored</option><option>Mixed</option></select><input> <br />
<select><option>---</option><option>Red</option><option>Blue</option><option>Uncolored</option><option>Mixed</option></select><input> <br />
<select><option>---</option><option>Red</option><option>Blue</option><option>Uncolored</option><option>Mixed</option></select><input> <br />
<select><option>---</option><option>Red</option><option>Blue</option><option>Uncolored</option><option>Mixed</option></select><input> <br />
<select><option>---</option><option>Red</option><option>Blue</option><option>Uncolored</option><option>Mixed</option></select><input> <br />
<select><option>---</option><option>Red</option><option>Blue</option><option>Uncolored</option><option>Mixed</option></select><input> <br />
<select><option>---</option><option>Red</option><option>Blue</option><option>Uncolored</option><option>Mixed</option></select><input> <br />
<select><option>---</option><option>Red</option><option>Blue</option><option>Uncolored</option><option>Mixed</option></select><input> <br />
<button onclick="ui_compute_colors()">compute</button>
</div>
<div id="outputs">
Outputs:<br />
<select><option>---</option><option>Red</option><option>Blue</option><option>Uncolored</option><option>Mixed</option></select><input> <br />
<select><option>---</option><option>Red</option><option>Blue</option><option>Uncolored</option><option>Mixed</option></select><input> <br />
<select><option>---</option><option>Red</option><option>Blue</option><option>Uncolored</option><option>Mixed</option></select><input> <br />
<select><option>---</option><option>Red</option><option>Blue</option><option>Uncolored</option><option>Mixed</option></select><input> <br />
<select><option>---</option><option>Red</option><option>Blue</option><option>Uncolored</option><option>Mixed</option></select><input> <br />
<select><option>---</option><option>Red</option><option>Blue</option><option>Uncolored</option><option>Mixed</option></select><input> <br />
<select><option>---</option><option>Red</option><option>Blue</option><option>Uncolored</option><option>Mixed</option></select><input> <br />
<select><option>---</option><option>Red</option><option>Blue</option><option>Uncolored</option><option>Mixed</option></select><input> <br />
<select><option>---</option><option>Red</option><option>Blue</option><option>Uncolored</option><option>Mixed</option></select><input> <br />
<select><option>---</option><option>Red</option><option>Blue</option><option>Uncolored</option><option>Mixed</option></select><input> <br />
</div>
<p id="errors">
Colors mixed (destroyed colored coins): <span id="got_mixed"></span><br/>
Fee is paid with colored coins: <span id="color_fee"></span><br/>
Zero-amount input mismatched: <span id="zero_input_mismatch"></span><br/>
Zero-amount output mismatched: <span id="zero_output_mismatch"></span><br/>
Uncolored band before colored band: <span id="uncolored_before_colored"></span><br/>
Color band broken (non-adjacent): <span id="color_band_broken"></span><br/>
</p>
<script>
var COLOR_MIXED = -1;
var COLOR_UNKNOWN = -2;
var COLOR_DEFAULT = 0;
var COLOR_RED = 1;
var COLOR_BLUE = 2;
function compute_colors(inputs, outputs) {
var cur_amount = 0;
var cur_color = COLOR_UNKNOWN;
var i = 0; //input index
var errors = {got_mixed: false, color_fee: false, zero_input_mismatch: false,
zero_output_mismatch: false, uncolored_before_colored: false,
color_band_broken: false};
var seen_colors = {};
for (var o = 0; o < outputs.length; ++o) {
var want_amount = outputs[o].amount;
if (want_amount > 0) {
// eat outputs up to want_amount
while ((cur_amount < want_amount) && (i < inputs.length)) {
if (inputs[i].color > 0 && (cur_color == COLOR_DEFAULT || cur_color == COLOR_MIXED)) {
errors.uncolored_before_colored = true;
}
if (cur_amount == 0) {
if (cur_color != inputs[i].color) {
cur_color = inputs[i].color;
if (seen_colors[cur_color]) {
errors.color_band_broken = true;
} else seen_colors[cur_color] = 1;
}
} else if (cur_color != inputs[i].color) {
cur_color = COLOR_MIXED;
errors.got_mixed = true;
}
if (inputs[i].amount == 0) errors.zero_input_mismatch = true; // we shouldn't eat zero inputs here
cur_amount += inputs[i].amount;
++i;
}
} else { // zero-amount output
if (cur_amount == 0 && i < inputs.length && inputs[i].amount == 0) {
// eat one zero-amount input
cur_color = inputs[i].color;
++i;
} else {
cur_color = COLOR_MIXED;
errors.zero_output_mismatch = true;
}
}
if (cur_amount < want_amount) return false;
outputs[o].color = cur_color;
cur_amount -= want_amount;
}
// find errors in unused inputs
if (cur_amount > 0 && cur_color > 0)
errors.color_fee = true;
while (i < inputs.length) {
if (inputs[i].amount == 0) errors.zero_input_mismatch = true;
else {
if (inputs[i].color > 1) errors.color_fee = true;
}
// uncolored before colored error?
// color band broken?
++i;
}
return errors;
}
function test_compute_colors() {
var inputs = [{color: 1, amount:1},
{color: 1, amount:2},
{color: 2, amount:1},
{color: 0, amount:3}];
var outputs = [{color: -2, amount: 3},
{color: -2, amount: 1},
{color: -2, amount: 2}];
var result = compute_colors(inputs, outputs);
if (result) {
alert(outputs);
}
}
var name_colors = {
"Red": 1,
"Blue": 2,
"Uncolored": 0,
"Mixed": -1,
"---": -2
};
var color_names = {
"1": "Red",
"2": "Blue",
"0":"Uncolored",
"-1": "Mixed",
"-2": "---"
};
function ui_compute_colors () {
var inputs = [];
var outputs = [];
var no_more_inputs = false;
var no_more_outputs = false;
$("#inputs input").each(function (i, e) {
if (!no_more_inputs) {
if (e.value !== "") {
inputs.push({color: COLOR_UNKNOWN, amount: parseInt(e.value), index: i});
} else no_more_inputs = true;
}
});
$("#inputs select").each(function (i, e) {
if (inputs[i]) {
inputs[i].color = name_colors[e.value];
}
});
$("#outputs input").each(function (i, e) {
if (!no_more_outputs) {
if (e.value !== "") {
outputs.push({color: COLOR_UNKNOWN, amount: parseInt(e.value), index: i});
} else no_more_outputs = true;
}
});
var res = compute_colors(inputs, outputs);
if (res) {
$("#outputs select").each(function (i, e) {
if (outputs[i]) {
e.value = color_names[outputs[i].color.toString()];
} else {
e.value = "---";
}
});
for (var ec in res) {
var selector = "#" + ec;
$(selector).text(res[ec].toString());
}
} else alert("invalid transaction");
};
///test_compute_colors();
</script>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment