Bantu saya golf nomor saya!

25

Saat menulis program , saya biasanya menggunakan konstanta numerik. Saya selalu meletakkannya dalam desimal karena itulah yang saya pikirkan, tetapi saya baru menyadari bahwa bahasa saya mendukung format angka lain yang mungkin mempersingkat kode saya.

Tantangan

Dengan bilangan bulat non-negatif kurang dari 2 ^ 53-1, putuskan apakah bilangan bulat itu memiliki representasi terpendek di:

  • Desimal
  • Heksadesimal
  • Notasi ilmiah

Desimal

Karena ini adalah format default bahasa saya, tidak ada notasi tambahan yang diperlukan untuk format ini. Setiap angka direpresentasikan seperti biasa untuk desimal.

Heksadesimal

Bahasa saya menggunakan 0xawalan untuk konstanta heksadesimal. Ini berarti bahwa jika suatu angka memiliki 4 digit heksadesimal, dibutuhkan 6 byte untuk merepresentasikan angka tersebut.

Notasi ilmiah

Bahasa saya menggunakan format berikut untuk notasi ilmiah:

[Basis nyata] e [Eksponen integer 10]

Sebagai contoh, 700akan direpresentasikan sebagai 7e3, dan 699akan direpresentasikan sebagai 6.99e3, karena basis harus antara -10 dan 10 (tidak inklusif). Untuk keperluan tantangan ini, pangkalan akan selalu setidaknya 0, karena angka yang dimasukkan adalah non-negatif.

Keluaran

Anda harus mengembalikan cara mengidentifikasi format mana yang terpendek (yaitu 0 untuk desimal, 1 untuk hex, 2 untuk ilmiah). Atau, Anda dapat menampilkan representasi terkecil dari nomor itu sendiri.

Uji kasus

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

Mencetak gol

Ini adalah , jadi jawabannya dalam byte terpendek untuk setiap bahasa menang.

musicman523
sumber
1
Persyaratan untuk naik 2^63-1mungkin sulit untuk beberapa bahasa. Pertimbangkan untuk mengendurkannya ke nilai yang lebih rendah seperti 2^32-1(sehingga nilainya sesuai dengan tipe data floating point ganda)
Luis Mendo
1
Saya melihat. Bagaimana dengan 2 ^ 52-1? Itu masih cocok double. Hanya sebuah saran; lakukan sesuai keinginan Anda
Luis Mendo
1
1000001000000bisa juga ditulis seolah- 1000001e6olah.
Erik the Outgolfer
1
@ Jonathan Allan ya, itu @ kamu, maaf. Dan tidak, Anda tidak boleh menampilkan daftar yang dipesan; karena ini adalah masalah keputusan , Anda perlu memutuskan satu output tunggal. (Tetapi implementasi Anda dapat mengurutkan daftar dan menampilkan item pertama.)
musicman523
1
Bukankah masalah keputusan berdasarkan definisi hanya seharusnya memiliki dua kemungkinan keluaran?
mbomb007

Jawaban:

5

05AB1E , 23 byte

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

Cobalah online!

-1 terima kasih kepada Emigna .

0untuk heksadesimal, 1untuk desimal, 2untuk ilmiah.

Erik the Outgolfer
sumber
Simpan satu byte dengan '.ìÁ0.
Emigna
@Emigna ooh bahwa selalu selalu bermain golf.
Erik the Outgolfer
4

05AB1E , 27 byte

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

Cobalah online!

Penjelasan

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
sumber
Ew, seharusnya ada sesuatu yang lebih pendek di sini.
Erik the Outgolfer
@EriktheOutgolfer: Mungkin. Saya menghabiskan banyak byte dengan notasi ilmiah. Mungkin akan lebih pendek untuk tidak membuat nilai aktual dan hanya memeriksa panjangnya saja.
Emigna
Panjang hex adalah len(hex(input)) + 2, jika itu membantu.
Erik the Outgolfer
@EriktheOutgolfer: Ya, 5 byte untuk mendapatkan panjang hex dan desimal . Ini adalah notasi ilmiah yang akan menelan biaya byte. Akan cenderung mengalahkan ini.
Emigna
2
@EriktheOutgolfer: Menggunakan ¹alih-alih Ds:g¹hgÌ
Emigna
3

Jelly , 28 byte

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

Sebuah link monadik kembali 1, 2atau 3untuk heksadesimal, ilmiah, atau desimal masing-masing.

Cobalah online! atau lihat test suite .

Saya pikir ini akan lebih pendek, tetapi saya tidak bisa melihatnya begitu juga posting.

Bagaimana monstrositas ini bekerja ...

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
sumber
1
28 byte !? Mungkin juga menggunakan C # ...: P
TheLethalCoder
1
@TheLethalCoder Jelas merupakan tantangan yang menipu - harus ada GL di luar sana yang hanya bisa memformat angka ke notasi ilmiah!
Jonathan Allan
@TheLethalCoder Ada jawaban Jelly 75 byte yang diposting pada pertanyaan lain belum lama ini. Tidak ingat yang mana. Ah itu yang ini , tapi yang ini 83.
Draco18
@ Draco18saya milikku, aku mengerti! Komentar membuat saya melihat ini yang berdiri di 91 dari 8 bulan yang lalu; Saya bermain golf ke 85 :)
Jonathan Allan
Saya harus menggunakan google frase "Jelly terpanjang" terbatas pada codegolf.stackexchange.com untuk menemukan mereka. : P Ada yang ketiga, tapi itu hanya 57 byte remeh .... Juga milikmu .
Draco18s
2

