Formate a reputação

13

Você provavelmente sabe que os diferentes níveis de reputação no Stack Exchange são formatados de maneira diferente quando vistos na página de perguntas / uma postagem. Existem todas as regras de formatação de representantes:

  • se um usuário tiver de 1 a 999 (um a três dígitos) representante, ele fica como está.
  • se um usuário tiver de 1000 a 9999 repetições (quatro dígitos), ele receberá a vírgula como um separador: 9,999
  • se um usuário tiver 10000 a 99999 repetições (cinco dígitos), ele será reduzido e arredondado. Ou seja, 16741 rep é formatado como 16.7k, observe o separador de pontos ao contrário da vírgula do representante inferior (ponto anterior).

    1. Já resultará 16750 16.8k(já que isso parece estar corrigido )

    2. 16941 resulta em 16.9k, 16950 arredonda para cima 17k, assim como 17014, por exemplo.

    3. 99941 arredonda para 99.9k, 99950 arredonda para 100k(isso é algo que eu realmente odeio com o rep-arredondamento no SE, porque 100.000 é um marco e 99950 não está nem perto).

  • Se um usuário tiver 100000 a 999999 representantes, será arredondado da seguinte maneira:

    1. 100100 arredonda para baixo 100k, 100500 arredonda para cima 101k. O problema é que o arredondamento é feito, mas a parte decimal é removida (ao contrário do representante de quatro dígitos).

    2. 100450 arredonda para baixo 100k, nenhum passo para arredondar 450 a 500. Nem 100499 - ainda é 100k.

    3. 279843 arredonda para cima 280ke 399999 arredonda para 400k.

Como entrada, você recebe a reputação bruta e a produz como formatada.

Você pode considerar essa entrada não receberá números / não números inválidos ou números com zeros à esquerda, ou seja 0001234.

Como Jon Skeet não parece chegar a 1.000.000 em breve, seu código deve ser o mais curto possível , não sendo necessário lidar com o representante maior que um milhão (ou seja, sem casos especiais para 999500 e acima).

nicael
fonte
7
"Porque Jon Skeet parece não chegar a 1.000.000 em breve" [citação necessário]
Milo Brandt
@Milo Easy - ele ganhou 93k em 2015. Ele tem 163.685 restantes até 1.000.000, portanto, isso levará mais de 1,5 anos (quase 2, eu diria). Com isso, você também deve levar em consideração que seu representante anual está diminuindo a cada ano, desde 2011. 2011: 134.7k, 2012: 131.8k, 2013: 116.8k, 2014: 104.3k, 2015: 94.3k.
Nicael
A longa explicação, mas apesar de tudo, é apenas a maneira de arredondamento é usally feito
edc65
@ Edc Veja esta resposta por Peter Taylor.
Nicael
2
Eu acho que a explicação poderia ser reduzida, dizendo " Se o representante estiver no intervalo de 10000 a 994999 (ambos inclusos), ele será arredondado para 3 algarismos significativos usando a regra da metade, dividida por 1000 e exibida com .um ponto decimal e com um sufixo k; sujeito à ressalva de que, se o terceiro número significativo estiver 0e estiver à direita do ponto decimal, o valor será exibido apenas em 2 números significativos. "Os pontos de corte específicos podem ser movidos para uma única lista de testes casos no final da postagem, o que é mais conveniente para copiar e colar em uma estrutura de teste.
Peter Taylor

Respostas:

4

Japt, 50 48 bytes

Primeira tentativa; pode haver um método melhor.

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

Experimente online!

Como funciona

          // 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
ETHproductions
fonte
7

JavaScript (ES6), 76 68 bytes

x=>x<1e4?x.toLocaleString():(x<1e5?(x/1e2+.5|0)/10:(x/1e3+.5|0))+"k"

Outra primeira tentativa. Graças a Deus por isso acessível.toLocaleString() , a alternativa mais curta que pude encontrar é 21 bytes mais ...

Isso separa milhares por um ,ou ., dependendo do país em que você vive. Por cinco dois bytes a mais, você pode usar sempre uma vírgula:

x=>x<1e4?x.toLocaleString`en`:(x<1e5?(x/1e2+.5|0)/10:(x/1e3+.5|0))+"k"
ETHproductions
fonte
Sua localidade funciona bem para você, mas aqui na Itália eu recebo 1.234 (ponto em vez de vírgula)
edc65
@ edc65 Agora, esse é um problema que nunca pensei em encontrar com um código de golfe. Isso funciona agora?
ETHproductions
Perfeito. Realmente não achei que fosse factível. E eu tentei apenas 'en' e parece funcionar muito
edc65
Não acho que você precise ajustar o código de idioma, porque ele não precisa ser portátil.
precisa saber é
1
Basicamente, se funcionar no seu computador, acho que é bom o suficiente.
precisa saber é
3

JavaScript (ES6), 71

Derrotar @ETHProductions enquanto ele não vê minha dica. Ele viu isso.

x=>x<1e3?x:x<1e4?(x+='')[0]+','+x.slice(1):(x/1e3).toFixed(x<99950)+'k'

Teste

f=x=>x<1e3?x:x<1e4?(x+='')[0]+','+x.slice(1):(x/1e3).toFixed(x<99950)+'k'

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

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

Teste

edc65
fonte
1
Talvez você deva atualizar sua linha "superando ETHproductions" ...?
Conor O'Brien
@ CᴏɴᴏʀO'Bʀɪᴇɴ feito.
edc65
2

ES6, 68 62 bytes

x=>x<1e4?`${x}`.split(/(?=...)/)+"":x.toPrecision(3)/1e3+"k"

Edit: Salvo 6 bytes quando eu percebi que ["1", "001"]strings to "1,001".

Editar: salvou 2 bytes para corrigir o comentário de @ Mwr247!

Neil
fonte
16950dá em 16.9kvez de17k
Mwr247 13/01
@ Mwr247 Obrigado, a correção me salva mais dois bytes!
Neil
1

Python 2.7, 58 bytes

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

Eu tive que usar (x+.5)para lidar com o 16950->17kcaso ..

TFeld
fonte