W odpowiedzi na (niesamowite) golfa orlp
:
Poprawność musi być na pierwszym miejscu
- Większość z nich rozkłada się na niektóre typy liczb całkowitych. Obejmuje to wersję z PO
- Co ciekawe to zrobić pracę za
int16_t
- więc nie jest to założenie. Prawdopodobnie przesunięcia bitów wymagałyby +16 dla 32-bitowych liczb całkowitych (w dzisiejszych czasach jest to prawie wszędzie). To sprawia, że postać jest większa ...
Jedynym „poprawnym” sposobem na napisanie go jest IMO (x>3) && (x > y+1)
, który może być golfowany do x>3&x>y+1
(9 znaków).
(Naprawdę musisz wziąć pod uwagę możliwość (większych) typów niepodpisanych, zwłaszcza, że niepodpisana jest „zaraźliwa” w wyrażeniach C ++. Podejrzewam, że „naprawienie”, które przy pomocy odpowiednich static_cast<>
znaków snułoby cel ...
AKTUALIZACJA
Dzięki następującym testom udało mi się ustalić, które wyrażenia faktycznie działają niezawodnie:
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();
}
Dane wyjściowe dotyczące coliru, tutaj w celach informacyjnych:
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
streszczenie
Ponieważ chodzi o „koszt” powtarzania elementów kodu źródłowego, możesz użyć tabeli odnośników. Możesz „ukryć” tabelę odnośników, więc jest to albo
LUT[x][y]
lub
LUT[x*6+y]
Oczywiście możesz być pedantyczny, tępy i zmienić nazwę LUT
L[x][y]
Więc moja „wersja” to ... 7 znaków . (Lub wykonaj, jeśli funkcja iL(x,y)
jest jeszcze krótsza).
Lub, co ważniejsze: poprawne, testowalne i konserwowalne.