X greater than 3 with at least 2 difference between X and Y

11

1

I am trying to golf down some C++. Is it possible to make this condition shorter?

X > 3 & X - Y > 1

(Apart from removing whitespace, of course.)

So, X is at least 4 but X >= Y + 2.

X and Y are integers in the [0,5] interval.

I have tried to find some bitwise formula but failed.

Cristy

Posted 2014-05-03T18:02:34.340

Reputation: 229

I can only match the length, but can't come up with anything shorter. My solution is x>3+y*y/7 for what it is worth (not much). – CasaDeRobison – 2015-02-24T09:24:03.420

It's.... pretty short already. – Geobits – 2014-05-03T18:05:27.390

Yeah, but the problem is that I use this condition (only with variable names changed) in more places, so they add up. I think there can be a formula for this condition, noting that they are in [0,5] interval, but can't see it. – Cristy – 2014-05-03T18:06:39.110

If you use it often and don't want to type it out each time, use a function? – Geobits – 2014-05-03T18:07:37.727

I used it like 4 times, so that is 36 characters. Creating a function + calling it will be longer. – Cristy – 2014-05-03T18:08:30.707

It's generally not a good idea to use & for logical operations. – Joe Z. – 2014-05-03T18:16:07.680

1@JoeZ. For CodeGolf? Why? As long as it is working... – Cristy – 2014-05-03T18:22:12.343

1Guys, what's with the close votes? This is not a general programming question? This is about advice for code golfing. (@Cristy you may want to make that clearer in the question though, before the question does get closed and starts amassing downvotes.) – Martin Ender – 2014-05-03T19:25:38.187

@Cristy I took the liberty to do that as the close-votes keep coming in. Feel free to rephrase my edit. – Martin Ender – 2014-05-03T19:41:41.627

Oh, I assumed that all the questions on codegolf.se.com are about codegolf, lol :D – Cristy – 2014-05-03T19:56:35.037

4@Cristy yes they are, but (so far) questions asking about golfing advice are very rare whereas most questions asking for advice are indeed just general programming questions - which are off-topic. Hence, I can understand why the first reaction of people might be, "oh that's another question that actually belongs on SO", without even thinking it could be about golfing advice. I'd actually like to see more of these in the future, and maybe there'll be a tag for them some day or so, and it will be clear immediately that you know how to use this site. ;) – Martin Ender – 2014-05-03T20:23:23.970

1

@m.buettner I tend to agree that this kind of code-golf advice question is possibly a good fit for this site. Of course the tagging would need to be sorted out - perhaps [tag:advice] or something like that. Do you want to take this to meta?

– Digital Trauma – 2014-05-03T20:50:42.957

@DigitalTrauma I want to and will (later tonight or tomorrow) – Martin Ender – 2014-05-03T20:53:09.743

(/cc @DigitalTrauma, see above comment) – Doorknob – 2014-05-03T21:14:58.363

@Doorknob yep, I'm aware of that question. Already considering whether my post will be an answer to it or a new question (referencing yours). ;) Depends on whether my actual post will be more of a question or answer I suppose. ^^ – Martin Ender – 2014-05-03T21:23:09.710

Just to be sure: When you say that “X and Y range in the [0,5] interval.”, this means that they are floats? – Wrzlprmft – 2014-05-08T18:33:16.773

4If they are integers between 0..5 inclusive, you can do the same thing with x*x-y*y>9. It's the same amount of characters, but you may be able to find a shortcut/alternative to that approach. Just another way of looking at it. – Geobits – 2014-05-08T18:43:32.880

@Wrzlprmft They are integers. – Cristy – 2014-05-09T17:54:39.580

5Use Python: 3<x>y+1 – avall – 2014-05-09T22:32:45.450

1I tried to prove mathematically that this cannot be improved, but didn't quite manage to :) (The general idea was that you need at least one asymmetrical operation, as well as at least one comparison operator and one number... and I just can't see a way to pull that off in C++ under 9 characters) – Tal – 2014-06-04T07:04:28.467

1Ppl, stop trying to close this topic. It's not an OT because it is about Codegolf. It isn't a programming problem to solve but to golf a problem. It is 100% valid question. – avall – 2014-06-09T07:41:52.337

