Aiutami a giocare a golf con i miei numeri!


25

Quando scrivo programmi di , di solito finisco per usare alcune costanti numeriche. Li metto sempre in decimale perché è così che penso, ma mi sono appena reso conto che la mia lingua supporta altri formati numerici che potrebbero permettermi di abbreviare leggermente il mio codice.

Sfida

Dato un numero intero non negativo inferiore a 2 ^ 53-1, decidi se quel numero intero ha la rappresentazione più breve in:

  • Decimale
  • esadecimale
  • Notazione scientifica

Decimale

Poiché questo è il formato predefinito della mia lingua, per questo formato non è necessaria alcuna notazione aggiuntiva. Ogni numero è rappresentato come al solito per i decimali.

esadecimale

Le mie lingue usano il 0xprefisso per le costanti esadecimali. Ciò significa che se un numero ha 4 cifre esadecimali, saranno necessari 6 byte per rappresentare quel numero.

Notazione scientifica

La mia lingua utilizza il seguente formato per la notazione scientifica:

[Base reale] e [esponente intero di 10]

Ad esempio, 700sarebbe rappresentato come 7e3e 699sarebbe rappresentato come 6.99e3, poiché la base deve essere compresa tra -10 e 10 (non inclusivo). Ai fini di questa sfida, la base sarà sempre almeno 0, poiché il numero immesso non è negativo.

Produzione

Dovresti restituire un modo per identificare quale formato è il più breve (ovvero 0 per i decimali, 1 per esadecimale, 2 per scientifici). In alternativa, è possibile produrre la più piccola rappresentazione del numero stesso.

Casi test

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

punteggio

Questo è , quindi vince la risposta nei byte più brevi per ogni lingua.


1
Il requisito per salire 2^63-1può essere difficile per alcune lingue. Considera di ridurlo a un valore inferiore come 2^32-1(quindi i valori si adattano a un doppio tipo di dati in virgola mobile)
Luis Mendo

1
Vedo. Che ne dici di 2 ^ 52-1? Questo si adatta ancora double. Solo un suggerimento; fai come ritieni opportuno
Luis Mendo il

1
1000001000000può anche essere scritto come 1000001e6se.
Erik the Outgolfer,

1
@JonathanAllan sì, sei stato @ tu, scusa. E no, non è possibile produrre l'elenco ordinato; poiché si tratta di un problema decisionale , è necessario decidere un singolo output. (Ma l'implementazione potrebbe ordinare l'elenco e produrre il primo elemento.)
musicman523

1
Un problema decisionale per definizione non dovrebbe avere solo due possibili risultati?
mbomb007,

Risposte:



4

05AB1E , 27 byte

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

Provalo online!

Spiegazione

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

Ew, qui dovrebbe esserci qualcosa di più corto.
Erik the Outgolfer,

@EriktheOutgolfer: Probabilmente. Passo molti byte con la notazione scientifica. Probabilmente sarebbe più breve non creare i valori effettivi e controllare solo le lunghezze.
Emigna,

La lunghezza esadecimale è len(hex(input)) + 2, se questo aiuta.
Erik the Outgolfer,

@EriktheOutgolfer: Sì, 5 byte per ottenere lunghezze esadecimali e decimali . È la notazione scientifica che costerà byte. Probabilmente batterà questo però.
Emigna,

2
@EriktheOutgolfer: utilizzando ¹invece di Ds:g¹hgÌ
Emigna il

3

Gelatina , 28 byte

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

Un collegamento monadico che ritorna 1, 2o rispettivamente 3per esadecimale, scientifico o decimale.

Provalo online! o vedere una suite di test .

Ho pensato che sarebbe stato più breve, ma non riesco a vederlo, quindi sto postando.

Come funziona questa mostruosità ...

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)

1
28 byte !? Potrebbe anche usare C # ...: P
TheLethalCoder il

1
@TheLethalCoder Sicuramente una sfida ingannevole - ci deve essere un GL là fuori che può semplicemente formattare i numeri sulla notazione scientifica!
Jonathan Allan,

@TheLethalCoder C'è una risposta Jelly a 75 byte pubblicata su un'altra domanda non molto tempo fa. Non ricordo quale. Ah, era questo , ma questo è 83.
Draco18s

@ Draco18s sia il mio che vedo! Il commento mi ha fatto guardare questo che era in piedi a 91 da 8 mesi fa; L'ho giocato a 85 :)
Jonathan Allan il

Ho dovuto cercare su Google la frase "gelatina più lunga" riservata a codegolf.stackexchange.com per trovarli. : P Ce n'era un terzo, ma era solo un misero 57 byte .... Anche il tuo .
Draco18s

