Pomóż mi zagrać w moje liczby!

25

Pisząc programy do , zwykle używam stałych liczbowych. Zawsze umieszczam je po przecinku, ponieważ tak myślę, ale właśnie zdałem sobie sprawę, że mój język obsługuje inne formaty liczb, które mogą pozwolić mi nieco skrócić kod.

Wyzwanie

Biorąc pod uwagę nieujemną liczbę całkowitą mniejszą niż 2 ^ 53-1, zdecyduj, czy ta liczba całkowita ma najkrótszą reprezentację w:

  • Dziesiętny
  • Szesnastkowy
  • Notacja naukowa

Dziesiętny

Ponieważ jest to domyślny format mojego języka, dla tego formatu nie jest wymagana dodatkowa notacja. Każda liczba jest reprezentowana jak zwykle po przecinku.

Szesnastkowy

Moje języki używają 0xprefiksu dla stałych szesnastkowych. Oznacza to, że jeśli liczba ma 4 cyfry szesnastkowe, reprezentacja tej liczby zajmie 6 bajtów.

Notacja naukowa

Mój język używa następującego formatu notacji naukowej:

[Podstawa rzeczywista] e [Wykładnik liczby całkowitej 10]

Na przykład 700byłoby reprezentowane jako 7e3i 699byłoby reprezentowane jako 6.99e3, ponieważ podstawa musi wynosić od -10 do 10 (nie obejmuje). Dla celów tego wyzwania podstawa zawsze będzie wynosić co najmniej 0, ponieważ wprowadzona liczba nie jest ujemna.

Wydajność

Powinieneś zwrócić sposób identyfikacji, który format jest najkrótszy (tj. 0 dla dziesiętnych, 1 dla szesnastkowych, 2 dla naukowych). Alternatywnie możesz wypisać najmniejszą reprezentację samej liczby.

Przypadki testowe

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

Punktacja

To jest , więc wygrywa odpowiedź w najkrótszych bajtach dla każdego języka.

musicman523
źródło
1
W 2^63-1przypadku niektórych języków wymóg przejścia na wyższy poziom może być trudny. Rozważ złagodzenie tego do niższej wartości, takiej jak 2^32-1(aby wartości pasowały do ​​podwójnego zmiennoprzecinkowego typu danych)
Luis Mendo
1
Widzę. Co powiesz na 2 ^ 52-1? To wciąż pasuje double. Tylko sugestia; rób, co uważasz za stosowne
Luis Mendo
1
1000001000000można również napisać tak, 1000001e6jakby.
Erik the Outgolfer
1
@JonathanAllan tak, to był @ ty, przepraszam. I nie, nie możesz wydrukować uporządkowanej listy; ponieważ jest to problem decyzyjny , musisz zdecydować o jednym wyjściu. (Ale twoja implementacja może posortować listę i wygenerować pierwszy element.)
musicman523
1
Czy problem decyzyjny z definicji nie powinien mieć tylko dwóch możliwych wyników?
mbomb007

Odpowiedzi:

5

05AB1E , 23 bajty

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

Wypróbuj online!

-1 dzięki Emignie .

0dla szesnastkowego, 1dziesiętnego, 2naukowego.

Erik the Outgolfer
źródło
Zapisz bajt za pomocą '.ìÁ0.
Emigna
@Emigna ooh, które przygotowują zawsze golfa.
Erik the Outgolfer
4

05AB1E , 27 bajtów

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

Wypróbuj online!

Wyjaśnienie

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
źródło
Ew, tu powinno być coś krótszego.
Erik the Outgolfer
@EriktheOutgolfer: Prawdopodobnie. Sporo bajtów spędzam na notacji naukowej. Prawdopodobnie krócej byłoby nie tworzyć rzeczywistych wartości, a jedynie sprawdzać długości.
Emigna
Długość heksa jest len(hex(input)) + 2, jeśli to pomaga.
Erik the Outgolfer
@EriktheOutgolfer: Tak, 5 bajtów, aby uzyskać długości szesnastkowe i dziesiętne . To notacja naukowa będzie kosztować bajty. Prawdopodobnie to pokona.
Emigna
2
@EriktheOutgolfer: Używanie ¹zamiast Ds:g¹hgÌ
Emigna
3

Galaretka , 28 bajtów

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

Monadycznego Link powrocie 1, 2albo 3na szesnastkowy, naukowej lub przecinku odpowiednio.

Wypróbuj online! lub zobacz zestaw testowy .

Myślałem, że to będzie krótsze, ale nie widzę tego, więc piszę.

Jak działa ta potworność ...

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
źródło
1
28 bajtów !?
Równie
1
@TheLethalCoder Zdecydowanie zwodnicze wyzwanie - musi istnieć GL, który może po prostu sformatować liczby do notacji naukowej!
Jonathan Allan
@TheLethalCoder Nie tak dawno temu 75-bajtowa odpowiedź na galaretkę została zamieszczona na inne pytanie. Nie pamiętam co. Ach, to był ten , ale ten ma 83.
Draco18s
@ Draco18s oba moje, widzę! Ten komentarz sprawił, że spojrzałem na ten, który miał 91 lat przed 8 miesiącami; Grałem w golfa do 85 :)
Jonathan Allan
Musiałem znaleźć w Google wyrażenie „najdłuższa galaretka” ograniczone do codegolf.stackexchange.com, aby je znaleźć. : P Trzeci był, ale był tylko marny 57 bajtów .... Również twój .
Draco18s,
2

