83
\$\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\$ Commented Dec 20, 2016 at 10:10
  • 9
    \$\begingroup\$ This could probably use a leaderboard. \$\endgroup\$ Commented 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
    Commented Dec 28, 2016 at 20:13
  • 3
    \$\begingroup\$ @FlipTack Oh, I thought it was codegolf. \$\endgroup\$
    – Mr Lister
    Commented 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
    Commented Dec 28, 2016 at 20:25

193 Answers 193

1
2
3 4 5
7
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\$
3
  • 1
    \$\begingroup\$ Using the builtin is of course shorter, but less fun: sign(scan()). \$\endgroup\$
    – Billywob
    Commented Dec 20, 2016 at 10:40
  • \$\begingroup\$ Sorry, shouldve explicitly mentioned avoiding the builtin \$\endgroup\$
    – JAD
    Commented Dec 20, 2016 at 10:48
  • \$\begingroup\$ 21 bytes (4.5 years later…) \$\endgroup\$ Commented Apr 1, 2021 at 14:41
5
\$\begingroup\$

Brain-Flak, 48 46 40 bytes

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

Try it Online

Explanation

{                                }{}({}) #Do nothing if zero
   ({}<([()])>)                          #Put a -1 under input
 ([            ]<>(()))                  #Put 1 and a negative copy of input on the off stack
                       {        }        #Until zero
                        ({}())           #Increment
                              <>         #Swap
\$\endgroup\$
1
5
\$\begingroup\$

Befunge 93, 14 13 bytes

Golfed off a byte by combining the 2 1s

1~50p :0`_.@.

Try it Online!

This one is interesting, as it takes the first character of the number and alters the code accordingly.

 ~50p         Stores the first character in the space (labeled <char> here)
1    <char>   If the number is negative, it performs subtraction, giving 1 - 0 == -1
              If it is 0, 0 is on top. If it is positive, a positive # will be.

 :0`_         This checks the top number to see if it is positive.
     .@       If it is <1, it is printed. (0 or -1)
1     @.      Otherwise, the IP loops back harmlessly, and prints 1
\$\endgroup\$
4
\$\begingroup\$

05AB1E, 3 bytes

0.S

Try it online!

\$\endgroup\$
4
  • \$\begingroup\$ Oh wow! (I mean, how did you get it so long?) \$\endgroup\$
    – user85052
    Commented Jan 26, 2020 at 23:38
  • \$\begingroup\$ @a'_' Well, there wasn't any way of doing it shorter than this. \$\endgroup\$
    – Emigna
    Commented Jan 27, 2020 at 20:36
  • \$\begingroup\$ Don't use the legacy version and you have 2 bytes \$\endgroup\$
    – naffetS
    Commented Mar 27, 2020 at 20:13
  • \$\begingroup\$ 2 bytes is possible even on the legacy version \$\endgroup\$
    – Grimmy
    Commented Apr 24, 2020 at 9:59
4
\$\begingroup\$

Labyrinth, 8 bytes

1,_47-%!

Try it online!

I'm posting this as a separate answer because my other Labyrinth answer is based on arithmetic on the actual numerical input value, whereas this mostly ignores the number and works with the character code of the first character instead.

Explanation

So yeah, this reads the first character code which is either 45 (-, which should yield -1), 48 (0, which should yield 0) or 49 to 57 (1-9, which should yield 1). This mapping can be accomplished via the simple formula 1 % (x - 47). To see why this works, here is the breakdown of the code for 3 different examples:

Code    Comment             Example -5      Example 0       Example 5
1       Push 1.             [1]             [1]             [1]
,       Read character.     [1 45]          [1 48]          [1 53]
_47-    Subtract 47.        [1 -2]          [1 1]           [1 6]
%       Modulo.             [-1]            [0]             [1]
!       Print.              []              []              []

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

Another simple computation that works:

x -= 46
x %= x-1
\$\endgroup\$
4
\$\begingroup\$

x86_64 machine language on Linux, 13 bytes

 0:   31 c0                   xor    %eax,%eax
 2:   85 ff                   test   %edi,%edi
 4:   0f 9f c0                setg   %al
 7:   c1 ef 1f                shr    $0x1f,%edi