2

JavaScript (ES6), 90 byte

Restituisce 0 per decimale, 1 per esadecimale, -1 per scientifico.

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

Spiegazione

  • log(n) / log(10): logaritmo in base 10 di n; all'incirca la lunghezza di ncome un decimale.

  • log(n) / log(16) + 2: logaritmo in base 16 di npiù 2; all'incirca la lunghezza di nun esadecimale più il anteposto 0x.

  • n.toExponential().length - 1: n.toExponential()restituisce una stringa con nformato scientifico (es. 7e+3) ma sottraiamo 1 dalla sua lunghezza per tenere conto dell'estraneo +.

Ora che abbiamo le lunghezze di tutte e 3 le rappresentazioni D, He S, mettiamo a confronto:
S<H?-(S<D):+(H<D)


JavaScript (ES6), 97 byte

Questo produce il numero nel formato con la lunghezza più breve. Ispirato al tentativo cancellato di @ Shaggy .

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


Bello :) Mi chiedo che potresti saccheggiare qualcosa dal mio tentativo abbandonato di trovare una soluzione per continuare a giocare a golf? Lo troverai nei post eliminati alla fine della pagina.
Shaggy,

@Shaggy Yours è fondamentalmente diverso poiché genera il numero formattato. Ho invece aggiunto una risposta separata basata su di essa. :)
darrylyeo,

1

C #, 106 97 96 143 132 byte

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

In modo fastidioso in C # l' identificatore di ulong.ToStringformato eperde precisione sui numeri più alti, quindi ho dovuto farlo manualmente. C'è probabilmente un modo più breve per farlo, ma per ora funziona. Lo formatta anche in modo errato per questa sfida, quindi dovrei rimuovere manualmente l'output comunque.

Se imposto una stringa sul valore di ncome var s=n+"";funziona più a lungo a causa del ritorno esplicito e delle parentesi graffe extra.

Restituisce il valore più breve dall'array di ogni diverso valore in cui [0] = decimal, [1] = hexadecimal, [2] = scientific.

Versione completa / formattata:

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

Il modo corretto di calcolare l'output scientifico è:

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

Tuttavia, visto che 0è più breve di quanto 0e0posso rimuovere quel caso speciale.


1

Python 2, 83 77 byte

Emette la rappresentazione più piccola del numero.

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

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

La regex rimuove gli zeri finali e il punto decimale, se necessario, nonché il segno più e lo zero iniziale dall'esponente, se presente.


Penso che i backtick aggiungeranno un Lnumero elevato all'interno dell'intervallo di input. strlo eviterei.
xnor

@xnor L'intero massimo che dobbiamo supportare è all'interno della intrappresentazione di Python . I lunghi iniziano all'incirca 2**63.
mbomb007,

Devi fare il regex subbing? Puoi semplicemente rimuovere i +personaggi con str.replace?
musicman523

1
@ musicman523 Sarebbe molto più lungo. Il sottotitaggio regex deve essere fatto comunque per rimuovere gli zeri e il punto decimale, ed è solo 2 byte da rimuovere +mentre ci sono.
mbomb007,

1

Ohm , 35 byte

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

Provalo online!

Uscite 0 per decimale, 1 per esadecimale e 2 per scientifico.

Spiegazione:

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

0

PHP , 90 byte

stampa 0 per decimale, 1 per esadecimale e 2 per scientifico

in caso di pareggio verrà stampato il numero più alto

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

Provalo online!

PHP , 91 byte

stampa 0 per decimale, 1 per esadecimale e 2 per scientifico

in caso di pareggio verrà stampato il numero più basso

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

Provalo online!

PHP , 103 byte

stampa 0 per decimale, 1 per esadecimale e 2 per scientifico

in caso di pareggio verranno stampati tutti i numeri

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;

Provalo online!

PHP , 109 byte

Output di un array con le soluzioni più brevi

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

Provalo online!


0

C, 187 185 byte

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

decompresso:

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
}

Stampa 0 per decimale, 1 per esadecimale, 2 per notazione scientifica.


0

TI-Basic, 130 byte

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

Oppure, in alternativa:

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

Oppure, in esadecimale:

dc4e3eceb84e3ed7303e3170b1c04e04443e3370b1bbbcbbbfbbb642415345104e2b313604483e3004463e3104493ed14e6c4940b8ba4e83493e31304904493e46703104463ed43ec0447131044c3e317044714670104471466c31113e7270b14c117010306fba4c04533e10486c44113210446c53117010486d441110317010486c5311044e3ed6303e4e

Stampa 0 per decimale, 1 per esadecimale, 2 per notazione scientifica

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.