В ответ на (удивительные) гольфы orlp
:
Корректность должна быть на первом месте
- Большинство из них разбиты на некоторые целочисленные типы. Это включает в себя версию от ОП
- Интересно , они делают работу
int16_t
- так что есть предположение. Вероятно, сдвиги битов должны были бы +16 для 32-битных целых (это почти везде в наши дни). Это делает их персонаж больше ...
Единственный «правильный» способ написать это, IMO, это (x>3) && (x > y+1)
, возможно, игра в гольф x>3&x>y+1
( до 9 символов).
(Вы действительно должны принять во внимание возможность (более крупных) типов без знака, тем более что unsigned-ness является «заразной» в выражениях C ++. Я предполагаю, что «исправление» того, что с помощью соответствующих static_cast<>
s, как бы побеждает цель ...)
ОБНОВИТЬ
С помощью следующих тестов я смог выяснить, какие выражения на самом деле работают надежно:
Live On Coliru
#define REPORT(caption, expr) do {\
do_report(caption, [](T x, T y) -> bool { return (expr); }, #expr); } while (false)
template <typename T> struct driver {
static void run() {
std::cout << "\n" << __PRETTY_FUNCTION__ << "\n";
// the only two correct implementations:
REPORT("MASTER" , (x>3) && (x>y+1));
REPORT("GOLF" , x>3&x>y+1);
REPORT("lookup" , "000000000000000000000000111000111100"[x*6+y]-'0');
// failing sometimes:
REPORT("question", (x>3)&(x-y>1));
REPORT("orlp0" , x>3&x-y>1);
REPORT("orlp2" , ~y+x>2>>y);
REPORT("orlp3" , x*x-y*y>9);
REPORT("orlp4" , ~y>x/~3*x);
REPORT("orlp5" , -3>>y>y-x);
REPORT("orlp6" , ~y+x<<y>2);
// failing always
REPORT("orlp1" , -x<~y>4>x);
}
private:
static void do_report(std::string const& caption, bool (*f)(T,T), char const* expression) {
std::string r;
for (T x = 0; x < 6; ++x) for (T y = 0; y < 6; ++y) r += f(x, y)?'1':'0';
bool const correct = "000000000000000000000000111000111100" == r;
std::cout << (correct?"OK\t":"ERR\t") << r << "\t" << caption << "\t" << expression << "\n";
}
};
int main() {
driver<int8_t>::run();
driver<int16_t>::run();
driver<int32_t>::run();
driver<int64_t>::run();
driver<uint8_t>::run();
driver<uint16_t>::run();
driver<uint32_t>::run();
driver<uint64_t>::run();
}
Вывод на колиру, вот для справки:
static void driver<T>::run() [with T = signed char]
OK 000000000000000000000000111000111100 MASTER (x>3) && (x>y+1)
OK 000000000000000000000000111000111100 GOLF x>3&x>y+1
OK 000000000000000000000000111000111100 lookup "000000000000000000000000111000111100"[x*6+y]-'0'
OK 000000000000000000000000111000111100 question (x>3)&(x-y>1)
OK 000000000000000000000000111000111100 orlp0 x>3&x-y>1
OK 000000000000000000000000111000111100 orlp2 ~y+x>2>>y
OK 000000000000000000000000111000111100 orlp3 x*x-y*y>9
OK 000000000000000000000000111000111100 orlp4 ~y>x/~3*x
OK 000000000000000000000000111000111100 orlp5 -3>>y>y-x
OK 000000000000000000000000111000111100 orlp6 ~y+x<<y>2
ERR 000000000000000000000000000000000000 orlp1 -x<~y>4>x
static void driver<T>::run() [with T = short int]
OK 000000000000000000000000111000111100 MASTER (x>3) && (x>y+1)
OK 000000000000000000000000111000111100 GOLF x>3&x>y+1
OK 000000000000000000000000111000111100 lookup "000000000000000000000000111000111100"[x*6+y]-'0'
OK 000000000000000000000000111000111100 question (x>3)&(x-y>1)
OK 000000000000000000000000111000111100 orlp0 x>3&x-y>1
OK 000000000000000000000000111000111100 orlp2 ~y+x>2>>y
OK 000000000000000000000000111000111100 orlp3 x*x-y*y>9
OK 000000000000000000000000111000111100 orlp4 ~y>x/~3*x
OK 000000000000000000000000111000111100 orlp5 -3>>y>y-x
OK 000000000000000000000000111000111100 orlp6 ~y+x<<y>2
ERR 000000000000000000000000000000000000 orlp1 -x<~y>4>x
static void driver<T>::run() [with T = int]
OK 000000000000000000000000111000111100 MASTER (x>3) && (x>y+1)
OK 000000000000000000000000111000111100 GOLF x>3&x>y+1
OK 000000000000000000000000111000111100 lookup "000000000000000000000000111000111100"[x*6+y]-'0'
OK 000000000000000000000000111000111100 question (x>3)&(x-y>1)
OK 000000000000000000000000111000111100 orlp0 x>3&x-y>1
OK 000000000000000000000000111000111100 orlp2 ~y+x>2>>y
OK 000000000000000000000000111000111100 orlp3 x*x-y*y>9
OK 000000000000000000000000111000111100 orlp4 ~y>x/~3*x
OK 000000000000000000000000111000111100 orlp5 -3>>y>y-x
OK 000000000000000000000000111000111100 orlp6 ~y+x<<y>2
ERR 000000000000000000000000000000000000 orlp1 -x<~y>4>x
static void driver<T>::run() [with T = long int]
OK 000000000000000000000000111000111100 MASTER (x>3) && (x>y+1)
OK 000000000000000000000000111000111100 GOLF x>3&x>y+1
OK 000000000000000000000000111000111100 lookup "000000000000000000000000111000111100"[x*6+y]-'0'
OK 000000000000000000000000111000111100 question (x>3)&(x-y>1)
OK 000000000000000000000000111000111100 orlp0 x>3&x-y>1
OK 000000000000000000000000111000111100 orlp2 ~y+x>2>>y
OK 000000000000000000000000111000111100 orlp3 x*x-y*y>9
OK 000000000000000000000000111000111100 orlp4 ~y>x/~3*x
OK 000000000000000000000000111000111100 orlp5 -3>>y>y-x
OK 000000000000000000000000111000111100 orlp6 ~y+x<<y>2
ERR 000000000000000000000000000000000000 orlp1 -x<~y>4>x
static void driver<T>::run() [with T = unsigned char]
OK 000000000000000000000000111000111100 MASTER (x>3) && (x>y+1)
OK 000000000000000000000000111000111100 GOLF x>3&x>y+1
OK 000000000000000000000000111000111100 lookup "000000000000000000000000111000111100"[x*6+y]-'0'
OK 000000000000000000000000111000111100 question (x>3)&(x-y>1)
OK 000000000000000000000000111000111100 orlp0 x>3&x-y>1
OK 000000000000000000000000111000111100 orlp2 ~y+x>2>>y
OK 000000000000000000000000111000111100 orlp3 x*x-y*y>9
OK 000000000000000000000000111000111100 orlp4 ~y>x/~3*x
OK 000000000000000000000000111000111100 orlp5 -3>>y>y-x
OK 000000000000000000000000111000111100 orlp6 ~y+x<<y>2
ERR 000000000000000000000000000000000000 orlp1 -x<~y>4>x
static void driver<T>::run() [with T = short unsigned int]
OK 000000000000000000000000111000111100 MASTER (x>3) && (x>y+1)
OK 000000000000000000000000111000111100 GOLF x>3&x>y+1
OK 000000000000000000000000111000111100 lookup "000000000000000000000000111000111100"[x*6+y]-'0'
OK 000000000000000000000000111000111100 question (x>3)&(x-y>1)
OK 000000000000000000000000111000111100 orlp0 x>3&x-y>1
OK 000000000000000000000000111000111100 orlp2 ~y+x>2>>y
OK 000000000000000000000000111000111100 orlp3 x*x-y*y>9
OK 000000000000000000000000111000111100 orlp4 ~y>x/~3*x
OK 000000000000000000000000111000111100 orlp5 -3>>y>y-x
OK 000000000000000000000000111000111100 orlp6 ~y+x<<y>2
ERR 000000000000000000000000000000000000 orlp1 -x<~y>4>x
static void driver<T>::run() [with T = unsigned int]
OK 000000000000000000000000111000111100 MASTER (x>3) && (x>y+1)
OK 000000000000000000000000111000111100 GOLF x>3&x>y+1
OK 000000000000000000000000111000111100 lookup "000000000000000000000000111000111100"[x*6+y]-'0'
ERR 000000000000000000000000111001111100 question (x>3)&(x-y>1)
ERR 000000000000000000000000111001111100 orlp0 x>3&x-y>1
ERR 111111011111001111000111111011111101 orlp2 ~y+x>2>>y
ERR 011111001111000111000011111001111100 orlp3 x*x-y*y>9
ERR 111111111111111111111111111111111111 orlp4 ~y>x/~3*x
ERR 111111011111001111000111111011111101 orlp5 -3>>y>y-x
ERR 111111011111001111000111111011111101 orlp6 ~y+x<<y>2
ERR 000000000000000000000000000000000000 orlp1 -x<~y>4>x
static void driver<T>::run() [with T = long unsigned int]
OK 000000000000000000000000111000111100 MASTER (x>3) && (x>y+1)
OK 000000000000000000000000111000111100 GOLF x>3&x>y+1
OK 000000000000000000000000111000111100 lookup "000000000000000000000000111000111100"[x*6+y]-'0'
ERR 000000000000000000000000111001111100 question (x>3)&(x-y>1)
ERR 000000000000000000000000111001111100 orlp0 x>3&x-y>1
ERR 111111011111001111000111111011111101 orlp2 ~y+x>2>>y
ERR 011111001111000111000011111001111100 orlp3 x*x-y*y>9
ERR 111111111111111111111111111111111111 orlp4 ~y>x/~3*x
ERR 111111011111001111000111111011111101 orlp5 -3>>y>y-x
ERR 111111011111001111000111111011111101 orlp6 ~y+x<<y>2
ERR 000000000000000000000000000000000000 orlp1 -x<~y>4>x
Резюме
Поскольку речь идет о «стоимости» повторяющихся элементов исходного кода, вы можете использовать таблицу поиска. Вы можете «спрятать» таблицу поиска, так что это либо
LUT[x][y]
или же
LUT[x*6+y]
Конечно, вы можете быть педантичным и тупым и переименовать LUT
L[x][y]
Так что моя "версия" ... 7 символов . (Или сделай если функция и L(x,y)
еще короче).
Или, что еще более важно: правильно, проверяемо и ремонтопригодно.