10:   29 f8                   sub    %edi,%eax
12:   c3                      retq

The input (first function parameter) is passed into %edi. To try it out, compile and run the following C program

#include<stdio.h>
#include<stdlib.h>
#define s(x) ((int(*)(int))"\x31\xc0\x85\xff\xf\x9f\xc0\xc1\xef\x1f\x29\xf8\xc3")(x)
int main(){
  printf( "%d %d %d\n", s(-5), s(0), s(44) );
}
\$\endgroup\$
4
  • \$\begingroup\$ I'm a bit surprised that x86 doesn't have a builtin for sign. \$\endgroup\$
    – user45941
    Commented Dec 23, 2016 at 15:00
  • \$\begingroup\$ Casting a C string to a function pointer? That's nasty. \$\endgroup\$
    – anon
    Commented Dec 26, 2016 at 1:08
  • 1
    \$\begingroup\$ @QPaysTaxes, that is also an elegant/horrifying way to make lambdas in C qsort(a,sizeof a/4,4,"\x8b\7+\6\xc3"); \$\endgroup\$
    – ceilingcat
    Commented Dec 29, 2016 at 5:17
  • \$\begingroup\$ I got virtually the same solution in a language I created that is based off of C lambdas. What C code did you use to generate this machine code? \$\endgroup\$
    – MD XF
    Commented Mar 27, 2018 at 18:50
4
\$\begingroup\$

Turing Machine code, 65 bytes

0 0 0 * halt
0 - - r 2
0 * 1 r 3
2 * 1 r 3
3 * _ r 3
3 _ _ * halt

Try it online.

\$\endgroup\$
2
  • \$\begingroup\$ Could you link to an interpreter? \$\endgroup\$
    – user45941
    Commented Dec 23, 2016 at 15:00
  • \$\begingroup\$ couldn't you output using halt state here :P \$\endgroup\$
    – ASCII-only
    Commented Apr 12, 2019 at 7:19
4
\$\begingroup\$

Hexagony, 13 bytes

?</!~/~@$\!@

Expanded:

  ? < /
 ! ~   /
~ @ $ \ !
 @ . . .
  . . .

Try it online!

Hexagony truthy/falsiness for numbers checks based on being positive or not. This makes singling out zero a bit tricky, so we check if a number and its negation are both non-positive to check for zero. Uses the unprintable character 0x01 to literally store 1 in a memory edge to save a byte zeroing the edge first. In the expanded version it is between the ~ and the / on the second line.

Breakdown:

For positive numbers the code is very simple. We start at the top left moving eastward, then take the fork to the right. The rest of the program is "linear" along the surface of the code, giving: ?<0x01\.!@ where both \ and . are no-ops. 0x01 sets the current memory edge to 1 and then ! prints that and @ ends the program.

For negative numbers and zero, we start the same but turn left at the <. This leads us back around to the \ but this time approaching from the southwest. This time it acts as a mirror and redirects the instruction pointer westward. The $ allows us to skip the program-ending @. Next we hit ~ which negates the value that we read in. If the number was negative it is now positive, and if it was zero it is still not positive.

When hitting the edge of the hexagon we wrap to the right if the value was positive and to the left if the value was negative or zero. Negative numbers will then wrap to the right and begin moving westwards from the top right. Hitting some mirrors leads us to a familiar looking path starting with the edge being set to 1. Then ~ negates it and ! prints giving -1. We wrap around and hit the other @.

Zero will instead wrap to the bottom, which has nothing but no-ops. Then it wraps back to the middle and is printed by !. Then some mirrors redirect us to the @ to end the program.

\$\endgroup\$
4
\$\begingroup\$

Excel, 8 bytes

=Sign(n)

Pretty basic, but the only language I feel complete confidence in.

Without a builtin!

Excel, 23 bytes

=If(n>0,1,If(n<0,-1,0))

not so confident

Crystal Reports Formula (Noncompete), 24 bytes

IIF(n>0,1,IIF(n<0,-1,0))
\$\endgroup\$
4
\$\begingroup\$

Minecraft Functions (18w11a, 1.13 snapshots), 131 bytes

Number signs in minecraft

Uses a function named a in the minecraft namespace

execute if score @p n matches 0 run say 0
execute if score @p n matches 1.. run say 1
execute if score @p n matches ..-1 run say -1

"Takes input" from a scoreboard objective named n, create it with /scoreboard objectives add n dummy and then set it using /scoreboard players set @p n 8. Then call the function using /function a

\$\endgroup\$
4
\$\begingroup\$

Hexagony, 18 15 bytes

~.?>.)<<!!.&,.@

Try it online!

n > 0

  ~ . ?
 . . . .
< . ! . .
 , . @ .
  . . .

n == 0

  ~ . ?
 > . ) <
< . ! . &
 . . @ .
  . . .

n < 0

  ~ . ?
 > . ) <
< ! . . .
 , . @ .
  . . .

Abuses the same EOF trick used in Jo Kings answer.

Sadly I currently don't have access to these neat visual tools used in other solutions.

\$\endgroup\$
4
\$\begingroup\$

Vyxal, 1 byte

±

Try it Online!

Nothing special, just a built-in, but nobody else had posted it yet, so I figured I might as well.

No built-in, 72 bytes

Thanks to @Bubbler for saving 5 bytes.

ȧ/

Try it Online!

Does |x| / x. In Vyxal, 0 / 0 returns 0 instead of a divide by zero error, so this works.

\$\endgroup\$
4
  • \$\begingroup\$ hey, have you seen this bounty? Because you're eligible for it \$\endgroup\$
    – lyxal
    Commented Apr 21, 2021 at 5:11
  • \$\begingroup\$ Non-trivial 6 bytes ((x>0) - (x<0)) and 4 bytes (max(min(x,1),-1)) \$\endgroup\$
    – Bubbler
    Commented Apr 21, 2021 at 5:13
  • \$\begingroup\$ 2 bytes (x/abs(x)), which happens to not error on 0. \$\endgroup\$
    – Bubbler
    Commented Apr 21, 2021 at 5:23
  • \$\begingroup\$ @Bubbler the fact that it doesn't error on division by 0 is intentional. I added that a while ago \$\endgroup\$
    – lyxal
    Commented Apr 21, 2021 at 6:13
4
\$\begingroup\$

K (ngn/k), 4 bytes

0 1'

Try it online!

Uses sortedList' as binary search.

  • 0 1' do a binary lookup on 0 1; if the input is 0, it will match the first index, returning 0; if larger than 0, it'll match to the 1 value at the second index, returning 1. If the input is smaller than 0, it will return -1, indicating that the input is less than each value in the sorted list.
\$\endgroup\$
4
\$\begingroup\$

tinylisp, 21 bytes

