Created
March 11, 2020 02:44
-
-
Save jrocha/4fc6f24313f6e327c277687ee5e290af to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Collections.Generic; | |
using System.Diagnostics; | |
using System.IO; | |
using System.Text; | |
namespace SBSTR1 { | |
class Program { | |
static int ProgramV0(string strA, string strB) { | |
var pertence = 0; | |
for (int i = 0; i < strA.Length - strB.Length; i++) { | |
for (int j = 0; j < strB.Length; j++) { | |
if (strA[i + j] == strB[j]) | |
pertence = 1; | |
else { | |
pertence = 0; | |
j = strB.Length; | |
} | |
} | |
if (pertence > 0) | |
i = strA.Length; | |
} | |
return pertence; | |
} | |
static int ProgramV1(string strA, string strB) { | |
var pertence = 0; | |
var comparacaoA = default(char); | |
var comparacaoB = default(char); | |
for (int i = 0; i < 10 - 5; i++) { | |
for (int j = 0; j < 5; j++) { | |
comparacaoA = strA[i + j]; | |
comparacaoB = strB[j]; | |
if (comparacaoA == comparacaoB) | |
pertence = 1; | |
else { | |
pertence = 0; | |
j = 5; | |
} | |
} | |
if (pertence > 0) | |
i = 10; | |
} | |
return pertence; | |
} | |
static int ProgramV2(string strA, string strB) { | |
var pertence = 0; | |
var comparacaoA = default(char); | |
var comparacaoB = default(char); | |
var contadorA = 5; | |
var indexA = 0; | |
var contadorB = 5; | |
var indexB = 0; | |
while (contadorA > 0) { | |
indexA = 5 - contadorA; | |
contadorB = 5; | |
while (contadorB > 0) { | |
indexB = 5 - contadorB; | |
comparacaoA = strA[indexA + indexB]; | |
comparacaoB = strB[indexB]; | |
if (comparacaoA == comparacaoB) | |
pertence = 1; | |
else { | |
pertence = 0; | |
contadorB = 0; | |
} | |
contadorB--; | |
} | |
if (pertence > 0) | |
contadorA = 0; | |
contadorA--; | |
} | |
return pertence; | |
} | |
static int ProgramV3(string strA, string strB) { | |
var pertence = 0; | |
var comparacaoA = default(char); | |
var comparacaoB = default(char); | |
var contadorA = 5; | |
var indexA = 0; | |
var contadorB = 5; | |
var indexB = 0; | |
while (contadorA > 0) { // contadorA[] loop | |
indexA = 5 - contadorA; | |
contadorB = 5; | |
while (contadorB > 0) { // contadorB[] loop | |
indexB = 5 - contadorB; | |
comparacaoA = strA[indexA + indexB]; // copia nao destrutiva de valores | |
comparacaoB = strB[indexB]; // copia nao destrutiva de valores | |
if (comparacaoA != comparacaoB) { // NEQ | |
pertence = 0; // reset cell [-] | |
contadorB = 0; // reset cell [-] | |
} else { | |
pertence = 1; // reset para 1 [-]+ | |
} | |
contadorB--; | |
} | |
if (pertence > 0) | |
contadorA = 0; // reset cell [-] | |
contadorA--; | |
} | |
return pertence; | |
} | |
static int ProgramV4(string strA, string strB) { | |
var nroTeste = 1; | |
var pertence = 0; | |
var comparacaoA = default(char); | |
var comparacaoB = default(char); | |
var contadorA = 5; | |
var indexA = 0; | |
var contadorB = 5; | |
var indexB = 0; | |
while (nroTeste > 0) { // nroTeste[] loop | |
while (contadorA > 0) { // contadorA[] loop | |
indexA = 5 - contadorA; | |
contadorB = 5; | |
while (contadorB > 0) { // contadorB[] loop | |
indexB = 5 - contadorB; | |
comparacaoA = strA[indexA + indexB]; // copia nao destrutiva de valores | |
comparacaoB = strB[indexB]; // copia nao destrutiva de valores | |
if (comparacaoA != comparacaoB) { // NEQ | |
pertence = 0; // reset cell [-] | |
contadorB = 0; // reset cell [-] | |
} else { | |
pertence = 1; // reset para 1 [-]+ | |
} | |
contadorB--; | |
} | |
if (pertence > 0) | |
contadorA = 0; // reset cell [-] | |
contadorA--; | |
} | |
nroTeste--; | |
} | |
return pertence; | |
} | |
static int ProgramV5(int tests) { | |
DECLARE("nroTeste", 1, tests); | |
DECLARE("pertence", 1); | |
DECLARE("comparacaoA", 1); | |
DECLARE("comparacaoB", 1); | |
DECLARE("contadorA", 1); | |
DECLARE("indexA", 1); | |
DECLARE("contadorB", 1); | |
DECLARE("indexB", 1); | |
DECLAREARRAY("strA", 10); | |
DECLAREARRAY("strB", 5); | |
DECLARE("REG0", 1, 0); | |
DECLARE("REG1", 1, 0); | |
DECLARE("REG2", 1, 0); | |
DECLARE("REG3", 1, 0); | |
DECLARE("REGCMP", 1, 0); | |
DECLARE("REGCOPY", 1, 0); | |
WHILE("nroTeste", () => { | |
ASSIGN("pertence", 0); | |
ASSIGN("comparacaoA", 0); | |
ASSIGN("comparacaoB", 0); | |
ASSIGN("contadorA", 5); | |
ASSIGN("indexA", 0); | |
ASSIGN("contadorB", 5); | |
ASSIGN("indexB", 0); | |
MoveToCell("strA"); | |
READANDFORWARD(10); | |
MoveToCell("REG0"); | |
READANDFORWARD(1); | |
MoveToCell("strB"); | |
READANDFORWARD(5); | |
MoveToCell("REG0"); | |
READANDFORWARD(1); | |
WHILE("contadorA", () => { | |
// indexA = 5 - contadorA | |
ASSIGN("REG0", 5); | |
COPY("REG1", "contadorA"); | |
WHILE("REG1", () => { | |
DECREMENT("REG0"); | |
DECREMENT("REG1"); | |
}); | |
COPY("indexA", "REG0"); | |
ASSIGN("contadorB", 5); | |
WHILE("contadorB", () => { | |
// indexB = 5 - contadorB | |
ASSIGN("REG0", 5); | |
COPY("REG1", "contadorB"); | |
WHILE("REG1", () => { | |
DECREMENT("REG0"); | |
DECREMENT("REG1"); | |
}); | |
COPY("indexB", "REG0"); | |
// REG0 = indexA + indexB | |
COPY("REG0", "indexA"); | |
COPY("REG1", "indexB"); | |
WHILE("REG1", () => { | |
INCREMENT("REG0"); | |
DECREMENT("REG1"); | |
}); | |
// comparacaoA = strA[REG0] | |
EXELEM("comparacaoA", "strA", "REG0"); | |
//REG0 = indexB | |
COPY("REG0", "indexB"); | |
// comparacaoB = strB[REG0] | |
EXELEM("comparacaoB", "strB", "REG0"); | |
COMPARE("comparacaoA", "comparacaoB"); | |
IFNOTEQ(() => { | |
RESET("pertence"); | |
RESET("contadorB"); | |
}, () => { | |
ASSIGN("pertence", 1); | |
}); | |
DECREMENT("contadorB"); | |
}); | |
ASSIGN("REG2", 0); | |
COMPARE("pertence", "REG2"); | |
IFNOTEQ(() => { | |
RESET("contadorA"); | |
}); | |
DECREMENT("contadorA"); | |
}); | |
ASSIGN("REG2", 0); | |
COMPARE("pertence", "REG2"); | |
IFNOTEQ(() => { | |
ASSIGN("REG2", 49); //1 pertence | |
PRINT("REG2"); | |
}, () => { | |
ASSIGN("REG2", 48); //0 nao pert | |
PRINT("REG2"); | |
}); | |
DECREMENT("nroTeste"); | |
}); | |
return mem[varMap["pertence"]]; | |
} | |
private static void PRINT(string var) { | |
MoveToCell(var); | |
var charToPrint = (char)mem[cellPointer]; | |
OUTPUT.Write(charToPrint); | |
OUTPUT.Write('\n'); | |
INSTRUCTIONS.Write("."); | |
} | |
private static void READANDFORWARD() { | |
var buf = new byte[1]; | |
INPUT.Read(buf, 0, 1); | |
INSTRUCTIONS.Write(","); | |
while (buf[0] > 0) { | |
INCREMENT(); | |
buf[0]--; | |
} | |
FORWARD(1); | |
} | |
private static void READANDFORWARD(int n) { | |
for (int i = 0; i < n; i++) { | |
READANDFORWARD(); | |
} | |
} | |
static Stream INPUT; | |
static int cellPointer = 0; | |
static int lastVarPointer = 0; | |
static int interpret = 1; | |
static Dictionary<string, int> varSize = new Dictionary<string, int>(); | |
static Dictionary<string, int> varMap = new Dictionary<string, int>(); | |
static int[] mem = new int[64 * 1024]; | |
static TextWriter INSTRUCTIONS = new StreamWriter("comp.bf"); | |
static TextWriter OUTPUT = Console.Out; | |
static void DECLARE(string varName, int size) { | |
varMap[varName] = lastVarPointer; | |
varSize[varName] = size; | |
mem[varMap[varName]] = 0; | |
lastVarPointer += size; | |
} | |
static void DECLARE(string varName, int size, int initialVal) { | |
varMap[varName] = lastVarPointer; | |
varSize[varName] = size; | |
mem[varMap[varName]] = 0; | |
lastVarPointer += size; | |
ASSIGN(varName, initialVal); | |
} | |
static void DECLAREARRAY(string varName, int size) { | |
// ARRAY LAYOUT: 0 0 ARRAY 0 0 | |
lastVarPointer += 2; | |
varMap[varName] = lastVarPointer; | |
varSize[varName] = size; | |
lastVarPointer += size; | |
lastVarPointer += 2; | |
} | |
static void COMPARE(string varNameA, string varNameB) { | |
COPY("REG0", varNameA); | |
COPY("REG1", varNameB); | |
MoveToCell("REG0"); | |
FORWARD(1); | |
WHILE(() => { | |
DECREMENT(); | |
BACK(1); | |
DECREMENT(); | |
FORWARD(1); | |
}); | |
BACK(1); | |
COPY("REGCMP", "REG0"); | |
} | |
static void IFNOTEQ(Action actionIf, Action actionElse = null) { | |
RESET("REG0"); | |
ASSIGN("REG1", 1); | |
COPY("REG0", "REGCMP"); | |
MoveToCell("REG0"); | |
WHILE(() => { | |
RESET("REG0"); | |
RESET("REG1"); | |
actionIf(); | |
MoveToCell("REG0"); | |
}); | |
if (null != actionElse) { | |
MoveToCell("REG1"); | |
WHILE(() => { | |
RESET("REG0"); | |
RESET("REG1"); | |
actionElse(); | |
MoveToCell("REG0"); | |
}); | |
} | |
} | |
static void EXELEM(string varNameTarget, string varNameSource, string varNameOffset) { | |
RESET(varNameTarget); | |
var idxAddress = varMap[varNameSource] + varSize[varNameSource] + 1; | |
COPY(idxAddress, varMap[varNameOffset]); | |
MoveToCell(idxAddress); | |
INCREMENT(); | |
// copia para indice solicitado para ficar: 0 0 array 0 idx | |
WHILE(() => { | |
DECREMENT(); // decrementa idx | |
BACK(2); | |
WHILE(() => BACK(1)); // volta ate achar zero | |
FORWARD(1); | |
WHILE(() => { // copia dados para cell anterior | |
DECREMENT(); | |
BACK(1); | |
INCREMENT(); | |
FORWARD(1); | |
}); | |
FORWARD(1); // avanca para sair do zero | |
WHILE(() => { // anda ate achar prox zero | |
FORWARD(1); | |
}); | |
FORWARD(1); // voltou para o idx | |
}); | |
BACK(2); | |
WHILE(() => BACK(1)); // volta ate achar zero | |
FORWARD(1); // posiciona no primeiro item do array | |
WHILE(() => { // move valor atual para esquerda | |
DECREMENT(); | |
BACK(1); | |
INCREMENT(); | |
FORWARD(1); | |
}); | |
// <[->>[>]>+>+<<<[<]<] copy outside array twice | |
BACK(1); | |
WHILE(() => { | |
DECREMENT(); | |
FORWARD(2); | |
WHILE(() => FORWARD(1)); | |
FORWARD(1); | |
INCREMENT(); | |
FORWARD(1); | |
INCREMENT(); | |
BACK(3); | |
WHILE(() => BACK(1)); | |
BACK(1); | |
}); | |
// >>[>]>> go to second copy | |
FORWARD(2); | |
WHILE(() => FORWARD(1)); | |
FORWARD(2); | |
// [-<<<[<]<+>>[>]>>] move second copy back to where it comes | |
WHILE(() => { | |
DECREMENT(); | |
BACK(3); | |
WHILE(() => BACK(1)); | |
BACK(1); | |
INCREMENT(); | |
FORWARD(2); | |
WHILE(() => FORWARD(1)); | |
FORWARD(2); | |
}); | |
// <<<[<]<[[->+<]<]>>[>]> move all items back to their original position | |
BACK(3); | |
WHILE(() => BACK(1)); | |
BACK(1); | |
WHILE(() => { | |
WHILE(() => { | |
DECREMENT(); | |
FORWARD(1); | |
INCREMENT(); | |
BACK(1); | |
}); | |
BACK(1); | |
}); | |
FORWARD(2); | |
WHILE(() => FORWARD(1)); | |
FORWARD(1); | |
COPY(varMap[varNameTarget], idxAddress); | |
RESET(idxAddress); | |
} | |
static void BACK(int n) { | |
cellPointer -= n; | |
INSTRUCTIONS.Write(new string('<',n)); | |
} | |
static void FORWARD(int n) { | |
cellPointer += n; | |
INSTRUCTIONS.Write(new string('>', n)); | |
} | |
static void COPY(int addressTarget, int addressSource) { | |
RESET("REGCOPY"); | |
RESET(addressTarget); | |
MoveToCell(addressSource); | |
WHILE(addressSource, () => { | |
INCREMENT("REGCOPY"); | |
INCREMENT(addressTarget); | |
DECREMENT(addressSource); | |
}); | |
WHILE("REGCOPY", () => { | |
DECREMENT("REGCOPY"); | |
INCREMENT(addressSource); | |
}); | |
} | |
static void COPY(string varNameTarget, string varNameSource) => | |
COPY(varMap[varNameTarget], varMap[varNameSource]); | |
static void MoveToCell(string varName) => | |
MoveToCell(varName, 0); | |
static void MoveToCell(string varName, int offset) => | |
MoveToCell(varMap[varName], offset); | |
static void MoveToCell(int address) => | |
MoveToCell(address, 0); | |
static void MoveToCell(int address, int offset) { | |
int varCell = address; | |
var moves = ""; | |
if (varCell > cellPointer) { | |
moves = new string('>', varCell + offset - cellPointer); ; | |
} else if (varCell < cellPointer) { | |
moves = new string('<', cellPointer - varCell + offset); ; | |
} | |
INSTRUCTIONS.Write(moves); | |
cellPointer = varCell; | |
} | |
static void RESET(string varName) => | |
RESET(varMap[varName]); | |
static void RESET(int address) { | |
MoveToCell(address); | |
INSTRUCTIONS.Write("[-]"); | |
mem[address] = 0; | |
} | |
static void WHILE(Action action) { | |
if (interpret > 0) { | |
INSTRUCTIONS.Write("["); | |
while (mem[cellPointer] > 0) { | |
action(); | |
} | |
INSTRUCTIONS.Write("]"); | |
} else { | |
INSTRUCTIONS.Write("["); | |
action(); | |
INSTRUCTIONS.Write("]"); | |
} | |
} | |
static void WHILE(int address, Action action) { | |
if (interpret > 0) { | |
MoveToCell(address); | |
INSTRUCTIONS.Write("["); | |
while (mem[address] > 0) { | |
action(); | |
MoveToCell(address); | |
} | |
INSTRUCTIONS.Write("]"); | |
} else { | |
MoveToCell(address); | |
INSTRUCTIONS.Write("["); | |
action(); | |
MoveToCell(address); | |
INSTRUCTIONS.Write("]"); | |
} | |
} | |
static void WHILE(string varName, Action action) { | |
WHILE(varMap[varName], action); | |
} | |
static void ASSIGN(string varName, int val) { | |
RESET(varName); | |
mem[varMap[varName]] = val; | |
INSTRUCTIONS.Write(new string('+', val)); | |
} | |
static void DECREMENT(string varName) => DECREMENT(varMap[varName]); | |
static void DECREMENT(int address) { | |
MoveToCell(address); | |
DECREMENT(); | |
} | |
static void DECREMENT() { | |
mem[cellPointer]--; | |
INSTRUCTIONS.Write(new string('-', 1)); | |
} | |
static void INCREMENT(string varName) => INCREMENT(varMap[varName]); | |
static void INCREMENT(int address) { | |
MoveToCell(address); | |
INCREMENT(); | |
} | |
static void INCREMENT() { | |
mem[cellPointer]++; | |
INSTRUCTIONS.Write(new string('+', 1)); | |
} | |
static void Main(string[] args) { | |
MemoryStream ms = new MemoryStream(); | |
StreamWriter sw = new StreamWriter(ms); | |
sw.Write("1110111011 10011\n"); | |
sw.Write("1010110010 10110\n"); | |
sw.Flush(); | |
ms.Seek(0, SeekOrigin.Begin); | |
INPUT = ms; | |
ProgramV5(2); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment