• Post Reply Bookmark Topic Watch Topic
  • New Topic
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other Pie Elite all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Campbell Ritchie
  • Tim Cooke
  • Liutauras Vilda
  • Jeanne Boyarsky
  • paul wheaton
Sheriffs:
  • Ron McLeod
  • Devaka Cooray
  • Henry Wong
Saloon Keepers:
  • Tim Holloway
  • Stephan van Hulst
  • Carey Brown
  • Tim Moores
  • Mikalai Zaikin
Bartenders:
  • Frits Walraven

[Java puzzle] Dysfunctional

 
Ranch Hand
Posts: 135
4
  • Likes 1
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Another puzzle. Sorry about the use of a raw type.

 
Marshal
Posts: 79941
396
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
What is the puzzle supposed to do? Find two values that are neither equal to each other nor unequal?
 
Istvan Kovacs
Ranch Hand
Posts: 135
4
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Find two values x, y and a function F such that the two values are == equal, yet applying the same (pure, stateless) function, which does not contain any conditional statements or the like, produces different results for those values.
So,
x == y,
but F(x) != F(y).

I used capital F above, because our function is not implemented in method f(), that one is merely a factory method to return the actual function.
Ideally, f() is like:
return x -> (a simple expression that maps x to a different value)
For example (this one is obviously not the right solution):
return (String s) -> s.toUpperCase();

I used var and raw types to hide the types of item1, item2, the argument and the return value of function.
 
Campbell Ritchie
Marshal
Posts: 79941
396
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Please don't “correct” posts like that. It doesn't add clarity, but makes it uncertain what I replied to. Please post any changes in a new post.
 
Istvan Kovacs
Ranch Hand
Posts: 135
4
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
OK, sorry.
Meanwhile, I realised more solutions exist (I wonder how many hackish loopholes people will find in the original one). So, here is a 'level 2' version of the puzzle, if that is acceptable:



You are only allowed to modify lines 11, 12, 51 and 53. You are, however, free to add anything after line 54, or add any number of types to the package dysfunctional, and use them on those lines.
 
Campbell Ritchie
Marshal
Posts: 79941
396
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Istvan Kovacs wrote:. . .

I am finding this question difficult to understand. I would have thought you are supposed to find two values that will cause the program to print, “Success.” Needless to say, that code can be relied on to crash with an exception.
If you aren't allowed ifs, why would you be allowed a switch‑case?
I also think it is dubious practise to throw an Error of any kind. Maybe an assertion is allowed to throw an AssertionError, but your code doesn't contain any assertions.
 
Istvan Kovacs
Ranch Hand
Posts: 135
4
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
I can add assert statements, but then we depend on people calling the code with -ea.
The randomisation is there in case people get tricky in the additional code allowed by this instruction:
free to add anything after line 54, or add any number of types to the package dysfunctional, and use them on those lines

But let's try this, without exceptions.

You are only allowed to modify lines 11, 12, 44 and 46. You are, however, free to add anything after line 47, or add any number of types to the package dysfunctional, and use them on those lines.


 
Campbell Ritchie
Marshal
Posts: 79941
396
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
And?
You have shown several examples of code which appear to fail. If the idea behind the puzzle is to get it to print, “success,” how are you going to do that?
 
Marshal
Posts: 8954
646
Mac OS X Spring VI Editor BSD Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Campbell Ritchie wrote:You have shown several examples of code which appear to fail


Well, probably for a purpose not to spoil the correct answer that gets to "Success!";

Campbell Ritchie wrote:how are you going to do that?


I believe Istvan left this exercise for a reader Yesterday I had a quick think, but then I was too busy with advent of code, so no luck

 
Campbell Ritchie
Marshal
Posts: 79941
396
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
I can think of a few things where the usual == and != operators seem to be at odds with equals(), I am keeping quiet about them, too.

It would appear one of my examples where == and != operators seem to be at odds with equals() caused it to print, “Success.” What a surprise!
 
Istvan Kovacs
Ranch Hand
Posts: 135
4
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Campbell Ritchie wrote:And?
You have shown several examples of code which appear to fail. If the idea behind the puzzle is to get it to print, “success,” how are you going to do that?



I'm sorry, I don't understand what I did wrong. I have posted puzzles a few times, and they were well received. So yes, when I came across something at work that was somewhat surprising, I turned it into a puzzle. I thought it was evident from the beginning that the aim was to get to the line that prints a message confirming success.
I could have simply posted a solution, but then that's not a puzzle. I could have simply posted the thing I discovered at work saying "Hey, did you know that skdjfh weiru sdfn? I didn't; I just learned that at work today", but then again, it's not fun. These puzzles are intended to provide a fun, and hopefully more effective way of learning something than linking a section of the specs.
I'm sorry if I failed to make my intention clear. I'm sorry the style with the AssertionErrors was sub-par (even though I think I was making assertions, so an AssertionError was a logical choice; it was like a test, without involving a framework).

