Programming Puzzles & Code Golf Stack Exchange is a question and answer site for programming puzzle enthusiasts and code golfers. Join them; it only takes a minute:

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

Given an integer, make an expression that produces it from 0 using unary negation - and bitwise complement ~ (~n = -n-1), with the operators applied right to left.

...
-3  = ~-~-~0
-2  = ~-~0
-1  = ~0
 0  = 0
 1  = -~0
 2  = -~-~0
 3  = -~-~-~0
...

Your expression must be as short as possible, which means no redundant parts of ~~, --, -0, or 00. Output or print the expression as a string or a sequence of characters.

var QUESTION_ID=92598,OVERRIDE_USER=20260;function answersUrl(e){return"https://api.stackexchange.com/2.2/questions/92598/answers?page="+e+"&pagesize=100&order=desc&sort=creation&site=codegolf&filter="+ANSWER_FILTER}function commentUrl(e,s){return"https://api.stackexchange.com/2.2/answers/"+s.join(";")+"/comments?page="+e+"&pagesize=100&order=desc&sort=creation&site=codegolf&filter="+COMMENT_FILTER}function getAnswers(){jQuery.ajax({url:answersUrl(answer_page++),method:"get",dataType:"jsonp",crossDomain:!0,success:function(e){answers.push.apply(answers,e.items),answers_hash=[],answer_ids=[],e.items.forEach(function(e){e.comments=[];var s=+e.share_link.match(/\d+/);answer_ids.push(s),answers_hash[s]=e}),e.has_more||(more_answers=!1),comment_page=1,getComments()}})}function getComments(){jQuery.ajax({url:commentUrl(comment_page++,answer_ids),method:"get",dataType:"jsonp",crossDomain:!0,success:function(e){e.items.forEach(function(e){e.owner.user_id===OVERRIDE_USER&&answers_hash[e.post_id].comments.push(e)}),e.has_more?getComments():more_answers?getAnswers():process()}})}function getAuthorName(e){return e.owner.display_name}function process(){var e=[];answers.forEach(function(s){var r=s.body;s.comments.forEach(function(e){OVERRIDE_REG.test(e.body)&&(r="<h1>"+e.body.replace(OVERRIDE_REG,"")+"</h1>")});var a=r.match(SCORE_REG);a&&e.push({user:getAuthorName(s),size:+a[2],language:a[1],link:s.share_link})}),e.sort(function(e,s){var r=e.size,a=s.size;return r-a});var s={},r=1,a=null,n=1;e.forEach(function(e){e.size!=a&&(n=r),a=e.size,++r;var t=jQuery("#answer-template").html();t=t.replace("{{PLACE}}",n+".").replace("{{NAME}}",e.user).replace("{{LANGUAGE}}",e.language).replace("{{SIZE}}",e.size).replace("{{LINK}}",e.link),t=jQuery(t),jQuery("#answers").append(t);var o=e.language;/<a/.test(o)&&(o=jQuery(o).text()),s[o]=s[o]||{lang:e.language,user:e.user,size:e.size,link:e.link}});var t=[];for(var o in s)s.hasOwnProperty(o)&&t.push(s[o]);t.sort(function(e,s){return e.lang>s.lang?1:e.lang<s.lang?-1:0});for(var c=0;c<t.length;++c){var i=jQuery("#language-template").html(),o=t[c];i=i.replace("{{LANGUAGE}}",o.lang).replace("{{NAME}}",o.user).replace("{{SIZE}}",o.size).replace("{{LINK}}",o.link),i=jQuery(i),jQuery("#languages").append(i)}}var ANSWER_FILTER="!t)IWYnsLAZle2tQ3KqrVveCRJfxcRLe",COMMENT_FILTER="!)Q2B_A2kjfAiU78X(md6BoYk",answers=[],answers_hash,answer_ids,answer_page=1,more_answers=!0,comment_page;getAnswers();var SCORE_REG=/<h\d>\s*([^\n,]*[^\s,]),.*?(\d+)(?=[^\n\d<>]*(?:<(?:s>[^\n<>]*<\/s>|[^\n<>]+>)[^\n\d<>]*)*<\/h\d>)/,OVERRIDE_REG=/^Override\s*header:\s*/i;
body{text-align:left!important}#answer-list,#language-list{padding:10px;width:290px;float:left}table thead{font-weight:700}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="//cdn.sstatic.net/codegolf/all.css?v=83c949450c8b"> <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><div id="language-list"> <h2>Winners 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><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>

