Aidez-moi à jouer mes numéros!


25

Lors de l'écriture de programmes de , je finis généralement par utiliser des constantes numériques. Je les mets toujours en décimal parce que c'est ce que je pense, mais je viens de réaliser que ma langue prend en charge d'autres formats numériques qui pourraient me permettre de raccourcir légèrement mon code.

Défi

Étant donné un entier non négatif inférieur à 2 ^ 53-1, décidez si cet entier a la représentation la plus courte dans:

  • Décimal
  • Hexadécimal
  • Notation scientifique

Décimal

Comme il s'agit du format par défaut de ma langue, aucune notation supplémentaire n'est requise pour ce format. Chaque nombre est représenté comme d'habitude pour la décimale.

Hexadécimal

Mes langues utilisent le 0xpréfixe pour les constantes hexadécimales. Cela signifie que si un nombre a 4 chiffres hexadécimaux, il faudra 6 octets pour représenter ce nombre.

Notation scientifique

Ma langue utilise le format suivant pour la notation scientifique:

[Base réelle] e [Exposant entier de 10]

Par exemple, 700serait représenté comme 7e3, et 699serait représenté comme 6.99e3, car la base doit être comprise entre -10 et 10 (non inclus). Aux fins de ce défi, la base sera toujours au moins égale à 0, car le nombre entré n'est pas négatif.

Sortie

Vous devez renvoyer un moyen d'identifier le format le plus court (ie 0 pour décimal, 1 pour hex, 2 pour scientifique). Vous pouvez également générer la plus petite représentation du nombre lui-même.

Cas de 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

Notation

C'est du , donc la réponse dans les octets les plus courts pour chaque langue l'emporte.


1
L'obligation de remonter 2^63-1peut être difficile pour certaines langues. Envisagez de relâcher cela à une valeur inférieure telle que 2^32-1(de sorte que les valeurs tiennent dans un type de données à virgule flottante double)
Luis Mendo

1
Je vois. Que diriez-vous de 2 ^ 52-1? Cela tient toujours double. Juste une suggestion; faites comme bon vous semble
Luis Mendo

1
1000001000000peut également être écrit comme 1000001e6si.
Erik the Outgolfer

1
@JonathanAllan oui, c'était @ vous, désolé. Et non, vous ne pouvez pas sortir la liste ordonnée; comme il s'agit d'un problème de décision , vous devez décider d'une seule sortie. (Mais votre implémentation peut trier la liste et afficher le premier élément.)
musicman523

1
Un problème de décision n'est-il pas par définition censé avoir seulement deux sorties possibles?
mbomb007

Réponses:



4

05AB1E , 27 octets

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

Essayez-le en ligne!

Explication

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, il devrait y avoir quelque chose de plus court ici.
Erik the Outgolfer

@EriktheOutgolfer: Probablement. Je passe beaucoup d'octets avec la notation scientifique. Il serait probablement plus court de ne pas créer les valeurs réelles et de vérifier uniquement les longueurs à la place.
Emigna

La longueur hexagonale est len(hex(input)) + 2, si cela aide.
Erik the Outgolfer

@EriktheOutgolfer: Oui, 5 octets pour obtenir des longueurs hexadécimales et décimales . C'est la notation scientifique qui coûtera des octets. Sera probablement battre cela cependant.
Emigna

2
@EriktheOutgolfer: utiliser ¹au lieu deDs :g¹hgÌ
Emigna

3

Gelée , 28 octets

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

Un lien monadique retour 1, 2ou 3pour hexadécimal, scientifique, ou décimal respectivement.

Essayez-le en ligne! ou consultez une suite de tests .

Je pensais que ce serait plus court, mais je ne le vois pas, alors je poste.

Comment fonctionne cette monstruosité ...

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 octets!?
Autant

1
@TheLethalCoder Certainement un défi trompeur - il doit y avoir un GL là-bas qui peut simplement formater les nombres en notation scientifique!
Jonathan Allan

@TheLethalCoder Il y a une réponse Jelly de 75 octets publiée sur une autre question il n'y a pas si longtemps. Je ne me souviens plus de quoi. Ah c'était celui-ci , mais celui-ci a 83 ans.
Draco18s

@ Draco18s les miens je vois! Le commentaire m'a fait regarder celui-ci qui était à 91 il y a 8 mois; Je l'ai joué à 85 :)
Jonathan Allan

J'ai dû rechercher sur google l'expression "la plus longue gelée" limitée à codegolf.stackexchange.com afin de les trouver. : P Il y en avait un troisième, mais ce n'était qu'un maigre 57 octets .... Aussi le vôtre .
Draco18s

2

JavaScript (ES6), 90 octets

