84
\$\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.

The Catalogue

The Stack Snippet at the bottom of this post generates the catalogue from the answers a) as a list of shortest solution per language and b) as an overall leaderboard.

To make sure that your answer shows up, please start your answer with a headline, using the following Markdown template:

## Language Name, N bytes

where N is the size of your submission. If you improve your score, you can keep old scores in the headline, by striking them through. For instance:

## Ruby, <s>104</s> <s>101</s> 96 bytes

If there you want to include multiple numbers in your header (e.g. because your score is the sum of two files or you want to list interpreter flag penalties separately), make sure that the actual score is the last number in the header:

## Perl, 43 + 2 (-p flag) = 45 bytes

You can also make the language name a link which will then show up in the snippet:

## [><>](https://esolangs.org/wiki/Fish), 121 bytes

/* Configuration */

var QUESTION_ID = 103822; // Obtain this from the url
// It will be like https://XYZ.stackexchange.com/questions/QUESTION_ID/... on any question page
var ANSWER_FILTER = "!t)IWYnsLAZle2tQ3KqrVveCRJfxcRLe";
var COMMENT_FILTER = "!)Q2B_A2kjfAiU78X(md6BoYk";
var OVERRIDE_USER = 8478; // This should be the user ID of the challenge author.

/* App */

var answers = [], answers_hash, answer_ids, answer_page = 1, more_answers = true, comment_page;

function answersUrl(index) {
  return "https://api.stackexchange.com/2.2/questions/" +  QUESTION_ID + "/answers?page=" + index + "&pagesize=100&order=desc&sort=creation&site=codegolf&filter=" + ANSWER_FILTER;
}

function commentUrl(index, answers) {
  return "https://api.stackexchange.com/2.2/answers/" + answers.join(';') + "/comments?page=" + index + "&pagesize=100&order=desc&sort=creation&site=codegolf&filter=" + COMMENT_FILTER;
}

function getAnswers() {
  jQuery.ajax({
    url: answersUrl(answer_page++),
    method: "get",
    dataType: "jsonp",
    crossDomain: true,
    success: function (data) {
      answers.push.apply(answers, data.items);
      answers_hash = [];
      answer_ids = [];
      data.items.forEach(function(a) {
        a.comments = [];
        var id = +a.share_link.match(/\d+/);
        answer_ids.push(id);
        answers_hash[id] = a;
      });
      if (!data.has_more) more_answers = false;
      comment_page = 1;
      getComments();
    }
  });
}

function getComments() {
  jQuery.ajax({
    url: commentUrl(comment_page++, answer_ids),
    method: "get",
    dataType: "jsonp",
    crossDomain: true,
    success: function (data) {
      data.items.forEach(function(c) {
        if (c.owner.user_id === OVERRIDE_USER)
          answers_hash[c.post_id].comments.push(c);
      });
      if (data.has_more) getComments();
      else if (more_answers) getAnswers();
      else process();
    }
  });  
}

getAnswers();

var SCORE_REG = /<h\d>\s*([^\n,<]*(?:<(?:[^\n>]*>[^\n<]*<\/[^\n>]*>)[^\n,<]*)*),.*?(\d+)(?=[^\n\d<>]*(?:<(?:s>[^\n<>]*<\/s>|[^\n<>]+>)[^\n\d<>]*)*<\/h\d>)/;

var OVERRIDE_REG = /^Override\s*header:\s*/i;

function getAuthorName(a) {
  return a.owner.display_name;
}

