¿Es un número entero, una cadena o un decimal?

8

Su desafío es determinar si la entrada dada es un número entero, una cadena o un decimal.

Reglas

  • Una cadena es cualquier entrada que no sea un número entero o flotante
  • Un entero debe contener solo caracteres numéricos y no debe comenzar con un cero
  • Un decimal es cualquier entrada que contiene el punto ( .) y el período está rodeado de caracteres numéricos.

Nota: .01 no se considera un decimal válido.

  • El programa debe generar una cadena sin formato, ya sea "cadena", "entero" o "decimal".
  • Puede suponer que solo se utilizan caracteres ASCII imprimibles

Casos:

asdf -> string
asdf3.4 -> string
2 -> integer
2.0 -> decimal
02 -> string
40. -> string
. -> string
.01 -> string
0.0 -> decimal
.9.9.9 -> string
[empty space] -> string

EDITAR: se corrigió el error tipográfico. Me refería a .01 sin el cero inicial, no con. Si eso no lo dejó claro, ¡ya está arreglado!

Este es el , por lo que gana la respuesta más corta.

noɥʇʎԀʎzɐɹƆ
fuente
55
¿Por qué 02 no es un número entero? Estos se sienten como restricciones arbitrarias para aumentar la dificultad del desafío.
Addison Crump
1
Creo que 02no se considera un número entero porque la mayoría de los idiomas recortan los ceros a la izquierda cuando el tipo es un integerpero mantienen los ceros a la izquierda cuando se almacena como a string. Aunque estoy con @isaacg que si 0.0se considera un decimal, también 0.01debería serlo. .01sin contar tiene sentido, supongo ...
hargasinski
3
@Zequ .01 no contar tiene sentido, supongo ... ¿por qué? Es válido en casi todos los idiomas.
mınxomaτ
2
¡Bienvenido a Programming Puzzles & Code Golf! No hay necesidad de hacer ping innecesariamente a todos los que comentaron su pregunta; su edición coloca automáticamente su pregunta en la cola de reapertura, donde se volverá a abrir si es necesario. Además, muchos de sus desafíos parecen haberse cerrado; es posible que desee intentar ejecutarlos primero en nuestro Sandbox . ¡Gracias!
Pomo de la puerta
1
@CrazyPython Creo que la idea a la que te refieres con "entero válido" y "decimal válido" es la idea de una representación canónica. Según entiendo sus reglas, hay exactamente una forma de escribir cada número entero y cada decimal. Si esa es la intención, agregar eso al desafío aclarará por qué las reglas son como son.
isaacg

Respuestas:

3

Pyth, 33 bytes (39 sin cadena empaquetada)

@_c."at%¸Ã`9hàãáÊ"7.x/`MsB+vz0z0

Algunos bytes se eliminan debido a Markdown. Código oficial y conjunto de pruebas.

Sin cuerda empaquetada:

@_c"integerdecimalstring"7.x/`MsB+vz0z0

Pasa todos los casos de prueba anteriores. Básicamente, para verificar si una cadena es un número entero o decimal, verifica si la cadena se puede evaluar como un literal de Python ( v), y si es así, si puede agregarle 0 y convertirla nuevamente a su representación de cadena, y obtener La cadena de entrada. Si es así, es un entero o un decimal. Si también puede enviarlo a un int y aún así recuperar la cadena original, es un número entero.

isaacg
fuente
2

Javascript, 112 121 87 bytes

Gracias a @ edc65 por guardar 34 bytes al convertir el código original (en la explicación) a ES6. No cambié la explicación porque muestra la lógica mejor.

b=a=>/^[1-9]\d*$/.test(a)?"integer":/^([1-9]\d+|\d)\.\d+$/.test(a)?"decimal":"str‌​ing"

Básicamente, esto convierte las reglas para un entero y un decimal en la pregunta en comprobaciones de expresiones regulares, y las prueba con la entrada dada. Si la entrada no coincide, debe ser una cadena. Pasa todas las pruebas dadas en la pregunta.

Ungolfed + explicación

function b(a) {
    if(/^[1-9]\d*$/.test(a)) // regex check for the rules of an 'integer':
        return"integer";     // ^[1-9] - check to make sure the first digit
                             // \d* - check to make sure that it is followed by zero or more digits
                             // $ - ensures that the previous check continues to the end of the word
    if(/^([1-9]\d+|\d)\.\d+$/.test(a)) // regex check for the rules of a 'decimal', starting from the middle
        return"decimal";     // \. checks for a '.' in the word
                             // the ([1-9]\d+|\d) and \d+ check to make sure the '.' is surrounded by
                             // one or more numerical characters on each side.
                             // the ^,$ ensure that the match is for the whole word
return"string";              // none of the others match, so it must be a string.

}

