¡Ayúdame a jugar mis números!

25

Al escribir programas de , generalmente termino usando algunas constantes numéricas. Siempre los pongo en decimal porque así es como pienso, pero me di cuenta de que mi idioma admite otros formatos de números que podrían permitirme acortar un poco mi código.

Reto

Dado un entero no negativo menor que 2 ^ 53-1, decida si ese entero tiene la representación más corta en:

  • Decimal
  • Hexadecimal
  • Notación cientifica

Decimal

Dado que este es el formato predeterminado de mi idioma, no se necesita una notación adicional para este formato. Cada número se representa como de costumbre para el decimal.

Hexadecimal

Mis idiomas usan el 0xprefijo para constantes hexadecimales. Esto significa que si un número tiene 4 dígitos hexadecimales, se necesitarán 6 bytes para representar ese número.

Notación cientifica

Mi lenguaje usa el siguiente formato para notación científica:

[Base real] e [Exponente entero de 10]

Por ejemplo, 700se representaría como 7e3, y 699se representaría como 6.99e3, porque la base debe estar entre -10 y 10 (no incluido). Para los propósitos de este desafío, la base siempre será al menos 0, ya que el número ingresado no es negativo.

Salida

Debe devolver una forma de identificar qué formato es más corto (es decir, 0 para decimal, 1 para hexadecimal, 2 para científico). Alternativamente, puede generar la representación más pequeña del número mismo.

Casos de prueba

Decimal       | Hexadecimal  | Scientific        | Winner
--------------|--------------|-------------------|-------------
0             | 0x0          | 0e0               | Decimal
15            | 0xF          | 1.5e1             | Decimal
6999          | 0x1B57       | 6.999e3           | Decimal
7000          | 0x1B58       | 7e3               | Scientific
1000000000000 | 0xE8D4A51000 | 1e12              | Scientific
1000000000001 | 0xE8D4A51001 | 1.000000000001e12 | Hexadecimal
1000000001000 | 0xE8D4A513E8 | 1.000000001e12    | Hexadecimal
1000001000000 | 0xE8D4B45240 | 1.000001e12       | Scientific

Tanteo

Este es el , por lo que gana la respuesta en los bytes más cortos para cada idioma.

musicman523
fuente
1
El requisito de subir 2^63-1puede ser difícil para algunos idiomas. Considere relajar eso a un valor más bajo como 2^32-1(para que los valores quepan en un tipo de datos de coma flotante doble)
Luis Mendo
1
Veo. ¿Qué tal 2 ^ 52-1? Eso todavía encaja double. Sólo una sugerencia; Haz lo que quieras
Luis Mendo
1
1000001000000También se puede escribir como 1000001e6si.
Erik the Outgolfer
1
@JonathanAllan sí, ese fue @ tu, lo siento. Y no, no puede generar la lista ordenada; Dado que este es un problema de decisión , debe decidir sobre una sola salida. (Sin embargo, su implementación puede ordenar la lista de salida y el primer elemento.)
musicman523
1
¿No se supone que un problema de decisión, por definición, solo tiene dos salidas posibles?
mbomb007

Respuestas:

5

05AB1E , 23 bytes

hg̹gD<g>¹ÀðìÁ0ÜðÜg+)Wk

Pruébalo en línea!

-1 gracias a Emigna .

0para hexadecimal, 1para decimal,2 para científico.

Erik el Outgolfer
fuente
Guardar un byte con '.ìÁ0.
Emigna
@Emigna ooh que antepone siempre cosas de golf.
Erik the Outgolfer
4

05AB1E , 27 bytes

Dg<¹À'.ìÁ0Ü'.Ü…ÿeÿIh…0xÿ)é¬

Pruébalo en línea!

Explicación

D                            # duplicate input, one copy will be used as decimal notation
 g<                          # len(input)-1
   ¹À                        # push input and rotate left
     '.ìÁ                    # prepend a dot and rotate right
         0Ü'.Ü               # remove trailing zeroes and then any trailing dot
              …ÿeÿ           # format scientific notation
                  Ih         # input converted to hex
                    …0xÿ     # format hex
                        )    # wrap in a list
                         é   # sort by length
                          ¬  # get the first (shortest) item
