Shubbles and Smoles - Część I

10

Ustawić

Rozważ dziwnie ukształtowane pudełko zawierające 29 ponumerowanych komórek, jak pokazano na ryc. 1 poniżej.

szczypce i smole

Wewnątrz tego pudełka 2D znajdują się dwa gatunki zwierząt w kształcie kwadratu: szubienice i smole. Ryc. 1 (a) pokazuje niektóre strzępki na niebiesko, a niektóre smole na czerwono. Każde stworzenie zajmuje dokładnie jedną komórkę siatki. Pudełko może zawierać od 0 do 26 shubble, ale zawsze będzie zawierało dokładnie dwa smole.

Pod wpływem siły grawitacji shubble i smole siedzą na dnie pudełka, układając się na wierzchu wszystkiego pod nimi. Oba gatunki są wyjątkowo leniwe i pozostają wiecznie nieruchome.

W pudełku znajduje się również stot, przedstawiony jako czarny kwadrat, który zajmuje dokładnie jedną komórkę siatki. Kieł nie podlega grawitacji.

Pudełko ma jeden otwór umieszczony na dole komórki 28, jak pokazano na rysunku.

Aby tekstowo przedstawić konfigurację shubble, smoles i stot w polu, używamy 29-znakowego łańcucha, po jednym znaku na komórkę siatki, w wyliczonej kolejności, z .reprezentowaniem pustej komórki, oreprezentującej shubble, xreprezentującą smole , i @reprezentujący stot. Na przykład konfiguracja z rys. 1 (a) jest reprezentowana przez ciąg znaków [email protected]....

Manipulacje

Skrzynkę można obrócić o dowolną wielokrotność 90 °. Podczas obracania pudełka shubble i smole pozostają nieruchome w obrębie komórek siatki. Po zakończeniu obrotu spadają bezpośrednio w dół, aż albo i ) zostaną zablokowane przez ścianę poniżej, ii ) zostaną zablokowane przez szew, smole lub stot poniżej, lub iii ) wpadną przez otwór w komórce 28 i wyjdź z pudełka. Stot nie spada; pozostaje ustalony w bieżącej komórce, nawet jeśli stworzenia spoczywają na nim.

Skrzyni nie można obrócić ponownie, dopóki stworzenia nie upadną i nie osiągną nowej stabilnej konfiguracji.

Tekstowo, obroty skrzynek są oznaczone jako +dla obrotu o 90 ° zgodnie z ruchem wskazówek zegara, |dla obrotu 180 ° i -dla obrotu 90 ° przeciwnie do ruchu wskazówek zegara.

Dodatkowo, stot można przesuwać w czterech kierunkach kompasu w przyrostach jednej komórki siatki. Ruch nie może: i ) spowodować kolizji między kikutem a stworzeniem (tj. Docelowa komórka siatki musi być pusta), ii ) spowodować kolizję między kikutem a ścianą ani iii ) spowodować, aby kikut wyszedł z pudełka przez dziura w komórce 28.

Stot nie może się również poruszać, jeśli na nim spoczywają stworzenia (w odniesieniu do aktualnej grawitacji).

Tekstowo ruchy stot są oznaczane przez <dla lewej, >dla prawej, ^dla góry i vdla dołu. Ruchy Stot są zawsze określane w odniesieniu do „standardowej” (nieobróconej) ramy przedstawionej na rysunkach. To znaczy, jeśli kikut znajduje się w komórce 10, ruch ^zawsze przenosi go do komórki 5, a ruch >zawsze przenosi go do komórki 11. Orientacja pudełka nie wpływa na kierunek ruchu.

Sekwencje manipulacji są kodowane przy użyciu ciągów znaków od lewej do prawej. Na przykład sznurek +<<^-wskazuje, że pudełko jest obrócone o 90 ° w kierunku zgodnym z ruchem wskazówek zegara, następnie stot przesuwa się dwukrotnie w lewo i raz w górę (w stosunku do standardowej ramy), a następnie pudełko jest obracane o 90 ° w kierunku przeciwnym do ruchu wskazówek zegara z powrotem do pierwotnej orientacji.

