Fałszywa prognoza

15

Przybył nowy superkomputer prognozujący pogodę i nie działa.

W międzyczasie twój szef chce, abyś kupił technikom jakiś czas, fałszując codzienne mapy wiatru.

Twoim zadaniem jest narysowanie siatki strzałek przedstawiających kierunek wiatru.

Siatka jest:

  • składa się z kwadratowych płytek 15px
  • 8 płytek po 8 płytek
  • Łącznie 120 pikseli kwadratowych
  • 000 tła

Każda płytka siatki ma 8 potencjalnych orientacji, reprezentujących kierunek wiatru:

  1. Północ
  2. Północny wschód
  3. Wschód
  4. Południowy wschód
  5. południe
  6. Południowy zachód
  7. Zachód
  8. Północny zachód

Co należy przedstawić w następujący sposób:

N N. NE NE E mi SE SE S S. SW południowy zachód W W. NWpółnocny zachód

Mapy muszą się zmieniać stopniowo , aby były wiarygodne.

Oznacza to, że każda płytka może różnić się od sąsiada tylko o jeden krok. Konkretnie:

  • Płytka może różnić się tylko o jeden przyrost lub spadek od każdej z 4 sąsiadujących płytek. (lub 3 dla płytek bocznych, 2 dla płytek narożnych).
  • np. kafelek z sąsiadem E może być NE, E lub SE (zakładając, że jest zgodny z innymi sąsiadami).
  • Orientacje mogą zawracać, tzn. N -> NW i NW -> N.

Aby to zilustrować, obowiązuje następująca mapa:

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 

Mapy muszą być unikalne , nie generuj tej samej mapy dla różnych danych wejściowych.

  • Dane wejściowe są liczbami całkowitymi odpowiadającymi dniom między teraz a twoją prognozą (np. 1 to prognoza jutra, 365 to rok).
  • Dane wyjściowe to mapa jako obraz.
  • Wyjście powinno być odtwarzalne, to samo wejście zawsze daje takie samo wyjście
  • Musisz dawać unikalne mapy przez co najmniej 8 lat - tzn. Brak identycznych danych wyjściowych dla danych wejściowych od 1 do 2920 (ignoruję lata przestępne).
  • Nie ma zdefiniowanej wydajności dla żadnego wejścia większego niż 2920.

Zwycięskie zgłoszenie wygeneruje prawidłowe mapy (do 2920 dnia) z najmniejszą liczbą bajtów kodu źródłowego.

jsh
źródło
Jaka jest maksymalna ilość wejściowa, którą należy obsłużyć? Czy są jakieś ograniczenia, np. Prognozy dwóch kolejnych sposobów, które muszą się różnić tylko o maksymalną kwotę?
Ingo Bürk
Maksymalna ilość danych wejściowych, które należy obsłużyć, to 2920 .
Kolejne
Przepraszam, musiałem przeoczyć ostatni punkt kuli. :)
Ingo Bürk
8
Nieco temat: Pokazałem to znajomemu, który jest prognostą pogody, i powiedział mi, że niektóre z tych aplikacji pogodowych, które można uzyskać, nie są dużo lepsze niż to, co tutaj robimy, ponieważ najwyraźniej po prostu pobierają bezpłatne dane pogodowe z duże lotniska i interpoluj je, najczęściej te interpolacje są do bani.
flawr
2
„Przybył nowy superkomputer prognozujący pogodę i nie działa”. Prześlij go do International Journal of Climate Science. Będzie równa kursowi. : P
COTO

Odpowiedzi:

4

BBC Basic, 83 znaki ASCII, tokenizowany rozmiar pliku 72

Pobierz emulator na 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

Jest to w zasadzie część koncepcji Martina, ale implementacja w BBC basic jest zupełnie inna. Przeprogramowuję czcionkę dla liczb0 a 1następnie wypisuję cyfry binarne nw odwrotnej kolejności.

Nieskluczony kod znajduje się poniżej. W BBC basic możesz drukować pojedyncze znaki ASCII za pomocąVDU polecenia, ale język ma szereg kodów specyficznych dla maszyny, podobnych do sekwencji specjalnych, ale rozpoczynających się od znaków niedrukowalnych. Aby przeprogramować czcionkę, zaczynamy od ASCII 23. Zwykle pobierane są wartości 8-bitowe, ale jeśli użyjesz średnika jako separatora zamiast przecinka, zajmie to 16-bitowe małe wartości endian (tak jak w wersji golfowej).

  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.

Wynik

Dla liczb od 0 do 7. Zauważ, że czcionka nie jest resetowana na końcu programu, dlatego cyfry 0 i 1 pojawiają się jako strzałki w pierwszych dwóch przykładach. wprowadź opis zdjęcia tutaj

Level River St
źródło
Dobry pomysł! :) Ale czy płytki 15x15?
Martin Ender
@ MartinBüttner BBC basic pozwala przedefiniować czcionkę na siatce 8x8. Aby zachować małe liczby, zrobiłem najmniejszą rozpoznawalną strzałkę wschodnią (5x5 wciśniętą w prawy górny róg siatki) i zrobiłem najbardziej podobną strzałkę na północny wschód. W zastosowanym tutaj trybie ekranowym definicja ma zgodność 1: 1 z pikselami (i pozostawia spore odstępy między wierszami), ale podwoiłem rozmiar siatki w Windows Paint, aby uzyskać lepszy rozmiar obrazu na SE. Niektóre inne tryby ekranu w BBC basic mają więcej niż 1 piksel na element siatki, a znaki zdefiniowane przez użytkownika są wyraźnie bardziej ziarniste niż zwykła czcionka.
Level River St
23

