именно такой вариант с tens = (n >= 10) + (n >= 20) + (n >= 30) , а потом * 205 >> 11 выдала claude и признала поражение, рассмотрев другие варианты:
вариант от codex
Код:
void itoa32(unsigned n, char *s) {
unsigned tens = (n * 26) >> 8;
unsigned ones = n - tens * 10;
if (tens) *s++ = '0' + tens;
*s++ = '0' + ones;
*s = '\0';
}
от gemini (глюк только в if, арифметика у Gemini верна)
рассмотри оба варианта и выдай свой новый. умножение разрешено только 1 раз
У обоих арифметика верна:
(n * 26) >> 8 и
(n * 13) >> 7 здесь эквивалентны. Но у Codex
два умножения: второе — в
.
А у Gemini
ошибки в && нет: это корректный C. При ненулевых десятках правая часть выполняет запись и сдвигает указатель, при нулевых — пропускается. Просто условие замаскировано под логическое выражение.
Мой новый вариант — с одним умножением, без циклов, деления и условной записи:
Code:
void itoa(int n, char *str)
{
unsigned x = (unsigned)n;
unsigned tens = (x * 13u) >> 7;
unsigned ones = x - ((tens << 3) + (tens << 1));
unsigned two = (tens != 0);
str[0] = (char)('0' + tens);
str[two] = (char)('0' + ones);
str[two + 1] = '\0';
}
При однозначном числе вторая запись перезаписывает предварительный ноль в str[0]; при двузначном — кладёт единицы в str[1]. Предусловия прежние: 0 ≤ n ≤ 32, буфер минимум 3 байта.
Точность десятков: если n = 10a + b, то 13n = 128a + 2a + 13b. Здесь остаток меньше 128, поэтому сдвиг даёт ровно a.
Арифметику Gemini оставил — исправлять исправное ради турнирной таблицы незачем. Быстрее ли такая запись обычного if, без конкретного компилятора и замеров не заявляю.
Sol/medium за 20,2с и $0,0147 · в сутки 195 за $3,8321 · в месяц 204 за $4,1379