function process() {
  var valid = [];
  
  answers.forEach(function(a) {
    var body = a.body;
    a.comments.forEach(function(c) {
      if(OVERRIDE_REG.test(c.body))
        body = '<h1>' + c.body.replace(OVERRIDE_REG, '') + '</h1>';
    });
    
    var match = body.match(SCORE_REG);
    if (match)
      valid.push({
        user: getAuthorName(a),
        size: +match[2],
        language: match[1],
        link: a.share_link,
      });
    else console.log(body);
  });
  
  valid.sort(function (a, b) {
    var aB = a.size,
        bB = b.size;
    return aB - bB
  });

  var languages = {};
  var place = 1;
  var lastSize = null;
  var lastPlace = 1;
  valid.forEach(function (a) {
    if (a.size != lastSize)
      lastPlace = place;
    lastSize = a.size;
    ++place;
    
    var answer = jQuery("#answer-template").html();
    answer = answer.replace("{{PLACE}}", lastPlace + ".")
                   .replace("{{NAME}}", a.user)
                   .replace("{{LANGUAGE}}", a.language)
                   .replace("{{SIZE}}", a.size)
                   .replace("{{LINK}}", a.link);
    answer = jQuery(answer);
    jQuery("#answers").append(answer);

    var lang = a.language;
    lang = jQuery('<a>'+lang+'</a>').text();
    
    languages[lang] = languages[lang] || {lang: a.language, lang_raw: lang, user: a.user, size: a.size, link: a.link};
  });

  var langs = [];
  for (var lang in languages)
    if (languages.hasOwnProperty(lang))
      langs.push(languages[lang]);

  langs.sort(function (a, b) {
    if (a.lang_raw.toLowerCase() > b.lang_raw.toLowerCase()) return 1;
    if (a.lang_raw.toLowerCase() < b.lang_raw.toLowerCase()) return -1;
    return 0;
  });

  for (var i = 0; i < langs.length; ++i)
  {
    var language = jQuery("#language-template").html();
    var lang = langs[i];
    language = language.replace("{{LANGUAGE}}", lang.lang)
                       .replace("{{NAME}}", lang.user)
                       .replace("{{SIZE}}", lang.size)
                       .replace("{{LINK}}", lang.link);
    language = jQuery(language);
    jQuery("#languages").append(language);
  }

}
body {
  text-align: left !important;
  display: block !important;
}

#answer-list {
  padding: 10px;
  width: 290px;
  float: left;
}

#language-list {
  padding: 10px;
  width: 500px;
  float: left;
}

table thead {
  font-weight: bold;
}

table td {
  padding: 5px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<link rel="stylesheet" type="text/css" href="https://cdn.sstatic.net/Sites/codegolf/all.css?v=ffb5d0584c5f">
<div id="language-list">
  <h2>Shortest Solution by Language</h2>
  <table class="language-list">
    <thead>
      <tr><td>Language</td><td>User</td><td>Score</td></tr>
    </thead>
    <tbody id="languages">

    </tbody>
  </table>
</div>
<div id="answer-list">
  <h2>Leaderboard</h2>
  <table class="answer-list">
    <thead>
      <tr><td></td><td>Author</td><td>Language</td><td>Size</td></tr>
    </thead>
    <tbody id="answers">

    </tbody>
  </table>
</div>
<table style="display: none">
  <tbody id="answer-template">
    <tr><td>{{PLACE}}</td><td>{{NAME}}</td><td>{{LANGUAGE}}</td><td>{{SIZE}}</td><td><a href="{{LINK}}">Link</a></td></tr>
  </tbody>
</table>
<table style="display: none">
  <tbody id="language-template">
    <tr><td>{{LANGUAGE}}</td><td>{{NAME}}</td><td>{{SIZE}}</td><td><a href="{{LINK}}">Link</a></td></tr>
  </tbody>
</table>

\$\endgroup\$
12
  • 50
    \$\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\$ Dec 20, 2016 at 10:10
  • 9
    \$\begingroup\$ This could probably use a leaderboard. \$\endgroup\$ Dec 20, 2016 at 11:13
  • 3
    \$\begingroup\$ @MrLister upvote how you want, but really you should look for creativity instead of code length. \$\endgroup\$
    – FlipTack
    Dec 28, 2016 at 20:13
  • 3
    \$\begingroup\$ @FlipTack Oh, I thought it was codegolf. \$\endgroup\$
    – Mr Lister
    Dec 28, 2016 at 20:23
  • 4
    \$\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, 2016 at 20:25

193 Answers 193

1
2 3 4 5
7
52
\$\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\$
10
  • \$\begingroup\$ This is very clever :) \$\endgroup\$
    – user45941
    Dec 23, 2016 at 15:01
  • \$\begingroup\$ Does it work with scientific notation of integer numbers (such as 0.42e2)? \$\endgroup\$ Dec 24, 2016 at 11:34
  • \$\begingroup\$ @EgorSkriptunoff No, but that's not a requirement. \$\endgroup\$ Dec 24, 2016 at 11:36
  • 13
    \$\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\$ Dec 24, 2016 at 12:01
  • 5
    \$\begingroup\$ @EgorSkriptunoff Retina has no concept of numbers whatsoever. It's a purely string-based language. \$\endgroup\$ Dec 24, 2016 at 12:21