Wyzwanie

Z absolutnie dobrych powodów (których nie mogę ujawnić), chcemy wyodrębnić wszystkie shubble z pudełka bez wydobywania jednego smole. Aby to osiągnąć, możemy użyć manipulacji opisanych powyżej.

Przed rozwiązaniem tego problemu należy symulować wpływ różnych manipulacji na zawartość pudełka, na którym skupia się to wyzwanie.

Musisz napisać program, który akceptuje dwa argumenty z stdin(lub równoważne):

  • ciąg opisujący początkowy stan skrzynki
  • sekwencja manipulacji

Możesz założyć, że oba argumenty są poprawne pod względem składniowym, że pudełko zaczyna się w standardowej orientacji, a początkowy stan pudełka jest stabilny i legalny.

Program musi generować dane wyjściowe stdout(lub równoważne):

  • ( przypadek 1 ) końcowy stan skrzynki, wyrażony jako ciąg znaków, jeśli sekwencja ruchów jest legalna (nie narusza zasad ruchu stot) i nie powoduje wychodzenia żadnych smolów z pudełka. Ostateczna orientacja pudełka nie jest ważna.

  • ( przypadek 2 ) pojedynczy wykrzyknik !, jeśli sekwencja ruchów jest nielegalna lub powoduje opuszczenie skrzynki przez smole

Punktacja

Zwycięski program jest najkrótszym programem pod względem liczby bajtów , z zastrzeżeniem bardzo lukratywnych mnożników premii:

  • twierdzić, że mnożnik wynosi 0,65, jeśli zamiast wydrukować zakodowane wyjście dla przypadku 1, program wyprowadza obraz ASCII ramki w jej ostatecznym stanie i orientacji, używając znaków spec dla shubble, smoles, stots i pustych komórek i umieszczając *w komórce tuż za otworem w komórce 28. Wiodące i końcowe białe znaki są ignorowane.

    Na przykład, jeśli ryc. 1 (a) zostanie obrócony o 90 °, moc wyjściowa wyniesie

       .  .
      .....
      .o...
      xo.@.
     *ooo..
      x  .
    
  • twierdzą, że mnożnik wynosi 0,22, jeśli zamiast drukowania zakodowanego wyjścia dla przypadku 1, program wysyła plik obrazu lub wyświetla okno GUI z obrazem pudełka w jego ostatecznym stanie i orientacji. Zdjęcie powinno być w stylu pokazanym na ryc. 1 (a), pokazując komórki siatki, ściany i stworzenia / stoty za pomocą kolorowych pól.

  • twierdzą, że mnożnik wynosi 0,15, jeśli zamiast drukowania zakodowanego wyjścia dla przypadku 1, program wyświetla animowane okno .gif lub animowane okno GUI pokazujące wszystkie stany pośrednie w symulacji w odstępach 1 sek. Obowiązują te same zasady, jak w przypadku mnożnika 0,22. Pierwsza klatka animacji powinna przedstawiać stan początkowy symulacji. Dodatkowo animacja powinna pokazywać „ukryte” stany pośrednie

    • shubble / smoles spada do stabilnej konfiguracji o jedną komórkę na klatkę animacji po obrocie

    • pośredni obrót skrzynki o 90 ° przy obrocie o 180 °

  • zgłosić mnożnik 0.12, jeśli program tworzy animowane okno .gif lub animowane okno GUI powyższego stylu, ale działa przy 20 fps i pokazuje

    • płynne, ciągłe animacje obracającego się pudełka

    • płynne, ciągłe animacje poruszania się kału i rozpadania się / smolli w stabilną konfigurację

    Pęcherzyki spadające przez otwór w komórce 28 powinny być pokazane wychodzące z pudełka i powinny zniknąć, gdy całkowicie znikną na zewnątrz. Możesz wybrać własny czas animacji, o ile nie zostanie wykonana więcej niż 1 manipulacja / s.

Całkowity wynik to floor( base score * multiplier ). Można domagać się tylko jednego mnożnika.

W końcu to świat smole. ;)

