67
\$\begingroup\$

Given a number N, output the sign of N:

  • If N is positive, output 1
  • If N is negative, output -1
  • If N is 0, output 0

N will be an integer within the representable range of integers in your chosen language.

\$\endgroup\$
  • 45
    \$\begingroup\$ This is a trivial challenge with a lot of trivial solutions. There are however some non-trivial solutions too. To voters: Please read the first sentence of this meta post before upvoting builtin functions. \$\endgroup\$ – Stewie Griffin Dec 20 '16 at 10:10
  • 8
    \$\begingroup\$ This could probably use a leaderboard. \$\endgroup\$ – Martin Ender Dec 20 '16 at 11:13
  • 2
    \$\begingroup\$ @MrLister upvote how you want, but really you should look for creativity instead of code length. \$\endgroup\$ – FlipTack Dec 28 '16 at 20:13
  • 3
    \$\begingroup\$ @FlipTack Oh, I thought it was codegolf. \$\endgroup\$ – Mr Lister Dec 28 '16 at 20:23
  • 3
    \$\begingroup\$ @MrLister that's the objective winning criterion. but does it really take more effort to type s for a sign builtin, or use some clever bitshifting/maths to work it out? Have a look at this meta post \$\endgroup\$ – FlipTack Dec 28 '16 at 20:25

141 Answers 141

46
\$\begingroup\$

Retina, 9 bytes

[1-9].*
1

Try it online!

Replaces a non-zero digit and everything after it with 1. This leaves a potential leading - intact and changes all numbers except 0 itself to absolute value 1.

\$\endgroup\$
  • \$\begingroup\$ This is very clever :) \$\endgroup\$ – Mego Dec 23 '16 at 15:01
  • \$\begingroup\$ Does it work with scientific notation of integer numbers (such as 0.42e2)? \$\endgroup\$ – Egor Skriptunoff Dec 24 '16 at 11:34
  • \$\begingroup\$ @EgorSkriptunoff No, but that's not a requirement. \$\endgroup\$ – Martin Ender Dec 24 '16 at 11:36
  • 9
    \$\begingroup\$ @EgorSkriptunoff it doesn't support Roman numerals either. Unless the challenge explicitly mentions a certain non-standard format that needs to be supported, the general assumption is the it's fine to deal with a single format that's natural in your language of choice. \$\endgroup\$ – Martin Ender Dec 24 '16 at 12:01
  • 3
    \$\begingroup\$ @EgorSkriptunoff Retina has no concept of numbers whatsoever. It's a purely string-based language. \$\endgroup\$ – Martin Ender Dec 24 '16 at 12:21
42
\$\begingroup\$

C (GCC), 24 23 22 18 bytes

Thanks to @aross and @Steadybox for saving a byte!

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

Not guaranteed to work on all systems or compilers, works on TIO.

\$\endgroup\$
  • 7
    \$\begingroup\$ @betseg That is because upvotes on built-ins are now frowned upon. \$\endgroup\$ – Erik the Outgolfer Dec 20 '16 at 11:41
  • 4
    \$\begingroup\$ Saving 1 byte with this return n>>16|!!n; \$\endgroup\$ – aross Dec 21 '16 at 15:36
  • 5
    \$\begingroup\$ @GB Size of int is probably either 2 (16, x86) or 4 (32, x86_64) but remember, all that's needed is an architecture on which it is valid. This isn't Stack Overlflow, portability is not important. \$\endgroup\$ – cat Dec 21 '16 at 23:37
  • 2
    \$\begingroup\$ f(n){n=n>>31|!!n;} works too. But this is just a compiler quirk, not a language feature. \$\endgroup\$ – G B Dec 22 '16 at 5:50
  • 2
    \$\begingroup\$ @GB Compiler quirks are perfectly valid, so long as it can be proven that there is a compiler in which the quirk works. Luckily, gcc has the quirk. \$\endgroup\$ – Mego Dec 23 '16 at 14:38
34
\$\begingroup\$

Mathematica, 4 bytes

Clip

How about not using the built-in Sign and still scoring 4 bytes? ;)

Clip with a single argument clips (or clamps) the input value between -1 and 1. Since the inputs will only be integers, this is the same as using Sign.

