Нечитабельна , 1830 1796 1791 1771 1762 1745 1736 1727 1626 1606 1577 байт
Вихід є в зворотному алфавітному порядку ( z
до a
), але згідно з вашими правилами, що видається допустимим.
"" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" """ "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" """ "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" """" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" " "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" " "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" """" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" " "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" """ "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" " "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" " "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" " '"" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" " "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" """ "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" " "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" """ "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" " "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" """ "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" """" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" """ "" "" "" "" "" "" "" "" "" "" "" "" """ "" "" "" "" "" "" "" "" "" "" "" "" "
Пояснення
По-перше, щоб скласти враження про те, що можна нечитати, ось основна операція:
- У вас є нескінченна стрічка цілочисельних комірок довільного розміру
- Ви НЕ мати покажчик пам'яті , як в Brainfuck; натомість ви відмежуєте осередки за розташуванням на стрічці. Це означає, що ви можете “прочитати значення №4” або “значення читання # (значення читання №4)” (подвійний відвід).
- Ви можете лише читати або записувати комірки пам’яті (не безпосередньо приріст / зменшення, як у Brainfuck).
- Ви можете збільшувати / зменшувати значення в виразі. Таким чином, щоб збільшити осередок пам'яті , ви повинні прочитати , надбавка , писати , або інакше кажучи:
write(x, inc(read(x)))
.
- У той час, як циклі і потрійні умовні умови можуть перевіряти лише нуль проти не нуля.
Ця програма використовує стрічку наступним чином. Імена змінних будуть використані в псевдокоді нижче. Також цей документ першої версії (що склав 1830 байт); дивіться правки внизу про те, що змінилося з тих пір.
- Комірка 0: змінна
q
- Cell 1: змінні
a
, p
,ch
- Клітина 2: змінні
hash
,v
- Клітина 3: змінні
b
,r
- Клітина 4: змінні
aa
,l
- В комірці 5: залишається 0, щоб позначити "кінець" рядка десяткових цифр
- Клітини 6–95: зберігають рядок десяткових цифр назад
- Осередки 96–121: зберігають кількість голосів, які слід відрахувати від користувачів
a
(96) до z
(121) (код ASCII букви мінус один).
- Клітини 4657–7380: пригадайте, які поєднання виборців / голосуючих стикалися вже не раз. Ці клітинки мають лише 4 можливі значення:
0
= ще не бачили, -1
= бачили один раз, -2
= бачили двічі, -3
= бачили будь-яку кількість разів більше 2.
Алгоритм по суті протікає таким чином:
- Продовжуйте читати пари символів
a
і b
. Обчисліть значення хеша (a-2)*(a-1)+b-1
, яке є унікальним для кожної комбінації літер a – z.
- Перевірте комірку пам'яті на це хеш-значення (
*hash
). Якщо це так -3
, користувач вже має право на видалення голосів, тому збільшується *(b-1)
. Інакше декремент *hash
. Якщо це зараз -3
, користувач щойно отримав право на видалення голосів після трьох випадків, таким чином збільшуючи *(b-1)
їх 3
.
- Після цього пройдіть символи у зворотному порядку (
z
до a
) та виведіть ті, для яких потрібні голоси, що віднімаються. Це вимагає ручного цілого поділу на 10, щоб перевести число на десяткові цифри.
З урахуванням всього цього програма виглядає як псевдокод:
// 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
}
Редагувати 1, 1830 → 1796: Зрозуміло, що я можу повторно використовувати повернене значення циклу час в одному місці.
Редагувати 2, 1796 → 1791: Виходить програма трохи меншою, якщо замість ячеек 6–95 я зберігаю десяткові цифри у колах з відмітною нумерацією (–1 далі). Як додатковий бонус, програма більше не обмежується 10⁹⁰ голосами!
Редагування 3, 1791 → тисяча сімсот сімдесят один: Замість присвоєння результату *(ch = l + 95)
до v
, я тепер призначити його , q
а потім перемістити завдання v = q
в стан в той час, приймаючи код 1777 байт. Потім поміняйте місце розташування q
та v
на стрічку, тому що q
зараз це більше, ніж 1 v
.
Редакція 4, 1771 → 1762: Дюх. Ініціалізація hash
до 1 замість 0 на 9 байт коротша. Хеш-код тепер є ще 1, що не має значення.
Редагувати 5, 1762 → 1745: Якщо я ініціалізую q
і r
до 1 замість 0, мені доведеться посипати -1
місцями s, щоб зробити його правильним, і все, здається, скасувати - за винятком того, що while v { --v; [...] }
цикл тепер повинен виконати одну меншу ітерацію, що я можу зробити, сказавши while --v { [...] }
, що на 26 символів коротше.
Правка 6, 1745 → 1736: Замість цього { r = 1; ++q }
ми можемо писати q = *((r = 1)+1)+1
. Це покладається на те, що q
є в слоті №2 змінної. Якби це було в слоті №1, це було б ще коротше, але тоді вся програма була б довшою загалом.
Edit 7, 1745 → 1727: Reverted Edit 6 і замість цього досягнув економії, включивши внутрішню петлю до виразу, що обчислює цифру ASCII-коду, який також закінчується в 1736 байт ..., але потім зберігається інструкція про декремент (9 байт ), змінивши ((++r) - 11) ? r :
на (r - 10) ? ++r :
.
Редагувати 8, 1727 → 1626: перероблено хеш-розрахунок. Тепер він використовує один менший цикл while. Місце розташування комірок тепер знаходиться за своїми фактичними кодами ASCII (більше 1 не вимикається). Перестановляйте змінні в різні місця на стрічці, оскільки вони зараз трапляються з різною частотою.
Редагуйте 9, 1626 → 1606: Більш божевільний вклад. Тіло першого циклу while виглядає приблизно так:
// 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)
}
і призначення змінної тепер майже повністю змінилося.
Редагування 10, 1606 → 1 577: Я помітив , що a
і a2
обидва декрементируется 0 в той час як петлі, так що, якщо я міг би пару p
ні з одним з тих , хто, але НЕ з ch
, я не повинен був би ініціювати p
до 0
(який коштує 29 байт). Виявляється, я можу це зробити, замінивши p
і r
. Найновіші змінні призначення (та їх частота зустрічань у коді) тепер:
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)
nanananananananabatman
тестового випадку.