JavaScript (ES6), 90 byte

Mengembalikan 0 untuk desimal, 1 untuk heksadesimal, -1 untuk ilmiah.

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

Penjelasan

  • log(n) / log(10): basis-10 logaritma n; kira-kira panjangnya nsebagai desimal.

  • log(n) / log(16) + 2: basis-16 logaritma nplus 2; kira-kira panjang nsebagai heksadesimal ditambah yang diawali 0x.

  • n.toExponential().length - 1: n.toExponential()mengembalikan string dengan ndalam format ilmiah (mis. 7e+3) tetapi kami mengurangi 1 dari panjangnya untuk memperhitungkan yang asing +.

Sekarang bahwa kita memiliki panjang semua 3 representasi D, Hdan S, kita membandingkan:
S<H?-(S<D):+(H<D)


JavaScript (ES6), 97 byte

Ini menghasilkan angka dalam format dengan panjang terpendek. Terinspirasi oleh upaya yang dihapus @ Shaggy .

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

Darrylyeo
sumber
Bagus :) Saya ingin tahu, bisakah Anda menjarah apa pun dari upaya saya yang terbengkalai pada solusi untuk bermain golf ini lebih jauh? Anda akan menemukannya di posting yang dihapus di akhir halaman.
Shaggy
@Shaggy Yours pada dasarnya berbeda karena menampilkan nomor yang diformat. Saya menambahkan jawaban terpisah sebagai gantinya. :)
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()

Mengganggu di C # ulong.ToStringspecifier format ekehilangan presisi pada angka yang lebih tinggi sehingga saya harus melakukannya secara manual. Mungkin ada cara yang lebih pendek untuk melakukannya tetapi ini berhasil untuk saat ini. Ini juga memformatnya secara tidak benar untuk tantangan ini jadi saya harus menghapus outputnya secara manual.

Jika saya menetapkan string ke nilai nkarena var s=n+"";berhasil lebih lama karena pengembalian eksplisit dan kurung kurawal ekstra.

Ini mengembalikan nilai terpendek dari array dari setiap nilai yang berbeda di mana [0] = decimal, [1] = hexadecimal, [2] = scientific.

Versi Lengkap / Terformat:

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

Cara yang benar untuk menghitung output ilmiah adalah:

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

Namun, mengingat 0lebih pendek dari 0e0saya dapat menghapus kasus khusus itu.

TheLethalCoder
sumber
1

Python 2, 83 77 byte

Menghasilkan representasi terkecil dari angka tersebut.

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

Cobalah online

Tidak Disatukan:

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)

Regex menghapus nol yang tertinggal dan titik desimal jika perlu, serta tanda plus dan memimpin nol dari eksponen jika ada.

mbomb007
sumber
Saya pikir backticks akan menambahkan sejumlah Lbesar dalam rentang input. strakan menghindarinya.
xnor
@ xnor Bilangan bulat maksimum yang harus kita dukung ada di dalam intrepresentasi Python . Lama mulai kira-kira 2**63.
mbomb007
Apakah Anda perlu melakukan subtitle regex? Bisakah Anda menghapus +karakter saja str.replace?
musicman523
1
@ musicman523 Itu akan jauh lebih lama. Subbing regex perlu dilakukan pula untuk menghapus nol dan titik desimal, dan itu hanya 2 byte untuk menghapus +sementara saya melakukannya.
mbomb007
1

Ohm , 35 byte

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

Cobalah online!

Output 0 untuk desimal, 1 untuk hex dan 2 untuk ilmiah.

Penjelasan:

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

PHP , 90 byte

mencetak 0 untuk desimal, 1 untuk heksadesimal dan 2 untuk ilmiah

dalam kasus seri, angka tertinggi akan dicetak

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

Cobalah online!

PHP , 91 byte

mencetak 0 untuk desimal, 1 untuk heksadesimal dan 2 untuk ilmiah

dalam kasus seri, angka terendah akan dicetak

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

Cobalah online!

PHP , 103 byte

mencetak 0 untuk desimal, 1 untuk heksadesimal dan 2 untuk ilmiah

dalam kasus seri semua angka akan dicetak

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;

Cobalah online!

PHP , 109 byte

Output array dengan solusi terpendek

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

Cobalah online!

Jörg Hülsermann
sumber
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);}

Dekompresi:

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
}

Mencetak 0 untuk desimal, 1 untuk hex, 2 untuk notasi ilmiah.

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

Atau, sebagai alternatif:

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

Atau, dalam hex:

dc4e3eceb84e3ed7303e3170b1c04e04443e3370b1bbbcbbbfbbb642415345104e2b313604483e3004463e3104493ed14e6c4940b8ba4e83493e31304904493e46703104463ed43ec0447131044c3e317044714670104471466c31113e7270b14c117010306fba4c04533e10486c44113210446c53117010486d441110317010486c5311044e3ed6303e4e

Mencetak 0 untuk desimal, 1 untuk hex, 2 untuk notasi ilmiah

Élektra
sumber