IOCCC Nineteen

This year’s EDAMAME award goes out to yours truly. “The what?!” you ask. It’s an award in a category created to honor my winning entry to the 19th International Obfuscated C Code Contest. Here’s the award winning code:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define PI 314
#define Z if
#define P a->b
#define Q else
#define W =f();
#define X char
#define J while
#define N return
#define V struct e

#define  g(_,a)((_&&a)?!strcmp(_,a):0)
typedef V*d; V{ d o,_; X*b; int c; };
d f() { d _=(d)malloc(sizeof(V)); _
->b=0; _->o=_->_=0; _->c=1>>1>1;
N _; } d k,l,m,n,o,p,q,r; d j
() { d _=l; d a W a->o W
l->o=a; l W l-> _=_;
N a; } d u(d _,
X*a){ J(_){
Z(g(a,_
->b)
){
 N
_;
} _=
_->_; }
N 0; } d s
(X*q){ d _=n; Z
(g("q", q)){ N o; }  
J(PI){ _=u(_,"cde"); _=_
-> _ ; Z ( g (q, _->b) ){ N _
->_ ; } } } void t(d a, d _) { d 
  S,I,M,U,L,A,T,O,R  ; Z(a==o){ S W
S->o W m->o=S; I=m; m W m->_=I; _=_->
_; J(_) { S->o->o=_->o; I=S->o; S->o W
S->o->_=I; _->o->o->o=S; I=_->o->o; _
->o->o  W _->o->o->_=I; _=_->_; } } 
Q { M W _=_->_; J(57-*P){ U=M; U
->b=P; U->o=_->o; M W M->_=U;
_=_->_; a=a->_; } a=a->_
; J(a&&!g("qtm",P)&&
!g("cde",P)){ L
=s (P); a=a
->_; A=
L; T
 W
O=
T;
J(*L
->b-57){ R
=g("/",P)?j():g
(P,"0")?p:g("b",P)?
q:g(P,"j")?r:0; Z(!!!R){
R=u(M,P); Z(!R) { R=j(); U=M;
U->b=P; U->o=R; M W M->_=U; } Q{
R=R->o; } } O=O->_ W O->o=R; O->b=L
->b; L=L->_; a=a->_; } t(A, T); } } }
void h(d e){ d _,a,c, z=e->o->_; J(z){ 
_=z->o; c=_->o->_; a= c->_->_->o; c=_
->c?c->_->o :c->o; Z(c->c<a->c) { c
->c++; h(c); } Q Z(a->c<c->c){ a
->c++; h(a); } z=z->_; } } X*
v(X*_,int O){ X*s=(X*)m\
alloc(strlen(_)*siz\
eof(X)); X*l=s;
J((*l++=*_?
*_-O:0)
)_++
;N
s;
 }
/**/
int ma\
in(){d a,_
,b;d    T,O,F,U
,    R,  E, L, A, Y
; X c[PI],x[PI],w[PI],*y
,*B,*d,*K=v("Cvjme!dpnqmfuf;\
!&e!dpnqpofout-!&e!opeft/\x0b",1
),*e=v("&e;!&t\x0b\0nbjo)*|jou!j>1\
<gps)<j=51<j,,*qsjoug)#&e!#-j+j,j,52\
*<~",1); int i,z,C,G,H,D,I ; k W l W m
W n W o W p W q W r W b=o; for(*x=D=I
=i=0; 5-i; i++){ b->b=i&4?v(";",2):
v("s",2); b=b->_ W } H=p->c=1; p
->o W r->o W q->o W a=n; J(g\
ets(c)){ d=c; J(*d){ *d=
*d<65||*d>90 ?*d:*d+
32; d++; } y=s\
trchr(c,35)
; Z(y){
*y=0
 ;
 }
 B
=st\
rtok(c,
" "); J(B)
{ a=a->_ W P=v(
B,1); Z(g("qtm",P))
{ _=a; } B=strtok(0," ")
; } } _=_->_; z=atoi(v(_->b,-
1)); _=_->_; C=atoi(v(_->b,-1));
G=C; _=_->_; T=s(_->b); _=_->_; O W
F=O; U=k; J(_&&!g( "cde",_->b)){ i=*_
->b; R=i-47?48-i?i-98?106-i?0:r:q:p:j(
); Z(!R){ R=j(); U=U->_ W U->o=R; } F
= F->_ W F->o=R; _=_->_; } t(T, O); 
E=m->_; J(E){ D++; E=E->_; } L=l
->_; J(L){ I++; L =L->_; } p\
rintf(K,D,I); for(i='\''
/'\''; z>i; i++){ J(
!--G){ G=C; H=1
-H ; break;
} r->c=
! (q
->
c=
H)
; L=
l->_; J
(L) { L->o
->c=!1; L=L->_;
} h(p); Z(q->c){ h(
q); } Q{ h(r); } E=m->_;
J(E){ A=E->o; A->c=A->o->_->_
->_->_->o->c; E= E->_; } Y=k->_; 
d=w; J(Y){ *d++=48+Y->o->c; Y=Y->_;
} *d=0; Z(!g(w,x)){ strcpy(x,w); pri\
ntf (e,  i,  w   ) ;  }  }   N  0  ; }

