Sunday, July 18, 2010

Puzzle 62 - WARNING - Is this the End?

The world is about to end, but maybe, just maybe there is some Hope. So it give it a spin and try it. After all the fate of Earth rests in your hands!
(The code is well commented, I think you'll find everything you need out there.)

package com.test; import java.util.ArrayList; import java.util.List; /*This class had been set to trigger on December 21, 2012. *Due to a programming this class will trigger off in the next 15 mins *of you reading it. *Yes its a know issue and we've sorry about it, but right now there are other major *issues to solve and this can wait for later! **/ public class DoomsDayEarth { /*No point in returning anything once the world has been destroyed!*/ public static void destroyWorld(List<EvilObject> evilObjects) { /*You do get a chance to save the world. Try it!*/ Hope.save(evilObjects); /*This code destroys the world and prints world destroyed. *Prevent that from happening and if possible get it to print world saved * */ for(Destroy d : evilObjects) { d.destroy(); } } public static void main(String[] args) { List<EvilObject> evil = new ArrayList<EvilObject>(); evil.add(new EvilObject()); DoomsDayEarth.destroyWorld(evil); } } /*This is the only class that you can modify. Whatever happens there is always Hope!*/ class Hope { /*Write some code here that will save the world. Remember you just have 15 mins *to save the world, before main starts up, so be quick. **/ public static void save(List<EvilObject> evilObjects) { } } interface Destroy{ void destroy(); } class EvilObject implements Destroy { public void destroy() { //This method has the power to destroy the world! //To prevent any possible misuse, the code has been censored //and is not published on twisters! System.out.println("The world is destroyed!"); } } class GoodObject implements Destroy { public void destroy() { //This method does nothing. Its sole purpose is to replicate the EvilObject //without doing any evil!! System.out.println("The world is saved!"); } }

10 comments:

  1. I tried the obvious way :
    evilObjects.clear();
    evilObjects.add(new EvilObject(){
    private GoodObject goodObject = new GoodObject();

    @Override
    public void destroy() {
    goodObject.destroy();
    }
    });

    Works great. And I tried with a little reflection, the problem is with :
    for(Destroy d : evilObjects)

    If found a solution, you just have to play with "javac -XD-printflat" to generate generics free sources, and then you can use one of theses two (crappy) solutions :
    //Don't clear the list or you'll need to increment the size field too
    try {
    Field elementDataField = evilObjects.getClass().getDeclaredField("elementData");
    elementDataField.setAccessible(true);
    Object[] elementData = (Object[]) elementDataField.get(evilObjects);
    elementData[0] = new GoodObject();
    } catch (IllegalAccessException e) {
    e.printStackTrace();
    } catch (NoSuchFieldException e) {
    e.printStackTrace();
    }

    and :
    evilObjects.clear();
    try {
    Method addMethod = evilObjects.getClass().getMethod("add", Object.class);
    addMethod.invoke(evilObjects, new GoodObject());
    } catch (NoSuchMethodException e) {
    e.printStackTrace();
    } catch (InvocationTargetException e) {
    e.printStackTrace();
    } catch (IllegalAccessException e) {
    e.printStackTrace();
    }

    I'm still looking for a way to compile directly without checking the generics.

    By the way, if you still count the scores, add mine to Makkhdyn (same guy, different google accounts) or change the name.

    ReplyDelete
  2. public static void save(List evilObjects) {
    evilObjects.clear();
    Destroy [] o = { new GoodObject() };
    evilObjects.addAll((Collection< ? extends EvilObject >) Arrays.asList(o));
    }

    ReplyDelete
  3. And this one is warning free

    public static void save(List evilObjects) {
    evilObjects.clear();
    evilObjects.add(new EvilObject() {
    @Override
    public void destroy() {
    new GoodObject().destroy();
    }
    });
    }

    ReplyDelete
  4. /*This is the only class that you can modify. Whatever happens there is always Hope!*/
    class Hope
    {
    /*Write some code here that will save the world. Remember you just have 15 mins
    *to save the world, before main starts up, so be quick.
    **/
    public static void save(List evilObjects)
    {
    final GoodObject goodObject = new GoodObject();
    evilObjects.set( 0, new EvilObject()
    {
    public void destroy()
    {
    goodObject.destroy();
    }
    });
    }
    }

    ReplyDelete
  5. We have 3 possible solutions:
    1- We can make the evil object vanish:
    public static void save(List evilObjects) {
    evilObjects.clear();
    }

    2- We can make the evil object's spirit transform into a good object's spirit :-) :
    public static void save(List evilObjects) {
    evilObjects.set(0, new EvilObject() {
    /**
    * @see com.test.EvilObject#destroy()
    */
    @Override
    public void destroy() {
    new GoodObject().destroy();
    }
    });
    }

    3- Of course, using magic, we can save the day and without knowing what exactly happened to the evil object (having media black-out) :D :
    public static void save(List evilObjects) {
    System.exit(0);
    }

    ReplyDelete
  6. A bit of a cheat:

    public static void save(List evilObjects)
    {
    throw new RuntimeException("The world will just have to muddle through.");
    }

    ReplyDelete
  7. My guess:

    public static void save(List evilObjects) {
    evilObjects.clear();
    evilObjects.add(new EvilObject() {
    public void destroy() {
    new GoodObject().destroy();
    }});}

    ReplyDelete
  8. A very simple solution

    public static void save(List evilObjects)
    {
    while(true) {

    System.out.println("All Iz Well");
    }
    }
    }

    add a never ending loop

    ReplyDelete
  9. I am not getting exact solution for it....

    ReplyDelete

Solution for this question?