#include <stdio.h>
#include <string.h>
#include <malloc.h>
unsigned int shortRotCrazyPrint(unsigned int C, char goal);
//first character: b -> cause a jump to address 98 which will be encrypted first
// then execution continues with data pointer at 1 and program counter at 99
const char* translation = "5z]&gqtyfr$(we4{WP)H-Zn,[%\\3dL+Q;>U!pJS72FhOA1CB6v^=I_0/8|jsb9m<.TVac`uY*MK'X~xDl}REokN:#?G\"i@";
unsigned int crazy(unsigned int a, unsigned int d){
unsigned int crz[] = {1,0,0,1,0,2,2,2,1};
int position = 0;
unsigned int output = 0;
while (position < 10){
unsigned int i = a%3;
unsigned int j = d%3;
unsigned int out = crz[i+3*j];
unsigned int multiple = 1;
int k;
for (k=0;k<position;k++)
multiple *= 3;
output += multiple*out;
a /= 3;
d /= 3;
position++;
}
return output;
}
unsigned int rotateR(unsigned int d){
unsigned int carry = d%3;
d /= 3;
d += 19683 * carry;
return d;
}
unsigned int memory[59050]; // program
unsigned int memory_runtime[59050]; // memory at runtime: with encrypted commands
unsigned int lastAval = 0; // last value of A register
int main(int a, char* b[]){
int outputCounter = 0;
int i;
unsigned char* out_s;
int C;
int firstIt;
int stop;
if (a > 1){
int pos = 0;
int sameLen = 0;
for (i=1;i<a;i++){
}
if (sameLen == 0)
sameLen++;
out_s
= (unsigned char*)(malloc(sameLen
*sizeof(unsigned char))); for (i=1;i<a;i++){
out_s[pos]=' ';
pos++;
}
if (pos>0)
pos--;
out_s[pos]=0;
}
else{
// READ STRING FROM STDIN
// maximal 10.000 characters!
int pos = 0;
unsigned int result = 0;
out_s
= (unsigned char*)malloc(10001*sizeof(unsigned char)); if (stdin == 0){
printf("Cannot access STDIN.\n"); return -1;
}
while (!feof(stdin
) && pos
< 10000){ result
= fread(out_s
+pos
,1,1,stdin
); if (result<0){
printf("Error while reading from STDIN.\n"); return -1;
}
if (result==0)
break;
pos++;
}
out_s[pos]=0;
}
memory[0] = 'b'; //jmp to 99
for (i=1;i<99;i++){
int nop = (68-(i%94)+94)%94;
if (nop<33) nop+=94;
memory[i]=nop;
}
memcpy(memory_runtime
,memory
,99*sizeof(unsigned int)); memory_runtime[98] = translation[memory[98]-33];
C = 99;
firstIt = 1;
while (*out_s != 0){
int inc;
// if character is still in A register just print it out
if (!firstIt){
if (*out_s == *(out_s-1)){
if (C+1 >= 59049){
goto finish;
}else{
int out = (5-C%94+94)%94;
if (out<33) out+=94;
memory[C] = out;
memory_runtime[C] = translation[out-33];
C++;
out_s++;
continue;
}
}
}
// load character to A register
do {
C += (inc = shortRotCrazyPrint(C, *out_s));
if (inc==0)
out_s++;
}while(inc == 0 && *out_s!=0);
if (inc == 0)
break;
if (C+1 >= 59049){
C-=inc;
goto finish;
}else{
// print A register
int out = (5-C%94+94)%94;
if (out<33) out+=94;
memory[C] = out;
memory_runtime[C] = translation[out-33];
C++;
}
firstIt = 0;
out_s++;
}
finish:
while (C+1 >= 59049){
C-=1;
}
// halt
stop = (81-C%94+94)%94;
if (stop<33) stop+=94;
memory[C] = stop;
memory_runtime[C] = translation[stop-33];
C++;
for (i=0;i<C;i++){
}
return 0;
}
unsigned int shortRotCrazyPrint(unsigned int C, char goal) {
int maxwidth = 1;
int i;
if (((unsigned char)goal >= 154 && (unsigned char)goal <= 208) || goal == 43)
return 0; //TODO: 43 ('+') is possible with one shiftR and 2 crazies. At least a not-efficient + should be iplemented
do{
int rotPos = 0;
int crazyInsteadRot = 0;
if (maxwidth > 1000){
// this should not occur
return 0;
}
if (maxwidth + C >= 59049){
//maximum space exceeded
return 0;
}
do{
unsigned int shift_val;
unsigned int result;
for (i=C;i<C+rotPos;i++){
int nop = (68-i%94+94)%94;
if (nop<33) nop+=94;
memory[i]=nop;
if (memory[i] >= 33 && memory[i] <= 126)
if (i >= 98)
memory_runtime[i] = translation[memory[i]-33];
else
memory_runtime[i] = memory[i];
}
if (!crazyInsteadRot){
int shift = (39-(C+rotPos)%94+94)%94;
if (shift<33) shift+=94;
shift_val = memory_runtime[C+rotPos-98];
memory[C+rotPos] = shift;
if (C+rotPos >= 98)
memory_runtime[C+rotPos] = translation[memory[C+rotPos]-33];
else
memory_runtime[C+rotPos] = memory[C+rotPos];
}else{
int cr = (62-(C+rotPos)%94+94)%94;
if (cr<33) cr+=94;
shift_val = memory_runtime[C+rotPos-98];
memory[C+rotPos] = cr;
if (C+rotPos >= 98)
memory_runtime[C+rotPos] = translation[memory[C+rotPos]-33];
else
memory_runtime[C+rotPos] = memory[C+rotPos];
}
for (i=C+rotPos+1;i<(int)(C+maxwidth);i++){
int nop = (68-i%94+94)%94;
if (nop<33) nop+=94;
memory[i]=nop;
if (memory[i] >= 33 && memory[i] <= 126)
if (i >= 98)
memory_runtime[i] = translation[memory[i]-33];
else
memory_runtime[i] = memory[i];
}
if (rotPos + 1 < maxwidth){
int crzy = (62-(C+maxwidth-1)%94+94)%94;
unsigned int crzy_val = memory_runtime[C+maxwidth-1-98];
if (crzy<33) crzy+=94;
memory[C+maxwidth-1] = crzy;
if (C+maxwidth-1 >= 98)
memory_runtime[C+maxwidth-1] = translation[memory[C+maxwidth-1]-33];
else
memory_runtime[C+maxwidth-1] = memory[C+maxwidth-1];
if (!crazyInsteadRot)
result = crazy(rotateR(shift_val), crzy_val);
else
result = crazy(crazy(lastAval,shift_val), crzy_val);
}else{
if (!crazyInsteadRot)
result = rotateR(shift_val);
else
result = crazy(lastAval,shift_val);
}
if ((unsigned char)result == (unsigned char)goal){
//DONE!
lastAval = result;
return maxwidth;
}
if (crazyInsteadRot){
rotPos++;
crazyInsteadRot = 0;
}else
crazyInsteadRot = 1;
}while (rotPos < maxwidth);
maxwidth++;
}while(1);
}