The program is a C version of my TOFU Circuit Simulator. EDAMAME stands for Electronic Design Automation Mechanical Abstract Machine Emulator. If the pun still escapes you, go here: http://en.wikipedia.org/wiki/Edamame. If you still can’t figure out what the IOCCC is, try this link: http://en.wikipedia.org/wiki/IOCCC.

To create this monstrosity, I started out in Java:

package tofu.ioccc;

import java.io.*;

public class Tofu {
  
  static class List {
    String str;
    List list;
    int value;
    List next;
  }
   
  private static List probes = new List();
  private static List nodes = new List();
  private static List relays = new List();
  private static List tokens = new List();
  private static List relayDef = new List();  
  private static List powerNode = new List();
  private static List clockNode = new List();
  private static List clockNegNode = new List();
  
  private static List newNode() {
    List node = new List();
    node.list = new List();
    nodes.list = node;
    List temp = nodes;
    nodes = new List();
    nodes.next = temp;
    return node;
  }
   
  // returns pointer to first arg of def
  private static List findDef(String name) {
    if ("r".equals(name)) {
      return relayDef;
    }
    List def = tokens;
    for(;;) {
      def = find(def, "def");
      def = def.next;
      if (name.equals(def.str)) {
        return def.next;
      }
    }
  }
  
