Помогите мне в гольф мои номера!

25

При написании программ я обычно использую некоторые числовые константы. Я всегда помещаю их в десятичную дробь, потому что я так думаю, но я только что понял, что мой язык поддерживает другие числовые форматы, которые могут позволить мне немного сократить код.

Вызов

Если неотрицательное целое число меньше 2 ^ 53-1, решите, имеет ли это целое кратчайшее представление в:

  • Десятичный
  • шестнадцатеричный
  • Научная нотация

Десятичный

Поскольку это формат по умолчанию для моего языка, для этого формата не требуется никаких дополнительных обозначений. Каждое число представляется как обычно для десятичного числа.

шестнадцатеричный

Мои языки используют 0xпрефикс для шестнадцатеричных констант. Это означает, что если число имеет 4 шестнадцатеричных цифры, для представления этого числа потребуется 6 байтов.

Научная нотация

Мой язык использует следующий формат для научной нотации:

[Действительная база] e [Целочисленный показатель 10]

Например, 700будет представлен как 7e3и 699будет представлен как 6.99e3, потому что основание должно быть между -10 и 10 (не включительно). Для целей этой задачи основание всегда будет по крайней мере 0, так как введенное число неотрицательно.

Выход

Вы должны вернуть способ определения, какой формат самый короткий (т. Е. 0 для десятичного числа, 1 для шестнадцатеричного, 2 для научного). Кроме того, вы можете вывести наименьшее представление самого числа.

Контрольные примеры

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

счет

Это , поэтому выигрывает ответ в кратчайших байтах для каждого языка.

musicman523
источник
1
Требование подняться 2^63-1может быть трудным для некоторых языков. Подумайте об уменьшении этого значения до более низкого значения, например 2^32-1(чтобы значения соответствовали типу данных с двойной плавающей запятой)
Луис Мендо
1
Понимаю. Как насчет 2 ^ 52-1? Это все еще вписывается double. Просто предложение; делай, как считаешь нужным
Луис Мендо
1
1000001000000также может быть написано как 1000001e6будто.
Эрик Outgolfer
1
@JonathanAllan да, это был @ ты, извини. И нет, вы не можете вывести упорядоченный список; поскольку это проблема решения , вам нужно выбрать один выход. (Но ваша реализация может отсортировать список и вывести первый элемент.)
musicman523
1
Разве проблема решения по определению не должна иметь только два возможных выхода?
mbomb007

Ответы:

5

05AB1E , 23 байта

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

Попробуйте онлайн!

-1 спасибо Эмигне .

0для шестнадцатеричной, 1для десятичной, 2для научных.

Эрик Outgolfer
источник
Сохранить байт с '.ìÁ0.
Emigna
@ Emigna ооо, что всегда готово для игры в гольф.
Эрик Outgolfer
4

05AB1E , 27 байт

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

Попробуйте онлайн!

объяснение

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
источник
Ew, здесь должно быть что-то короче.
Эрик Outgolfer
@EriktheOutgolfer: Возможно. Я провожу много байтов с научной нотацией. Вероятно, было бы короче, чтобы не создавать фактические значения и вместо этого проверять только длины.
Эминья
Шестнадцатеричная длина есть len(hex(input)) + 2, если это поможет.
Эрик Outgolfer
@EriktheOutgolfer: Да, 5 байтов, чтобы получить длину в шестнадцатеричном и десятичном виде . Это научное обозначение, которое будет стоить байтов. Вероятно, побьет это все же.
Эминья
2
@EriktheOutgolfer: Использование ¹вместо Ds:g¹hgÌ
Emigna
3

Желе , 28 байт

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

Монадическая ссылка возвращение 1, 2или 3шестнадцатеричный, научной или десятичный соответственно.

Попробуйте онлайн! или посмотрите набор тестов .

Я думал, что это будет короче, но я не вижу этого, поэтому пишу.

Как работает это чудовище ...

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 байт !?
Можно
1
@TheLethalCoder Определенно обманчивая задача - должен быть GL, который может просто отформатировать числа в научную нотацию!
Джонатан Аллан
@TheLethalCoder Не так давно на другой вопрос был опубликован 75-байтовый ответ Jelly. Не могу вспомнить, что именно. Ах, это был этот , но это 83.
Draco18s
@ Draco18s оба мои, я вижу! Комментарий заставил меня взглянуть на этот, который стоял на 91 от 8 месяцев назад; Я сыграл в гольф до 85 :)
Джонатан Аллан
Мне пришлось оставить в Google фразу «самое длинное желе», ограниченную codegolf.stackexchange.com, чтобы найти их. : P Был третий, но это были всего лишь ничтожные 57 байтов .... Тоже ваши .
Draco18s
2

