Hilf mir, meine Zahlen zu spielen!

25

Beim Schreiben von Programmen verwende ich normalerweise einige numerische Konstanten. Ich habe sie immer in Dezimalzahlen angegeben, weil ich so denke, aber ich habe gerade festgestellt, dass meine Sprache andere Zahlenformate unterstützt, mit denen ich meinen Code möglicherweise leicht verkürzen kann.

Herausforderung

Entscheiden Sie bei einer nicht-negativen Ganzzahl von weniger als 2 ^ 53-1, ob diese Ganzzahl die kürzeste Darstellung hat in:

  • Dezimal
  • Hexadezimal
  • Wissenschaftliche Schreibweise

Dezimal

Da dies das Standardformat meiner Sprache ist, ist für dieses Format keine zusätzliche Notation erforderlich. Jede Zahl wird wie gewohnt als Dezimalzahl dargestellt.

Hexadezimal

Meine Sprachen verwenden das 0xPräfix für hexadezimale Konstanten. Das heißt, wenn eine Zahl 4 hexadezimale Stellen hat, werden 6 Bytes benötigt, um diese Zahl darzustellen.

Wissenschaftliche Schreibweise

Meine Sprache verwendet das folgende Format für die wissenschaftliche Notation:

[Reale Basis] e [Integer-Exponent von 10]

Beispielsweise 700würde dargestellt werden als 7e3, und 699würde dargestellt werden als 6.99e3, weil die Basis zwischen -10 und 10 liegen muss (nicht inklusive). Für die Zwecke dieser Abfrage ist die Basis immer mindestens 0, da die eingegebene Zahl nicht negativ ist.

Ausgabe

Sie sollten einen Weg zurückgeben, um zu identifizieren, welches Format am kürzesten ist (dh 0 für Dezimalzahl, 1 für Hexadezimalzahl, 2 für Wissenschaftlichkeit). Alternativ können Sie die kleinste Darstellung der Zahl selbst ausgeben.

Testfälle

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

Wertung

Das ist , also gewinnt die Antwort in den kürzesten Bytes für jede Sprache.

musicman523
quelle
1
2^63-1Für einige Sprachen kann es schwierig sein, die Anforderungen zu erfüllen . Ziehen Sie in Betracht, dies auf einen niedrigeren Wert zu reduzieren, z. B. 2^32-1(damit die Werte in einen doppelten Gleitkomma-Datentyp passen)
Luis Mendo,
1
Aha. Wie wäre es mit 2 ^ 52-1? Das passt noch double. Nur ein Vorschlag; tun, was Sie für richtig halten
Luis Mendo
1
1000001000000kann auch so geschrieben werden 1000001e6.
Erik der Outgolfer
1
@ JonathanAllan ja, das warst du, sorry. Und nein, Sie können die geordnete Liste nicht ausgeben. Da dies ein Entscheidungsproblem ist , müssen Sie sich für einen einzelnen Ausgang entscheiden. (Aber Ihre Implementierung kann die Liste sortieren und das erste Element ausgeben.)
musicman523
1
Soll ein Entscheidungsproblem per Definition nicht nur zwei mögliche Ausgänge haben?
mbomb007

Antworten:

5

05AB1E , 23 Bytes

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

Probieren Sie es online!

-1 danke an Emigna .

0 für hexadezimal, 1 für dezimal, 2für wissenschaftlich.

Erik der Outgolfer
quelle
Speichern Sie ein Byte mit '.ìÁ0.
Emigna
@Emigna ooh, dass immer Golfsachen voranstellen.
Erik der Outgolfer
4

05AB1E , 27 Bytes

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

Probieren Sie es online!

Erläuterung

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
quelle
Ew, hier sollte etwas kürzer sein.
Erik der Outgolfer
@EriktheOutgolfer: Wahrscheinlich. Ich verbringe viele Bytes mit der wissenschaftlichen Notation. Es wäre wahrscheinlich kürzer, die tatsächlichen Werte nicht zu erstellen und stattdessen nur die Längen zu überprüfen.
Emigna
Hex Länge ist len(hex(input)) + 2, wenn das hilft.
Erik der Outgolfer
@EriktheOutgolfer: Ja, 5 Bytes, um Längen von Hex und Dezimal zu erhalten . Es ist die wissenschaftliche Notation, die Bytes kostet. Wird das aber wahrscheinlich schlagen.
Emigna
2
@EriktheOutgolfer: Mit ¹anstelle von Ds:g¹hgÌ
Emigna
3

Gelee , 28 Bytes

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

Eine monadischen Verbindung Rückkehr 1, 2oder3 für hexadezimal, wissenschaftlich oder dezimal.

Probieren Sie es online! oder sehen a Testsuite an .

Ich dachte, das wäre kürzer, aber ich kann es nicht sehen, also poste ich.

Wie diese Monstrosität funktioniert ...

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
quelle
1
28 Bytes !?
Könnte
1
@TheLethalCoder Auf jeden Fall eine trügerische Herausforderung - es muss eine GL da draußen geben, die Zahlen einfach nach der wissenschaftlichen Notation formatieren kann!
Jonathan Allan
@TheLethalCoder Es gibt eine 75-Byte-Gelee-Antwort auf eine andere Frage, die vor nicht allzu langer Zeit gestellt wurde. Ich kann mich nicht erinnern was. Ah, es war dieser , aber dieser ist 83.
Draco18s
@Draco18s meine beiden sehe ich! Der Kommentar hat mich betrachten diese die vor bei 91 von 8 Monaten stand; Ich habe es auf 85 golfen :)
Jonathan Allan
Ich musste den Ausdruck "längstes Gelee" auf codegolf.stackexchange.com googeln, um sie zu finden. : P Es gab ein drittes, aber es waren nur dürftige 57 Bytes ... Auch deins .
Draco18s
2