JavaScript (ES6), 90 bajtów

Zwraca 0 dla wartości dziesiętnych, 1 dla wartości szesnastkowych, -1 dla wartości naukowych.

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

Wyjaśnienie

  • log(n) / log(10): logarytm podstawowy 10 dla n; z grubsza njako liczba dziesiętna.

  • log(n) / log(16) + 2: logarytm bazowy 16 nplus 2; w przybliżeniu długość njako wartość szesnastkowa plus wartość dodana 0x.

  • n.toExponential().length - 1: n.toExponential()zwraca ciąg znaków nw formacie naukowym (np. 7e+3), ale odejmujemy 1 od jego długości, aby uwzględnić obce +.

Teraz, gdy mamy długości wszystkich 3 przedstawień D, Hi Sporównujemy:
S<H?-(S<D):+(H<D)


JavaScript (ES6), 97 bajtów

Ten wypisuje liczbę w formacie o najkrótszej długości. Zainspirowany usuniętą próbą @ Shaggy .

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

darrylyeo
źródło
Fajnie :) Zastanawiam się, czy mógłbyś splądrować coś z mojej porzuconej próby rozwiązania problemu golfa? Znajdziesz go w usuniętych postach na końcu strony.
Shaggy
@Shaggy Yours jest zasadniczo inny, ponieważ wyświetla sformatowaną liczbę. Zamiast tego dodałem osobną odpowiedź. :)
darrylyeo
1

C #, 106 97 96 143 132 bajtów

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

Irytujące w języku C # specyfikator ulong.ToStringformatu etraci precyzję na wyższych liczbach, więc musiałem to zrobić ręcznie. Prawdopodobnie jest to krótszy sposób, ale na razie to działa. Formatuje go również niepoprawnie dla tego wyzwania, więc i tak musiałbym ręcznie usunąć dane wyjściowe.

Jeśli ustawię ciąg znaków na wartość, nponieważ var s=n+"";działa on dłużej ze względu na wyraźny zwrot i dodatkowe nawiasy klamrowe.

Zwraca najkrótszą wartość z tablicy każdej innej wartości gdzie [0] = decimal, [1] = hexadecimal, [2] = scientific.

Wersja pełna / sformatowana:

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

Prawidłowy sposób obliczenia wyników naukowych to:

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

Jednak widząc, że 0jest krótszy niż 0e0mogę usunąć ten specjalny przypadek.

TheLethalCoder
źródło
1

Python 2, 83 77 bajtów

Zwraca najmniejszą reprezentację liczby.

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

Wypróbuj online

Nie golfowany:

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)

Wyrażenie regularne usuwa zera końcowe i kropkę dziesiętną, jeśli to konieczne, a także znak plus i wiodące zero z wykładnika, jeśli taki istnieje.

mbomb007
źródło
Wydaje mi się, że backsticks dopisze Ldo dużej liczby w zakresie wejściowym. struniknąłby tego.
xnor
@ xnor Maksymalna liczba całkowita, którą musimy wesprzeć, mieści się w intreprezentacji Pythona . Długo zaczynają się mniej więcej od początku 2**63.
mbomb007
Czy potrzebujesz zrobić subgex wyrażenia regularnego? Czy możesz po prostu usunąć +postacie za pomocą str.replace?
musicman523
1
@ musicman523 To by było o wiele dłużej. Subbing wyrażenia regularnego musi być zresztą zrobiony, aby usunąć zera i przecinek dziesiętny, i to tylko 2 bajty, aby usunąć +czas, w którym jestem.
mbomb007
1

Ohm , 35 bajtów

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

Wypróbuj online!

Wyjście 0 dla dziesiętnych, 1 dla szesnastkowych i 2 dla naukowych.

Wyjaśnienie:

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
źródło
0

PHP , 90 bajtów

wypisuje 0 dla dziesiętnego, 1 dla szesnastkowego i 2 dla naukowego

w przypadku remisu zostanie wydrukowana najwyższa liczba

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

Wypróbuj online!

PHP , 91 bajtów

wypisuje 0 dla dziesiętnego, 1 dla szesnastkowego i 2 dla naukowego

w przypadku remisu zostanie wydrukowana najniższa liczba

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

Wypróbuj online!

PHP , 103 bajty

wypisuje 0 dla dziesiętnego, 1 dla szesnastkowego i 2 dla naukowego

w przypadku remisu wszystkie liczby zostaną wydrukowane

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;

Wypróbuj online!

PHP , 109 bajtów

Wyprowadź tablicę z najkrótszymi rozwiązaniami

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

Wypróbuj online!

Jörg Hülsermann
źródło
0

C 187 185 bajtów

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

Dekompresowane:

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
}

Drukuje 0 dla dziesiętnego, 1 dla szesnastkowego, 2 dla notacji naukowej.

Élektra
źródło
0

TI-Basic, 130 bajtów

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

Lub alternatywnie:

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

Lub szesnastkowo:

dc4e3eceb84e3ed7303e3170b1c04e04443e3370b1bbbcbbbfbbb642415345104e2b313604483e3004463e3104493ed14e6c4940b8ba4e83493e31304904493e46703104463ed43ec0447131044c3e317044714670104471466c31113e7270b14c117010306fba4c04533e10486c44113210446c53117010486d441110317010486c5311044e3ed6303e4e

Drukuje 0 dla dziesiętnego, 1 dla szesnastkowego, 2 dla notacji naukowej

Élektra
źródło