35
\$\begingroup\$

The challenge

Given two integers as input (x and y), output x as a string with as many leading zeroes necessary for it to be y characters long without the sign.

Rules

  • If x has more than y digits, output x as string without modification.

  • Output as integer is not accepted, even if there are no leading zeroes.

  • When x is negative, keep the - as is and operate on the absolute value.

  • Negative y should be treated as 0, meaning you output x as is (but as string)

Examples:

IN: (1,1)   OUT: "1"
IN: (1,2)   OUT: "01"
IN: (10,1)  OUT: "10"
IN: (-7,3)  OUT: "-007"
IN: (-1,1)  OUT: "-1"
IN: (10,-1) OUT: "10"
IN: (0,0)   OUT: "0"
IN: (0,1)   OUT: "0"
IN: (0,4)   OUT: "0000"

Shortest code in bytes wins, standard loopholes apply.

\$\endgroup\$
9
  • \$\begingroup\$ sandbox: codegolf.meta.stackexchange.com/a/14264/69737 \$\endgroup\$
    – Brian H.
    Dec 1, 2017 at 9:49
  • 2
    \$\begingroup\$ Can I take x as string? \$\endgroup\$
    – LiefdeWen
    Dec 1, 2017 at 9:56
  • \$\begingroup\$ what does (-1,1) give? \$\endgroup\$
    – Adám
    Dec 1, 2017 at 9:59
  • \$\begingroup\$ @Adám added it to the examples. \$\endgroup\$
    – Brian H.
    Dec 1, 2017 at 10:42
  • 1
    \$\begingroup\$ Is a leading + sign acceptable for positive numbers? \$\endgroup\$ Dec 1, 2017 at 17:21

46 Answers 46

8
\$\begingroup\$

Pyth, 12 bytes

%"%0*d",+E>0

Try it here!

\$\endgroup\$
8
\$\begingroup\$

Python 2, 29 bytes

lambda x,y:x.zfill(y+(x<'.'))

Try it online!

Just str.zfill comes so close.

\$\endgroup\$
6
\$\begingroup\$

05AB1E, 11 10 bytes

Input given as amount_of_digits, number

ÎIÄg-×ì'-†

Try it online!

Explanation

Î            # push 0 and first input
 IÄ          # push the absolute value of the second input
   g         # length
    -        # subtract, (input1-len(abs(input2))
     ×       # repeat the zero that many times
      ì      # prepend to the second input
       '-†   # move any "-" to the front
\$\endgroup\$
3
  • \$\begingroup\$ Seems like this is the winning answer so far, if not bettered tomorrow i'll accept it. \$\endgroup\$
    – Brian H.
    Dec 4, 2017 at 10:16
  • \$\begingroup\$ you've been outgolfed :( \$\endgroup\$
    – Brian H.
    Dec 5, 2017 at 9:32
  • \$\begingroup\$ @BrianH. Indeed I have :) \$\endgroup\$
    – Emigna
    Dec 5, 2017 at 9:47
6
\$\begingroup\$

Python, 29 bytes

Take input as f(x,y). Using Python's % operator.

lambda x,y:'%0*d'%(y+(x<0),x)

Try it online!

\$\endgroup\$
5
\$\begingroup\$

C#, 56 bytes

Try it Online!

a=>b=>(a<0?"-":"")+((a<0?-a:a)+"").PadLeft(b<0?0:b,'0')
\$\endgroup\$
5
\$\begingroup\$

Java (OpenJDK 8), 47 bytes

x->y->"".format("%0"+((y<1?1:y)-(x>>31))+"d",x)

Try it online!

At first I thought, easy, 30 chars max (which is quite short when manipulating strings in Java). Then the exceptions happened.

\$\endgroup\$
5
\$\begingroup\$

JavaScript (ES6), 42

Recursive, parameters in reverse order, first y then x. And Currying

y=>r=x=>x<0?'-'+r(-x):`${x}`.padStart(y,0)

Test

var F=
y=>r=x=>x<0?'-'+r(-x):`${x}`.padStart(y,0)

;`IN: (1,1)   OUT: "1"
IN: (1,2)   OUT: "01"
IN: (10,1)  OUT: "10"
IN: (-7,3)  OUT: "-007"
IN: (-1,1)  OUT: "-1"
IN: (10,-1) OUT: "10"
IN: (0,0)   OUT: "0"
IN: (0,1)   OUT: "0"
IN: (0,4)   OUT: "0000"`
.split(`\n`).map(r => r.match(/[-\d]+/g))
.forEach(([x,y,k])=>{
  o = F(y)(x)
  ok = o == k
  console.log(ok?'OK':'KO',x,y,'->', o)
})

