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.
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.420It'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.6801@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
1
@m.buettner http://meta.codegolf.stackexchange.com/questions/1470/re-evaluating-tips-and-tip-like-questions
– Doorknob – 2014-05-03T21:14:37.810(/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
andY
range in the [0,5] interval.”, this means that they are floats? – Wrzlprmft – 2014-05-08T18:33:16.7734If 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.4501I 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.4431This solution is longer, but seems interesting:
(x&4)>>(y^x&1)
– Qwertiy – 2014-10-23T09:30:35.280