21
\$\begingroup\$

Congratulations! You've just been hired by NASA to work on the new Horizons 2 project.

Sadly, there have been huge budget cuts recently, so the top management has decided to fake the whole planned Pluto flyby (as they did for the moon landings in the 70s).

Your task is to write a program that will accept as input a date in the format yyyymmdd, and will provide a fake photograph of Pluto for this date. You can assume the entered date will be in the year 2015 or 2016.

The photograph is a 15x15 grid of ASCII characters. The characters on the grid have their x- and y-coordinates within the range [-7, 7] - the top-left character is at (-7, -7) while the bottom-right character is at (7, 7).

The photograph will be computed with the following rules:

  • The probe will be the nearest to Pluto on 25/12/2015
  • The distance d to Pluto is given by this formula : square root of ((difference in days to christmas) ^ 2 + 10)
  • The radius r of Pluto's image on the photo is given by : 22 / d
  • A character with coordinates (x, y) on the grid must be set to # if x^2 + y^2 <= r^2 ; it must be set to space otherwise.
  • There are stars at positions (-3, -5), (6, 2), (-5, 6), (2, 1), (7, -2). Stars are represented by a dot ., and they are of course hidden by Pluto.

One more thing: The NASA board has come to the conclusion that the discovery of life on Pluto would likely result in a substantial budget increase. Your program should then add clues of life on Pluto:

  • When the distance to Pluto is <= 4, add a plutonian at coordinates (-3,-1) : (^_^)

Example photograph for input 20151215: (Your code should have all the newlines as this code does)

               

    .          


       #      .
      ###      
     #####     
      ###.     
       #     . 



  .            

Photograph for input 20151225:

               
    #######    
   #########   
  ###########  
 ############# 
 #############.
 ###(^_^)##### 
 ############# 
 ############# 
 ############# 
 ############# 
  ###########  
   #########   
  . #######    

As a comparison, here's a photo of Pluto's satellite Hydra as taken by New Horizons. Differences are hardly noticeable with our ASCII art.

enter image description here

This is code golf, so the shortest code in bytes wins!