share|improve this question
6  
So... you want us to put our thing down, flip it and reverse it? – Jordan 2 days ago
1  
whitespace between ~ and 0 allowed? – Adám 2 days ago
    
No, output the strings exactly. – xnor 2 days ago
2  
Obligatory xkcd.com/153 – Jared Smith yesterday

29 Answers 29

Python, 32 bytes

lambda x:("-~"*abs(x))[x<0:]+"0"

Anonymous lambda function. Given an integer x writes "-~" abs(x) times and removes the first char if x is negative, then a zero is added to the end.

share|improve this answer
    
Aw, beat me to it. – mbomb007 2 days ago
    
I just wrote the same too - with n in the place of x and ' in the place of " :) – Jonathan Allan 2 days ago
2  
@JonathanAllan Then you can safely consider it a dupe. – Erik the Golfer 2 days ago

JavaScript (ES6), 33 31 bytes

f=x=>x<0?"~"+f(~x):x&&"-"+f(-x)

Recursion < built-ins < loops (at least in this case). Basically unevaluates the input:

  • if it's less than 0, flip it and add a ~ to the string;
  • if it's more than 0, negate it and add a - to the string;
  • if it's exactly 0, return 0.

Takes advantage of this pattern:

 0         = 0
-1 = ~( 0) = ~0
+1 = -(-1) = -~0
-2 = ~(+1) = ~-~0
+2 = -(-2) = -~-~0
-3 = ~(+2) = ~-~-~0
+3 = -(-3) = -~-~-~0
etc.
share|improve this answer

05AB1E, 14 13 bytes

Ä„-~×¹0‹i¦}0J

Explanation

 „-~           # the string "-~"
Ä   ×          # repeated abs(input) times
     ¹0‹i¦}    # if input is negative, remove the first char
           0J  # join with 0

Try it online!

share|improve this answer

Pyth, 14 13 12 Bytes

_<>0Q+0sm"~-

-2 Bytes thanks to @StevenH.

test suite

Decided to try out Pyth, so i translated my python answer to it. Any help welcome!

Explanation:

_<>0Q+0sm"~-     
        m"~-     # Map "~-" onto the input (= a list of n times "~-").
       s         # Join the list to a string.
     +0          # Add "0" in front. 
 <>0Q            # Slice off the last char if the input is negative.
_                # Reverse the whole thing.
share|improve this answer
    
Use implicit input at the end to save one byte: >0 instead of <Q0 – Steven H. 2 days ago
    