COTO
źródło
2
+1 za specyfikację, ale prawdopodobnie nie wezmę udziału.
John Dvorak
Brzmi fajnie. Dla pewności: kształt pudełka jest całkowicie ustalony, tak? Więc nie musimy uwzględniać żadnych innych kształtów?
Ingo Bürk
@ IngoBürk: poprawnie. Kształt pudełka jest ustalony.
COTO,
Czy w przypadku danych wyjściowych możemy użyć twojego obrazu jako zasobu (lub dowolnego innego zasobu), czy też musimy narysować go całkowicie w kodzie? Jeśli możemy go użyć, jak się liczy? Spróbuję spróbować, ale teraz jestem na wakacjach.
Ingo Bürk
1
Możesz korzystać z zewnętrznych zasobów graficznych (np. Obrazy, znaczniki SVG), o ile podasz ich liczbę bajtów w sumie dla programu. Podstawowy obraz nie musi być strasznie skomplikowany. 12 linii tworzących siatkę; ściana; i kolorowe pudełka wewnątrz pudełka. Jeśli wolisz, kolorowe pole może wypełnić całą komórkę siatki, a ściana może dokładnie prześledzić wzdłuż granicy najbardziej zewnętrznych komórek. W ten sposób cały obraz można zdefiniować poprzez narysowanie prostokątów, linii i polilinii na siatce współrzędnych kwadratowych 6 x 6.
COTO,

Odpowiedzi:

2

MATLAB, jak dotąd nie golfił * 0,15

Byłoby wspaniale, gdyby ktoś zaryzykował domysł, czy to działa dobrze.

n = @()input('', 's');
E = @()fprintf('!');
M = zeros(7,9);
G = M;
I = [9:7:44 17:7:52 18:7:46 12:7:47 20:7:55];
M0 = M;
M0(I) = 1;
M([I 49]) = 1;
G(I) = n()-46;
trot = 0;
Xtr = [0 1-10i 11-7i 8+i];
X0 ='c66++66++oozzoozzn'-i*'YYNNAA--  ++88LLYY'-22+22i;
for a = [97 n()]
    a = find('-|+a^<v>'==a);
    if a<5
        R = @(m) rot90(m, a);
        G = R(G);
        [nr,nc] = size(G);
        M = R(M);
        M0 = R(M0);
        trot = mod(trot+a,4);
        X = exp(i*pi*trot/2)*X0 + 11*Xtr(trot+1);
    else
        z = find(G==18);
        J = z + [-nr,1]*[0,-1;1,0]^(trot+a)*[1;0];
        if ~M0(J) | G(J) | G(z+1)
            E();return
        end
        G(z) = 0;
        G(J) = 18;
    end
    fall = 1; 
    while fall
        clf
        plot(X/11,'k','LineW',3);
        for x = 2:nc; for y = 2:nr
             ch = G(y,x);
             if M0(y,x) 
                 rectangle('Po',[x,-y,1,1],'F',~ch|ch==[74 1 65]);
             end
        end;end
        pause(1);
        G2 = G;
        for r = nr-1:-1:2
            s = G2 > 30;
            f = G2(r,:) .* (s(r,:) & ~s(r+1,:) & M(r+1,:) & G(r+1,:)~=18);
            if r==size(G,1)-1 & any(f==74)
                E();return
            end
            G2(r:r+1,:) = G2(r:r+1,:) + [-f;f];
        end
        G2 = G2 .* M0;
        fall = any(any(G2 ~= G));
        G = G2;
    end 
end

Przykładowy wynik końcowy dla niektórych losowych ruchów:

[email protected]...
+>|<-v+^+

wprowadź opis zdjęcia tutaj

feersum
źródło
1
Czy mógłbyś faktycznie pokazać GIF animacji?
Martin Ender
Fajne! Sprawdzę to wieczorem (i opublikuję kilka przypadków testowych).
COTO
Program nie wymaga wyświetlania animowanego pliku .gif, ale jeśli chcesz go wygenerować, feersum, ten artykuł wyjaśnia, jak to zrobić z łatwością.
COTO