ช่วยฉันตีหมายเลขของฉันด้วย!


25

เมื่อเขียนโปรแกรมฉันมักจะลงเอยด้วยค่าคงที่ตัวเลข ฉันใส่มันเป็นทศนิยมเสมอเพราะนั่นคือสิ่งที่ฉันคิด แต่ฉันเพิ่งรู้ว่าภาษาของฉันรองรับรูปแบบตัวเลขอื่น ๆ ที่อาจทำให้ฉันย่อรหัสของฉันลงเล็กน้อย

ท้าทาย

รับจำนวนเต็มที่ไม่เป็นลบน้อยกว่า 2 ^ 53-1 ตัดสินใจว่าจำนวนเต็มนั้นมีการแทนค่าสั้นที่สุดใน:

  • ทศนิยม
  • เลขฐานสิบหก
  • สัญกรณ์วิทยาศาสตร์

ทศนิยม

เนื่องจากนี่เป็นรูปแบบเริ่มต้นของภาษาของฉันจึงไม่จำเป็นต้องมีเครื่องหมายพิเศษสำหรับรูปแบบนี้ ทุกหมายเลขจะแสดงตามปกติสำหรับทศนิยม

เลขฐานสิบหก

ภาษาของฉันใช้0xคำนำหน้าสำหรับค่าคงที่เลขฐานสิบหก ซึ่งหมายความว่าหากตัวเลขมีเลขฐานสิบหก 4 หลักจะใช้เวลา 6 ไบต์เพื่อแสดงตัวเลขนั้น

สัญกรณ์วิทยาศาสตร์

ภาษาของฉันใช้รูปแบบต่อไปนี้สำหรับสัญกรณ์ทางวิทยาศาสตร์:

[ฐานจริง] e [เลขชี้กำลังจำนวนเต็มของ 10]

ตัวอย่างเช่น700จะแสดงเป็น7e3และ699จะแสดงเป็น6.99e3เพราะฐานจะต้องอยู่ระหว่าง -10 ถึง 10 (ไม่รวม) สำหรับจุดประสงค์ของการท้าทายฐานจะมีค่าอย่างน้อย 0 เสมอเนื่องจากจำนวนที่ป้อนนั้นไม่เป็นลบ

เอาท์พุต

คุณควรกลับวิธีระบุรูปแบบที่สั้นที่สุด (เช่น 0 สำหรับทศนิยม, 1 สำหรับ hex, 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ที่เหมาะกับยังคงอยู่ใน เพียงข้อเสนอแนะ; ทำตามที่เห็นสมควร
Luis Mendo

1
1000001000000สามารถเขียนได้ราวกับ1000001e6ว่า
Erik the Outgolfer

1
@JanathanAllan ใช่นั่นคือ @ คุณขอโทษ และไม่คุณไม่สามารถส่งออกรายการสั่งซื้อ เนื่องจากนี่เป็นปัญหาในการตัดสินใจคุณต้องตัดสินใจเลือกหนึ่งเอาต์พุต (แต่การนำไปใช้ของคุณอาจเรียงลำดับรายการและส่งออกรายการแรก)
musicman523

1
ไม่ใช่ปัญหาการตัดสินใจตามคำจำกัดความที่ควรจะมีสองผลลัพธ์ที่เป็นไปได้?
mbomb007

คำตอบ:


5

05AB1E , 23 ไบต์

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

ลองออนไลน์!

-1 ขอบคุณที่Emigna

0สำหรับเลขฐานสิบหก1สำหรับทศนิยม2สำหรับทางวิทยาศาสตร์


'.ìÁ0บันทึกไบต์ด้วย
Emigna

@Emigna ooh ที่เติมสนามกอล์ฟเสมอทุกสิ่ง
Erik the 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

ใช่ควรมีบางสิ่งที่สั้นกว่านี้
Erik the Outgolfer

@EriktheOutgolfer: อาจเป็นไปได้ ฉันใช้ไบต์ไปกับสัญกรณ์วิทยาศาสตร์ มันอาจจะสั้นกว่าที่จะไม่สร้างค่าจริงและตรวจสอบความยาวแทนเท่านั้น
Emigna

ความยาวฐานlen(hex(input)) + 2สิบหกคือถ้าช่วย
Erik the Outgolfer

@EriktheOutgolfer: ใช่ 5 ไบต์เพื่อให้ได้ความยาวของฐานสิบหกและทศนิยม มันเป็นสัญกรณ์ทางวิทยาศาสตร์ที่จะมีราคาไบต์ มีแนวโน้มที่จะเอาชนะสิ่งนี้ได้
Emigna

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 ไบต์! อาจใช้ C # ... : P
TheLethalCoder

1
@TheLethalCoder แน่นอนความท้าทายที่หลอกลวง - ต้องมี GL ที่นั่นซึ่งสามารถจัดรูปแบบตัวเลขให้กับเครื่องหมายทางวิทยาศาสตร์ได้!
Jonathan Allan

@TheLethalCoder มีคำตอบเจลลี่ 75 ไบต์ที่โพสต์ไว้ในคำถามอื่นเมื่อไม่นานมานี้ จำอะไรไม่ได้ มันเป็นอันนี้แต่อันนี้คือ 83
Draco18s

@ Draco18s ทั้งฉันเห็นแล้ว! ความคิดเห็นทำให้ฉันดูที่นี่ซึ่งยืนที่ 91 จาก 8 เดือนที่ผ่านมา; ฉันตีมันลงที่ 85 :)
Jonathan Allan