Emigna
fuente
Ew, debería haber algo más corto aquí.
Erik the Outgolfer
@EriktheOutgolfer: Probablemente. Paso muchos bytes con la notación científica. Probablemente sería más corto no crear los valores reales y solo verificar las longitudes.
Emigna
La longitud del maleficio es len(hex(input)) + 2, si eso ayuda.
Erik the Outgolfer
@EriktheOutgolfer: Sí, 5 bytes para obtener longitudes de hexadecimal y decimal . Es la notación científica que costará bytes. Aunque probablemente superará esto.
Emigna
2
@EriktheOutgolfer: Uso en ¹lugar de Ds:g¹hgÌ
Emigna
3

Jalea , 28 bytes

TṀµỊ¬+‘
DµL’DL+Ç,L
b⁴L+2;ÇỤḢ

Un enlace monádico regresar 1, 2o3 para hexadecimal, científico o decimal, respectivamente.

Pruébalo en línea! o ver un conjunto de pruebas .

Pensé que esto sería más corto, pero no puedo verlo, así que estoy publicando.

Cómo funciona esta monstruosidad ...

TṀµỊ¬+‘    - Link 1, length of mantissa + "e": list of decimal digits  e.g. [7,0,1,0]
T          - truthy indexes                                                 [1,  3  ]
 Ṁ         - maximum                                                             3
  µ        - monadic chain separation, call that m
   Ị       - insignificant? (abs(m)<=1) -- here: 1 for m=1, 0 otherwise          0
    ¬      - logical not                  i.e. 1 if a "." will be used           1
     +     - add m                                                               4
      ‘    - increment                    always uses an 'e'                     5

DµL’DL+Ç,L - Link 2, lengths of scientific and decimal notations: non-negative-integer, n
D          - cast to decimal list
 µ         - monadic chain separation, call that d
  L        - length of d (number of decimal digits of n)
   ’       - decrement (value of exponent)
    D      - cast to decimal list (exponent's digits)
     L     - length (number of characters in the exponent)
       Ç   - call last link (1) as a monad(d) (number of characters in mantissa + "e")
         L - length of d (number of decimal digits of n)
        ,  - pair

b⁴L+2;ÇỤḢ - Main link: non-negative-integer, n
 ⁴        - literal 16
b         - convert n to base 16
  L       - length (number of hexadecimal digits)
   +2     - add two (number of characters including the "0x")
      Ç   - call the last link (2) as a monad (characters in scientific and decimal)
     ;    - concatenate ([charsInHexadecimal, charsInScientific, charsInDecimal])
       Ụ  - sort indexes by value
        Ḣ - head (1-based-index in the above list of (one of) the shortest)
Jonathan Allan
fuente
1
28 bytes? También podría usar C # ...: P
TheLethalCoder
1
@TheLethalCoder Definitivamente un desafío engañoso: ¡debe haber un GL que pueda formatear números a la notación científica!
Jonathan Allan
@TheLethalCoder Hay una respuesta de 75 bytes Jelly publicada en otra pregunta no hace mucho tiempo. No recuerdo cuál. Ah, era este , pero este es 83.
Draco18s
@ Draco18s tanto mía que veo! El comentario me hizo mirar este que estaba parado en 91 desde hace 8 meses; Lo jugué hasta 85 :)
Jonathan Allan
Tuve que buscar en google la frase "jalea más larga" restringida a codegolf.stackexchange.com para encontrarlos. : P Hubo un tercero, pero solo fueron unos miserables 57 bytes ... También el tuyo .
Draco18s
2

JavaScript (ES6), 90 bytes

Devuelve 0 para decimal, 1 para hexadecimal, -1 para científico.

n=>(l=Math.log,D=l(n)/l(10),H=l(n)/l(16)+2,S=n.toExponential().length-1,S<H?-(S<D):+(H<D))

Explicación

  • log(n) / log(10): base-10 logaritmo de n; aproximadamente la longitud de ncomo un decimal.

  • log(n) / log(16) + 2: base-16 logaritmo de nmás 2; aproximadamente la longitud de nun hexadecimal más el antepuesto 0x.

  • n.toExponential().length - 1: n.toExponential()devuelve una cadena con nformato científico (p 7e+3. ej. ) pero restamos 1 de su longitud para tener en cuenta lo extraño +.

Ahora que tenemos las longitudes de las 3 representaciones D, Hy S, podemos comparar:
S<H?-(S<D):+(H<D)


