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;//
(Sin nueva línea final: cuando se copia, la primera línea de la copia y la última línea del original deben coincidir)
Básicamente, esto funciona haciendo una secuencia de variables estáticas que, en la construcción, incrementan un contador de variable global. Luego, en la destrucción, si el contador no es 0, realiza toda su salida y lo pone a cero.
Para definir una secuencia de variables sin conflictos de nombres, usamos la macro explicada de la siguiente manera:
#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.
lo que depende de las peculiaridades del procesador de cadenas. Usamos z
muchas veces para definir clases / variables que no entrarán en conflicto entre sí cuando se copien en líneas separadas. Además, las definiciones que deben aparecer solo una vez se colocan en la primera línea, que se comenta en copias del código. Las declaraciones #define
y #include
no les importa que se repitan, por lo que no es necesario un manejo especial.
Este código también presenta un comportamiento indefinido en la declaración:
printf("%d %o %x",--c,c,c)
ya que no hay puntos de secuencia, pero se modifica y se accede a c. LLVM 6.0 da una advertencia, pero la compila según lo deseado, que --c
evalúa antes c
. Se podría, a expensas de dos bytes, agregue la instrucción --c;
antes de las salidas y el cambio --c
en printf
a c
, lo que deshacerse de la advertencia.
Reemplazado std::cout
por printf
guardar 26 bytes gracias a una sugerencia de mi hermano.
1 01 0x1
? (Incluye prefijos)