Recortar y contar los decimales

11

En este desafío, escribirá un programa para generar cuántos decimales hay en la cadena de entrada y recortará la entrada si es necesario.

Ejemplos

-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

Reglas

  • La entrada será una cadena que se puede tomar, STDIN, argumentos de función o el equivalente más cercano
  • La salida puede ser a través de la función return, STDOUT o el equivalente más cercano.
  • No hay límite en el tamaño para el entero de entrada, excepto para la longitud máxima de cadena de sus idiomas .
  • Si la entrada tiene ceros innecesarios (iniciales o finales):
    1. Deberías sacarlos
    2. Salida de la cantidad de lugar decimal en el nuevo número
    3. Salida del nuevo número separado por un separador (por ejemplo, espacio, nueva línea, coma)
  • La entrada siempre coincidirá con este RegEx: -?\d+(\.\d+)?o si no habla RegEx :
    • No podría ser una -al principio lo que implica un número negativo. Entonces habrá al menos un dígito. Entonces podría haber ... .ay algunos dígitos más.
    • Para verificar si una entrada es válida, marque aquí
  • Sin expresiones regulares

Este es el por lo que el código más corto en bytes gana

Downgoat
fuente
¿Quizás agregar un caso de prueba con signo menos y ceros a la izquierda?
Luis Mendo
¿Está permitido generar el número final independientemente de si se recortó o no?
insertusernamehere
1
@insertusernamehereno, solo puede generar el segundo número si se ha recortado
Downgoat
1
Es posible que desee agregar un caso / ejemplo de prueba para un solo 0.
insertusernamehere
3
-1 para la restricción de expresiones regulares sin sentido.
Conor O'Brien

Respuestas:

0

PHP 7, 142 bytes

De alguna manera logré exprimir todo en una sola declaración de impresión:

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

Se ejecuta desde la línea de comandos, como:

$ php trimandcount.php "-04833.010"

Manifestación

Vea todos los casos de prueba, incluido uno muy largo (62 caracteres) en acción:

Probar antes de comprar 1

1 Desplácese sobre el cuadro debajo de " Salida para 7.0.0 " para ver todos los resultados.

insertusernamehere
fuente
4

Python 2, 165 180 bytes

Al principio estaba pensando en escribir mi primer programa Pyth, conseguí contar los dígitos después de la coma potencial. Pero luego me molesté bastante, no sé cómo disfrutarías ese idioma, supongo que es solo para ganar. De todos modos, aquí está mi solución (editado ya que no funcionó para grandes cantidades):

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

En caso de que alguien quiera desarrollar mi trabajo en Pyth: ~b@+cz"."" "1Wq@b_1"0"~b<b_1)plrb6para ver dónde se encuentra, puede insertar un punto intermedio @+.

ბიმო
fuente
2

05AB1E , 23 bytes (no competitivo)

Maldición, estaba tan cerca. Python analiza flotadores muy grandes usando notación científica, así que arreglé este error en el intérprete. Sin embargo, esto se hizo después del desafío y, por lo tanto, mi presentación no es competitiva.

Código:

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

Explicación:

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

Utiliza la codificación ISO 8859-1 .

Adnan
fuente
2

JavaScript (ES6), 156 162

Editar error corregido para '-0' - thx @Fez Vrasta Edit 2 6 bytes guardados thx @Neil

Es un desastre, pero está 100% basado en cadenas: sin límite debido a los tipos numéricos

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

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

Prueba

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
fuente
Parece que tanto la mía como sus respuestas tienen problemas con la -0entrada ... deberíamos dar salida 0, no0 0
Fez Vrasta
Sí, gracias por señalar
edc65
@FezVrasta fijo
edc65
¿ c=='.'?p=t:+c&&(l=t,k=k||t)Funciona para ahorrarte un byte?
Neil
Creo que podría ahorrar algo más usando t=l=k=p=0y ++t&&c=='.'etc.
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}

Editar: Guardado 3 bytes gracias a @ edc65; guardado 1 byte gracias a insertusernamehere.

Neil
fuente
Prueba spread en lugar de splitt=[...s]
edc65
@ edc65 Me paso años intentando volver a jugar golf después de tener que volver a escribirlo y vas y encuentras un ahorro de 3 bytes en un instante ...
Neil
Creo que puede guardar 1 byte : reemplazar t[--l]==0con t[--l]<1.
insertusernamehere
@ inserciónusernamehere Gracias!
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;}

Este es C ++ portátil, que no hace suposiciones de codificación de caracteres e incluye bibliotecas (ni siquiera la Biblioteca estándar).

La entrada se pasa s. Se devuelve el número de decimales; la cadena se modifica en el lugar y se devuelve el nuevo inicio p.

Por derecho, debería devolver un size_t, pero en su lugar voy a afirmar que debe compilar esto para un sistema operativo que limita el tamaño de las cadenas a la mitad del rango de int. Creo que eso es razonable; Cuenta con más de 2 mil millones de decimales en arquitecturas de 32 bits.

Explicación

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

Programa de prueba

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

Prueba de salida

    -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
fuente