Skip to content

Instantly share code, notes, and snippets.

@jrocha
Created March 11, 2020 02:44
Show Gist options
  • Save jrocha/4fc6f24313f6e327c277687ee5e290af to your computer and use it in GitHub Desktop.
Save jrocha/4fc6f24313f6e327c277687ee5e290af to your computer and use it in GitHub Desktop.
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