Programma di validazione Piem


11

Scrivi un programma che definisce una funzione che può verificare se una variabile di stringa chiamata "qualsiasi cosa tu voglia o immessa dall'utente" sia o meno un piem. (piem = una storia o una poesia in cui le lunghezze delle parole rappresentano le cifre di π ( da Wikipedia ))

Qualche esempio:

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

È necessario eliminare qualsiasi tipo di punteggiatura o newline prima dell'elaborazione. Puro codice golf, il più breve vince

Data di fine: sera del 10/01/2014

Varie risposte

  • Quante cifre dobbiamo gestire? Più di 10
  • Per motivi di interesse, come devono essere interpretati gli 0 in PI? Saltate o parole di 10 lettere? Come parole di 10 lettere
  • "una variabile chiamata piem" - quindi il nome del parametro deve essere piem? No, non è stato corretto il testo della domanda
  • Un bonus divertente potrebbe essere una soluzione che è esso stesso un piem Se la tua soluzione è un piem otterrai * 0,5 bonus
  • Per ragioni di argomento, _ è sempre la punteggiatura? Puoi decidere se è la punteggiatura o se non lo è
  • Non è chiaro cosa si intende per "qualsiasi tipo di punteggiatura" Voglio dire. ""?! ;; ()
  • Quindi le cifre dovrebbero essere contate? E la multa della legge sarebbe falsa? Le cifre devono essere trattate come lettere, la legge va bene = Falso; La legge va bene = Vero

Commenti

  • La soluzione APL deve essere conteggiata in byte
  • Se la tua soluzione funziona per oltre 100 cifre di pi otterrai * 0,8 bonus
  • A causa del grande interesse, la data di fine è un giorno in più in futuro.

6
Quante cifre dobbiamo gestire?
marinus,

5
"una variabile chiamata piem" - quindi il nome del parametro deve essere piem? Ciò rende errate tutte le risposte correnti.
Ingo Bürk,

2
Un bonus divertente potrebbe essere una soluzione che è di per sé un piem.
britishtea,

5
Per motivi di interesse, come devono essere interpretati gli 0 in PI? Saltate o parole di 10 lettere?
MickyT

3
È un peccato non rispondere a domande molto importanti, ma hai già modificato in una data di fine.
Ingo Bürk,

Risposte:


3

APL (39)

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

Utilizza tutte le cifre fornite dalla costante pi dell'interprete APL, fino a un limite di 99. Nel mio caso (Dyalog APL 14 a 32 bit) c'erano 16 cifre. La versione a 64 bit ha probabilmente più cifre. Tuttavia, sono sufficienti 16 cifre per il funzionamento degli esempi forniti.

Le stringhe che hanno più di quella quantità di parole falliranno , anche se tutte le cifre che potrebbe controllare erano vere. (Lo stesso vale per gli altri post, al momento della stesura di questo documento.) Ad esempio, se ci fossero solo 10 cifre, il messaggio "Come voglio un drink" fallirebbe. Questo può essere risolto, ma al costo di 14 caratteri:

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

Quella versione accetterà qualsiasi stringa in cui le prime N cifre sono corrette.


Il tuo codice è il corto ma non è Unicode ... Dovrò pensare se meriti la vittoria o no, la versione javascript è solo un po 'più lunga di questa ... Comunque ho votato a favore di questa risposta.
Caridorc,

1
@marinus La domanda non specifica se il punteggio deve essere assegnato da caratteri o byte, ma il valore predefinito è byte (come da tag wiki), quindi penso che il tuo punteggio sia più vicino a 60.
Martin Ender

1
Data la codifica corretta è 1 byte per carattere. APL precede Unicode di decenni dopo tutto.
Marin

1
@marinus Fair point! Conosci qualche particolare codifica (esistente) in cui funzionerebbe effettivamente?
Martin Ender,

2
@ MartinBüttner: la tabella codici IBM 907 è una, ma ci sono molti carichi.
Marin

7

JavaScript (169) (140) (137) (135) (63) per 17 cifre di pi

Nella mia versione Law's finee Law ' s fineritorno sia vero.

