Programa de validación Piem

11

Escriba un programa que defina una función que pueda verificar si una variable de cadena llamada "cualquier cosa que desee o ingrese el usuario" es o no un piem. (piem = una historia o un poema en el que la longitud de las palabras representa los dígitos de π ( de Wikipedia ))

Algunos ejemplos:

myfunction("I am clearly wrong") # False
myfunction("How I want a drink, alcoholic of course, after the heavy lectures involving quantum mechanics") #True (Taken from Wikipedia)
myfunction("Law ' s fine") # True

Debe eliminar cualquier tipo de puntuación o nueva línea antes de procesar. Golf de código puro, las victorias más cortas

Fecha final: noche del 10/01/2014

Varias respuestas

  • ¿Cuántos dígitos necesitamos manejar? Mas de 10
  • Como cuestión de interés, ¿cómo deben interpretarse los 0 en PI? ¿Saltado o palabras de 10 letras? Como palabras de 10 letras
  • "una variable llamada piem", ¿entonces el nombre del parámetro debe ser piem? No, no lo ha hecho, texto de pregunta corregido
  • Un bono divertido podría ser una solución que es en sí misma un piem. Si su solución es un piem, obtiene * 0.5 bonus
  • En aras de la discusión, ¿es _ siempre puntuación? Puedes decidir si es puntuación o si no lo es
  • No está claro qué se entiende por "cualquier tipo de puntuación" quiero decir, ''?! ;; ()
  • Entonces, ¿los dígitos deben contarse? ¿Y la multa de Law sería falsa? Los dígitos deben tratarse como letras, Law's fine = False; La ley está bien = Verdadero

Comentarios

  • La solución APL debe contarse en bytes
  • Si su solución funciona para más de 100 dígitos de pi, obtendrá * 0.8 de bonificación
  • Debido al gran interés, la fecha de finalización es un día más en el futuro.
Caridorc
fuente
66
¿Cuántos dígitos necesitamos manejar?
marinus
55
"una variable llamada piem", ¿entonces el nombre del parámetro debe ser piem? Eso hace que todas las respuestas actuales sean incorrectas.
Ingo Bürk
2
Un bono divertido podría ser una solución que es en sí misma un piem.
britishtea
55
Como cuestión de interés, ¿cómo deben interpretarse los 0 en PI? ¿Saltado o palabras de 10 letras?
MickyT
3
Es una pena que no respondas a preguntas muy importantes, pero que ya hayas editado en una fecha de finalización.
Ingo Bürk

Respuestas:

3

APL (39)

{N≡(≢N←≢¨('\w+'⎕S'\0')⍵)↑⍎¨'_. '~⍨99⍕○1}

Utiliza todos los dígitos que proporciona la constante pi del intérprete APL, hasta un límite de 99. En mi caso (Dyalog APL 14 de 32 bits), eso era 16 dígitos. La versión de 64 bits probablemente tenga más dígitos. Sin embargo, 16 dígitos son suficientes para que funcionen los ejemplos dados.

Las cadenas que tengan más de esa cantidad de palabras fallarán , incluso si todos los dígitos que pudiera verificar fueran verdaderos. (Lo mismo es cierto para otras publicaciones, a partir de este escrito.) Por ejemplo, si solo hubiera 10 dígitos, el 'Cómo quiero un trago' fallaría. Esto se puede arreglar, pero a costa de 14 caracteres:

{(≢¨('\w+'⎕S'\0')⍵){∧/(⌊/≢¨⍺⍵)↑∨⌿⍺∘.=⍵}⍎¨'_. '~⍨99⍕○1}

Esa versión aceptará cualquier cadena donde los primeros N dígitos sean correctos.