JavaScript (ES6), 90 Byte

Gibt 0 für dezimal, 1 für hexadezimal und -1 für wissenschaftlich zurück.

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

Erläuterung

  • log(n) / log(10): Logarithmus zur Basis 10 von n; ungefähr die Länge nals Dezimalzahl.

  • log(n) / log(16) + 2: Logarithmus zur Basis 16 von nplus 2; ungefähr die Länge nals Hexadezimalzahl plus der vorangestellten 0x.

  • n.toExponential().length - 1: n.toExponential()gibt einen String nim wissenschaftlichen Format (zB 7e+3) zurück, aber wir subtrahieren 1 von seiner Länge, um das Überflüssige zu berücksichtigen +.

Nachdem wir nun die Länge aller 3 Darstellungen Dhaben H, Svergleichen wir:
S<H?-(S<D):+(H<D)


JavaScript (ES6), 97 Byte

Dieser gibt die Zahl im Format mit der kürzesten Länge aus. Inspiriert von @ Shaggys gelöschtem Versuch .

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

darrylyeo
quelle
Schön :) Ich frage mich, ob Sie irgendetwas von meinem aufgegebenen Versuch plündern können, eine Lösung zu finden, um dies weiter zu verbessern. Sie finden es in den gelöschten Beiträgen am Ende der Seite.
Shaggy
@Shaggy Yours unterscheidet sich grundlegend, da es die formatierte Zahl ausgibt. Ich habe stattdessen eine separate Antwort hinzugefügt. :)
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()

Ärgerlicherweise in C # der ulong.ToStringFormatbezeichnere bei höheren Zahlen an Genauigkeit verliert, sodass ich ihn manuell ausführen musste. Es gibt wahrscheinlich einen kürzeren Weg, aber das funktioniert erstmal. Es formatiert es auch falsch für diese Herausforderung, so dass ich die Ausgabe sowieso manuell entfernen müsste.

Wenn ich einen String auf den Wert von setze n , wie var s=n+"";es funktioniert mehr wegen der expliziten Rückkehr und zusätzlichen geschweiften Klammern.

Es wird der kürzeste Wert aus dem Array jedes anderen Werts zurückgegeben, in dem [0] = decimal, [1] = hexadecimal, [2] = scientific.

Voll / Formatierte Version:

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

Die korrekte Methode zur Berechnung des wissenschaftlichen Outputs lautet:

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

Da 0es jedoch kürzer ist als 0e0ich, kann ich diesen Sonderfall beseitigen.

TheLethalCoder
quelle
1

Python 2, 83 Bytes

Gibt die kleinste Darstellung der Zahl aus.

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

Probieren Sie es online aus

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)

Die Regex entfernt nachgestellte Nullen und den Dezimalpunkt, falls erforderlich, sowie das Pluszeichen und die führende Null vom Exponenten, falls es eine gibt.

mbomb007
quelle
Ich denke, die Backticks werden Lan große Zahlen im Eingabebereich angehängt . strwürde das vermeiden.
xnor
@xnor Die maximale Ganzzahl, die wir unterstützen müssen, liegt in der intDarstellung von Python . Longs beginnen ungefähr bei 2**63.
mbomb007
Müssen Sie das Regex-Subbing durchführen? Kannst du nur +Zeichen mit entfernen str.replace?
musicman523
1
@ musicman523 Das wäre viel länger. Das Regex-Subbing muss sowieso durchgeführt werden, um die Nullen und den Dezimalpunkt zu entfernen, und es sind nur 2 Bytes, um das zu entfernen, +während ich dabei bin.
mbomb007
1

Ohm , 35 Bytes

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

Probieren Sie es online!

Ausgänge 0 für dezimal, 1 für hex und 2 für wissenschaftlich.

Erläuterung:

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

PHP , 90 Bytes

Gibt 0 als Dezimalzahl, 1 als Hexadezimalzahl und 2 als wissenschaftliche Zahl aus

Im Falle eines Unentschieden wird die höchste Zahl gedruckt

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

Probieren Sie es online!

PHP , 91 Bytes

Gibt 0 als Dezimalzahl, 1 als Hexadezimalzahl und 2 als wissenschaftliche Zahl aus

Im Falle eines Unentschieden wird die niedrigste Zahl gedruckt

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

Probieren Sie es online!

PHP , 103 Bytes

Gibt 0 als Dezimalzahl, 1 als Hexadezimalzahl und 2 als wissenschaftliche Zahl aus

Im Falle eines Unentschieden werden alle Zahlen gedruckt

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;

Probieren Sie es online!

PHP , 109 Bytes

Geben Sie ein Array mit den kürzesten Lösungen aus

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

Probieren Sie es online!

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

Dekomprimiert:

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
}

Gibt 0 als Dezimalzahl, 1 als Hexadezimalzahl und 2 als wissenschaftliche Notation aus.

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

Oder alternativ:

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

Oder in hex:

dc4e3eceb84e3ed7303e3170b1c04e04443e3370b1bbbcbbbfbbb642415345104e2b313604483e3004463e3104493ed14e6c4940b8ba4e83493e31304904493e46703104463ed43ec0447131044c3e317044714670104471466c31113e7270b14c117010306fba4c04533e10486c44113210446c53117010486d441110317010486c5311044e3ed6303e4e

Gibt 0 als Dezimalzahl, 1 als Hexadezimalzahl und 2 als wissenschaftliche Notation aus

Élektra
quelle