Выполнить облет Плутона

21

Поздравляем! Вы только что были наняты НАСА для работы над новым проектом Horizons 2.

К сожалению, в последнее время произошли огромные сокращения бюджета, поэтому высшее руководство решило подделать весь запланированный полет Плутона (как они это сделали для посадок на Луну в 70-х годах).

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

Фотография представляет собой сетку 15x15 символов 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)на сетке должен быть установлен в #if x^2 + y^2 <= r^2; в противном случае он должен быть установлен на пробел.
  • Есть звезды в положениях (-3, -5), (6, 2), (-5, 6), (2, 1), (7, -2). Звезды представлены точкой ., и они, конечно, скрыты Плутоном.

Еще одна вещь: совет НАСА пришел к выводу, что открытие жизни на Плутоне, вероятно, приведет к существенному увеличению бюджета. Ваша программа должна добавить подсказки жизни на Плутоне:

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

Пример фотографии для ввода 20151215: (Ваш код должен иметь все новые строки, как этот код)

               

    .          


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



  .            

Фотография для ввода 20151225:

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

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

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

Это код гольф, поэтому выигрывает самый короткий код в байтах!

Arnaud
источник
1
Это было бы идеальным испытанием для языка рисования ASCII, над которым я работаю. Возможно я отправлю ответ с этим после того, как это закончено. :)
ETHproductions
1
@ SuperChafouin Я удалил `с в пользу <pre><code>; не стесняйтесь откатиться, если вам это не нравится.
Джастин
1
You can assume the entered date will be in the year 2015 or 2016.Но тогда зачем вообще указывать год?
Минксомаа
Могу ли я взять даты в форме 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, чтобы отбросить 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.sqrt8 байтов.

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":

                   
        #######    
       #########   
      ###########  
     ############# 
     #############.
     ###(^_^)##### 
     ############# 
     ############# 
     ############# 
     ############# 
      ###########  
       #########   
      . #######    
                   
intrepidcoder
источник
Мои два примера были неверны (была однодневная смена), я исправил их в вопросе. Спасибо за указание этого!
Арно
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.

Попробуй это здесь

Arnaud
источник