Sunday, July 26, 2009

Puzzle 45 – Equally Unequal - II

Language – Java | Type – Concept | Last date 29-Jul-2009 9:00 p.m. IST | Points 2 + Bonus

The last puzzle seems to have got a lot of flake for being simple – It also got the maximum participation – so it looks like you folks like simplicity but don’t like simplicity :)

So I decided to try something different this week! There are lots of new folks who have joined in and I would like, you to climb the point ladder quickly – here is the perfect opportunity!

package com.twisters;
public class Equal_Unequal {
public static void main(java.lang.String[] args) {
<someType1> x = <someValue1>;
<someType2> y = <someValue2>;
System.out.println(
"Values are equal : "+(x==y));
}
}

Steps that you need to follow:

1. Fill in a value for both the someType and someValue. They could be same or different.
2. You may not add any other code or delete any of the existing code.
3. Run the program. It should print Values are equal : true
4. Run the program. It should print Values are equal : false

P.S – As you can see you cannot compile again between the two runs – in case it wasn’t obvious enough.

Pretty simple up too now so here is the catch – For every different logical solution that you offer you get two bonus points. Now for a solution to be logically different it must satisfy two criteria.
a. sometype must be different from the other solutions.
b. It must exhibit a different Java principle (or different logical reason) from the other solutions that you have posted.
In case you are not sure if its logically different I would suggest to post the solution!

While it is not necessary to explain what you consider your solution as the guiding principle of your solution - it would be great if you do give a short explanation.

I can think of three – probably four different logical solutions to this puzzle (& frankly more than 20 if you remove the logical clause).

Looking for hints and more bonuses? You might want to watch out for an additional clause on twitter.

As usual looking forward to your solutions!!