\$\endgroup\$
5
  • \$\begingroup\$ While impressive, I feel this answer skirts the rules slightly by defining the function f(y)(x) instead of f(x,y). \$\endgroup\$
    – styletron
    Dec 1, 2017 at 14:46
  • \$\begingroup\$ Reading up on the "currying" rules, I wanted to add that my objection was more with the reversed params and not with the currying itself. \$\endgroup\$
    – styletron
    Dec 1, 2017 at 14:58
  • 1
    \$\begingroup\$ @styletron the order of the parameters is not specified in the challenge. So I can take advantage of this \$\endgroup\$
    – edc65
    Dec 1, 2017 at 15:04
  • \$\begingroup\$ Dang, y=>r=x=>x<0?'-'+r(-x):(x+='')[y-1]?x:r(0+x) comes so close... \$\endgroup\$ Dec 2, 2017 at 0:01
  • \$\begingroup\$ i have no issues with people reversing the input order. \$\endgroup\$
    – Brian H.
    Dec 4, 2017 at 10:13
5
\$\begingroup\$

Python 3.6, 28 37 bytes

lambda x,y:f'{x:0{(y,0)[y<0]+(x<0)}}'

Try it online! (Test case from Colera Su's answer)

Taking advantage of the new way to format strings in python 3.6

+9 bytes to handle y<0

\$\endgroup\$
2
  • \$\begingroup\$ Looks like this fails when y is negative: tio.run/##K6gsycjPM/… \$\endgroup\$
    – Shaggy
    Dec 2, 2017 at 11:38
  • \$\begingroup\$ Indeed. So i'm up with 37 bytes. \$\endgroup\$
    – Lescurel
    Dec 2, 2017 at 14:22
5
\$\begingroup\$

bash, 27, 25 bytes

-2 bytes thanks to Bruce Forte

printf %0$[$2+($1<0)]d $1

try it online

\$\endgroup\$
2
  • 1
    \$\begingroup\$ You can save two bytes by inlining the padding length. Also another interesting one (28 bytes): printf %\ 0$[1+$1]d $2|xargs. \$\endgroup\$ Dec 2, 2017 at 17:55
  • \$\begingroup\$ maybe you mean printf %\ 0$[1+$2]d $1|xargs, i didn't remember this format for signed numbers also xargs trick to remove leading space \$\endgroup\$ Dec 2, 2017 at 19:28
5
\$\begingroup\$

Husk, 12 bytes

Ö±Ωo≥⁰#±:'0s

Try it online!

Explanation

Ö±Ωo≥⁰#±:'0s  Inputs are y=4 and x=-20
           s  Convert x to string: "-20"
        :'0   Prepend '0'
  Ω           until
      #±      the number of digits
   o≥⁰        is at least y: "00-20"
Ö±            Sort by is-digit: "-0020"
              Print implicitly.
\$\endgroup\$
5
\$\begingroup\$

R, 56 48 bytes

function(x,y)sprintf(paste0("%0",y+(x<0),"d"),x)

Try it online!

-8 bytes thanks to djhurio

Explanation

  • sprintf("%0zd",x) returns x as a string padded with zeros to be of length z
  • paste0("%0",y+(x<0),"d") constructs the string "%0zd", where z is y, plus 1 if x is less than zero
  • If z is less than the number of digits in x, x is printed as a string as is
\$\endgroup\$
3
  • \$\begingroup\$ 48 bytes function(x,y)sprintf(paste0("%0",y+(x<0),"d"),x) \$\endgroup\$
    – djhurio
    Dec 2, 2017 at 14:05
  • \$\begingroup\$ @djhurio brilliant! I think that would warrant another answer rather than an edit of mine, what do you say? \$\endgroup\$
    – duckmayr
    Dec 2, 2017 at 14:40
  • \$\begingroup\$ You can make it as an edit. This solution is not so much different, just using different function. \$\endgroup\$
    – djhurio
    Dec 2, 2017 at 18:14
4
\$\begingroup\$

Japt, 13 8 bytes

Takes first input (x) as a string.

®©ùTV}'-

Try it

Saved a massive 5 bytes thanks to ETHproductions.


Explanation

Implicit input of string U=x and integer V=y.

® }'- splits U to an array on the minus symbol, maps over it and rejoins it to a string with a minus symbol.

© is logical AND (&&) so if the current element is truthy (a non-empty string) then pad left (ù) with 0 (T) to length V.

