Programa validador Piem

11

Escreva um programa que defina uma função que possa verificar se uma variável de cadeia chamada "qualquer coisa que você deseja ou introduziu pelo usuário" é ou não um piem. (piem = uma história ou poema em que os comprimentos das palavras representam os dígitos de π ( da Wikipedia ))

Alguns exemplos:

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

Você deve excluir qualquer tipo de pontuação ou nova linha antes do processamento. Golfe de código puro, as vitórias mais curtas

Data final: noite de 10/01/2014

Várias respostas

  • Quantos dígitos precisamos manusear? Mais do que 10
  • Por uma questão de interesse, como os 0s no PI devem ser interpretados? Palavras puladas ou com 10 letras? Como 10 letras palavras
  • "uma variável chamada piem" - então o nome do parâmetro deve ser piem? Não, o texto da pergunta não foi corrigido
  • Um bônus divertido pode ser uma solução que é um piem. Se sua solução é um piem, você recebe * 0,5 de bônus
  • Por uma questão de argumento, _ é sempre pontuação? Você pode decidir se é pontuação ou se não é
  • Não está claro o que se entende por "qualquer tipo de pontuação", quero dizer,. '"?! ;; ()
  • Então os dígitos devem ser contados? E a multa de Law seria falsa? Os dígitos devem ser tratados como letras; a multa de Law = False; Lei é boa = True

Comentários

  • A solução APL deve ser contada em bytes
  • Se sua solução funcionar com mais de 100 dígitos de pi, você recebe * 0,8 de bônus
  • Por causa do grande interesse, a data final é mais um dia no futuro.
Caridorc
fonte
6
Quantos dígitos precisamos manusear?
marinus
5
"uma variável chamada piem" - então o nome do parâmetro deve ser piem? Isso torna todas as respostas atuais incorretas.
Ingo Bürk
2
Um bônus divertido pode ser uma solução que é um piem.
britishtea
5
Por uma questão de interesse, como os 0s no PI devem ser interpretados? Palavras puladas ou com 10 letras?
MickyT
3
É uma pena que você não responda a perguntas muito importantes, mas já editou em uma data final.
Ingo Bürk

Respostas:

3

APL (39)

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

Ele usa todos os dígitos que a constante pi do intérprete APL fornece, até um limite de 99. No meu caso (Dyalog APL 14 de 32 bits), eram 16 dígitos. A versão de 64 bits provavelmente tem mais dígitos. No entanto, 16 dígitos são suficientes para os exemplos fornecidos.

Seqüências de caracteres com mais do que essa quantidade de palavras falharão , mesmo se todos os dígitos que pudessem verificar fossem verdadeiros. (O mesmo se aplica a outras postagens, até o momento em que este artigo foi escrito.) Por exemplo, se houvesse apenas 10 dígitos, o "Como eu quero beber" falharia. Isso pode ser corrigido, mas ao custo de 14 caracteres:

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

Essa versão aceita qualquer string em que os primeiros N dígitos estejam corretos.

marinus
fonte
Seu código é o shorte, mas não é Unicode ... Vou ter que pensar se você merece a vitória ou não, a versão javascript é um pouco mais longa do que isso ... Enfim, votei nessa resposta.
Caridorc 29/09/14
1
@marinus A questão não especifica se as submissões devem ser marcado por caracteres ou bytes, mas o padrão é bytes (de acordo com o wiki tag), então eu acho que sua pontuação está mais perto de 60.
Martin Ender
1
Dada a codificação correta, é 1 byte por caractere. O APL é anterior ao Unicode por décadas, afinal.
marinus
1
@marinus Fair point! Você conhece alguma codificação específica (existente) na qual isso realmente funcionaria?
Martin Ender
2
@ MartinBüttner: a página de código 907 da IBM é uma, mas há muitas cargas.
marinus
7

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

Na minha versão Law's finee Law ' s fineretornar ambos verdadeiro.

Versão mais recente (63) de Ingo Bürk e hsl

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

Nova versão (135) para 17 dígitos do pi (graças 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
}

Versão antiga (169) para 32 dígitos do 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;
}
flawr
fonte
Você pode salvar 3 bytes com:1e15*Math.PI+"2384626433832795"
xem
Obrigado =) Enquanto isso, mudei usando essa ideia, mas agora usando apenas os primeiros 17 dígitos.
flawr
@ IngoBürk Muito obrigado, apenas verificando o que funciona.
flawr
Desculpe, não importa. Isso não parece funcionar. : / O forloop não pode ser adicionado dessa maneira.
Ingo Bürk
Mas o que funciona é inicializar r=0e, em seguida, apenas repetir r+=s[a].length!=p[a](você pode omitir o ;no final). Então volte !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)*''}/)}

Explicação

  • A entrada é tomada como argumento para uma lambda. Espera a String.
  • Pi é calculado até 999decimais e transformado em uma String com o .removido.
  • Os sinais de pontuação são removidos do poema e são divididos em palavras individuais. "Let's"é contado como duas palavras: "Let"e "s".
  • Use Array#mappara converter cada palavra no tamanho da palavra, concatená-las em a String.
  • Usando um Regexp, verifique se os dois Strings criados começam com os mesmos caracteres.

Eu apliquei o bônus por lidar com mais de 100 dígitos. _não é tratado como pontuação nesta solução.

britishtea
fonte
Observe que você não está tratando _como pontuação.
Martin Ender
Bem manchado. Por uma questão de argumento, _ sempre é pontuação? E frases como My nickname on Stack Overflow is britishtea_500.
britishtea
Foi apenas uma observação. O OP não é exatamente específico sobre os detalhes aqui.
Martin Ender
Justo. Deixarei a resposta por enquanto até que ela seja especificada no problema :) #
2200
Usando bigdecimal você não tem limite de dígitos PI? Nice (+1)
edc65
4

Mathematica, 123 bytes * 0,8 = 98,4

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

Quase a inscrição mais longa até agora, mas:

  • Funciona para qualquer número de dígitos do Pi.
  • Ele remove todos os caracteres ASCII necessários e a quebra de linha, sem dividir as palavras nesses locais.
  • Ele lida com 0 dígitos no Pi corretamente (como palavras de 10 letras)
Martin Ender
fonte
se ele funciona para o número de dígitos do Pi você recebe um bônus de 0,8
Caridorc
1

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

Como em resposta 's @flawr , Law ' s finee Law's finetanto retorno True.

Agradecemos ao @Emil por remover 12 caracteres do 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
fonte
Você pode salvar 12 caracteres não salvando lem uma variável e definindo a função 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
fonte
1

python 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
fonte
Você pode substituir o ;por uma nova linha para facilitar a leitura. Além disso, vários espaços podem ser removidos.
tomsmeding
1

Python 3-129

Não considera pontuação:

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(' '))))
Beta Decay
fonte
0

T-SQL 488 383

E agora para uma grande solução 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

Isso cria uma função com valor de tabela embutida que usa um CTE recursivo para detectar limites de palavras.

Cria uma função escalar que percorre o caminho entre as palavras e o PI até 31 decimais (primeiro 0). É chamado da seguinte maneira

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

CJam, 40

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

Não está claro o que se entende por "qualquer tipo de pontuação"; Esta solução remove os ,.'"?!;;caracteres.

Ypnypn
fonte
0

Ferramentas Bash e Unix, 111

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

NodeJS 32 dígitos 230 bytes

Não consigo diminuí-lo com 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
fonte
remova o espaço em branco.
Rohan Jhunjhunwala