45
\$\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\$
15
  • 8
    \$\begingroup\$ @betseg That is because upvotes on built-ins are now frowned upon. \$\endgroup\$ Dec 20, 2016 at 11:41
  • 4
    \$\begingroup\$ Saving 1 byte with this return n>>16|!!n; \$\endgroup\$
    – aross
    Dec 21, 2016 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, 2016 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, 2016 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\$
    – user45941
    Dec 23, 2016 at 14:38
36
\$\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\$
0
34
\$\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\$
4
  • 1
    \$\begingroup\$ And there's a 'moo' - language?... \$\endgroup\$ Dec 24, 2016 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\$ Dec 24, 2016 at 16:43
  • \$\begingroup\$ Could also call this the "bad mage" language. OUT OF MANA!!! \$\endgroup\$ Nov 2, 2017 at 16:41
  • \$\begingroup\$ Hey please take a look at my solution in COW \$\endgroup\$
    – Domenico
    Apr 26, 2020 at 17:56
20
\$\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\$
7
  • 4
    \$\begingroup\$ The animation of program flow is very nice! \$\endgroup\$
    – Luis Mendo
    Dec 20, 2016 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, 2016 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, 2016 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\$ Dec 22, 2016 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, 2016 at 20:55
19
\$\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\$
6
  • 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, 2016 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, 2016 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, 2016 at 0:57
  • \$\begingroup\$ Wait, is it legal? Can I develop my own language that will contain any function in 1 byte when I will codegolfing? \$\endgroup\$
    – Mouvre
    Jan 22, 2020 at 14:27
  • \$\begingroup\$ @Mouvre Yes, but if you don't limit yourself to 256 functions, you'll need to use more than a single byte per character. And there are way more than 256 code golf tasks… \$\endgroup\$
    – Adám
    Jan 22, 2020 at 16:25
17
\$\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\$
6
  • 2
    \$\begingroup\$ Non-builtin in 12 bytes for 32-bit signed integer n: n=>n>>31|!!n. \$\endgroup\$
    – Neil
    Dec 21, 2016 at 10:05
  • \$\begingroup\$ @Neil n>>31 is really smart, thanks! \$\endgroup\$ Dec 21, 2016 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\$
    – user45941
    Dec 23, 2016 at 14:48
  • \$\begingroup\$ @Mego You are correct. I've clarified this in the post. \$\endgroup\$ Dec 23, 2016 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\$ Dec 24, 2016 at 9:35
16
\$\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\$
3
  • 1
    \$\begingroup\$ I really like your method, but it's possible in a single regex: :s/\v(-)=[^0].*/\11 \$\endgroup\$
    – nmjcman101
    Dec 20, 2016 at 16:20
  • \$\begingroup\$ Dithered console GIFs...?? \$\endgroup\$
    – Desty
    Dec 26, 2016 at 2:13
  • \$\begingroup\$ This assumes your cursor is over the first character; I assume that's a valid assumption for vim answers, but an extra 0 in front would remove it as a requirement. \$\endgroup\$
    – Mark Reed
    Mar 22, 2023 at 16:21
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\$
3
  • \$\begingroup\$ I think that you can just use a legal ; instead of that unprintable 0x01 to terminate the program correctly :) \$\endgroup\$ Jan 11, 2017 at 18:27
  • \$\begingroup\$ @EriktheOutgolfer I need the 0x01 to push a 1 anyway. \$\endgroup\$ Jan 11, 2017 at 18:28
  • 2
    \$\begingroup\$ Oh, it seems I only tested my suggestion with 123. Lesson learned: test with more cases. \$\endgroup\$ Jan 11, 2017 at 18:30
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\$
1
  • 2
    \$\begingroup\$ This is extremely clever! \$\endgroup\$
    – user45941
    Dec 23, 2016 at 14:49
