Wyprowadzić znak

67

Biorąc pod uwagę liczbę N, wypisz znak N:

  • Jeśli N jest dodatnie, wyjście 1
  • Jeśli N jest ujemne, wyjście -1
  • Jeśli N wynosi 0, wyjście 0

N będzie liczbą całkowitą w reprezentatywnym zakresie liczb całkowitych w wybranym języku.

Mego
źródło
45
Jest to trywialne wyzwanie z wieloma trywialnymi rozwiązaniami. Istnieją jednak również pewne nietrywialne rozwiązania. Do wyborców: Proszę przeczytać pierwsze zdanie tego meta postu przed aktualizacją wbudowanych funkcji.
Stewie Griffin,
8
Prawdopodobnie przydałoby się to w tabeli wyników.
Martin Ender,
2
@MrLister głosuj, jak chcesz, ale naprawdę powinieneś szukać kreatywności zamiast długości kodu.
FlipTack,
3
@FlipTack Oh, myślałem, że to codegolf.
Pan Lister,
3
@MrLister to kryterium obiektywnego zwycięstwa. ale czy naprawdę potrzeba więcej wysiłku, aby wpisać swbudowany znak, lub użyć sprytnych przesunięć bitowych / matematyki, aby je wypracować? Spójrz na ten meta post
FlipTack

Odpowiedzi:

46

Siatkówka , 9 bajtów

[1-9].*
1

Wypróbuj online!

Zamienia niezerową cyfrę i wszystko po niej na 1. Pozostawia to potencjalną wiodącą -nienaruszoną i zmienia wszystkie liczby oprócz 0siebie na wartość bezwzględną 1.

Martin Ender
źródło
To bardzo sprytne :)
Mego
Czy działa z naukowym zapisem liczb całkowitych (np. 0.42e2)?
Egor Skriptunoff
@EgorSkriptunoff Nie, ale nie jest to wymagane.
Martin Ender
9
@EgorSkriptunoff nie obsługuje też cyfr rzymskich. O ile wyzwanie nie zawiera wyraźnego wzmianki o pewnym niestandardowym formacie, który musi być obsługiwany, ogólne założenie jest takie, że dobrze jest poradzić sobie z jednym formatem, który jest naturalny w wybranym języku.
Martin Ender,
3
@EgorSkriptunoff Retina nie ma żadnego pojęcia liczb. Jest to język oparty wyłącznie na łańcuchach znaków.
Martin Ender,
42

C (GCC), 24 23 22 18 bajtów

Dzięki @aross i @Steadybox za uratowanie bajtu!

f(n){n=!!n|n>>31;}

Nie gwarantuje się działania na wszystkich systemach lub kompilatorach, działa na TIO .

betseg
źródło
7
@betseg Wynika to z tego, że opinie na temat wbudowanych elementów są teraz niezadowolone.
Erik the Outgolfer,
4
Oszczędzając 1 bajt z tymreturn n>>16|!!n;
aross
5
@ GB Rozmiar int to prawdopodobnie 2 (16, x86) lub 4 (32, x86_64), ale pamiętaj, wszystko czego potrzebujesz to architektura, na której jest poprawny. To nie jest przepełnienie stosu, przenośność nie jest ważna.
kot
2
f(n){n=n>>31|!!n;}też działa. Ale to tylko dziwactwo kompilatora, a nie funkcja języka.
GB
2
Dziwactwa kompilatora @GB są całkowicie poprawne, o ile można udowodnić, że istnieje kompilator, w którym działa dziwactwo. Na szczęście gcc ma dziwactwo.
Mego
34

Mathematica, 4 bajty

Clip

Co powiesz na nieużywanie wbudowanego Signi nadal ocenianie 4 bajtów? ;)

Clipz pojedynczym argumentem przycina (lub zaciska) wartość wejściową pomiędzy -1i 1. Ponieważ dane wejściowe będą tylko liczbami całkowitymi, jest to to samo, co użycie Sign.

Martin Ender
źródło
29

COW, 225 213 201 bajtów

oomMOOmoOmoOmoOmoOMoOMoOmOomOomOoMoOMMMmoOMMMMOOMOomOo
mOoMOomoOmoOmoomOomOoMMMmoOmoOmoOMMMMOOOOOmoOMOoMOomOo
mOomOoMoOMMMmoOMMMMOOMOomOomOoMoOmoOmoOmoomoOmoomOomOo
mOomoomoOMOOmoOmoOmoOMOoMMMOOOmooMMMOOM

Wypróbuj online!

Ten kod działa w ten sposób, że określa znak, naprzemiennie dodając i odejmując większe liczby i sprawdzając, który z nich działał jako ostatni. Biorąc pod uwagę dowolną niezerową liczbę całkowitą, najpierw odejmij 1, następnie dodaj 2, a następnie odejmij 3, itd., A ostatecznie osiągniesz 0. Śledź swój stan, naprzemiennie dodając i odejmując 2 od wartości zaczynającej się od 0. Dla przykład:

-5  - 1  = -6  (current state: 0 + 2 = 2)
-6  + 2  = -4  (current state: 2 - 2 = 0)
-4  - 3  = -7  (current state: 0 + 2 = 2)
-7  + 4  = -3  (current state: 2 - 2 = 0)
-3  - 5  = -8  (current state: 0 + 2 = 2)
-8  + 6  = -2  (current state: 2 - 2 = 0)
-2  - 7  = -9  (current state: 0 + 2 = 2)
-9  + 8  = -1  (current state: 2 - 2 = 0)
-1  - 9  = -10 (current state: 0 + 2 = 2)
-10 + 10 =  0  (current state: 2 - 2 = 0)
value is now at 0.  state - 1 = 0 - 1 = -1
sign of original number is -1

Kiedy skończysz, odejmij 1 od swojego stanu, a otrzymasz znak, dodatni lub ujemny. Jeśli oryginalny numer to 0, nie zawracaj sobie tym głowy i po prostu wydrukuj 0.

Szczegółowe wyjaśnienie:

oom                                        ;Read an integer into [0]
MOO                                        ;Loop while [0] is non-empty
    moOmoOmoOmoOMoOMoOmOomOomOo            ;    Decrement [4] twice
    MoOMMMmoOMMM                           ;    Increment [1], then copy [1] to [2]
    MOO                                    ;    Loop while [2] is non-empty
        MOomOomOoMOomoOmoO                 ;        Decrement [0] and [2]
    moo                                    ;    End loop now that [2] is empty
    mOomOoMMMmoOmoOmoOMMM                  ;    Navigate to [0], and copy to [3]
    MOO                                    ;    Perform the next steps only if [3] is non-zero
        OOOmoOMOoMOomOomOomOoMoOMMMmoOMMM  ;        Clear [3], increment [4] twice, increment [1], and copy it to [2]
        MOO                                ;        Loop while [2] is non-empty
            MOomOomOoMoOmoOmoO             ;            Decrement [2] and increment [0]
        moo                                ;        End loop now that [2] is empty
    moO                                    ;        Navigate back to [3]
    moo                                    ;    End the condition
    mOomOomOo                              ;    Navigate back to [0]
moo                                        ;End loop once [0] is empty.
moO                                        ;Navigate to [1]. If [1] is 0, then input was 0.  Otherwise, [4] contains (sign of [0] + 1)
MOO                                        ;Perform the next steps only if [1] is non-zero
    moOmoOmoOMOoMMMOOO                     ;    Navigate to [4], copy it to the register, and clear [4].
moo                                        ;End condition
MMMOOM                                     ;If the register contains something (which is true iff the condition ran), paste it and print it.  Otherwise, no-op and print 0.

Wciąż eksperymentuję z golfem (będziesz zszokowany, gdy odkryjesz, że gra w golfa na COW jest raczej trudna), więc może to oznaczać kilka kolejnych bajtów w przyszłości.

Gabriel Benamy
źródło
1
I jest „muczenie” - język? ...
Mukul Kumar
1
@MukulKumar To pochodna pieprzenia mózgu o nazwie COW, która pozwala na kilka rzeczy, których bf nie robi
Gabriel Benamy,
Można to nazwać językiem „złego maga”. OUT OF MANA!!!
Magic Octopus Urn
18

Cubix , 10 bajtów