\$\endgroup\$
5
  • \$\begingroup\$ Nice one! You can save quite a bit by simply mapping around -: ethproductions.github.io/japt/… \$\endgroup\$ Dec 1, 2017 at 19:40
  • \$\begingroup\$ @ETHproductions: Great call. Thanks. Been so long since I've done so, I'd completely forgotten you can split, map and rejoin a string all in one method! \$\endgroup\$
    – Shaggy
    Dec 1, 2017 at 20:59
  • \$\begingroup\$ Yes, I suppose that functionality should be moved to q, which would then be q-_©ùTV to save 1 byte :-) \$\endgroup\$ Dec 1, 2017 at 23:51
  • \$\begingroup\$ @ETHproductions, if I'm understanding that right, you're suggesting that if a function is passed as a second argument of S.q() (giving us S.q(s,f)) then S would be split on s, run through f and rejoined with s? I like it! :) \$\endgroup\$
    – Shaggy
    Dec 2, 2017 at 0:05
  • \$\begingroup\$ Yeah, did I talk to Oliver and not you about doing that (if passed a function, do the normal functionality, run through the function, and undo the first change; N.s, S/A.y, N.ì do this already) with a bunch of methods? I had a conversation with someone, I just can't remember who now :s \$\endgroup\$ Dec 2, 2017 at 0:31
4
\$\begingroup\$

Alice, 23 bytes

/oRe./'+Ao
\I*tI&0-R$@/

Try it online!

Input should be linefeed-separated with the number on the first line and the width on the second.

Explanation

/...
\...@/

This is the usual framework for linear programs in Ordinal mode. The only catch in this case is this bit:

.../...
...&...

This causes the IP to enter Cardinal mode vertically and execute just the & in Cardinal mode before resuming in Ordinal mode.

Unfolding the zigzag control flow then gives:

IRt.&'-A$o*eI/&/0+Ro@

I    Read the first line of input (the value) as a string.
R    Reverse the string.
t.   Split off the last character and duplicate it.
&    Fold the next command over this string. This doesn't really do anything,
     because the string contains only one character (so folding the next
     command is identical to executing it normally).
'-   Push "-".
A    Set intersection. Gives "-" for negative inputs and "" otherwise.
$o   If it's "-", print it, otherwise it must have been a digit which we
     leave on the stack.
*    Join the digit back onto the number. If the number was negative, this
     joins the (absolute value of the) number to an implicit empty string,
     doing nothing.
e    Push an empty string.
I    Read the width W.
/&/  Iterate the next command W times.
0    Append a zero. So we get a string of W zeros on top of the absolute
     value of the input number.
+    Superimpose. This takes the character-wise maximum of both strings
     and appends extraneous characters from the longer string. Since the
     string of zeros can never be larger than the digits in the input,
     the input itself will be uneffected, but extraneous zeros are appended,
     padding the string to the required length.
R    Reverse the result.
o    Print it.
@    Terminate the program.

Here are two alternatives, also at 23 bytes, which use Cardinal H (abs) to get rid of the -:

/R.I&0-RoH
\Ie#\'+Ao\@/

/R.H#/.+Xo
\Ie\I&0QRo@/

In principle, these are a command shorter, but the & doesn't fit into a position where there's a 1-character string on the stack, so we need to skip it with a #.

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

C, 33 bytes

f(x,y){printf("%0*d",y+(x<0),x);}

Try it online!

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

Charcoal, 16 13 bytes

‹N⁰﹪⁺⁺%0ηd↔Iθ

Try it online!

This is the shortest I could get using Charcoal without printing leading or trailing whitespaces. At least I am now starting to understand how to use the Modulo function to format strings.

The deverbosed code is as follows:

Print(Less(InputNumber(),0));    # Prints a - if the first input is less than 0
Print(Modulo(Add(Add("%0",h),"d"),Abs(Cast(q))));   # q: first input;  h: second input
  • 3 bytes saved thanks to Neil!
\$\endgroup\$
3
  • 1
    \$\begingroup\$ To print - or nothing is really easy in Charcoal: Printing 1 prints - while printing 0 prints nothing. So, the ternary is superfluous, saving 3 bytes. \$\endgroup\$
    – Neil
    Dec 1, 2017 at 12:29
  • \$\begingroup\$ If you swap the InputNumber() with the Cast(q), I think you can then switch to a string comparison to save another byte. \$\endgroup\$
    – Neil
    Dec 1, 2017 at 12:32
  • \$\begingroup\$ @Neil I knew that I could simplify the Ternary! \$\endgroup\$
    – Charlie
    Dec 1, 2017 at 12:45
