Programming Puzzles & Code Golf Stack Exchange is a question and answer site for programming puzzle enthusiasts and code golfers. It's 100% free, no registration required.

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

You probably do know that the different reputation levels on Stack Exchange are formatted differently when seen from the questions page / a post. There're all the rep-formatting rules:

  • if a user has 1 to 999 (one to three digits) rep, it's left as-is.
  • if a user has 1000 to 9999 rep (four digits), it receives the comma as a separator: 9,999
  • if a user has 10000 to 99999 rep (five digits), it's shortened and rounded. I.e., 16741 rep is formatted as 16.7k, notice the dot separator unlike the comma for the lower rep (previous point).

    1. 16750 will already result 16.8k (since this seems to be fixed)

    2. 16941 results in 16.9k, 16950 rounds up to 17k, as well as does 17014, for example.

    3. 99941 rounds to 99.9k, 99950 rounds to 100k (this is something I actually hate with the rep-rounding on SE, because 100,000 is such a milestone, and 99950 is nowhere near).

  • If a user has 100000 to 999999 rep, it's rounded this way:

    1. 100100 rounds down to 100k, 100500 rounds up to 101k. The thing is, the rounding is done, but the decimal part is stripped (unlike the four-digits rep).

    2. 100450 rounds down to 100k, no step to round 450 to 500. Nor does 100499 - it's still 100k.

    3. 279843 rounds up to 280k, and 399999 rounds to 400k.

As input, you're given the raw reputation, and output it as formatted.

You can consider that input won't receive any invalid numbers / non-numbers, or numbers with leading zeros, i.e. 0001234.

Because Jon Skeet doesn't seem to be reaching 1,000,000 soon, your code must be as short as possible you don't need to handle the rep greater than one million (i.e. no special cases for 999500 and above).

share|improve this question
"Because Jon Skeet doesn't seem to be reaching 1,000,000 soon" [citation needed] – Milo Brandt Jan 12 at 19:20
@Milo Easy - he earned 93k for 2015. He has 163,685 left until 1,000,000, so this way it will take him more than 1,5 years (almost 2, I'd say). With this, you should also take into account that his yearly rep is decreasing with each year, since 2011. 2011: 134.7k, 2012: 131.8k, 2013: 116.8k, 2014: 104.3k, 2015: 94.3k. – nicael Jan 12 at 20:08
A long explanation, but all in all, it's just the way rounding is usally done – edc65 Jan 12 at 21:04
@Edc See this answer by Peter Taylor. – nicael Jan 12 at 21:22
I think the explanation could be shortened by saying "If the rep is in the range 10000 to 994999 (both inclusive), it is rounded to 3 significant figures using the half-up rule, divided by 1000, and displayed with . for a decimal point and with a suffixed k; subject to the caveat that if the third significant figure is 0 and is to the right of the decimal point then the value is displayed only to 2 significant figures." The specific cutoffs could then be moved to a single list of test cases at the end of the post, which is more convenient for copy-pasting into a test framework. – Peter Taylor Jan 12 at 22:05

JavaScript (ES6), 76 68 bytes


Another first attempt. Thank goodness for that handy .toLocaleString(), the shortest alternative I could find is 21 bytes longer...

This separates thousands by either , or ., depending on what country you live in. For five two bytes more, you can make it always use a comma:

share|improve this answer
Your locale works fine for you, but here in Italy I get 1.234 (dot instead of comma) – edc65 Jan 12 at 20:48
@edc65 Now that's a problem I never thought I would run into with a code golf. Does it work now? – ETHproductions Jan 12 at 20:51
Perfect. Really I didn't think that was doable. And I tried just 'en' and it seems to work too – edc65 Jan 12 at 21:01
I don't think you need to adjust for locale, because it doesn't need to be portable. – geokavel Jan 12 at 21:13
Basically, if it works on your computer, I think it's good enough. – geokavel Jan 12 at 21:16

Japt, 50 48 bytes

First attempt; there may be a better method.

U<A³?U:U<L²?Us i1', :(U<1e5?Ue2n)r /A:Ue3n)r)+'k

Try it online!

How it works

          // Implicit: U = input integer, A = 10, L = 100
U<A³?U    // If U is less than A³ (10³ = 1000), return U.
:U<L²?    // Else, if U is less than L² (100² = 10000), return:
Us i1',   //  U.toString, with a comma inserted at position 1.
:(        // Else, return:
U<1e5?    //  If U is less than 1e5:
Ue2n)     //   U * (10 to the power of -2), 
r /A      //   rounded and divided by 10.
:Ue3n)r)  //  Else: U * (10 to the power of -3), rounded.
+'k       //  Either way, add a "k" to the end.
          // Implicit: output last expression
share|improve this answer

JavaScript (ES6), 71

Beating @ETHProductions while he does not see my hint. He saw it.




function test() { n=+I.value, O.textContent = n + ' -> ' + f(n) }

<input id=I type=number value=19557 oninput=test()>
<pre id=O></pre>


share|improve this answer
Perhaps you should update your "beating ETHproductions" line...? – Cᴏɴᴏʀ O'Bʀɪᴇɴ Jan 12 at 22:30
@CᴏɴᴏʀO'Bʀɪᴇɴ done. – edc65 Jan 12 at 22:43

ES6, 68 62 bytes


Edit: Saved 6 bytes when I realised that ["1", "001"] stringifies to "1,001".

Edit: Saved 2 bytes to fix @Mwr247's comment!

share|improve this answer
16950 gives 16.9k instead of 17k – Mwr247 Jan 13 at 6:02
@Mwr247 Thanks, the fix saves me two more bytes! – Neil Jan 13 at 8:37

Python 2.7, 58 bytes

lambda x:['%.3g'%((x+.5)/1e3)+'k','{:,}'.format(x)][x<1e4]

I had to use (x+.5) to deal with the 16950->17k case..

share|improve this answer

Your Answer


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.