Taglia e conta i decimali


11

In questa sfida, si scriverà un programma per generare quante posizioni decimali si trovano nella stringa di input e tagliare l'input se necessario.

Esempi

-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

Regole

  • L'input sarà una stringa che può essere presa attraverso, STDIN, argomenti di funzione o l'equivalente più vicino
  • L'output può essere attraverso il ritorno di funzione, STDOUT o l'equivalente più vicino.
  • Non vi è alcun limite alla dimensione dell'intero di input ad eccezione della lunghezza massima della stringa delle lingue .
  • Se l'input ha zeri non necessari (iniziali o finali):
    1. Dovresti eliminarli
    2. Emette la quantità di decimale nel nuovo numero
    3. Stampa il nuovo numero separato da un separatore (ad es. Spazio, newline, virgola)
  • L'input corrisponderà sempre a questo RegEx:, -?\d+(\.\d+)?o se non parli RegEx :
    • Ci potrebbe essere un -all'inizio che implica un numero negativo. Quindi ci sarà almeno una cifra. Quindi potrebbero esserci ... .ae qualche altra cifra.
    • Per verificare se un input è valido, controlla qui
  • No Regex

Questo è quindi vince il codice più breve in byte


Forse aggiungi un caso di test con segno meno e zeri iniziali?
Luis Mendo,

È consentito emettere il numero finale indipendentemente dal fatto che sia stato tagliato o no?
inserireusernamehere

1
@inserireusernamequi no è possibile emettere il secondo numero solo se è stato tagliato
Downgoat

1
Potresti voler aggiungere un caso / esempio di test per un singolo 0.
inserireusernamehere

3
-1 per la restrizione regex inutile.
Conor O'Brien,

Risposte:


0

PHP 7, 142 byte

In qualche modo sono riuscito a spremere tutto in una singola istruzione di stampa:

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

Viene eseguito dalla riga di comando, come:

$ php trimandcount.php "-04833.010"

dimostrazione

Guarda tutti i casi di test incluso uno molto lungo (62 caratteri) in azione:

Prova prima di acquistare 1

1 Passa il mouse sopra la casella " Output for 7.0.0 " per visualizzare tutti i risultati.


4

Python 2, 165 180 byte

All'inizio stavo pensando di scrivere il mio primo programma Pyth, ho avuto modo di contare le cifre dopo la potenziale virgola. Ma poi mi sono abbastanza seccato, non so come ti piacerebbe quella lingua, immagino sia solo per scopi vincenti. Comunque ecco la mia soluzione (modificata poiché non funzionava per grandi numeri):

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

Nel caso in cui qualcuno volesse basarsi sul mio lavoro in Pyth: ~b@+cz"."" "1Wq@b_1"0"~b<b_1)plrb6per vedere dove ti trovi, potresti voler inserire un p tra @+.


2

05AB1E , 23 byte (non competitivo)

Accidenti, ero così vicino. Python analizza float molto grandi usando la notazione scientifica, quindi ho corretto questo bug nell'interprete. Tuttavia, ciò è stato fatto dopo la sfida e la mia presentazione non è quindi competitiva.

Codice:

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

Spiegazione:

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

Utilizza la codifica ISO 8859-1 .


2

JavaScript (ES6), 156 162

Modifica bug risolto per '-0' - thx @Fez Vrasta Edit 2 6 byte salvati thx @Neil

È un casino, ma è basato su una stringa al 100% - nessun limite a causa di tipi numerici

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

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

Test

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>


Sembra sia il mio che le tue risposte hanno problemi con -0come input .. dovremmo produrre 0, non0 0
Fez Vrasta,

Sì, grazie per aver ricordato
edc65

@FezVrasta fixed
edc65

Funziona c=='.'?p=t:+c&&(l=t,k=k||t)per salvarti un byte?
Neil,

Penso che potresti essere in grado di risparmiare un po 'di più usando t=l=k=p=0e ++t&&c=='.'ecc.
Neil,

1

ES6, 102 180 177 byte

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}

Modifica: salvato 3 byte grazie a @ edc65; salvato 1 byte grazie a insertusernamehere.


Prova a diffondere invece di divideret=[...s]
edc65 il

@ edc65 Trascorro anni cercando di rigirarlo dopo averlo riscritto e vai a trovare un risparmio di 3 byte in un lampo ...
Neil

Penso che puoi salvare 1 byte : sostituisci t[--l]==0con t[--l]<1.
inserisci nomeutentequi

@inserireusernamehere Grazie!
Neil,

0

C ++, 180 byte

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

Questo è C ++ portatile, che non fa ipotesi sulla codifica dei caratteri e non include librerie (nemmeno la Libreria standard).

L'ingresso è passato s. Viene restituito il numero di cifre decimali; la stringa viene modificata sul posto e viene restituito il nuovo inizio p.

Per diritto, dovrei restituire a size_t, ma invece dirò che dovresti compilare questo per un sistema operativo che limita la dimensione delle stringhe a metà dell'intervallo di int. Penso che sia ragionevole; conta oltre 2 miliardi di decimali su architetture a 32 bit.

Spiegazione

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

Programma di 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);
    }
}

Uscita di prova

    -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)
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.