\$\endgroup\$
29
\$\begingroup\$

COW, 225 213 201 bytes

oomMOOmoOmoOmoOmoOMoOMoOmOomOomOoMoOMMMmoOMMMMOOMOomOo
mOoMOomoOmoOmoomOomOoMMMmoOmoOmoOMMMMOOOOOmoOMOoMOomOo
mOomOoMoOMMMmoOMMMMOOMOomOomOoMoOmoOmoOmoomoOmoomOomOo
mOomoomoOMOOmoOmoOmoOMOoMMMOOOmooMMMOOM

Try it online!

The way that this code works is that it determines the sign by alternating adding and subtracting bigger numbers, and seeing which one was the last one that worked. Given any non-zero integer, first subtract 1, then add 2, then subtract 3, etc. and you'll eventually reach 0. Keep track of your state by alternating adding and subtracting 2 to a value that starts off at 0. For example:

-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

When you're done, subtract 1 from your state and you get the sign, positive or negative. If the original number is 0, then don't bother doing any of this and just print 0.

Detailed Explanation:

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.

I'm still experimenting with golfing it (you will be shocked to discover that golfing in COW is rather difficult), so this may come down a few more bytes in the future.

\$\endgroup\$
  • 1
    \$\begingroup\$ And there's a 'moo' - language?... \$\endgroup\$ – Mukul Kumar Dec 24 '16 at 7:45
  • 1
    \$\begingroup\$ @MukulKumar It's a brainfuck derivative called COW that allows for a couple of things that bf doesn't \$\endgroup\$ – Gabriel Benamy Dec 24 '16 at 16:43
  • \$\begingroup\$ Could also call this the "bad mage" language. OUT OF MANA!!! \$\endgroup\$ – Magic Octopus Urn Nov 2 '17 at 16:41
18
\$\begingroup\$

Cubix, 10 bytes

