URI: 
       ga.c - brcon2024-hackathons - Bitreichcon 2024 Hackathons
  HTML git clone git://bitreich.org/brcon2024-hackathons git://enlrupgkhuxnvlhsf6lc3fziv5h2hhfrinws65d7roiv6bfj7d652fid.onion/brcon2024-hackathons
   DIR Log
   DIR Files
   DIR Refs
   DIR Tags
   DIR Submodules
       ---
       ga.c (3316B)
       ---
            1 #include <stdint.h>
            2 #include <stdio.h>
            3 #include <stddef.h>
            4 #include <stdlib.h>
            5 #include <string.h>
            6 
            7 struct machine {
            8         uint8_t a;
            9 
           10         uint8_t loads;
           11         uint8_t adds;
           12         uint8_t subs;
           13         uint8_t times;
           14         uint8_t noops;
           15 
           16         uint8_t instr;
           17 };
           18 
           19 enum {
           20         LOAD,
           21         ADD,
           22         SUB,
           23         TIMES,
           24         END,
           25 };
           26 
           27 #define CODE_LENGTH 16
           28 #define POOL_LENGTH 16
           29 struct genome {
           30         uint8_t code[CODE_LENGTH + 1]; /* +1 sentinal (0) */
           31         uint16_t fitness;
           32 } pool[POOL_LENGTH];
           33 
           34 uint8_t newcode[CODE_LENGTH];
           35 
           36 void
           37 execute(struct machine *m, size_t l, uint8_t code[])
           38 {
           39         size_t ip;
           40         int16_t c;
           41 
           42         for (ip = 0; ip < l;) {
           43                 switch (code[ip++] & 0x7) {
           44                 case LOAD:
           45                         m->loads++;
           46                         m->a = code[ip++];
           47                         break;
           48                 case ADD:
           49                         m->adds++;
           50                         c = (int16_t)m->a + code[ip++];
           51                         if (c > 255)
           52                                 m->a = 0;
           53                         else
           54                                 m->a = c;
           55                         break;
           56                 case SUB:
           57                         m->subs++;
           58                         c = (int16_t)m->a - code[ip++];
           59                         if (c < 0)
           60                                 m->a = 0;
           61                         else
           62                                 m->a = c;
           63                         break;
           64                 case TIMES:
           65                         m->times++;
           66                         m->a = (uint16_t)m->a * code[ip++] / 255;
           67                         break;
           68                 case END:
           69                         m->instr++;
           70                         return;
           71                         break;
           72                 default:
           73                         m->noops++;
           74                         break;
           75                 }
           76                 m->instr++;
           77         }
           78 }
           79 
           80 void
           81 mutate(uint8_t code[], size_t l)
           82 {
           83         uint8_t i, bi, j;
           84 
           85         for (j = 0; j < 4; j++) {
           86                 if (rand() % 100 >= 50)
           87                         continue;
           88 
           89                 i = rand() % CODE_LENGTH;
           90                 bi = rand() % 8;
           91 
           92                 code[i] ^= 1 << bi;
           93         }
           94 }
           95 
           96 #define min(a, b) (((a) < (b)) ? (a) : (b))
           97 
           98 void
           99 cross(uint8_t a[], size_t al, uint8_t b[], size_t bl, uint8_t c[], size_t cl)
          100 {
          101         uint8_t i, si, sl;
          102         uint8_t *one, *two;
          103 
          104         if (rand() % 2) {
          105                 one = a;
          106                 two = b;
          107         } else {
          108                 one = b;
          109                 two = a;
          110         }
          111 
          112         si = rand() % (min(al, bl) + 1);
          113         sl = rand() % (min(al, bl) - si + 1);
          114 
          115         for (i = 0; i < si; i++)
          116                 c[i] = one[i];
          117 
          118         for (; i < si + sl; i++)
          119                 c[i] = two[i];
          120 
          121         for (; i < cl; i++)
          122                 c[i] = one[i];
          123 }
          124 
          125 void
          126 cross2(uint8_t a[], size_t al, uint8_t b[], size_t bl, uint8_t c[], size_t cl)
          127 {
          128         uint8_t i;
          129 
          130         for (i = 0; i < al; i++)
          131                 c[i] = a[i] + b[i];
          132 }
          133 
          134 void
          135 printcode(uint8_t code[], size_t l)
          136 {
          137         uint8_t i;
          138 
          139         for (i = 0; i < l;) {
          140                 switch (code[i++] & 0x7) {
          141                 case LOAD:
          142                         printf("LOAD %d ", code[i++]);
          143                         break;
          144                 case ADD:
          145                         printf("ADD %d ", code[i++]);
          146                         break;
          147                 case SUB:
          148                         printf("SUB %d ", code[i++]);
          149                         break;
          150                 case TIMES:
          151                         printf("TIMES %d ", code[i++]);
          152                         break;
          153                 case END:
          154                         printf("END ");
          155                         return;
          156                         break;
          157                 default:
          158                         printf("NOOP ");
          159                         break;
          160                 }
          161         }
          162 }
          163 
          164 int
          165 main(void)
          166 {
          167         struct machine m;
          168         struct genome *g1, *g2, *w1;
          169         size_t i, j;
          170 
          171         for (i = 0; i < POOL_LENGTH; i++) {
          172                 for (j = 0; j < CODE_LENGTH; j++)
          173                         pool[i].code[j] = rand();
          174                 pool[i].code[j] = 0;
          175         }
          176 
          177         do {
          178                 g1 = g2 = w1 = NULL;
          179 
          180                 for (i = 0; i < POOL_LENGTH; i++) {
          181                         memset(&m, 0, sizeof(m));
          182 
          183                         execute(&m, CODE_LENGTH, pool[i].code);
          184                         pool[i].fitness = m.a * 255 / (m.instr + m.loads);
          185 
          186                         if (!g1 || g1->fitness < pool[i].fitness) {
          187                                 g2 = g1;
          188                                 g1 = &pool[i];
          189                         } else if (!g2 || g2->fitness < pool[i].fitness) {
          190                                 w1 = g2;
          191                                 g2 = &pool[i];
          192                         } else if (!w1 || w1->fitness > pool[i].fitness) {
          193                                 w1 = &pool[i];
          194                         }
          195                 }
          196 
          197                 printf("g1->fitness = %d, g2->fitness = %d, w1->fitness = %d\n", g1->fitness, g2->fitness, w1->fitness);
          198                 cross(g1->code, CODE_LENGTH, g2->code, CODE_LENGTH, newcode, CODE_LENGTH);
          199                 mutate(newcode, CODE_LENGTH);
          200 
          201                 printcode(newcode, CODE_LENGTH);
          202                 puts("");
          203 
          204                 memcpy(w1->code, newcode, CODE_LENGTH);
          205         } while (1);
          206 }