wtorek, 2 marca 2010

Program w C/C++ bez użycia średników

Czy dostaliście kiedyś zadanie napisać program w C++ (lub C) tak, aby nie użyć ani jednego średnika?

Jak to możliwe? Przecież średnik w prawie każdym języku zajmuje ważne miejsce - a to rozdziela instrukcje (SQL, Pascal, Perl), a to musi kończyć każdą instrukcję (C, C++, C#, Java) - jak więc sobie dać radę bez niego.

Jak zobaczymy - bez problemowo można. Jako przykładowy program-pomocnik do gry w "BUM". Jeżeli ktoś nie zna tej gry (zna ktoś?), to krótki przypomnienie:

1. Grają dwaj gracze. Na przemian mówią kolejne liczby naturalne.
2. Jeżeli gracz ma wypowiedzieć liczbę podzielną przez 3 lub przez 5 to zamiast tej liczby gracz mówi "BUM".
3. Tak samo jeżeli liczba do wypowiedzenia zawiera w sobie cyfrę 3 lub 5 to zamiast tej liczby gracz mówi "BUM".

Napiszmy na początku "klasycznie" program-pomocnik, który wypisze nam liczby od 1 do 100 wypisując "BUM" tam gdzie powinien:

#include <cstdio>

int main()
{
  for (int i = 1; i <= 100; i++)
  {
    if (i % 3 == 0 || i % 5 == 0)
    {
      printf("BUM\n");
      continue;
    }
    int j;
    for (j = 1; j <= i; j *= 10)
    {
      int digit = (i/j) % 10;
      if (digit == 3 || digit == 5)
      {
        printf("BUM\n");
        break;
      }
    }
    if (j > i)
    {
      printf("%d\n", i);
    }
  }
}



A teraz trochę magii. Zastosujemy parę prostych zasad:

1. Zmienna zadeklarowana w if obowiązuje w całym tym bloku.
2. Instrukcja wywołana w if się wykona.
3. Instrukcja if kończy się nawiasami klamrowymi, a nie średnikiem ;)
4. Pętla while nie zawiera w sobie średników ;)

Voila:

#include <cstdio>

int main()
{
  if (int i = 1)
  {
    while (i <= 100)
    {
      if (i % 3 == 0 || i % 5 == 0)
      {
        if (printf("NUM\n")) { }
      }
      else
      {
        if (int j = 1)
        {
          if (int flag = 1)
          {
            while (flag && j <= i)
            {
              if ((i/j) % 10 == 3 || (i/j) % 10 == 5)
              {
                if (printf("BUM\n")) { }
                if (flag = 0) { }
              }
              if (j *= 10) { }
            }
            if (flag)
            {
              if (printf("%d\n", i)) { }
            }
          }
        }
      }
      if (i++) {}
    }
  }
}



Ominąłem jeden problem: funkcje zwracające void. Powiedzmy, że mamy funkcję:

void f(int x)
{
  if (printf("hello %d\n", x)) { }
}


Nie możemy jej wywołać tak:

if (f(5)) { }

Ponieważ if nie przyjmuje typu void. Na ratunek przychodzi nam kolejny znak interpunkcyjny, powodujący chaos i zamieszanie (zwłaszcza w double pi = 3,14;) przecinek:

if (f(5), 1) { }

So cool.

2 komentarze:

  1. To ja mam podobne zadanie dla Ciebie - napisz powyższy program w javie bez użycia funkcji main. Da się (sprawdzałem i chyba kiedyś Ci nawet o tym mówiłem:P)

    OdpowiedzUsuń