Giả mạo dự báo


15

Thời tiết mới dự báo siêu máy tính đã đến, và nó không hoạt động.

Trong khi đó, ông chủ của bạn muốn bạn mua các kỹ thuật viên một thời gian bằng cách làm giả các bản đồ gió hàng ngày.

Nhiệm vụ của bạn là vẽ một lưới các mũi tên đại diện cho hướng gió.

Lưới là:

  • tạo thành gạch vuông 15px
  • 8 gạch bằng 8 gạch
  • Tổng diện tích 120px
  • 000 nền

Mỗi ô lưới có 8 hướng tiềm năng, đại diện cho hướng gió:

  1. Bắc
  2. Đông bắc
  3. phía đông
  4. Đông Nam
  5. miền Nam
  6. Tây nam
  7. hướng Tây
  8. Tây Bắc

Mà phải được mô tả như sau:

N N NE ĐB E E SE SE S S SW SW W W Tây BắcTây Bắc

Các bản đồ phải thay đổi dần dần , để có thể tin được.

Điều này có nghĩa là mỗi ô chỉ có thể khác với hàng xóm của nó một bước. Đặc biệt:

  • Một lát chỉ có thể khác nhau bởi một mức tăng hoặc giảm từ mỗi trong số 4 gạch liền kề. (hoặc 3 cho gạch bên, 2 cho gạch góc).
  • ví dụ: một ô có hàng xóm E có thể là NE, E hoặc SE (giả sử nó phù hợp với các hàng xóm khác).
  • Các định hướng có thể lặp lại xung quanh, tức là N -> NW và NW -> N

Để minh họa, bản đồ sau là hợp lệ:

NW  N NE NE NE NE NE NE 
 N NE NE NE NE NE NE  E 
NE NE NE NE NE NE  E SE 
 E NE NE NE NE  E SE  S 
SE  E  E  E  E SE  S SE 
 S SE SE SE SE  S SE  E 
SW  S  S  S  S SE  E NE 
SW SW  S  S SE  E NE  N 

Bản đồ phải là duy nhất , không tạo cùng một bản đồ cho các đầu vào khác nhau.

  • Đầu vào là một số nguyên tương ứng với các ngày giữa bây giờ và dự báo của bạn (ví dụ 1 là dự báo của ngày mai, 365 là thời gian của một năm).
  • Đầu ra là bản đồ như một hình ảnh.
  • Đầu ra phải được tái sản xuất, cùng một đầu vào sẽ luôn cho cùng một đầu ra
  • Bạn phải cung cấp bản đồ duy nhất trong ít nhất 8 năm - tức là không có đầu ra giống hệt nhau cho bất kỳ đầu vào nào trong khoảng từ 1 đến 2920 (Tôi bỏ qua các năm nhuận).
  • Không có đầu ra được xác định cho bất kỳ đầu vào nào lớn hơn 2920.

Việc gửi chiến thắng sẽ tạo ra các bản đồ hợp lệ (tính đến ngày 2920) với ít byte mã nguồn nhất.


Đầu vào tối đa cần được xử lý là gì? Có bất kỳ hạn chế nào, ví dụ, dự báo về hai cách liên tiếp phải chỉ khác nhau một lượng tối đa không?
Ingo Bürk

Đầu vào tối đa cần xử lý là 2920 . Không có giới hạn về các dự báo liên tiếp (ngoại trừ chúng phải là duy nhất)
jsh

Ồ, xin lỗi, tôi phải bỏ qua điểm đạn cuối cùng. :)
Ingo Bürk

8
Hơi lạc đề: Chỉ trình bày điều này với một người bạn là người dự báo thời tiết và anh ta nói với tôi rằng một số ứng dụng thời tiết mà bạn có thể nhận được không tốt hơn nhiều so với những gì chúng tôi đang làm ở đây, vì họ dường như chỉ lấy dữ liệu thời tiết miễn phí từ các sân bay lớn và nội suy chúng, thường xuyên hơn không phải là những nội suy chỉ hút.
flawr

2
"Siêu máy tính dự báo thời tiết mới đã đến, và nó không hoạt động." Gửi nó đến Tạp chí Khoa học Khí hậu Quốc tế. Nó sẽ ngang bằng với khóa học. : P
COTO