14 comments:

  1. You didn't mentioned anything on running the program, So I assume that I can use the command line argument,
    So here is my first solution, It can be extended to many solutions as u said, Run the program again with same and different command line parameters,
    eg
    java Equal_Unequal 1 1 -> will print true
    java Equal_Unequal 1 2 -> will print false

    package com.twisters;
    public class Equal_Unequal {
    public static void main(java.lang.String[] args) {
    int x = Integer.parseInt(args[0]);
    int y = Integer.parseInt(args[1]);
    System.out.println("Values are equal : "+(x==y));
    }
    }

    ReplyDelete
  2. package com.twisters;
    public class Equal_Unequal {
    public static void main(java.lang.String[] args) {
    int x = Math.round((float)Math.random());
    int y = 0;
    System.out.println("Values are equal : "+(x==y));
    }
    }

    ReplyDelete
  3. 1. We could place such logic into args[]

    int x = Integer.valueOf(args[0]);
    int y = Integer.valueOf(args[1]);

    Call with two args: "1 1" and "0 1"

    2. We could emulate such logic playing with external resources. (create directory\file\open port\add .class file\ and etc. between program runs)

    boolean x = !new File("x").exists();
    boolean y = true;

    Create file "x" after first run

    3. We could emulate such logic playing with system properties or even with JVM parameters

    long x = Runtime.getRuntime().totalMemory();
    long y = 5177344;

    add -Xms64m after first run to JVM parameters (yeah, this one works fine only at my comp and only my curr enviroment)

    Cant think another solution as others are similar to that. Args, resources or enviroment changes.

    ReplyDelete
  4. here! I used to take random numbers between two numbers like(1 and 0) and use to multiply them with the main number, now i compare these two numbers ,as it get differed for different compilations, we get both false and true randomly and simultaneously. here is the code.............

    package com.twisters;
    public class Nash_First {
    public static void main(java.lang.String[] args) {
    char x = 138;
    int y = ((int)(Math.random() * 2))*x;
    System.out.println(y);
    System.out.println("Values are equal : "+(x==y));
    }
    }

    ReplyDelete
  5. Here, i took an array and stored two char literals and now by using the random number generation i am picking up a certain indexed character by using a static method of character class by method name codePointAt(char[],int index) and comparing with the other character, As it differs for the different compilations, it satisfies the required output. So here goes the code.......
    public class Nash_Second {
    public static void main(java.lang.String[] args) {
    char x = 'c';
    char y = (char)Character.codePointAt(new char[]{'a','c'},((int)(Math.random() * 2)));
    System.out.println(y);
    System.out.println("Values are equal : "+(x==y));
    }
    }

    ReplyDelete
  6. Here in this code, i used random number generation itself, but changed the way i assin the data and also changed the datatypes. So its different from others and also satisfies the required outputs.

    public class Fourth {
    public static void main(java.lang.String[] args) {
    double x = 30.0;
    double y = (x+((int)(Math.random() * 2)));
    System.out.println("Values are equal : "+(x==y));
    }
    }

    ReplyDelete
  7. @moderator!

    I am sorry that i used system.out.println in my programs, actually it was kept in my simulator to check the data in the variable y. dont consider it as an extra code, if possible i request you to delete that line ok! and please consider it.

    ReplyDelete
  8. Solution 1: primitive types and the parseXXX method of their respective wrapper

    int x = Integer.parseInt(args[0]);
    int y = 0;

    Run with argument "0" then "1".

    This works with all primitive types and their wrapper's parse method. You can even mix the primitive number types, e.g. int x= ...; float y = 0;.


    Solution 2: the caching of the primitive types wrapper's valueOf method

    Integer x = Integer.valueOf(Integer.parseInt(args[0]));
    Integer y = Integer.valueOf(0);

    Run with argument "0" then "1".

    The newer implementations of the Wrapper classes (since Java 5, I reckon) use a cache for a certain range of input values for their valueOf method. This works with Long, Integer, Short, Byte and Boolean.


    Solution 3: String.intern()

    String x = args[0].intern();
    String y = "A";

    Run with argument "A" then "B".

    See Puzzle 37 for why the two Strings are not only equal but the same instance.


    Solution 4: the one without arguments

    long x = new java.util.GregorianCalendar(2009, 6, 27, 22, 36, 0).getTimeInMillis() / 60000;
    long y = new java.util.Date().getTime() / 60000;

    Run twice without any arguments.

    This is all about timing. If run within the correct minute, it will return true, one or more minutes later it will return false.


    Solution 5: y = x
    Object x = new Object();
    Object y = args.length > 0 ? x : null;

    Run with argument "0" then run without any arguments.

    For non-primitive types, x==y is only true if x and y are the same instance. In solution 2 and 3 we used different aspects of the Java API to solve this problem. Here we simply set y = x if the programme is run with arguments.


    Solution 6: another one without arguments

    Boolean x = new java.util.Random().nextBoolean();
    Boolean y = Boolean.TRUE;

    Run twice without arguments. Repeat until the desired output appears.

    Well, it works one out of four times and there is no rule that says it has to work all the time ;)

    ReplyDelete
  9. In this solution, I am reading the system time(i.e seconds) and remainder of that seconds/2 is taken and assigned. and comparing the values gives our result.

    public class Fifth {
    public static void main(java.lang.String[] args) {
    int x = 1;
    int y = (new java.util.Date().getSeconds())%2;
    System.out.println("Values are equal : "+(x==y));
    }
    }

    ReplyDelete
  10. public class Fifth {
    public static void main(java.lang.String[] args) {
    boolean x = true;
    boolean y = (new java.util.Date().getSeconds())%2==1?true:false;
    System.out.println("Values are equal : "+(x==y));
    }
    }

    ReplyDelete
  11. The obvious solution is to use the only obvious available state which is passed to the running instance and that is the arguments.
    So simply checking for the number of arguments and running the program with a different number of arguments will do the trick:

    int x = args.length;
    int y = 1;

    An alternative implementation could use system properties so invoking the same code with different system properties will do the same trick:

    String x = System.getProperty("foo", "bar");
    String y = "bar";

    Using the preferences API, there is another way to store and retrieve values on the disk in a single line of code without the need to catch exceptions

    double x = java.util.prefs.AbstractPreferences.userRoot().getDouble("foo", 42.0d);
    double y = 42.0d;

    also file trivial file IO can be used:
    boolean x = new File("blah").exists();
    boolean y = false;

    Of course you can add your own class and use any custom type to it:

    CustomType x = CustomTypesContainerClass.X1;
    CustomType y = CustomTypesContainerClass.X2;

    and between the two runs only recompile the jar that contains CustomTypesContainerClass so that X1 and X2 point to the same reference or not. Using the classpath it would be possible to use different versions of CustomTypesContainerClass without even recompiling.

    ReplyDelete
  12. One more try:
    long x = System.currentTimeMillis();
    long y = System.currentTimeMillis();
    depending on your hardware (the executing speed of the program) this will be either the same or different values. Running many different programs under a high load might also "help" to get to the "false" result.

    ReplyDelete
  13. I found another four solutions!

    Solution 7: VM version

    byte x = Byte.parseByte(System.getProperty("java.version").substring(2,3));
    byte y = 6;

    Run first with a JRE6 VM then with another VM.


    Solution 8: environment variable

    short x = Short.parseShort(System.getenv("PUZZLE"));
    short y = 0;

    Before the first run set the environment variable PUZZLE to 0; before the second run set it to 1.

    This is another one that doesn't use arguments.


    Solution 9: VM parameter

    boolean x = Boolean.getBoolean("twister");
    boolean y = true;

    First run with VM parameter -Dtwister=TRUE, then with -Dtwister=FALSE.

    You could mix this solution with solution 7 and using both times the VM parameter -Dtwister=TRUE but using a VM version >= 1.0.2 the first time and a VM version < 1.0.2 the second time, because the return value of Boolean.getBoolean() changed for the input parameter "TRUE" with version 1.0.2. Before that version getBoolean("TRUE") returned false while it later returns true.


    Solution 10: operation system

    char x = System.getProperty("os.name").charAt(0);
    char y = 'M';

    Run it on an Apple MacIntosh first, then run it on any other OS.


    Well, that's it! I'm also thinking of a solution involving SoftReferences and running with different garbage collectors, but I already spent enough time on this puzzle :)

    ReplyDelete
  14. int x = Integer.valueOf(System.getProperty("prop1"));
    int y = Integer.valueOf(System.getProperty("prop2"));
    System.out.println("Values are equal : "+(x==y));

    First run with -Dprop1=1 -Dprop2=1, than with -Dprop1=1 -Dprop2=2

    ReplyDelete

Solution for this question?