(W0^I?>O2@

Test it online!

This code is wrapped to the following cube net:

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

The code is then run with the IP (instruction pointer) starting on the I, facing east. I inputs a signed integer from STDIN, pushing it onto the stack.

The next command is ?, which changes the direction of the IP depending on the sign of the top item. If the input is 0, it keeps moving in same direction, running through the following code:

  • > - Point the IP to the east. (No-op since we're already going east.)
  • O - Output the top item as an integer.
  • 2 - Push 2 to the stack. This is practically a no-op, because...
  • @ - Terminates the program.

If the input is negative, the IP turns left at the ?; because this is a cube, the IP moves onto the 0 in the second row, heading east. 0 pushes a literal 0, then this code is run:

  • ^ - Point the IP north.
  • W - "Sidestep" the IP one spot to the left.
  • ( - Decrement the top item.

The TOS is now -1, and the IP wraps around the cube through a bunch of no-ops . until it hits the >. This runs the same output code mentioned above, outputting -1.

If the input is positive, the same thing happens as with negative inputs, with one exception: the IP turns right instead of left at the ?, and wraps around the cube to the 2, which pushes a literal 2. This is then decremented to 1 and sent to output.

\$\endgroup\$
  • 4
    \$\begingroup\$ The animation of program flow is very nice! \$\endgroup\$ – Luis Mendo Dec 20 '16 at 10:25
  • \$\begingroup\$ Nice language. Could it be shorter? 4 flow controls seems much. In operation-count it can be 8 bytes by introducing another ?, but now it uses the bottom half of the cube: ..1nI?..>O@.........? \$\endgroup\$ – BlackShift Dec 21 '16 at 7:19
  • \$\begingroup\$ Six is possible if we ignore outputs after the first: /I?nO1 By the way, this only works because I returns -1 in the online interpreter instead of 0 according to the spec. \$\endgroup\$ – BlackShift Dec 21 '16 at 7:45
  • \$\begingroup\$ @BlackShift Thanks for your interest! I like your suggestions, but I'm not sure how to improve them. It's definitely possible to use less instructions; the tricky part is using less of the cube... ;-) And thanks for pointing out that -1 bug, I'll get that fixed soon. \$\endgroup\$ – ETHproductions Dec 22 '16 at 3:04
  • \$\begingroup\$ @ETHproductions IMO It's not a bug, it makes sense for I to return -1 when input ends just like lowercase i does. \$\endgroup\$ – FlipTack Dec 24 '16 at 20:55
16
\$\begingroup\$

JavaScript (ES6), 9 bytes

Math.sign

Straightforward.

The shortest non-builtin is 13 bytes:

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

Thanks to @Neil, this can be golfed by a byte, but at the cost of only working on 32-bit integers:

n=>n>0|n>>31

Or you could do

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

which seems more golfable, but I'm not sure how.

\$\endgroup\$
  • 2
    \$\begingroup\$ Non-builtin in 12 bytes for 32-bit signed integer n: n=>n>>31|!!n. \$\endgroup\$ – Neil Dec 21 '16 at 10:05
  • \$\begingroup\$ @Neil n>>31 is really smart, thanks! \$\endgroup\$ – ETHproductions Dec 21 '16 at 15:07
  • \$\begingroup\$ I don't think the third solution is valid, since Javascript uses double-precision floats for numerics. But, I could be wrong. \$\endgroup\$ – Mego Dec 23 '16 at 14:48
  • \$\begingroup\$ @Mego You are correct. I've clarified this in the post. \$\endgroup\$ – ETHproductions Dec 23 '16 at 16:00
  • 1
    \$\begingroup\$ @Mego Sorry, I missed your comment. When using bitwise operators, JS implicitly casts their operands to signed 32-bit integers, so the third solution works, but only on numbers from -2147483648 to 2147483647. \$\endgroup\$ – ETHproductions Dec 24 '16 at 9:35
15
\$\begingroup\$

APL (Dyalog APL), 1 byte

Works for complex numbers too, returning 1∠θ:

×

TryAPL online!


Without that built-in, for integers (as per OP):

¯1⌈1⌊⊢

¯1⌈ the largest of negative one and

1⌊ the smallest of one and

the argument

TryAPL online!

... and a general one:

>∘0-<∘0

>∘0 more-than-zero

- minus

<∘0 less-than-zero

TryAPL online!

\$\endgroup\$
  • 1
    \$\begingroup\$ You actually did it in ONE byte... You sir, are a legend. I'm sure Jon Skeet would be proud. \$\endgroup\$ – user53855 Dec 21 '16 at 0:27
  • \$\begingroup\$ @Mango You are joking, right? There are a handful of single-byte answers to this challenge. \$\endgroup\$ – Adám Dec 21 '16 at 0:46
  • 1
    \$\begingroup\$ I was being sarcastic, also I said that because this is the first single byte answer I saw. \$\endgroup\$ – user53855 Dec 21 '16 at 0:57
14
\$\begingroup\$

><>, 9 8 bytes

Thanks to Sp3000 for saving a byte.

'i$-%n/

There's an unprintable 0x01 before the /.

Try it online!

Explanation

This is a port of my character code-based Labyrinth answer.

'     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.
\$\endgroup\$
  • \$\begingroup\$ I think that you can just use a legal ; instead of that unprintable 0x01 to terminate the program correctly :) \$\endgroup\$ – Erik the Outgolfer Jan 11 '17 at 18:27
  • \$\begingroup\$ @EriktheOutgolfer I need the 0x01 to push a 1 anyway. \$\endgroup\$ – Martin Ender Jan 11 '17 at 18:28
  • 2
    \$\begingroup\$ Oh, it seems I only tested my suggestion with 123. Lesson learned: test with more cases. \$\endgroup\$ – Erik the Outgolfer Jan 11 '17 at 18:30
14
\$\begingroup\$

Vim, 22 bytes

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

Saved one byte thanks to @DJMcMayhem!

Here, ^M is a literal newline.

As @nmjcman101 pointed out in the comments, a single regex can be used (:s/\v(-)=[^0].*/\11^M, 20 bytes) instead, but since this is basically the same as a Retina answer would be, I'm sticking to my own method.

Explanation:

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.

Here's a gif of it running with a negative number (old version):

Running with negative

Here's it running with 0:

Running with zero

Running with positive:

Running with positive

\$\endgroup\$
  • 1
    \$\begingroup\$ I really like your method, but it's possible in a single regex: :s/\v(-)=[^0].*/\11 \$\endgroup\$ – nmjcman101 Dec 20 '16 at 16:20
  • \$\begingroup\$ Dithered console GIFs...?? \$\endgroup\$ – Desty Dec 26 '16 at 2:13
12
\$\begingroup\$

///, 52 36 bytes

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

Ungolfed, explanation:

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

It's basically a MapReduce implemenatation, i.e. there are two phases:

  • Replace all occurrences of digits 2-9 by 1, e.g. 1230405 -> 1110101
  • Reduce pairs of 11 or 10 to 1 repeatedly, e.g. 1110101-> 1

If there was a - in front initially, it will remain and the output will be -1. A single 0 is never replaced, thus resulting in itself.

Update: Save additional 16 bytes by aliasing //1/ with a, thanks to Martin Ender.

Try it online, with test cases

\$\endgroup\$
  • 2
    \$\begingroup\$ This is extremely clever! \$\endgroup\$ – Mego Dec 23 '16 at 14:49
11
\$\begingroup\$

Python 2, 17 bytes

lambda n:cmp(n,0)

Try it online!

\$\endgroup\$
  • 5
    \$\begingroup\$ Oh you ninja'd me. \$\endgroup\$ – Jonathan Allan Dec 20 '16 at 6:02
  • 1
    \$\begingroup\$ Whoops. Sorry... \$\endgroup\$ – Dennis Dec 20 '16 at 6:05
  • 5
    \$\begingroup\$ Too bad you can't do (0).__rcmp__ ... \$\endgroup\$ – Sp3000 Dec 20 '16 at 8:32
  • 1
    \$\begingroup\$ You can do -(0).__cmp__ though. \$\endgroup\$ – nyuszika7h Dec 20 '16 at 18:57
  • 1
    \$\begingroup\$ @nyuszika7h Not quite. Trying to use it as a function raises a TypeError. \$\endgroup\$ – Dennis Dec 20 '16 at 18:59
11
\$\begingroup\$

Labyrinth, 10 bytes

?:+:)%:(%!

Try it online!

Explanation

Labyrinth's control flow semantics actually give you a "free" way to determine a number's sign, because the chosen path at a 3-way fork depends on whether the sign is negative, zero or positive. However, I haven't been able to fit a program with junctions into less than 12 bytes so far (although it may be possible).

Instead, here's a closed-form solution, that doesn't require any branches:

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.              []              []              []

The instruction pointer then hits a dead end, turns around and terminates when % now attempts a division by zero.

Doubling the input is necessary to make this work with inputs 1 and -1, otherwise one of the two modulo operations would already attempt a division by zero.

\$\endgroup\$
  • 1
    \$\begingroup\$ Your code is happy and turns sad :D \$\endgroup\$ – Stefan Dec 21 '16 at 15:23
  • 2
    \$\begingroup\$ @Stefan You can change the order if you prefer. ;) \$\endgroup\$ – Martin Ender Dec 21 '16 at 15:28