Renvoie 0 pour décimal, 1 pour hexadécimal, -1 pour scientifique.

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

Explication

  • log(n) / log(10): logarithme en base 10 de n; à peu près la longueur d' nune décimale.

  • log(n) / log(16) + 2: logarithme en base 16 de nplus 2; à peu près la longueur d' nun hexadécimal plus le préfixé 0x.

  • n.toExponential().length - 1: n.toExponential()retourne une chaîne nau format scientifique (par exemple 7e+3) mais nous soustrayons 1 de sa longueur pour tenir compte de l’étranger+ .

Maintenant que nous avons les longueurs de toutes les 3 représentations D, Het S, nous comparons:
S<H?-(S<D):+(H<D)


JavaScript (ES6), 97 octets

Celui-ci sort le nombre dans le format avec la longueur la plus courte. Inspiré par la tentative supprimée de @ Shaggy .

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


Nice :) Je me demande si vous pourriez piller quoi que ce soit de ma tentative abandonnée de solution pour jouer au golf plus bas? Vous le trouverez dans les articles supprimés à la fin de la page.
Shaggy

@Shaggy Yours est fondamentalement différent car il génère le numéro formaté. J'ai ajouté une réponse distincte basée sur elle à la place. :)
darrylyeo

1

C #, 106 97 96 143 132 octets

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

Ennuyeusement en C # le ulong.ToString spécificateur de format eperd sa précision sur les nombres plus élevés, donc j'ai dû le faire manuellement. Il y a probablement un moyen plus court de le faire, mais cela fonctionne pour l'instant. Il le formate également incorrectement pour ce défi, je devrais donc supprimer manuellement sa sortie de toute façon.

Si je mets une chaîne à la valeur de nasvar s=n+""; cela fonctionne plus longtemps à cause du retour explicite et des accolades supplémentaires.

Il renvoie la valeur la plus courte du tableau de chaque valeur différente où [0] = decimal, [1] = hexadecimal, [2] = scientific .

Version complète / formatée:

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

La bonne façon de calculer la production scientifique est:

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

Cependant, vu que 0c'est plus court que 0e0je peux supprimer ce cas spécial.


1

Python 2, 83 77 octets

Génère la plus petite représentation du nombre.

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

Essayez-le en ligne

Non golfé:

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)

Le regex supprime les zéros de fin et le point décimal si nécessaire, ainsi que le signe plus et le zéro de tête de l'exposant s'il y en a un.


Je pense que les backticks s'ajouteront à un Lgrand nombre dans la plage d'entrée. stréviterait cela.
xnor

@xnor Le nombre entier maximum que nous devons prendre en charge est dans la intreprésentation de Python . Les longs commencent à peu près 2**63.
mbomb007

Avez-vous besoin de faire le sous-titrage regex? Pouvez-vous simplement supprimer des +caractères avec str.replace?
musicman523

1
@ musicman523 Ce serait beaucoup plus long. La sous-expression rationnelle doit être effectuée de toute façon pour supprimer les zéros et le point décimal, et ce n'est que de 2 octets pour supprimer +pendant que j'y suis.
mbomb007

1

Ohm , 35 octets

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

Essayez-le en ligne!

Sorties 0 pour décimal, 1 pour hex et 2 pour scientifique.

Explication:

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 octets

imprime 0 pour décimal, 1 pour hexadécimal et 2 pour scientifique

en cas d'égalité, le numéro le plus élevé sera imprimé

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

Essayez-le en ligne!

PHP , 91 octets

imprime 0 pour décimal, 1 pour hexadécimal et 2 pour scientifique

en cas d'égalité, le numéro le plus bas sera imprimé

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

Essayez-le en ligne!

PHP , 103 octets

imprime 0 pour décimal, 1 pour hexadécimal et 2 pour scientifique

en cas d'égalité tous les numéros seront imprimés

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;

Essayez-le en ligne!

PHP , 109 octets

Produire un tableau avec les solutions les plus courtes

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

Essayez-le en ligne!


0

C, 187185 octets

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

Décompressé:

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 pour décimal, 1 pour hex, 2 pour notation scientifique.


0

TI-Basic, 130 octets

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 bien:

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

Ou, en hex:

dc4e3eceb84e3ed7303e3170b1c04e04443e3370b1bbbcbbbfbbb642415345104e2b313604483e3004463e3104493ed14e6c4940b8ba4e83493e31304904493e46703104463ed43ec0447131044c3e317044714670104471466c31113e7270b14c117010306fba4c04533e10486c44113210446c53117010486d441110317010486c5311044e3ed6303e4e

Imprime 0 pour décimal, 1 pour hex, 2 pour notation scientifique

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.