changeset 4851:e551b31f713f

<mroman_> fetch http://eso.mroman.ch/crunchfuck/crunchfuck.c
author HackBot
date Fri, 12 Sep 2014 14:05:13 +0000
parents 883ba6b025fe
children 6c8a9319f36f
files crunchfuck.c
diffstat 1 files changed, 221 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/crunchfuck.c	Fri Sep 12 14:05:13 2014 +0000
@@ -0,0 +1,221 @@
+/*
+Copyright (c) 2012, Roman Muentener, fmnssun _at_ gmail [dot] com
+
+Permission to use, copy, modify, and/or distribute this software for any 
+purpose with or without fee is hereby granted, provided that the above 
+copyright notice and this permission notice appear in all copies.
+
+THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 
+WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 
+AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, 
+INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM 
+LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE 
+OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 
+PERFORMANCE OF THIS SOFTWARE.
+*/
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <assert.h>
+#include <limits.h>
+
+int valid_bf(char* program);
+char* next_bf(char* program, int pos);
+void interpret(char* program, int* solutions, unsigned long int boundl, unsigned long int boundh);
+inline int mod(int a, int b);
+
+#define PROG_MAX_LEN 40
+#define PROG_MAX_STEPS 5000
+
+int main(int argc, char* argv[])
+{
+  printf("  _                        \n");
+  printf(" / `_   _  _  /__/|   _  /_\n");
+  printf("/_,//_// //_ / // /_//_ /\\ \n");
+  printf("\n");
+
+
+  char* program;
+  int* solutions;
+
+  if(argc != 5) {
+    printf("Usage: %s prog boundl boundh n\n", argv[0]);
+    printf("\tprog - A start program (example: ++++++++)\n");
+    printf("\tn - How many (next) programs you want to check\n");
+    exit(1);
+  }
+
+  fflush(stdout);
+
+  program = calloc(PROG_MAX_LEN, sizeof(char));
+  assert(program != NULL);
+
+  solutions = calloc(265, sizeof(int));
+  assert(solutions != NULL);
+
+  strncpy(program, argv[1], PROG_MAX_LEN - 1);
+  
+  unsigned long int limit = strtoul(argv[2], NULL, 10), i = 0;
+  unsigned long int boundl = strtoul(argv[3], NULL, 10);
+  unsigned long int boundh = strtoul(argv[4], NULL, 10);
+  assert(limit > 0);
+  
+
+  //printf("Reading a list of already known solutions for...\n");
+  /*while(1) {
+    int d;
+    if(scanf("%d",&d) == 1) {
+      solutions[d] = 1;
+    }
+    else break;
+  }*/
+  //printf("Done reading...\n");
+  
+
+  for(;i < limit;i++) {
+    if(valid_bf(program))
+      interpret(program, solutions, boundl, boundh);
+    program = next_bf(program, 0);
+  }
+
+  printf("Last program: %s\n", program);
+}
+
+inline int mod(int a, int b) {
+  if(a > b)
+    return a - b;
+  if(a < 0)
+    return a + b;
+  return a;
+}
+
+void interpret(char* program, int* solutions, unsigned long int boundl, unsigned long int boundh)
+{
+  unsigned char memory[256] = {0};
+  short iptr = 0;
+  unsigned char cptr = 0;
+  short steps = 0;
+  short len = strlen(program);
+
+  while(iptr < len) {
+    if(steps > PROG_MAX_STEPS) return;
+    steps++;
+
+    //printf("%d %c (iptr := %d, cptr := %d)\n",steps, program[iptr], iptr, cptr); 
+
+    switch(program[iptr]) {
+      case '+':
+        memory[cptr]++;
+        break;
+      case '-':
+        memory[cptr]--;
+        break;
+      case '>':
+        cptr++;
+        break;
+      case '<':
+        cptr--;
+        break;
+      case '[':
+        if(memory[cptr] == 0) {
+          int lvl = 0;
+          iptr++;
+          while(iptr < len) {
+            if(program[iptr] == ']')
+              if(lvl < 1) break;
+              else lvl--;
+            if(program[iptr] == '[')
+              lvl++;
+            iptr++;
+          }
+        }
+        break;
+      case ']':
+        if(memory[cptr] != 0) {
+          int lvl = 0;
+          iptr--;
+          while(iptr >= 0) {
+            if(program[iptr] == '[')
+              if(lvl < 1) break;
+              else lvl--;
+            if(program[iptr] == ']')
+              lvl++;
+            iptr--;
+          }
+        }
+        break;
+    }
+
+    iptr++;
+  }
+
+  if(!solutions[memory[cptr]]) {
+    if(memory[cptr] > boundl && memory[cptr] < boundh)
+      printf("Result: %u -> %s\n", memory[cptr], program);
+    fflush(stdout);
+    solutions[memory[cptr]] = 1;
+  }
+}
+
+char* next_bf(char* program, int pos)
+{
+  if(pos >= PROG_MAX_LEN) {
+    fputs("Presumed maximum length exceeded!\n", stderr);
+    exit(1);
+  }
+
+  /* Next instruction */
+  switch(program[pos]) {
+    case '\0':
+      program[pos] = '+';
+      break;
+    case '+':
+      program[pos] = '-';
+      break;
+    case '-':
+      program[pos] = '>';
+      break;
+    case '>':
+      program[pos] = '<';
+      break;
+    case '<':
+      program[pos] = '[';
+      break;
+    case '[':
+      program[pos] = ']';
+      break;
+    case ']':
+      program[pos] = '+';
+      return next_bf(program, pos+1);
+  }
+
+  return program;
+}
+
+int valid_bf(char* program)
+{
+  int level = 0;
+  while(*program) {
+    char c = *program;
+    switch(c) {
+      case '[':
+        level++;
+        break;
+      case ']':
+        level--;
+        break;
+      default: break;
+    }
+
+    if(level < 0)
+      return 0;
+
+    program++;
+  }
+
+  if(level != 0)
+    return 0;
+
+  return 1;
+}