@StevenH. Thank you! Now we're in a tie with the shortest answer! – KarlKastor 2 days ago
2  
Very different solution (that, unfortunately, doesn't save any bytes): tW>0Q_+0sm"~- – Steven H. 2 days ago
2  
@StevenH. Golfed your solution down to 12: _<>0Q+0sm"~- I hope your okay with me adding this to my solution. – KarlKastor 2 days ago

C, 46 bytes

m(x){putchar(x?x<0?126:45:48);x&&m(-x-(x<0));}

Unlike most (all?) other answers, this one outputs the operators ~ and - one by one.

share|improve this answer

Retina, 19 17 bytes

Replace the number with unary, with a zero on the end. Replace each 1 with -~. Remove double negative if there is one.

\d+
$*10
1
-~
--

Try it online

All test cases at once (slightly modified program to support multiple test cases)

share|improve this answer
2  

Perl 38 35 33 (23 + 1 for -p) 24

s/\d+/"-~"x$&.0/e;s;--;

-13 thanks to Dada

share|improve this answer
    
You probably meant -p instead of -r. Also you can get rid of those last parenthesis and semicolon : if$h<0 is enough. – Dada 2 days ago
    
I did, thanks. I've been writing too many answers in sed I guess. – Riley 2 days ago
    
Probably, yea. (Get rid of the last 2 parenthesis too) – Dada 2 days ago
    
You can also save 2 bytes by doing $h<0&&s;.; instead of s/.// if $h<0. (-p adds a ; at the end of the code, so no need for the last ; of s;.;;. And a if b is roughly equivalent to b && a, but in this case it saves you one byte because you can remove the space) – Dada 2 days ago
    
Thanks, I didn't know -p added a ; too. – Riley 2 days ago

Dyalog APL, 18 bytes

'0',⍨0∘>↓'-~'⍴⍨2×|

'0',⍨ character zero appended to

0∘> negativeness (i.e. 1 for numbers under 0; 0 for zero and up)

dropped from

'-~'⍴⍨ the string "~-" cyclically reshaped to length

two times

| the absolute value

+ plus

0∘< positiveness (i.e 1 for numbers over 0)

TryAPL online!

share|improve this answer

Haskell, 41 bytes

f n=['-'|n>0]++(tail$[1..abs n]>>"-~")++"0"

f n|n<0=tail$f(-n)|x<-[1..n]>>"-~"=x++"0"

Thanks to nimi for 3 bytes

share|improve this answer
    
tail fails for n=0. You can use drop 1 instead. – nimi 2 days ago
    
@nimi Thanks; I have no idea how I missed that.. – BlackCap 2 days ago
1  
Don't waste the otherwise guard: f n|n<0=tail.f$abs n|x<-[1..n]>>"-~"=x++"0". – nimi 2 days ago
1  
2 bytes to save: ...|n<0=tail$f(-n)|.... – nimi 2 days ago

V, 21 bytes

/ä
é
D@"ña-~ñá0kgJó--

Try it online!

V has very limited number support, and it actually has no concept of negative numbers. This means in order to support negatives (or even 0), we have to use some hacky workarounds.

Explanation:

/ä                  "Move forward to the first digit
é                   "And enter a newline
D                   "Delete this number, into register '"'
 @"                 "That number times:
   ñ   ñ            "Repeat the following:
    a               "  Append the string:
     -~             "  '-~'
        á0          "Append a 0
          k         "Move up a line
           gJ       "And join these two lines together
             ó--    "Remove the text '--', if it exists
share|improve this answer

Java 7, 95 79 bytes

79 bytes:

String s(int x){String t=x<0?"~":"";while((x<0?++x:x--)!=0)t+="-~";return t+0;}

Ungolfed:

String s(int x) {
    String t = x<0 ? "~" : "";
    while((x<0 ? ++x : x--) != 0)
        t += "-~";
    return t+0;
}

Old version (95 bytes):

String s(int x){return new String(new char[x<0?-x:x]).replace("\0","-~").substring(x<0?1:0)+0;}

Usage:

class A {
    public static void main(String[]a) {
        System.out.println(s(-3));
        System.out.println(s(-2));
        System.out.println(s(-1));
        System.out.println(s(0));
        System.out.println(s(1));
        System.out.println(s(2));
        System.out.println(s(3));
    }
    static String s(int x){String t=x<0?"~":"";while((x<0?++x:x--)!=0)t+="-~";return t+0;}
}

Try it here!

Output:

~-~-~0
~-~0
~0
0
-~0
-~-~0
-~-~-~0
share|improve this answer
    
Hi, and welcome to PPCG! Nice first post! – Easterly Irk 2 days ago
    
Welcome to PPCG! Hmm, that's a shorter solution than mine, so I will delete my answer and upvote yours instead. :) – Kevin Cruijssen 2 days ago

EXCEL: 55 33 bytes

=REPT("-~",IF(A1>0,A1,ABS(A1)-1))&"0"

Input is in the form of putting a number in the A1 cell. Formula can go anywhere except A1.

share|improve this answer
    
I don't think it works for negative numbers... – pajonk yesterday

Ruby, 35 bytes

->x{("-~"*x.abs+?0)[(x<0?1:0)..-1]}
share|improve this answer

JavaScript (ES6), 39 37 bytes

x=>"-~".repeat(x<0?-x:x).slice(x<0)+0

Saved 2 bytes thanks to @Neil

share|improve this answer

Jelly, 10 bytes

A⁾-~ẋḊẋ¡N0

This is a full program. Try it online!

How it works

A⁾-~ẋḊẋ¡N0  Main link. Argument: n

A           Take the absolute value of n.
 ⁾-~ẋ       Repeat the string "-~" that many times. Result: s
       ¡    Conditional application:
     Ḋ        Dequeue; remove the first element of s...
      ẋ N     if s, repeated -n times, is non-empty.
         0  Print the previous return value. Set the return value to 0.
            (implicit) Print the final return value.
share|improve this answer

Matlab, 61 bytes

x=input('');A=repmat('-~',1,abs(x));disp([A((x<0)+1:end) 48])
share|improve this answer

Pyke, 14 13 bytes

X,"-~"*Q0<>0+

Try it here!

share|improve this answer

Perl 6, 25 bytes

{substr '-~'x.abs~0,0>$_}

Explanation:

{
  substr
    # string repeat 「-~」 by the absolute value of the input
    '-~' x .abs

    # concatenate 0 to that
    ~ 0

    ,

    # ignore the first character of the string if it is negative
    0 > $_
}
share|improve this answer

Jelly, 14 12 bytes

-2 bytes thanks to @Dennis (return 0 rather than concatenate "0", making this a full program only.)

0>‘
A⁾-~ẋṫÇ0

Test it at TryItOnline

How?

0>‘      - link 1 takes an argument, the input
0>       - greater than 0? 1 if true 0 if false
  ‘      - increment

A⁾-~ẋṫÇ0 - main link takes an argument, the input
      Ç  - y = result of previous link as a monad
A        - x = absolute value of input
 ⁾-~     - the string "-~"
    ẋ    - repeat the sting x times
     ṫ   - tail repeatedString[y:] (y will be 1 or 2, Jelly lists are 1-based)
       0 - implicit print then return 0
share|improve this answer

T-SQL, 87 bytes

select substring(replicate('-~',abs(x)),case when x<0then 2 else 1 end,x*x+1)+'0'from #

The x*x+1 condition in substring is sufficient, since x^2+1>=2*abs(x) for all x.

As usually in SQL, the input is stored in a table:

create table # (x int)

insert into # values (0)
insert into # values (1)
insert into # values (-1)
insert into # values (2)
insert into # values (-2)
share|improve this answer

CJam, 18 14 bytes

Took some inspiration from Emigna's answer to save 4 bytes.

li_z"-~"*\0<>0

Try it online! (As a linefeed-separated test suite.)

Explanation

li      e# Read input and convert to integer N.
_z      e# Duplicate and get |N|.
"-~"*   e# Repeat this string |N| times.
\0<     e# Use the other copy of N to check if it's negative.
>       e# If so, discard the first '-'.
0       e# Put a 0 at the end.
share|improve this answer

PseudoD, 688 bytes

utilizar mate.pseudo
utilizar entsal.pseudo
adquirir numero
adquirir abs
adquirir relleno
adquirir indice
fijar numero a llamar LeerPalabra finargs
si son iguales numero y CERO
llamar EscribirLinea {0} finargs
salir
fin
fijar abs a llamar ValorAbsoluto numero finargs
fijar indice a CERO
si comparar Importar.Ent.Comparar numero < CERO
fijar relleno a {~}
sino
fijar relleno a {-}
fin
mientras comparar Importar.Ent.Comparar indice < abs
llamar Escribir relleno finargs
si son iguales relleno y {~}
fijar relleno a {-}
Importar.Ent.Sumar indice UNO indice
sino
fijar relleno a {~}
fin
finbucle
si son iguales relleno y {~}
llamar Escribir {~} finargs
fin
llamar EscribirLinea {0} finargs

Explain:

Read a number from STDIN;
If the number is zero (0); Then:
    Writes 0 to STDOUT and exits;
End If;
If the number is less than zero (0); Then:
    Set the fill character to "~";
Else:
    Set the fill character to "-";
End If;
For i = 0; While i is less than abs(number); do:
    Write the fill character to STDOUT;
    If the fill character is "~":
        Set the fill character to "-"
        Increment i by one
    Else:
        Set the fill character to "~"
    End if;
End for;
If the fill character is "~"; Then:
    Write "~" to STDOUT;
End If;
Write "0" to STDOUT
share|improve this answer

Vim - 31 keystrokes

First vim golf, prolly missed a ton of stuff.

`i-~<esc>:s/-\~-/\~-/dwp<left>ii<esc><left>d$@"<esc>a0`
share|improve this answer
    
Nice, welcome to the club! :) You could do :s/^- instead of :s/-\~/\~- and D instead of d$ – DJMcMayhem yesterday
    