9
\$\begingroup\$

PHP, 16 bytes

Uses the new spaceship operator.

<?=$argv[1]<=>0;
\$\endgroup\$
  • \$\begingroup\$ Don't forget to mention that this is a PHP7 answer only. And since you're using <?=, you should use $_GET[n], which doesn't take any more bytes. To use <?=, you need to be inside a webserver (like Apache), and there you won't have access to $argv. You can try to run <?php var_dump($argv); from a PHP file, acessed through Apache, and it will show NULL. \$\endgroup\$ – Ismael Miguel Dec 22 '16 at 16:16
  • 1
    \$\begingroup\$ "To use <?=, you need to be inside a webserver (like Apache)," No. The <?= operator works just fine from the command line. \$\endgroup\$ – Alex Howansky Dec 22 '16 at 16:48
  • \$\begingroup\$ Running php -r '<?=1' I get PHP Parse error: syntax error, unexpected '<' in Command line code on line 1. But seems to work fine from a file. I guess you are right. \$\endgroup\$ – Ismael Miguel Dec 22 '16 at 16:58
  • \$\begingroup\$ The -r flag is to run a code snippet. This is complete source. Save it to a file and then run php file.php \$\endgroup\$ – Alex Howansky Dec 22 '16 at 17:00
  • \$\begingroup\$ I figured it out already. I really didn't knew that it worked from a file, using the (implicit) -f parameter. \$\endgroup\$ – Ismael Miguel Dec 22 '16 at 17:02