Versione più recente (63) di Ingo Bürk e hsl

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

Nuova versione (135) per 17 cifre di pi (grazie 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
}

Vecchia versione (169) per 32 cifre di 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;
}

È possibile salvare 3 byte con:1e15*Math.PI+"2384626433832795"
xem

Grazie =) Nel frattempo l'ho cambiato usando questa idea ma ora usando solo le prime 17 cifre.
Flawr,

@ IngoBürk Grazie mille, sto solo controllando cosa funziona.
Flawr,

Scusa, non importa. Non sembra funzionare. : / Il forloop non può essere aggiunto in questo modo.
Ingo Bürk,

Ma ciò che funziona è l'inizializzazione r=0e quindi il semplice ciclo r+=s[a].length!=p[a](alla fine è possibile omettere ;). Quindi, ritorna !r.
Ingo Bürk,

7

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

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

Spiegazione

  • L'input viene preso come argomento per un lambda. Si aspetta a String.
  • Pi viene calcolato fino a 999decimali e trasformato in una stringa con il .rimosso.
  • I segni di punteggiatura vengono rimossi dalla poesia ed è suddiviso in singole parole. "Let's"è contato come due parole: "Let"e "s".
  • Utilizzare Array#mapper convertire ogni parola nella dimensione della parola, concatenarli in a String.
  • Usando un Regexp, controlla se i due creati Stringiniziano con gli stessi caratteri.

Ho applicato il bonus per la gestione di oltre 100 cifre. _non viene gestito come punteggiatura in questa soluzione.


Nota che non stai trattando _come punteggiatura.
Martin Ender,

Ben individuato. Per ragioni di argomento, la punteggiatura è _ sempre ? Che dire frasi come My nickname on Stack Overflow is britishtea_500.
britishtea,

Era solo un'osservazione. L'OP non è esattamente specifico sui dettagli qui.
Martin Ender,

Giusto. Lascerò la risposta per ora fino a quando non viene specificato nel problema :)
britishtea,

Usando bigdecimal non hai limiti alle cifre PI? Nizza (+1)
edc65,

4

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

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

Quasi la presentazione più lunga finora, ma:

  • Funziona con qualsiasi numero di cifre di Pi.
  • Rimuove tutti i caratteri ASCII richiesti e l'interruzione di riga, senza suddividere le parole in quei punti.
  • Gestisce correttamente 0 cifre in Pi (come parole di 10 lettere)

se funziona per il numero di cifre di Pi ricevi un bonus di 0,8
Caridorc,

1

Python - 130 127 116 - 17 cifre di pi

Come nella risposta di @flawr , Law ' s fineed Law's fineentrambi restituiscono True.

Grazie a @Emil per aver rimosso 12 caratteri dal programma.

import re
f=lambda x:all(j==int("31415926535897932"[i])for i,j in enumerate([len(s)for s in re.findall("[\w]+",x)]))

Puoi salvare 12 caratteri non salvandoli lin una variabile e definendo la funzione 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;}

1

pitone 3, 17 cifre di pi, 104

import re;f=lambda s:all(map(int.__eq__, map(int, '31415926535897932'), map(len,re.findall('[\w]+',s))))

È possibile sostituire il ;con una nuova riga per la leggibilità. Inoltre, è possibile rimuovere un numero di spazi.
tomsmeding

1

Python 3 - 129

Non tiene conto della punteggiatura:

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

0

T-SQL 488 383

E ora per una soluzione T-SQL di grandi dimensioni :)

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

Ciò crea una funzione con valori di tabella incorporata che utilizza un CTE ricorsivo per rilevare i confini delle parole.

Crea una funzione scalare che si fa strada tra le parole e PI fino a 31 decimali (primo 0). Si chiama nel modo seguente

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

0

CJam, 40

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

Non è chiaro cosa si intende per "qualsiasi tipo di punteggiatura"; questa soluzione rimuove i ,.'"?!;;personaggi.


0

Strumenti Bash e Unix, 111

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

0

Nodo JS 32 cifre 230 byte

Non posso accorciarlo 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');

rimuovere gli spazi bianchi.
Rohan Jhunjhunwala,
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.