Ajude-me a jogar meus números!

25

Ao escrever programas de , geralmente acabo usando algumas constantes numéricas. Eu sempre os coloco em decimal, porque é assim que penso, mas acabei de perceber que meu idioma suporta outros formatos de números que podem me permitir diminuir um pouco meu código.

Desafio

Dado um número inteiro não negativo menor que 2 ^ 53-1, decida se esse número inteiro tem a menor representação em:

  • Decimal
  • Hexadecimal
  • Notação científica

Decimal

Como esse é o formato padrão do meu idioma, não há notação extra necessária para esse formato. Cada número é representado como de costume para decimal.

Hexadecimal

Meus idiomas usa o 0xprefixo para constantes hexadecimais. Isso significa que, se um número tiver 4 dígitos hexadecimais, serão necessários 6 bytes para representar esse número.

Notação científica

Meu idioma usa o seguinte formato para notação científica:

[Base real] e [Expoente inteiro de 10]

Por exemplo, 700seria representado como 7e3e 699seria representado como 6.99e3, porque a base deve estar entre -10 e 10 (não inclusivo). Para os propósitos deste desafio, a base sempre será pelo menos 0, pois o número inserido não é negativo.

Saída

Você deve retornar uma maneira de identificar qual formato é mais curto (ou seja, 0 para decimal, 1 para hexadecimal, 2 para científico). Como alternativa, você pode gerar a menor representação do número em si.

Casos de teste

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

Pontuação

Isso é , então a resposta nos bytes mais curtos para cada idioma vence.

musicman523
fonte
1
O requisito de subida 2^63-1pode ser difícil para alguns idiomas. Considere relaxante que para um valor inferior, tal como 2^32-1(de modo que os valores se encaixam em um tipo de dados de ponto flutuante duplo)
Luis Mendo
1
Entendo. Que tal 2 ^ 52-1? Isso ainda se encaixa double. Apenas uma sugestão; Faça o que achar melhor
Luis Mendo
1
1000001000000Também pode ser escrito como 1000001e6se.
Erik the Outgolfer
1
@ JonathanAllan sim, isso foi @ você, desculpe. E não, você não pode exibir a lista ordenada; Como esse é um problema de decisão , você precisa decidir sobre uma única saída. (Mas a sua implementação pode ordenar a lista e saída o primeiro item.)
musicman523
1
Por definição, um problema de decisão não deve ter apenas duas saídas possíveis?
mbomb007

Respostas:

5

05AB1E , 23 bytes

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

Experimente online!

-1 graças a Emigna .

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

Erik, o Outgolfer
fonte
Salve um byte com '.ìÁ0.
Emigna
@ Emigna ooh que precede sempre coisas de golfe.
Erik the Outgolfer
4

05AB1E , 27 bytes

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

Experimente online!

Explicação

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
fonte
Eca, deve haver algo mais curto aqui.
Erik the Outgolfer
@EriktheOutgolfer: Provavelmente. Eu gasto muitos bytes com a notação científica. Provavelmente seria mais curto não criar os valores reais e apenas verificar os comprimentos.
Emigna
Comprimento hexadecimal é len(hex(input)) + 2, se isso ajuda.
Erik the Outgolfer
@ EriktheOutgolfer: Sim, 5 bytes para obter comprimentos de hex e decimal . É a notação científica que custará bytes. Provavelmente vai superar isso.
Emigna
2
@EriktheOutgolfer: Usando em ¹vez de Ds:g¹hgÌ
Emigna
3

Gelatina , 28 bytes

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

Um link monádico retornando 1, 2ou 3hexadecimal, científico ou decimal, respectivamente.

Experimente online! ou veja uma suíte de testes .

Eu pensei que isso seria mais curto, mas não posso vê-lo, então estou postando.

Como essa monstruosidade funciona ...

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
fonte
1
28 bytes !? Poderia muito bem usar C # ...: P
TheLethalCoder
1
@TheLethalCoder Definitivamente um desafio enganoso - deve haver um GL por aí que possa apenas formatar números para a notação científica!
Jonathan Allan
@TheLethalCoder Há uma resposta de 75 bytes da Jelly postada em outra pergunta não faz muito tempo. Não me lembro qual. Ah, era esse aqui , mas esse é 83. #
Draco18s
@ Draco18s tanto meu que eu vejo! O comentário me fez olhar para este que estava em 91 a 8 meses atrás; I golfed-lo para baixo a 85 :)
Jonathan Allan
Eu tive que pesquisar no google a frase "geléia mais longa" restrita ao codegolf.stackexchange.com para encontrá-los. : P Havia um terceiro, mas eram apenas 57 bytes insignificantes .... Também o seu .
precisa saber é o seguinte
2

