Esegui un sorvolo di Plutone


21

Congratulazioni! Sei stato appena assunto dalla NASA per lavorare al nuovo progetto Horizons 2.

Purtroppo, recentemente ci sono stati enormi tagli al budget, quindi il top management ha deciso di falsificare l'intero flyby Pluto pianificato (come hanno fatto per gli sbarchi sulla luna negli anni '70).

Il tuo compito è quello di scrivere un programma che accetterà come input una data nel formato yyyymmdde fornirà una falsa fotografia di Plutone per questa data. Puoi presumere che la data inserita sia nell'anno 2015 o 2016.

La fotografia è una griglia 15x15 di caratteri ASCII. I personaggi sulla griglia hanno le loro coordinate x e y all'interno dell'intervallo [-7, 7]: il carattere in alto a sinistra è a (-7, -7)mentre il carattere in basso a destra è a (7, 7).

La fotografia verrà calcolata con le seguenti regole:

  • La sonda sarà la più vicina a Plutone il 25/12/2015
  • La distanza dda Plutone è data da questa formula:square root of ((difference in days to christmas) ^ 2 + 10)
  • Il raggio rdell'immagine di Plutone sulla foto è dato da:22 / d
  • Un carattere con coordinate (x, y)sulla griglia deve essere impostato su #if x^2 + y^2 <= r^2; deve essere impostato su spazio altrimenti.
  • Ci sono stelle in posizioni (-3, -5), (6, 2), (-5, 6), (2, 1), (7, -2). Le stelle sono rappresentate da un punto .e sono ovviamente nascoste da Plutone.

Ancora una cosa: il consiglio della NASA è giunto alla conclusione che la scoperta della vita su Plutone comporterebbe probabilmente un sostanziale aumento del budget. Il tuo programma dovrebbe quindi aggiungere indizi sulla vita su Plutone:

  • Quando la distanza da Plutone è <= 4, aggiungi un plutoniano alle coordinate (-3,-1):(^_^)

Esempio di fotografia per l'input 20151215: (Il tuo codice dovrebbe avere tutte le nuove righe come fa questo codice)

               

    .          


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



  .            

Fotografia per input 20151225:

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

A titolo di confronto, ecco una foto del satellite Hydra di Plutone scattata da New Horizons. Le differenze sono appena percettibili con la nostra arte ASCII.

inserisci qui la descrizione dell'immagine

Questo è il codice golf, quindi vince il codice più breve in byte!


1
Questa sarebbe stata una sfida perfetta per il linguaggio di disegno artistico ASCII a cui sto lavorando. Forse posterò una risposta con esso dopo che è finito. :)
ETHproductions,

1
@SuperChafouin Ho rimosso la `s in favore di <pre><code>; sentiti libero di tornare indietro se non ti piace.
Justin,

1
You can assume the entered date will be in the year 2015 or 2016.Ma allora perché specificare un anno?
mınxomaτ,

Posso prendere le date nel modulo 2015/12/25?
intrepidcoder

Risposte:


3

JavaScript (ES6), 237 byte

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

Demo dal vivo . Esegui in Firefox.

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

Golf

È stato divertente giocare a golf.

Non ho bisogno di creare un oggetto Date, quindi ho codificato il valore in millisecondi per salvare 13 byte:

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

Sostituisci l'array associativo con una stringa delimitata per eliminare 9 byte:

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

Il più grande refattore stava sostituendo i loop con i IIFE nidificati e ricorsivi per eliminare 10 byte:

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

Mi sono anche liberato di Math.sqrtaltri 8 byte.

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

Problemi

Ho potuto ottenere la fotografia corretta solo per i casi di test cambiando la data più vicina a 24/12/2015 e non so se il problema risiede nel mio codice o nella domanda. Si prega di chiarire e aggiornerò la mia risposta.

Ecco il mio output usando le differenze dal 25/12/2015.

Modifica: risposta aggiornata per utilizzare Natale come data più vicina.

Fotografia per "20151215":

                   

        .          


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



      .            
                   

Fotografia per "20151225":

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

I miei due esempi erano sbagliati (c'era un turno di un giorno), li ho corretti nella domanda. Grazie per averlo indicato!
Arnaud,

3

C # 4.0, 393 byte

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

Esempio:

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

Produzione:

20151216


    .


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



  .

20151224

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

2

CJam, 165 byte

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 prima parte calcola la differenza del giorno e la memorizza nella Dvariabile. Il resto è un doppio ciclo che scorre attraverso Xe Y.

Provalo qui

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.