数字をゴルフしてください!


25

プログラムを書くとき、私は通常、いくつかの数値定数を使用することになります。それが私が考える方法だから、私は常にそれらを10進数に入れましたが、私は自分のコードがコードをわずかに短くするかもしれない他の数値形式をサポートしていることに気付きました。

チャレンジ

2 ^ 53-1未満の非負の整数が与えられた場合、その整数が以下で最も短い表現を持つかどうかを決定します。

  • 小数
  • 16進数
  • 科学表記法

小数

これは私の言語のデフォルト形式であるため、この形式に追加の表記法は必要ありません。すべての数値は、通常の10進数で表されます。

16進数

私の言語では、0x16進定数にプレフィックスを使用しています。これは、数値に4桁の16進数がある場合、その数値を表すのに6バイトかかることを意味します。

科学表記法

私の言語では、科学表記法に次の形式を使用しています。

[実底] e [10の整数指数]

たとえば、700はとして表され7e3ベースは-10〜10(非包括的)でなければならないため699として表されます。このチャレンジでは、入力された数値が負でないため、ベースは常に少なくとも0になります。6.99e3

出力

どの形式が最も短いかを識別する方法を返す必要があります(つまり、10進数の場合は0、16進数の場合は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(値は、倍精度浮動小数点データ型に収まるように)
ルイスMendo

1
そうですか。2 ^ 52-1はどうですか?それはまだ収まりますdouble。単なる提案。あなたが適切と思うように行う
ルイスメンドー

1
1000001000000のように書くこともでき1000001e6ます。
エリックアウトゴルファー

1
@ジョナサンアランはい、それは@あなたでした、ごめんなさい。いいえ、順序付きリストを出力することはできません。これは決定問題であるため、1つの出力を決定する必要があります。(ただし、実装によってリストがソートされ、最初のアイテムが出力される場合があります。)
musicman523

1
ではない意思決定問題の定義では、2つのだけ可能な出力を持っていることになって?
mbomb007

回答:



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

えー、ここにはもっと短いものがあるはずです。
エリックアウトゴルファー

@EriktheOutgolfer:おそらく。科学表記法で多くのバイトを費やしています。実際の値を作成せず、長さのみをチェックする方がおそらく短くなります。
エミグナ

len(hex(input)) + 2それが役立つ場合、16進数の長さはです。
エリックアウトゴルファー

@EriktheOutgolfer:ええ、5バイトで16進数10進数の長さを取得します。バイトがかかるのは科学表記法です。おそらくこれを打ち負かすでしょう。
エミグナ

2
@EriktheOutgolfer:の¹代わりに使用Dsg¹hgÌ
エミグナ

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間違いなく欺challenge的な挑戦-数字を科学的表記法にフォーマットするだけのGLがあるはずです!
ジョナサンアラン

@TheLethalCoderそれほど前ではない別の質問に投稿された75バイトのゼリーの回答があります。何を思い出せない。ああ、それはだったこの1、しかしこれは 83です
Draco18s

@ Draco18s両方とも私が見る!このコメントから、8か月前から91だったこの記事を見ることができました。私は85までゴルフをしました:)
ジョナサンアラン

それらを見つけるには、codegolf.stackexchange.comに限定された「longest Jelly」というフレーズをGoogleで検索する必要がありました。:第三は、Pありましたが、それは....のみ微々たる57のバイトでした。また、あなた
Draco18s

2

JavaScript(ES6)、90バイト

10進数の場合は0、16進数の場合は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。おおよそn10進数の長さ。

  • log(n) / log(16) + 2nプラス2の16を底とする対数。大体n16進数の長さにprependedを加えた0x

  • n.toExponential().length - 1:科学的な形式(例)でn.toExponential()文字列を返しますが、余分なものを考慮してその長さから1を引きます。n7e+3+

今、私たちはすべての3つの表現の長さを持っていることDHおよび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]


ニース:)これをさらにゴルフに解決するための私の放棄された試みから何かを略奪することができますか?ページの最後にある削除された投稿にあります。
シャギー

@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数値が大きくなると精度が失われるため、手動で行う必要がありました。おそらくもっと短い方法がありますが、これは今のところ機能します。また、このチャレンジのためにそれを間違ってフォーマットするので、とにかく出力を手動で取り除く必要があります。

私はの値に文字列を設定した場合nvar 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よりもasの方が短いです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

1

オーム、35バイト

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

オンラインでお試しください!

10進数の場合は0、16進数の場合は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バイト

10進数で0、16進数で1、科学技術で2を出力します

同点の場合、最高の数字が印刷されます

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

オンラインでお試しください!

PHP、91バイト

10進数で0、16進数で1、科学技術で2を出力します

同点の場合、最小の数字が印刷されます

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

オンラインでお試しください!

PHP、103バイト

10進数で0、16進数で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
}

10進数の場合は0、16進数の場合は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

または、16進数で:

dc4e3eceb84e3ed7303e3170b1c04e04443e3370b1bbbcbbbfbbb642415345104e2b313604483e3004463e3104493ed14e6c4940b8ba4e83493e31304904493e46703104463ed43ec0447131044c3e317044714670104471466c31113e7270b14c117010306fba4c04533e10486c44113210446c53117010486d441110317010486c5311044e3ed6303e4e

10進数の場合は0、16進数の場合は1、科学表記法の場合は2を出力します

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.