JavaScript (ES6), 97 bytes

Éste genera el número en el formato con la longitud más corta. Inspirado por el intento eliminado de @ Shaggy .

n=>[n+'','0x'+n.toString(16),n.toExponential().replace('+','')].sort((x,y)=>x.length-y.length)[0]

Darrylyeo
fuente
Bonito :) Me pregunto ¿podrías saquear algo de mi intento abandonado de encontrar una solución para el golf? Lo encontrarás en las publicaciones eliminadas al final de la página.
Shaggy
@Shaggy Yours es fundamentalmente diferente ya que genera el número formateado. Agregué una respuesta separada basada en ella en su lugar. :)
darrylyeo
1

C #, 106 97 96 143 132 bytes

using System.Linq;n=>new[]{n+"",$"0x{n:X}",(n+"").Insert(1,".").TrimEnd('0','.')+"e"+((n+"").Length-1)}.OrderBy(s=>s.Length).First()

Molesto en C #, el ulong.ToStringespecificador de formato epierde precisión en los números más altos, así que tuve que hacerlo manualmente. Probablemente haya una forma más corta de hacerlo, pero esto funciona por ahora. También lo formatea incorrectamente para este desafío, por lo que tendría que eliminar manualmente su salida de todos modos.

Si configuro una cadena al valor de nya var s=n+"";que funciona más tiempo debido al retorno explícito y las llaves extra.

Devuelve el valor más corto de la matriz de cada valor diferente donde [0] = decimal, [1] = hexadecimal, [2] = scientific.

Versión completa / formateada:

using System.Linq;
Func<ulong, string> f = n =>
    new[]
    {
        n + "",
        $"0x{n:X}",
        (n + "").Insert(1, ".").TrimEnd('0', '.') + "e" + ((n + "").Length - 1)
    }.OrderBy(s => s.Length).First();

La forma correcta de calcular la producción científica es:

(n < 1 ? n + "" : (n + "").Insert(1, ".").TrimEnd('0', '.')) + "e" + ((n + "").Length - 1)

Sin embargo, ya que 0es más corto de lo 0e0que puedo eliminar ese caso especial.

TheLethalCoder
fuente
1

Python 2, 83 77 bytes

Emite la representación más pequeña del número.

import re
lambda n:min(`n`,hex(n),re.sub('\.?0*e\+0?','e','%.15e'%n),key=len)

Pruébalo en línea

Sin golf:

import re
n=input()
d=`n`
h=hex(n)
s=re.sub('(.)\.?0*e\+0?',r'\1e','%.15e'%n)
print min(d,h,s,key=len)

La expresión regular elimina los ceros finales y el punto decimal si es necesario, así como el signo más y el cero inicial del exponente si hay uno.

mbomb007
fuente
Creo que los backticks agregarán La números grandes dentro del rango de entrada. strLo evitaría.
xnor
@xnor El entero máximo que tenemos que soportar está dentro de la intrepresentación de Python . Los largos comienzan más o menos 2**63.
mbomb007
¿Necesitas hacer el regex subbing? ¿Puedes simplemente eliminar +personajes con str.replace?
musicman523
1
@ musicman523 Eso sería mucho más largo. La sustitución de expresiones regulares debe realizarse de todos modos para eliminar los ceros y el punto decimal, y solo son 2 bytes para eliminar +mientras estoy en ello.
mbomb007
1

Ohm , 35 bytes

l┼xl2+┼DRîsRl≥al≤Dla°┼îa/ì\?≥;+WD╤k

Pruébalo en línea!

Salidas 0 para decimal, 1 para hexadecimal y 2 para científico.

Explicación:

l                                      Implicit input, get length                                          
 ┼                                     Input again
  x                                    To hex
   l                                   Get length
    2+                                 Add 2 because of "0x"
      ┼                                Get input again
       D                               Duplicate on the stack
        RîsR                           Remove zeroes at the end (reverse, to int, to string, reverse)
            l                          Get length (= length of base)
             ≥                         Add 1 because to count "e" in the scientific notation
              a                        Swap top two values on the stack
               l≤                      Get length - 1 ( = get the exponent of 10 in scientific notation)
                 D                     Duplicate on the stack
                  l                    Get length ( = length of the exponent)
                   a                   Swap. Now on top of the stack we have the exponent again
                    °                  10^exponent
                     Ō                Get input for the fourth time
                       a/              Divide input by the 10^exp calculated earlier
                         ì\?           If this thing is not an integer...
                            ≥;         ...add one to count the "."
                              +        Sum base length ( + "e") + exponent length ( + ".")
                               W       Wrap stack in array
                                D      Duplicate
                                 ╤k    Get index of min value
