ตัดและนับทศนิยม


11

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

ตัวอย่าง

-12.32
2

32
0

3231.432
3

-34.0
0 -34

023
0 23

00324.230
2 324.23

10
0

00.3
1 0.3

0
0

-04.8330
3 -4.833

กฎระเบียบ

  • อินพุตจะเป็นสตริงที่สามารถใช้ผ่าน STDIN อาร์กิวเมนต์ของฟังก์ชันหรือค่าที่ใกล้เคียงที่สุด
  • เอาต์พุตสามารถผ่านการคืนค่าฟังก์ชัน STDOUT หรือเทียบเท่าที่ใกล้เคียงที่สุด
  • ไม่มีการ จำกัด ขนาดสำหรับอินพุตจำนวนเต็มยกเว้นความยาวสตริงสูงสุดของภาษาของคุณ
  • หากอินพุตมีค่าศูนย์ (นำหน้าหรือต่อท้าย) ที่ไม่จำเป็น:
    1. คุณควรพาพวกเขาออกไป
    2. เอาท์พุทจำนวนตำแหน่งทศนิยมในจำนวนใหม่
    3. ส่งออกหมายเลขใหม่คั่นด้วยตัวคั่น (เช่นช่องว่าง, บรรทัดใหม่, จุลภาค)
  • ข้อมูลที่ป้อนจะตรงกับ RegEx นี้เสมอ: -?\d+(\.\d+)?หรือถ้าคุณไม่พูด RegEx :
    • มีอาจจะเป็น-ที่จุดเริ่มต้นหมายความจำนวนลบ จากนั้นจะมีอย่างน้อยหนึ่งหลัก จากนั้นอาจมี ... .และอีกจำนวนหนึ่ง
    • ในการตรวจสอบว่าอินพุตถูกต้องหรือไม่ตรวจสอบที่นี่
  • ไม่มี Regex

นี่คือสั้นที่สุดในหน่วยไบต์


อาจเพิ่มกรณีทดสอบที่มีเครื่องหมายลบและเลขศูนย์นำหน้าใช่ไหม
Luis Mendo

อนุญาตให้ส่งออกหมายเลขสุดท้ายโดยไม่คำนึงว่าจะถูกเล็มหรือไม่?
แทรกชื่อที่นี่

1
@insertusername คุณไม่สามารถส่งออกหมายเลขที่สองได้หากถูกตัดออกเท่านั้น
Downgoat

1
คุณอาจต้องการที่จะเพิ่มการทดสอบ / 0กรณีตัวอย่างสำหรับคนเดียว
แทรกที่นี่

3
-1 สำหรับข้อ จำกัด regex ที่ไม่มีจุดหมาย
Conor O'Brien

คำตอบ:


0

PHP 7, 142 ไบต์

ฉันสามารถบีบทุกอย่างให้เป็นงานพิมพ์เดียว:

<?=strlen((explode('.',$t=trim('-'==($_=$argv[1])[0]?$n=$_=trim($_,'-'):$_,0)))[1]).($t!==$_?($n?' -':' ').('.'==$t[0]?0:'').trim($t,'.'):'');

ทำงานจากบรรทัดคำสั่งเช่น:

$ php trimandcount.php "-04833.010"

การสาธิต

ดูกรณีทดสอบทั้งหมดรวมถึงการดำเนินการที่ยาวมาก (62 ตัวอักษร):

ลองก่อนซื้อ1

1 วางเมาส์เหนือช่องด้านล่าง " เอาต์พุตสำหรับ 7.0.0 " เพื่อดูผลลัพธ์ทั้งหมด


4

Python 2, 165 180 bytes

ตอนแรกฉันคิดว่าจะเขียนโปรแกรม Pyth แรกของฉันแล้วให้นับตัวเลขหลังเครื่องหมายจุลภาค แต่แล้วฉันก็ค่อนข้างหงุดหงิดฉันไม่รู้ว่าคุณจะสนุกกับภาษานั้นเดาว่ามันเป็นเพียงเพื่อวัตถุประสงค์ในการชนะ ต่อไปนี้เป็นวิธีแก้ปัญหาของฉัน (แก้ไขเนื่องจากไม่ได้ผลเป็นจำนวนมาก):

def t(i):
 o,a='',i
 while a[-1]=='0':
  a=a[:-1]
 while a[0]=='0':
  a=a[1:]
 if a[-1]=='.':a=a[:-1]
 if'.'in a:o=str(len(a)-a.index('.')-1)
 else:o='0'
 if a!=i:o+=" "+a
 print o

ในกรณีที่ใครต้องการที่จะสร้างการทำงานของฉันใน Pyth: เพื่อดูว่าคุณจะอยู่ที่คุณอาจต้องการที่จะแทรกระหว่าง~b@+cz"."" "1Wq@b_1"0"~b<b_1)plrb6 AP@+


