¡Vamos a abreviar esos números! Ahora revertir?

11

Introducción:

Al igual que Twitter e Instagram y otros, quería mostrar números como 1.2Ky en 3.8 Mlugar de 1,222o 3,823,456.

¡Pero eso no es todo! Como todos sabemos, puede haber algunos seres humanos a quienes sin duda no les gustarán estas abreviaturas y tratarán de revertirlas. Entonces, 1.2kse convertirá 1,200y 3.8 Mse convertirá 3,800,000.

La tarea:

  • su tarea es escribir un programa o una función que convierta una lista de números ( que se dan como cadenas ) en sus pares abreviados y viceversa.

Por ejemplo, si la lista de entrada (o alguna STDIN) era ['1.4k', '1,234,567', '7.99M'], entonces debería generar:

['1,400', '1.2M', '7,990,000']

Puede seguir el siguiente esquema para abreviaturas:

  • 10 3 -> un kilo -> K
  • 10 6 -> un millón -> M
  • 10 9 -> mil millones -> B

Su código puede asumir todas las minúsculas, mayúsculas, mayúsculas y minúsculas o entradas indefinidas para la entrada y usar cualquiera de estas para la salida, pero debe ser coherente.

Reglas y restricciones:

  • puede escribir un programa o función, tomando la entrada a través STDIN(o la alternativa más cercana), el argumento de la línea de comandos o el argumento de la función y generando el resultado a través STDOUT(o la alternativa más cercana), el valor de retorno de la función o el parámetro de la función (out).
  • la entrada puede estar en cualquier lista conveniente o formato de cadena. Puede suponer que son menores que cada uno y que la lista contiene al menos un elemento.ai231
  • cada número abreviado contendrá solo uno, . mientras que un número normal contendrá tantos , como sea necesario (puede suponer que estos números no se modificarán).
  • usted NO PUEDE introducir un número como '123456'sino123,456
  • se aplican reglas estándar de .

Casos de prueba:

Input: ['1.5M', '77.6k', '123,456,789']         Output: ['1,500,000', '77,600', '123.4M']
Input: ['3,000,000,000', '581k', '2b']          Output: ['3B', '581,000', '2,000,000,000']
Input: ['0.1k']                                 Output: ['100']
Input: ['888', '33']                            Output: ['0.888k', '0.033k']

Aclaraciones:

  • para números <1000 después del punto decimal en la salida de abreviatura, debe tener tantos dígitos como sea necesario para obtener el resultado correcto. (por ejemplo: 2-> se convertirá 0.002k) - eso significa 3 decimales como máximo ; para números> 1000 puede tener un máximo de 1 decimal .
  • la abreviatura puede estar en minúsculas o mayúsculas
  • Eliminé la restricción incorporada como se sugiere en los comentarios

¡El código más corto en bytes gana!

Grajdeanu Alex.
fuente
1
Solicitudes de aclaración: ¿cuántos dígitos después del punto decimal en la salida de abreviatura? ¿Cómo abreviar números <1000? mayúsculas o minúsculas o ambas en entrada y salida?
edc65
1
No debería '123,456,789' -> '123.4M'? Además, esto no aclara cuántos decimales usar. Seguramente, cualquier cosa por debajo de 1000 no debería ser abreviada de todos modos.
Kade
1
@ anonymous2 lee la tercera regla.
Grajdeanu Alex.
44
"no se le permite usar ningún módulo / función incorporada" ¿ Alguna función incorporada?
Alex Howansky el
1
Su uso de "kilo" sugiere prefijos SI y esos serían ["k", "M", "G"]. ¿Qué significa "mientras que un número normal contendrá tantos, según sea necesario ", en mi país sería un error usar alguno?
Angs

Respuestas:

2

PHP, 234 224 213 201 205 bytes

for(;$x=$argv[++$n];){$y=str_replace(",","",$x)/1e3;for($i=0;$y>999;$i++)$y=($y|0)/1e3;echo(A<$c=substr($x,strlen($x)-1))?number_format($x*[k=>1e3,m=>1e6,b=>1e9][$c]):($i?($y*10|0)/10:$y).kmb[$i]," ";}

6 bytes guardados por insertusernamehere, 4 bytes inspirados por eso.


  • toma datos de los argumentos de la línea de comandos, imprime los resultados separados por espacios con un separador final
  • espera abreviatura en minúsculas
  • corre con -r

-2 bytes si el guión bajo como separador está bien: reemplazar " "con _.
-1 byte si el redondeo correcto está bien: reemplazar ($y*10|0)/10con round($y,1).
-17 bytes para PHP 7.1: reemplazar substr($x,strlen($x)-1)con $x[-1].


80 (63) bytes para expandir un solo argumento:

<?=number_format(($x=$argv[1])*[K=>1e3,M=>1e6,B=>1e9][substr($x,strlen($x)-1)]);

guardar en el archivo, luego ejecutar (o reemplazar <?=con echo+ espacio y ejecutar con -r.

Titus
fuente
Su segundo ejemplo no se compila.
Alex Howansky el
1
Tienes parens desequilibrados.
Alex Howansky el
1
-4 bytes: for($j=1;$x=$argv[$j++];) - en lugar deforeach($argv as$i=>$x)if($i)
insertusernamehere
1
-2 bytes: kmb[$i] - en lugar de "kmb"[$i].
insertusernamehere
1
@insertusernamehere Índices de cadena negativos están llegando en PHP 7.1; y eso es un RC (todavía). Gracias por los otros bytes!
Tito el
2

JavaScript, 545 524 522 518 514 508 504 498 494 214 bytes

¡Gracias a @ETHproductions por ahorrar 180 bytes!

d=F=>F.map(f=>1/f.slice(-1)?f=(f=f.replace(/,/g,""))[9]?(f/1e8|0)/10+"B":f[6]?(f/1e5|0)/10+"M":f/1e3+"k":R(R(f.slice(0,-1)+"e"+' kMB'.indexOf(f.substr(-1))*3-0+"").match(/.{1,3}/g)+""),R=x=>[...x].reverse().join``)

Para llamar a la función:

d(["1.5M","1,500,000"]) //["1,500,500","1.5M"]

Salidas como alert, donde cada alertuna contiene un elemento diferente de la entrada

Versión legible:

d = F => F.map(f => 1 / f.slice(-1) ? f = (f = f.replace(/,/g, ""))[9] ? (f / 1e8 | 0) / 10 + "B" : f[6] ? (f / 1e5 | 0) / 10 + "M" : f / 1e3 + "k" : R(R(f.slice(0, -1) + "e" + ' kMB'.indexOf(f.substr(-1)) * 3 - 0 + "").match(/.{1,3}/g) + ""), R = x => [...x].reverse().join ``)

Resumen de ediciones: función convertida en una función de flecha

  • punto y coma eliminado ";"
  • remoto var
  • convertido a una función de flecha
  • mapa usado para iterar a través de los elementos individuales de la matriz
  • usado en |0lugar de piso
  • regex usado para probar
  • utiliza operadores ternarios en lugar de sentencias if-else
  • incluido una función separada para .reverse().join''
usuario41805
fuente
3
Estas son algunas de las formas de jugar golf. No dude en hacer cualquier pregunta que pueda tener :-)
ETHproductions