(W0^I?>O2@

Przetestuj online!

Ten kod jest zawinięty w następującą kostkę netto:

    ( W
    0 ^
I ? > O 2 @ . .
. . . . . . . .
    . .
    . .

Kod jest następnie uruchamiany z adresem IP (wskaźnikiem instrukcji) rozpoczynającym się od I, skierowanym na wschód. Iwprowadza podpisaną liczbę całkowitą ze STDIN, wypychając ją na stos.

Następnym poleceniem jest ?zmiana kierunku adresu IP w zależności od znaku najwyższego elementu. Jeśli wejście ma wartość 0, porusza się w tym samym kierunku, przechodząc przez następujący kod:

  • >- Skieruj adres IP na wschód. (Brak operacji, ponieważ już jedziemy na wschód.)
  • O - Wypisuje najwyższy element jako liczbę całkowitą.
  • 2- Wciśnij 2 na stos. Jest to praktycznie brak możliwości, ponieważ ...
  • @ - Kończy program.

Jeśli sygnał wejściowy jest ujemny, IP skręca w lewo na ?; ponieważ jest to sześcian, IP przenosi się 0do drugiego rzędu, kierując się na wschód. 0wypycha literał 0, a następnie uruchamiany jest ten kod:

  • ^ - Skieruj adres IP na północ.
  • W - „Sidepep” IP jeden punkt w lewo.
  • ( - Zmniejszenie najwyższej pozycji.

TOS jest teraz -1, a IP owija się wokół kostki przez szereg no-ops, .dopóki nie trafi >. Uruchamia to ten sam kod wyjściowy, o którym mowa powyżej, generując -1.

Jeśli dane wejściowe są dodatnie, dzieje się to samo, co w przypadku danych wejściowych ujemnych, z jednym wyjątkiem: adres IP skręca w prawo zamiast w lewo ?i owija się wokół kostki 2, co wypycha literał 2. To jest następnie zmniejszane do 1 i wysłane do wyjścia.

ETHprodukcje
źródło
4
Animacja przebiegu programu jest bardzo ładna!
Luis Mendo,
Fajny język. Czy może być krótszy? 4 sterowanie przepływem wydaje się dużo. W liczeniu operacji może to być 8 bajtów po wprowadzeniu kolejnego ?, ale teraz wykorzystuje dolną połowę sześcianu: ..1nI? ..> O @ .........?
BlackShift,
Sześć jest możliwe, jeśli zignorujemy dane wyjściowe po pierwszym: / I? NO1 Nawiasem mówiąc, działa to tylko dlatego, że zwracam -1 w tłumaczeniu online zamiast 0 zgodnie ze specyfikacją.
BlackShift,
@BlackShift Dziękujemy za zainteresowanie! Lubię twoje sugestie, ale nie jestem pewien, jak je poprawić. Zdecydowanie można użyć mniej instrukcji; trudna część zużywa mniej kostki ... ;-) A dzięki za wskazanie tego błędu -1, wkrótce go naprawię.
ETHproductions
@ETHproductions IMO To nie jest błąd, warto Izwracać -1, gdy dane wejściowe kończą się tak jak małe litery i.
FlipTack,
16

JavaScript (ES6), 9 bajtów

Math.sign

Bezpośredni.

Najkrótszy wbudowany to 13 bajtów:

n=>n>0|-(n<0)

Dzięki @Neil można zagrać w bajt, ale kosztem pracy tylko na 32-bitowych liczbach całkowitych:

n=>n>0|n>>31

Lub możesz to zrobić

n=>n>0?1:!n-1

co wydaje się bardziej grywalne, ale nie jestem pewien jak.

ETHprodukcje
źródło
2
Dla wbudowanego w 12 bajtów dla 32-bitowej liczby całkowitej n: n=>n>>31|!!n.
Neil,
@Neil n>>31jest naprawdę sprytny, dzięki!
ETHproductions
Nie sądzę, aby trzecie rozwiązanie było prawidłowe, ponieważ JavaScript używa liczb zmiennoprzecinkowych podwójnej precyzji. Ale mogę się mylić.
Mego
@Mego Masz rację. Wyjaśniłem to w poście.
ETHproductions
1
@Mego Przepraszam, przegapiłem twój komentarz. Podczas korzystania z operatorów bitowych JS domyślnie rzuca operandami na 32-bitowe liczby całkowite ze znakiem, więc trzecie rozwiązanie działa, ale tylko na liczbach od -2147483648 do 2147483647.
ETHproductions
15

APL (Dyalog APL) , 1 bajt

Działa również dla liczb zespolonych, zwracając 1∠ θ :

×

Wypróbuj APL online!


Bez tego wbudowanego dla liczb całkowitych (zgodnie z OP):

¯11⌊⊢

¯1⌈ największy z negatywnych i

1⌊ najmniejszy z nich i

argument

Wypróbuj APL online!

... i ogólny:

>∘0-<∘0

>∘0 więcej niż zero

- minus

<∘0 mniej niż zero

Wypróbuj APL online!

Adám
źródło
1
Zrobiłeś to w JEDNYM bajcie ... Proszę pana, jesteś legendą. Jestem pewien, że Jon Skeet byłby dumny.
@Mango Żartujesz, prawda? Istnieje kilka jednobajtowych odpowiedzi na to wyzwanie.
Adám
1
Byłem sarkastyczny, powiedziałem to również, ponieważ jest to pierwsza jednobajtowa odpowiedź, jaką zobaczyłem.
14

> <> , 9 8 bajtów

Dzięki Sp3000 za zapisanie bajtu.

'i$-%n/

Tam jest niecenzuralny 0x01przed /.

Wypróbuj online!

Wyjaśnienie

To jest port mojej odpowiedzi na Labirynt oparty na kodzie postaci .

'     Push the entire program (except ' itself) onto the stack, which ends 
      with [... 1 47].
i     Read the first character of the input.
$-    Subtract the 47.
%     Take the 1 modulo this value.
n     Output the result as an integer.
0x01  Unknown command, terminates the program.
Martin Ender
źródło
Myślę, że możesz po prostu użyć legalnego ;zamiast tego niedrukowalnego, 0x01aby poprawnie zakończyć program :)
Erik Outgolfer
@EriktheOutgolfer Muszę mimo 0x01to naciskać 1.
Martin Ender
2
Och, wygląda na to, że przetestowałem tylko moją sugestię 123. Wyciągnięta lekcja: test z większą liczbą przypadków.
Erik the Outgolfer
14

Vim, 22 bajty

xVp:s/-/-1^M:s/[1-9]/1^M

Oszczędność jednego bajtu dzięki @DJMcMayhem !

Oto ^Mdosłowna nowa linia.

Jak zauważył @ nmjcman101 w komentarzach, :s/\v(-)=[^0].*/\11^Mzamiast tego można użyć pojedynczego wyrażenia regularnego ( 20 bajtów), ale ponieważ jest to w zasadzie to samo, co odpowiedź Retina, trzymam się własnej metody.

Wyjaśnienie:

xVp                        Delete everything except the first character. If the number is negative, this leaves a -, a positive leaves any number between 1 and 9, and 0 leaves 0.
   :s/-/-1^M               Replace a - with a -1
            :s/[1-9]/1^M   Replace any number between 1 and 9 with 1.

Oto jego gif z liczbą ujemną (stara wersja):

Bieg z ujemnym

Oto działa z 0:

Bieg z zerem

Bieganie z pozytywem:

Bieganie z pozytywem