Now that I think about it, I don't think this handles 0. You could get around this by incrementing before deleting with <C-a> and then deleting two characters off the end. – DJMcMayhem yesterday
    
@DJMcMayhem oh, 0i doesn't work? – Maltysen yesterday
    
No, unfortunately not. 0 moves the cursor to the first character on the current row. You can sorta use 0 as a count in V though. – DJMcMayhem yesterday

PHP, 61 bytes

if(0>$n=$argv[1]){echo"~";$n=~$n;}echo str_repeat("-~",$n),0;
share|improve this answer

><>, 18 + 3 = 22 bytes

:?!n0$-:0):1go-
-~

Try it online! +3 bytes for the ​ -v flag to initialise the stack with the input. If assuming that STDIN is empty is okay, then the following is a byte shorter:

:?!ni*:0):1go-
-~

The program keeps flipping the input n as necessary until it reaches 0, after which it errors out.

[Loop]
:?!n      If n is 0, output it as a num. If this happens then the stack is now
          empty, and the next subtraction fails
0$-       Subtract n from 0
:0)       Push (n > 0)
:1go      Output the char at (n>0, 1) which is a char from the second line
-         Subtract, overall updating n -> -n-(n>0)
share|improve this answer

PHP, 58 bytes

<?=((0<$a=$argv[1])?'-':'').str_pad('0',2*abs($a),'~-',0);
share|improve this answer

