帮我打我的号码!


25

在编写程序时,我通常最终会使用一些数字常量。我总是将它们放在十进制中,因为这就是我的想法,但是我只是意识到我的语言支持其他数字格式,这可能会使我略微缩短代码。

挑战

给定一个小于2 ^ 53-1的非负整数,请确定该整数是否具有以下最短表示形式:

  • 小数
  • 十六进制
  • 科学计数法

小数

由于这是我的语言的默认格式,因此该格式无需额外的注释。每个数字都照常表示为十进制。

十六进制

我的语言将0x前缀用于十六进制常量。这意味着,如果一个数字有4个十六进制数字,则将需要6个字节来表示该数字。

科学计数法

我的语言使用以下格式表示科学符号:

[Real base] 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

计分

这是,因此每种语言的答案以最短字节为准。


1
2^63-1对于某些语言,可能难以达到要求。考虑将其放宽到较低的值,例如2^32-1(这样的值适合双浮点数据类型)
Luis Mendo

1
我懂了。2 ^ 52-1怎么样?那仍然适合double。只是一个建议;做你认为合适的
路易斯Mendo

1
1000001000000也可以写成1000001e6虽然。
暴民埃里克(Erik the Outgolfer)

1
@JonathanAllan是的,那是@您,对不起。不,您可能不输出订购清单;由于这是一个决策问题,因此您需要确定一个输出。(但是您的实现可以对列表进行排序并输出第一项。)
musicman523

1
根据定义,决策问题不是仅应具有两个可能的输出吗?
mbomb007 '17

Answers:



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

哎呀,这里应该短些。
暴民埃里克(Erik the Outgolfer)

@EriktheOutgolfer:可能是。我用科学记数法花了很多字节。不创建实际值而只检查长度可能会更短。
Emigna

十六进制长度为len(hex(input)) + 2,如果有帮助。
暴民埃里克(Erik the Outgolfer)

@EriktheOutgolfer:是的,需要5个字节来获取十六进制十进制的长度。这是科学的表示法,将花费字节。可能会击败这个。
Emigna

2
@EriktheOutgolfer:使用¹而不是Dsg¹hgÌ
Emigna

3

果冻,28 个字节

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

返回12或分别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个字节!?最好使用C#...:P
TheLethalCoder

1
@TheLethalCoder绝对是一个欺骗性的挑战-必须有一个GL,它可以将数字格式化为科学计数法!
乔纳森·艾伦,

@TheLethalCoder不久前,在另一个问题上发布了一个75字节的果冻答案。记不得了。啊这是这一个,但是这一次是83
Draco18s

@ Draco18s都是我的!这个评论使我看了一个 8个月前站在91岁的人。我打到85 :)
乔纳森·艾伦

为了找到它们,我不得不在谷歌上搜索“最长的果冻”这个词,只限于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) + 2n加2 的以16为底的对数;大约n为十六进制的长度加上前缀0x

  • n.toExponential().length - 1n.toExponential()返回n科学格式的字符串(例如7e+3),但是我们从它的长度中减去1以考虑多余的字符+

现在,我们有所有3所表示的长度DHS我们比较:
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]


尼斯:)我想知道您能从我为解决这个问题而放弃的尝试中吸取任何东西吗?您可以在页面末尾的已删除帖子中找到它。
毛茸茸的

@Shaggy Yours从根本上有所不同,因为它输出格式化的数字。我根据它添加了一个单独的答案。:)
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在更高的数字上失去了精度,因此我不得不手动进行操作。可能有一种更短的方法,但这目前可行。对于此挑战,它的格式也不正确,因此无论如何我都必须手动剥离其输出。

如果我将字符串设置为nas 的值,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我可以删除的特殊情况短。


1

Python 2,83 77字节

输出数字的最小表示形式。

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

在线尝试

取消高尔夫:

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)

正则表达式将删除尾随的零和小数点(如果有必要),以及从指数中删除加号和前导零(如果有的话)。


我认为反引号会L在输入范围内将追加到大量数字上。str会避免这种情况。
xnor

@xnor我们必须支持的最大整数在Python的int表示范围内。多头从大约开始2**63
mbomb007

您是否需要进行正则表达式匹配?您可以使用删除+字符str.replace吗?
musicman523

1
@ musicman523这会更长。无论如何,都需要进行正则表达式匹配以删除零和小数点,而仅剩2个字节就可以删除+我正在使用的那个字符。
mbomb007 '17

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

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,187185字节

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基本(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代表科学计数法

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.