9
\$\begingroup\$

Brain-Flak 74 42 40 Bytes

Saved 2 bytes thanks to 1000000000

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

Try it Online!

Explanation:

{                                }       # 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)
\$\endgroup\$
8
\$\begingroup\$

J, 1 byte

*

Try it online (with test cases)!

\$\endgroup\$
8
\$\begingroup\$

C, 24 20 19 18 bytes

I abuse two C exploits to golf this down; This is in C (GCC).

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

Try it online!


Revision History:

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

2) f(a){a=(a>0)-(a<0);} //20 bytes

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

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


Revision 1: First attempt. Simple logic

Revision 2: Abuses a memory/stack bug in GCC where, as far as I can tell, a non-returning function will return the last set variable in certain cases.

Revision 3: Abuses ternary behavior where undefined result will return conditional result (which is why the true return on my ternary is nil)

Revision 4: Subtract a bool cast (!!) from the ternary conditional substitution for nil referenced in revision 2.

\$\endgroup\$
7
\$\begingroup\$

Ruby, 10 bytes

->x{x<=>0}
\$\endgroup\$
  • \$\begingroup\$ Would 0.<=> also work, or can you not reference methods like that in Ruby? \$\endgroup\$ – Nic Hartley Dec 26 '16 at 1:04
  • \$\begingroup\$ .<=> expects 1 argument, so it would end up being 0.<=> x, which is longer. \$\endgroup\$ – Seims Dec 30 '16 at 0:47
  • \$\begingroup\$ @QPaysTaxes you would need 0.method:<=> because method calls in ruby don't use parentheses and 0.<=> would be interpreted as a method call with too few arguments. \$\endgroup\$ – Cyoce Jan 7 '17 at 23:04
7
\$\begingroup\$

Perl, 9 bytes

Requires -E at no extra cost.

say<><=>0

Usage

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

I'm happy with the fish operator!

\$\endgroup\$
  • 1
    \$\begingroup\$ It doesn't really "require" -E, that's only if you call it from the CLI instead of a file, which is why I guess you said no extra cost. \$\endgroup\$ – nyuszika7h Dec 20 '16 at 21:53
  • \$\begingroup\$ @nyuszika7h indeed, requires I guess in the way that testing via -e won't work, but -E is accepted as no longer than -e. As per consensus on meta. I hope that helps a little! \$\endgroup\$ – Dom Hastings Dec 21 '16 at 13:50
  • \$\begingroup\$ Yeah, I was not suggesting requiring any extra cost for that, as it works fine when that script is executed normally from a file. \$\endgroup\$ – nyuszika7h Dec 21 '16 at 17:29
7
\$\begingroup\$

Stack Cats, 6 + 4 = 10 bytes

_[:I!:

+4 bytes for the ​ -nm flags. n is for numeric I/O, and since Stack Cats requires programs to be palindromic, m implicitly mirrors the source code to give the original source

_[:I!:!I:]_

Try it online! As with basically all good Stack Cats golfs, this was found by brute force, beat any manual attempts by a long shot, and can't easily be incorporated into a larger program.

Add a D flag if you'd like to see a step-by-step program trace, i.e. run with -nmD and check STDERR/debug.


Stack Cats uses a tape of stacks which are implicitly filled with zeroes at the bottom. At the start of the program, all input is pushed onto the input stack, with a -1 at the base to separate the input from the implicit zeroes. At the end of the program, the current stack is output, except a base -1 if present.

The relevant commands here are:

_           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)

Note that all of these commands are invertible, with its inverse being the mirror of the command. This is the premise of Stack Cats — all nontrivial terminating programs are of odd length, since even length programs self-cancel.

We start with

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

