X mayor que 3 con al menos 2 diferencias entre X e Y

11

Estoy tratando de jugar golf en C ++. ¿Es posible acortar esta condición?

X > 3 & X - Y > 1

(Además de eliminar espacios en blanco, por supuesto).

Entonces, Xes al menos 4pero X >= Y + 2.

Xy Yson enteros en el intervalo [0,5].

He tratado de encontrar alguna fórmula bit a bit pero fallé.

Cristy
fuente
1
@JoeZ. ¿Para CodeGolf? ¿Por qué? Mientras funcione ...
Cristy
44
@Cristy sí, pero (hasta ahora) las preguntas sobre consejos de golf son muy raras, mientras que la mayoría de las preguntas que piden consejos son solo preguntas generales de programación, que están fuera de tema. Por lo tanto, puedo entender por qué la primera reacción de las personas podría ser, "oh, esa es otra pregunta que realmente pertenece a SO", sin siquiera pensar que podría tratarse de consejos de golf. Yo realmente como para ver más de estos en el futuro, y tal vez habrá una etiqueta para ellos un día o así, y quedará claro inmediatamente que usted sabe cómo utilizar este sitio. ;)
Martin Ender
44
Si son enteros entre 0..5 inclusive, puede hacer lo mismo con x*x-y*y>9. Es la misma cantidad de caracteres, pero es posible que pueda encontrar un atajo / alternativa a ese enfoque. Solo otra forma de verlo.
Geobits
55
El uso de Python:3<x>y+1
Avall
2
Encontré muchas soluciones con la precedencia del operador de Python, por ejemplo y+3<2^x, pero la precedencia del operador de C es diferente. Apuesto a que hay una solución de 7 caracteres, solo tengo que modificar mi script para lidiar con la precedencia del operador C
Claudiu

Respuestas:

11

Después de forzar de forma bruta cada combinación útil de símbolos de menos de 9 caracteres, descubrí que no hay una solución más pequeña que x>3&x-y>1.

Por diversión, aquí hay algunas soluciones funky de 9 personajes que encontró el forzador bruto:

-x<~y>4>x
~y+x>2>>y
x*x-y*y>9
~y>x/~3*x
-3>>y>y-x
~y+x<<y>2

El forzamiento bruto se realizó en Python, construyendo árboles de sintaxis de arriba hacia abajo donde ningún niño puede tener un operador con una prioridad inferior a su padre de acuerdo con las reglas de C. Para reducir las posibilidades, solo permití literales de un solo dígito, y ningún operador binario puede tener dos hijos constantes. No podría pensar en ninguna solución que tuviera un literal de dos dígitos, o una que construya una constante usando un operador binario. Luego, cada expresión se evaluó para [0, 5] y si coincide se imprime.

orlp
fuente
Me gusta mucho x*x-y*y>9. ¿Quizás deberías probar también las constantes de varios dígitos? (también, paréntesis)
John Dvorak
@ JanDvorak yo también. Expresa bien la lógica de "distancia entre x e y". Creo que si trazas esto en un gráfico, sería más obvio.
sehe
@ JanDvorak No creo que los paréntesis puedan ser una solución más pequeña. Una solución más pequeña puede tener un máximo de 8 caracteres, de los cuales 2 deben ser xyy 2 deben ser paréntesis, dejando solo 4 caracteres de lógica. Intentaré ejecutar el forzador bruto con constantes de 2 dígitos, pero realmente no creo que dé un resultado.
orlp
¿Qué tal, x, y, una constante, un par de paréntesis y dos operadores?
John Dvorak
@ JanDvorak Knock out, (a#b)$ces el formato. De abcdos deben ser xy y, dejando 3 ubicaciones posibles para [0-9xy], y solo una vuelta de xy. Solo los operadores interesantes son +-*/&|^<>, entonces 9 posibilidades. Por lo tanto, las posibilidades totales son inferiores a 3 * 12 * 2 * 9 * 9 <5832.
orlp
0

En respuesta a los (impresionantes) campos de golf por orlp:

La corrección debe ser lo primero

  • La mayoría de estos se descomponen para algunos tipos enteros. Esto incluye la versión del OP
  • Es interesante que hacer el trabajo de int16_t- por lo que no es el supuesto. Probablemente los cambios de bits necesitarían +16 para entradas de 32 bits (eso es prácticamente en todas partes en estos días). Esto los convierte en un personaje más grande ...

La única forma "correcta" de escribirlo, IMO es (x>3) && (x > y+1), que puede reducirse a x>3&x>y+1(9 caracteres).

(Realmente debe tener en cuenta la posibilidad de tipos sin signo (más grandes), especialmente porque la falta de firma es "contagiosa" en las expresiones de C ++. Supongo que "arreglar" eso con los static_cast<>s apropiados sería un poco frustrante para el propósito ...)

ACTUALIZAR

Con las siguientes pruebas he podido averiguar qué expresiones funcionan realmente de manera confiable:

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();
}

Salida en coliru, aquí para referencia:

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

Resumen

Dado que se trata del "costo" de repetir elementos de código fuente, puede usar una tabla de búsqueda. Puede "ocultar" la tabla de búsqueda, por lo que es

 LUT[x][y]

o

 LUT[x*6+y]

Por supuesto, puedes ser pedante y obtuso y renombrar el LUT

 L[x][y]

Entonces mi "versión" es ... 7 caracteres . (O hacer si es una función y L(x,y)es aún más corta).

O, lo que es más importante: correcto, comprobable y mantenible.

sehe
fuente
Se agregó un "verdadero" golf. No menos de 9 caracteres, ¡pero el primero en ser correcto!
sehe