4
\$\begingroup\$

Retina, 39 bytes

\d+$
$*0
((\d)*),(?<-2>-0+|0)*(0*)
$3$1

Try it online!

Input should be comma-separated with the number first and the width second.

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

PHP, 45 bytes

printf("%0".($argv[2]+(0>$n=$argv[1])).d,$n);

or

[,$n,$e]=$argv;printf("%0".($e+(0>$n)).d,$n);       # requires PHP 7.1 or later

Run with -nr or try them online.

\$\endgroup\$
3
  • \$\begingroup\$ Getting an error when executing the code in that link. \$\endgroup\$
    – Shaggy
    Dec 2, 2017 at 11:43
  • \$\begingroup\$ @Shaggy The second version requires PHP 7.1 \$\endgroup\$
    – Titus
    Dec 2, 2017 at 12:41
  • \$\begingroup\$ I went on and on about this, and I arrived to exactly this answer. I believe this is the optimal version \$\endgroup\$ Dec 2, 2017 at 16:38
3
\$\begingroup\$

Mathematica, 118 bytes

(j=ToString;If[#2<=0,j@#,If[(z=IntegerLength@#)>=#2,t=z,t=#2];s=j/@PadLeft[IntegerDigits@#,t];If[#>=0,""<>s,"-"<>s]])&


Try it online!

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

Mathematica, 63 62 bytes

If[#<0,"-",""]<>IntegerString[#,10,Max[#2,IntegerLength@#,1]]&

Try it online!

\$\endgroup\$
2
  • 2
    \$\begingroup\$ Welcome to PPCG! I think this isn't quite doing what you want. You probably meant IntegerLength instead of IntegerDigits. You can save a byte by using IntegerLength@# instead of IntegerLength[#] though. \$\endgroup\$ Dec 1, 2017 at 17:47
  • \$\begingroup\$ Thank you! I was copying the code from another computer by hand where I was testing it and I indeed mistyped IntegerDigits for IntegerLength. It should work now. I have also added a TIO link with all the test cases in the challenge description (+1) showing that it works as expected. Thank you also for the suggestion for saving an extra byte! I don't know how I missed it before. :) \$\endgroup\$
    – MatjazGo
    Dec 4, 2017 at 9:52
2
\$\begingroup\$

Excel, 29 bytes

Using Excel's TEXT functionality ("Converts a value to text in a specific number format").

x in A1, y in B1

=TEXT(A1,REPT("0",MAX(1,B1)))
\$\endgroup\$
1
  • \$\begingroup\$ You can drop the ))) for -3 Bytes by converting to Google Sheets \$\endgroup\$ Dec 18, 2017 at 17:46
2
\$\begingroup\$

Octave, 44 bytes

@(x,y)fprintf(['%0',num2str(y+(x<0)),'d'],x)

Try it online!

\$\endgroup\$
2
  • 1
    \$\begingroup\$ For 31 bytes \$\endgroup\$ Dec 1, 2017 at 17:24
  • \$\begingroup\$ If leading + signs are allowed for positive numbers (waiting to hear from op if ok), this works for 28. \$\endgroup\$ Dec 1, 2017 at 17:25
2
\$\begingroup\$

Haskell, 54 bytes

x#y|s<-show$abs$x=['-'|x<0]++('0'<$[length s+1..y])++s

Try it online!

\$\endgroup\$
0
2
\$\begingroup\$

Perl 5, 22 + 1 (-n) = 23 bytes

printf"%0*d",<>+/-/,$_

Try it online

\$\endgroup\$
6
  • \$\begingroup\$ Loops infinitely on 10,-1 \$\endgroup\$
    – Zaid
    Dec 1, 2017 at 13:31
  • \$\begingroup\$ fixed +5 bytes \$\endgroup\$ Dec 1, 2017 at 14:07
  • \$\begingroup\$ found another solution -5 bytes \$\endgroup\$ Dec 1, 2017 at 14:25
  • \$\begingroup\$ Sweet. I'm working on one as well... stay tuned \$\endgroup\$
    – Zaid
    Dec 1, 2017 at 14:28
  • \$\begingroup\$ I managed it in 26 bytes \$\endgroup\$
    – Zaid
    Dec 1, 2017 at 14:45
2
\$\begingroup\$

Ruby, 31 28 bytes

Thanks Carl for saving 3 bytes using interpolation.

->x,y{"%0#{y+(x<0?1:0)}d"%x}

