C90 (gcc), 46 байт
r;main(c,v)int**v;{while(0<--c&*v[c])r++;c=r;}
Введення здійснюється через аргументи командного рядка (одне ціле число на аргумент), вихід - через вихідний код .
Спробуйте в Інтернеті!
Як це працює
r - глобальна змінна. Його тип за замовчуванням до int і, будучи глобальним, він значення за замовчуванням до 0 .
Аргумент функції c за замовчуванням також для int . Він буде містити ціле число n + 1 для масивів n булевих; перший аргумент main - це завжди шлях до виконуваного файлу.
Аргумент функції v оголошується як int**
. Фактичний тип v буде char**
, але оскільки ми розглянемо лише найменш значущий біт кожного аргументу, щоб повідомити символи 0 (кодова точка 48 ) та 1 (кодова точка 49 ), це не має значення для маленького ендіана машини.
Зменшення циклу while c і порівнює його з 0 . Як тільки c досягне 0 , ми вирвемося з циклу. Це потрібно, лише якщо масив не містить 0 's.
Поки 0<--c
повертається 1 , ми беремо c- й аргумент командного рядка ( v[c]
) і витягуємо його перший символ за допомогою перенаправлення покажчика ( *
). Візьмемо побітові AND булевого 0<--c
та кодового пункту символу (і три байти сміття, що слідують за ним), тому умова повернеться 0, коли зустрінеться 0 , вириваючись із циклу.
У останньому випадку, хоча аргументи командного рядка дорівнюють 1 , з r++
кроком r на 1 , таким чином підраховуючи кількість кінцевих 1 -х.
Нарешті, c=r
зберігає обчислене значення r у c . За допомогою налаштувань за замовчуванням компілятор оптимізує та видаляє призначення; він фактично генерує movl %eax, -4(%rbp)
інструкцію. Оскільки ret
повертає значення регістру EAX, це генерує бажаний вихід.
Зауважте, що цей код не працює з C99, який повертає 0 з основного, якщо досягнуто кінця основного .
01100
?