Записанные цифры до цифр - понимание короткого запутанного кода

Может кто-нибудь помочь мне понять этот код?

long long n,u,m,b;main(e,r){for(;n++||(e=getchar()|32)>=0;b=
"ynwtsflrabg"[n%=11]-e?b:b*8+n)for(r=b%64-25;e<47&&b;b/=8)for
(n=19;n;"1+DIY/.K430x9G(kC["[n]-42&255^b||(m+=n>15?n:n>9?m%
u*~-u:~r?n+!r*16:n*16,b=0))u=1ll<<6177%n--*4;printf("%llx",m);}

Я нашел некоторые объяснения, но они очень краткие. Что я знаю до сих пор: этот код выводит десятичное число для заданного ввода записанных чисел. Он ищет некоторые комбинации символов, которые образуют числа, и сохраняет эти символы в восьмеричном представлении вместо шестнадцатеричного. Он присваивает некоторые значения найденным комбинациям. Затем он добавляет эти значения к результату (для слов типа "пять", "тринадцать" и т. Д.) Или каким-то образом сдвигает цифры (для слов типа "тысяча" и т. Д.). Это все, что я понял из найденных объяснений: https://www.ioccc.org/2012/kang/hint.html, http://j.mearie.org/post/7462182919/spelt-number-to-decimal.

Я пытался понять это выражение кода по выражению, но я только пришел к бесконечному циклу, где я не понимаю, для чего нужна одна переменная, поскольку она изменяется только позже, но тогда она зависит от следующей переменной, то есть также изменен позже в циклах. Я просто не знаю с чего начать.

Я попытался прокомментировать каждый кусок кода + убрать некоторые запутывания и неясности:

long long n, u, m, b; // = 0

int main(int e, int r) {

/* loop1:*/ for(;
/* --condition: */
/*   if not:*/  n++ || // n++ == 0 <=> n == 0        // Set n += 1
/*     then:*/
/*   if not:*/  (e = getchar() | 32) >= 0;           // Set e <- input char
                // `| 32` transforms upper case to lower case
                // getchar < 0 <=> EOF
/*     then break*/
/* --increment: */
                b =
/*           if:*/  "ynwtsflrabg"[n %= 11] - e ?     // Set n %= 11
/*       then b=*/  b                          :
/*       else b=*/  b * 8 + n)

    /* loop2:*/ for(r = (b % 64) - 25;               // Set r
    /* --condition: */
    /*    if not:*/ (e < 47) && b;
    /*      break*/
    /* --increment: */
                    b /= 8)                          // Set b

        /* loop3:*/ for(n = 19;                      // Set n
        /* --condition: */
        /*   if not:*/  n; // <=> n != 0
        /*     then break */
        /* --increment: */
        /*   if not:*/  ("1+DIY/.K430x9G(kC["[n] - 42) & 255 ^ b ||
                        /* <=> {7, 1, 26, 31, 47, 5, 4, 33, 10, 9, 6, 78, 
                                15, 29, 254, 65, 25, 49, 214}[n] == b */
        /*     then:*/  (m +=                       // Set m
        /*             if:*/  n > 15           ?
        /*        then m+=*/  n                :
        /*        else if:*/  n > 9            ?
        /*        then m+=*/  m % u * ~-u      :
                              // <=> m % u * (u - 1)
        /*        else if:*/  ~(int)r          ?
        /*        then m+=*/  n + !(int)r * 16 :
        /*        else m+=*/  n * 16,
                        b = 0))                      // Set b

        /* --body: */   u = 1ll << (6177 % n-- * 4); // Set u, n
                        // <=> u = pow(2, 6177 % n-- * 4)

    printf("%llx\n", m);
}

Большая часть этого переписанного кода может выглядеть даже страшнее, чем оригинал, но мне просто нужно было пройти шаг за шагом, так что, возможно, это поможет кому-то еще.

Кажется, что вывод генерируется в последнем цикле, в m += ..., Но я не могу понять условие выше этого: "1+DIY/.K430x9G(kC["[n] - 42) & 255 ^ b, Это переводится как: {7, 1, 26, 31, 47, 5, 4, 33, 10, 9, 6, 78, 15, 29, 254, 65, 25, 49, 214}[n] == b, где моя {...} нотация ведет себя как строковый литерал, содержащий символы, соответствующие этим числам - которые на данный момент кажутся мне бессмысленными.

редактировать

Кто-то проголосовал за закрытие этого вопроса за неясность. Чтобы было понятно, что мне нужно:

Я был бы признателен за любые подсказки или идеи по любому из методов, используемых в этом коде. Как например:

  • Автор кода использовал преднамеренное запутывание: i["foo"] вместо "foo"[i],
  • Автор сократил (u - 1) выражение как ~-u

Мои основные проблемы с деталями:

  • "1+DIY/.K430x9G(kC["[n]-42&255^b - Почему эти персонажи?
  • m+=n>15?n:n>9?m%u*~-u:~r?n+!r*16:n*16,b=0) - Почему эти условия на n?
  • e<47 - Зачем 47 - / персонаж?

0 ответов

Другие вопросы по тегам