Realizar un sobrevuelo de Plutón

21

¡Felicidades! La NASA te acaba de contratar para trabajar en el nuevo proyecto Horizons 2.

Lamentablemente, recientemente ha habido grandes recortes presupuestarios, por lo que la alta gerencia ha decidido fingir todo el sobrevuelo planeado de Plutón (como lo hicieron para los alunizajes en los años 70).

Su tarea es escribir un programa que acepte como entrada una fecha en el formato yyyymmddy proporcionará una fotografía falsa de Plutón para esta fecha. Puede suponer que la fecha ingresada será en el año 2015 o 2016.

La fotografía es una cuadrícula de 15x15 de caracteres ASCII. Los caracteres en la cuadrícula tienen sus coordenadas x e y dentro del rango [-7, 7]: el carácter superior izquierdo está en (-7, -7)mientras que el carácter inferior derecho está en (7, 7).

La fotografía se computará con las siguientes reglas:

  • La sonda será la más cercana a Plutón el 25/12/2015
  • La distancia da Plutón viene dada por esta fórmula:square root of ((difference in days to christmas) ^ 2 + 10)
  • El radio rde la imagen de Plutón en la foto viene dado por:22 / d
  • Un carácter con coordenadas (x, y)en la cuadrícula debe establecerse en #if x^2 + y^2 <= r^2; debe establecerse en espacio de lo contrario.
  • Hay estrellas en las posiciones (-3, -5), (6, 2), (-5, 6), (2, 1), (7, -2). Las estrellas están representadas por un punto .y, por supuesto, están ocultas por Plutón.

Una cosa más: la junta de la NASA llegó a la conclusión de que el descubrimiento de la vida en Plutón probablemente resultaría en un aumento sustancial del presupuesto. Su programa debería agregar pistas de la vida en Plutón:

  • Cuando la distancia a Plutón es <= 4, agregue un plutoniano en las coordenadas (-3,-1):(^_^)

Fotografía de ejemplo para entrada 20151215: (Su código debe tener todas las líneas nuevas como lo hace este código)

               

    .          


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



  .            

Fotografía para entrada 20151225:

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

A modo de comparación, aquí hay una foto del satélite Hydra de Plutón tomada por New Horizons. Las diferencias apenas se notan con nuestro arte ASCII.

ingrese la descripción de la imagen aquí

Este es el código de golf, por lo que gana el código más corto en bytes.

Arnaud
fuente
1
Este habría sido un desafío perfecto para el lenguaje de dibujo de arte ASCII en el que estoy trabajando. Tal vez publique una respuesta con él después de que haya terminado. :)
ETHproductions
1
@SuperChafouin Eliminé la `s a favor de <pre><code>; siéntase libre de retroceder si no le gusta.
Justin
1
You can assume the entered date will be in the year 2015 or 2016.Pero entonces, ¿por qué especificar un año?
mınxomaτ
¿Puedo tomar fechas en el formulario 2015/12/25?
intrepidcoder

Respuestas:

3

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

Demostración en vivo . Ejecutar en Firefox.

Versión original

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

Esto fue divertido para el golf.

No necesito crear un objeto Date, así que codifiqué el valor en milisegundos para guardar 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

Reemplace la matriz asociativa con una cadena delimitada para eliminar 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

El refactor más grande fue reemplazar los bucles for con IIFE anidados y recursivos para eliminar 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

También me deshice de Math.sqrt8 bytes más.

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

Cuestiones

Solo pude obtener la fotografía correcta para los casos de prueba cambiando la fecha más cercana a 2015/12/24, y no sé si el problema radica en mi código o la pregunta. Por favor aclare y actualizaré mi respuesta.

Aquí está mi salida usando las diferencias de 2015/12/25.

Editar: Respuesta actualizada para usar Navidad como la fecha más cercana.

Fotografía de "20151215":

                   

        .          


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



      .            
                   

Fotografía de "20151225":

                   
        #######    
       #########   
      ###########  
     ############# 
     #############.
     ###(^_^)##### 
     ############# 
     ############# 
     ############# 
     ############# 
      ###########  
       #########   
      . #######    
                   
codificador intrépido
fuente
Mis dos ejemplos estaban equivocados (hubo un turno de un día), los he corregido en la pregunta. Gracias por señalar eso!
Arnaud
3

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

Ejemplo:

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

Salida:

20151216


    .


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



  .

20151224

     #####
   #########
  ###########
  ###########
 #############.
 ###(^_^)#####
 #############
 #############
 #############
  ###########
  ###########
   #########
  .  #####
peter saliente
fuente
2

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

La primera parte calcula la diferencia del día y la almacena en la Dvariable. El resto es un doble ciclo que itera a través de Xy Y.

Pruébalo aquí

Arnaud
fuente