Nieczytelny , 1830 1796 1791 1771 1762 1745 1736 1727 1626 1606 1577 bajtów
Dane wyjściowe są w odwrotnej kolejności alfabetycznej ( zdo a), ale zgodnie z regułami, które wydają się dozwolone.
„” „” „” „” „„ ”„ ”„ ”„ ”„ ”„ ”„ ”„ ”„ „” „„ ”„ ”„ ”„ „” „” „” „” „” „” „” „” „” „„ ”„ ”„ ”„ ”„ „” „„ ”„ „” „” „” „„ ”„ ”„ ”„ ” „” „” „” „” „„ ”„ ”„ „” „” „” „” „„ ”„ „” „” „” „” „” „” „”„” „” „” „” „„ ”„ ”„ ”„ „” „” „” „” „„ ”„ ”„ ”„ ”„ ”„ ”„ ”„ ” „” „” „” „” „” „” „” „„ ”„ ”„ ”„ ”„ „” „„ ”„ „” „„ ”„ ”„ ”„ ” „” „” „” „” „„ ”„ „” „„ ”„ ”„ ”„ „” „„ ”„ „” „” „” „” „” „”„” „” „” „” „„ ”„ ”„ ”„ ”„ ”„ ”„ „” „„ ”„ „” „„ ”„ ”„ ”„ ”„ ”„ ” „” „” „” „” „„ ”„ ”„ ”„ ”„ ”„ ”„ ”„ ”„ „” „„ ”„ ”„ ”„ ”„ ”„ ” „” „” „” „” „„ ”„ ”„ ”„ ”„ ”„ ”„ ”„ „” „„ ”„ ”„ ”„ ”„ ”„ ”„” „” „” „” „„ ”„ ”„ ”„ ”„ ”„ ”„ ”„ „” „„ ”„ ”„ ”„ ”„ ”„ ” „” „” „” „” „„ ”„ ”„ ”„ ”„ ”„ ”„ ”„ ”„ „” „„ ”„ ”„ ”„ ”„ ”„ ” „” „” „” „” „” „” „„ ”„ „” „” „” „„ ”„ „” „„ ”„ ”„ ”„ ”„ ”„ ”„” „„ ”„ ”„ „” „” „„ ”„ „” „” „” „” „„ ”„ „” „” „” „” „” „” „” „” „” „” „” „„ ”„ ”„ „” „” „” „„ ”„ „” „„ ”„ ”„ ”„ ”„ ”„ ” „” „” „” „„ ”„ ”„ „” „„ ”„ ”„ ”„ „” „„ ”„ „” „” „” „” „” „”„” „” „” „„ ”„ ”„ ”„ ”„ ”„ ”„ „” „„ ”„ „” „” „” „„ ”„ ”„ ” „” „” „” „” „„ ”„ ”„ ”„ ”„ ”„ ”„ ”„ „” „„ ”„ ”„ ”„ ”„ ”„ ” „” „” „” „„ ”„ ”„ „” „„ ”„ ”„ ”„ „” „„ ”„ „” „” „” „” „” „” „„” „” „” „” „” „” „” „„ ”„ ”„ ”„ „” „„ ”„ „” „” „” „” „” „” „” „” „” „” „„ ”„ ”„ ”„ ”„ ”„ ”„ ”„ ”„ „” „” „” „” „” „” „” „” „” „” „” „” „„ ”„ ”„ „” „„ ”„ ”„ ”„ ”„ „” „„ ”„ ”„ ”„ ”„ ”„ ”„” „” „” „” „” „” „„ ”„ ”„ ”„ ”„ ”„ „” „„ ”„ ”„ ”„ ”„ ”„ ”„ ” „” „” „” „” „” „” „” „„ ”„ ”„ ”„ ”„ „” „„ ”„ ”„ ”„ ”„ ”„ ” „” „” „” „„ ”„ ”„ „” „„ ”„ ”„ ”„ „” „„ ”„ „” „” „” „” „” „”„” „” „” „„ ”„ ”„ ”„ ”„ ”„ ”„ „” „„ ”„ „” „” „” „„ ”„ ”„ ” „” „” „” „” „„ ”„ ”„ ”„ „” „” „” „„ ”„ „” „„ ”„ ”„ ”„ ”„ ”„ ”„ ” „” „” „” „” „” „” „” „„ ”„ ”„ ”„ ”„ „” „„ ”„ ”„ ”„ ”„ ”„ ”„ ”„” „” „” „” „„ ”„ ”„ ”„ „” „” „” „„ ”„ „” „„ ”„ ”„ ”„ ”„ ”„ ”„ ” „” „” „” „” „„ ”„ „” „” „” „” „” „” „” „„ ”„ „” „” „” „” „” „” „” „” „” „” „” „” „„ ”„ ”„ ”„ ”„ ”„ „” „„ ”„ ”„ ”„ ”„ ”„ ”„” „” „” „” „„ ”„ „” „” „” „” „” „” „„ ”„ ”„ ”„ ”„ ”„ ”„ ” „” „” „” „„ ”„ ”„ ”„ ”„ „” „” „” „„ ”„ „” „” „”„” „” „” „” „” „” „” „„ ”„ ”„ ”„ ”„ ”„ ”„” „” „” „” „” „” „” „„ ”„ ”„ ”„ ”„ ”„ ”
Wyjaśnienie
Po pierwsze, aby zorientować się, co może zrobić Nieczytelny, oto jego podstawowe działanie:
- Masz nieskończoną taśmę komórek liczb całkowitych o dowolnym rozmiarze
- Zdajesz nie posiada wskaźnik pamięć jak w brainfuck; zamiast tego wyrejestrowujesz komórki według ich położenia na taśmie. Oznacza to, że możesz „odczytać wartość # 4” lub „odczytać wartość # (odczytać wartość 4)” (podwójne dereferencje).
- Możesz tylko czytać lub zapisywać komórki pamięci (nie bezpośrednio zwiększać / zmniejszać, jak w Brainfuck).
- Możesz zwiększać / zmniejszać wartości w wyrażeniu. Dlatego, aby zwiększyć komórkę pamięci trzeba czytać , przyrost , pisać , lub inaczej umieścić:
write(x, inc(read(x))).
- Istnieją pętle while i trójskładnikowe warunki, które mogą sprawdzać tylko zero lub zero.
Ten program używa taśmy w następujący sposób. Nazwy zmiennych zostaną użyte w pseudokodzie później poniżej. Dokumentuje także pierwszą wersję (1830 bajtów); zobacz zmiany u dołu, które zmieniły się od tego czasu.
- Komórka 0: zmienna
q
- Komórka 1: zmienne
a, p,ch
- Komórka 2: zmienne
hash,v
- Komórka 3: zmienne
b,r
- Komórka 4: zmienne
aa,l
- Komórka 5: pozostaje 0, aby zaznaczyć „koniec” ciągu cyfr dziesiętnych
- Komórki 6–95: przechowuje ciąg cyfr dziesiętnych do tyłu
- Komórki 96–121: przechowują liczbę głosów, które należy odjąć od użytkowników
a(96) do z(121) (kod ASCII litery minus jeden).
- Komórki 4657–7380: pamiętaj, które kombinacje wyborców / wyborców napotkano ile razy. Komórki te mają tylko 4 możliwe wartości:
0= jeszcze nie widział, -1= widział raz, -2= widział dwa razy, -3= widział dowolną liczbę razy więcej niż 2.
Algorytm zasadniczo działa w następujący sposób:
- Czytaj dalej pary znaków
ai b. Oblicz wartość skrótu (a-2)*(a-1)+b-1, która jest unikalna dla każdej kombinacji liter a – z.
- Sprawdź komórkę pamięci przy tej wartości skrótu (
*hash). Jeśli tak -3, użytkownik jest już uprawniony do usunięcia głosu, więc zwiększaj *(b-1). W przeciwnym razie spadek *hash. Jeśli jest to teraz -3 , użytkownik po prostu stać się kwalifikują się do usunięcia głosowanie po trzech zdarzeń, więc zwiększyć *(b-1)przez 3.
- Następnie przejrzyj postacie w odwrotnej kolejności (
zdo a) i wypisz te, które wymagają odliczenia głosów. Wymaga to ręcznego dzielenia liczb całkowitych przez 10, aby przełożyć liczbę na cyfry dziesiętne.
Po tym wszystkim wyjaśniono, że tak wygląda program jako pseudokod:
// Read pairs of characters
while (a = read) + 1 {
b = read
// Calculate hash = (a-1)*(a-2)/2 + b-1
// This also sets a = b-1
hash = 0
while --a {
aa = a
while --aa {
++hash
}
}
while --b {
++a
++hash
}
// If this combination has just been seen for the third time,
// increment *a by 3; if more than third time, increment *a by 1
*a = (*hash + 3) ? ((--*hash) + 3 ? *a : (*a+3)) : (*a+1)
}
// Loop through the characters z to a
l = 27
while --l { // l loops from 26 to 1 (not 0)
(v = *(ch = l + 95)) ? { // 'a' is ASCII 97, but cell 96
print (ch+1) // print the votee
// Now we need to turn the number v into decimal.
// p points to where we are storing decimal digits.
p = 5
while v {
// Integer division by 10 (q=quotient, r=remainder)
r = (q = 0)
while v {
--v
(++r - 10) ? 1 : {
r = 0
++q
}
}
// Store digit ASCII character
*(++p) = r + 48 // 48 = '0'
v = q
}
// Now output all the digit ASCII characters in reverse order
while *p {
print *(--p + 1)
}
} : 1
}
Edycja 1, 1830 → 1796: Uświadomiłem sobie, że mogę ponownie użyć wartości zwracanej pętli while w jednym miejscu.
Edycja 2, 1796 → 1791: Okazuje się, że program jest nieco mniejszy, jeśli zamiast komórek 6–95 przechowuję cyfry dziesiętne w komórkach o numerach ujemnych (–1 wzwyż). Jako dodatkowy bonus program nie jest już ograniczony do 10⁹⁰ głosów!
Edycja 3, 1791 → 1771: Zamiast przypisywać wynik *(ch = l + 95)do v, teraz przypisuję go do, qa następnie przenoszę przypisanie v = qdo warunku while, przenosząc kod do 1777 bajtów. Następnie zamień lokalizację qi vna taśmie, ponieważ qjest teraz o 1 bardziej powszechna niż v.
Edytuj 4, 1771 → 1762: Duh. Inicjalizacja hashna 1 zamiast 0 jest krótsza o 9 bajtów. Kod skrótu jest teraz o 1 więcej, co nie ma znaczenia.
Edycja 5, 1762 → 1745: Jeśli zainicjuję qi rdo 1 zamiast 0, muszę posypać kilka -1s miejscami, aby wszystko było w porządku, i wydaje się, że wszystko się anuluje - poza tym, że while v { --v; [...] }pętla musi teraz wykonać jedną mniejszą iterację, co mogę zrobić, mówiąc o while --v { [...] }26 znaków krótszych.
Edycja 6, 1745 → 1736: Zamiast tego { r = 1; ++q }możemy pisać q = *((r = 1)+1)+1. Zależy to od faktu, że qznajduje się w zmiennej szczelinie nr 2. Gdyby znajdował się w gnieździe nr 1, byłby jeszcze krótszy, ale cały program byłby ogólnie dłuższy.
Edycja 7, 1745 → 1727: Cofnięto Edycja 6 i zamiast tego osiągnięto oszczędność poprzez wstawienie najbardziej wewnętrznej podczas pętli do wyrażenia obliczającego cyfrowy kod ASCII, który również kończy się na 1736 bajtach ... ale następnie zapisał instrukcję dekrementacji (9 bajtów ), zmieniając ((++r) - 11) ? r :na (r - 10) ? ++r :.
Edytuj 8, 1727 → 1626: Przerobiono obliczanie wartości skrótu. Teraz używa o jedną mniej pętli while. Lokalizacje komórek mają teraz swoje rzeczywiste kody ASCII (już nie wyłączone o 1). Przetasowane zmienne w różnych miejscach na taśmie, ponieważ występują one teraz z inną częstotliwością.
Edytuj 9, 1626 → 1606: Bardziej szalone wstawianie. Ciało pierwszej pętli while wygląda teraz mniej więcej tak:
// b = next char
*(b = (hash = read)) = {
// hash = b + (a-1)*(a-2)/2
while (a2 = --a) {
while --a2 {
++hash
}
}
// If this combination has just been seen for the third time,
// increment *b by 3; if more than third time, increment *b by 1
(*hash + 3) ? ((--*hash) + 3 ? *b : (*b+3)) : (*b+1)
}
a przypisanie zmiennych zmieniło się prawie całkowicie.
Edycja 10, 1606 → 1577: Zauważyłem, że ai a2są zarówno zmniejszany do 0 w podczas pętli, więc jeśli mogę powiązać pz żadnym z nich, ale nie z ch, nie trzeba zainicjować pdo 0(która kosztuje 29 bajtów). Okazuje się, że mogę to zrobić, zamieniając pi r. Najnowsze przypisania zmiennych (i ich częstotliwość występowania w kodzie) to teraz:
0 = v (3) (total 3)
1 = hash (6), r (5), ch (2) (total 13)
2 = b (4), q (5) (total 9)
3 = a (3), p (5) (total 8)
4 = a2 (3), l (4) (total 7)
nanananananananabatmanprzypadku testowego.