2

05AB1E , 23 ไบต์ (ไม่แข่งขัน)

ประณามฉันอยู่ใกล้มาก Python วิเคราะห์คำลอยตัวขนาดใหญ่มากโดยใช้สัญลักษณ์ทางวิทยาศาสตร์ดังนั้นฉันจึงแก้ไขข้อผิดพลาดนี้ในล่าม อย่างไรก็ตามสิ่งนี้ทำหลังจากการท้าทายและการส่งของฉันจึงไม่ใช่การแข่งขัน

รหัส:

DÞ'.¡0Üg,\DÞ0Ü'.ÜDrQ_i,

คำอธิบาย:

D                       # Duplicate top of the stack, or input when empty
 Þ                      # Convert to float
  '.¡                   # Split on '.' (decimal point)
     0Ü                 # Remove trailing zeroes
       g                # Get the length
        ,               # Output top of the stack (the length)
         \              # Discard the top item
          D             # Duplicate top of the stack
           Þ            # Convert to float
            0Ü          # Remove trailing zeroes
              '.Ü       # Remove trailing dots
                 D      # Duplicate top of the stack
                  r     # Reverse the stack
                   Q_i, # If not equal, print top of the stack

ใช้การเข้ารหัส ISO 8859-1


2

JavaScript (ES6), 156 162

แก้ไขข้อผิดพลาดคงที่สำหรับ '-0' - ขอบคุณ @Fez Vrasta แก้ไข 2 6 ไบต์บันทึก thx @Neil

มันยุ่งเหยิง แต่มันเป็นสตริง 100% ไม่ จำกัด เนื่องจากชนิดตัวเลข

s=>(l=k=p=t=0,[...s].map(c=>++t&&c=='.'?p=t:+c&&(l=t,k=k||t)),m=p>l?p-1:p?l:t,k=k>p&&p?p-2:k-1,r=(s<'0'?'-':'')+s.slice(k,m),(p&&m>p?m-p:0)+(r!=s?' '+r:''))

น้อย golfed

f=s=>
(
  // All values are position base 1, so that 0 means 'missing'
  // k position of first nonzero digit
  // l position of last non zero digit
  // p position of decimal point
  // t string length
  l=k=p=t=0,
  // Analyze input string
  [...s].map((c,i)=>c=>++t&&c=='.'?p=t:+c&&(l=t,k=k||t)),
  // m position of last digits in output
  // if the point is after the last nz digit, must keep the digits up to before the point
  // else if point found, keep  up to l, else it's a integer: keep all
  m=p>l?p-1:p?l:t,
  // the start is the first nonzero digit for an integer
  // but if there is a point must be at least 1 char before the point
  k=k>p&&p?p-2:k-1,
  // almost found result : original string from k to m
  r=(s<'0'?'-':'')+s.slice(k,m), // but eventually prepend a minus
  (p&&m>p?m-p:0) // number of decimal digits
  +(r!=s?' '+r:'') // append the result if it's different from input
)

ทดสอบ

F=s=>(l=k=p=t=0,[...s].map(c=>++t&&c=='.'?p=t:+c&&(l=t,k=k||t)),m=p>l?p-1:p?l:t,k=k>p&&p?p-2:k-1,r=(s<'0'?'-':'')+s.slice(k,m),(p&&m>p?m-p:0)+(r!=s?' '+r:''))

console.log=x=>O.textContent+=x+'\n';
// Test cases  
;[['-12.32','2'],['32','0'],['3231.432','3'],['-34.0','0 -34']
 ,['023','0 23'],['00324.230','2 324.23'],['10','0'],['00.3','1 0.3']
 ,['0','0'],['-0','0'],['-04.8330','3 -4.833']]
.forEach(t=>{
  var i=t[0],k=t[1],r=F(i);
  console.log((k==r?'OK ':'KO ')+i+' -> '+r)})

function test(){var i=I.value,r=F(i);R.textContent=r;}
test()
input { width:90% }
input,span { font-family: sans-serif; font-size:14px }
Input: <input id=I oninput='test()' value='-000000098765432112345.67898765432100000'>
Output: <span id=R></span><br>
Test cases<br>
<pre id=O></pre>


ดูเหมือนว่าทั้งฉันและคำตอบของคุณมีปัญหาเกี่ยวกับการ-0ป้อนข้อมูล .. เราควรจะส่งออก0ไม่ได้0 0
Fez Vrasta

ใช่ขอบคุณที่ชี้ให้เห็น
edc65

แก้ไข @FezVrasta แล้ว
edc65

