W2 · debug_snippet.cpp

3D 폴딩 / 공간 · 2503 단백질폴딩
W2_folding/debug_snippet.cpp
// W2 debug_snippet.cpp — 2503 단백질폴딩 개선 힌트 출력
// 사용: user.cpp 상단 복붙. process() 시작 dbg_init(), fold 시도 dbg_fold(), 종료 dbg_report().

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

static const int SPACE_LEN_DBG = 100;
static const int MAX_AMINO_DBG = 20;
static const int AMINO_LEN_DBG = 28;

typedef struct { char symbol; bool connector; int x,y,z; } DbgElement;

static clock_t gDbgStart;
static double gDbgElapsedMs() { return ((double)(clock()-gDbgStart)/CLOCKS_PER_SEC)*1000.0; }

static int gDbgApplied = 0;
static int gDbgAccepted = 0;
static int gDbgReverted = 0;
static long long gDbgBest = 0;
static long long gDbgCur = 0;

static void dbg_init() {
    gDbgStart = clock();
    gDbgApplied = gDbgAccepted = gDbgReverted = 0;
    gDbgBest = gDbgCur = 0;
}

// 핵심: verify 흉내 + SCORE 분해 (protein()으로 읽은 elements 기반)
// 반환: ok=1 (합법), 0=위반. 분해 지표는 stderr 출력.
static int dbg_verify_and_score(DbgElement elems[MAX_AMINO_DBG][AMINO_LEN_DBG], int aminoCount) {
    static int space[SPACE_LEN_DBG][SPACE_LEN_DBG][SPACE_LEN_DBG];
    memset(space, 0, sizeof(space));

    int oob = 0, overlap = 0;
    int xmin=999, xmax=-1, ymin=999, ymax=-1, zmin=999, zmax=-1;
    int h=0,c=0,o=0,n=0,s=0;

    for (int ai = 0; ai < aminoCount; ai++) {
        for (int ei = 0; elems[ai][ei].symbol; ei++) {
            int x = elems[ai][ei].x, y = elems[ai][ei].y, z = elems[ai][ei].z;
            char sym = elems[ai][ei].symbol;
            if (x<0||x>=SPACE_LEN_DBG||y<0||y>=SPACE_LEN_DBG||z<0||z>=SPACE_LEN_DBG) { oob++; continue; }
            if (space[z][y][x]) { overlap++; continue; }
            int w = 0;
            switch(sym) {
                case 'H': w=1; h++; break;
                case 'C': w=2; c++; break;
                case 'O': w=5; o++; break;
                case 'N': w=10; n++; break;
                case 'S': w=30; s++; break;
            }
            space[z][y][x] = w;
            if (x<xmin)xmin=x; if (x>xmax)xmax=x;
            if (y<ymin)ymin=y; if (y>ymax)ymax=y;
            if (z<zmin)zmin=z; if (z>zmax)zmax=z;
        }
    }

    long long total = 0, ss=0, sn=0, nn=0, hh=0;
    for (int z=1; z<SPACE_LEN_DBG-1; z++)
      for (int y=1; y<SPACE_LEN_DBG-1; y++)
        for (int x=1; x<SPACE_LEN_DBG-1; x++) {
            int v = space[z][y][x];
            if (!v) continue;
            int w;
            w=space[z-1][y][x]; total+=(long long)v*w;
            w=space[z+1][y][x]; total+=(long long)v*w;
            w=space[z][y-1][x]; total+=(long long)v*w;
            w=space[z][y+1][x]; total+=(long long)v*w;
            w=space[z][y][x-1]; total+=(long long)v*w;
            w=space[z][y][x+1]; total+=(long long)v*w;
        }

    int ok = (oob==0 && overlap==0);
    fprintf(stderr, "[VERIFY] ok=%d oob=%d overlap=%d bbox=[%d..%d,%d..%d,%d..%d] ",
            ok, oob, overlap, xmin,xmax, ymin,ymax, zmin,zmax);
    fprintf(stderr, "[SCORE] total=%lld H=%d C=%d O=%d N=%d S=%d\n",
            total, h, c, o, n, s);
    return ok ? (int)1 : 0;  // total은 전역으로 별도 전달 필요 시 수정
}

static void dbg_fold_attempt(int accepted, int reverted) {
    gDbgApplied++;
    if (accepted) gDbgAccepted++;
    if (reverted) gDbgReverted++;
    if ((gDbgApplied % 2000) == 0) {
        fprintf(stderr, "[FOLD] applied=%d accepted=%d reverted=%d accept_rate=%.3f elapsed=%.0fms\n",
                gDbgApplied, gDbgAccepted, gDbgReverted,
                (double)gDbgAccepted/gDbgApplied, gDbgElapsedMs());
    }
}

static void dbg_report(int tc) {
    fprintf(stderr, "[TC%d FINAL] applied=%d accepted=%d reverted=%d best=%lld elapsed=%.0fms\n",
            tc, gDbgApplied, gDbgAccepted, gDbgReverted, gDbgBest, gDbgElapsedMs());
}