Câu trả lời:


4

BBC Basic, 83 ký tự ASCII, mã hóa token hóa 72

Tải xuống trình giả lập tại http://www.bbcbasic.co.uk/bbcwin/bbcwin.html

  INPUTn:VDU23,48,516;543;4;0;23,49,783;5,9;0;0:WIDTH8FORi=1TO64PRINT;1ANDn;:n/=2NEXT

Đây về cơ bản là một cảng của khái niệm Martin, nhưng việc triển khai trong BBC cơ bản là rất khác nhau. Tôi lập trình lại phông chữ cho các số 01sau đó xuất các chữ số nhị phân ntheo thứ tự ngược lại.

Mã Ungolfed là dưới đây. Trong BBC cơ bản, bạn có thể in các ký tự ASCII riêng lẻ bằng cách sử dụng VDUlệnh, nhưng ngôn ngữ có một loạt các mã dành riêng cho máy tương tự như các chuỗi thoát nhưng bắt đầu bằng các ký tự không thể in được. Để lập trình lại phông chữ, chúng tôi bắt đầu với ASCII 23. Thông thường các giá trị 8 bit được lấy, nhưng nếu bạn sử dụng dấu chấm phẩy làm dấu phân cách thay vì dấu phẩy, sẽ mất các giá trị endian nhỏ 16 bit (như được sử dụng trong phiên bản được đánh gôn).

  INPUTn
  VDU23,48,4,2,31,2,4,0,0,0         :REM redefine font for "0" as an east facing arrow, with an 8x8 bitmap
  VDU23,49,15,3,5,9,0,0,0,0         :REM redefine font for "1" as a northeast facing arrow, with an 8x8 bitmap
  WIDTH8                            :REM set print width to 8 characters
  FORi=1TO64PRINT;1ANDn;:n/=2:NEXT  :REM print the binary digits of n in reverse order from least significant to most significant.

Đầu ra

Đối với các số từ 0 đến 7. Lưu ý rằng phông chữ không được đặt lại ở cuối chương trình, do đó các số 0 và 1 xuất hiện dưới dạng mũi tên trong hai ví dụ đầu tiên. nhập mô tả hình ảnh ở đây


Ý kiến ​​hay! :) Nhưng gạch 15x15?
Martin Ender

@ MartinBüttner BBC cơ bản cho phép bạn xác định lại một phông chữ trên lưới 8x8. Để giữ số nhỏ, tôi đã làm mũi tên phía đông nhỏ nhất có thể nhận biết được (5x5 vắt vào góc trên cùng bên phải của lưới) và tạo ra mũi tên hướng đông bắc trông giống nhất. Trong mã màn hình được sử dụng ở đây, định nghĩa có tỷ lệ tương ứng 1: 1 với pixel (và để lại một khoảng cách rộng giữa các hàng) nhưng tôi đã nhân đôi kích thước lưới trong Windows Paint để có được hình ảnh kích thước tốt hơn trên SE. Một số chế độ màn hình khác trong BBC cơ bản có nhiều hơn 1 pixel cho mỗi thành phần lưới và các ký tự do người dùng xác định rõ ràng hơn nhiều so với phông chữ thông thường.
Cấp sông St

23

Matlab (182 *)

Nó được giả định rằng đầu vào được lưu trữ trong n. Nhìn vào thuật toán, không chắc rằng kết quả sẽ là duy nhất, nhưng tôi đã kiểm tra n=1 upto 3000xem chúng có phải là duy nhất và đáp ứng các quy tắc hay không. Về cơ bản, tôi chỉ sử dụng các số phức của vòng tròn đơn vị và 'làm mịn' chúng bằng cách kết hợp với bộ lọc gaussian. Sau đó, họ được 'làm tròn' đến 8 hướng có thể.

* Tôi không biết làm cách nào để chia tỷ lệ đầu ra thành một số pixel nhất định, do đó phải thực hiện thủ công = /

EDIT: Tôi mới phát hiện ra rằng có những trường hợp chương trình kiểm tra của tôi không nhận ra giải pháp sai (thay đổi hơn 1 bước), nhưng tôi đang cố gắng tìm giải pháp khác.

