Effectuer un survol de Pluton

21

Toutes nos félicitations! Vous venez d'être embauché par la NASA pour travailler sur le nouveau projet Horizons 2.

Malheureusement, il y a eu d'énormes compressions budgétaires récemment, donc la direction a décidé de simuler tout le survol de Pluton prévu (comme ils l'ont fait pour les alunissages dans les années 70).

Votre tâche consiste à écrire un programme qui acceptera comme entrée une date au format yyyymmddet fournira une fausse photographie de Pluton pour cette date. Vous pouvez supposer que la date entrée sera en 2015 ou 2016.

La photographie est une grille 15x15 de caractères ASCII. Les caractères sur la grille ont leurs coordonnées x et y dans la plage [-7, 7]- le caractère en haut à gauche est à (-7, -7)tandis que le caractère en bas à droite est à (7, 7).

La photographie sera calculée selon les règles suivantes:

  • La sonde sera la plus proche de Pluton le 25/12/2015
  • La distance dà Pluton est donnée par cette formule:square root of ((difference in days to christmas) ^ 2 + 10)
  • Le rayon r de l'image de Pluton sur la photo est donné par:22 / d
  • Un caractère avec des coordonnées (x, y)sur la grille doit être défini sur #if x^2 + y^2 <= r^2; sinon, il doit être réglé sur espace.
  • Il y a des étoiles à des positions (-3, -5), (6, 2), (-5, 6), (2, 1), (7, -2). Les étoiles sont représentées par un point ., et elles sont bien sûr cachées par Pluton.

Une dernière chose: le conseil d'administration de la NASA est parvenu à la conclusion que la découverte de la vie sur Pluton entraînerait probablement une augmentation substantielle du budget. Votre programme devrait ensuite ajouter des indices de vie sur Pluton:

  • Lorsque la distance à Pluton est <= 4, ajoutez un plutonien aux coordonnées (-3,-1):(^_^)

Exemple de photo à saisir 20151215: (votre code doit avoir toutes les nouvelles lignes comme ce code)

               

    .          


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



  .            

Photographie pour entrée 20151225:

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

À titre de comparaison, voici une photo du satellite Hydra de Pluton prise par New Horizons. Les différences sont à peine perceptibles avec notre art ASCII.

entrez la description de l'image ici

C'est le golf de code, donc le code le plus court en octets gagne!

Arnaud
la source
1
Cela aurait été un défi parfait pour le langage de dessin artistique ASCII sur lequel je travaille. Peut-être que je posterai une réponse avec elle une fois terminée. :)
ETHproductions
1
@SuperChafouin J'ai supprimé le `s en faveur de <pre><code>; n'hésitez pas à revenir en arrière si vous ne l'aimez pas.
Justin
1
You can assume the entered date will be in the year 2015 or 2016.Mais alors pourquoi spécifier une année?
mınxomaτ
Puis-je prendre des dates sous la forme 2015/12/25?
intrepidcoder du

Réponses:

3

JavaScript (ES6), 237 octets

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))

Démo en direct . Exécutez dans Firefox.

Version originale

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.
}

Le golf

C'était amusant de jouer au golf.

Je n'ai pas besoin de créer un objet Date, j'ai donc codé en dur la valeur en millisecondes pour économiser 13 octets:

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

Remplacez le tableau associatif par une chaîne délimitée pour éliminer 9 octets:

{'-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

Le plus grand refactor a été de remplacer les boucles for par des IIFE récursifs imbriqués pour supprimer 10 octets:

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

Je me suis également débarrassé de Math.sqrt8 octets de plus.

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

Problèmes

Je n'ai pu obtenir la photo correcte pour les cas de test qu'en changeant la date la plus proche à 2015/12/24, et je ne sais pas si le problème réside dans mon code ou la question. Veuillez clarifier et je mettrai à jour ma réponse.

Voici ma sortie en utilisant les différences par rapport au 25/12/2015.

Modifier: réponse mise à jour pour utiliser Noël comme date la plus proche.

Photographie pour "20151215":

                   

        .          


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



      .            
                   

Photographie de "20151225":

                   
        #######    
       #########   
      ###########  
     ############# 
     #############.
     ###(^_^)##### 
     ############# 
     ############# 
     ############# 
     ############# 
      ###########  
       #########   
      . #######    
                   
intrépide
la source
Mes deux exemples étaient erronés (il y avait un quart de travail d'une journée), je les ai corrigés dans la question. Merci d'avoir souligné ça!
Arnaud
3

C # 4.0, 393 octets

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;}

Exemple:

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

Sortie:

20151216


    .


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



  .

20151224

     #####
   #########
  ###########
  ###########
 #############.
 ###(^_^)#####
 #############
 #############
 #############
  ###########
  ###########
   #########
  .  #####
peter saliente
la source
2

CJam, 165 octets

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;}*

La première partie calcule la différence de jour et la stocke dans la Dvariable. Le reste est une double boucle qui parcourt XetY .

Testez-le ici

Arnaud
la source