I guess what you mentioned is optimal solution since there are <br>- two checks and <br>- involves two variables – Parvej Solkar – 2014-06-24T10:05:11.423

2I found a lot of solutions with Python's operator precedence, e.g. y+3<2^x, but C's operator precedence is different. I'm betting there's a 7-char solution, just have to modify my script to deal with C operator precedence instead – Claudiu – 2014-09-15T01:17:20.443

1This solution is longer, but seems interesting: (x&4)>>(y^x&1) – Qwertiy – 2014-10-23T09:30:35.280

Answers

11

After brute forcing every useful combination of symbols under 9 characters, I've found there to be no smaller solution than x>3&x-y>1.

For fun here's some funky 9 character solutions the brute forcer found:

-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

Brute forcing was done in Python, building top-down syntax trees where no child may have an operator with precedence lower than its parent according to C's rules. To cut down on possibilities I only allowed single digit literals, and no binary operator may have two constant children. I could not possibly think of any solution that would have a two digit literal, or one that builds a constant using a binary operator. Then each expression was evaluated for [0, 5] and if it matches it gets printed.

orlp

Posted 2014-05-03T18:02:34.340

Reputation: 37 067

I really like x*x-y*y>9. Perhaps you should try multi-digit constants as well? (also, parentheses) – John Dvorak – 2015-03-11T09:21:06.467

@JanDvorak me too. It expresses well the logic of "distance between x and y". I think if you plot this in a chart, it would become more obvious. – sehe – 2015-03-11T09:26:15.303

@JanDvorak I don't think parentheses can ever be a smaller solution. A smaller solution can be a max of 8 characters, of which 2 must be xy, and 2 must be the parentheses, leaving only 4 characters of logic. I'll try running the brute forcer with 2 digit constants, but I really don't think it'll give a result. – orlp – 2015-03-11T09:27:42.070

How about, x, y, a constant, a pair of parentheses and two operators? – John Dvorak – 2015-03-11T09:29:18.847

@JanDvorak Knock yourself out, (a#b)$c is the format. Out of abc two must be x and y, leaving 3 possible locations for [0-9xy], and only one flip of xy. Only interesting operators are +-*/&|^<>, so 9 possibilities. Thus total possibilities is less than 312299 < 5832. – orlp – 2015-03-11T09:42:08.153

@JanDvorak do you think you can get smaller than 7 characters? I've just written a bit of a critique. I admit I'm not a golf.SE regular, so I might not be in the target audience. I do think my answer contributes important (data) points, though – sehe – 2015-03-11T10:34:05.573

@JanDvorak No possible expressions with double digit literals. – orlp – 2015-03-11T12:07:03.920

0

In response to the (awesome) golfs by orlp:

Correctness must come first

  • Most of these break down for some integer types. This includes the version from the OP
  • Interestingly they do work for int16_t - so there is the assumption. Probably the bit shifts would need to +16 for 32 bit ints (that's pretty much everywhere these days). This makes them a character bigger...

The only "correct" way to write it, IMO is (x>3) && (x > y+1), which may be golfed down to x>3&x>y+1 (9 characters).

(You really need to take the possibility of (larger) unsigned types into consideration, especially since unsigned-ness is "contagious" in C++ expressions. I suppose "fixing" that with the appropriate static_cast<>s would kinda defeat the purpose...)

UPDATE

With the following tests I've been able to figure out which expressions actually work reliably:

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

Output on coliru, here for reference:

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

Summary

Since this about the "cost" of repeating source code elements, you might use a lookup table. You can "hide" the lookup table, so it is either

 LUT[x][y]

or

 LUT[x*6+y]

Of course you can be pedantic and obtuse and rename the LUT

 L[x][y]

So my "version" is ... 7 characters. (Or make if a function and L(x,y) is even shorter).

Or, more importantly: correct, testable and maintainable.

sehe

Posted 2014-05-03T18:02:34.340

Reputation: 360

Added a "true" golf. No shorter than 9 characters, but the first one to be correct! – sehe – 2015-03-11T10:42:45.290