  private static List find(List list, String name) {
    while(list != null) {
      if (name.equals(list.str)) {
        return list;
      
      list = list.next;
    }
    return null;
  }
   
  public static void build(List def, List argNodes) {
    if (def == relayDef) {
      List relay = new List();
      relay.list = new List();
      relays.list = relay;      
      List temp = relays;
      relays = new List();
      relays.next = temp;
      argNodes = argNodes.next;
      int i = 0;
      while(argNodes != null) {
        relay.list.list = argNodes.list;
        temp = relay.list;
        relay.list = new List();
        relay.list.next = temp;
        argNodes.list.list.list = relay;          
        temp = argNodes.list.list;
        argNodes.list.list = new List();        
        argNodes.list.list.next = temp;  
        argNodes = argNodes.next;
      }
    else {
      List locals = new List();
      argNodes = argNodes.next; 
      while(!":".equals(def.str)) {
        System.out.printf("string is %s\n", def.str);
        List local = locals;
        local.str = def.str;
        local.list = argNodes.list;
        locals = new List();
        locals.next = local;
        argNodes = argNodes.next;     
        def = def.next;
      }
      def = def.next;
      while(def != null && !"run".equals(def.str&& !"def".equals(def.str)) {
        List subdef = findDef(def.str);
        def = def.next;
        List sub = subdef;
        List args = new List();
        List arg = args;
        while(!":".equals(subdef.str)) {
          List node = null;
          if ("0".equals(def.str)) {          
            node = newNode();
          else if ("1".equals(def.str)) { 
            node = powerNode;
          else if ("c".equals(def.str)) {
            node = clockNode;
          else if ("k".equals(def.str)) {
            node = clockNegNode;
          else {
            node = find(locals, def.str);
            if (node == null) {
              node = newNode();
              List local = locals;
              local.str = def.str;
              local.list = node;
              locals = new List();
              locals.next = local;
            else {
              node = node.list;
            }
          }
          arg = arg.next = new List();
          arg.list = node;
          arg.str = subdef.str;                    
          subdef = subdef.next;
          def = def.next;
        }
        build(sub, args);
      }
    }
  }
  
  private static void flow(List node) {
    List rs = node.list.next;
    while(rs != null) {
      List relay = rs.list;      
      List coil = relay.list.next.next.next.next.list;
      List lever = relay.list.next.next.next.list;
      List normallyDisconnected = relay.list.next.next.list;
      List normallyConnected = relay.list.next.list;
      if (relay.value == 1) {
        if (lever.value == && normallyDisconnected.value == 0) {
          normallyDisconnected.value = 1;
          flow(normallyDisconnected);
        else if (lever.value == && normallyDisconnected.value == 1) {
          lever.value = 1;
          flow(lever);
        }
      else {
        if (lever.value == && normallyConnected.value == 0) {
          normallyConnected.value = 1;
          flow(normallyConnected);
        else if (lever.value == && normallyConnected.value == 1) {
          lever.value = 1;
          flow(lever);
        }
      }
      rs = rs.next;
    }
  }
  
  public static void main(String[] asthrows Throwable {
    
    List rDef = relayDef;
    for(int i = 0; i < 5; i++) {
      rDef.str = (i == 4":" "r";
      rDef = rDef.next = new List();
    }
    
    powerNode.value = 1;
    powerNode.list = new List();
    clockNegNode.list = new List();
    clockNode.list = new List();
    
    BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
    String input = null;    
    List tokenNode = tokens; 
    List runNode = null;
    
    // Build token list
    while((input = br.readLine()) != null) {
      int commentStart = input.indexOf('#');
      if (commentStart >= 0) {
        input = input.substring(0, commentStart);
      }
      input = input.trim().toLowerCase();
      if (input.length() == 0) {
        continue;
      }
      String[] tokens = input.split("\\s+");
      for(int i = 0; i < tokens.length; i++) {
        tokenNode = tokenNode.next = new List();
        tokenNode.str = tokens[i];
        if ("run".equals(tokens[i])) {
          runNode = tokenNode;
        }
      }         
    }
    
    runNode = runNode.next;
    int iterations = Integer.parseInt(runNode.str);
    runNode = runNode.next;
    int halfClock = Integer.parseInt(runNode.str);
    int clock = halfClock;
    int power = 1;
    runNode = runNode.next;    
    List def = findDef(runNode.str);
    runNode = runNode.next;
    List args = new List();
    List arg = args;
    List temp = null;
    List probe = probes;
    while(runNode != null && !"def".equals(runNode.str)) {
      List node = null;
      if ("0".equals(runNode.str)) {          
        node = newNode();
      else if ("1".equals(runNode.str)) { 
        node = powerNode;
      else if ("c".equals(runNode.str)) {
        node = clockNode;
      else if ("k".equals(runNode.str)) {
        node = clockNegNode;
      else if ("?".equals(runNode.str)) {
        node = newNode();
        probe = probe.next = new List();
        probe.list = node;
      
      arg = arg.next = new List();
      arg.list = node;            
      runNode = runNode.next;
    }
    build(def, args);  
    
    int relayCount = 0;
    int nodeCount = 0;
    List rs = relays.next;
    while(rs != null) {
      relayCount++;
      rs = rs.next;
    }    
    List ns = nodes.next;
    while(ns != null) {
      nodeCount++;
      ns = ns.next;
    }
    System.out.printf("Build complete: %d components, %d nodes.%n",
        relayCount, nodeCount);
    
    String last = null;
    StringBuffer sb = new StringBuffer();
    for(int i = 1; i <= iterations; i++) {
      if (--clock == 0) {        
        clock = halfClock;  
        if (power == 1) {
          power = 0;
        else {
          power = 1;
        }
      
      clockNode.value = power;
      clockNegNode.value = (power == 00;
      sb.setLength(0);
      ns = nodes.next;
      while(ns != null) {
        ns.list.value = 0;
        ns = ns.next;
      }
      flow(powerNode);
      if (clockNode.value == 1) {
        flow(clockNode);
      else {
        flow(clockNegNode);
      }
      rs = relays.next;
      while(rs != null) {
        List relay = rs.list;
        relay.value = relay.list.next.next.next.next.list.value;
        rs = rs.next;
      }  
      
      List ps = probes.next;
      while(ps != null) {
        sb.append(ps.list.value);
        ps = ps.next;
      }
      String current = sb.toString();
      if (!current.equals(last)) {
        System.out.printf("%d: %s%n", i, current);
      }
      last = current;
    }
  }
}

As a first level of obfuscation, the data structures are built entirely out of List nodes. Each node stores a string, a number and 2 child nodes. These nodes are hooked together to form linked lists and trees (lists of lists) for parsing the input file and for representing the circuitry in memory.

The Java code was readily converted into C code:

#include <stdlib.h>
#include <stdio.h>
#include <string.h>

typedef struct LIST* List;

struct LIST {
  char* str;  
  List list;
  int value;
  List next;
}

List newList() {
  List list = (List)malloc(sizeof(struct LIST));
  list->str = NULL;  
  list->list = NULL;
  list->value = 0;
  list->next = NULL;
  return list;
}

List probes;
List nodes;
List relays;
List tokens;
List relayDef;  
List powerNode;
List clockNode;
List clockNegNode;

int streq(char *s1, char *s2) {
  if (s1 == NULL || s2 == NULL) {
    return 0;
  }
  return strcmp(s1, s2== 0;
}
  
List newNode() {
  List temp = nodes;
  List node = newList();
  node->list = newList();
  nodes->list = node;  
  nodes = newList();
  nodes->next = temp;
  return node;
}

List find(List list, char* name) {
  while(list) {
    if (streq(name, list->str)) {
      return list;
    
    list = list->next;
  }
  return NULL;
}
   
List findDef(char* name) {
  List def = tokens;
  if (streq("r", name)) {
    return relayDef;
  }  
  for(;;) {
    def = find(def, "def");
    def = def->next;
    if (streq(name, def->str)) {
      return def->next;
    }
  
}
  
void build(List def, List argNodes) {
  List relay;
  List temp;
  List locals;
  List local;
  List subdef;
  List sub;
  List args;
  List arg;
  List node;
  if (def == relayDef) {
    relay = newList();
    relay->list = newList();
    relays->list = relay;      
    temp = relays;
    relays = newList();
    relays->next = temp;
    argNodes = argNodes->next;
    while(argNodes) {
      relay->list->list = argNodes->list;
      temp = relay->list;
      relay->list = newList();
      relay->list->next = temp;
      argNodes->list->list->list = relay;          
      temp = argNodes->list->list;
      argNodes->list->list = newList();        
      argNodes->list->list->next = temp;  
      argNodes = argNodes->next;
    }
  else {
    locals = newList();
    argNodes = argNodes->next;
    while(!streq(":", def->str)) {
      local = locals;
      local->str = def->str;
      local->list = argNodes->list;
      locals = newList();
      locals->next = local;
      argNodes = argNodes->next;
      def = def->next;
    }
    def = def->next;
    while(def && !streq("run", def->str&& !streq("def", def->str)) {
      subdef = findDef(def->str);
      def = def->next;
      sub = subdef;
      args = newList();
      arg = args;
      while(!streq(":", subdef->str)) {
        node = NULL;
        if (streq("0", def->str)) {          
          node = newNode();
        else if (streq("1", def->str)) { 
          node = powerNode;
        else if (streq("c", def->str)) {
          node = clockNode;
        else if (streq("k", def->str)) {
          node = clockNegNode;
        else {
          node = find(locals, def->str);
          if (!node) {
            node = newNode();
            local = locals;
            local->str = def->str;
            local->list = node;
            locals = newList();
            locals->next = local;
          else {
            node = node->list;
          }
        }
        arg = arg->next = newList();
        arg->list = node;
        arg->str = subdef->str;                    
        subdef = subdef->next;
        def = def->next;
      }
      build(sub, args);
    }
  }
}
  
void flow(List node) {
  List relay;      
  List coil;
  List lever;
  List normallyDisconnected;
  List normallyConnected;
  List rs = node->list->next;
  while(rs) {
    relay = rs->list;      
    coil = relay->list->next->next->next->next->list;
    lever = relay->list->next->next->next->list;
    normallyDisconnected = relay->list->next->next->list;
    normallyConnected = relay->list->next->list;
    if (relay->value) {
      if (lever->value && !normallyDisconnected->value) {
        normallyDisconnected->value = 1;
        flow(normallyDisconnected);
      else if (!lever->value && normallyDisconnected->value) {
        lever->value = 1;
        flow(lever);
      }
    else {
      if (lever->value && !normallyConnected->value) {
        normallyConnected->value = 1;
        flow(normallyConnected);
      else if (!lever->value && normallyConnected->value) {
        lever->value = 1;
        flow(lever);
      }
    }
    rs = rs->next;
  }
}

char* newString(char *str) {
  char* s = (char*)calloc(strlen(str), sizeof(char));
  strcpy(s, str);
  return s;
}

int main(void) {
  List tokenNode;
  List runNode;
  List rDef;
  char input[256];
  char last[256"";
  char current[256];
  int i;
  char* commentStart;
  char* result;
  char* ch;
  int iterations;
  int halfClock;
  int clock;
  int power;  
  int relayCount = 0;
  int nodeCount = 0;
  List def;
  List args;
  List arg;
  List probe; 
  List node;
  List rs;
  List ns;
  List relay;
  List ps;
  
  probes = newList();
  nodes = newList();
  relays = newList();
  tokens = newList();
  relayDef = newList();  
  powerNode = newList();
  clockNode = newList();
  clockNegNode = newList();
    
  rDef = relayDef;
  for(i = 0; i < 5; i++) {
    rDef->str = (i == 4? newString(":": newString("r");
    rDef = rDef->next = newList();
  }
  
  powerNode->value = 1;
  powerNode->list = newList();
  clockNegNode->list = newList();
  clockNode->list = newList();
    
  tokenNode = tokens; 
  
  while(gets(input)) {
    commentStart = strchr(input, '#');
    if (commentStart) {
      *commentStart = '\0';
    }

    result = strtok(input, " ");
    while(result) {
      tokenNode = tokenNode->next = newList();
      tokenNode->str = newString(result);
      if (streq("run", result)) {
        runNode = tokenNode;
      }
      result = strtok(NULL, " ");
    }         
  }
  
  runNode = runNode->next;
  iterations = atoi(runNode->str);
  runNode = runNode->next;
  halfClock = atoi(runNode->str);
  clock = halfClock;
  power = 1;
  runNode = runNode->next; 
  def = findDef(runNode->str);
  runNode = runNode->next;
  args = newList();
  arg = args;
  probe = probes;
  while(runNode && !streq("def", runNode->str)) {
    if (streq("0", runNode->str)) {          
      node = newNode();
    else if (streq("1", runNode->str)) { 
      node = powerNode;
    else if (streq("c", runNode->str)) {
      node = clockNode;
    else if (streq("k", runNode->str)) {
      node = clockNegNode;
    else if (streq("?", runNode->str)) {
      node = newNode();
      probe = probe->next = newList();
      probe->list = node;
    
    arg = arg->next = newList();
    arg->list = node;            
    runNode = runNode->next;
  }
  build(def, args);  
  
  rs = relays->next;
  while(rs) {
    relayCount++;
    rs = rs->next;
  }    
  ns = nodes->next;
  while(ns) {
    nodeCount++;
    ns = ns->next;
  }
  printf("Build complete: %d components, %d nodes.\n",
      relayCount, nodeCount);
  
  for(i = 1; i <= iterations; i++) {
    if (--clock == 0) {        
      clock = halfClock;  
      if (power == 1) {
        power = 0;
      else {
        power = 1;
      }
    
    clockNode->value = power;
    clockNegNode->value = power ? 1;
    ns = nodes->next;
    while(ns) {
      ns->list->value = 0;
      ns = ns->next;
    }
    flow(powerNode);
    if (clockNode->value) {
      flow(clockNode);
    else {
      flow(clockNegNode);
    }
    rs = relays->next;
    while(rs) {
      relay = rs->list;
      relay->value = relay->list->next->next->next->next->list->value;
      rs = rs->next;
    }  
    
    ps = probes->next;
    ch = current;
    while(ps) {
      *ch = ps->list->value ? '1' '0';
      ch++;
      ps = ps->next;
    }
    *ch = '\0';
    if (!streq(current, last)) {
      strcpy(last, current);
      printf("%d: %s\n", i, current);
    }
  }
  return 0;
}

From there, I iteratively applied obfuscations. Functions and variables were renamed to single length names. Some of those were rearranged to spell TOFU, RELAY and SIMULATOR. Chunks of code were replaced with defines. Strings were encrypted by adding 1 to each character value. The poorly named constant PI was defined for array allocation and to occasionally mean true. A triple-NOT is used for NOT. Comparisons against single characters are done via subtraction against the ASCII numerical value of the character. A while-loop is used as an if-statement. Constants are defined with unusual expressions. And so on. I had a little extra space left over; so, I hid a tiny C program in one of the encrypted strings after the null terminator that generates primes using a polynomial.

Several weeks prior to announcing the winners on the IOCCC webpage, the judges share all the winning entries among the winners and they ask for feedback and suggested changes. Óscar Toledo G., winner of Best of Show, sent me the following:

Hi, testing your entry, I've located a memory
assignment that can fail anytime, because the \0
character is written beyond the memory assignment: 

malloc(strlen(_) * sizeof(X)) 

My suggestion is: 

malloc((strlen(_) + 1) * sizeof(X)) 

The following expressions in your entry may have
incorrect evaluations on some compilers, as ANSI C
says that only comma, trinary, and boolean AND & OR
have defined evaluation order. 

O = O->_ W
b = b->_ W
a = a->_ W
U = U->_ W
F = F->_ W 

My suggestion is: 

O->_ W O = O->_; 

Both suggestions are unnecessary if the program
will be running only on x86 and GCC. 

Your entry is impressive, I liked Konrad Zuse
references, and I actually learned something new
about old computers. 

By the way, nice prime numbers! 

Regards,
Óscar Toledo G.

I have no idea how he analyzed my entry, but I used his awesome suggestions to improved my entry:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define PI 314
#define Z if
#define P a->b
#define Q else
#define W =f();
#define X char
#define J while
#define N return
#define V struct e

#define  g(_,a)((_&&a)?!strcmp(_,a):0)
typedef V*d; V{ d o,_; X*b; int c; };
d f() { d _=(d)malloc(sizeof(V)); _
->b=0; _->o=_->_=0; _->c=1>>1>1;
N _; } d k,l,m,n,o,p,q,r; d j
() { d _=l; d a W a->o W
l->o=a; l W l-> _=_;
N a; } d u(d _,
X*a){ J(_){
Z(g(a,_
->b)
){
 N
_;
} _=
_->_; }
N 0; } d s
(X*q){ d _=n; Z
(g("q", q)){ N o; }  
J(PI){ _=u(_,"cde"); _=_
-> _ ; Z ( g (q, _->b) ){ N _
->_ ; } } } void t(d a, d _) { d 
  S,I,M,U,L,A,T,O,R  ; Z(a==o){ S W
S->o W m->o=S; I=m; m W m->_=I; _=_->
_; J(_) { S->o->o=_->o; I=S->o; S->o W
S->o->_=I; _->o->o->o=S; I=_->o->o; _
->o->o  W _->o->o->_=I; _=_->_; } } 
Q { M W _=_->_; J(57-*P){ U=M; U
->b=P; U->o=_->o; M W M->_=U;
_=_->_; a=a->_; } a=a->_
; J(a&&!g("qtm",P)&&
!g("cde",P)){ L
=s (P); a=a
->_; A=
L; T
 W
O=
T;
J(*L
->b-57)
{R=g("/",P)
?j():g(P,"0")?p
:g("b",P)?q:g(P,"j"
)?r:0; Z(!!!R){ R=u(M,P)
; Z(!R) { R=j(); U=M; U->b=P
; U->o=R; M W M->_=U; } Q{ R=R->
o; } } O->_ W O=O->_; O->o=R; O->b
=L->b; L=L->_; a=a->_; } t(A, T); } }
}void h(d e){ d _,a,c, z=e->o->_; J(z)
{ _=z->o; c=_->o->_; a= c->_->_->o; c
=_->c?c->_->o:c->o; Z(c->c<a->c){ c
->c++; h(c); } Q Z(a->c<c->c){ a
->c++; h(a); } z=z ->_; } } X
*v(X*_, int O){ X*s=(X*)
malloc((1+strlen(_))
*sizeof(X)); X*
l=s;J((*l++
=*_?*_-
O:0)
)_
++
;N
s; }
int ma\
in(){d a,_
,b;d    T,O,F,U
,  R,  E,  L,  A,  Y
; X c[PI],x[PI],w[PI],*y
,*B,*d,*K=v("Cvjme!dpnqmfuf;\
!&e!dpnqpofout-!&e!opeft/\x0b",1
),*e=v("&e;!&t\x0b\0nbjo)*|jou!j>1\
<gps)<j=51<j,,*qsjoug)#&e!#-j+j,j,52\
*<~",1); int i,z,C,G,H,D,I ; k W l W m
W n W o W p W q W r W b=o; for(*x=D=I
=i=0; 5-i; i++){ b->b=i&4?v(";",2):
v("s",2); b->_ W b=b->_; } H=p->
c=1; p->o W r->o W q->o W a=n
; J(gets(c)){ d=c; J(*d)
{ *d=*d<65||*d>90 ?*
d:*d+32; d++; }
y=strchr(c
,35);Z(
y){*
y=
0;
 }
B=s\
trtok(c
," "); J(B
){ a->_ W a=a->
_; P=v(B,1); Z(g("q\
tm",P)){ _=a; } B=strtok
(0," "); } } _=_->_; z=atoi(
v(_->b, -1)); _=_->_; C=atoi(v(_
->b,-1)); G=C; _=_->_; T=s(_->b); _
=_->_; O W F=O; U=k; J(_&&!g( "cde",_
->b)){ i=*_->b; R=i-47?48-i?i-98?106-i
?0:r:q:p:j(); Z(!R){ R=j(); U->_ W U=
U->_; U->o=R; } F->_ W F=F->_; F->o
=R; _=_->_; } t(T, O); E=m->_; J
(E){ D++; E=E->_; }L=l->_; J
(L){ I++; L =L->_; } pr\
intf(K,D,I) ; for(i=
'\''/'\''; z>i;
i++){J(!--
G){ G=C
; H=
1-
H;
b\
rea\
k ; } r
->c=!(q->c
=H);L=l->_; J(L
) { L->o->c=!1; L=L
->_; } h(p); Z(q->c){ h(
q); } Q{ h(r); } E=m->_; J(E)
{ A=E->o ; A->c=A->o->_->_->_->_
->o->c; E= E->_; } Y=k->_; d=w; J(Y
){*d++=48+Y->o->c;Y=Y->_;}*d=0;Z(!g(w
,x)){strcpy(x,w);printf(e,i,w);}}N 0;}

DOWNLOAD OBFUSCATED TOFU

2007.12.08