Loovjo
źródło
1
Naprawdę podoba mi się twoja metoda, ale jest to możliwe w jednym wyrażeniu regularnym::s/\v(-)=[^0].*/\11
nmjcman101
GIFy z konsolą Dithered ... ??
Desty
12

///, 52 36 bajtów

/a/\/1\/\///2a3a4a5a6a7a8a9a10a11/1/

Niegolfowane, wyjaśnienie:

/2/1/
/3/1/
/4/1/
/5/1/
/6/1/
/7/1/
/8/1/
/9/1/
/10/1/
/11/1/

Jest to w zasadzie implementacja MapReduce, tzn. Są dwie fazy:

  • Zastąp wszystkie wystąpienia cyfr 2- 9przez 1, np. 1230405->1110101
  • Zmniejsz pary 11lub, 10aby 1wielokrotnie, np. 1110101->1

Jeśli na początku był -front, pozostanie on i wynik będzie -1. Singiel 0nigdy nie jest zastępowany, a zatem sam w sobie.

Aktualizacja: Zaoszczędź dodatkowe 16 bajtów, aliasing //1/z a, dzięki Martinowi Enderowi.

Wypróbuj online z testami

Cedric Reichenbach
źródło
2
To jest bardzo sprytne!
Mego
11

Python 2 , 17 bajtów

lambda n:cmp(n,0)

Wypróbuj online!

Dennis
źródło
5
Och, ty ninja mnie.
Jonathan Allan,
1
Ups Przepraszam ...
Dennis,
5
Szkoda, że ​​nie możesz zrobić (0).__rcmp__...
Sp3000
1
Możesz to zrobić -(0).__cmp__.
nyuszika7h,
1
@ nyuszika7h Niezupełnie. Próbuje użyć go jako funkcja podnosi TypeError .
Dennis,
11

Labirynt , 10 bajtów

?:+:)%:(%!

Wypróbuj online!

Wyjaśnienie

Semantyka sterowania przepływem Labiryntu faktycznie daje „wolny” sposób na określenie znaku liczby, ponieważ wybrana ścieżka w rozwidleniu 3-kierunkowym zależy od tego, czy znak jest ujemny, zero czy dodatni. Jednak do tej pory nie byłem w stanie dopasować programu ze złączami do mniej niż 12 bajtów (chociaż może być to możliwe).

Zamiast tego oto rozwiązanie w formie zamkniętej, które nie wymaga żadnych oddziałów:

Code    Comment             Example -5      Example 0       Example 5
?       Read input.         [-5]            [0]             [5]
:+      Double.             [-10]           [0]             [10]
:)      Copy, increment.    [-10 -9]        [0 1]           [10 11]
%       Modulo.             [-1]            [0]             [10]
:(      Copy, decrement.    [-1 -2]         [0 -1]          [10 9]
%       Modulo.             [-1]            [0]             [1]
!       Print.              []              []              []

Wskaźnik instrukcji następnie uderza w ślepy zaułek, odwraca się i kończy, gdy %teraz próbuje podzielić przez zero.

Podwojenie wejście jest konieczne, aby tę pracę z wejściami 1i -1, poza jednym z dwóch operacji modulo będzie już próba dzielenia przez zero.

Martin Ender
źródło
1
Twój kod jest szczęśliwy i zasmuca:D
Stefan
2
@Stefan Możesz zmienić kolejność, jeśli wolisz. ;)
Martin Ender,
9

PHP, 16 bajtów

Korzysta z nowego operatora statku kosmicznego.

<?=$argv[1]<=>0;
Alex Howansky
źródło
Nie zapomnij wspomnieć, że jest to tylko odpowiedź PHP7. A ponieważ używasz <?=, powinieneś użyć $_GET[n], który nie zajmuje więcej bajtów. Aby użyć <?=, musisz być w serwerze internetowym (takim jak Apache) i tam nie będziesz mieć dostępu $argv. Możesz spróbować uruchomić <?php var_dump($argv);z pliku PHP, dostępnego przez Apache, i to pokaże NULL.
Ismael Miguel
1
„Aby użyć <? =, Musisz być w serwerze internetowym (takim jak Apache)”. Nie. <?=Operator działa dobrze z linii poleceń.
Alex Howansky
Biegam php -r '<?=1', rozumiem PHP Parse error: syntax error, unexpected '<' in Command line code on line 1. Ale wydaje się, że działa dobrze z pliku. Chyba masz racje.
Ismael Miguel
-rFlaga jest uruchomienie fragmentu kodu. To jest kompletne źródło. Zapisz go do pliku, a następnie uruchomphp file.php
Alex Howansky
Już to rozgryzłem. Naprawdę nie wiedziałem, że to działa z pliku, używając parametru (niejawnego) -f.
Ismael Miguel,
9

Brain-Flak 74 42 40 Bytes

Zaoszczędzono 2 bajty dzięki 1000000000

{([({}<([()])>)]<>(())){({}())<>}}{}({})

Wypróbuj online!

Wyjaśnienie:

{                                }       # if 0 do nothing
   (          )                          # push:                           
    {}<     >                            # the input, after 
       (    )                            # pushing:
        [  ]                             # negative:
         ()                              # 1

 (                    )                  # Then push:
  [            ]                         # the negative of the input
                <>                       # on the other stack with:
                   ()                    # a 1 
                  (  )                   # pushed under it

                       {        }        # while 1: 
                        ({}())           # increment this stack and...
                              <>         # switch stacks

                                 {}      # pop the top (the counter or 0 from input)
                                   (  )  # push:
                                    {}   # the top (this is a no-op, or pushes a 0)
Riley
źródło
Możesz zapisać 2 bajty, usuwając monadę zero wokół(())
0
8

C, 24 20 19 18 bajtów

Nadużywam dwóch exploitów C do gry w golfa; To jest w C (GCC).

f(a){a=a>0?:-!!a;}

Wypróbuj online!


Historia zmian:

1) f(a){return(a>0)-(a<0);}// 24 bajty

2) f(a){a=(a>0)-(a<0);}// 20 bajtów

3) f(a){a=a>0?:-1+!a;}// 19 bajtów

4) f(a){a=a>0?:-!!a;}// 18 bajtów


Wersja 1: Pierwsza próba. Prosta logika

Wersja 2: Nadużywa błąd pamięci / stosu w GCC, gdzie, o ile mogę stwierdzić, funkcja nie zwracająca zwraca w niektórych przypadkach ostatnią ustawioną zmienną.

Wersja 3: Nadużywa zachowania trójskładnikowego, w którym niezdefiniowany wynik zwróci wynik warunkowy (dlatego prawdziwy zwrot z trójki jest zerowy)

Wersja 4: Odejmij wartość bool cast ( !!) od trójskładnikowego podstawienia warunkowego dla nilodniesienia w wersji 2.

Albert Renshaw
źródło
7

Rubinowy, 10 bajtów

->x{x<=>0}
GB
źródło
Czy 0.<=>również działałoby, czy nie możesz odwoływać się do takich metod w Ruby?
Nic Hartley,
.<=>oczekuje 1 argumentu, więc skończy się na 0.<=> xdłuższym.
Wygląda na
@QPaysTaxes, których potrzebujesz, 0.method:<=>ponieważ wywołania metod w Rubim nie używają nawiasów i 0.<=>będą interpretowane jako wywołanie metody ze zbyt małą liczbą argumentów.
Cyoce
7

Perl, 9 bajtów

Wymaga -Ebez dodatkowych kosztów.

say<><=>0

Stosowanie

perl -E 'say<><=>0' <<< -9999
-1
perl -E 'say<><=>0' <<< 9999
1
perl -E 'say<><=>0' <<< -0
0

Jestem szczęśliwy z operatorem ryb!

Dom Hastings
źródło
1
To tak naprawdę „nie wymaga” -E, tylko wtedy, gdy wywołujesz go z CLI zamiast z pliku, i dlatego sądzę, że powiedziałeś bez dodatkowych kosztów.
nyuszika7h,
@ nyuszika7h rzeczywiście wymaga, jak sądzę, sposobu, w jaki testowanie przez -enie będzie działać, ale -Ejest akceptowane jako nie dłużej niż -e. Zgodnie z konsensusem w sprawie meta. Mam nadzieję, że to trochę pomoże!
Dom Hastings,
Tak, nie sugerowałem, że wymagałoby to dodatkowych kosztów, ponieważ działa dobrze, gdy ten skrypt jest normalnie wykonywany z pliku.
nyuszika7h,
7

Koty stosu , 6 + 4 = 10 bajtów

_[:I!:

+4 bajty dla ​ -nmflag. nsłuży do numerycznego we / wy, a ponieważ Stack Cats wymaga, aby programy były palindromiczne, mniejawnie odzwierciedla kod źródłowy, aby podać oryginalne źródło

_[:I!:!I:]_

Wypróbuj online! Podobnie jak w przypadku wszystkich dobrych golfów Stack Cats, został on znaleziony brutalną siłą, pokonał wszelkie ręczne próby długim strzałem i nie można go łatwo włączyć do większego programu.

Dodaj Dflagę, jeśli chcesz zobaczyć śledzenie programu krok po kroku, tj. -nmDUruchom i sprawdź STDERR / debug.


Stack Cats używa taśmy stosów, które są domyślnie wypełnione zerami na dole. Na początku programu wszystkie dane wejściowe są wypychane na stos wejściowy, z -1podstawą u, aby oddzielić dane wejściowe od niejawnych zer. Na końcu programu generowany jest bieżący stos, z wyjątkiem bazy, -1jeśli jest obecny.

Odpowiednie polecenia tutaj to:

_           Perform subtraction [... y x] -> [... y y-x], where x is top of stack
[           Move left one stack, taking top of stack with you
]           Move right one stack, taking top of stack with you
:           Swap top two of stack
I           Perform [ if top is negative, ] if positive or don't move if zero. Then
                negate the top of stack.
!           Bitwise negate top of stack (n -> -n-1)

Zauważ, że wszystkie te polecenia są odwracalne, a ich odwrotność jest lustrem polecenia. Takie jest założenie Stack Cats - wszystkie nietrywialne programy kończące mają nieparzystą długość, ponieważ programy o długości parzystej same się anulują.

Zaczynamy od

               v
               n
              -1
...  0    0    0    0    0  ...

_odejmuje, tworząc górę -1-ni [przesuwa wynik w lewo o jeden stos:

           v
       -1-n   -1
...  0    0    0    0    0  ...

:zamienia dwie pierwsze i Inic nie robi, ponieważ górna część stosu ma teraz zero. !następnie bitowo neguje górne zero na a -1i :zamienia dwa górne z powrotem. !następnie bitowo neguje górę, zmieniając -1-nsię nponownie:

          v
          n
         -1   -1
...  0    0    0    0    0  ...

Teraz rozgałęziamy się na podstawie I, która jest stosowana do naszego oryginalnego n:

  • Jeśli njest ujemne, przesuwamy w lewo o jeden stos i kończymy -nna domyślnym zera. :zamienia, kładąc zero na wierzchu i ]przesuwa zero na wierzch, z -1którego właśnie wyszliśmy. _następnie odejmuje, pozostawiając końcowy stos jak [-1 -1]i tylko jeden -1jest wyprowadzany, ponieważ baza -1jest ignorowana.

  • Jeśli nwynosi zero, nie poruszamy się i nie :wymieniamy, stawiając -1na wierzchu. ]następnie przesuwa to w lewo -1u góry po prawej -1i _odejmuje, pozostawiając ostatni stos jak [-1 0], generując zero i ignorując podstawę -1.

  • Jeśli njest pozytywny, poruszamy się w prawo o jeden stos i kończymy -nna a -1. :zamienia, kładąc -1na wierzch i ]przesuwa w -1prawo, na domniemaną wartość zero. _następnie odejmuje, dając 0 - (-1) = 1i pozostawiając końcowy stos jak [1], który jest wyprowadzany.