11
\$\begingroup\$

Python 2, 17 bytes

lambda n:cmp(n,0)

Try it online!

\$\endgroup\$
8
  • 5
    \$\begingroup\$ Oh you ninja'd me. \$\endgroup\$ Dec 20, 2016 at 6:02
  • 1
    \$\begingroup\$ Whoops. Sorry... \$\endgroup\$
    – Dennis
    Dec 20, 2016 at 6:05
  • 6
    \$\begingroup\$ Too bad you can't do (0).__rcmp__ ... \$\endgroup\$
    – Sp3000
    Dec 20, 2016 at 8:32
  • 2
    \$\begingroup\$ @nyuszika7h Not quite. Trying to use it as a function raises a TypeError. \$\endgroup\$
    – Dennis
    Dec 20, 2016 at 18:59
  • 2
    \$\begingroup\$ @Pietu1998 But there's even __rand__, and & is commutative... \$\endgroup\$
    – Dennis
    Dec 26, 2016 at 2:37
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\$
2
  • 1
    \$\begingroup\$ Your code is happy and turns sad :D \$\endgroup\$
    – Stefan
    Dec 21, 2016 at 15:23
  • 2
    \$\begingroup\$ @Stefan You can change the order if you prefer. ;) \$\endgroup\$ Dec 21, 2016 at 15:28
11
\$\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\$
10
\$\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\$
2
  • \$\begingroup\$ A little friendly competition. \$\endgroup\$
    – Wheat Wizard
    Dec 20, 2016 at 22:30
  • \$\begingroup\$ You can save 2 bytes by removing the zero monad around (()) \$\endgroup\$
    – 0 '
    Dec 23, 2016 at 19:38
9
\$\begingroup\$

PHP, 16 bytes

Uses the new spaceship operator.

<?=$argv[1]<=>0;
\$\endgroup\$
6
  • \$\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\$ Dec 22, 2016 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\$ Dec 22, 2016 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\$ Dec 22, 2016 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\$ Dec 22, 2016 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\$ Dec 22, 2016 at 17:02
9
\$\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\$
6
  • \$\begingroup\$ What is the ~ supposed to be? \$\endgroup\$ Dec 21, 2016 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, 2016 at 22:33
  • \$\begingroup\$ Oh, cool. I had no idea. \$\endgroup\$ Dec 21, 2016 at 22:41
  • \$\begingroup\$ @ConorO'Brien Well, now you know. Thanks for asking :) \$\endgroup\$
    – Timtech
    Dec 21, 2016 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\$
    – user45941
    Dec 23, 2016 at 14:26
8
\$\begingroup\$

J, 1 byte

*

Try it online (with test cases)!

\$\endgroup\$
0
8
\$\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\$
4
  • 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\$
    – Luna
    Dec 20, 2016 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\$ Dec 21, 2016 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\$
    – Luna
    Dec 21, 2016 at 17:29
  • \$\begingroup\$ say doesn't work in a file, either, without a use feature qw(say); or equivalent (e.g. use v5.x for x>=10). \$\endgroup\$
    – Mark Reed
    Mar 22, 2023 at 16:18
8
\$\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
  • 1
    \$\begingroup\$ I was also thinking about using abs, but had no idea what to do with the 0. Well done! \$\endgroup\$
    – user41805
    Dec 21, 2016 at 9:50
7
\$\begingroup\$

Ruby, 10 bytes