JavaScript (ES6), 90 bytes

Retorna 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))

Explicação

  • log(n) / log(10): logaritmo de base 10 de n; aproximadamente o comprimento de ncomo decimal.

  • log(n) / log(16) + 2: logaritmo da base 16 de nmais 2; aproximadamente o comprimento de num hexadecimal mais o precedido 0x.

  • n.toExponential().length - 1: n.toExponential()retorna uma string nno formato científico (por exemplo 7e+3), mas subtraímos 1 do seu comprimento para explicar o que é estranho +.

Agora que temos os comprimentos de todos os 3 representações D, He S, comparamos:
S<H?-(S<D):+(H<D)


JavaScript (ES6), 97 bytes

Este gera o número no formato com o menor comprimento. Inspirado pela tentativa excluída de @ Shaggy .

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

darrylyeo
fonte
Bom :) Gostaria de saber se você poderia pilhar alguma coisa da minha tentativa abandonada de encontrar uma solução para resolver isso ainda mais? Você o encontrará nas postagens excluídas no final da página.
Shaggy
O @Shaggy Yours é fundamentalmente diferente, pois gera o número formatado. Eu adicionei uma resposta separada com base nela. :)
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()

Irritantemente em C #, o ulong.ToStringespecificador de formato eperde precisão nos números mais altos, então tive que fazer isso manualmente. Provavelmente existe uma maneira mais curta de fazer isso, mas isso funciona por enquanto. Ele também o formata incorretamente para esse desafio, então eu teria que retirar manualmente sua saída de qualquer maneira.

Se eu definir uma string para o valor de n, var s=n+"";pois funciona mais por causa do retorno explícito e de chaves extras.

Retorna o menor valor da matriz de cada valor diferente em que [0] = decimal, [1] = hexadecimal, [2] = scientific.

Versão completa / formatada:

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();

A maneira correta de calcular a produção científica é:

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

No entanto, vendo como 0é mais curto do que 0e0eu posso remover esse caso especial.

TheLethalCoder
fonte
1

Python 2, 83 77 bytes

Produz a menor representação do número.

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

Experimente online

Ungolfed:

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)

A regex remove zeros à direita e o ponto decimal, se necessário, além do sinal de mais e zero à esquerda do expoente, se houver um.

mbomb007
fonte
Acho que os backticks acrescentam um Lnúmero grande ao intervalo de entrada. strevitaria isso.
xnor
@xnor O número máximo máximo que temos que suportar está dentro da intrepresentação do Python . Os longos começam aproximadamente 2**63.
mbomb007
Você precisa fazer a subexposição regex? Você pode apenas remover +caracteres com str.replace?
musicman523
1
@ musicman523 Seria muito mais longo. A sub-regex precisa ser feita de qualquer maneira para remover os zeros e o ponto decimal, e são apenas 2 bytes para remover o +tempo em que estou nela.
mbomb007
1

Ohm , 35 bytes

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

Experimente online!

Saídas 0 para decimal, 1 para hexadecimal e 2 para científico.

Explicação:

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
fonte
0

PHP , 90 bytes

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

em caso de empate, o número mais alto será impresso

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

Experimente online!

PHP , 91 bytes

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

em caso de empate, o número mais baixo será impresso

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

Experimente online!

PHP , 103 bytes

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

em caso de empate, todos os números serão impressos

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;

Experimente online!

PHP , 109 bytes

Saída de uma matriz com as soluções mais curtas

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

Experimente online!

Jörg Hülsermann
fonte
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 notação científica.

Élektra
fonte
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

Ou alternativamente:

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

Ou, em hexadecimal:

dc4e3eceb84e3ed7303e3170b1c04e04443e3370b1bbbcbbbfbbb642415345104e2b313604483e3004463e3104493ed14e6c4940b8ba4e83493e31304904493e46703104463ed43ec0447131044c3e317044714670104471466c31113e7270b14c117010306fba4c04533e10486c44113210446c53117010486d441110317010486c5311044e3ed6303e4e

Imprime 0 para decimal, 1 para hexadecimal, 2 para notação científica

Élektra
fonte