Schneiden und zählen Sie die Dezimalstellen


11

In dieser Herausforderung werden Sie ein Programm zur Ausgabe von, wie viele Dezimalstellen in dem Eingang schreiben String und schneiden Sie die Eingabe , wenn nötig.

Beispiele

-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

Regeln

  • Die Eingabe ist eine Zeichenfolge, die durch STDIN, Funktionsargumente oder das nächstgelegene Äquivalent geführt werden kann
  • Die Ausgabe kann über Funktionsrückgabe, STDOUT oder das nächstgelegene Äquivalent erfolgen.
  • Die Größe der Eingabe-Ganzzahl ist unbegrenzt, mit Ausnahme der maximalen Zeichenfolgenlänge Ihrer Sprache .
  • Wenn die Eingabe unnötige (führende oder nachfolgende) Nullen enthält:
    1. Sie sollten sie herausnehmen
    2. Geben Sie die Dezimalstelle in der neuen Zahl aus
    3. Geben Sie die neue Zahl durch ein Trennzeichen getrennt aus (z. B. Leerzeichen, Zeilenumbruch, Komma).
  • Die Eingabe stimmt immer mit diesem RegEx: überein -?\d+(\.\d+)?, oder wenn Sie nicht RegEx sprechen :
    • Es könnte sein , -am Anfang impliziert eine negative Zahl. Dann wird es mindestens eine Ziffer geben. Dann könnte es ... noch ein .paar Ziffern geben.
    • Um zu überprüfen, ob eine Eingabe gültig ist, überprüfen Sie hier
  • Kein Regex

Dies ist so dass der kürzeste Code in Bytes gewinnt


Vielleicht einen Testfall mit Minuszeichen und führenden Nullen hinzufügen?
Luis Mendo

Darf die endgültige Nummer ausgegeben werden, unabhängig davon, ob sie gekürzt wurde oder nicht?
Insertusernamehere

1
@insertusernamehere nein, Sie können die zweite Nummer nur ausgeben, wenn sie
gekürzt wurde

1
Möglicherweise möchten Sie einen Testfall / ein Beispiel für eine einzelne hinzufügen 0.
Insertusernamehere

3
-1 für die sinnlose Regex-Einschränkung.
Conor O'Brien

Antworten:


0

PHP 7, 142 Bytes

Ich habe es irgendwie geschafft, alles in einer einzigen Druckaussage zusammenzufassen:

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

Läuft über die Befehlszeile wie:

$ php trimandcount.php "-04833.010"

Demo

Alle Testfälle anzeigen, einschließlich eines sehr langen (62 Zeichen) in Aktion:

Versuchen Sie es vor dem Kauf 1

1 Bewegen Sie den Mauszeiger über das Feld unter " Ausgabe für 7.0.0 ", um alle Ergebnisse anzuzeigen .


4

Python 2, 165 180 Bytes

Zuerst dachte ich darüber nach, mein erstes Pyth-Programm zu schreiben, damit es die Ziffern nach dem möglichen Komma zählt. Aber dann wurde ich ziemlich verärgert, ich weiß nicht, wie Sie diese Sprache genießen würden, denke, es ist nur zu Gewinnzwecken. Wie auch immer, hier ist meine Lösung (bearbeitet, da sie bei großen Zahlen nicht funktioniert hat):

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

Für den Fall, dass jemand auf meiner Arbeit in Pyth aufbauen möchte: ~b@+cz"."" "1Wq@b_1"0"~b<b_1)plrb6Um zu sehen, wo Sie sich befinden, möchten Sie möglicherweise ap dazwischen einfügen @+.


2

05AB1E , 23 Bytes (nicht wettbewerbsfähig)

Verdammt, ich war so nah dran. Python analysiert sehr große Floats in wissenschaftlicher Notation, daher habe ich diesen Fehler im Interpreter behoben. Dies geschah jedoch nach der Herausforderung und meine Einreichung ist daher nicht wettbewerbsfähig.

Code:

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

Erläuterung:

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

Verwendet die ISO 8859-1-Codierung .


2

JavaScript (ES6), 156 162

Bearbeiten Behobener Fehler für '-0' - thx @Fez Vrasta Edit 2 6 Bytes gespeichert thx @Neil

Es ist ein Chaos, aber es basiert zu 100% auf Zeichenfolgen - keine Begrenzung aufgrund numerischer Typen

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

Weniger Golf gespielt

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
)

Prüfung

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>


Scheint , wie sowohl meine und Ihre Antworten haben Probleme mit -0als Eingabe .. wir ausgeben sollen 0, nicht0 0
Fes Vrasta

Ja, danke für den Hinweis
edc65

@ FezVrasta behoben
edc65

Hat c=='.'?p=t:+c&&(l=t,k=k||t)Arbeit , die Ihnen ein Byte speichern?
Neil

Ich glaube , Sie könnten in der Lage sein , etwas mehr zu sparen , indem Sie t=l=k=p=0und ++t&&c=='.'usw.
Neil

1

ES6, 102 180 177 Bytes

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}

Bearbeiten: 3 Bytes dank @ edc65 gespeichert; 1 Byte dank insertusernamehere gespeichert.


Versuchen Sie zu verbreiten statt zu teilent=[...s]
edc65

@ edc65 Ich verbringe Ewigkeiten damit, es wieder nach unten zu spielen, nachdem ich es neu schreiben musste, und du gehst und findest blitzschnell eine 3-Byte-Ersparnis ...
Neil

Ich denke, Sie können 1 Byte sparen : Ersetzen t[--l]==0durch t[--l]<1.
Insertusernamehere

@insertusernamehere Danke!
Neil

0

C ++, 180 Bytes

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

Dies ist portables C ++, das keine Annahmen zur Zeichenkodierung macht und keine Bibliotheken enthält (nicht einmal die Standardbibliothek).

Eingabe wird übergeben s. Die Anzahl der Dezimalstellen wird zurückgegeben. Die Zeichenfolge wird an Ort und Stelle geändert und der neue Start wird in zurückgegeben p.

Von Rechts size_twegen sollte ich a zurückgeben , aber stattdessen werde ich behaupten, dass Sie dies für ein Betriebssystem kompilieren sollten, das die Größe von Zeichenfolgen auf die Hälfte des Bereichs von begrenzt int. Ich denke das ist vernünftig; Auf 32-Bit-Architekturen werden mehr als 2 Milliarden Dezimalstellen gezählt.

Erläuterung

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

Testprogramm

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

Testausgabe

    -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)
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.