Wątek przeniesiony 2014-02-13 18:14 z Off-Topic przez ŁF.

jednolinijkowce - tak czy nie?

5

Co jest nie tak z tym kodem?

#include <cstdio>
#include <cstring>
using namespace std;
 
int main()
  {
   unsigned T;
   scanf("%u",&T);
   while(T--)
     {
      static char A[1001],B[1001];
      scanf(" %1000s %1000s",B,A);
      char *a=A;
      for(char *b=B;(*a)&&((b=strchr(b,*a))!=0);++a) ++b;
      printf("%s\n",*a?"Nie":"Tak");
     }
   return 0;
  }

z http://4programmers.net/Forum/Newbie/156914-wyszukiwanie_podciagu_w_danym_ciagu_-_kod_nie_zostaje_zaakceptowany_przez_sedziego_spoj

  1. stosuje duże litery do zmiennych
  2. zadanie polega na znalezieniu drugiego ciągu w pierwszym (a tu jest odwrotnie - szukamy a w b)
  3. rozwiązanie sprowadzone do jednej linijki nie jest ładnym rozwiązaniem - i o tym jest dyskusja w ww wątku
  4. w standardzie GNU explicite Richard Stallman pisze żeby takich kodów unikać:

GNU C/C++ Coding Standards, Richard Stallman
(avoid assignments inside if-conditions)
http://www.sourceformat.com/pdf/cpp-coding-standard-gnu.pdf

  1. @_13th_Dragon powołuje się na Boost i STL (np. STLPort).
    W Boost nie znalazłem ani jednego jednolinijkowego for-a z przypisaniem w warunku pętli.
    W STLPort nie szukałem, ale chętnie zobacze jakiegoś.

I pytanie:

  • kto pisze takie kody i jak mu to usprawnia pracę?

Wersja poglądowa, rozpisana dla ludzi którzy nie mają czasu lub ochoty formatować i analizować jednolinijkowców:

#include <cstdio>
#include <cstring>
using namespace std;

int main() {
    unsigned cnt;
    scanf("%u", &cnt);
    while (cnt--) {
        static char atab[1001], btab[1001];
        scanf(" %1000s %1000s", atab, btab);
        char *a = atab;
        char *b = btab;
        while(*b) {
            a = strchr(a, *b);
            if (!a)
                break;
            ++a;
            ++b;
        }
        printf("%s\n", *b ? "Nie" : "Tak");
    }
    return 0;
}

(for zamieniony na while)

3

Lubie czytac posty @_13th_Dragon jezeli uzyje ciekawego algorytmu. Jezeli chodzi o takie zadania, przewaznie omijam posty. Z prostego wzgledu. Szkoda mi czasu na analizowanie dokladnie co tam sie dzieje.
Kazdy ma swoj styl pisania, ja takiego nie popieram, bo z mojego doswiadczenia.

  1. dluzej sie analizuje
  2. na pierwszy rzut oka NIE widac co to robi
  3. gorzej sie utrzymuje.

osobiscie wole drugi kod.

Moge zrozumiec taki kod jezeli chodzi o wydajnosc , nie w innych przypadkach. Takze na SPOJ to jest calkiem dobre rozwiazanie.
A najladniejszy kod dal @Shalom. Ten kod mozna czytac i po 10 sekundach wiadomo o co chodzi w calym programie

nawet @vpiotr owi powiedzialbym zeby tego ifa obsluzyl w {} a zamaist a == 0 wpisac po prostu if (!a). Prinfta rozbic, if trojargumentowy tez nie jest fajny. Kod ma byc taki zeby dalo sie go czytac jak ksiazke. Szybko i wiedziec co dany kawalek kodu robi. Analizowanie kodu po kims dzieki takim zalozeniom jest wielokrotnie krotsze. Jezeli bedzie jakis bug. To bedziemy mogli go szybko odnalezc, gdyz bedziemy wiedziec dokladnie gdzie to moze wystepowac. Wole poprawiac bugi i rozszerzac kod latwo, niz przepisywac wszystko i rozszerzac trudno. Wystepowanie bugow/feature'ow przewaznie zawsze jest taka sama nie zaleznie jak "krotki" bedzie ten kod. A lepiej spedzic nad poprawieniem 4 min niz godzine

0

@_13th_Dragon: twierdziłeś, że Twój kod wzoruje się na K&R (C Programming Language, Brian W. Kernighan, Dennis M. Ritchie).