JavaScript (ES6), 90 байт

Возвращает 0 для десятичного числа, 1 для шестнадцатеричного, -1 для научного.

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

объяснение

  • log(n) / log(10): основание-10 логарифм n; примерно длина nкак десятичная дробь.

  • log(n) / log(16) + 2: основание-16 логарифм nплюс 2; примерно длина nшестнадцатеричного плюс добавленный 0x.

  • n.toExponential().length - 1: n.toExponential()возвращает строку с nв научном формате (например 7e+3), но мы вычитаем 1 из ее длины, чтобы учесть посторонние +.

Теперь, когда мы имеем длину всех 3 -х представлений D, Hи Sмы сравниваем:
S<H?-(S<D):+(H<D)


JavaScript (ES6), 97 байт

Этот выводит число в формате с самой короткой длиной. Вдохновленный удаленной попыткой @ Shaggy .

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

darrylyeo
источник
Здорово :) Интересно, не могли бы вы что-нибудь разграбить из-за моей заброшенной попытки решить эту проблему? Вы найдете это в удаленных сообщениях в конце страницы.
Лохматый
@Shaggy Ваш принципиально отличается, поскольку он выводит отформатированный номер. Вместо этого я добавил отдельный ответ, основанный на нем. :)
darrylyeo
1

C #, 106 97 96 143 132 байта

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

Досадно в C # ulong.ToStringспецификатор форматаe теряет точность при старших числах, поэтому мне пришлось делать это вручную. Вероятно, есть более короткий способ сделать это, но пока это работает. Он также форматирует его неправильно для этой задачи, поэтому мне все равно придется вручную обрезать вывод.

Если я установлю строку в значение, так nкак var s=n+"";она работает дольше из-за явного возврата и дополнительных фигурных скобок.

Он возвращает самое короткое значение из массива каждого другого значения, где [0] = decimal, [1] = hexadecimal, [2] = scientific.

Полная / Отформатированная версия:

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

Правильный способ расчета научных результатов:

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

Тем не менее, видя, что 0короче, чем 0e0я могу удалить этот особый случай.

TheLethalCoder
источник
1

Python 2, 83 77 байт

Выводит наименьшее представление числа.

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

Попробуйте онлайн

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)

При необходимости регулярное выражение удаляет завершающие нули и десятичную точку, а также знак плюс и начальный ноль от показателя степени, если он есть.

mbomb007
источник
Я думаю, что обратные пометки будут добавлять Lк большим числам в пределах диапазона ввода. strбы избежать этого.
xnor
@xnor Максимальное целое число, которое мы должны поддерживать, находится в intпредставлении Python . Длинные начинаются примерно 2**63.
mbomb007
Вам нужно сделать подстановку регулярных выражений? Вы можете просто удалить +символы с str.replace?
musicman523
1
@ musicman523 Это было бы намного дольше. Подстановка регулярного выражения в любом случае должна быть сделана для удаления нулей и десятичной точки, и это всего лишь 2 байта, чтобы удалить, +пока я в нем.
mbomb007
1

Ом 35 байт

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

Попробуйте онлайн!

Выходы 0 для десятичной, 1 для шестнадцатеричной и 2 для научной.

Объяснение:

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
источник
0

PHP , 90 байт

печатает 0 для десятичной, 1 для шестнадцатеричной и 2 для научной

в случае галстука будет напечатано наибольшее число

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

Попробуйте онлайн!

PHP , 91 байт

печатает 0 для десятичной, 1 для шестнадцатеричной и 2 для научной

в случае галстука будет напечатано наименьшее число

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

Попробуйте онлайн!

PHP , 103 байта

печатает 0 для десятичной, 1 для шестнадцатеричной и 2 для научной

в случае галстука будут напечатаны все номера

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;

Попробуйте онлайн!

PHP , 109 байт

Выведите массив с кратчайшими решениями

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

Попробуйте онлайн!

Йорг Хюльсерманн
источник
0

C 187 185 байт

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

расжатая:

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
}

Выводит 0 для десятичной дроби, 1 для шестнадцатеричной, 2 для научной записи.

Электра
источник
0

TI-Basic, 130 байт

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

Или, альтернативно:

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

Или в шестнадцатеричном виде:

dc4e3eceb84e3ed7303e3170b1c04e04443e3370b1bbbcbbbfbbb642415345104e2b313604483e3004463e3104493ed14e6c4940b8ba4e83493e31304904493e46703104463ed43ec0447131044c3e317044714670104471466c31113e7270b14c117010306fba4c04533e10486c44113210446c53117010486d441110317010486c5311044e3ed6303e4e

Выводит 0 для десятичной дроби, 1 для шестнадцатеричной, 2 для научной записи

Электра
источник