Executar um sobrevôo de Plutão


21

Parabéns! Você acabou de ser contratado pela NASA para trabalhar no novo projeto Horizons 2.

Infelizmente, houve enormes cortes no orçamento recentemente, então a alta gerência decidiu fingir todo o sobrevoo planejado de Plutão (como fizeram nos pousos na lua nos anos 70).

Sua tarefa é escrever um programa que aceite como entrada uma data no formato yyyymmdde forneça uma fotografia falsa de Plutão para essa data. Você pode supor que a data inserida será no ano de 2015 ou 2016.

A fotografia é uma grade 15x15 de caracteres ASCII. Os caracteres na grade têm suas coordenadas xe y dentro do intervalo [-7, 7]- o caractere superior esquerdo está em (-7, -7)enquanto o caractere inferior direito está em (7, 7).

A fotografia será calculada com as seguintes regras:

  • A sonda será a mais próxima de Plutão em 25/12/2015
  • A distância dpara Plutão é dada por esta fórmula:square root of ((difference in days to christmas) ^ 2 + 10)
  • O raio rda imagem de Plutão na foto é dado por:22 / d
  • Um caractere com coordenadas (x, y)na grade deve ser definido como #se x^2 + y^2 <= r^2; caso contrário, ele deve ser definido como espaço.
  • Há estrelas em posições (-3, -5), (6, 2), (-5, 6), (2, 1), (7, -2). As estrelas são representadas por um ponto .e, é claro, são escondidas por Plutão.

Mais uma coisa: o conselho da NASA chegou à conclusão de que a descoberta da vida em Plutão provavelmente resultaria em um aumento substancial do orçamento. Seu programa deve adicionar pistas da vida em Plutão:

  • Quando a distância até Plutão for <= 4, adicione um plutoniano nas coordenadas (-3,-1):(^_^)

Exemplo de fotografia para entrada 20151215: (Seu código deve ter todas as novas linhas como este código)

               

    .          


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



  .            

Fotografia para entrada 20151225:

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

Como comparação, aqui está uma foto do satélite Hydra de Plutão, tirada pela New Horizons. As diferenças são quase imperceptíveis em nossa arte ASCII.

insira a descrição da imagem aqui

Isso é código de golfe, então o código mais curto em bytes vence!


11
Esse teria sido um desafio perfeito para a linguagem de desenho de arte ASCII em que estou trabalhando. Talvez eu poste uma resposta depois que terminar. :)
— ETHproductions

11
@SuperChafouin removi os `s a favor de <pre><code>; sinta-se à vontade para reverter se não gostar.
— Justin Justin

11
You can assume the entered date will be in the year 2015 or 2016.Mas então por que especificar um ano?
— mınxomaτ 28/09/2015

Posso fazer datas no formato 25/12/2015?
— Intrepidcoder #

Respostas:


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

Demonstração ao vivo . Execute no Firefox.

Versão 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.
}

Golfe

Foi divertido jogar golfe.

Como não preciso criar um objeto Date, codifiquei o valor em milissegundos para salvar 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

Substitua a matriz associativa por uma sequência 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

O maior refator foi substituir os loops for por IIFE s aninhados e 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

Eu também me livrei de Math.sqrtmais 8 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

Problemas

Só consegui a fotografia correta para os casos de teste alterando a data mais próxima para 24/12/2015, e não sei se o problema está no meu código ou na pergunta. Esclareça e atualizarei minha resposta.

Aqui está a minha saída usando as diferenças de 25/12/2015.

Editar: resposta atualizada para usar o Natal como a data mais próxima.

Fotografia para "20151215":

                   

        .          


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



      .            
                   

Fotografia para "20151225":

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

Meus dois exemplos estavam errados (houve um turno de um dia), eu os corrigi na pergunta. Obrigado por apontar isso!
— 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;}

Exemplo:

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

Saída:

20151216


    .


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



  .

20151224

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

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

A primeira parte calcula a diferença do dia e a armazena na Dvariável O resto é um loop duplo que itera através de Xe Y.

Teste aqui

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.