X supérieur à 3 avec au moins 2 différences entre X et Y


11

J'essaie de jouer au golf en C ++. Est-il possible de raccourcir cette condition?

X > 3 & X - Y > 1

(En plus de supprimer les espaces, bien sûr.)

Donc, Xc'est au moins 4mais X >= Y + 2.

Xet Ysont des entiers dans l'intervalle [0,5].

J'ai essayé de trouver une formule au niveau du bit mais j'ai échoué.


1
@JoeZ. Pour CodeGolf? Pourquoi? Tant que ça marche ...
Cristy

4
@Cristy oui, mais (jusqu'à présent) les questions concernant les conseils sur le golf sont très rares alors que la plupart des questions demandant des conseils ne sont en fait que des questions générales de programmation - qui sont hors sujet. Par conséquent, je peux comprendre pourquoi la première réaction des gens pourrait être, "oh c'est une autre question qui appartient en fait à SO", sans même penser qu'il pourrait s'agir de conseils de golf. J'aimerais en voir plus à l'avenir, et peut-être qu'il y aura un tag pour eux un jour ou deux, et il sera clair immédiatement que vous savez comment utiliser ce site. ;)
Martin Ender

4
S'il s'agit d'entiers compris entre 0 et 5 inclus, vous pouvez faire la même chose avec x*x-y*y>9. C'est le même nombre de caractères, mais vous pourrez peut-être trouver un raccourci / une alternative à cette approche. Juste une autre façon de voir les choses.
Geobits

5
Utilisez Python:3<x>y+1
avall

2
J'ai trouvé beaucoup de solutions avec la priorité d'opérateur de Python, par exemple y+3<2^x, mais la priorité d'opérateur de C est différente. Je parie qu'il existe une solution à 7 caractères, il suffit de modifier mon script pour gérer la priorité de l'opérateur C à la place
Claudiu

Réponses:


11

Après avoir forcé brutalement toutes les combinaisons utiles de symboles de moins de 9 caractères, j'ai trouvé qu'il n'y avait pas de solution plus petite que x>3&x-y>1.

Pour le plaisir, voici quelques solutions géniales à 9 caractères trouvées par le forceur brut:

-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

Le forçage brutal a été effectué en Python, créant des arbres de syntaxe descendants où aucun enfant ne peut avoir un opérateur de priorité inférieure à son parent selon les règles de C. Pour réduire les possibilités, je n'autorisais que des littéraux à un chiffre, et aucun opérateur binaire ne peut avoir deux enfants constants. Je ne pouvais pas penser à une solution qui aurait un littéral à deux chiffres, ou une qui construit une constante à l'aide d'un opérateur binaire. Ensuite, chaque expression a été évaluée pour [0, 5] et si elle correspond, elle est imprimée.


J'aime vraiment x*x-y*y>9. Peut-être devriez-vous également essayer des constantes à plusieurs chiffres? (aussi, parenthèses)
John Dvorak

@JanDvorak moi aussi. Il exprime bien la logique de la "distance entre x et y". Je pense que si vous tracez cela dans un graphique, cela deviendrait plus évident.
sehe

@JanDvorak Je ne pense pas que les parenthèses puissent jamais être une solution plus petite. Une solution plus petite peut comprendre un maximum de 8 caractères, dont 2 doivent être xyet 2 doivent être les parenthèses, ne laissant que 4 caractères de logique. Je vais essayer d'exécuter le forceur brut avec des constantes à 2 chiffres, mais je ne pense vraiment pas que cela donnera un résultat.
orlp

Que diriez-vous, x, y, une constante, une paire de parenthèses et deux opérateurs?
John Dvorak

@JanDvorak Assommez-vous, (a#b)$cc'est le format. Sur abcdeux doivent être xet y, laissant 3 emplacements possibles pour [0-9xy], et un seul flip de xy. Seuls les opérateurs intéressants le sont +-*/&|^<>, donc 9 possibilités. Ainsi, les possibilités totales sont inférieures à 3 * 12 * 2 * 9 * 9 <5832.
orlp

0

En réponse aux (super) golfs orlp:

La correction doit venir en premier

  • La plupart d'entre eux se décomposent pour certains types entiers. Cela inclut la version de l'OP
  • Fait intéressant , ils font le travail pour int16_t- donc il y a l'hypothèse. Probablement, les décalages de bits auraient besoin de +16 pour les entiers 32 bits (c'est à peu près partout ces jours-ci). Cela en fait un personnage plus grand ...

La seule façon "correcte" de l'écrire, c'est l'OMI (x>3) && (x > y+1), qui peut être jouée jusqu'à x>3&x>y+1(9 caractères).

(Vous devez vraiment prendre en compte la possibilité de types non signés (plus grands), d'autant plus que unsigned-ness est "contagieux" dans les expressions C ++. Je suppose que "réparer" qu'avec les static_cast<>s appropriés irait à l'encontre du but ...)

METTRE À JOUR

Avec les tests suivants, j'ai pu déterminer quelles expressions fonctionnent réellement de manière fiable:

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

Sortie sur coliru, ici pour référence:

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

Résumé

Étant donné qu'il s'agit du «coût» de la répétition des éléments de code source, vous pouvez utiliser une table de recherche. Vous pouvez "masquer" la table de recherche, il est donc possible

 LUT[x][y]

ou

 LUT[x*6+y]

Bien sûr, vous pouvez être pédant et obtus et renommer la LUT

 L[x][y]

Donc ma "version" est ... 7 caractères . (Ou faites si c'est une fonction et L(x,y)est encore plus courte).

Ou, plus important encore: correct, testable et maintenable.


Ajout d'un "vrai" golf. Pas plus court que 9 caractères, mais le premier à être correct!
sehe
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.