Używając tylko drukowalnego ASCII (kody szesnastkowe od 20 do 7E), napisz kwadratowy program podstawowy N × N bez komentarzy, który jest otoczony przez kolejne 4 warstwy , tworząc kwadratowy program (N + 8) × (N + 8) (N> 0) . Dla N = 3 układ (który ma zostać zastąpiony rzeczywistym kodem) wygląda następująco:
44444444444
43333333334
43222222234
43211111234
4321CCC1234
4321CCC1234
4321CCC1234
43211111234
43222222234
43333333334
44444444444
- C reprezentują podstawowy program 3 × 3.
- Jedynki oznaczają pierwszą warstwę, dwójki oznaczają drugą warstwę itp.
Program zawsze przyjmuje ciąg liczb całkowitych oddzielonych spacjami, na przykład 0 -1 31 -1 2 2 2
przez stdin lub podobny (powinny to być zwykłe liczby, bez cudzysłowów, nawiasów itp.). Wynik zależy od tego, które części układu zostały uruchomione.
Istnieje pięć sposobów uruchamiania programu (nowe wiersze są uwzględniane w biegu). Każdy robi coś innego niż lista:
Uruchom tylko rdzeń:
CCC CCC CCC
Oblicza to maksymalne wartości bezwzględne elementów listy wejściowej i drukuje
CORE
wiele razy w nowym wierszu. Jeśli maksimum wynosi 0, nic nie jest wyprowadzane (nowa linia jest w porządku).Wyjściem
0 -1 31 -1 2 2 2
byłobyCORE CORE ...
31 razy.
Uruchom rdzeń z warstwą 1:
11111 1CCC1 1CCC1 1CCC1 11111
Daje to średnią (średnią arytmetyczną ) wartości listy do standardowej precyzji zmiennoprzecinkowej.
- Wynik
0 -1 31 -1 2 2 2
wyniósłby 35/7 =5
(5.0
jest w porządku).
- Wynik
Uruchom rdzeń z warstwami 1 i 2:
2222222 2111112 21CCC12 21CCC12 21CCC12 2111112 2222222
Powoduje to odwrócenie listy rozdzielonych spacjami listy danych wejściowych.
- Wyjściem
0 -1 31 -1 2 2 2
byłoby2 2 2 -1 31 -1 0
.
- Wyjściem
Uruchom rdzeń z warstwami 1, 2 i 3 (wzór powinien być oczywisty).
W ten sposób powstaje rozdzielona spacjami lista posortowanej listy danych wejściowych.- Wyjściem
0 -1 31 -1 2 2 2
byłoby-1 -1 0 2 2 2 31
.
- Wyjściem
Uruchom rdzeń z warstwami 1, 2, 3 i 4.
Spowoduje to utworzenie rozdzielonej spacjami listy danych wejściowych z usuniętymi duplikatami, kolejność nie ma znaczenia.- Wyjściem dla
0 -1 31 -1 2 2 2
może być-1 0 2 31
.
- Wyjściem dla
Wszystkie dane wyjściowe są w standardowej lub podobnej alternatywie.
Tylko te 5 kombinacji układów ma określone zachowanie.
Notatki
- Komentarze nie są dozwolone w rdzeniu, warstwach ani ich kombinacjach. Kod, który nie działa ani nie robi nic konstruktywnego, nie jest liczony jako komentarz.
- Pamiętaj, że rdzeń może mieć dowolne (dodatnie) wymiary N × N, ale warstwy mają grubość tylko jednego znaku.
- Możesz założyć, że na wejściu nie ma spacji początkowych ani końcowych, a dokładnie jedna spacja między liczbami. Zawsze będzie zawierać co najmniej jedną liczbę. (Listy wyników również powinny być sformatowane w ten sposób.)
- Możesz założyć, że lista i obliczenia niezbędne do otrzymania danych wyjściowych nie będą miały wartości, które przepełniają (lub zaniżają) liczby całkowite (o ile ich maksymalna wartość jest rozsądna, np. 2 16 ).
Punktacja
Pisanie tego programu normalnie byłoby łatwe. Pisanie z małym rdzeniem jest trudne.
Program z najmniejszym rozmiarem rdzenia (najmniejszym N) wygrywa. W przypadku remisów zwycięzcą jest pełny program (kwadrat (N + 8) × (N + 8)) z najmniejszą liczbą wyraźnych znaków (nie licząc nowych linii).
Podaj swoją wartość N na górze swojej odpowiedzi.
źródło
Odpowiedzi:
CJam, N = 5, 27 (26) unikalnych znaków
Ma 26 znaków, jeśli nie liczę spacji. Program można tak naprawdę przekonwertować na taki, który nie używa spacji, po prostu wypełniając wszystkie puste spacje brakiem
_;
operacji (np. Który duplikuje górny element stosu, a następnie odrzuca, lub sortując tablicę raz za razem), ale to oderwałby się od rzeczywistego kodu.Sprawdź to tutaj.
Rdzeń jest
(Plus pusta linia.)
Jestem całkiem pewien, że
N = 4
nie da się tego zrobić w CJam (i jestem pewien, że Dennis mnie przekona inaczej: D). Powyższe ma 17 znaków i chociaż może być możliwe sprowadzenie go do 16 (np. Jeśli CJam nie miał błędu do udławienia się:z
, co wymaga{z}%
lub za pomocą ARGV), nie sądzę, że możesz go dopasować w układzie bez wprowadzania podziału liniiCORE
.Wszystkie wdrożenia są bardzo prostymi rozwiązaniami dla danych zadań. Wszystkie zaczynają się od tego,
l~]
który czyta STDIN, ocenia go i umieszcza w tablicy.Poprzednia warstwa jest zawsze otoczona
{...}
, co sprawia, że jest to blok, który nie jest automatycznie wykonywany. I zamiast go wykonać, po prostu odrzucam go ze stosu;
, więc żadna warstwa nie zależy od kodu z poprzedniej warstwy. W Warstwie 1 kod nie mieścił się w pierwszym wierszu, więc kontynuowałem go po odrzuceniu bloku podstawowego.Teraz rzeczywiste programy:
Rdzeń:
Mapuj
abs
na listę, sortuj, weź ostatni element, powtórzCORE
(i podział linii) tyle razy.Warstwa 1:
Zduplikuj listę, weź długość, zamień elementy stosu, uzyskaj sumę, rzuć na
double
, zamień elementy stosu, podziel. Myślę, że może to być krótsze, ale nie ma na to zachęty.Warstwa 2:
Odwróć tablicę, riff ze spacjami.
Warstwa 3:
Posortuj tablicę, riffle ze spacjami.
Warstwa 4:
Duplikuj, weź zestaw zjednoczenia, riffle ze spacjami.
Możliwe są również inne optymalizacje, takie jak ponowne użycie
;
i*S
warstwy 2, ale znowu, ale to nie wpływa na wynik.źródło
Python 2 - N = 17, 53 znaków
Och, uwielbiam wyzwania związane z układem źródeł w Pythonie ...
Wciąż jednak jest trochę niewykorzystanych białych znaków.
Nadal mógłbym poprawić unikalną liczbę postaci, ale pozostanę przy lepszej czytelności - jeśli w ogóle istnieje.
Edycja: Och, to znowu Stan !
źródło
i=*
sztuczkiprint
nie jest możliwy w Pythonie 2. Ale na pewno jest miejsce na ulepszenia - być może przy użyciu Pythona 3.c*max(n)
Python 3: N = 11, 40 różnych znaków
Dzięki @Falko za bycie moją muzą. Działa to, ponieważ Python nie tworzy nowego zakresu dla każdej instrukcji if, więc zmienne pozostają w instrukcjach zewnętrznych
print
. Jedną irytującą rzeczą było to, żemap
obiekt (w naszym przypadkun
) może być użyty tylko raz. Konieczne było więc wykreślenieR=E(...)
linii, aleR
nie zostało to zdefiniowane. Dlatego miałem szczęście, że w pierwszym wierszu pozostały cztery miejsca!Dane wyjściowe można rozwiązać, udostępniając wiele elementów
*b[::-1]
zamiast listy. Alternatywa' '.join(...)
byłaby zbyt długa.źródło
C (gcc) , N = 15, 47 unikalnych znaków
Zakłada
sizeof(int) == 4
isizeof(int*) >= sizeof(int)
.4 warstwy
3 warstwy
2 warstwy
1 warstwa
Rdzeń
źródło
Runiczne Zaklęcia ,
N = 9N = 8, 38 znakówWypróbuj online!
Okazuje się, że się myliłem , zapomniałem już mieć jawne
o
polecenie s rt, ponieważ wcześniej napotkałem problem z „sortowaniem listy”. Ogranicza to jednak rozmiar danych wejściowych, które może przyjąć program końcowy (8 wartości) z powodu wewnętrznych kosztów polecenia sortowania. Niewielkie ulepszenie może zwiększyć rozmiar wejściowy do 13 kosztem 1 unikalnego znaku lub do 19 dla dwóch unikalnych znaków (wszystkie dodatkowe znaki znajdują się w Warstwie 1 i są dodawane w tym samym czasie, ale zwiększona pojemność stosu IP nie jest potrzebne do Warstwy 3, ponieważ C, L1 i L2 mogą wykonywać swoje obliczenia bez przechowywania całego wejścia w pamięci).Rdzeń: Wypróbuj online!
Warstwa 1: Wypróbuj online!
Warstwa 2: Wypróbuj online!
Warstwa 3: Wypróbuj online!
Warstwa 4: Wypróbuj online!
Dalsza kompresja jest wysoce nieprawdopodobna, ze względu na mniejszą przestrzeń wymagającą zwiększenia liczby znaków kontroli przepływu. Znalazłem układ, który dał 9 pustych miejsc w programie podstawowym, ale to nie wystarczy, ponieważ potrzebujemy (poprawnie ułożonego) 15.
Wyjaśnienie działania któregokolwiek z tych programów jest trudne bez wizualnej mapy ścieżki IP, co jest uciążliwe i czasochłonne w budowie. Początkowym punktem wejścia jest lewy górny róg programu podstawowego (
^
), który pozwala na spójną kontrolę przepływu w miarę dodawania nowych warstw, ponieważ każda warstwa ma możliwość przechwycenia nowo dodanej linii u góry lub u dołu.Warstwy 1 i 2 przechwytują na dole (tak, że górna linia pozostaje pusta dla przyszłych warstw), a następnie wykonują operacje wzdłuż prawej krawędzi (pętla ułożona pionowo). Warstwa 1 jest nieco za długa i zajmuje również 3 znaki wzdłuż górnej krawędzi, ale diagonalny odbłyśnik (
\
) w prawym górnym rogu wyrównuje adres IP z następną iteracją następnej pętli.Warstwa 3 przechwytuje wzdłuż górnej krawędzi w celu pobrania pierwszej wartości wejściowej przed przekierowaniem do dolnej krawędzi (warstwa 4 pozostawia NOP w tej kolumnie w dolnej linii) i odczytuje pełne dane wejściowe za pomocą pętli dolnej krawędzi, przekierowując w dół polecenie (
D
) w lewym dolnym rogu. Stamtąd IP odbija się kilka razy, zanim kończy się w$
pętli output ( ) w lewym dolnym rogu w celu rozdzielenia wartości między spacjami.Warstwa 4 wykorzystuje całą funkcjonalność warstwy 3 (stąd puste miejsce), ale przechwytuje własną nową górną krawędź (lewy górny róg), aby wykonać swoją własną funkcjonalność na końcu przetwarzania warstwy 3. Lewy górny róg wstawia ciąg znaków,
"@"
który służy do oznaczenia końca tablicy przed wejściem do pętli przetwarzania wzdłuż dolnej krawędzi . Jeśli zostanie znaleziona zduplikowana wartość, jest ona wyskakiwana (w~
prawym dolnym rogu), w przeciwnym razie brana jest gałąź, która zużywa nową prawą krawędź. Ta gałąź boczna sprawdza, czy osiągnięto koniec tablicy, a jeśli tak, wyjdź i przejdź do tej samej rozdzielonej spacjami pętli wyjściowej z warstwy 3. W przeciwnym razie użyj pustego miejsca na warstwie 3, aby powrócić do głównej pętla.źródło