Wykonaj przelot Plutona

21

Gratulacje! Właśnie zostałeś zatrudniony przez NASA do pracy nad nowym projektem Horizons 2.

Niestety ostatnio miały miejsce ogromne cięcia budżetowe, więc najwyższe kierownictwo postanowiło sfałszować cały planowany przelot Plutona (podobnie jak w przypadku lądowań na Księżycu w latach 70.).

Twoim zadaniem jest napisanie programu, który zaakceptuje jako datę datę w formacie yyyymmddi dostarczy fałszywe zdjęcie Plutona na tę datę. Możesz założyć, że wprowadzona data będzie w roku 2015 lub 2016.

Zdjęcie to siatka 15 x 15 znaków ASCII. Znaki na siatce mają współrzędne x i y w zakresie [-7, 7]- lewy górny znak znajduje się na, (-7, -7)a prawy dolny znak na (7, 7).

Zdjęcie zostanie obliczone według następujących zasad:

  • Sonda będzie najbliżej Plutona 25.12.2015
  • Odległość ddo Plutona jest określona przez ten wzór:square root of ((difference in days to christmas) ^ 2 + 10)
  • Promień robrazu Plutona na zdjęciu jest określony przez:22 / d
  • Znak ze współrzędnymi (x, y)na siatce należy ustawić na #if x^2 + y^2 <= r^2; w przeciwnym razie należy ustawić spację.
  • Są gwiazdy w pozycji (-3, -5), (6, 2), (-5, 6), (2, 1), (7, -2). Gwiazdy są reprezentowane przez kropkę .i oczywiście są ukryte przez Plutona.

Jeszcze jedno: Rada NASA doszła do wniosku, że odkrycie życia na Plutonie prawdopodobnie spowoduje znaczny wzrost budżetu. Twój program powinien następnie dodać wskazówki życia na Plutonie:

  • Gdy odległość do Plutona wynosi <= 4, dodaj pluton o współrzędnych (-3,-1):(^_^)

Przykładowe zdjęcie do wprowadzenia 20151215: (Twój kod powinien zawierać wszystkie znaki nowej linii, tak jak ten kod)

               

    .          


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



  .            

Zdjęcie do wprowadzenia 20151225:

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

Dla porównania, oto zdjęcie satelity Pluto Hydra zrobione przez New Horizons. Różnice są prawie niezauważalne w naszej sztuce ASCII.

wprowadź opis zdjęcia tutaj

To jest kod golfowy, więc wygrywa najkrótszy kod w bajtach!

Arnaud
źródło
1
Byłoby to idealne wyzwanie dla języka rysowania ASCII, nad którym pracuję. Być może opublikuję odpowiedź po jej zakończeniu. :)
ETHproductions
1
@ SuperChafouin Usunąłem `s na rzecz <pre><code>; możesz się wycofać, jeśli ci się nie podoba.
Justin
1
You can assume the entered date will be in the year 2015 or 2016.Ale dlaczego w ogóle określać rok?
mınxomaτ
Czy mogę przyjmować daty w formie 2015/12/25?
intrepidcoder

Odpowiedzi:

3

JavaScript (ES6), 237 bajtów

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 na żywo . Uruchom w przeglądarce Firefox.

Orginalna wersja

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

Gra w golfa

To była fajna gra w golfa.

Nie muszę tworzyć obiektu Date, więc zapisałem wartość w milisekundach, aby zapisać 13 bajtów:

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

Zamień tablicę asocjacyjną na ciąg ograniczników, aby wyeliminować 9 bajtów:

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

Największym refaktorem było zastąpienie pętli for zagnieżdżonymi, rekurencyjnymi IIFE, aby zrzucić 10 bajtów:

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

Pozbyłem się także Math.sqrt8 kolejnych bajtów.

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

Zagadnienia

Mogłem tylko uzyskać prawidłowe zdjęcie dla przypadków testowych, zmieniając najbliższą datę na 2015/12/24 i nie wiem, czy problem leży w moim kodzie, czy w pytaniu. Proszę wyjaśnić, a ja zaktualizuję swoją odpowiedź.

Oto mój wynik, używając różnic od 2015/12/25.

Edycja: Zaktualizowano odpowiedź, aby użyć świąt Bożego Narodzenia jako najbliższej daty.

Zdjęcie dla „20151215”:

                   

        .          


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



      .            
                   

Zdjęcie dla „20151225”:

                   
        #######    
       #########   
      ###########  
     ############# 
     #############.
     ###(^_^)##### 
     ############# 
     ############# 
     ############# 
     ############# 
      ###########  
       #########   
      . #######    
                   
intrepidcoder
źródło
Moje dwa przykłady były błędne (nastąpiła jednodniowa zmiana), poprawiłem je w pytaniu. Dzięki za wskazanie tego!
Arnaud
3

C # 4.0, 393 bajty

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

Przykład:

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

Wydajność:

20151216


    .


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



  .

20151224

     #####
   #########
  ###########
  ###########
 #############.
 ###(^_^)#####
 #############
 #############
 #############
  ###########
  ###########
   #########
  .  #####
Peter Saliente
źródło
2

CJam, 165 bajtów

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

Pierwsza część oblicza różnicę dnia i zapisuje ją w Dzmiennej. Reszta to podwójna pętla, która iteruje przez Xi Y.

Sprawdź to tutaj

Arnaud
źródło