ไม่c=='.'?p=t:+c&&(l=t,k=k||t)ทำงานเพื่อช่วยให้คุณประหยัดไบต์หรือไม่?
Neil

ฉันคิดว่าคุณอาจจะสามารถประหยัดได้มากขึ้นโดยการใช้t=l=k=p=0และ++t&&c=='.'อื่น ๆ
Neil

1

ES6, 102 180 177 ไบต์

s=>(t=s.replace(/(-?)0*(\d+(.\d*[1-9])?).*/,"$1$2"),d=t.length,d-=1+t.indexOf('.')||d,t!=s?d+' '+t:d)

s=>{t=[...s];for(m=t[0]<'0';t[+m]==0&&t[m+1]>'.';)t[m++]='';r=l=t.length;for(r-=1+t.indexOf('.')||l;t[--l]<1&&r;r--)t[l]='';t[l]<'0'?t[l]='':0;t=t.join``;return t!=s?r+' '+t:r}

แก้ไข: บันทึกแล้ว 3 ไบต์ด้วย @ edc65; บันทึก 1 ไบต์ด้วยการแทรกชื่อผู้ใช้ที่นี่


ลองใช้สt=[...s]
เปรด

@ edc65 ฉันใช้เวลานานหลายปีในการตีกอล์ฟกลับลงมาหลังจากที่ต้องเขียนใหม่และคุณจะได้พบกับการประหยัด 3 ไบต์ในแฟลช ...
Neil

ฉันคิดว่าคุณสามารถบันทึก1 ไบต์ : แทนที่ด้วยt[--l]==0 t[--l]<1
insertusernamehere

@insertusername ที่นี่ขอบคุณ!
Neil

0

C ++, 180 ไบต์

int f(char*s,char*&p){int m=*s=='-',n=0;for(p=s+m;*p=='0';++p);for(;*++s-'.'&&*s;);p-=p==s;if(*s){for(;*++s;)++n;for(;*--s=='0';--n)*s=0;*s*=n>0;}if(m&&*p-'0'|n)*--p='-';return n;}

นี่คือ C ++ แบบพกพาที่ทำให้ไม่มีการสันนิษฐานของการเข้ารหัสอักขระและรวมถึงไม่มีไลบรารี (แม้แต่ไลบรารีมาตรฐาน)

sการป้อนข้อมูลจะถูกส่งใน จำนวนตำแหน่งทศนิยมจะถูกส่งกลับ pสตริงที่มีการแก้ไขในสถานที่และเริ่มต้นใหม่จะถูกส่งกลับใน

ตามสิทธิที่ฉันควรจะกลับsize_tแต่ฉันจะไปเรียกร้องว่าคุณควรจะรวบรวมนี้สำหรับ OS ที่ จำกัด intขนาดของสายถึงครึ่งหนึ่งของช่วง ฉันคิดว่ามันสมเหตุสมผล มันนับมากกว่า 2 พันล้านตำแหน่งทศนิยมบนสถาปัตยกรรมแบบ 32 บิต

คำอธิบาย

int f(char*s, char*&p){
    int m=*s=='-', n=0;
    for(p=s+m;*p=='0';++p);     // trim leading zeros
    for(;*++s-'.'&&*s;);        // advance to decimal point
    p-=p==s;                    // back up if all zeros before point
    if(*s){
        for(;*++s;)++n;          // count decimal places
        for(;*--s=='0';--n)*s=0; // back up and null out trailing zeros
        *s*=n>0;                 // don't end with a decimal point
    }
    if(m&&*p-'0'|n)*--p='-';    // reinstate negative sign
    return n;
}

โปรแกรมทดสอบ

#include <cstring>
#include <cstdio>
int main(int argc, char **argv)
{
    for (int i = 1;  i < argc;  ++i) {
        char buf[200];
        strcpy(buf, argv[i]);
        char *s;
        int n = f(buf, s);
        printf("%10s ==> %-10s (%d dp)\n", argv[i], s, n);
    }
}

ทดสอบผลลัพธ์

    -12.32 ==> -12.32     (2 dp)
        32 ==> 32         (0 dp)
  3231.432 ==> 3231.432   (3 dp)
     -34.0 ==> -34        (0 dp)
       023 ==> 23         (0 dp)
 00324.230 ==> 324.23     (2 dp)
        10 ==> 10         (0 dp)
      00.3 ==> 0.3        (1 dp)
  -04.8330 ==> -4.833     (3 dp)
    -00.00 ==> 0          (0 dp)
       -00 ==> 0          (0 dp)
       000 ==> 0          (0 dp)
      0.00 ==> 0          (0 dp)
      -0.3 ==> -0.3       (1 dp)
         5 ==> 5          (0 dp)
        -5 ==> -5         (0 dp)
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.