marinus
fuente
Su código es el short pero no es Unicode ... Tendré que pensar si te mereces la victoria o no, la versión de JavaScript es solo un poco más larga que esto ... De todos modos, voté por esta respuesta.
Caridorc
1
@marinus La pregunta no especifica si las presentaciones deben puntuarse por caracteres o bytes, pero el valor predeterminado es bytes (según la etiqueta wiki), por lo que creo que su puntuación está más cerca de 60.
Martin Ender
1
Dada la codificación correcta es de 1 byte por carácter. APL es anterior a Unicode por décadas después de todo.
marinus
1
@marinus ¡Punto justo! ¿Conoces alguna codificación particular (existente) en la que eso realmente funcione?
Martin Ender
2
@ MartinBüttner: la página de códigos 907 de IBM es una, pero hay muchas.
marinus
7

JavaScript (169) (140) (137) (135) (63) para 17 dígitos de pi

En mi versión Law's finey Law ' s fineregreso ambos verdaderos.

La versión más nueva (63) por Ingo Bürk y hsl

f=s=>!s.split(/\W+/).some((x,i)=>x.length-(Math.PI*1e16+'')[i])

Nueva versión (135) para 17 dígitos de pi (Gracias a Ingo Bürk):

f=(s)=>{
s=s.split(/[!"#$%&'()*+, \-.\/:;<=>?@[\\\]^_`{|}~]+/);
p=Math.PI*1e16+'';
    r=0;
    for(a=s.length;a--;)r+=s[a].length!=p[a];
    return !r
}

Versión anterior (169) para 32 dígitos de pi:

f=(s)=>{
s=s.split(/[!"#$%&'()*+, \-.\/:;<=>?@[\\\]^_`{|}~]+/);
p="31415926535897932384626433832795".split('');
    r=1;
    for(a=s.length;a--;)if(s[a].length!=p[a]){r=0};
    return r;
}
falla
fuente
Puede guardar 3 bytes con:1e15*Math.PI+"2384626433832795"
xem
Gracias =) Mientras tanto, lo cambié usando esta idea pero ahora solo usando los primeros 17 dígitos.
defecto
@ IngoBürk Muchas gracias, solo compruebo lo que funciona.
defecto
Lo siento no importa. Eso no parece funcionar. : / El forbucle no se puede agregar de esta manera.
Ingo Bürk
Pero lo que sí funciona es inicializar r=0y luego hacer un ciclo r+=s[a].length!=p[a](puede omitirlo ;al final) Entonces, vuelve !r.
Ingo Bürk
7

Ruby, 113 101 79 (98 * 0,8)

require"bigdecimal/math"
x=->p{!(BigMath.PI(999).to_s[2..-1]!~/^#{p.scan(/\w+/).map(&:size)*''}/)}

Explicación

  • La entrada se toma como argumento para una lambda. Espera a String.
  • Pi se calcula hasta 999decimales y se convierte en una cadena con el .eliminado.
  • Los signos de puntuación se eliminan del poema y se divide en palabras individuales. "Let's"se cuenta como dos palabras: "Let"y "s".
  • Use Array#mappara convertir cada palabra al tamaño de la palabra, concatenarlas en a String.
  • Usando un Regexp, verifique si los dos Strings creados comienzan con los mismos caracteres.

He aplicado la bonificación por manejar más de 100 dígitos. _no se maneja como puntuación en esta solución.

britishtea
fuente
Tenga en cuenta que no se trata _como puntuación.
Martin Ender
Bien descrito. En aras de la discusión, ¿es _ siempre la puntuación? ¿Qué pasa con oraciones como My nickname on Stack Overflow is britishtea_500.
britishtea
Fue solo una observación. El OP no es exactamente específico sobre los detalles aquí.
Martin Ender
Lo suficientemente justo. Voy a dejar la respuesta para ahora hasta que se especifica en el problema :)
britishtea
¿Usando bigdecimal no tiene límite en los dígitos PI? Niza (+1)
edc65
4

Mathematica, 123 bytes * 0.8 = 98.4

f=#&@@RealDigits[Pi,10,Length[d=StringLength/@StringSplit@StringReplace[#,RegularExpression@"[!-.:-?]
"->""]/. 10->0]]==d&;

Casi la presentación más larga hasta ahora, pero:

  • Funciona para cualquier número de dígitos de Pi.
  • Elimina todos los caracteres ASCII necesarios y el salto de línea, sin dividir las palabras en esos lugares.
  • Maneja 0 dígitos en Pi correctamente (como palabras de 10 letras)
Martin Ender
fuente
si funciona para el número de dígitos de Pi, obtienes un bono de 0.8
Caridorc
1

Python - 130 127 116 - 17 dígitos de pi

Como en la respuesta de @flawr , Law ' s finey Law's fineambos devuelven True.

Gracias a @Emil por eliminar 12 caracteres del programa.

import re
f=lambda x:all(j==int("31415926535897932"[i])for i,j in enumerate([len(s)for s in re.findall("[\w]+",x)]))
monopolo
fuente
Puede guardar 12 caracteres no guardando len una variable y definiendo la función usando lambda.
Emil
1

Java, 185

boolean f(String...s){s=s[0].replaceAll("\\W","~").replaceAll("~+","~").split("~");for(int i=0;i<s.length;){if(s[i].length()!=(int)(Math.PI*Math.pow(10,i++)%10))return 0>1;}return 1>0;}
Ypnypn
fuente
1

pitón 3, 17 dígitos de pi, 104

import re;f=lambda s:all(map(int.__eq__, map(int, '31415926535897932'), map(len,re.findall('[\w]+',s))))
pgy
fuente
Puede reemplazarlo ;con una nueva línea para facilitar la lectura. Además, se pueden eliminar varios espacios.
tomsmeding
1

Python 3 - 129

No tiene en cuenta la puntuación:

import math
f=lambda p:all(1if len(p.split(' ')[i])!=int(str(math.pi).replace('.','')[i])else 1for i in range(len(p.split(' '))))
Decaimiento Beta
fuente
0

T-SQL 488 383

Y ahora para una gran solución T-SQL :)

CREATE FUNCTION F(@s VARCHAR(MAX))RETURNS CHAR(6) AS BEGIN DECLARE @ CHAR='T',@p VARCHAR(50)='31415926535897932384626433832795028841971693993751',@i INT=0WHILE @='T'AND @s<>''BEGIN SET @i=PATINDEX('%[^a-z0-9]%',@s)IF @i=0RETURN'#True'IF @i-1<>LEFT(@p,1)RETURN'#False'SET @p=STUFF(@p,1,1,'')SET @s=STUFF(@s,1,@i,'')SET @s=STUFF(@s,1,PATINDEX('%[a-z0-9]%',@s)-1,'')END RETURN'#True'END

Esto crea una función con valores de tabla en línea que utiliza un CTE recursivo para detectar límites de palabras.

Crea una función escalar que mastica a través de las palabras y PI hasta 31 decimales (primer 0). Se llama de la siguiente manera

SELECT dbo.f('SQL I golf, a large procedure is normal. Hefty not terse') --#True
MickyT
fuente
0

CJam, 40

"
,.'\"?!;:"{-}/S%{,PAV#*iA%=V):V}/]0#)!

No está claro qué se entiende por "cualquier tipo de puntuación"; Esta solución elimina los ,.'"?!;;caracteres.

Ypnypn
fuente
0

Herramientas Bash y Unix, 111

f() { grep ^"$(echo "$@"|grep -Po '[\w]+'|xargs -n1 sh -c 'echo ${#0}'|xargs|tr -d ' ')"<<<31415926535897932; 
pgy
fuente
0

NodoJS 32 dígitos 230 Bytes

No puedo acortarlo con JS: D

var p = "31415926535897932384626433832795", i = 0;
console.log(process.argv[2].split(/[\s,.]+/).every(function(w) {
    if (parseInt(p.charAt(i)) !== w.length) {
        return false;
    }
    i++;
    return true;
}) ? 'True' : 'False');
Wikunia
fuente
eliminar espacios en blanco.
Rohan Jhunjhunwala