ฉันต้อง google วลี "ยาวที่สุดเยลลี่" จำกัด to 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; ประมาณความยาวของเป็นเลขฐานสิบหกบวกเพิ่มด้านหน้าn0x

  • n.toExponential().length - 1: n.toExponential()กลับสตริงที่มีnในรูปแบบทางวิทยาศาสตร์ (เช่น7e+3) แต่เราลบ 1 +จากความยาวของมันไปยังบัญชีสำหรับภายนอก

ตอนนี้เรามีความยาวของทั้ง 3 เป็นตัวแทนD, HและSเราเปรียบเทียบ:
S<H?-(S<D):+(H<D)


JavaScript (ES6), 97 ไบต์

อันนี้ส่งออกตัวเลขในรูปแบบที่มีความยาวสั้นที่สุด แรงบันดาลใจจาก@ พยายามที่ลบปุย

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


Nice :) ฉันสงสัยว่าคุณจะปล้นอะไรจากความพยายามที่ถูกทอดทิ้งของฉันเพื่อแก้ไขปัญหานี้ลงไปอีกไหม? คุณจะพบมันในโพสต์ที่ถูกลบในตอนท้ายของหน้า
Shaggy

@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สูญเสียความแม่นยำในตัวเลขที่สูงขึ้นดังนั้นฉันต้องทำด้วยตนเอง อาจเป็นวิธีที่สั้นกว่าที่จะทำ แต่ตอนนี้ได้ผล นอกจากนี้ยังจัดรูปแบบมันไม่ถูกต้องสำหรับความท้าทายนี้ดังนั้นฉันจะต้องเอามันออกด้วยตนเอง

หากฉันตั้งสตริงค่าของ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ฉันสามารถลบเคสพิเศษนั้นได้


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)

regex จะลบศูนย์ต่อท้ายและจุดทศนิยมถ้าจำเป็นรวมทั้งเครื่องหมายบวกและนำศูนย์จากเลขชี้กำลังหากมีหนึ่ง


ฉันคิดว่า backticks จะต่อท้ายเป็นLจำนวนมากภายในช่วงอินพุต strจะหลีกเลี่ยงสิ่งนั้น
xnor

@xnor จำนวนเต็มที่สูงสุดที่เราต้องสนับสนุนอยู่ภายในการintแสดงของ Python Longs 2**63เริ่มต้นที่ประมาณ
mbomb007

คุณจำเป็นต้องทำ regex subbing หรือไม่ คุณสามารถลบ+อักขระด้วยได้str.replaceหรือไม่
musicman523

1
@ musicman523 นั่นคงจะนานกว่านี้อีกแล้ว ต้องทำการซับย่อย regex ต่อไปเพื่อลบศูนย์และจุดทศนิยมและมีเพียง 2 ไบต์เท่านั้นที่จะลบ+ขณะที่ฉันอยู่ในนั้น
mbomb007

1

โอห์ม 35 ไบต์

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

ลองออนไลน์!

เอาต์พุต 0 สำหรับทศนิยม 1 สำหรับ hex และ 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, 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 สำหรับ hex, 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

หรือเป็น hex:

dc4e3eceb84e3ed7303e3170b1c04e04443e3370b1bbbcbbbfbbb642415345104e2b313604483e3004463e3104493ed14e6c4940b8ba4e83493e31304904493e46703104463ed43ec0447131044c3e317044714670104471466c31113e7270b14c117010306fba4c04533e10486c44113210446c53117010486d441110317010486c5311044e3ed6303e4e

พิมพ์ 0 สำหรับทศนิยม 1 สำหรับ hex, 2 สำหรับสัญลักษณ์ทางวิทยาศาสตร์

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.