Sp3000
źródło
7

TI-Basic, 8 bajtów

median({1,Ans,~1

Alternatywne rozwiązania (możesz zaproponować więcej):

max(~1,min(Ans,1               8  bytes
0:If Ans:Ans/abs(Ans           9  bytes
(Ans>0)-(Ans<0                 10 bytes
Timtech
źródło
Co ~powinno być?
Conor O'Brien,
@ ConorO'Brien Symbol ujemny, aby odróżnić symbol odejmowania TI-Basic. Wiem, że Cemetech SC używa również ~do reprezentowania tego tokena.
Timtech,
Fajnie. Nie mam pojęcia.
Conor O'Brien
@ ConorO'Brien Cóż, teraz już wiesz. Dzięki za pytanie :)
Timtech,
1
To nie jest poprawne - użycie Ansjako danych wejściowych nie spełnia kryteriów prawidłowej domyślnej metody We / Wy (nie ma dwa razy więcej głosów pozytywnych niż ocen negatywnych - obecnie jest to + 19 / -12).
Mego
7

MATL , 6 bajtów

0>EGg-

Dane wejściowe mogą być liczbą lub tablicą. Wynikiem jest liczba lub tablica z odpowiednimi wartościami.

Wypróbuj online! Lub przetestuj kilka przypadków przy użyciu danych wejściowych z tablicy.

Wyjaśnienie

Pozwala to uniknąć korzystania z wbudowanej funkcji znakowania ( ZS).

0>   % Take input implicitly. Push 1 if positive, 0 otherwise
E    % Multiply by 2
Gg   % Push input converted to logical: 1 if nonzero, 0 otherwise
-    % Subtract. Implicitly display
Luis Mendo
źródło
MATL jest dłuższy niż Matlab i Octave ?
Adám
4
Mógłby również użyć wbudowanego, ZSjak napisano w odpowiedzi.
Stewie Griffin,
6

Galaretka , 1 bajt

TryItOnline!

Monadycznego znak atom , , robi dokładnie to, co jest podane na wejście całkowitą, albo jako pełny program lub jako monadycznej łącza (funkcja przyjmuje jeden argument).

Jonathan Allan
źródło
6

Mathematica, 4 bajty

Sign

Dokładnie to, co jest napisane na puszce

Greg Martin
źródło
Oszczędź bajt zsgn
Adám
3
WolframAlpha to nie to samo, co Mathematica; obejmuje automatyczną interpretację niejednoznacznego / naturalnego języka.
Greg Martin
Więc powinienem przesłać osobną odpowiedź?
Adám
wydaje mi się rozsądne ...
Greg Martin
6

Oktawa, 26 24 bajtów

f=@(x)real(asin(x))/pi*2

To moja pierwsza odpowiedź na Octave, wszelkie wskazówki dotyczące golfa są mile widziane!

Wypróbuj online!

Pomysł wzięcia asinpochodzi z pytania, w którym mówi output the sign:)

Wyjaśnienie

Uwaga: podzielenie liczby przez pii pomnożenie jej 2jest równoznaczne z podzieleniem liczby przezpi/2

Sprawa 0:

asin(0)plony 0. Przejęcie jej przez rzeczywistą część i podzielenie przez pi/2nie ma znaczenia dla wyniku.

Sprawa positive:

asin(1)plony pi/2. asindowolnej liczby większej niż 1da pi/2+ liczba zespolona. Przejęcie prawdziwej części daje pi/2i dzielenie przez pi/2dawanie1

Sprawa negative:

asin(-1)plony -pi/2. asindowolnej liczby mniejszej niż -1da -pi/2+ liczba zespolona. Przejęcie prawdziwej części daje -pi/2i dzielenie przez pi/2dawanie-1

Kritixi Lithos
źródło
@LuisMendo N will be an integerMam szczęście, że w pytaniu jest napisane :)
Kritixi Lithos
Och, nie przeczytałem tej części :)
Luis Mendo,
1
C L E V e R!
flawr
Nie potrzebujesz, f=jeśli reszta jest prawidłowym, nierekurencyjnym wyrażeniem funkcji.
Cyoce,
@Cyoce Przykro mi, ale nie wolę anonimowych funkcji
Kritixi Lithos,
6

Właściwie 1 bajt

s

Wypróbuj online!

Innym przypadkiem dokładnie tego, co jest napisane na puszce - sjest funkcja znaku.

Bez wbudowanego (4 bajty):

;A\+

Wypróbuj online!

;A\dzieli wartość bezwzględną wejścia przez wejście. Wynika to -1z danych wejściowych ujemnych i 1dodatnich. Niestety, ze względu na faktyczną obsługę błędów (jeśli coś pójdzie nie tak, polecenie jest ignorowane), 0ponieważ dane wejściowe pozostawiają dwie 0s na stosie. +naprawia to, dodając je (co powoduje błąd z czymkolwiek innym, więc jest ignorowane).

Mego
źródło
6

Piet, 188 53 46 41 bajtów

5bpjhbttttfttatraaearfjearoaearbcatsdcclq

Tłumacz online dostępny tutaj.

Ten kod pocztowy działa normalnie (n>0)-(n<0), ponieważ nie ma wbudowanego sprawdzania znaków. W rzeczywistości nie ma mniej niż wbudowane, więc dokładniejszy opis tej metody byłby (n>0)-(0>n).

Powyższy tekst przedstawia obraz. Możesz wygenerować obraz, wklejając go do pola tekstowego na stronie tłumacza. Dla wygody podałem poniżej obraz, w którym rozmiar kodu wynosi 31 pikseli. Siatka jest dostępna dla czytelności i nie jest częścią programu. Zauważ też, że ten program nie przecina żadnych białych kodów; postępuj zgodnie z kolorowymi kodami wokół obramowania obrazu, aby śledzić przebieg programu.

Wyjaśnienie

Program

Instruction    Δ Hue   Δ Lightness   Stack
------------   -----   -----------   --------------------
In (Number)    4       2             n
Duplicate      4       0             n, n
Push [1]       0       1             1, n, n
Duplicate      4       0             1, 1, in, in
Subtract       1       1             0, in, in
Duplicate      4       0             0, 0, in, in
Push [4]       0       1             4, 0, 0, in, in
Push [1]       0       1             1, 4, 0, 0, in, in
Roll           4       1             0, in, in, 0
Greater        3       0             greater, in, 0
Push [3]       0       1             3, greater, in, 0
Push [1]       0       1             1, 3, greater, in, 0
Roll           4       1             in, 0, greater
Greater        3       0             less, greater
Subtract       1       1             sign
Out (Number)   5       1             [Empty]
[Exit]         [N/A]   [N/A]         [Empty]

Aby jeszcze bardziej zmniejszyć rozmiar pliku, musiałbym zmienić program (wstrzymując oddech) zamiast kompresować plik tak, jak to robiłem. Chciałbym usunąć jeden wiersz, który golfowałby to do 36. Mogę również opracować własny interpreter, który miałby znacznie mniejszy format wejściowy, ponieważ zmiana kodu, aby go zmniejszyć, nie jest tym, czym jest golf.

Mody powiedziały mi, że całkowity rozmiar pliku ma znaczenie dla kodu Piet. Ponieważ interpreter akceptuje tekst jako prawidłowy wpis, a tekst surowy ma znacznie mniejszą liczbę bajtów niż jakikolwiek obraz, tekst jest oczywistym wyborem. Przepraszam za bezczelność, ale nie ustanawiam zasad. Meta dyskusja na ten temat sprawia, że moje opinie w tej sprawie jasne.

Jeśli uważasz, że jest to sprzeczne z duchem Pieta lub chciałbyś omówić to z jakiegokolwiek powodu, sprawdź dyskusję na temat meta .

Mike Bufardeci
źródło
2
Wierzę, że konwencja dla Piet polega na zliczeniu wszystkich kodów.
SuperJedi224,
@ SuperJedi224 Nie o tym zadecydowano w meta postie, wygląda na to, że liczba bajtów na obrazku będzie tym, co zamierzam zrobić.
Mike Bufardeci,
6

Pushy , 7 bajtów

To chyba najdziwniej wyglądający program, jaki kiedykolwiek napisałem ...

&?&|/;#

Wypróbuj online!

Używa sign(x) = abs(x) / x, ale z wyraźnym, sign(0) = 0aby uniknąć błędu zerowego podziału.

          \ Take implicit input
&?   ;    \ If the input is True (not 0):
  &|      \  Push its absolute value
    /     \  Divide
      #   \ Output TOS (the sign)

Działa x / abs(x)to, ponieważ wynosi 1, gdy x jest dodatnie, i -1, gdy x jest ujemne. Jeśli wartością wejściową jest 0, program przeskakuje do polecenia wyjściowego.


4 bajty (niekonkurujące)

Z powodu wakacji i zbyt długiego czasu zrobiłem kompletne przerobienie interpretera Pushy. Powyższy program nadal działa, ale ponieważ 0 / 0teraz domyślnie wynosi 0, następujące jest krótsze:

&|/#

Wypróbuj online!

FlipTack
źródło
1
Myślałem też o użyciu abs, ale nie miałem pojęcia, co zrobić z 0. Dobra robota!
Kritixi Lithos
5

R, 25 bajtów

'if'(x<-scan(),x/abs(x),0)

Przenosi numer do STDIN. Następnie sprawdza, czy to zero, jeśli nie, zwraca x/|x|którekolwiek 1z nich -1i zwraca 0, jeśli x=0.

Oczywiście nie jest to konieczne sign.

JAD
źródło
1
Stosując polecenie wbudowane jest oczywiście krótsze, ale mniej zabawy: sign(scan()).
Billywob,
Przepraszamy, należy wyraźnie wspomnieć o unikaniu wbudowanego
JAD
5

V 14 12 bajtów

Dzięki @DJMcMayhem za 2 bajty. Używa reg-ex do podstawienia. Trochę zabawy, ponieważ nie jest to wbudowane. Mam bardziej zabawną funkcję, ale nie działa tak, jak się spodziewałem.

ͨ-©½0]/±1

Sprawdź przypadki testowe

To po prostu tłumaczy, na :%s/\v(-)=[^0].*/\11który pasuje jeden lub więcej, -po których następuje dowolne oprócz 0, a następnie dowolna liczba razy. Zastąpiony jest pierwszym dopasowaniem (więc albo a -albo nic) i a 1. Wyrażenie regularne nie pasuje do 0, więc pozostaje samo.

The More Fun Way (21 bajtów)

é
Àé12|DkJòhé-òó^$/a

TryItOnline

To akceptuje dane wejściowe jako argument, a nie w buforze.

é<CR> Wstaw nową linię.

Àuruchom argument jako kod V. a -spowoduje przesunięcie kursora do poprzedniego wiersza, a dowolna liczba stanie się liczbą kolejnych poleceń

é1włożyć (liczy) 1jest

2| przejdź do drugiej kolumny

D usuń wszystko od drugiej kolumny (pozostawiając tylko jeden znak)

kJ Połącz dwie linie razem.

òhé-òtłumaczy się: „biegnij hé-aż do zerwania”. Jeśli 1 był na drugiej linii, to łamie się natychmiast po h. Jeśli był w pierwszym wierszu, wstawi znak -przed zerwaniem.

ó^$/aTo rozwiązuje fakt -1, 0, 1będzie zostawić puste i zastępuje pusty w rejestrze argumentów.

nmjcman101
źródło
Wiedziałem, że powinienem był lepiej przeczytać tę stronę. W rzeczywistości nie jest krótszy - zapomniałem 0, ale próbowałem wziąć numer jako argument Àé1. Liczba dodatnia daje ciąg jedynek, liczba ujemna POWINNA dać ciąg jedynek jeden rząd w górę, a 0 nie dałoby nic. Bit ujemnej liczby nie działał À, ale d$@"
działał
Ach Cóż, powodem, dla którego to nie działa, jest to, że nie ma innego rzędu, do którego mógłby przejść. Jeśli dodasz é<cr>, będą mieć dwie puste linie, a wtedy to zadziała . Nie jestem pewien, czy możesz użyć tego, aby uzyskać pełną odpowiedź
DJMcMayhem
Miałem jeszcze jedną linię, po prostu nie powiedziałem tego wprost w moim komentarzu. Jaki --argument dodałeś?
nmjcman101,
1
Oznacza „koniec opcji”. Ponieważ -6zaczyna się od flagi, docopt (biblioteka python dla opcji wiersza poleceń) uważa, że ​​jest to flaga wiersza poleceń, a nie argument. Dodanie --tylko sygnalizuje, że jest to argument, a nie opcja. W przeciwnym razie nie uruchomi się wcale z powodu nieprawidłowego wywołania wiersza poleceń.
DJMcMayhem
5

C #, 16 15 bajtów

Ulepszone rozwiązanie dzięki Neilowi

n=>n>0?1:n>>31;

Alternatywnie, wbudowana metoda jest dłuższa o 1 bajt:

n=>Math.Sign(n);

Pełny program z przypadkami testowymi:

using System;

public class P
{
    public static void Main()
    {
        Func<int,int> f =
        n=>n>0?1:n>>31;

        // test cases:
        for (int i=-5; i<= 5; i++)
            Console.WriteLine(i + " -> " + f(i));
    }
}
adrianmp
źródło
2
Spróbuj n>>31zamiast n<0?-1:0.
Neil,
1
To trochę smutne, gdy wbudowane narzędzie nie jest nawet najkrótszym rozwiązaniem.
Mego
Powiedzmy, że C # jest znany z tego, że jest dość gadatliwy ...
adrianmp,
1
Odp .: Nie sądzę, żebyś potrzebował końcowego, ;ponieważ lambda jest wyrażeniem, a nie stwierdzeniem. B) Math.Signczy Math::Signpoprawne zgłoszenie byłoby lub coś podobnego? Nie jestem pewien, w jaki sposób język C # obsługuje metody. Zasadniczo, czy x = Math.Sign;poprawna instrukcja C # byłaby xzainicjowana właściwym typem?
Cyoce,