FrodCube
fuente
0

PHP , 90 bytes

imprime 0 para decimal, 1 para hexadecimal y 2 para científico

en caso de empate se imprimirá el número más alto

<?=array_flip($m=[$l=log10($a=$argn)^0,2+(log($a,16)^0),strlen(($a/10**$l).$l)])[min($m)];

Pruébalo en línea!

PHP , 91 bytes

imprime 0 para decimal, 1 para hexadecimal y 2 para científico

en caso de empate se imprimirá el número más bajo

<?=array_search(min($m=[$l=log10($a=$argn)^0,2+(log($a,16)^0),strlen(($a/10**$l).$l)]),$m);

Pruébalo en línea!

PHP , 103 bytes

imprime 0 para decimal, 1 para hexadecimal y 2 para científico

en caso de empate se imprimirán todos los números

foreach($m=[$l=log10($a=$argn)^0,2+(log($a,16)^0),strlen(($a/10**$l).$l)]as$k=>$v)echo$v-min($m)?"":$k;

Pruébalo en línea!

PHP , 109 bytes

Produzca una matriz con las soluciones más cortas.

for(;!$p=preg_grep("#^.{".++$i."}$#",[$a=$argn,"0x".dechex($a),$a/10**($l=log10($a)^0)."e$l"]););print_r($p);

Pruébalo en línea!

Jörg Hülsermann
fuente
0

C, 187 185 bytes

main(){long long N;scanf("%lli",&N);long long D=log10(N)+1,H=log(N)/log(16)+3,F,S,i=1;while(N>i&&!(N%i))i*=10,F++;S=ceil(log10(D-1))+1+D-F+(D-F>1);printf("%i",N?H>D?2*(D>S):1+(H>S):N);}

Descomprimido:

void main(){
    long long N;
    scans("%lli", &N);
    long long D = log10(N) + 1; // Length of number (decimal)
    long long H = log(N)/log(16) + 3; // Length of number (hexadecimal)
    long long F; // Number of 0s at the end of decimal number
    long long S; // Length of number (scientific notation)
    long long i; // Counter (more or less)
    // Get number of zeros at the end of decimal number
    while(N > i && (N % i) == 0){
        i = i * 10;
        F++;
    }
    S = ceil(log10(D - 1)) + 1 + D - F + (D-F>1); // (Power) + (e) + (multiplier + (1 if len(multiplier) > 1))
    printf("%i", N!=0 ?
                (H > D ? 2 * (D > S) : 1 + (H > S)) 
              : 0); // Print the shortest number
}

Imprime 0 para decimal, 1 para hexadecimal, 2 para notación científica.

Élektra
fuente
0

TI-Basic, 130 bytes

Input N:If not(N:Goto 0:1+int(log(N→D:3+int(logBASE(N,16→H:0→F:1→I:While N>I and not(fPart(N/I:10I→I:F+1→F:End:log(D-1→L:1+D-F+(D-F>1):Ans+int(L)+(0≠fPart(L→S:(H>D)2(D>S)+(H≤D)(1+(H>S)→N:Lbl 0:N

O alternativamente:

�N>θN>�0>1p��ND>3p�������BASEN+16H>0F>1I>�NlI@��N�I>10II>Fp1F>�>�Dq1L>1pDqFpDqFl1>rp�Lp0o�LS>HlD2DlSpHmD1pHlSN>�0>N

O, en hexadecimal:

dc4e3eceb84e3ed7303e3170b1c04e04443e3370b1bbbcbbbfbbb642415345104e2b313604483e3004463e3104493ed14e6c4940b8ba4e83493e31304904493e46703104463ed43ec0447131044c3e317044714670104471466c31113e7270b14c117010306fba4c04533e10486c44113210446c53117010486d441110317010486c5311044e3ed6303e4e

Imprime 0 para decimal, 1 para hexadecimal, 2 para notación científica

Élektra
fuente