Cytuję:

"za samo przypisanie w warunku wieszałbym na suchej gałęzi ..."

  • to powinieneś zacząć od D.Ritchie, B.Kernighan poprzez B.Stroustrup'a na autorach współczesnych STL oraz boost'a kończąc.

Just-for-you przejrzałem jeszcze raz K&R.

W całej książce jest jeden for-a z przypisaniem w warunku:

5.2 Wskaźniki i argumenty funkcji (wydanie 2010)

for(*pn = 0; isdigit(c), c = getch())
  *pn = 10 * *pn + (c - '0');

W wydaniu z 1988 widać już lepiej o co chodziło autorom:

for(*pn = 0; c >= '0' && c <= '9'; c = getch())
  *pn = 10 * *pn + c - '0';

Jeśli coś przeoczyłem to i tak większość pętli wygląda tak:

  • for: pętla z inicjalizacją, czystym warunkiem i aktualizacją liczników
  • while: pozostałe pętle, w tym każda z przypisaniem w warunku

Kody K&R nie są specjalnie piękne (np. zmienne "fp", "fd", "nbp") ale i tak są super, jak na język C.
Po prostu mijasz się z prawdą, styl tego programu na pewno nie pochodzi z K&R.
Więc skąd?

0

Nie za bardzo widze co jest zlego w prostym przypisaniu w petli czy ifie, skoro calosc wykonuje sie, sprawdzajac warunek pojedynczej funkcji.
Example: [ http://beej.us/guide/bgnet/output/html/multipage/syscalls.html#getaddrinfo ]

if ((status = getaddrinfo(NULL, "3490", &hints, &servinfo)) != 0) {
    fprintf(stderr, "getaddrinfo error: %s\n", gai_strerror(status));
    exit(1);
}
0

Osobiście nie lubię jednolinijkowców, dla mnie są nieczytelne. Nie mam nic przeciwko prostym przypisywaniom w pętli czy if'ie choć sam tego nie praktykuję.

5

Moim zdaniem programowanie nie polega na napisaniu jak najkrótszego kodu pod względem liczby linijek czy znaków. Czytelność jest jedną z ważniejszych rzeczy, szczególnie, kiedy nad kodem pracuje wielu ludzi albo kod ma być używany przez wielu ludzi. To ostatnie to akurat są rzeczy tak oczywiste i podstawowe, że nie ma w ogóle o czym dyskutować. Taki potwór nigdy nie przejdzie przez normalne code review.

Podsuwanie takich kodów początkującym uważam za bardzo szkodliwe - zniechęca do nauki i uczy bardzo złych nawyków. Miejsce takich kodów jest na IOCCC.

Ten temat ponadto nie ma sensu. _13th_Dragon nie zmieni zdania, ani my nie zmienimy zdania, może zawczasu przenieście to do Flame.

Btw: Już dwa razy pokazywałem, że takie potwory są nie tylko nieczytelne ale też wolniejsze od czytelnego kodu.

0

@Endrju: Chcę się tylko upewnić że nie cyt. "obrosłem w łuski".
Bo może w dobie internetu od kołyski ludzie takie kody wciągają bez zastanowienia a ja tylko dramatyzuje.

13

Kod ma być przejrzysty i wydajny. W sensownie zorganizowanym zespole, w którym robi się review kodu, taki obfuskowany kod (zminifikowany?) zostałby zwrócony.
Nie ma czegoś takiego jak wydajność kosztem czytelności, ponieważ zawsze można napisać kod tak samo wydajny w sposób przejrzysty. Oszczędzanie na nazwach zmiennych, spacjach, enterach, wprowadzanie niestandardowego formatowania - to wszystko zemści się w pierwszym większym projekcie, nad którym trzeba będzie się pracować na tyle długo, że zapomni się o co chodziło w kodzie sprzed kilku miesięcy. A błyskawicznie wróci to w przypadku, kiedy nad projektem będzie pracować kilka osób, już widzę tę kłótnię po kilku pierwszych commitach (chociażby za formatowanie odległe od jakiegokolwiek standardu - vide przytoczony na samym początku wątku kod). No i kogo obchodzi oszczędność kilkunastu cykli procesora, albo nawet dwukrotne przyspieszenie kodu po miesiącu pracy, jeśli serwer jest obciążony w 5%? Optymalizuje się tylko wąskie gardła i to w taki sposób, żeby kod pozostał zrozumiały dla wszystkich.
Zwróćcie też uwagę na to, że programista jest drogi, dlatego powinien być możliwie wydajny. To oznacza, że nie powinien marnować czasu na próbach zrozumienia, co kolega miał na myśli (o ile nie zwolnili do tej pory tego kolegi za kod gównianej jakości - wtedy nawet nie można go spytać "wtf?!"). Z tego powodu też najpierw liczy się czytelność, a dopiero potem wydajność - sprzęt jest zwykle tańszy od programisty, więc można dokupić kolejny serwer, a zresztą słaba wydajność wyjdzie przy automatycznych testach wydajnościowych, a pomyślcie o ile trudniej robi się review takiego zobfuskowanego kodu i o ile trudniej wyłapać niewydajną logikę. To trochę, jakby Polak miał poprawiać błędy gramatyczne Czecha.
Moim zdaniem umiejętność napisania kodu w mniejszej ilości znaków nie świadczy dobrze ani o kompetencjach miękkich, ani twardych programisty.

0

Odwieczny problem - każdy programista ma inne zdanie co jest czytelne a co nie. Dla jednych klamerki w tej samej linijce są bardziej czytelne od klamerek w nowej linijce; jedni wolą Camel Case inni go nie cierpią; niektórzy wolą NULL'a od 0... Tak można by wymieniać. Coding style to idealny temat na marnowanie czasu zarówno prywatnego jak i tego w pracy. Nieraz widziałem code review, które skupiały się tylko i wyłącznie na "błędach" w stylu zamiast na realnych błędach w aplikacji. W sumie mnie to nie dziwi - łatwiej znaleźć "błąd" w stylu niż realnego buga. Do tego można pisać o tym kilometrowe wywody dowodzące swoich racji.
IMHO sprawa jest dosyć prosta:

  1. Jeżeli w projekcie jest ustalony coding style to bez gadania trzeba się go trzymać
  2. Jeżeli w projekcie nie ma ustalonego coding style'u to każdy wybiera styl jaki uważa za czytelny
    Oszczędza czas na jałowe dyskusje.
    Tak na prawdę problemem nie jest to, że ktoś pisze jednolinijkowce lub ich nie pisze. Problemem jest wiara Jeden Czytelny Styl, którego wszyscy powinni używać i zamknięcie się na inne na wszystko inne. Z tym warto by powalczyć.
0

A ja tam lubię jednolinijkowce. Nie ma co tracić czasu na rozbijanie na części prostego algorytmu. Jedna linijka, komentarz - co to robi. Jeśli przeszło unit testy to "fck off! this is my sit!".

A co do podrzucania takiego kodu początkującym. Powinni wiedzieć, że JavaScript z programowaniem ma niewiele wspólnego.

0

Primo kod podany jako przykład nieczytelnego jednolinijkowca jest rozwiązaniem zadania algorytmicznego. Popatrzcie sobie jak ludzie piszą kod na konkursy topcoder, tam taki kod jest "normalny". Nie ma sensu tego zjawiska dawać jako przykład złej praktyki programistycznej i nad nim debatować. Przecież chyba nikt w ten sposób nie pisze kodu produkcyjnego aplikacji, którą rozwija wiele osób?!

Ostatnie zdanie @ŁF normalnie śmiech na sali, Markowi Cyganowi chcesz odmawiać kompetencji?!

Kolejna sprawa, nikt nie wziął pod uwagę języków funkcyjnych gdzie jednolinijkowce np. wyrażenia listowe, wyrażenia lambda są czymś normalnym i naturalnym. Nie wyobrażam sobie ich nie używać.

Sorry, ale imho ten temat jest bez sensu. Chyba, że ten wątek został założony w celu zlinczowania autora na forum...

2

Ostatnie zdanie @ŁF normalnie śmiech na sali, Markowi Cyganowi chcesz odmawiać kompetencji?!

Nie zrozumiałeś tego ostatniego zdania. Chodzi o to, że umiejętność pisania jak najbardziej zwięzłego kodu nie jest dowodem kompetencji (oczywiście, nie jest też dowodem braku kompetencji).

10
Ola Nordmann napisał(a):

A ja tam lubię jednolinijkowce. Nie ma co tracić czasu na rozbijanie na części prostego algorytmu. Jedna linijka, komentarz - co to robi. Jeśli przeszło unit testy to "fck off! this is my sit!".

Widać że masz 0 doświadczenia zawodowego... Jak sobie piszesz do szuflady to możesz pisać jak ci się podoba, ale jak piszesz kod który ma być utrzymywany i rozwijany przez 10+ lat to się tak nie da robić.
Komentarze w kodzie? I to wyjaśniające kod? WTF? Jeśli musisz napisać taki komentarz to znaczy że kod jest napisany źle i tyle. Kod ma się sam komentować. Komentarze nie ewoluują razem z kodem, w efekcie za rok komentarz będzie taki sam, ale kod będzie już robił coś innego i wtedy już nikt nie dojdzie do tego co ten kod miał robić.
Poza tym stwierdzenie f*ck off! this is my s*it! jest idiotyczne, bo w dużym projekcie kod jest wspólny a nie tylko autora. To że ja dziś pisałem coś w klasie X / module Y nie znaczy że to są teraz "moje zabawki" i tylko ja coś z nimi będę robił. Będą przy nich pracować inni ludzie, który niekoniecznie wiedzą dlaczego w jakimś miejscu magicznie przesuwasz sobie wskaźnikiem po stosie i robisz jakieś cuda na kiju (a robisz to żeby urwać dwa cykle procesora i zaoszczędzić nanosekundy w jakimś zupełnie nie istotnym miejscu w kodzie). Czas programisty jest zbyt drogi żeby marnować go na wgryzanie się w "hakerski" kod.

0
Adam Borowski napisał(a):

Sorry, ale imho ten temat jest bez sensu. Chyba, że ten wątek został założony w celu zlinczowania autora na forum...

Tu nie chodzi o linczowanie kogokolwiek, chcę wyjaśnić czy taki kod może być zrozumiały.
Nie omawiamy tu osoby tylko kod.

Z tego co obserwuję ludzie (ja osobiście nie) mają nawet problem z takimi linijkami:

printf("%s\n",*a?"Nie":"Tak");

nie mówiąc już o wpakowaniu całego algorytmu w jedną linijkę.

2

Do wszystkiego potrzebne jest wyczucie. Jeśli wszędzie zamiast

if(ptr) ptr->doStuff();

będziemy pisać

if(ptr)
{
    ptr->doStuff();
}

to też będziemy tracić na czytelności - ilość miejsca w pionie na współczesnych ekranach jest zdecydowanie bardziej ograniczona niż w poziomie (mało kto używa pivota lub dużej ilości pionowych okien). Ja np. zdecydowanie wolę móc objąć całą funkcję wzrokiem, niż musieć scrollować tam i z powrotem.

W skrócie: kod powinien być optymalizowany pod czytającego.

0

U mnie tego typu jednolinijkowce są zupełnie nietolerowane, jeżeli masz taką potrzebę, powinienem wrzucić to w funkcję, z odpowiednią nazwą, a następnie rozbić to na kilka linii, tak żeby jedna linijka odpowiadała za jedno zadanie. Taka polityka... często wynika to z tego, że niektórzy korzystają z konsolowego gdb jako debuggera, a taki kod ciężko się w nim śledzi.

0

Z tego co obserwuję ludzie (ja osobiście nie) mają nawet problem z takimi linijkami:

printf("%s\n",*a?"Nie":"Tak");

Bo to jest bardzo zły kod. Jeśli chodzi o porównanie *a do zera, czy jakiegoś NULLa, warunek powinien być odwrotny:

   printf("%s\n", (*a == 0) ? "Tak" : "Nie");

Masz swoje ?:, a bez WTF-a z odwróconym warunkiem.

1
vpiotr napisał(a):

Tu nie chodzi o linczowanie kogokolwiek, chcę wyjaśnić czy taki kod może być zrozumiały.
Nie omawiamy tu osoby tylko kod.

Bitch please! W trzech pierwszych postach jest podany nick autora tego kodu! Jeżeli chodzi o kod, a nie o autora to dlaczego w ogóle został podany?

vpiotr napisał(a):

Z tego co obserwuję ludzie (ja osobiście nie) mają nawet problem z takimi linijkami:

printf("%s\n",*a?"Nie":"Tak");

nie mówiąc już o wpakowaniu całego algorytmu w jedną linijkę.

Jeżeli ktoś ma problem z takim kodem, to powinien się zastanowić nad sobą i dalszym przebiegiem swojej kariery zawodowej...

2

Ja mam problem z takim kodem. Napisanie w jednym miejscu w taki sposób prawdopodobnie wiąże się z pisaniem tak także w innych miejscach, a do czego to prowadzi już się wypowiedziałem. Jeśli nie rozumiesz czegoś z tego, co napisałem albo się z tym nie zgadzasz, to nie wstydź się i zapytaj albo skrytykuj, ale używając merytorycznych argumentów, a nie "powinien się nad sobą zastanowić".

1

Przepraszam ale jakich merytorycznych argumentów? Jeżeli wg Ciebie "prawdopodobnie wiąże się z pisaniem tak także w innych miejscach" jest merytorycznym argumentem, to sorry ale chyba się nie zrozumiemy. Czy widziałeś kiedyś kod napisany w Pythonie w stylu pep8? Jeżeli linijka kodu mieści się w 80 znakach, a oprócz tego są przestrzegane inne zasady np. używania spacji w wyrażeniach to wszystko jest ok. Pracowałem bardzo często z takim kodem i nie sprawiał mi problemów. Nie wiem, może programiści C/C++ powinni zacząć się po prostu stosować do jakiś sprawdzonych reguł w stylu pep8, a nie subiektywnie oceniać czytelność kodu, nad podstawie jakiegoś prawdopodobieństwa (SIC!) i własnego widzimisię.

2

Mamy XXI wiek i wymiary monitorów pozwalające wyświetlać trochę więcej niż 80 znaków w linii.
Porównaj czytelność (nie znam języka, nie wiem czy wcięcia pełnią w nim jakąś rolę, jeśli moje zmiany w formatowaniu coś rozwalają to nie zwracaj na to uwagi):

//13D
class R(Blob):
    def __init__(s,w,h,c='black',e=None,h=0):
        if (!w and !h and c=='red' and e=='strong' or h>100):raise ValueError("sorry, you lose")
        if !w and !h and (c=='red' or e is None):raise ValueError("I don't think so -- values are %s, %s"%(w,h))
        Blob.__init__(s,w,h,c,e,h)
//pep8
class Rectangle(Blob):

    def __init__(self, width, height,
                 color='black', emphasis=None, highlight=0):
        if (width == 0 and height == 0 and
                color == 'red' and emphasis == 'strong' or
                highlight > 100):
            raise ValueError("sorry, you lose")
        if width == 0 and height == 0 and (color == 'red' or
                                           emphasis is None):
            raise ValueError("I don't think so -- values are %s, %s" %
                             (width, height))
        Blob.__init__(self, width, height,
                      color, emphasis, highlight)

vs

//ŁF32
class Rectangle(Blob):

    def __init__(self, width, height, color='black', emphasis=None, highlight=0):
        if (width == 0 and height == 0 and color == 'red' and emphasis == 'strong' or highlight > 100):
            raise ValueError("sorry, you lose")

        if width == 0 and height == 0 and (color == 'red' or emphasis is None):
            raise ValueError("I don't think so -- values are %s, %s" % (width, height))

        Blob.__init__(self, width, height, color, emphasis, highlight)

Pomijam to, że długą listę warunków powinno zastępować się jedną (lub kilkoma) metodą zwracającą true/false.
Na pierwszy rzut oka - który fragment kodu jest najbardziej przejrzysty?

2

LOL widzę, że dyskusja stała się absurdalnie debilna, bo inaczej tego nie potrafię określić. Napisałem wyraźnie "może programiści C/C++ powinni zacząć się po prostu stosować do jakiś sprawdzonych reguł w stylu pep8". PEP8 to jest przykład, a nie jedyna oświecona prawda.

PEP8 to jest konwencja, macie inną, wolicie ustalić limit na 100, 200, 500 znaków proszę bardzo, napisałem wyraźnie Nikt Wam nie każe ograniczać się do 80 znaków. Podejrzewam, że programujecie pod Windowsem, a nie w konsoli linuxowej, macie pierdyliard monitorów i nie potrzebujecie pracować z kilkoma dokumentami otworzonymi obok siebie. Sorry ale ja mam lapka z rozdziałką 1366x768, nie będę kupować specjalnie monitora żeby pracować z Waszym kodem, z resztą nie zabiorę go na plażę, a lapka mogę.

Nie rozumiecie podstawowej rzeczy. Żadna konwencja nie jest lepsza od innej, ale warto stosować do jakiejś się w tym samym zespole, a nawet w ogóle (open source).

0

Nie mieszajmy tu różnych języków bo do niczego to nie doprowadzi.
W kodzie ze strony pierwszej widać fascynację językiem Lisp. Z tym że C to trochę inny język.

Czy Python ma wskaźniki? Czy Python ma wyniki funkcji zwracane przez argumenty wyjściowe? (termin "side effects").

Rozmawiajmy o C.

0
Adam Borowski napisał(a):

Nie rozumiecie podstawowej rzeczy. Żadna konwencja nie jest lepsza od innej, ale warto stosować do jakiejś się w tym samym zespole, a nawet w ogóle (open source).

Owszem, rozumiemy. Oednak są konwencje, które są gorsze, bo są nieczytelne dla innych - patrz konwencja konsekwentnie stosowana przez Dragona.

0
vpiotr napisał(a):

Czy Python ma wskaźniki?

Tak, brak wskaźników w Pythonie to zdecydowanie jest wada. W ogóle programiści Pythona to nie programiści, tylko dzieci neostrady 20 lat później. Ich zasady są śmieszne, lepiej nie trzymać się żadnych odgórnie ustalonych zasad, przekonywać, że wszelkie zasady są złe w końcu mamy XXI wiek, pierdyliard monitorów i jesteśmy zajebiści. Lepiej mędrkować na forum i robić nagonkę na kolesia, bo zadanie algorytmiczne zapisał krótko i zwięźle. "Styl 13D" rozwaliło mnie to...

Chłopaki naprawdę lepiej byłoby rozmawiać o konwencjach w ogólności, a nie robić nagonkę na Dragona. Podać kod, bez podawania nicku. Nie wiem czy ktoś z Was chciałby się znaleźć w jego skórze.

5

Adam, o czym Ty z nami rozmawiasz. Nie czytasz odpowiedzi, nie odnosisz się do argumentów, pozwalasz sobie na osobiste wycieczki, a - tu moja osobista wycieczka, bo już nie zdzierżę - Twoja gruntowna wiedza nt. programowania to zero postów w działach technicznych przez pierwsze trzy strony wyników, a na czwartej jeden kierujący pytającego do pluralsight'a, który jest płatny. Reszta to w większości flame i offtopic. Jesteś trollem. Idź sobie stąd.

0

Mam pisac w dzialach technicznych, zeby ktos urzadzal nagonke na moj styl kodowania i tworzyl watki na ten temat? Wasze niedoczekanie.

0

To co się z tym forum porobiło to jest całkowita porażka. Inaczej tego nazwać nie mogę.

Flame'ujecie @_13th_Dragon, a większość z was zajmuje się tutaj tłumaczeniem jego kodu dla innych. Brawo.

1

Piszcie jak chcecie, ważne żeby kod spełniał proste warunki:

  1. Dowolne formatowanie, ale takie same w całym projekcie
  2. Kod ma być łatwy w czytaniu (jeśli jednolinijkowiec jest łatwiejszy w czytaniu to może być)

Generalnie więcej czasu spędza się na czytaniu kodu niż na jego pisaniu, więc czytelny kod to sama zaleta. (na spoju może się aż tak często nie czyta, ale jak zawodowo piszesz to z reguły tak jest)

0

Myślę że można już zamknąć ten temat - o ile jest tu taka funkcja.

Podsumowując:

  • nie ma żadnych merytorycznych powodów żeby komuś utrudniać życie zamieniając kolejność warunków, usuwając "zbędne" spacje i końce linii lub skracając nazwy zmiennych.
    Można się spierać o liczbę znaków w linii (80 czy 130 czy 444), wielkość liter, klamerki, komentarze, ale są pewne niezmienne zasady w programowaniu.
    Jak ktoś tego nie czuje, to powinien przeczytać "how to write unmaintable code" z thc.org i tego NIE STOSOWAĆ (patrz L o n g L i n e s).

I proszę, nie wciskajcie ludziom kitu, że jeśli program wygląda jak z IOCCC ale działa dobrze to powinniśmy dziękować autorowi że go udostępnia.
Można tak napisać dla jaj lub z nudów - zgoda. Ale pls nie w kodzie produkcyjnym czy nawet edukacyjnym.

1 użytkowników online, w tym zalogowanych: 0, gości: 1