(q((N)(s(l 0 N)(l N 0

Anonymous function that takes a number and returns a number. Try it online!

Ungolfed/explanation

(load library)     ; Load the library to get ungolfed aliases for builtins
(lambda (N)        ; Anonymous function of one argument
  (sub2            ; Take the difference of
    (less? 0 N)    ; 1 if N is positive, 0 otherwise
    (less? N 0)))  ; 1 if N is negative, 0 otherwise
\$\endgroup\$
4
\$\begingroup\$

Trilangle, 21 bytes

?\<'1(0@'^\.!_@>'0.(#

Try it in the online interpreter!

Unfolds to this:

     ?
    \ <
   ' 1 (
  0 @ ' ^
 \ . ! _ @
> ' 0 . ( #

Conceptually equivalent to this C code:

#include <stdio.h>

int main() {
    int x;
    scanf("%i", &x);

    if (x < 0) {
        puts("-1");
    } else if (x > 0) {
        puts("1");
    } else {
        puts("0");
    }
}

but that really doesn't do justice to how dense the control flow is.

As with every Trilangle program, control flow starts in the north corner heading southeast, on the red path in the image above. It reads the following instructions:

  • ?: Read an integer from stdin and push it to the stack
  • \: Redirect control flow
  • <: Branch on sign

If the value read in was negative, control flow continues on the green path:

  • >: Redirect control flow
  • '0: Push a 0 to the stack
  • .: No-op
  • (: Decrement. Because the push-int instruction can only push a single digit, the easiest way to get -1 is '0( (push 0 and decrement) or '0~ (push 0 and bitwise NOT). Either works here; I chose ( arbitrarily.
  • #: Skip the next character (the /)
  • .: Another no-op
  • !: Print the top of the stack
  • _: No-op in this direction
  • @: End program

If the value read in was positive or zero, the IP follows the blue path:

  • (: Decrement. 0 is now negative and positive values are still non-negative.
  • ^: Branch on sign again

If the value read in was initially positive, it takes the yellow path:

  • _: Redirect control flow
  • '1: Push a 1 to the stack
  • \: No-op in this direction
  • .: No-op
  • !: Print the top of the stack
  • @: End program

If the value read in was initially zero, it follows the magenta path. This does a bit more work than necessary to avoid interfering with the other paths:

  • '1: Push a 1 to the stack
  • (: Decrement. Great, we've turned zero into zero.
  • \: Redirect control flow (moving towards the print statement)
  • ': Oh no, another push instruction? But we already have a zero!
  • 0: Push another zero I guess.
  • \: Redirect control flow, merging with the green path
  • .!_@: Same as above.

There are other ways I could achieve the same result, e.g.:

?\<)2(.@'^\.!_@>'0(.#

but that has basically the same control structure, and is still 21 bytes. I'm not certain it's impossible to do shorter, but I wouldn't know how.

\$\endgroup\$
4
\$\begingroup\$

Piet + ascii-piet, 19 bytes (4×6=24 codels)

tabraF krbtKbks?Tbb

Try Piet online!

(previous record: 40 codels/ascii-piet bytes)

An approach involving a CC+ turned out to be the most space-efficient compared to branchless ones.

inN             [n]
dup 1 ! > !     [n !(n>0)]
CC+             [n]  Switch CC if n is 0 or less (follow upper path)
                     otherwise follow lower path
Upper path:
! 1 -           [(n=0)-1]  0 if n is zero, -1 if negative
Lower path:
1               [n 1]  Simply push 1
outN            Print the top number and halt

Some candidates I tried include:

  • cost 15 (cost is 1 per command, plus pushed numbers minus 1)
1 ! inN dup 1 !  [0 n n 0]
>                [0 n n>0]
3 1 roll >       [n>0 0>n]
- outN           []  Print (n>0)-(0>n)
  • cost 16, tries not to use roll and instead uses a weird division trick. -1 / positive is -1, -1 / 0 is division by zero, -1 / -1 is 1, and -1 / -2.. is 0. I use + after / to make -1 / 0 case give -1, and then do %3-1 to map each case to the correct output.
1 2 - inN 1 -  [-1 n-1]
/ +            [x]  x = -1/(n-1) as described above
3 % 1 - outN   Print the correct ouptut
  • cost 16, uses a > and ! instead of two >s. The formula in this case is (n>0)*2 + (n=0) - 1.
inN dup !          [n n=0]
2 1 roll           [n=0 n]
1 ! >              [n=0 n>0]
dup + + 1 - outN   Calculate and print the result of the formula
\$\endgroup\$
1
  • \$\begingroup\$ +1 for building your own interpreter as well! \$\endgroup\$
    – Jonah
    Commented May 11, 2022 at 14:55
3
\$\begingroup\$

Forth, 22 bytes

Golfed

: S dup 0< swap 0> - ;

Test

: S dup 0< swap 0> - ;  ok

0 S . 0  ok
1 S . 1  ok
-1 S . -1  ok
12345 S . 1  ok
-12345 S . -1  ok

Try It Online !

\$\endgroup\$
1
  • \$\begingroup\$ Nice. I was going to post something similar that I wrote several months ago. \$\endgroup\$
    – mbomb007
    Commented Dec 20, 2016 at 22:38
3
\$\begingroup\$

GNU sed, 17 15 14 bytes

-2 bytes thanks to zeppelin. -1 byte thanks to manatwork.

/^0/!s/\w\+/1/

Try it online!

\$\endgroup\$
0
3
\$\begingroup\$

Plain English 101 81 bytes

To put a n number's sign into a s number:
Get the sign of the n returning the s.

Ungolfed version:

To put a number's sign into another number:
  Get the sign of the number returning the other number.

Either version can be used to golf the client code -- and make the client code more readable. For example, the following line of code displays a Windows message box containing the number -1 in the message body:

Debug -456's sign.

The Plain English IDE is available at github.com/Folds/english. The IDE runs on Windows. It compiles to 32-bit x86 code.

\$\endgroup\$
1
  • 1
    \$\begingroup\$ ... I don't think that the Ungolfed version was really necessary \$\endgroup\$ Commented Aug 1, 2017 at 18:36
3
\$\begingroup\$

Acc!!, 50 49 bytes

N
Count i while 45/_ {
Write _
49
}
Write 48+_/49

Acc!! reads input from stdin one character code at a time. This program decides what to output simply based on the first character of the input:

  • If it's -, output -1
  • If it's 0, output 0
  • Otherwise, output 1

Since Acc!! is a very bare-bones language, we have to use a loop for a conditional and integer division for comparison.

Commented version

# Read a character code from input and store it in _ (the accumulator)
N
# If that character was a minus sign (ASCII 45), 45/_ will be 1 and this loop will run
# If that code was a digit (ASCII 48-57), 45/_ will be 0 and the loop will be skipped
Count i while 45/_ {
  # For negative numbers, output the minus sign
  Write _
  # Set the accumulator to ASCII code of 1 so we will break out of the loop and write a 1
  49
}
# If the input was 0 (ASCII 48), _/49 will be 0 and the next line will write a 0
# Otherwise, _/49 will be 1 and the next line will write a 1
Write 48+_/49
\$\endgroup\$
1
  • \$\begingroup\$ Clever - this is the first solution I've seen that takes advantage of the fact that you only need to look at the first byte to determine the output (when using string input). \$\endgroup\$
    – user45941
    Commented Dec 23, 2016 at 14:58
3
\$\begingroup\$

LOLCODE, 191 bytes

HAI 1.3
I HAS A J ITZ A NUMBR
GIMMEH J
BIGGR OF J AN 0, O RLY?
	YA RLY
		VISIBLE "1"
	NO WAI
		BOTH SAEM "0" AN J, O RLY?
			YA RLY
				VISIBLE "0"
			NO WAI
				VISIBLE "-1"
	OIC
OIC
KTHXBYE

Try it online!

\$\endgroup\$
2
  • \$\begingroup\$ This is surprisingly readable. \$\endgroup\$ Commented Nov 21, 2017 at 18:17
  • \$\begingroup\$ @iamnotmaynard funny right? \$\endgroup\$
    – qqq
    Commented Nov 21, 2017 at 19:31
3
\$\begingroup\$

Befunge-93 (PyFunge), 12 bytes

~"1"%90p1X.@

Try it online!

Note that the X can be anything (except a new line), as it gets written over during run-time. It's just easier for explanation

Similar to my other Befunge answer, but this time it mods the first character by the ASCII for 1 first, so that a positive first digit will turn into a no-op, leaving the 1 on the top of the stack:

~               Read the first *character* of input - either a digit or "-"
 "1"%           Mod the character by the ASCII value of 1. After this step, the character
                is a '-' for negative numbers, '0' for 0, and small, unprintable
                characters for positive numbers

     90p        Puts the character in the space with the X.
        1       Pushes a 1

         X      3 different options based on the character that was put here:
         -      Negative: Subtract the 1 from the implicit 0 to get -1
         0      Zero:     Push 0
               Positive: A no-op, which leaves the 1 on top

          .     Prints out the top of the stack
           @    Ends the program
\$\endgroup\$
3
\$\begingroup\$

Hexagony, 16 bytes

...!/~.?.<.!1@.,

Try it online!

Not much smaller than the previous answer, but strangely elegant in comparison.

Expanded:

   . . .
  ! / ~ .
 ? . < . !
  1 @ . ,
   . . .
\$\endgroup\$
0
3
\$\begingroup\$

TIS -n 1 1, 57 bytes

@0
MOV UP ACC
ADD 998
SUB 998
SUB 998
ADD 998
MOV ACC ANY

Try it online!

The integral data type supported by TIS ranges from -999 to 999. Any value in input, code, or calculations is silently coerced (clamped) into that range (instead of truncation, overflowing, etc.).

So, by adding 998 to any number, then subtracting the same amount, it becomes 1 is it was positive, and stays untouched otherwise. We then do the same to coerce all negative numbers to -1.

We need to subtract across two separate operations, due to the coercion mentioned above.

If you are familiar with TIS-100, you will be used to a 3x4 array of computational nodes, however, this solutions only uses one such node, nominally taking input from above and giving it below.

\$\endgroup\$
3
\$\begingroup\$

Python 3, 30 bytes

Just here to share another solution.

lambda x:eval(f'x and {x}**0')

Try it online!

Explanation

lambda x:                      # Lambda function with the variable x
         eval(f'      {x}**0') # Raise x to the power of 0
                x and          # Since 0 ** 0 = 1, we prevent that
                               # by using logical and.
\$\endgroup\$
3
\$\begingroup\$

Python 3, 26 25 bytes

An interesting way to approach this problem using the irregularity of Python 3 hash function.

lambda x:x/abs(~hash(~x))

Try it online!

Explanation

The big idea is to return x/abs(x). However, this causes division by 0 if x is 0.

hash(i) (where \$i\$ is an integer) returns \$i\$ most of the time, with the exception of hash(-1) returning \$-2\$. Thus ~hash(~x) (where ~ denotes bitwise negation) evaluates to:

  • If x != 0: ~hash(~x) == ~~x == x
  • If x == 0: ~hash(~0) == ~hash(-1) == ~(-2) == 1

Thus instead of dividing by abs(x), we divides by abs(~hash(~x)) which can never be 0.

Note: This will not work for large integers (\$\ge2^{61}\$), since hash of long integer is calculated differently.

\$\endgroup\$
3
\$\begingroup\$

Mornington Crescent, 2060 2054 1246 bytes

The improved solution is here!

Take Northern Line to Bank
Take Circle Line to Bank
Take District Line to Parsons Green
Take District Line to Notting Hill Gate
Take Circle Line to Notting Hill Gate
Take Circle Line to Bank
Take Circle Line to Hammersmith
Take Circle Line to Cannon Street
Take Circle Line to Hammersmith
Take Circle Line to Cannon Street
Take Circle Line to Bank
Take District Line to Acton Town
Take District Line to Hammersmith
Take Circle Line to Notting Hill Gate
Take Circle Line to Notting Hill Gate
Take District Line to Acton Town
Take Piccadilly Line to Bounds Green
Take Piccadilly Line to Acton Town
Take Piccadilly Line to Bounds Green
Take Piccadilly Line to Holborn
Take Central Line to Holborn
Take Central Line to Notting Hill Gate
Take Circle Line to Notting Hill Gate
Take District Line to Acton Town
Take District Line to Parsons Green
Take District Line to Notting Hill Gate
Take Circle Line to Notting Hill Gate
Take Central Line to Holborn
Take Piccadilly Line to Bounds Green
Take Piccadilly Line to Acton Town
Take Piccadilly Line to Bounds Green
Take Piccadilly Line to Holborn
Take Piccadilly Line to Bounds Green
Take Piccadilly Line to Leicester Square
Take Northern Line to Leicester Square
Take Northern Line to Mornington Crescent

Try it online!

The algorithm:

  1. Parse an integer out of the string provided as input at Parsons Green.
  2. Take the two's complement of the result of step 1 at Notting Hill Gate.
  3. Compute the value of 1 by dividing the result of step 2 by itself.
  4. Take the two's complement of 1 to get -2.
  5. Take the greater of -2 and the result of 2.
  6. Take the two's complement of the result of step 5.
  7. Parse an integer out of a string that contains no integer at Parsons Green, yielding 0.
  8. Take the two's complement of 0 to get -1.
  9. Take the greater of -1 and the result of step 6.
  10. Output the result. In conclusion, the program clamps the integer between the values of -1 and 1, similarly to other solutions.

Old solution:
Took me the better part of two days to figure it out, but I think I have it. The program does not function correctly if faced with -0 or 03 as inputs, so its preconditions are such that there are no leading zeros in the input and that -0 is invalid as well.

Take Northern Line to Charing Cross
Take Northern Line to Charing Cross
Take Northern Line to Bank
Take Circle Line to Bank
Take Circle Line to Notting Hill Gate
Take Circle Line to Notting Hill Gate
Take Circle Line to Victoria
Take Victoria Line to Seven Sisters
Take Victoria Line to Green Park
Take Victoria Line to Green Park
Take Piccadilly Line to Russell Square
Take Piccadilly Line to Russell Square
Take Piccadilly Line to Acton Town
Take District Line to Acton Town
Take District Line to Bank
Take Circle Line to Hammersmith
Take District Line to Upminster
Take District Line to Hammersmith
Take Circle Line to Cannon Street
Take Circle Line to Hammersmith
Take Circle Line to Cannon Street
Take Circle Line to Bank
Take Circle Line to Victoria
Take District Line to Upminster
Take District Line to Upney
Take District Line to Upminster
Take District Line to Hammersmith
Take District Line to Upminster
Take District Line to Cannon Street
Take Circle Line to Hammersmith
Take District Line to Upminster
Take District Line to Upminster
Take District Line to Upney
Take District Line to Cannon Street
Take District Line to Upney
Take District Line to Cannon Street
Take District Line to Upney
Take District Line to Hammersmith
Take Circle Line to Notting Hill Gate
Take Circle Line to Notting Hill Gate
Take District Line to Upminster
Take District Line to Notting Hill Gate
Take Circle Line to Notting Hill Gate
Take District Line to Acton Town
Take District Line to Upney
Take District Line to Acton Town
Take Piccadilly Line to Bounds Green
Take Piccadilly Line to Acton Town
Take Piccadilly Line to Bounds Green
Take Piccadilly Line to Acton Town
Take District Line to Acton Town
Take District Line to Notting Hill Gate
Take Circle Line to Notting Hill Gate
Take District Line to Barking
Take District Line to Upminster
Take District Line to Hammersmith
Take District Line to Upminster
Take District Line to Barking
Take District Line to Upminster
Take District Line to Bank
Take Circle Line to Bank
Take Northern Line to Mornington Crescent

Try it online!

The algorithm:

  1. Get the first character of the input, which should be - if negative, 0 if zero, or any other digit 1 through 9 if positive.
  2. Convert to ASCII. Now the program should have 45 if the input was negative, 48 if the input was zero, and an integer between 49 and 57 if the input was positive.
  3. Take the bitwise NOT of the ASCII integer. Now the program should have -46 if the input was negative, -49 if the input was zero, and an integer between -50 and -58 if the input was positive.
  4. Add 49 to the previous integer. Now the program should have 3 if the input was negative, 0 if the input was zero, and an integer between -1 and -9 if the input was positive.
  5. Complete integer division by 3. Now the program should have 1 if the input was negative, 0 if the input was zero, and an integer between -1 and -3 if the input was positive.
  6. Take the maximum function of the previous integer and -1 (taking whichever is larger). Now the program should have 1 if the input was negative, 0 if the input was zero, and -1 if the input was positive.
  7. Take the bitwise NOT of the previous integer. Now the program should have -2 if the input was negative, -1 if the input was zero, and 0 if the input was positive.
  8. Add one to the previous integer. Now the program should have -1 if the input was negative, 0 if the input was zero, and 1 if the input was positive. We are done.

Overall, a very rewarding but tiring experience.

EDIT, -6 bytes: Changed Embankment to the shorter Barking.

\$\endgroup\$
1
  • \$\begingroup\$ Just realized there is a much better algorithm to do this. You can use max, bitwise not, max again, and bitwise not again. Oops... that's work for tomorrow. \$\endgroup\$
    – Cloudy7
    Commented Apr 23, 2020 at 1:51
3
\$\begingroup\$

BRASCA, 8 bytes

,'/-1$%n

Try it online!

Explanation

,            - Reverse the stack to take the first character from input
 '/-         - Subtract it by 47
    1$%      - 1 % that value
       n     - And output it
\$\endgroup\$
3
\$\begingroup\$

Zsh, 19 bytes

<<<$[($1>0)-($1<0)]

Try it Online. A neat trick from someone on stackoverflow.

\$\endgroup\$
3
\$\begingroup\$

Risky, built-in, 1 byte

1?

Try it online!

Risky, non-built-in, 3 bytes

_?/[?

Try it online!

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