hargasinski
fuente
Esto parece fallar en entradas como 01.23.
LegionMammal978
Lo arreglé, pasa el b("0.123")caso. Lo siento, ya que solo se mencionó explícitamente en la pregunta que un entero no podía tener ceros a la izquierda, supuse que no se aplicaba a los decimales.
hargasinski
Acortado a ES6 es 83 a=>/^[1-9]\d*$/.test(a)?"integer":/^([1-9]\d+|\d)\.\d+$/.test(a)?"decimal":"string"... no es el más corto posible de todos modos
edc65
Gracias, actualicé el código, tuve que agregarlo b=para que funcione en Chrome. Para mí, muestra que el original que publicaste tiene 85 bytes, en lugar de 83, más los 2 bytes para un total de 87.
hargasinski
@Zequ generalmente asigna la función a una variable ( b=) no se cuenta. Y el resto es 83, tenga cuidado con los extraños caracteres invisibles insertados por el editor de comentarios - hay algunos en mi comentario anterior entre "str" ​​e "ing"
edc65
1

Java, 133 bytes

String t(String v){if(v.matches("[1-9]\\d*"))return "integer";if(v.matches("(0|[1-9]\\d+)\\.\\d+"))return "decimal";return "string";}
SuperJedi224
fuente
1

JavaScript (ES6), 74 75

Editar 1 byte guardado gracias Zequ

f=i=>(i=i.match(/^(0|[1-9]\d*)(\.\d+)?$/))?i[2]?'decimal':'integer':'string'

Prueba

f=i=>(i=i.match(/^(0|[1-9]\d*)(\.\d+)?$/))?i[2]?'decimal':'integer':'string'

console.log=x=>O.textContent +=x +'\n';

// test cases from the question and some more
s=['asdf','asdf3.4','02','40.','.','.01','.9.9.9','','0.0.0','00.00','02.00']
i=['2', '11', '1000']
d=['2.0','0.0', '1.009', '911.1','123.4567890']

console.log('Strings:')
s.forEach(x=>console.log('<'+x+'> -> '+f(x)))
console.log('Integers:')
i.forEach(x=>console.log('<'+x+'> -> '+f(x)))
console.log('Decimals:')
d.forEach(x=>console.log('<'+x+'> -> '+f(x)))
<pre id=O></pre>

edc65
fuente
Podrías guardar un byte cambiando [^0\D]el partido regex a[1-9]
hargasinski el
@Zequ buena pista, gracias ... usando un rango compuesto parecía tan inteligente :(
edc65
1

Perl 5, 59 bytes

Con el -pargumento en la línea de comando (que se calcula en el recuento de bytes):

chop;$_=!/\D|^0/?"integer":/^\d+\.\d+$/?"decimal":"string"
Codefun64
fuente
Falla para cualquier 00.nn (prueba 00.00)
edc65
1
Fijo. Aunque tal vez eso debería estar en los casos de prueba dados.
Codefun64
Debería. Por otro lado, a menudo los casos de prueba no cubren todos los casos posibles.
edc65
Todavía está mal, ahora da 'entero' para la entrada .0. ¿Para qué sirve chop?
edc65
Fijo. Perdió el interés en este desafío. No estoy seguro si podría haber optimizado esta solución o no. Chop fue necesario en una iteración previa del guión. No le gustó la nueva línea de entrada del usuario.
Codefun64
0

Perl 6 , 61 bytes

{<string integer decimal>[?/^[(\d+\.\d+)|<[1..9]>\d*]$/+?$0]} # 61

Uso:

say «asdf asdf3.4 2 2.0 02 40. . .01 0.0 .9.9.9 ''».map: {...}
(string string integer decimal string string string string decimal string string)
Brad Gilbert b2gills
fuente
0

Python 2, 148 bytes

def f(s):
 try:
  t=float(s);assert s[0]!='0'
  if `t+0`==s:return'decimal'
  if `int(t)`==s:return'integer'
  return'string'
 except:return'string'


assert f('asdf') == 'string'
assert f('asdf3.4') == 'string'
assert f('2') == 'integer'
assert f('2.0') == 'decimal'
assert f('.') == 'string'
assert f('.01') == 'string'
assert f('.9.9.9') == 'string'
assert f(' ') == 'string'    
assert f('40.') == 'string'
assert f('02') == 'string'
assert f('0.0') == 'string'
assert f('00.00') == 'string'
Willem
fuente
0

JavaScript ES6, 74 70 bytes

w=>w.match(/^\d+\.\d+$/)?"decimal":w.match(/^\d+$/)?"integer":"string"
nicael
fuente
falla con los casos de prueba de la pregunta. Realmente, por favor, prueba antes de publicar.
edc65
@edc Gracias por los comentarios, aunque ¿podría decirme qué casos fallan, excepto 02?
nicael
Me alegro de que lo encuentres solo
edc65
Echa un vistazo a mi respuesta para un violín.
Pavlo
Debería funcionar con los casos de prueba si cambió /^\d+$/a ^[1-9]\d*(75 bytes).
Chiru