Utwórz najkrótszy program, który pobiera dwie liczby całkowite ze znakiem jako dane wejściowe (przez standardowe lub jako argumenty) i wyświetla 3 różne dane wyjściowe w zależności od tego, czy pierwsza liczba jest (1) większa niż, (2) mniejsza niż, czy (3) równa drugiej numer.
The Catch
W swoim programie nie możesz używać żadnego z poniższych:
- Standardowe operatory porównania:
<
,>
,<=
,>=
,==
,!=
. - Każdy plik biblioteki oprócz
conio
,stdio
lubiostream
. - Dowolny znak ASCII inny niż ASCII lub niedrukowalny.
Zwycięzca
Program z najmniejszą liczbą znaków wygrywa.
abs
bez dołączania pliku biblioteki (ponieważ kompilator i tak to wie) również nie jest dozwolone?Odpowiedzi:
53 bajty
Istotny jest tylko pierwszy znak wyniku. Trzy różne wyjścia to:
Działa dla pełnego zakresu wejściowego int na wszystkich platformach, na których sizeof (long)> sizeof (int).
Edycja: kosztuje jeden dodatkowy znak, aby przypadek 3 wydrukował jednoznacznie „+” zamiast:
źródło
Może brakuje mi czegoś w przepisach, ale ...
81 bajtów
Ouputs
00
jeślia > b
,-10
jeślia == b
i-1-1
jeślia < b
.źródło
long long
może mieć więcej niż 64 bity,int
może być tak duży, że możesz się przepełnić, wynikiem przesunięcia w prawo wartości ujemnych jest zdefiniowana implementacja. Prawie wszystkie odpowiedzi pochodzące od C mają podobne problemy.sizeof
.90 bajtów
Jeśli możemy użyć
stdio
, dlaczego nie skorzystać z jego możliwości formatowania w celu przeprowadzenia porównania?Zakłada kodowanie kompatybilne z ASCII i małą trwałość.
72 bajty
Ilości są zaokrąglane w kierunku zera, ale przesunięcia w prawo są (w praktyce) „zaokrąglane w dół”. To martwa gratka.
6579 bajtówInną wyróżniającą właściwością liczb ujemnych jest to, że wytwarzają one ujemne modulo. Ten w ogóle nie zależy od reprezentacji liczb całkowitych; działa nawet na moim 8-bitowym tosterze z nadmiarem 127! Aha, a skoro możemy użyć
conio
, dlaczego nie zapisać dwóch bajtówputch
? Teraz gdybym tylko mógł znaleźć swoją kopię TurboC ...EDYCJA : Obsługa dużych różnic przy założeniu, że
long long
jest szersza niżint
.źródło
%d
w swoim,scanf
aby jednoznacznie przeanalizować dwie liczby całkowite. Fajny pomysł!a = 1, b = 23
ia = 12, b = 3
. Czy123
w obu przypadkach nie musiałbyś używać STDIN?1 23
i12 3
jako).6461 znakówWyświetla wartości znaków -1, 0 i 1 odpowiednio dla wartości mniejszej, równej lub większej niż.
Ta implementacja opiera się na nieokreślonym zachowaniu dla
b
bycia typuint
i dla danych wejściowych spoza zakresuINT_MIN / 2
doINT_MAX / 2
. Na platformach, na których podpisuje się przepełnienie, niezależnie od tego, czy uzupełnienie 2s (w zasadzie wszystkie z nich), czy wielkość znaku, zawiedzie w przypadku 25% możliwych par prawidłowychint
. Co ciekawe (w każdym razie dla mnie), będzie działać poprawnie na platformach, na których nasycony jest przepełniony podpis.źródło
a-b
przepełni.-(2^14)
i2^14 - 1
na wszystkich platformach zgodnych i prawdopodobnie będzie działać dla znacznie większego zakresu na większości platform. Wszystkie pozostałe odpowiedzi w tym momencie przyjmują założenia dotyczące wielkości typu, względnych rozmiarów typów lub reprezentacji.main(a,b)
jest już niezdefiniowanym zachowaniem, więc żadna z odpowiedzi nie będzie działać. Przenośność nie ma znaczenia.5954 znaków54 znaków z kompilatorem takim jak gcc, który nie dręczy
main(x,y)
:59 znaków inaczej:
Wynik:
źródło
main(x,y)
działa w gcc, więc możesz upuścić te 5 bajtów z liczby postaci.66102 bajtówOdczytuje liczby całkowite ze STDIN i drukuje
0
(a <b),1
(a> b) lub2
(a == b).Edycja: Teraz powinno także działać w przypadku różnic, które są zbyt duże, aby zmieściły się w 32-bitowej liczbie całkowitej. Jestem pewien, że zagnieżdżone trójskładniki można skrócić za pomocą nieco więcej magii.
źródło
52 bajty
Niestety ten działa tylko dla dodatnich liczb całkowitych, ale pomyślałem, że koncepcja użycia operatorów czysto arytmetycznych była interesująca:
Wyjścia:
źródło
putchar(a/b-b/a)
jest o wiele krótszy.66 bajtów
Drukuje bajt 0x00 if
a == b
, 0x01 ifa < b
i 0xff ifa > b
.Ponieważ znak ASCII inny niż ASCII lub niedrukowalny w programie [my] i jeśli coś nie jest wyraźnie zabronione w pytaniu, jest to dozwolone , znak niezadrukowany na wydruku powinien być całkowicie w porządku.
źródło
long
jest 64-bitowy.87 znaków
Używanie sztuczki 2 ^ 31 do konwersji na niepodpisane int
Przesyłanie podziału do niepodpisanego, aby obsługiwać górny bit jako dane, a nie podpisywać
Użycie ^ do XOR a i b, gdy są równe, zwraca 0
Używanie zagnieżdżonych instrukcji warunkowych (?) W celu uzyskania „<”, „>” lub „=” w celu przesłania do puts ()
źródło
71 bajtów
http://ideone.com/uvXm6c
źródło
z=x-y
i jestem pewien, że są one konieczne. Możesz także zapisać dwa znaki, używając49,
50` i51
bezpośrednio, zamiast dodawać48
.-2000000000 2000000000
, podobnie jak w przypadku innych kombinacji liczb całkowitych, które powodują przepełnienie odejmowania.68 znaków
Umieszcza znak ASCII 1, 2 lub 3 odpowiednio na wartość mniejszą, większą lub równą.
źródło
a-b
przepełni.8889 bajtówZaczyna się to od dodania
1<<31
(INT_MIN
) do a i b, tak że 0 odpowiada terazINT_MIN
. Następnie zapętla i dekrementuje a i b co każdą pętlę, aż albo wyniesie 0, a następnie drukuje 0, 1 lub 2 w zależności od tego, czy a, b lub oba mają wartość 0.120119 bajtówNie jest to najkrótsze rozwiązanie, ale może być nieco bardziej golfa od lepszego golfisty niż ja. (Lub tylko ludzie z większą wiedzą o C niż ja)
Chodzi o to, aby zamaskować każdy bit, zaczynając od lewego i sprawdzając nierówność. Reszta powinna się wyjaśnić. Ponieważ liczby ujemne zaczynają się od 1 bitu, najpierw odwracam pierwszy bit za pomocą
a^=1<<31
.źródło
;)
buźka powinna być smutną);
buźką. 2.a&b
tylko sprawdza, czya
ib
mają bitów wspólnych; trzeba&&
.Myślę, że nawet nie zamierzam pisać krótkiego kodu. Spróbuję wykonać to porównanie w sposób przenośny zgodnie ze specyfikacją C99.
Operator modulo zachowuje znak, ale może również generować zero (w tym zero ujemne), więc upewniamy się, że mamy zarówno nieparzystą, jak i parzystą wartość do sprawdzenia (nawet nie wiedząc, czy używamy tych uzupełnień). Operacje arytmetyczne mogą się przepełniać, ale bitowe nie ulegną przepełnieniu, a upewniając się, że zarówno bity są ustawione, jak i wyczyszczone, unikamy przypadkowego przekształcenia naszej liczby w ujemne zero lub pułapkę. Fakt, że dwie operacje są do tego dziwne, nie powinien mieć znaczenia, ponieważ możliwa reprezentacja pułapki nie powoduje niezdefiniowanego zachowania, dopóki nie zostanie ustawiona w wartości. Wykonanie operacji z przełączonym bitem 0 gwarantuje, że otrzymamy dokładnie jedną resztę niezerową. Uzbrojeni w znajomość obu znaków możemy zdecydować, jak kontynuować porównanie.
Ta metoda może być jedną z niewielu, które pozwalają na wyodrębnienie znaku liczby całkowitej ujemnego zera. Rozwiązujemy ten problem, wyraźnie sprawdzając zero. Gdybyśmy naprawdę grali w golfa, moglibyśmy oczywiście pozwolić na porównanie dwóch zer, aby również wykonać odejmowanie.
źródło
C 80 znaków
Drukuje „<”, „>” lub „=”, tak jak powinno.
C 63 znaków
Nowe podejście:
Drukuje „1”, „2” lub „3”.
źródło
W 64 znakach bez stdio.h
a,b;main(){scanf("%d%d",&a,&b);puts((a-b)>>31?"<":a^b?">":"=");}
wypisuje „>” jeśli a> b, „<” jeśli a <b, „=” jeśli a == b int przepełnienie jest UB. Tylko nie przepełnij.
źródło