Matlab (182 *)

Zakłada się, że dane wejściowe są przechowywane w n. Patrząc na algorytm, nie jest pewne, czy wyniki będą unikalne, ale sprawdziłemn=1 upto 3000 , czy są one unikalne i spełniają reguły. Zasadniczo używam po prostu liczb zespolonych okręgu jednostkowego i „wygładzam” je przez conv2 za pomocą filtra gaussowskiego. Następnie zostają zaokrąglone w 8 możliwych kierunkach.

* Nie wiem jak skalować wyjście do określonej liczby pikseli, więc trzeba to zrobić ręcznie = /

EDYCJA: Właśnie odkryłem, że są przypadki, w których mój program sprawdzający nie rozpoznał niewłaściwych rozwiązań (zmiany o więcej niż 1 krok), ale próbuję znaleźć inne rozwiązanie.

Wejście:

n = 1

Kod:

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

pole wektorowe

wada
źródło
Co rozumiesz przez „skalowanie wyjścia do określonej liczby pikseli”, skalowanie strzałek lub obrazu?
krs013,
@ krs013 Mam na myśli skalowanie całego obrazu, nie dowiedziałem się jeszcze, jak to zrobić, aby miał np. szerokość dokładnie 8 * 16 pikseli.
flawr
15

Mathematica, 116 115 bajtów

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]

Przypuszczam, że dobry koń nigdy nie skacze wyżej niż musi. 2920 różnych siatek można bardzo łatwo osiągnąć przy użyciu tylko dwóch kierunków (używamN i NE), co sprawia, że ​​spełnienie zasady ciągłości jest banalne. Po prostu wybieram pomiędzy N i NE na podstawie bitów n, więc w rzeczywistości da to 2 64 różnych map wiatru.

Oto pierwsze dziesięć map:

wprowadź opis zdjęcia tutaj

PS: Moim oryginalnym pomysłem było wyliczenie wszystkich 8 4 kombinacji dla 4 rogów i interpolacja „liniowa” reszty siatki. Prawdopodobnie spowodowałoby to ładniejsze mapy, ale w końcu to jest golf golfowy, więc poszedłem z tym, co spełnia minimalne wymagania.

Martin Ender
źródło
Powinienem poprosić o 2 ^ 64 + 1 siatki. :)
jsh
@ jsh Mam 8 opcji dla dwóch sąsiednich kierunków. Sprawiłoby to, że kod byłby nieco dłuższy, ale nadal byłby podobnie łatwy i pozwoliłby na 2 ^ 67 unikatowych siatek. Ale nie martw się, myślę, że to wciąż fajny golf golfowy - robienie golfa z grafiką jest trudne (z powodu wymaganej obiektywności) i myślę, że wykonałeś z nim całkiem dobrą robotę.
Martin Ender
Podoba mi się pomysł interpolacji, ale jak interpolowałbyś, gdy każdy z czterech rogów wskazywałby na środek?
flawr
4
@ MartinBüttner: Chociaż technicznie odpowiada to specyfikacji, wydaje się być sprzeczne z duchem wyzwania, jakim jest uczynienie mapy wiarygodną. Tylko obserwacja.
COTO
2
@ COTO Bardzo prawda, ale to także golf golf, a nie konkurs popularności, a „wiarygodność” nie jest obiektywnym kryterium ważności.
Martin Ender
5

PHP 5.4, 549 bajtów

Nieco utrudniony przez konieczność definiowania strzałek jako grafiki, oto mój kod PHP:

<? $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);

Pobiera argument z wiersza poleceń, na przykład:

php windmap.php 123

To rozwiązanie wykorzysta dane wejściowe jako definicję czterech rogów. Reszta mapy będzie płynnie interpolowana między wartościami. Zdefiniował wyniki dla wszystkich wartości od 0 do 4095, co stanowi w sumie ~ 11,25 lat fałszywej prognozy, co powinno wystarczyć na naprawę oprogramowania pogodowego!

Oto GIF wszystkich wyników:

Gorące powietrze!

A plik ZIP zawierający każdą mapę można pobrać tutaj

(Mała uwaga: Moja domena niedawno wygasła, ponieważ nie zwracałem na to uwagi. Odnowiłem ją, ale powyższy obraz i link mogą nie działać do czasu aktualizacji DNS)

Nieskwalifikowany:

<?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");
Niet the Dark Absol
źródło
Jak działa interpolacja?
flawr
@flawr Przyjmuje przybliżoną odległość do każdego narożnika i używa go jako wagi dla tego, jak bardzo wartość tego narożnika powinna wpłynąć na wartość bieżącego punktu.
Niet the Dark Absol
Ale czy w tym przypadku każda strzałka powinna wskazywać środek w ramce 1647? tinyurl.com/o7z9grl
flawr
1
@flawr Spójrz w dół do lewej kolumny, aby zobaczyć, jak „interpoluje” od 7 (SE) do 1 (NE), przechodząc przez wszystkie wartości 6, 5, 4, 3, 2 ... w przeciwieństwie do krótszej „7, 0, 1 ”, którego możesz się spodziewać. Algorytm nie jest wystarczająco zaawansowany, aby interpolować z taką rotacją.
Niet the Dark Absol
Ach, tak to rozwiązałeś! To naprawdę miłe, ponieważ interpolacja z „7,0,1” spowodowałaby nieprawidłowe pole strzałki =) +1 dla grafiki strzałki!
flawr