If there is anything else I should do, please let me know.
If you think the topic is useless or hopeless, then delete it, please.
 
Istvan Kovacs
Ranch Hand
Posts: 135
4
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Campbell Ritchie wrote:I can think of a few things where the usual == and != operators seem to be at odds with equals(), I am keeping quiet about them, too.

It would appear one of my examples where == and != operators seem to be at odds with equals() caused it to print, “Success.” What a surprise!



OK, reading your comment I now see that I probably did not create the puzzle to be specific enough; even with the additional restrictions, which I thought would help, there is a whole different family of solutions than what I originally had in mind. We'll see if someone finds my original idea.
 
Master Rancher
Posts: 5057
81
  • Likes 1
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
 
Istvan Kovacs
Ranch Hand
Posts: 135
4
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Campbell Ritchie wrote:I can think of a few things where the usual == and != operators seem to be at odds with equals(), I am keeping quiet about them, too.

It would appear one of my examples where == and != operators seem to be at odds with equals() caused it to print, “Success.” What a surprise!



I just wanted to ask if your solution would still work if I added a check asserting that !Objects.equals(item1, function.apply(item1)) and the same for item2, but then Mike provided the exact solution I had in mind.
 
Campbell Ritchie
Marshal
Posts: 79941
396
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
I tried 0.0 and -0.0 myself, but my function only forces boxing by casting to (Double): x -> (Double)x
 
Campbell Ritchie
Marshal
Posts: 79941
396
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
You can create a similar puzzle with NaNs, but all the Boolean tests would have to be reversed.
 
Sheriff
Posts: 28321
95
Eclipse IDE Firefox Browser MySQL Database
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Thanks for posting this, Istvan. Your puzzles are always welcome.
 
Istvan Kovacs
Ranch Hand
Posts: 135
4
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Campbell Ritchie wrote:You can create a similar puzzle with NaNs, but all the Boolean tests would have to be reversed.



I did something like that in January. https://coderanch.com/t/768833/Java-puzzle-don-feel
 
Campbell Ritchie
Marshal
Posts: 79941
396
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Yes, I remember that discussion now I have seen your link.
 
Istvan Kovacs
Ranch Hand
Posts: 135
4
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
So, the solution has been revealed, but not yet explained:
- in the floating-point standard IEEE 754 (this is not just about Java), 0 is signed. https://en.wikipedia.org/wiki/IEEE_754#Signed_zero
- these values compare as ==. See https://en.wikipedia.org/wiki/IEEE_754#Comparison_predicates.
- however, they are are represented by (boxed into) different Double values, which are not equal according to equals();
- Objects.equals() was used to hide the boxing operation (you cannot call primitiveDouble.equals()).
- 1/+0 and 1/-0 result in +infinity and -infinity (but one could have used doubleValue -> -doubleValue as well as the mapping function). This is also described at https://en.wikipedia.org/wiki/IEEE_754#Signed_zero.
 
Campbell Ritchie
Marshal
Posts: 79941
396
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Once that values have been boxed, there is no need to do anything else; they return false from equals().
 
Campbell Ritchie
Marshal
Posts: 79941
396
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Here is the simplest version of f() applied to your original code, along with actual type parameters given to the declaration of function:-It should be possible to apply a method reference in line 34 instead: Function::identity.
 
Istvan Kovacs
Ranch Hand
Posts: 135
4
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Campbell Ritchie wrote:Here is the simplest version of f() applied to your original code, along with actual type parameters given to the declaration of function:


It should be possible to apply a method reference in line 34 instead: Function::identity.



Yes. That's why I wrote in a previous comment:


I just wanted to ask if your solution would still work if I added a check asserting that !Objects.equals(item1, function.apply(item1)) and the same for item2, but then Mike provided the exact solution I had in mind.



I also wanted to draw attention to the behaviour of +0 and -0 leading to +infinity and -infinity for x -> 1/x; however, even adding the non-identity restriction mentioned above would not prevent people from using x -> -x, so I failed in that regard.
 
snakes are really good at eating slugs. And you wouldn't think it, but so are tiny ads:
Gift giving made easy with the permaculture playing cards
https://coderanch.com/t/777758/Gift-giving-easy-permaculture-playing
reply
    Bookmark Topic Watch Topic
  • New Topic