Đầu vào:

n = 1

Mã số:

rand('seed',0);
for x=1:n
    b = exp(1i*rand(8)*2*pi);
end
for k=1:12
    b = conv2(b,[1,2,1]'*[1,2,1],'same');b=b./abs(b);
end
c = exp(1i*round(angle(b)*4/pi)*pi/4)/3;
quiver(real(c),imag(c));

Trường vector


Bạn có ý nghĩa gì khi "chia tỷ lệ đầu ra thành một số pixel nhất định", chia tỷ lệ các mũi tên hoặc hình ảnh?
krs013

@ krs013 Ý tôi là nhân rộng toàn bộ hình ảnh, tôi chưa tìm ra cách làm sao cho nó có chiều rộng chính xác là 8 * 16 pixel.
flawr

15

Toán học, 116 115 byte

f@n_:=Graphics[Array[(d=n~BitGet~#;Arrow@{1+{w=15#~Mod~8+6.5d,h=15Floor[#/8]},14+{w-13d,h}})&,64,0],ImageSize->120]

Tôi cho rằng một con ngựa tốt không bao giờ nhảy cao hơn nó phải. 2920 lưới khác nhau rất dễ dàng đạt được khi chỉ sử dụng hai hướng (tôi đang sử dụng NNE), điều này làm cho việc thỏa mãn quy tắc liên tục trở nên tầm thường. Tôi chỉ đơn giản là chọn giữa N và NE dựa trên các bit của n, vì vậy điều này thực sự sẽ tạo ra 2 64 bản đồ gió khác nhau.

Dưới đây là mười bản đồ đầu tiên:

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

PS: Ý tưởng ban đầu của tôi là liệt kê tất cả 8 4 kết hợp cho 4 góc và nội suy "tuyến tính" phần còn lại của lưới. Điều đó có thể đã dẫn đến các bản đồ đẹp hơn, nhưng đây là mã golf, vì vậy tôi đã đi với những gì đáp ứng các yêu cầu tối thiểu.


Tôi nên yêu cầu lưới 2 ^ 64 + 1. :)
2014

@jsh Tôi có 8 lựa chọn cho hai hướng liền kề. Nó sẽ làm cho mã dài hơn một chút, nhưng nó vẫn dễ dàng tương tự và sẽ cho phép 2 ^ 67 lưới duy nhất. Nhưng đừng lo lắng, tôi nghĩ rằng nó vẫn là một môn đánh gôn tốt - chơi golf đầu ra đồ họa rất khó (do tính khách quan bắt buộc) và tôi nghĩ bạn đã làm rất tốt với nó.
Martin Ender

Tôi thích ý tưởng của phép nội suy, nhưng làm thế nào bạn có thể nội suy khi mỗi bốn góc sẽ chỉ vào trung tâm?
flawr

4
@ MartinBüttner: Mặc dù về mặt kỹ thuật này đáp ứng được thông số kỹ thuật, nó dường như trái với tinh thần của thách thức, đó là làm cho bản đồ trở nên đáng tin. Chỉ là một quan sát.
COTO

2
@COTO Rất đúng, nhưng nó cũng là mã golf và không phải là một cuộc thi phổ biến, và "độ tin cậy" không phải là một tiêu chí hợp lệ khách quan.
Martin Ender

5

PHP 5,4, 549 byte

Hơi bị cản trở bởi nhu cầu xác định mũi tên là đồ họa, đây là mã PHP của tôi:

<? $i=$argv[1];$p="R0lGODdhBQAFAIAAAP///wAAACwAAAAABQAFAAAC";$a=[$p."BwRiicGsDwoAOw",$p."CEQeoLfmlhQoADs",$p."CARiF8hnmGABADs",$p."CIwDBouYvGIoADs",$p."BwRil8Gs+QoAOw",$p."CIQRYcqrnkABADs",$p."CARihscYn1YBADs",$p."CAx+Bmq6HWIBADs"];$c=[$i&7,$i>>3&7,$i>>6&7,$i>>9];$m=imagecreate(120,120);imagecolorallocate($m,255,255,255);foreach($a as$_)$z[]=imagecreatefromstring(base64_decode($_));for($y=0;$y<8;$y++)for($x=0;$x<8;$x++)imagecopy($m,$z[($c[0]*(7-$x)*(7-$y)+$c[1]*$x*(7-$y)+$c[2]*(7-$x)*$y+$c[3]*$x*$y)/49%8],$x*15+5,$y*15+5,0,0,5,5);imagepng($m);

Lấy đối số của nó từ dòng lệnh, chẳng hạn như:

php windmap.php 123

Giải pháp này sẽ sử dụng đầu vào như định nghĩa của bốn góc. Phần còn lại của bản đồ sẽ được nội suy trơn tru giữa các giá trị. Nó đã xác định kết quả cho tất cả các giá trị từ 0 đến 4095, tổng cộng ~ 11,25 năm dự báo giả, cần quá nhiều thời gian để sửa phần mềm thời tiết!

Đây là một GIF của tất cả các kết quả:

Hơi nóng!

Và một ZIP chứa mỗi bản đồ có thể được tải xuống ở đây

(Lưu ý nhỏ: Tên miền của tôi gần đây đã hết hạn vì tôi không chú ý. Tôi đã gia hạn nó, nhưng hình ảnh và liên kết ở trên có thể không hoạt động cho đến khi cập nhật DNS)

Không đủ điều kiện:

<?php
$input = $argv[1];
$prefix = "R0lGODdhBQAFAIAAAP///wAAACwAAAAABQAFAAAC";
$arrows = [
    $prefix."BwRiicGsDwoAOw", // E
    $prefix."CEQeoLfmlhQoADs", // NE
    $prefix."CARiF8hnmGABADs", // N
    $prefix."CIwDBouYvGIoADs", // NW
    $prefix."BwRil8Gs+QoAOw", // W
    $prefix."CIQRYcqrnkABADs", // SW
    $prefix."CARihscYn1YBADs", // S
    $prefix."CAx+Bmq6HWIBADs", // SE
];
$points = [
    $input & 7,
    $input >> 3 & 7,
    $input >> 6 & 7,
    $input >> 9 // input beyond 0o7777 (4095) will be undefined due to lack of & 7 here
];
$img = imagecreate(120,120);
imagecolorallocate($img,255,255,255);
$arrowimgs = [];
foreach($arrows as $src) {
    $arrowimgs[] = imagecreatefromstring(base64_decode($src));
}
for($y=0; $y<8; $y++) {
    for($x=0; $x<8; $x++) {
        $point = (
              $points[0] * (7-$x)/7 * (7-$y)/7
            + $points[1] *   $x  /7 * (7-$y)/7
            + $points[2] * (7-$x)/7 *   $y  /7
            + $points[3] *   $x  /7 *   $y  /7
        ) % 8;
        imagecopy($img,$arrowimgs[$point],$x*15+5,$y*15+5,0,0,5,5);
    }
}
imagepng($img,"out.png");

Làm thế nào để nội suy hoạt động?
flawr

@flawr Phải lấy xấp xỉ khoảng cách đến từng góc và sử dụng trọng số đó làm trọng số cho giá trị của góc đó sẽ ảnh hưởng đến giá trị của điểm hiện tại.
Niet the Dark Tuyệt đối

Nhưng trong trường hợp này, mỗi mũi tên nên chỉ vào giữa trong khung 1647? tinyurl.com/o7z9grl
flawr

1
@flawr Nhìn xuống cột ngoài cùng bên trái để xem cách "nội suy" từ 7 (SE) đến 1 (NE) bằng cách đi qua tất cả các giá trị 6, 5, 4, 3, 2 ... trái ngược với "7, ngắn hơn" 0, 1 "mà bạn có thể mong đợi. Thuật toán không đủ tinh vi để nội suy với phép quay như thế.
Niet the Dark Tuyệt đối

Ah đó là cách bạn giải quyết nó! Điều này thực sự rất hay, vì việc xen kẽ với '7,0,1' sẽ dẫn đến trường mũi tên không hợp lệ =) +1 cho đồ họa mũi tên!
flawr
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.