C ++, 205 179 bytes
int main(){};static int c=1;
#define v(x) A##x
#define u(x) v(x)
#define z u(__LINE__)
#include <cstdio>
class z{public:z(){++c;};~z(){if(c){printf("%d %o %x",--c,c,c);c=0;}}}z;//
(Sem nova linha final - quando copiada, a primeira linha da cópia e a última linha do original devem coincidir)
Basicamente, isso funciona criando uma sequência de variáveis estáticas que, em construção, incrementam um contador de variáveis globais. Então, na destruição, se o contador não for 0, ele realiza toda a sua saída e define o contador como zero.
Para definir uma sequência de variáveis sem conflitos de nome, usamos a macro explicada da seguinte maneira:
#define v(x) A##x //This concatenates the string "A" with the input x.
#define u(x) v(x) //This slows down the preprocessor so it expands __LINE__ rather than yielding A__LINE__ as v(__LINE__) would do.
#define z u(__LINE__)//Gives a name which is unique to each line.
que depende um pouco das peculiaridades do processador de strings. Usamos z
muitas vezes para definir classes / variáveis que não entrarão em conflito entre si quando copiadas em linhas separadas. Além disso, as definições que devem ocorrer apenas uma vez são colocadas na primeira linha, comentada em cópias do código. As instruções #define
e #include
não se importam com a repetição, portanto não precisam de tratamento especial.
Este código também apresenta um comportamento indefinido na instrução:
printf("%d %o %x",--c,c,c)
como não há pontos de sequência, mas c é modificado e acessado. O LLVM 6.0 fornece um aviso, mas o compila conforme o desejado - que é --c
avaliado antes c
. Pode-se, à custa de dois bytes, adicione a declaração --c;
antes das saídas e mudanças --c
em printf
que c
, o que se livrar do aviso.
Substituído std::cout
por printf
salvar 26 bytes graças a uma sugestão do meu irmão.
1 01 0x1
? (Inclui prefixos)