\$\endgroup\$
  • 1
    \$\begingroup\$ This would've been a perfect challenge for the ASCII-art-drawing language I'm working on. Perhaps I'll post an answer with it after it's finished. :) \$\endgroup\$ – ETHproductions Sep 28 '15 at 2:35
  • 1
    \$\begingroup\$ @SuperChafouin I removed the `s in favour of <pre><code>; feel free to roll back if you don't like it. \$\endgroup\$ – Justin Sep 28 '15 at 5:19
  • 1
    \$\begingroup\$ You can assume the entered date will be in the year 2015 or 2016. But then why specify a year at all? \$\endgroup\$ – mınxomaτ Sep 28 '15 at 6:42
  • \$\begingroup\$ Can I take dates in the form 2015/12/25? \$\endgroup\$ – intrepidcoder Oct 1 '15 at 14:45
3
\$\begingroup\$

JavaScript (ES6), 237 bytes

f=(n)=>(t=new Date('201'+n[3],n[4]+n[5],n[6]+n[7])/864e5-403805/24,r=484/(t*t+10),(g=(i)=>(++i<8?(h=(j)=>(i*i+j*j<=r?r>30.25&!~i&&'(^_^)'[j+3]||'#':~'p-3-5p62p-56p21p7-2'.indexOf('p'+j+i)?'.':' ')+(++j<8?h(j):''))(-7)+'\n'+g(i):''))(-8))

Live demo. Run in Firefox.

Original version

f=function(n) {
    t = (new Date('201'+n[3],''+n[4]+n[5],''+n[6]+n[7]) // Find the time difference in milliseconds,
    - new Date(2015,12,25)) / 864e5;                    // then divide by 86400000 to convert to days.

    r=22 / Math.sqrt(t*t+10);                           // Calculate the radius.

    s=[]; // s is the array that contains each line as a string.

    for(i=-7;i<8;i++)               // Loop through rows.
        for(j=-7,s[i+7]='';j<8;j++) // Loop through columns, appending one character per column.
                                    // s is zero based, so add 7 to the row.
            s[i+7]+=i*i+j*j<=r*r ?  // Choose which character to add to s. 
            (r>5.5&i==-1&&'(^_^)'[j+3]||'#') :  // Add a '#' if the position is inside the radius.
                                                // If distance < 4, then the radius > 5.5
                                                // Then add the face at the right position.
            {'-3-5':1,'62':1,'-56':1,'21':1,'7-2':1} // Add the stars if outside. Create an associative array.
            [j+''+i]?'.':' ';                        // If i concat j is in the array, the expression will be 1, 
                                                     // which is truthy, else it will be undefined, which is falsey.
    return s.join`\n` // Join all the rows with a new-line.
}

Golfing

This was fun to golf.

I don't need to create a Date object, so I hardcoded the value in milliseconds to save 13 bytes:

t=(new Date('201'+n[3],n[4]+n[5],n[6]+n[7])-new Date(2015,12,25))/864e5 // Before
t=new Date('201'+n[3],n[4]+n[5],n[6]+n[7])/864e5-403805/24 // After

Replace the associative array with a delimited string to eliminate 9 bytes:

{'-3-5':1,'62':1,'-56':1,'21':1,'7-2':1}[j+''+i]?'.':' ' // Before
~'p-3-5p62p-56p21p7-2'.indexOf('p'+j+i)?'.':' ' // After

The biggest refactor was replacing the for loops with nested, recursive IIFEs to knock off 10 bytes:

s=[];for(i=-7;i<8;i++)for(j=-7,s[i+7]='';j<8;j++)s[i+7]+= /* Chooses char at i,j */ ;return s.join`\n` // Before
(g=(i)=>(++i<8?(h=(j)=>( /* Chooses char at i,j */ )+(++j<8?h(j):''))(-7)+'\n'+g(i):''))(-8) // After

I also got rid of Math.sqrt for 8 more bytes.

r=22/Math.sqrt(t*t+10),(g=(i)=>(++i<8?(h=(j)=>(i*i+j*j<=r*r?r>5.5 // Before
r=484/(t*t+10),(g=(i)=>(++i<8?(h=(j)=>(i*i+j*j<=r?r>30.25 // After

Issues

I could only get the correct photograph for the test cases by changing the closest date to 2015/12/24, and I don't know if the problem lies in my code or the question. Please clarify and I will update my answer.

Here is my output using the differences from 2015/12/25.

Edit: Updated answer to use Christmas as the closest date.

Photograph for "20151215":

                   

        .          


           #      .
          ###      
         #####     
          ###.     
           #     . 



      .            
                   

Photograph for "20151225":

                   
        #######    
       #########   
      ###########  
     ############# 
     #############.
     ###(^_^)##### 
     ############# 
     ############# 
     ############# 
     ############# 
      ###########  
       #########   
      . #######    
                   
\$\endgroup\$
  • \$\begingroup\$ My two examples were wrong (there was a one day shift), I have corrected them in the question. Thanks for pointing that! \$\endgroup\$ – Arnaud Oct 1 '15 at 4:51
3
\$\begingroup\$

C# 4.0, 393 bytes

string p(string s){int i=Convert.ToInt32(s),Y=i/10000,m,x,y;s="";i-=Y*10000;m=i/100;i-=m*100;double d=Math.Sqrt(Math.Pow((new DateTime(2015,12,25)-new DateTime(Y,m,i)).Days,2)+10);string o,k=".-3-5.62.-56.21.7-2";for(y=-7;y<8;y++){for(x=-7;x<8;x++){o="#";if(d<=4&&x==-3&&y==-1){o="(^_^)";x+=4;}s+=Math.Pow(x,2)+Math.Pow(y,2)<=Math.Pow(22/d,2)?o:k.Contains("."+x+y)?".":" ";}s+="\n";}return s;}

Example:

string userInput = Console.ReadLine();
Console.WriteLine(p(userInput));

Output:

20151216


    .


      ###     .
     #####
     #####
     #####
      ###    .



  .

20151224

     #####
   #########
  ###########
  ###########
 #############.
 ###(^_^)#####
 #############
 #############
 #############
  ###########
  ###########
   #########
  .  #####
\$\endgroup\$
2
\$\begingroup\$

CJam, 165 bytes

q'-%:i~\0\({X1=29W$2%-X7<X+2%30+?+}fX+\2%-359 6?+:DD*A+mq:Z22Z/_*:R-7:Y];F{-7:X;F{XX*YY*+R>XYF*+[-78II+85H-23]#)'.S?Z4<Y-1=X-4>X2<&&&X-3="(^_^)"L?'#??X):X;}*NY):Y;}*

The first part computes the day difference and stores it in the D variable. The rest is a double loop that iterates through X and Y.

Test it here

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.