Виконайте проліт Плутона


21

Вітаємо! Вас щойно найняли НАСА для роботи над новим проектом «Горизонти 2».

На жаль, останнім часом відбулися величезні скорочення бюджету, тому керівництво вищого рівня вирішило підробити всю заплановану проліт Плутона (як це було зроблено для висадки на Місяць у 70-х роках).

Ваше завдання - написати програму, яка прийме як введення дату у форматі yyyymmddі надасть фальшиву фотографію Плутона на цю дату. Ви можете припустити, що введена дата буде у 2015 або 2016 роках.

На фотографії представлена ​​сітка 15х15 символів ASCII. Символи на сітці мають свої координати x- і y у межах діапазону [-7, 7]- символ у верхньому лівому куті знаходиться в (-7, -7)той час, як нижній правий символ знаходиться у (7, 7).

Для фотографії буде обчислено такі правила:

  • Зонд буде найближчим до Плутона 25.12.2015
  • Відстань dдо Плутона задається такою формулою:square root of ((difference in days to christmas) ^ 2 + 10)
  • Радіус rзображення Плутона на фотографії задається:22 / d
  • Символ з координатами (x, y)в сітці повинен бути встановлений, #якщо x^2 + y^2 <= r^2; його потрібно встановити на простір інакше.
  • Є зірки в положеннях (-3, -5), (6, 2), (-5, 6), (2, 1), (7, -2). Зірки представлені крапкою ., і вони, звичайно, приховані Плутоном.

І ще одне: колегія NASA дійшла висновку, що відкриття життя на Плутоні, ймовірно, призведе до значного збільшення бюджету. Тоді ваша програма повинна додати підказки життя на Плутоні:

  • Коли відстань до Плутона <= 4, додайте плутоніан за координатами (-3,-1):(^_^)

Приклад фотографії для введення 20151215: (Ваш код повинен містити всі нові рядки, як це робить)

               

    .          


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



  .            

Фотографія для введення 20151225:

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

Для порівняння, ось фотографія супутника Плутона "Гідра", зроблена "New Horizons". Відмінності навряд чи помітні в нашому мистецтві ASCII.

введіть тут опис зображення

Це кодовий гольф, тому найкоротший код у байтах виграє!


1
Це було б ідеальним викликом для мови художнього малювання ASCII, над якою я працюю. Можливо, я опублікую відповідь з нею після її закінчення. :)
ETHproductions

1
@SuperChafouin я видалив `s на користь <pre><code>; не соромтеся відкочуватися, якщо вам це не подобається.
Джастін

1
You can assume the entered date will be in the year 2015 or 2016.Але тоді навіщо взагалі вказувати рік?
mınxomaτ

Чи можу я взяти дати у формі 2015/12/25?
intrepidcoder

Відповіді:


3

JavaScript (ES6), 237 байт

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

Демонстраційна демонстрація . Запуск у Firefox.

Оригінальна версія

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

Гольф

Це було весело гольфу.

Мені не потрібно створювати об’єкт Date, тому я жорстко закодував значення в мілісекундах, щоб зберегти 13 байт:

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

Замініть асоціативний масив розділеним рядком, щоб усунути 9 байт:

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

Найбільшим рефактором була заміна циклів for для вкладених, рекурсивних IIFE s, щоб збити 10 байт:

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

Я також позбувся ще Math.sqrtна 8 байт.

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

Випуски

Я міг отримати правильну фотографію для тестових випадків, змінивши найближчу дату до 2015/12/24, і не знаю, чи проблема полягає в моєму коді чи питанні. Прошу уточнити, і я оновлю свою відповідь.

Ось мій результат, використовуючи відмінності від 2015/12/25.

Редагувати: оновлена ​​відповідь на використання Різдва як найближчої дати.

Фотографія для "20151215":

                   

        .          


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



      .            
                   

Фотографія для "20151225":

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

Мої два приклади були помилковими (була зміна на один день), я виправив їх у питанні. Дякуємо, що вказали на це!
Арно

3

C # 4.0, 393 байт

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

Приклад:

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

Вихід:

20151216


    .


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



  .

20151224

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

2

CJam, 165 байт

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

Перша частина обчислює різницю днів і зберігає її у Dзмінній. Решта - це подвійна петля, яка проходить через Xі Y.

Тестуйте це тут

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.