Ondalık Sayıları Kesme ve Sayma


11

Bu sınamada, girdi dizesinde kaç ondalık basamak bulunduğunu göstermek için bir program yazacak ve gerekirse girdiyi kırpacaksınız.

Örnekler

-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

kurallar

  • Girdi, STDIN, işlev bağımsız değişkenleri veya en yakın eşdeğerden alınabilecek bir dize olacaktır
  • Çıkış, işlev dönüşü, STDOUT veya en yakın eşdeğeri aracılığıyla olabilir.
  • Dillerinizin maksimum dize uzunluğu dışında , giriş tamsayısının boyutu için bir sınır yoktur .
  • Girişte gereksiz (baştaki veya sondaki) sıfırlar varsa:
    1. Onları çıkarmalısın
    2. Yeni sayıdaki ondalık basamak miktarını çıktılar
    3. Ayırıcı ile ayrılmış yeni sayının çıktısını (örn. Boşluk, yeni satır, virgül)
  • Giriş her zaman bu RegEx ile eşleşir: -?\d+(\.\d+)?veya RegEx'i konuşmuyorsanız :
    • Orada olabilir bir olmak -negatif bir sayı ima başında. Sonra en az bir rakam olacak. Sonra olabilir ... Bir olmak .ve biraz daha basamak.
    • Bir girişin geçerli olup olmadığını kontrol etmek için buraya bakın
  • Normal İfade Yok

Bu yani bayt en kısa kod kazanır


Belki eksi işareti ve önde gelen sıfırları olan bir test örneği ekleyin?
Luis Mendo

Kesilip kesilmemesine bakılmaksızın nihai sayının çıkarılmasına izin veriliyor mu?
insertusernameburada

1
@insertusernameburada hayır, yalnızca kesilmişse ikinci sayıyı
çıkaramazsınız

1
Tek bir kişi için test senaryosu / örneği eklemek isteyebilirsiniz 0.
insertusernameburada

3
Anlamsız normal ifade kısıtlaması için -1.
Conor O'Brien

Yanıtlar:


0

PHP 7, 142 bayt

Bir şekilde her şeyi tek bir baskı deyimine sıkıştırmayı başardım:

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

Komut satırından çalışır, örneğin:

$ php trimandcount.php "-04833.010"

gösteri

Çok uzun bir uygulama (62 karakter) dahil tüm test senaryolarını görün:

Satın almadan önce deneyin 1

1 Tüm sonuçları görmek için imleci " 7.0.0 için çıktı " nın altındaki kutunun üzerine getirin .


4

Python 2, 165180 bayt

İlk başta ilk Pyth programımı yazmayı düşünüyordum, potansiyel virgülden sonraki rakamları saymayı başardım. Ama sonra oldukça rahatsız oldum, bu dilden nasıl keyif alacağınızı bilmiyorum, sanırım sadece kazanan amaçlar için. Neyse işte benim çözüm (çok sayıda işe yaramadı beri düzenlenmiş)

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

Herhangi ~b@+cz"."" "1Wq@b_1"0"~b<b_1)plrb6birinin Pyth'teki çalışmamı inşa etmek istemesi durumunda: Nerede olduğunuzu görmek için arasına ap eklemek isteyebilirsiniz @+.


2

05AB1E , 23 bayt (rekabetçi değil)

Kahretsin, çok yakındım. Python bilimsel gösterimi kullanarak çok büyük yüzenleri ayrıştırır, bu yüzden bu hatayı yorumlayıcıda düzelttim. Ancak, bu meydan okumadan sonra yapıldı ve bu nedenle benim sunum rekabetçi değildir.

Kod:

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

Açıklama:

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 kodlamasını kullanır .


2

JavaScript (ES6), 156 162

Düzenle '-0' için düzeltilmiş hata - thx @Fez Vrasta Edit 2 6 bayt kaydedilen thx @Neil

Bu bir karmaşa, ancak% 100 dize tabanlı - sayısal türler nedeniyle sınır yok

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

Daha az golf

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
)

Ölçek

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>


Hem benim hem de cevaplarınızın -0girdi olarak problemleri var gibi görünüyor .. Çıktı yapmalıyız 0, değil0 0
Fez Vrasta

Evet, dikkat
çektiğiniz

@FezVrasta Çözüldü
edc65

c=='.'?p=t:+c&&(l=t,k=k||t)Size bayt kazandırmak için çalışır mı ?
Neil

Sana kullanarak biraz daha kaydetmek mümkün olabileceğini düşünüyorum t=l=k=p=0ve ++t&&c=='.'vb
Neil

1

ES6, 102 , 180 177 bayt

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}

Düzenleme: @ edc65 sayesinde 3 bayt kaydedildi; insertusernamehere sayesinde 1 bayt kaydedildi.


Split yerine yayılmayı deneyint=[...s]
edc65

@ edc65 Yeniden yazmak zorunda kaldıktan sonra tekrar golf oynamaya çalışıyorum ve gidip bir flaşta 3 bayt tasarruf buluyorsunuz ...
Neil

Sana kurtarabilir miyiz 1 byte değiştirin: t[--l]==0ile t[--l]<1.
insertusernameburada

@insertusernamehere Teşekkürler!
Neil

0

C ++, 180 bayt

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

Bu, karakter kodlaması varsayımları yapmayan ve hiçbir kitaplık (Standart Kitaplık bile dahil) içermeyen taşınabilir C ++'dır.

Giriş iletilir s. Ondalık basamak sayısı döndürülür; dize yerinde değiştirilir ve yeni başlangıç ​​döndürülür p.

Haklarına göre, ben dönmeliyim size_t, ama bunun yerine bu dizeleri boyutunu aralığının yarısını sınırlayan bir işletim sistemi için derlemek gerektiğini iddia edeceğim int. Bence bu makul; 32 bit mimarilerde 2 milyar ondalık basamak sayar.

açıklama

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

Test programı

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

Test çıktısı

    -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)
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.