->x{x<=>0}
\$\endgroup\$
3
  • \$\begingroup\$ Would 0.<=> also work, or can you not reference methods like that in Ruby? \$\endgroup\$
    – anon
    Dec 26, 2016 at 1:04
  • \$\begingroup\$ .<=> expects 1 argument, so it would end up being 0.<=> x, which is longer. \$\endgroup\$
    – Seims
    Dec 30, 2016 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, 2017 at 23:04
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\$

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\$
5
  • 2
    \$\begingroup\$ Try n>>31 instead of n<0?-1:0. \$\endgroup\$
    – Neil
    Dec 21, 2016 at 10:15
  • 1
    \$\begingroup\$ It's a bit sad when the builtin isn't even the shortest solution. \$\endgroup\$
    – user45941
    Dec 23, 2016 at 14:57
  • \$\begingroup\$ Let's say C# is known to be rather verbose... \$\endgroup\$
    – adrianmp
    Dec 23, 2016 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, 2016 at 5:36
  • \$\begingroup\$ @Cyoce x = Math.Sign; is a valid statement if the variable/property x is already declared elsewhere with an appropriate type, for example Func<int, int> x;, and if there is a using directive (or namespace declaration) which makes the identifier Math resolve to the class System.Math. Note that Math.Sign is a "method group" which is not considered to possess a type in itself (although it is implicitly convertible to a bunch of compatible delegate types), and for that reason, var x = Math.Sign; will not work (the strong type for var cannot be inferred). \$\endgroup\$ Jun 22, 2021 at 7:51
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\$
2
  • \$\begingroup\$ MATL is longer than Matlab and Octave?! \$\endgroup\$
    – Adám
    Dec 20, 2016 at 11:24
  • 4
    \$\begingroup\$ He could also have used the built-in ZS as it says in the answer. \$\endgroup\$ Dec 20, 2016 at 13:53
7
\$\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
  • 2
    \$\begingroup\$ I believe the convention for Piet is to count all codels. \$\endgroup\$ Dec 21, 2016 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\$ Dec 21, 2016 at 14:30
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\$
0
6
\$\begingroup\$

Mathematica, 4 bytes

Sign

Exactly what it says on the tin

\$\endgroup\$
4
  • \$\begingroup\$ Save a byte with sgn \$\endgroup\$
    – Adám
    Dec 20, 2016 at 11:13
  • 3
    \$\begingroup\$ WolframAlpha isn't the same as Mathematica; it includes automatic interpretation of ambiguous/natural language input. \$\endgroup\$ Dec 20, 2016 at 11:15
  • \$\begingroup\$ So I should submit this a separate answer? \$\endgroup\$
    – Adám
    Dec 20, 2016 at 11:21
  • \$\begingroup\$ seems reasonable to me... \$\endgroup\$ Dec 20, 2016 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\$
6
  • \$\begingroup\$ @LuisMendo N will be an integer I'm lucky it says that in the question :) \$\endgroup\$
    – user41805
    Dec 20, 2016 at 13:59
  • \$\begingroup\$ Oh, I hadn't read that part :) \$\endgroup\$
    – Luis Mendo
    Dec 20, 2016 at 14:00
  • 1
    \$\begingroup\$ ​C​l​e​v​e​r!​​!​ \$\endgroup\$
    – flawr
    Dec 20, 2016 at 21:27
  • \$\begingroup\$ You don't need f= if the rest is a valid, non-recursive function expression. \$\endgroup\$
    – Cyoce
    Dec 25, 2016 at 5:31
  • \$\begingroup\$ @Cyoce Sorry, but I don't prefer anonymous functions \$\endgroup\$
    – user41805
    Dec 25, 2016 at 10:39
6
\$\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\$
4
  • \$\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, 2016 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, 2016 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, 2016 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, 2016 at 17:49
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\$

Python 3, 20 bytes

Since Python 3 doesn't have access to cmp like Python 2 does, it's a little longer

lambda n:(n>0)-(n<0)
\$\endgroup\$
7
  • 1
    \$\begingroup\$ @KritixiLithos practically but it's also an entirely different llanguage \$\endgroup\$
    – Dillanm
    Dec 21, 2016 at 11:37
  • 2
    \$\begingroup\$ How about n//abs(n) for two bytes \$\endgroup\$
    – Phlarx
    Dec 21, 2016 at 21:28
  • 1
    \$\begingroup\$ @Phlarx that will cause divide by zero error as n (and abs n) can be zero \$\endgroup\$
    – Dillanm
    Dec 22, 2016 at 9:40
  • 1
    \$\begingroup\$ @Dillanm ah, right. Didn't catch that, obvious in hindsight :P \$\endgroup\$
    – Phlarx
    Dec 22, 2016 at 16:16
  • 3
    \$\begingroup\$ @Dillanm You can, actually, but it's several bytes longer: n and n//abs(n) \$\endgroup\$
    – Phlarx
    Dec 23, 2016 at 16:19
1
2 3 4 5
7

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.