_ subtracts, making the top -1-n, and [ moves the result left one stack:

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

: swaps top two and I does nothing, since the top of stack is now zero. ! then bitwise negates the top zero into a -1 and : swaps the top two back. ! then bitwise negates the top, turning -1-n back into n again:

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

Now we branch based on I, which is applied to our original n:

  • If n is negative, we move left one stack and end with -n on an implicit zero. : swaps, putting a zero on top, and ] moves the zero on top of the -1 we just moved off. _ then subtracts, leaving the final stack like [-1 -1], and only one -1 is output since the base -1 is ignored.

  • If n is zero, we don't move and : swaps, putting -1 on top. ] then moves this left -1 on top of the right -1, and _ subtracts, leaving the final stack like [-1 0], outputting the zero and ignoring the base -1.

  • If n is positive, we move right one stack and end with -n on a -1. : swaps, putting the -1 on top, and ] moves this -1 right, on top of an implicit zero. _ then subtracts, giving 0 - (-1) = 1 and leaving the final stack like [1], which is output.

\$\endgroup\$
7
\$\begingroup\$

TI-Basic, 8 bytes

median({1,Ans,~1

Alternative solutions (feel free to suggest more):

max(~1,min(Ans,1               8  bytes
0:If Ans:Ans/abs(Ans           9  bytes
(Ans>0)-(Ans<0                 10 bytes
\$\endgroup\$
  • \$\begingroup\$ What is the ~ supposed to be? \$\endgroup\$ – Conor O'Brien Dec 21 '16 at 22:27
  • \$\begingroup\$ @ConorO'Brien Negative symbol, to differentiate between TI-Basic's subtract symbol. I know that Cemetech SC uses ~ to represent this token as well. \$\endgroup\$ – Timtech Dec 21 '16 at 22:33
  • \$\begingroup\$ Oh, cool. I had no idea. \$\endgroup\$ – Conor O'Brien Dec 21 '16 at 22:41
  • \$\begingroup\$ @ConorO'Brien Well, now you know. Thanks for asking :) \$\endgroup\$ – Timtech Dec 21 '16 at 22:54
  • 1
    \$\begingroup\$ This is not valid - using Ans as input does not meet the criteria for being a valid default I/O method (it doesn't have twice as many upvotes as downvotes - currently it's at +19/-12). \$\endgroup\$ – Mego Dec 23 '16 at 14:26
7
\$\begingroup\$

MATL, 6 bytes

0>EGg-

Input may be a number or an array. The result is number or an array with the corresponding values.

Try it online! Or test several cases using array input.

Explanation

This avoids using the builtin sign function (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
\$\endgroup\$
  • \$\begingroup\$ MATL is longer than Matlab and Octave?! \$\endgroup\$ – Adám Dec 20 '16 at 11:24
  • 4
    \$\begingroup\$ He could also have used the built-in ZS as it says in the answer. \$\endgroup\$ – Stewie Griffin Dec 20 '16 at 13:53
6
\$\begingroup\$

Jelly, 1 byte

TryItOnline!

The monadic sign atom, , does exactly what is specified for an integer input, either as a full program or as a monadic link (function taking one argument).

\$\endgroup\$
6
\$\begingroup\$

Mathematica, 4 bytes

Sign

Exactly what it says on the tin

\$\endgroup\$
  • \$\begingroup\$ Save a byte with sgn \$\endgroup\$ – Adám Dec 20 '16 at 11:13
  • 3
    \$\begingroup\$ WolframAlpha isn't the same as Mathematica; it includes automatic interpretation of ambiguous/natural language input. \$\endgroup\$ – Greg Martin Dec 20 '16 at 11:15
  • \$\begingroup\$ So I should submit this a separate answer? \$\endgroup\$ – Adám Dec 20 '16 at 11:21
  • \$\begingroup\$ seems reasonable to me... \$\endgroup\$ – Greg Martin Dec 20 '16 at 11:24
6
\$\begingroup\$

Octave, 26 24 bytes

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

This is my first Octave answer, any golfing tips are appreciated!

Try it online!

The idea for taking the asin comes from the question where it says output the sign :)

Explanation

Note: dividing the number by pi and multiplying it by 2 is the equivalent of dividing the entire number by pi/2

Case 0:

asin(0) yields 0. Taking the real part of it and dividing it by pi/2 makes no difference to the output.

Case positive:

asin(1) yields pi/2. asin of any number bigger than 1 will give pi/2 + complex number. Taking the real part of it gives pi/2 and dividing it by pi/2 gives 1

Case negative:

asin(-1) yields -pi/2. asin of any number smaller than -1 will give -pi/2 + complex number. Taking the real part of it gives -pi/2 and dividing it by pi/2 gives -1

\$\endgroup\$
  • \$\begingroup\$ @LuisMendo N will be an integer I'm lucky it says that in the question :) \$\endgroup\$ – Cows quack Dec 20 '16 at 13:59
  • \$\begingroup\$ Oh, I hadn't read that part :) \$\endgroup\$ – Luis Mendo Dec 20 '16 at 14:00
  • 1
    \$\begingroup\$ ​C​l​e​v​e​r!​​!​ \$\endgroup\$ – flawr Dec 20 '16 at 21:27
  • \$\begingroup\$ You don't need f= if the rest is a valid, non-recursive function expression. \$\endgroup\$ – Cyoce Dec 25 '16 at 5:31
  • \$\begingroup\$ @Cyoce Sorry, but I don't prefer anonymous functions \$\endgroup\$ – Cows quack Dec 25 '16 at 10:39
6
\$\begingroup\$

Actually, 1 byte

s

Try it online!

Another case of exactly what it says on the tin - s is the sign function.

Without the builtin (4 bytes):

;A\+

Try it online!

;A\ divides the absolute value of the input by the input. This results -1 for negative inputs and 1 for positive inputs. Unfortunately, due to Actually's error handling (if something goes wrong, the command is ignored), 0 as input leaves two 0s on the stack. + rectifies this by adding them (which causes an error with anything else, so it's ignored).

\$\endgroup\$
6
\$\begingroup\$

Piet, 188 53 46 41 bytes

5bpjhbttttfttatraaearfjearoaearbcatsdcclq

Online interpreter available here.

This piet code does the standard (n>0)-(n<0), as there is no sign checking builtin. In fact, there is no less-than builtin, so a more accurate description of this method would be (n>0)-(0>n).

The text above represents the image. You can generate the image by pasting it into the text box on the interpreter page. For convenience I have provided the image below where the codel size is 31 pixels. The grid is there for readability and is not a part of the program. Also note that this program does not cross any white codels; follow the colored codels around the border of the image to follow the program flow.

Explanation

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]

To reduce the filesize any further, I would need to actually change the program (gasp) instead of just compressing the file as I have been doing. I would like to remove one row which would golf this down to 36. I may also develop my own interpreter which would have a much smaller input format, as actually changing the code to make it smaller is not what code golf is about.

The mods told me that the overall filesize is what counts for Piet code. As the interpreter accepts text as valid input and raw text has a much smaller byte count than any image, text is the obvious choice. I apologize for being cheeky about this but I do not make the rules. The meta discussion about this makes my opinions on the matter clear.

If you think that that goes against the spirit of Piet or would like to discuss this further for any reason, please check out the discussion on meta.

\$\endgroup\$
  • 2
    \$\begingroup\$ I believe the convention for Piet is to count all codels. \$\endgroup\$ – SuperJedi224 Dec 21 '16 at 11:04
  • \$\begingroup\$ @SuperJedi224 That is not what was decided in the meta post, it looks like number of bytes in the image is what I will be going with. \$\endgroup\$ – Mike Bufardeci Dec 21 '16 at 14:30
6
\$\begingroup\$

Pushy, 7 bytes

This is probably the strangest-looking program I've ever written...

&?&|/;#

Try it online!

It uses sign(x) = abs(x) / x, but with an explicit sign(0) = 0 to avoid zero division error.

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

This works because x / abs(x) is 1 when x is positive and -1 when x is negative. If the input is 0, the program jumps to the output command.


4 bytes (non-competing)

Because of holidays and having too much time, I've done a complete rewrite of the Pushy interpreter. The above program still works, but because 0 / 0 now default to 0, the following is shorter:

&|/#

Try it online!

\$\endgroup\$
  • 1
    \$\begingroup\$ I was also thinking about using abs, but had no idea what to do with the 0. Well done! \$\endgroup\$ – Cows quack Dec 21 '16 at 9:50
5
\$\begingroup\$

R, 25 bytes

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

Takes the number to STDIN. Then checks if it's zero, if not, returns x/|x| which is either 1 of -1, and outputs 0 if x=0.

This is without using the builtin sign of course.

\$\endgroup\$
  • 1
    \$\begingroup\$ Using the builtin is of course shorter, but less fun: sign(scan()). \$\endgroup\$ – Billywob Dec 20 '16 at 10:40
  • \$\begingroup\$ Sorry, shouldve explicitly mentioned avoiding the builtin \$\endgroup\$ – JAD Dec 20 '16 at 10:48
5
\$\begingroup\$

V 14 12 bytes

Thanks @DJMcMayhem for 2 bytes. Uses a reg-ex to do the substitution. Kind of fun, because it's not a built-in. I have a more fun function, but it's not working the way I expected.

ͨ-©½0]/±1

Verify Test Cases

This just translates to :%s/\v(-)=[^0].*/\11 which matches one or more - followed by anything but 0, followed by anything any number of times. It's replaced with the first match (so either a - or nothing) and a 1. The regex doesn't match 0, so that stays itself.

The More Fun Way (21 bytes)

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

TryItOnline

This accepts the input as an argument rather than in the buffer.

é<CR> Insert a new line.

À run the argument as V code. a - will move the cursor to the previous line, and any number will become the count for the next command

é1 insert (count)1's

2| move to the second column

D delete everything from the second column onwards (leaving only one character)

kJ Join the two lines together.

òhé-ò translates to: "run hé- until breaking". If the 1 was on the second line, this breaks immediately after the h. If it was on the first line, it will insert a - before breaking.

ó^$/a This fixes the fact that -1,0,1 will leave a blank, and replaces a blank with the argument register.

\$\endgroup\$
  • \$\begingroup\$ I knew I should have read that page better. It's not actually shorter - I forgot 0, but I was trying to take the number in as an argument and then Àé1. A positive number gives a string of ones, a negative number SHOULD give a string of ones one row up, and 0 would give nothing. The negative number bit didn't work with À, but did with d$@" \$\endgroup\$ – nmjcman101 Dec 20 '16 at 17:27
  • \$\begingroup\$ Ah. Well the reason that doesn't work is because there isn't another row up for it to go onto. If you add é<cr> it'll have two empty lines and then that does work. I'm not sure if you can use that to get a full answer \$\endgroup\$ – DJMcMayhem Dec 20 '16 at 17:40
  • \$\begingroup\$ I did have another line to up to, just didn't explicitly say that in my comment. What's the -- argument you added? \$\endgroup\$ – nmjcman101 Dec 20 '16 at 17:47
  • 1
    \$\begingroup\$ It means "end of options". Since -6 starts with a flag, docopt (the python library for command line options) thinks it's a command-line flag rather than an argument. Adding -- just signals that it's an argument not an option. Otherwise, it won't run at all because of invalid command line invocation. \$\endgroup\$ – DJMcMayhem Dec 20 '16 at 17:49
5
\$\begingroup\$

C#, 16 15 bytes

Improved solution thanks to Neil

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

Alternatively, the built-in method is 1 byte longer:

n=>Math.Sign(n);

Full program with test cases:

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));
    }
}
\$\endgroup\$
  • 2
    \$\begingroup\$ Try n>>31 instead of n<0?-1:0. \$\endgroup\$ – Neil Dec 21 '16 at 10:15
  • 1
    \$\begingroup\$ It's a bit sad when the builtin isn't even the shortest solution. \$\endgroup\$ – Mego Dec 23 '16 at 14:57
  • \$\begingroup\$ Let's say C# is known to be rather verbose... \$\endgroup\$ – adrianmp Dec 23 '16 at 15:00
  • 1
    \$\begingroup\$ A) I don't think you need the trailing ; as a lambda is an expression, not a statement. B) would Math.Sign or Math::Sign or something similar be a valid submission? Not sure how C# in particular handles methods. Basically, would x = Math.Sign; be a valid C# statement if x was initialized with the right type? \$\endgroup\$ – Cyoce Dec 25 '16 at 5:36

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.