Lakukan flyby Pluto

21

Selamat! Anda baru saja dipekerjakan oleh NASA untuk mengerjakan proyek Horizons 2 yang baru.

Sayangnya, ada pemotongan anggaran besar baru-baru ini, sehingga manajemen puncak telah memutuskan untuk memalsukan seluruh flyby Pluto yang direncanakan (seperti yang mereka lakukan untuk pendaratan di bulan di tahun 70-an).

Tugas Anda adalah menulis program yang akan menerima sebagai masukan tanggal dalam format yyyymmdd, dan akan memberikan foto Pluto palsu untuk tanggal ini. Anda dapat mengasumsikan tanggal yang dimasukkan adalah tahun 2015 atau 2016.

Foto itu adalah kisi-kisi karakter ASCII 15x15. Karakter pada kisi memiliki koordinat x dan y dalam rentang [-7, 7]- karakter kiri atas berada pada (-7, -7)saat karakter kanan bawah berada pada (7, 7).

Foto akan dihitung dengan aturan berikut:

  • Probe akan menjadi yang terdekat ke Pluto pada 25/12/2015
  • Jarak dke Pluto diberikan oleh rumus ini:square root of ((difference in days to christmas) ^ 2 + 10)
  • Jari-jari rgambar Pluto pada foto diberikan oleh:22 / d
  • Karakter dengan koordinat (x, y)pada kisi harus diatur ke #jika x^2 + y^2 <= r^2; itu harus diatur ke ruang sebaliknya.
  • Ada bintang di posisi (-3, -5), (6, 2), (-5, 6), (2, 1), (7, -2). Bintang-bintang diwakili oleh sebuah titik ., dan mereka tentu saja disembunyikan oleh Pluto.

Satu hal lagi: Dewan NASA sampai pada kesimpulan bahwa penemuan kehidupan di Pluto kemungkinan akan menghasilkan peningkatan anggaran yang substansial. Program Anda kemudian harus menambahkan petunjuk kehidupan di Pluto:

  • Ketika jarak ke Pluto adalah <= 4, tambahkan plutonian pada koordinat (-3,-1):(^_^)

Contoh foto untuk input 20151215: (Kode Anda harus memiliki semua baris baru seperti kode ini)

               

    .          


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



  .            

Foto untuk input 20151225:

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

Sebagai perbandingan, berikut adalah foto Hydra satelit Pluto yang diambil oleh New Horizons. Perbedaan hampir tidak terlihat dengan seni ASCII kami.

masukkan deskripsi gambar di sini

Ini kode golf, jadi kode terpendek dalam byte menang!

Arnaud
sumber
1
Ini akan menjadi tantangan yang sempurna untuk bahasa gambar seni ASCII yang sedang saya kerjakan. Mungkin saya akan mengirim jawaban setelah itu selesai. :)
ETHproduksi
1
@SuperChafouin Saya menghapus `s mendukung <pre><code>; jangan ragu untuk mundur jika Anda tidak menyukainya.
Justin
1
You can assume the entered date will be in the year 2015 or 2016.Tapi mengapa harus menentukan tahun?
mınxomaτ
Bisakah saya mengambil tanggal dalam formulir 2015/12/25?
intrepidcoder

Jawaban:

3

JavaScript (ES6), 237 byte

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 langsung . Jalankan di Firefox.

Versi asli

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

Ini menyenangkan untuk bermain golf.

Saya tidak perlu membuat objek Date, jadi saya hardcoded nilai dalam milidetik untuk menyimpan 13 byte:

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

Ganti array asosiatif dengan string terbatas untuk menghilangkan 9 byte:

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

Refactor terbesar mengganti for loop dengan IIFE bersarang, rekursif untuk menghasilkan 10 byte:

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

Saya juga menyingkirkan Math.sqrt8 byte lebih.

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

Masalah

Saya hanya bisa mendapatkan foto yang benar untuk kasus uji dengan mengubah tanggal terdekat ke 2015/12/24, dan saya tidak tahu apakah masalahnya ada pada kode saya atau pertanyaannya. Tolong jelaskan dan saya akan memperbarui jawaban saya.

Ini adalah output saya menggunakan perbedaan dari 2015/12/25.

Sunting: Jawaban yang diperbarui untuk menggunakan Natal sebagai tanggal terdekat.

Foto untuk "20151215":

                   

        .          


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



      .            
                   

Foto untuk "20151225":

                   
        #######    
       #########   
      ###########  
     ############# 
     #############.
     ###(^_^)##### 
     ############# 
     ############# 
     ############# 
     ############# 
      ###########  
       #########   
      . #######    
                   
intrepidcoder
sumber
Dua contoh saya salah (ada shift satu hari), saya telah mengoreksi mereka dalam pertanyaan. Terima kasih telah menunjukkan itu!
Arnaud
3

C # 4.0, 393 byte

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

Contoh:

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

Keluaran:

20151216


    .


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



  .

20151224

     #####
   #########
  ###########
  ###########
 #############.
 ###(^_^)#####
 #############
 #############
 #############
  ###########
  ###########
   #########
  .  #####
Peter Saliente
sumber
2

CJam, 165 byte

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

Bagian pertama menghitung perbedaan hari dan menyimpannya dalam Dvariabel. Sisanya adalah loop ganda yang berulang melalui Xdan Y.

Uji di sini

Arnaud
sumber