Jste zde

Zajímavé úlohy pro programátory v C a C++ #12

Tentokrát budeme doplňovat program, který nevypadá jako Céčkový ani C++ový, tak, že bude přeložitelný překladačem C či C++ a bude dělat to samé, co původní program.

Zadání

Uvažujte následující kód, který nápadně připomíná Hello World zapsaný v jazyce Java.

// ???
 
public static void main(String[] args) {
    System.out.println("Ahoj svete!");
}

Co je třeba do kódu doplnit na místo označené komentářem s otazníky, aby zadaný program šel přeložit překladačem podle normy C99 či C++98 a po spuštění vypsal "Ahoj svete!" (bez uvozovek)? "Vítězí" řešení s nejmenším počtem použitých znaků ;).

Řešení

S varováními (202 znaků):

#define public union String{union{int println(char*s){printf(s);}}out;
#define args);}System;int main(
#include<cstdio>
public static void main(String[] args) {
    System.out.println("Ahoj svete!");
}

Bez varování (210 znaků):

#define public union String{union{void println(const char*s){printf(s);}}out;
#define args );}System;int main(
#include<cstdio>
public static void main(String[] args) {
    System.out.println("Ahoj svete!");
}

Řešení je založeno na příspěvcích od Libora.

Komentáře

$ cat reseni.cc
 
#define public 
#define static 
#define void int
#define String int argc, char* argv
#define args
#include <cstdio>
struct A{struct B{int(*println)(const char*,...);B():println(printf){}}out;}System;
public static void main(String[] args) {
    System.out.println("Ahoj svete!");
}
$ g++ reseni.cc -o reseni
$ ./reseni 
Ahoj svete!$ 
$ wc -m reseni.cc 
282 reseni.cc

Díky za odpověď -- je to správně :). Podaří se to někomu zkrátit? (Jen poznamenám, že to lze zkrátit o téměř 50 znaků.)

Skoro o 50 znaků lepší, ale s warningy (ukazatel prý není číslo :D):

$ make 
g++  -std=c++98   reseni.cc   -o reseni
reseni.cc:7: warning: first argument of ‘int main(int*)’ should be ‘int’
reseni.cc:7: warning: ‘int main(int*)’ takes only zero or two arguments
./reseni
Ahoj svete!
cat reseni.cc
#define static :struct B{int(*println)(const char*,...);}out;}System={{printf}};
#define void int
#define String int
#define args
#include <cstdio>
class A{
public static void main(String[] args) {
    System.out.println("Ahoj svete!");
}
wc -m reseni.cc
239 reseni.cc

I bez warningů už se vejdu na 8 bitů:

$ make 
g++  -std=c++98   reseni.cc   -o reseni
./reseni
Ahoj svete!
cat reseni.cc
#define static :struct B{int(*println)(const char*,...);}out;}System={{printf}};
#define void int
#define String int argc,char*argv
#define args
#include <cstdio>
class A{
public static void main(String[] args) {
    System.out.println("Ahoj svete!");
}
wc -m reseni.cc
254 reseni.cc

Co se počítá?

Obojí ;). Budu to brát jako dvě verze: s warningy a bez warningů. Já jsem teď na 217 s warningy a 228 bez warningů.

Žádný nový trik, jen skrácení příliš dlouhých identifikátorů, než mi to někdo vyžere.

g++  -std=c++98   reseni.cc   -o reseni
g++  -std=c++98   reseniw.cc   -o reseniw
reseniw.cc:7: warning: non-local variable ‘<anonymous class> System’ uses anonymous type
reseniw.cc:7: warning: first argument of ‘int main(int*)’ should be ‘int’
reseniw.cc:7: warning: ‘int main(int*)’ takes only zero or two arguments
./reseni
Ahoj svete!
cat reseni.cc
#define static :struct B{int(*println)(const char*,...);}out;}System={{printf}};
#define void int
#define String int,char*
#define args
#include <cstdio>
class A{
public static void main(String[] args) {
    System.out.println("Ahoj svete!");
}
wc -m reseni.cc
245 reseni.cc
./reseniw
Ahoj svete!
cat reseniw.cc
#define static :struct{int(*println)(const char*,...);}out;}System={{printf}};
#define void int
#define String int
#define args
#include <cstdio>
class{
public static void main(String[] args) {
    System.out.println("Ahoj svete!");
}
wc -m reseniw.cc
235 reseniw.cc

Btw, to od tebe není pěkné, snižovat laťku během hry :p

> Btw, to od tebe není pěkné, snižovat laťku během hry :p

Já vím :].

g++  --std=c++98   reseni.cc   -o reseni
g++  --std=c++98   reseniw.cc   -o reseniw
reseniw.cc:2:13: warning: missing whitespace after the macro name
./reseni
Ahoj svete!
cat reseni.cc
#define public struct String{struct{int(*println)(const char*,...);}out;
#define args );}System={{printf}};int main(
#include<cstdio>
public static void main(String[] args) {
    System.out.println("Ahoj svete!");
}
<code>
wc -m reseni.cc
216 reseni.cc
./reseniw
Ahoj svete!
cat reseniw.cc
#define public struct String{struct{int(*println)(const char*,...);}out;
#define args);}System={{printf}};int main(
#include<cstdio>
public static void main(String[] args) {
    System.out.println("Ahoj svete!");
}
wc -m reseniw.cc
215 reseniw.cc

Ještě pro doplnění čisté céčko (ne špinavé c++)

cc --std=c99    cecko.c   -o cecko
cc --std=c99    ceckow.c   -o ceckow
ceckow.c:2:15: warning: ISO C99 requires whitespace after the macro name
ceckow.c:7: warning: initialization from incompatible pointer type
./cecko
Ahoj svete!
cat cecko.c
#include<stdio.h>
#define static {struct{int(*println)(const char*,...);}out;}System={{printf}};
#define void int
#define String int c
#define args 
struct
public static void main(String[] args) {
    System.out.println("Ahoj svete!");
}
wc -m cecko.c
238 cecko.c
./ceckow
Ahoj svete!
cat ceckow.c
#include<stdio.h>
#define static{struct{int(*println)();}out;}System={{printf}};
#define void int
#define String int a
#define args 
struct
public static void main(String[] args) {
    System.out.println("Ahoj svete!");
}
wc -m ceckow.c
222 ceckow.c

Wow, pěkné ;). Kdyby to bylo v předmětu, tak Ti dám bonusový bod :). Když jsem použil ten tvůj poslední trik, tak jsem se dostal na 202 s warningy a 210 bez warningů ;). Ať je nějaká sranda, tak to zveřejním (vyměnil jsem struct za union a ukazatel na funkci za metodu).

S warningy (202):

#define public union String{union{int println(char*s){printf(s);}}out;
#define args);}System;int main(
#include<cstdio>
public static void main(String[] args) {
    System.out.println("Ahoj svete!");
}

Bez warningů (210):

#define public union String{union{void println(const char*s){printf(s);}}out;
#define args );}System;int main(
#include<cstdio>
public static void main(String[] args) {
    System.out.println("Ahoj svete!");
}

Zveřejnil jsem řešení dvanácté úlohy.

Přidat komentář