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.
1,_47-%!
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.
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
0 0 0 * halt
0 - - r 2
0 * 1 r 3
2 * 1 r 3
3 * _ r 3
3 _ _ * halt
{([({}<([()])>)]<>(())){({}())<>}}{}({})
{ }{}({}) #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
?</!~/~@$\!@
Expanded:
? < /
! ~ /
~ @ $ \ !
@ . . .
. . .
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.
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.
=Sign(n)
Pretty basic, but the only language I feel complete confidence in.
Without a builtin!
=If(n>0,1,If(n<0,-1,0))
not so confident
IIF(n>0,1,IIF(n<0,-1,0))
Since Python 3 doesn't have access to cmp like Python 2 does, it's a little longer
lambda n:(n>0)-(n<0)
n and n//abs(n)
\$\endgroup\$
– Phlarx
Dec 23 '16 at 16:19
Golfed off a byte by combining the 2 1
s
1~50p :0`_.@.
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
Limit[2ArcTan@x#/Pi,x->∞]&
2HeavisideTheta@#-1/._[_]->1/2&
Round@Integrate[E^(2#+I t#)/(2+I t)/Pi,{t,-∞,∞},PrincipalValue->True]-1&
Just to be different :)
Median@{#,1,-1}
and #~Min~1~Max~-1
if you want some more ideas ;)
\$\endgroup\$
– Martin Ender
Dec 20 '16 at 12:09
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
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) );
}
qsort(a,sizeof a/4,4,"\x8b\7+\6\xc3");
\$\endgroup\$
– ceilingcat
Dec 29 '16 at 5:17
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.
A true approach, not using built-ins but function composition (the dot):
(1-).fromEnum.compare 0
(or with more space)
(1-) . fromEnum . compare 0
Explanation:
compare 0 : partially applying the compare function to
the first argument 0 results in a function which takes
a number and compares it to 0.
(compare 0) n = compare 0 n =
LT : if 0 < n
EQ : if 0 = n
GT : if 0 > n
fromEnum : it maps LT to 0, EQ to 1 and GT to 2
(1-) : n -> 1 - n
pred
with (1-)
which allows you to replace (`compare`0)
with compare 0
.
\$\endgroup\$
– 0 '
Oct 20 '17 at 7:27
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
~.?>.)<<!!.&,.@
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.
#(compare % 0)
This uses the built-in compare
function of clojure: it returns a 1
if the first arg is greater than the second arg, 0
if it's equal, and -1
if it's smaller.
Usage:
(#(...) {number})
+(*cmp 0)
+( # turn into a number
* # Whatever (input)
cmp # compared to
0 # 0
)
sign
Usage:
sign 1
Builtin.
tt cmp0
Usage:
(tt cmp0)5
Uses a compare function with 0.
x=>x/Math.abs(x)|0
x/Math.abs(x)
is always 1 if x is positive and -1 if x is negative. If x is 0, it returns Nan, which we transform to 0 with the |0
bit.
Just a rewrite of Jordan's Sed solution.
0=0
<D>=1
Sample run:
bash-4.3$ gema '0=0;<D>=1' <<< $'-303\n-12\n-5\n0\n1\n20\n404'
-1
-1
-1
0
1
1
1
*=@cmpn{*;0;-1;0;1}
Posted just because Gema has a nice function for this task:
@cmpn{number;number;less-value;equal-value;greater-value}
Compare numbers.
Sample run:
bash-4.3$ gema '*=@cmpn{*;0;-1;0;1}' <<< -303
-1
bash-4.3$ gema '*=@cmpn{*;0;-1;0;1}' <<< 0
0
bash-4.3$ gema '*=@cmpn{*;0;-1;0;1}' <<< 404
1
@cmd/cset/a"%1>>31|!!%1
>>31
evaluates to -1
if the input is negative and 0
if it is positive, while !!
evaluates to 1
if it is nonzero and 0
if it is zero, so we just have to bitwise OR the two results together.
Math.signum
In the comments, some people pointed out that this might not technically be valid, if so, here's another version at 12 bytes:
Math::signum
-<,
[
[
>-[-<]
>
]
->[>+>]
]
<.
This takes a single byte from stdin and interprets it as a signed char, printing \xff
for negative, \x00
for zero, and \x01
for positive.
Viewed as an unsigned char, we are checking whether it is greater than 127, with 0 as a special case. We can do the comparison by decrementing from 255 twice at a time.
,>+.
is a valid answer.
\$\endgroup\$
– Esolanging Fruit
Dec 22 '16 at 4:38
,[>+>]<.
, I don't think that could be argued as anything other than a loophole.
\$\endgroup\$
– Mitch Schwartz
Dec 22 '16 at 5:49
lambda n:n and n/abs(n)
I know I can make it shorter by doing (n>0) - (n<0), but everyone else seems do be doing that so I thought I would do something different.
/
with //
, you don't need to cast to int.
\$\endgroup\$
– Dennis
Dec 22 '16 at 3:01
1.0 == 1
and -1.0 == -1
. Nice job using the rarely-used definition of the sign function as the derivative of the absolute value function (with f(0) = 0
explicitly defined)!
\$\endgroup\$
– Mego
Dec 23 '16 at 14:40
-2 bytes thanks to zeppelin. -1 byte thanks to manatwork.
/^0/!s/\w\+/1/
/^0+$/b;s/[0-9]+/1/
(Using the -r flag)
Translation:
/^0+$/b;
If the number is zero, skip to the end of the script
s/[0-9]+/1/
Substitute any other numbers with 1. If it's negative the negative sign will remain too.
Thanks to @Mistah Figgins for saving me two three bytes
I'm sure this is further golfable. I'll look at it again in the morning.
&:#@!#._0`#@:#._1-.@
Only takes in one line of input for each run, but that's within spec, I guess.
:#@ #
-> #@:#
as well. My goal whenever writing befunge 93/98 is no whitespace at all. (he says as his own submission is 7% whitespace)
\$\endgroup\$
– MildlyMilquetoast
Jan 6 '17 at 7:21
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:
-
, output -1
0
, output 0
1
Since Acc!! is a very bare-bones language, we have to use a loop for a conditional and integer division for comparison.
# 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
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