Labyrinth, 25 bytes

`?+#~.
.  ; 6
54_"#2
  @!

Try it online!

Explanation

I really like the control flow in this one. The IP runs in a figure 8 (or actually a ∞, I guess) through the code to reduce the input slowly to 0 while printing the corresponding characters.

The code starts in the upper left corner going right. The ` doesn't do anything right now. ? reads the input and + adds it to the implicit zero below. Of course that doesn't do anything either, but when we run over this code again, ? will push a zero (because we're at EOF), and + will then get rid of that zero.

Next the # pushes the stack depth, simply to ensure that there's a positive value on the stack to make the IP turn south, and ; discards it again.

The " is a no-op and acts as the main branch of the code. There are three cases to distinguish:

  • If the current value is positive, the IP turns right (west) and completes one round of the left loop:

    _45.`?+
    _45      Push 45.
       .     Print as character '-'.
        `    Negate the current value (thereby applying the unary minus).
         ?+  Does nothing.
    
  • If the current value is negative, the IP turns left (east) and the following code is run:

    #26.~
    #        Push stack depth, 1.
     26      Turn it into a 126.
       .     Print as character '~'.
        ~    Bitwise NOT of the current value (applying the ~).
    

    Note that these two will alternate (since both change the sign of the input) until the input value is reduced to zero. At that point...

  • When the current value is zero, the IP simply keeps moving south, and executes the ! and then turns west onto the @. ! prints the 0 and @ terminates the program.
share|improve this answer

Octave, 51 bytes

x=input('');[("-~"'*[1:abs(x)>0])((x<0)+1:end),'0']

At first blatantly copying the Matlab approach by @pajonk and then modifying some details, rewriting as an "outer product" between a vector of ones and the characters "-~" and abusing on-the-fly-indexing (or what it could be called) lets us save some bytes. It still pains me slightly that I can't get the index expression to take fewer bytes.

Octave allows a(i1)(i2) or even (...)(i1)(i2) for indexing where Matlab would want us to store variables in between the indexings.

((x<0)+1:end)

is far too long to describe "skip first if". There must be a better way.

share|improve this answer

GolfScript, 30 bytes

~." = ""-~"@abs*2$0<{(;}{}if 0

Input: -5

Output: -5 = ~-~-~-~-~0

Explanation

~.     # Input to integer and duplicate
" = "  # Push string to print
"-~"   # We shall output a repetition of this string
@abs   # Move the input onto the stack and computes abs
*      # Multiply "-~" for abs(input) times
2$     # Copy onto the stack the input
0<     # Is it less than 0?
{(;}   # Yes: remove first '-' from the output
{}if   # No: do nothing
0      # Push 0

Try it online!

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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