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-9].*
1
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
.
0.42e2
)?
\$\endgroup\$
– Egor Skriptunoff
Dec 24 '16 at 11:34
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.
f(n){n=n>>31|!!n;}
works too. But this is just a compiler quirk, not a language feature.
\$\endgroup\$
– G B
Dec 22 '16 at 5:50
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
.
oomMOOmoOmoOmoOmoOMoOMoOmOomOomOoMoOMMMmoOMMMMOOMOomOo
mOoMOomoOmoOmoomOomOoMMMmoOmoOmoOMMMMOOOOOmoOMOoMOomOo
mOomOoMoOMMMmoOMMMMOOMOomOomOoMoOmoOmoOmoomoOmoomOomOo
mOomoomoOMOOmoOmoOmoOMOoMMMOOOmooMMMOOM
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.
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.
OUT OF MANA!!!
\$\endgroup\$
– Magic Octopus Urn
Nov 2 '17 at 16:41
(W0^I?>O2@
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.
I
to return -1 when input ends just like lowercase i
does.
\$\endgroup\$
– FlipTack
Dec 24 '16 at 20:55
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.
n
: n=>n>>31|!!n
.
\$\endgroup\$
– Neil
Dec 21 '16 at 10:05
n>>31
is really smart, thanks!
\$\endgroup\$
– ETHproductions
Dec 21 '16 at 15:07
Works for complex numbers too, returning 1∠θ:
×
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
... and a general one:
>∘0-<∘0
>∘0
more-than-zero
-
minus
<∘0
less-than-zero
Thanks to Sp3000 for saving a byte.
'i$-%n/
There's an unprintable 0x01
before the /
.
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.
;
instead of that unprintable 0x01
to terminate the program correctly :)
\$\endgroup\$
– Erik the Outgolfer
Jan 11 '17 at 18:27
0x01
to push a 1
anyway.
\$\endgroup\$
– Martin Ender
Jan 11 '17 at 18:28
123
. Lesson learned: test with more cases.
\$\endgroup\$
– Erik the Outgolfer
Jan 11 '17 at 18:30
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):
Here's it running with 0:
Running with positive:
:s/\v(-)=[^0].*/\11
\$\endgroup\$
– nmjcman101
Dec 20 '16 at 16:20
/a/\/1\/\///2a3a4a5a6a7a8a9a10a11/1/
/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:
2
-9
by 1
, e.g. 1230405
-> 1110101
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.
?:+:)%:(%!
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.
Uses the new spaceship operator.
<?=$argv[1]<=>0;
<?=
, you should use $_GET[n]
, which doesn't take any more bytes. To use <?=
, you need to be inside a webserver (like Apache), and there you won't have access to $argv
. You can try to run <?php var_dump($argv);
from a PHP file, acessed through Apache, and it will show NULL
.
\$\endgroup\$
– Ismael Miguel
Dec 22 '16 at 16:16
<?=
operator works just fine from the command line.
\$\endgroup\$
– Alex Howansky
Dec 22 '16 at 16:48
php -r '<?=1'
I get PHP Parse error: syntax error, unexpected '<' in Command line code on line 1
. But seems to work fine from a file. I guess you are right.
\$\endgroup\$
– Ismael Miguel
Dec 22 '16 at 16:58
-r
flag is to run a code snippet. This is complete source. Save it to a file and then run php file.php
\$\endgroup\$
– Alex Howansky
Dec 22 '16 at 17:00
-f
parameter.
\$\endgroup\$
– Ismael Miguel
Dec 22 '16 at 17:02
Saved 2 bytes thanks to 1000000000
{([({}<([()])>)]<>(())){({}())<>}}{}({})
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\$
– 0 '
Dec 23 '16 at 19:38
I abuse two C exploits to golf this down; This is in C (GCC).
f(a){a=a>0?:-!!a;}
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.
->x{x<=>0}
0.<=>
also work, or can you not reference methods like that in Ruby?
\$\endgroup\$
– Fund Monica's Lawsuit
Dec 26 '16 at 1:04
.<=>
expects 1 argument, so it would end up being 0.<=> x
, which is longer.
\$\endgroup\$
– Seims
Dec 30 '16 at 0:47
0.method:<=>
because method calls in ruby don't use parentheses and 0.<=>
would be interpreted as a method call with too few arguments.
\$\endgroup\$
– Cyoce
Jan 7 '17 at 23:04
Requires -E
at no extra cost.
say<><=>0
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!
-E
, that's only if you call it from the CLI instead of a file, which is why I guess you said no extra cost.
\$\endgroup\$
– nyuszika7h
Dec 20 '16 at 21:53
-e
won't work, but -E
is accepted as no longer than -e
. As per consensus on meta. I hope that helps a little!
\$\endgroup\$
– Dom Hastings
Dec 21 '16 at 13:50
_[: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.
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
~
to represent this token as well.
\$\endgroup\$
– Timtech
Dec 21 '16 at 22:33
Ans
as input does not meet the criteria for being a valid default I/O method (it doesn't have twice as many upvotes as downvotes - currently it's at +19/-12).
\$\endgroup\$
– Mego
Dec 23 '16 at 14:26
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.
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
ZS
as it says in the answer.
\$\endgroup\$
– Stewie Griffin
Dec 20 '16 at 13:53
Sign
Exactly what it says on the tin
f=@(x)real(asin(x))/pi*2
This is my first code-golf Octave answer, any golfing tips are appreciated!
The idea for taking the asin
comes from the question where it says output the sign
:)
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
N will be an integer
I'm lucky it says that in the question :)
\$\endgroup\$
– Kritixi Lithos
Dec 20 '16 at 13:59
f=
if the rest is a valid, non-recursive function expression.
\$\endgroup\$
– Cyoce
Dec 25 '16 at 5:31
s
Another case of exactly what it says on the tin - s
is the sign function.
Without the builtin (4 bytes):
;A\+
;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 0
s on the stack. +
rectifies this by adding them (which causes an error with anything else, so it's ignored).
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.
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.
This is probably the strangest-looking program I've ever written...
&?&|/;#
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.
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:
&|/#
abs
, but had no idea what to do with the 0
. Well done!
\$\endgroup\$
– Kritixi Lithos
Dec 21 '16 at 9:50
'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.
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
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
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.
Àé1
. A positive number gives a string of ones, a negative number SHOULD give a string of ones one row up, and 0 would give nothing. The negative number bit didn't work with À
, but did with d$@"
\$\endgroup\$
– nmjcman101
Dec 20 '16 at 17:27
é<cr>
it'll have two empty lines and then that does work. I'm not sure if you can use that to get a full answer
\$\endgroup\$
– DJMcMayhem♦
Dec 20 '16 at 17:40
--
argument you added?
\$\endgroup\$
– nmjcman101
Dec 20 '16 at 17:47
-6
starts with a flag, docopt (the python library for command line options) thinks it's a command-line flag rather than an argument. Adding --
just signals that it's an argument not an option. Otherwise, it won't run at all because of invalid command line invocation.
\$\endgroup\$
– DJMcMayhem♦
Dec 20 '16 at 17:49
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));
}
}
;
as a lambda is an expression, not a statement. B) would Math.Sign
or Math::Sign
or something similar be a valid submission? Not sure how C# in particular handles methods. Basically, would x = Math.Sign;
be a valid C# statement if x
was initialized with the right type?
\$\endgroup\$
– Cyoce
Dec 25 '16 at 5:36
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