Thực hiện một chuyến bay Pluto


21

Xin chúc mừng! Bạn vừa được NASA thuê để làm việc trong dự án Horizons 2 mới.

Đáng buồn thay, gần đây đã có sự cắt giảm ngân sách rất lớn, vì vậy ban lãnh đạo cao nhất đã quyết định giả mạo toàn bộ kế hoạch bay Pluto (như họ đã làm cho cuộc đổ bộ mặt trăng vào những năm 70).

Nhiệm vụ của bạn là viết một chương trình sẽ chấp nhận làm đầu vào một ngày ở định dạng yyyymmddvà sẽ cung cấp một bức ảnh giả về Sao Diêm Vương cho ngày này. Bạn có thể giả sử ngày nhập sẽ vào năm 2015 hoặc 2016.

Bức ảnh là một lưới 15x15 ký tự ASCII. Các ký tự trên lưới có tọa độ x và y trong phạm vi [-7, 7]- ký tự trên cùng bên trái ở (-7, -7)trong khi ký tự dưới cùng bên phải ở (7, 7).

Bức ảnh sẽ được tính toán với các quy tắc sau:

  • Tàu thăm dò sẽ là nơi gần nhất với Sao Diêm Vương vào ngày 25/12/2015
  • Khoảng cách dđến Sao Diêm Vương được tính theo công thức này:square root of ((difference in days to christmas) ^ 2 + 10)
  • Bán kính rhình ảnh của Sao Diêm Vương trên ảnh được đưa ra bởi:22 / d
  • Một ký tự có tọa độ (x, y)trên lưới phải được đặt thành #if x^2 + y^2 <= r^2; nó phải được đặt thành không gian khác.
  • Có những ngôi sao tại các vị trí (-3, -5), (6, 2), (-5, 6), (2, 1), (7, -2). Các ngôi sao được thể hiện bằng một dấu chấm ., và tất nhiên chúng được ẩn bởi Sao Diêm Vương.

Một điều nữa: Hội đồng NASA đã đi đến kết luận rằng việc khám phá sự sống trên Sao Diêm Vương có thể sẽ dẫn đến việc tăng ngân sách đáng kể. Chương trình của bạn sau đó sẽ thêm manh mối của cuộc sống trên Sao Diêm Vương:

  • Khi khoảng cách đến Sao Diêm Vương là <= 4, hãy thêm một plutonia tại tọa độ (-3,-1):(^_^)

Ảnh ví dụ cho đầu vào 20151215: (Mã của bạn phải có tất cả các dòng mới như mã này)

               

    .          


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



  .            

Ảnh cho đầu vào 20151225:

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

Để so sánh, đây là một bức ảnh về vệ tinh Hydra của Sao Diêm Vương được chụp bởi New Horizons. Sự khác biệt hầu như không đáng chú ý với nghệ thuật ASCII của chúng tôi.

nhập mô tả hình ảnh ở đây

Đây là mã golf, vì vậy mã ngắn nhất tính bằng byte sẽ thắng!


1
Đây sẽ là một thử thách hoàn hảo cho ngôn ngữ vẽ nghệ thuật ASCII mà tôi đang làm việc. Có lẽ tôi sẽ đăng một câu trả lời với nó sau khi nó kết thúc. :)
Sản phẩm điện tử

1
@SuperChafouin Tôi đã xóa `s ủng hộ <pre><code>; cứ thoải mái quay lại nếu bạn không thích nó.
Justin

1
You can assume the entered date will be in the year 2015 or 2016.Nhưng sau đó tại sao chỉ định một năm ở tất cả?
mınxomaτ

Tôi có thể lấy ngày ở dạng 2015/12/25 không?
intrepidcoder

Câu trả lời:


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

Bản demo trực tiếp . Chạy trong Firefox.

Phiên bản gốc

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

Chơi gôn

Đây là niềm vui để chơi gôn.

Tôi không cần tạo đối tượng Date, vì vậy tôi đã mã hóa giá trị tính bằng mili giây để lưu 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

Thay thế mảng kết hợp bằng một chuỗi phân tách để loại bỏ 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

Bộ tái cấu trúc lớn nhất đã thay thế các vòng lặp cho các IIFE được lồng, đệ quy để loại bỏ 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

Tôi cũng đã loại bỏ Math.sqrtthêm 8 byte.

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

Các vấn đề

Tôi chỉ có thể có được bức ảnh chính xác cho các trường hợp thử nghiệm bằng cách thay đổi ngày gần nhất thành 2015/12/24 và tôi không biết vấn đề nằm ở mã của tôi hay câu hỏi. Hãy làm rõ và tôi sẽ cập nhật câu trả lời của tôi.

Đây là đầu ra của tôi bằng cách sử dụng sự khác biệt từ 2015/12/25.

Chỉnh sửa: Cập nhật câu trả lời để sử dụng Giáng sinh là ngày gần nhất.

Ảnh chụp cho "20151215":

                   

        .          


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



      .            
                   

Ảnh chụp cho "20151225":

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

Hai ví dụ của tôi đã sai (có một ca làm việc một ngày), tôi đã sửa chúng trong câu hỏi. Cảm ơn đã chỉ ra rằng!
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;}

Thí dụ:

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

Đầu ra:

20151216


    .


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



  .

20151224

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

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

Phần đầu tiên tính toán sự khác biệt trong ngày và lưu trữ nó trong Dbiến. Phần còn lại là một vòng lặp kép lặp qua XY.

Kiểm tra nó ở đây

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.