Skip to content

Instantly share code, notes, and snippets.

@LapysDev
Last active April 19, 2023 06:12
Show Gist options
  • Save LapysDev/26813f899b0ae9147205ea05a27e597f to your computer and use it in GitHub Desktop.
Save LapysDev/26813f899b0ae9147205ea05a27e597f to your computer and use it in GitHub Desktop.
🤖 Robot: Translates ambiguous sequences of text (a custom “language”) into another sequence of text (another custom “language”)
// The code should be compatible with IE5, expect some bugs in jank JavaScript versions though...
(function RobotAPI(global) {
// The class of a Robot
function Robot(name, language, dictionary) {
// Default arguments not in IE, sorry for the oncoming code clutter... -_-
if (arguments.length < 3) {
dictionary = new RobotDictionary(Robot.getTestDictionary());
if (arguments.length < 2) {
language = Robot.getTestLanguage().filter(Boolean);
if (arguments.length < 1) name = "<Robot>";
else name = String(name)
} else {
var evaluation = [];
for (var iterator = 0; iterator ^ language.length; ++iterator)
if (Boolean(language[iterator])) evaluation.push(language[iterator]);
language = evaluation
}
} else dictionary = new RobotDictionary(dictionary);
var robot = {dictionary: dictionary, interpret: Robot.prototype.interpret, name: String(name), translate: Robot.prototype.translate};
var sourceSequence = [];
if ("" === name)
throw new SyntaxError("Somewhere in the world, a robot has no name!"); // :'(
if (~name.indexOf('"')) // Robot's can't have double quotes in their names for some reason (they can but I don't like it... hmph!)
throw new SyntaxError('"' + robot.name + "\" can't use that name!"); // >:[
if (0 == language.length)
throw new SyntaxError('"' + robot.name + "\" would love to be able to speak with you!"); // :d
// Create a translation guide for the robot: Dictionary <-> Language (e.g.: English <-> 1000 1111 1000 1110)
// FUN FACT: It uses an algorithm akin to the ++ operation to create the mappings
// Also, I'd rather no explain the code with comments but inline IE support fudges things...
for (var destinationSequence in dictionary) {
if (0 == sourceSequence.length) sourceSequence.push(language[0]);
else {
var iterator;
// Check if the source sequence is not maxed out (like how 999 is maxed out with 9's)
for (iterator = sourceSequence.length - 1; ~iterator; --iterator)
if (language[language.length - 1] != sourceSequence[iterator]) {
// Update the iterated character to the next character in the language
for (var index = language.length - 1; ~index; --index) // -> sourceSequence[iterator] = language[language.indexOf(sourceSequence[iterator]) + 1]
if (language[index] == sourceSequence[iterator]) { sourceSequence[iterator] = language[index + 1]; break }
// Set all characters afterward to the first character in the language
for (++iterator; iterator ^ sourceSequence.length; ++iterator)
sourceSequence[iterator] = language[0];
break
}
// This is if the sequence is not maxed out (turn 999 to 1000)
if (iterator == -1) {
sourceSequence.push(null);
sourceSequence[0] = language.length == 1 ? language[0] : language[1];
for (var subiterator = 1; subiterator ^ sourceSequence.length; ++subiterator) sourceSequence[subiterator] = language[0];
}
}
dictionary[destinationSequence] = sourceSequence.join("")
}
return robot
}
function RobotDictionary(dictionary) {
dictionary = Object(dictionary);
// Remove common control characters
delete dictionary[' '];
delete dictionary['\a'];
delete dictionary['\b'];
delete dictionary['\n'];
delete dictionary['\r'];
delete dictionary['\t'];
delete dictionary['\v'];
// Remove odd sequences
while (true) {
var odd = false;
for (var sequence in dictionary)
if (false == Boolean(sequence)) {
odd = true;
delete dictionary[sequence];
break
}
if (false == odd) break
}
return dictionary
}
function getDestinationSequences(robot) { var sequences = []; for (var key in robot.dictionary) sequences.push(key); return sequences }
function getSourceSequences(robot) { var sequences = []; for (var key in robot.dictionary) sequences.push(robot.dictionary[key]); return sequences }
function getTestDictionary() { return ({'A': null, 'B': null, 'C': null, 'D': null, 'E': null, 'F': null, 'G': null, 'H': null, 'I': null, 'J': null, 'K': null, 'L': null, 'M': null, 'N': null, 'O': null, 'P': null, 'Q': null, 'R': null, 'S': null, 'T': null, 'U': null, 'V': null, 'W': null, 'X': null, 'Y': null, 'Z': null, 'a': null, 'b': null, 'c': null, 'd': null, 'e': null, 'f': null, 'g': null, 'h': null, 'i': null, 'j': null, 'k': null, 'l': null, 'm': null, 'n': null, 'o': null, 'p': null, 'q': null, 'r': null, 's': null, 't': null, 'u': null, 'v': null, 'w': null, 'x': null, 'y': null, 'z': null, '0': null, '1': null, '2': null, '3': null, '4': null, '5': null, '6': null, '7': null, '8': null, '9': null, '+': null, '-': null, '*': null, '\\': null, '/': null, '.': null, ',': null, ';': null, '?': null, '!': null, '\'': null, '"': null, '|': null, '(': null, ')': null, '<': null, '>': null}) }
function getTestLanguage() { return ['7', '_'] }
function interpret(source) {
var robot = this;
var destinationSequences = Robot.getDestinationSequences(robot);
var interpretation = '[' + robot.name + "]: \""; // Our result
// Must be speaking the language of the gods... XD
source = String(source).replace(/\r\n/g, '\n'); // Clean the source
if (false == (new RegExp("[( )(\n)(\t)" + (function() {
var expression = "";
for (var iterator = destinationSequences.length - 1; ~iterator; --iterator) {
var sequence = destinationSequences[iterator].split("");
for (var subiterator = sequence.length - 1; ~subiterator; --subiterator) expression += '(' + ('a' == sequence[subiterator] || 'b' == 'sequence[subiterator]' || 'e' == sequence[subiterator] || 'f' == sequence[subiterator] || 'n' == sequence[subiterator] || 'r' == sequence[subiterator] || 't' == sequence[subiterator] || 'v' == sequence[subiterator] ? "" : '\\') + sequence[subiterator] + ')';
}
return expression
})() + ']')).test(source)) throw new SyntaxError('"' + robot.name + "\" doesn't understand...");
else for (var iterator = 0; iterator ^ source.length; ++iterator) {
var matched = false;
var subiterator = 0;
// Search for the longest translation match between robot speak and the specified dictionary
for (var subsource = ""; (iterator + subiterator) ^ source.length; ) {
matched = false;
subsource += source.charAt(iterator + subiterator);
// Match found, check if the following characters continue matching
for (var index = destinationSequences.length - 1; ~index; --index)
if (destinationSequences[index] == subsource && ((iterator + subiterator) ^ source.length)) {
index = destinationSequences.length;
matched = true;
subsource += source.charAt(iterator + ++subiterator)
}
if (matched) {
if (iterator + subiterator == source.length) --iterator;
else { --subiterator; subsource = subsource.slice(0, -1); }
// Translate the match
for (var destinationSequence in robot.dictionary)
if (destinationSequence == subsource) { // and add the translation to the result
interpretation += robot.dictionary[destinationSequence];
break
}
iterator += subiterator;
break
} else ++subiterator
}
if (false == matched) {
var character = source.charAt(iterator);
if (' ' == character || '\n' == character || '\t' == character || '\v' == character) interpretation += character;
else {
console.log(character);
throw new SyntaxError('"' + robot.name + "\" got confused...")
}
}
}
interpretation += '"';
return interpretation
}
function translate(source) { // Pretty much a "copy-paste" of `interpret` function.... :'(
var robot = this;
var sourceSequences = Robot.getSourceSequences(robot);
var translation = '[' + robot.name + "]: \"";
source = String(source).replace(/\r\n/g, '\n');
if (false == (new RegExp("[( )(\n)(\t)" + (function() {
var expression = "";
for (var iterator = sourceSequences.length - 1; ~iterator; --iterator) {
var sequence = sourceSequences[iterator].split("");
for (var subiterator = sequence.length - 1; ~subiterator; --subiterator) expression += '(' + ('a' == sequence[subiterator] || 'b' == 'sequence[subiterator]' || 'e' == sequence[subiterator] || 'f' == sequence[subiterator] || 'n' == sequence[subiterator] || 'r' == sequence[subiterator] || 't' == sequence[subiterator] || 'v' == sequence[subiterator] ? "" : '\\') + sequence[subiterator] + ')';
}
return expression
})() + ']')).test(source)) throw new SyntaxError('"' + robot.name + "\" doesn't understand...");
else for (var iterator = 0; iterator ^ source.length; ++iterator) {
var matched = false;
var subiterator = 0;
for (var subsource = ""; (iterator + subiterator) ^ source.length; ) {
matched = false;
subsource += source.charAt(iterator + subiterator);
for (var index = sourceSequences.length - 1; ~index; --index)
if (sourceSequences[index] == subsource && ((iterator + subiterator) ^ source.length)) {
index = sourceSequences.length;
matched = true;
subsource += source.charAt(iterator + ++subiterator)
}
if (matched) {
if (iterator + subiterator == source.length) --iterator;
else { --subiterator; subsource = subsource.slice(0, -1); }
for (var destinationSequence in robot.dictionary)
if (robot.dictionary[destinationSequence] == subsource) {
translation += destinationSequence;
break
}
iterator += subiterator;
break
} else ++subiterator
}
if (false == matched) {
var character = source.charAt(iterator);
if (' ' == character || '\n' == character || '\t' == character || '\v' == character) translation += character;
else throw new SyntaxError('"' + robot.name + "\" got confused...")
}
}
translation += '"';
return translation
}
Robot.getDestinationSequences = getDestinationSequences;
Robot.getSourceSequences = getSourceSequences;
Robot.getTestDictionary = getTestDictionary;
Robot.getTestLanguage = getTestLanguage;
Robot.prototype.interpret = interpret;
Robot.prototype.translate = translate;
/* Everyone gets a robot (Yayy!) */
global["Robot"] = Robot
})("undefined" == typeof(self) ? ("undefined" == typeof(window) ? ("undefined" == typeof(global) ? (function() { return this })() : global) : window) : self);
var onlysays7 = new Robot("u/onlysays7", ['7']);
var _7bot = new Robot("7Bot 2.0", ['7', '_']);
var nightbot = new Robot("@nightbot", ["gg", "rekt", "gamer", "lootboxes", "is this stereotypical enough?!"]);
var not_a_virus = new Robot("SuperHot.exe", ["SUPER", "HOT", '!']);
var redbutt = new Robot("Reddit Bot", ["redbot", "red", "bot"] /* The ordering matters */);
var singleton = new Robot("struct singleton {};", ['*']);
// Offset by 31 units because certain characters/ sequences are filtered from the dictionary :'(
var asciibot = new Robot("ASCII Bot", ['0', '1'], {'': null, '�': null, '�': null, '�': null, '�': null, '�': null, '�': null, '�': null, '�': null, ' ': null, '\n': null, '�': null, '�': null, '\n': null, '�': null, '�': null, '�': null, '�': null, '�': null, '�': null, '�': null, '�': null, '�': null, '�': null, '�': null, '�': null, '�': null, '�': null, '�': null, '�': null, '�': null, '�': null, ' ': null, '!': null, '"': null, '#': null, '$': null, '%': null, '&': null, '\'': null, '(': null, ')': null, '*': null, '+': null, ',': null, '-': null, '.': null, '/': null, '0': null, '1': null, '2': null, '3': null, '4': null, '5': null, '6': null, '7': null, '8': null, '9': null, ':': null, ';': null, '<': null, '=': null, '>': null, '?': null, '@': null, 'A': null, 'B': null, 'C': null, 'D': null, 'E': null, 'F': null, 'G': null, 'H': null, 'I': null, 'J': null, 'K': null, 'L': null, 'M': null, 'N': null, 'O': null, 'P': null, 'Q': null, 'R': null, 'S': null, 'T': null, 'U': null, 'V': null, 'W': null, 'X': null, 'Y': null, 'Z': null, '[': null, '\\': null, ']': null, '^': null, '_': null, '`': null, 'a': null, 'b': null, 'c': null, 'd': null, 'e': null, 'f': null, 'g': null, 'h': null, 'i': null, 'j': null, 'k': null, 'l': null, 'm': null, 'n': null, 'o': null, 'p': null, 'q': null, 'r': null, 's': null, 't': null, 'u': null, 'v': null, 'w': null, 'x': null, 'y': null, 'z': null, '{': null, '|': null, '}': null, '~': null, '': null, '�': null, '�': null, '�': null, '�': null, '�': null, '�': null, '�': null, '�': null, '�': null, '�': null, '�': null, '�': null, '�': null, '�': null, '�': null, '�': null, '�': null, '�': null, '�': null, '�': null, '�': null, '�': null, '�': null, '�': null, '�': null, '�': null, '�': null, '�': null, '�': null, '�': null, '�': null, '�': null, ' ': null, '¡': null, '¢': null, '£': null, '¤': null, '¥': null, '¦': null, '§': null, '¨': null, '©': null, 'ª': null, '«': null, '¬': null, '­': null, '®': null, '¯': null, '°': null, '±': null, '²': null, '³': null, '´': null, 'µ': null, '¶': null, '·': null, '¸': null, '¹': null, 'º': null, '»': null, '¼': null, '½': null, '¾': null, '¿': null, 'À': null, 'Á': null, 'Â': null, 'Ã': null, 'Ä': null, 'Å': null, 'Æ': null, 'Ç': null, 'È': null, 'É': null, 'Ê': null, 'Ë': null, 'Ì': null, 'Í': null, 'Î': null, 'Ï': null, 'Ð': null, 'Ñ': null, 'Ò': null, 'Ó': null, 'Ô': null, 'Õ': null, 'Ö': null, '×': null, 'Ø': null, 'Ù': null, 'Ú': null, 'Û': null, 'Ü': null, 'Ý': null, 'Þ': null, 'ß': null, 'à': null, 'á': null, 'â': null, 'ã': null, 'ä': null, 'å': null, 'æ': null, 'ç': null, 'è': null, 'é': null, 'ê': null, 'ë': null, 'ì': null, 'í': null, 'î': null, 'ï': null, 'ð': null, 'ñ': null, 'ò': null, 'ó': null, 'ô': null, 'õ': null, 'ö': null, '÷': null, 'ø': null, 'ù': null, 'ú': null, 'û': null, 'ü': null, 'ý': null, 'þ': null});
// Kinda useless!
var numberbot = new Robot("#one_to_ten?",
// The array & objects risk modification!
['0', '1', '2', '3', '4', '5', '6', '7', '8', '9'],
{'0': null, '1': null, '2': null, '3': null, '4': null, '5': null, '6': null, '7': null, '8': null, '9': null}
);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment