Couper et compter les décimales

11

Dans ce défi, vous allez écrire un programme pour afficher le nombre de décimales dans la chaîne d' entrée et découper l'entrée si nécessaire.

Exemples

-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

Règles

  • L'entrée sera une chaîne qui peut être parcourue, STDIN, des arguments de fonction ou l'équivalent le plus proche
  • La sortie peut se faire via le retour de fonction, STDOUT ou l'équivalent le plus proche.
  • Il n'y a pas de limite sur la taille de l'entier d'entrée, à l' exception de la longueur de chaîne maximale de votre langue .
  • Si l'entrée contient des zéros inutiles (de début ou de fin):
    1. Vous devriez les retirer
    2. Sortie la quantité de décimales dans le nouveau nombre
    3. Afficher le nouveau numéro séparé par un séparateur (par exemple espace, nouvelle ligne, virgule)
  • L'entrée correspondra toujours à ce RegEx:, -?\d+(\.\d+)?ou si vous ne parlez pas RegEx :
    • Il pourrait y avoir un -au début impliquant un nombre négatif. Ensuite, il y aura au moins un chiffre. Ensuite, il pourrait y avoir ... un .et quelques chiffres supplémentaires.
    • Pour vérifier si une entrée est valide, vérifiez ici
  • Pas de regex

C'est le donc le code le plus court en octets gagne

Downgoat
la source
Peut-être ajouter un cas de test avec signe moins et zéros de tête?
Luis Mendo
Est-il autorisé à sortir le nombre final, qu'il ait été coupé ou non?
insertusernamehere
1
@insertusernamehere no vous ne pouvez sortir le deuxième nombre que s'il a été coupé
Downgoat
1
Vous voudrez peut-être ajouter un cas de test / exemple pour un seul 0.
insertusernamehere
3
-1 pour la restriction regex inutile.
Conor O'Brien

Réponses:

0

PHP 7, 142 octets

J'ai en quelque sorte réussi à tout compresser en une seule déclaration d'impression:

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

S'exécute à partir de la ligne de commande, comme:

$ php trimandcount.php "-04833.010"

Démo

Voir tous les cas de test dont un très long (62 caractères) en action:

Essayez avant d'acheter 1

1 Passez la souris sur la case " Sortie pour 7.0.0 " pour voir tous les résultats.

insertusernamehere
la source
4

Python 2, 165180 octets

Au début, je pensais à écrire mon premier programme Pyth, à le faire compter les chiffres après la virgule potentielle. Mais ensuite, je me suis énervé, je ne sais pas comment vous aimeriez cette langue, je suppose que c'est juste pour gagner. Quoi qu'il en soit, voici ma solution (modifiée car elle ne fonctionnait pas pour les grands nombres):

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

Au cas où quelqu'un voudrait s'appuyer sur mon travail en Pyth: ~b@+cz"."" "1Wq@b_1"0"~b<b_1)plrb6Pour voir où vous en êtes, vous voudrez peut-être insérer un ap entre @+.

ბიმო
la source
2

05AB1E , 23 octets (non concurrentiel)

Merde, j'étais si proche. Python analyse de très gros flottants en utilisant la notation scientifique, j'ai donc corrigé ce bogue dans l'interpréteur. Cependant, cela a été fait après la contestation et ma soumission n'est donc pas compétitive.

Code:

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

Explication:

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

Utilise le codage ISO 8859-1 .

Adnan
la source
2

JavaScript (ES6), 156 162

Edit Correction d'un bug pour '-0' - thx @Fez Vrasta Edit 2 6 octets enregistrés thx @Neil

C'est un gâchis, mais il est basé à 100% sur les chaînes - aucune limite en raison des types numériques

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

Moins 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
)

Tester

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>

edc65
la source
On dirait que les miennes et vos réponses ont des problèmes avec -0comme entrée .. nous devrions sortir 0, pas0 0
Fez Vrasta
Oui, merci de l'avoir signalé
edc65
@FezVrasta fixed
edc65
Fonctionne-t-il c=='.'?p=t:+c&&(l=t,k=k||t)pour vous faire économiser un octet?
Neil
Je pense que vous pourriez être en mesure d'économiser encore plus en utilisant t=l=k=p=0et ++t&&c=='.'etc.
Neil
1

ES6, 102 180 177 octets

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}

Edit: sauvé 3 octets grâce à @ edc65; enregistré 1 octet grâce à insertusernameici.

Neil
la source
Essayez d'étaler au lieu de divisert=[...s]
edc65
@ edc65 Je passe beaucoup de temps à essayer de jouer au golf après avoir dû le réécrire et vous allez trouver une économie de 3 octets en un éclair ...
Neil
Je pense que vous pouvez économiser 1 octet : remplacer t[--l]==0par t[--l]<1.
insertusernamehere
@insertusernamehere Merci!
Neil
0

C ++, 180 octets

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

Il s'agit d'un C ++ portable, qui ne fait aucune hypothèse d'encodage de caractères et ne comprend aucune bibliothèque (pas même la bibliothèque standard).

L'entrée est transmise s. Le nombre de décimales est renvoyé; la chaîne est modifiée sur place et le nouveau départ est retourné p.

Par droits, je devrais retourner un size_t, mais à la place, je vais prétendre que vous devez le compiler pour un système d'exploitation qui limite la taille des chaînes à la moitié de la plage de int. Je pense que c'est raisonnable; il compte plus de 2 milliards de décimales sur les architectures 32 bits.

Explication

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

Programme de test

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

Sortie test

    -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)
Toby Speight
la source