Try it online!

\$\endgroup\$
1
  • 2
    \$\begingroup\$ 28: ->x,y{"%0#{y+(x<0?1:0)}d"%x} \$\endgroup\$
    – Carl
    Dec 1, 2017 at 17:44
2
\$\begingroup\$

Japt, 14 12 bytes

Saved 2 bytes thanks to @ETHproductions

s r"%d+"_ù0V

Try it online

\$\endgroup\$
5
  • \$\begingroup\$ It's a bit cheaper to keep the minus sign in and just mess with the digits: Test it online \$\endgroup\$ Dec 1, 2017 at 17:03
  • \$\begingroup\$ @ETHproductions: Or take x as a string for 10 bytes. \$\endgroup\$
    – Shaggy
    Dec 1, 2017 at 17:23
  • \$\begingroup\$ @ETHproductions thanks fellas. I'll update it when I get back to my desk. \$\endgroup\$
    – Oliver
    Dec 1, 2017 at 18:55
  • \$\begingroup\$ @Shaggy Looks like you posted your own answer, so I'll use ETHproduction's trick. Thanks though. \$\endgroup\$
    – Oliver
    Dec 1, 2017 at 20:29
  • \$\begingroup\$ Oliver, that 10-byter is just @ETHproduction's 12-byte solution upgraded to Japt 2.0a0 with U as a string allowing us to golf off the first 2 characters. \$\endgroup\$
    – Shaggy
    Dec 1, 2017 at 21:08
2
\$\begingroup\$

PowerShell, 25 40 bytes

param($a,$b)$a|% *g $("D$b"*($b|% *o 0))

Try it online!

Explanation

This calls .ToString() on the number with a generated format string, but multiplies it by -1, 0, or 1 based on whether $b (y) is negative, 0, or positive respectively; this is to handle negative y values which format strings don't by themselves.

This seems to require wrapping negative numbers in a substatement () for it to work which is just a quirk of the invocation when using literals; if passed variables of type integer, it would not need that.

\$\endgroup\$
4
  • \$\begingroup\$ It looks like both of these fail when y is negative. \$\endgroup\$
    – Shaggy
    Dec 2, 2017 at 11:45
  • \$\begingroup\$ @Shaggy ugh good catch. Removed second solution altogether and fixed up the first, thanks! \$\endgroup\$
    – briantist
    Dec 2, 2017 at 16:02
  • \$\begingroup\$ Ouch, 15 bytes! Sorry! \$\endgroup\$
    – Shaggy
    Dec 2, 2017 at 18:54
  • \$\begingroup\$ @Shaggy heh, one of these days I'll actually write the PowerShell-based golfing language I've been thinking about. This actually pushed me to research a bit more and get closer to starting it, so thanks for that ;) \$\endgroup\$
    – briantist
    Dec 2, 2017 at 18:56
2
\$\begingroup\$

C# 6.0, 35 bytes

(x,y)=>(x.ToString($"D{y<0?0:y}"));

Alternative solution (51 bytes)

(x,y)=>(x.ToString(string.Format("D{0}",y<0?0:y)));
\$\endgroup\$
2
\$\begingroup\$

Clean, 90 86 83 bytes

import StdEnv
@x y=if(y<0)"-"""+++{if(c>'-')c'0'\\c<-rjustify x[k\\k<-:toString y]}

Try it online!

\$\endgroup\$
1
\$\begingroup\$

C (gcc), 45 bytes

f(x,y){printf("%s%0*i","-"+(x>=0),y,abs(x));}

Try it online!

Explanation

printf formats three arguments:

%s      ->    "-"+(x>=0)
%0*i    ->    y
        ->    abs(x)

%s formats the string "-"+(x>=0). "-" is really just an address, something like 41961441. In memory, this looks something like this:

MEMORY ADDRESS | 41961441  41961442 ...
VALUE          | 45 ('-')  0 (0x00) ...

When formatted into a string, C takes the address (say 41961441) and keeps on acquiring characters until a null byte (0x00) is met. When x is less than zero, the value "-"+(x>=0) has that of the original address (41961441). Otherwise, x>=0 is 1, so the expression becomes "-"+1, which points the null byte after "-", which prints nothing.

%0*i prints an integer padded with a specified number of 0s. y denotes this number. We pad abs(x) to avoid the negative in some arguments.

\$\endgroup\$
1
\$\begingroup\$

Perl, 25 + -n flag = 26 bytes

printf"%0*d",<>+($_<0),$_

Try it online!

\$\endgroup\$

Your Answer

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

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