Scrivi un rivelatore haiku-w


41

Un haiku è una poesia con tre righe, con un conteggio delle sillabe 5/7/5 , rispettivamente.

Un haiku-w è una poesia con tre righe, con un conteggio di parole 5/7/5 , rispettivamente.

Sfida

Scrivi un programma che restituirà true se l'input è un haiku-w, e false in caso contrario.

Un input haiku-w valido deve essere composto da 3 righe, separate da una nuova riga.

  • La riga 1 deve essere composta da 5 parole, ciascuna separata da uno spazio.
  • La riga 2 deve essere composta da 7 parole, ciascuna delle quali è separata da uno spazio.
  • La riga 3 deve essere composta da 5 parole, ognuna separata da uno spazio.

Esempi

The man in the suit
is the same man from the store.
He is a cool guy.

Risultato: vero

Whitecaps on the bay:
A broken signboard banging
In the April wind.

Risultato: falso


Regole

  • Questo è , quindi vince la risposta più breve in byte.
  • Si applicano scappatoie standard per il golf da codice. È vietato barare.
  • Altri valori di ritorno booleani, come 1e 0, sono accettabili.
  • È accettabile anche un elenco di stringhe di lunghezza 3 come input.
  • Gli input haiku-w validi non devono avere spazi iniziali o finali o spazi multipli che separano le parole.

1
L'haiku-w conterrà sempre 3 righe?
Kritixi Lithos,

1
Sì. Se l'input contiene più o meno di 3 righe, il programma dovrebbe restituire false .
DomTheDeveloper

5
Ci saranno mai spazi iniziali o finali su qualsiasi linea? O più spazi che separano le parole?
Greg Martin,

8
A proposito, chiarimenti come questo sono uno dei motivi principali per pubblicare prima le domande proposte nella Sandbox . :)
Greg Martin,

11
Punti bonus per invii in cui il codice stesso è un haiku-w.
Glorfindel,

Risposte:


25

JavaScript (ES6), 73 72 64 63 54 42 39 byte

Grazie a Neil per aver salvato 13 byte

a=>a.map(b=>b.split` `.length)=='5,7,5'

Spiegazione

Questa è una funzione fat-arrow che accetta una matrice di stringhe come argomento. Sostituisce ogni riga con il conteggio delle parole. Se è un haiku-w, aora contiene di nuovo un array di cinque, sette e cinque. Poiché JavaScript non ci consente di confrontare 2 array contemporaneamente, l'array viene prima convertito in una stringa e quindi confrontato. Ciò si traduce in un valore booleano che viene restituito.


1
%e *hanno la stessa precedenza, quindi non hai bisogno della ()s, anche se penso che (d*2|5)potrebbe anche funzionare. Inoltre puoi cavartela con un singolo &, anche se penso che puoi migliorare anche usando (b...).length==3>b.some(...length-...).
Neil,

Grazie per il suggerimento sulle parentesi. Inoltre, ho cambiato il mio approccio, quindi non controllo più esplicitamente la lunghezza.
Luca

1
Ah, in quel caso, non preoccuparti del calcolo, usa solo a=>a.map(c=>c.split .length)=='5,7,5'.
Neil,

Hehe, hai ragione. Avrei dovuto pensarci ...
Luke,

Non è ancora necessario il comando +''- ==stringify se l'altro argomento è una stringa.
Neil,

12

AWK (GNU Awk), 24, 30, 28, 20 byte

golfed

517253==$0=q=q NF NR

Emetterà "517253" per True e stringa vuota per False .

In awk, qualsiasi valore numerico diverso da zero o qualsiasi valore di stringa non vuoto è vero. Qualsiasi altro valore (zero o la stringa nulla, "") è falso

La Guida dell'utente di GNU Awk

Come funziona

Ogni istruzione (regola) awk è costituita da un modello (o espressione) con un'azione associata:

pattern {action}

Awk leggerà l'input riga per riga (record per record) e valuterà l'espressione del pattern per vedere se deve essere invocata un'azione corrispondente.

Il codice sopra è un'espressione Awk (pattern) autonoma senza il blocco di azioni, che è implicito essere {print $0}in quel caso.

Dovrebbe essere letto da destra a sinistra:

q=q NF NR

Aggiungere una N umero di F ields (parole) e N umero di R ecords (cioè il numero di linea corrente), alla variabile q .

In questo modo, durante l'elaborazione di un Haiku-w corretto, q verrà impostato su:

  • 51 - on line # 1 (5 parole)
  • 5172 - on line # 2 (5 parole + 7 parole)
  • 517253 - on line # 3 (5 parole + 7 parole + 5 parole)

$0=q

Assegna il valore appena calcolato di q a $ 0 (che contiene per impostazione predefinita l'intera riga / record corrente).

517253==$0

Confrontalo con una "firma" per un Haiku-w corretto (517253), se esiste una corrispondenza, l'intera espressione viene valutata "vera" e print $0viene eseguita un'azione corrispondente (implicita ), inviando "517253" a stdout (Vero) , altrimenti l'output sarà vuoto (False).

Nota che questo riconoscerà correttamente un Haiku-w, anche se è seguito da un numero arbitrario di linee di immondizia, ma credo che sia ok, come:

È accettabile anche un elenco di stringhe di lunghezza 3 come input.

(ovvero possiamo supporre che l'input sia lungo 3 righe)

Test

>awk '517253==$0=q=q NF NR'<<EOF
The man in the suit
is the same man from the store.
He is a cool guy.
EOF

517253

Provalo online!


2
Ciò non riesce se l'input è costituito da una riga contenente 575 parole o due righe contenenti 57 e 5 parole, ecc.
Lynn

@Lynn, vero, mettendo in attesa, fino a quando non viene risolto.
zeppelin,

@Lynn, ora dovrebbe essere risolto
zeppelin

1
Soluzione molto intelligente! :)
Lynn,

9

Python , 42 byte

lambda l:[s.count(' ')for s in l]==[4,6,4]

Provalo online!

Prende l'input come un elenco di linee, con le parole separate da spazi singoli.

Poiché siamo garantiti non ci saranno spazi iniziali o finali e solo singoli spazi separeranno ogni parola, possiamo verificare un w-haiku semplicemente contando gli spazi in ogni riga.

Facciamo questo in una comprensione di lista, per creare un elenco dei conteggi di spazio. Se è un haiku corretto, dovrebbe apparire così [4, 6, 4], quindi lo confrontiamo con questo e restituiamo il risultato.


Se stai bene con il supporto solo Python 2, è possibile salvare due byte: map(str.count,l,' ').
vaultah,

8

Gelatina , 10 9 byte

ċ€⁶⁼“¥©¥‘

Provalo online!

Spiegazione

ċ€⁶⁼“¥©¥‘  Input: length-3 list of strings
 €         For each string
ċ ⁶          Count the number of spaces
    “¥©¥‘  Convert string to code page indices, makes [4, 6, 4]
   ⁼       Match

Inoltre ċ€⁶⁼4,6,4e ċ€⁶⁼464D¤... non riesco a trovare niente di più corto, però. (Oh, si può capovolgere, troppo: 464D⁼ċ€⁶$)
Lynn

ċ€⁶Ḍ=464funziona bene per 8.
Jonathan Allan,

In realtà, no , scusa.
Jonathan Allan

7

Lotto, 102 byte

@echo off
call:c&&call:c 2||exit/b
:c
set/an=%1+5
set/ps=
for %%W in (%s%)do set/an-=1
exit/b%n%

Esce con un livello di errore diverso da zero non appena legge una riga con il numero errato di parole.


1
...... beh, merda
1717

7

Mathematica, 21 byte

{4,6,4}==Count@" "/@#&

Funzione senza nome che prende un elenco di elenchi di caratteri come input e di ritorno True o False. Conta semplicemente quanti spazi ci sono in ogni elenco di personaggi, che secondo le regole della sfida sono perfettamente correlati al numero di parole in ogni riga.

Presentazione precedente:

Mathematica, 31 byte

Length/@StringSplit/@#=={5,7,5}&

Funzione senza nome che prende un elenco di stringhe come input e che restituisce Trueo False.



6

Retina , 12 byte

M%` 
^4¶6¶4$

(c'è uno spazio finale dopo la prima riga)

Provalo online!

  • M%`  - Conta il numero di spazi in ogni riga.

    • M - Modalità partita: stampa il numero di partite.
    • % - per ogni riga
    • ` - configurazione separata e modello regex
    • - solo uno spazio.
  • ^4¶6¶4$ - Dovrebbero esserci 4, 6 e 4 spazi, ed esattamente tre righe.

    • corrisponde a newline. Il resto è una semplice espressione regolare.

Stampa 1per input valido, 0per invalido.


4

Python, 58 44 byte

lambda h:[len(l.split())for l in h]==[5,7,5]

-14 di tbodt


Puoi prendere l'input come un elenco di stringhe di lunghezza 3. È possibile salvare i byte spesi utilizzando split("\n").
miglia

44 byte:lambda h:[len(l.split())for l in h]==[5,7,5]
martedì

Qualcuno lo rende più corto da raggiungere barrato 44
Charlie


4

Pyth, 9 byte

qj464T/R;

Un programma che accetta input di un elenco di "quoted strings"e stampa TrueoFalse se del caso.

Suite di test

Come funziona

qj464T/R;   Program. Input: Q
qj464T/R;Q  Implicit variable fill
     T      Are the base-10
 j          digits
  464       of 464
q           equal
      /     to the number
        ;   of spaces
       R    in each string
         Q  in the input?
            Implicitly print

4

Japt , 11 byte

Risparmio di molti byte grazie a @ETHproductions

Questo richiede una matrice di tre stringhe come input.

®¸lÃ¥"5,7,5

Eseguilo online!


4

PowerShell , 43 byte

"$args"-replace'\S'-match'^(    )
\1  
\1$'

Provalo online!

Spiegazione

Accetta l'input come stringa separata da una nuova riga.

Rimuove tutti gli spazi non bianchi, quindi controlla che corrisponda esattamente a "4 spazi, newline, 6 spazi, newline, 4 spazi newline", usando una regex.

Il gruppo di acquisizione corrisponde a 4 spazi, il backreference si \1riferisce a quello. Le nuove righe sono incorporate nella stringa. Nota la seconda riga del regex contiene due spazi dopo il backreference.


1
Questo è un approccio interessante!
Ismael Miguel,

4

Pyke, 11 9 byte

dL/uq

Provalo qui!

dL/       -  map(i.count(" "), input)
        q - ^ == V
   u  -  [4, 6, 4]

Dopo il ubyte ci sono i seguenti byte:0x03 0x04 0x06 0x04


3

J, 12 byte

4 6 4=#@;:@>

L'input è un elenco in scatola di stringhe.

Spiegazione

Questa è una forchetta con un dente sinistro costante. Questo controlla il risultato del dente giusto #@;:@>, per la parità con 4 6 4. Il momento giusto decomprime ogni ( >), quindi ( @) converte ogni stringa in parole ( ;:), quindi ( @) prende la lunghezza di ogni ( #).


3

R, 48 byte

all(stringr::str_count(scan(,"")," ")==c(4,6,4))

Legge un vettore di carattere a 3 lunghezze da stdin e funziona contando il numero di spazi. Per contare il numero di spazi che usiamo str_countdal stringrpacchetto che può contare le occorrenze in base a un modello regex.

Un approccio alternativo senza l'utilizzo di pacchetti potrebbe essere:

all(sapply(scan(,""),function(x)length(el(strsplit(x," "))))==c(5,7,5))

La prima volta che abbia mai visto elprima, grazie per quello.
BLT

3

C 142 byte

void f(){char *c;l=3;s[3]={0};while(l>0){if(*c==' ')s[l-1]++;if((*c=getchar())=='\n'){l--;}}printf("%d",(s[0]==4 && s[1]==6 && s[2]==4)?1:0);}

Versione non golfata:

void f()
{
  char *c;
  c = (char *)malloc(sizeof(char)); 
  int l=3;
  int s[3]= {0};


  while(l>0)
  {  
    if(*c==' ')
    s[l-1]++;

    if( (*c=getchar())=='\n')
    {    
      l--;
    }   
  }
  printf("%d",(s[0]==4 && s[1]==6 && s[2]==4)?1:0);
}

Restituisce 1 per la sequenza 5/7/5 altrimenti 0.

Una prova positiva:

inserisci qui la descrizione dell'immagine


3

C ++, 357 byte

Una specie di nuovo per programmare il golf, ma questo è il migliore che potrei fare rapidamente

#include <iostream>
using namespace std;
int n(std::string s)
{
    int b = 0;
    for(char c: s)
        if(c == ' ') b++;
    cout << "C = " << b;
    return b;
}
int main()
{
    string a, b, c;
    getline(cin, a);
    getline(cin, b);
    getline(cin, c);
    if(n(a)==4 && n(b)==6 && n(c)==4)
        cout<<'1';
    else cout << '0';
    return 0;
}

4
Benvenuti in PPCG! L'obiettivo del code golf è quello di rendere il codice il più breve possibile; un buon primo passo sarebbe rimuovere tutti gli spazi bianchi non necessari.
ETHproductions

3

Ruby 1.9.3

Non golfato, ma è di per sé un haiku-w

def haiku_w(input)
  lines = input.split("\n")
  lengths = lines.map(&:split).map(&:length)
  lengths.eql?([5,7,5])
end

o...

lines equals input split (newlines)
lengths equals lines map split map length
lengths equals five seven five?

Sfortunatamente non funziona con i principali spazi bianchi su nessuna riga, ma fa fronte al trailing.


2

Python 2 , 57 64 byte

Modifica corretta con l'aggiunta di 7 byte dopo il feedback di @Dada. Grazie!

i,j=input,''
for x in i():j+=`len(x.split())`+' '
i(j=='5 7 5 ')

Provalo online!

Non è la risposta più breve di Python da molto tempo, ma volevo solo usare il nuovo trucco che ho imparato recentemente sull'uso input() per visualizzare l'output e salvare printun'istruzione. Accetta un elenco di righe come input. Richiede Ctrl C (o qualsiasi altro tasto premuto per quella materia) per terminare il programma (con un'eccezione) in un terminale ma funziona bene senza su TIO.


4
Questo fallirà in casi come questo .
Dada,

Ti darò quel @Dada. Questo è un serio caso di prova :)
ElPedro,

Corretto e testato con il test case.
ElPedro,

2

MATL, 16 byte

"@Y:Ybn&h][ACA]=

L'input è un array di celle di stringhe e restituisce a matrice di verità o falsa .

Provalo online

Spiegazione

        % Implicitly grab input
"       % For each element in the cell array
@Y:Yb   % Split it on spaces
n       % Count the number of elements
&h      % Horizontally concatenate everything on the stack
[ACA]   % Create the array [5 7 5]
=       % Perform an element-wise equality
        % Implicitly display the truthy/falsey array

2

MATLAB / Octave, 38 byte

@(x)cellfun(@(y)sum(y==32),x)==[4 6 4]

Questa soluzione accetta una matrice di celle di stringhe come input, conta il numero di spazi in ciascuna riga, quindi confronta il risultato con la matrice [4 6 4]e produce una matrice di verità (tutti i valori sono 1) o falsa (qualsiasi valore è zero).

Demo online



2

Clojure, 44 byte

#(=(for[l %](count(filter #{\ }l)))'(4 6 4))

L'input è un elenco di stringhe. La funzione trova solo spazi e li conta. Questa spiegazione è un Haiku. :)


2

Java 7, 154 byte

class M{public static void main(String[]a){System.out.print(a.length==3&&a[0].split(" ").length==5&a[1].split(" ").length==7&a[2].split(" ").length==5);}}

Il requisito del programma e il potenziale di avere meno o più di tre righe, per non parlare della stessa verbosità di Java, fa sì che questo codice "golfizzato" sia piuttosto grande.

Ungolfed:

Provalo qui.

class M{
  public static void main(String[] a){
    System.out.print(a.length == 3
        && a[0].split(" ").length == 5
         & a[1].split(" ").length == 7
         & a[2].split(" ").length == 5);
  }
}

2

SimpleTemplate, 77 byte

Purtroppo, l'approccio dell'espressione regolare è il più breve.

{@if"@^([^\s]+ ?){5}\s([^\s]+ ?){7}\s([^\s]+ ?){5}+$@"is matchesargv}{@echo1}

Richiede che il testo sia indicato come primo argomento, con le nuove righe in stile * NIX. Questo non funzionerà con le newline in stile Windows.

Ungolfed:

{@if "@^([^\s]+ ?){5}\s([^\s]+ ?){7}\s([^\s]+ ?){5}+$@"is matches argv}
    {@echo 1}
{@/}

Basato su non regex, 114 byte

{@setR 1}{@eachargv asL keyK}{@php$DATA[L]=count(explode(' ',$DATA[L]))!=5+2*($DATA[K]&1)}{@set*R R,L}{@/}{@echoR}

Ciò richiede che ogni riga sia data come argomento alla funzione.

Ungolfed:

{@set result 1}
{@each argv as line key k}
    {@php $DATA['line'] = count(explode(' ', $DATA['line'])) != 5+2*( $DATA['k'] & 1 )}
    {@set* result result, line}
{@/}
{@echo result}

2

Impilato, 22 byte

[' 'eq sum]map(4 6 4)=

Prende input dall'alto dello stack come un elenco di stringhe di caratteri, come tale:

($'The man in the suit' $'is the same man from the store.' $'He is a cool guy.')

Spiegazione

[' 'eq sum]map(4 6 4)=
[         ]map          map the following function over each item
 ' 'eq                  vectorized equality with ' '
       sum              summed
              (4 6 4)=  is equal to (4 6 4)

2

Java (OpenJDK) , 82 byte

-2 byte grazie a @ corvus_192!

s->s[0].split(" ").length==5&s[2].split(" ").length==5&s[1].split(" ").length==7

Provalo online!

Sembra così giocabile a golf ma senza una funzione di mappa integrata, non riesco a trovare un buon modo. L'iterazione nell'array è più lunga di alcuni byte, così come la scrittura di una funzione della mappa usando i flussi.

L'espressione lambda prende una matrice di stringhe e restituisce un valore booleano.


E se hai solo due linee come input o quattro?
Kevin Cruijssen,

@KevinCruijssen secondo l'op, "È accettabile anche un elenco di stringhe di lunghezza 3 come input". Il mio programma occupa un elenco di 3 righe di lunghezza.
Pavel,

Potresti ottenere una funzione mappa se chiami Arrays.stream, ma è abbastanza lungo da non Arrays
valerne la

@ Pokechu22 sì, ci ho provato, ma alla fine sono rimasto più a lungo.
Pavel

È possibile utilizzare &invece di &&salvare due byte
corvus_192

2

SmileBASIC, 96 94 byte

INPUT A$,B$,C$?C(A$,4)*C(B$,6)*C(C$,4)DEF C(S,E)WHILE""<S
INC N,POP(S)<"!
WEND
RETURN N==E
END

1

R, 100 byte

f<-function(a){all(sapply(a,function(x){length(grep(" ",as.list(strsplit(x,"")[[1]])))})==c(4,6,4))}

Prende come argomento un elenco di stringhe di lunghezza 3. Probabilmente non verrà ulteriormente golfato dal momento che un ulteriore golf lo trasforma nella risposta di @ Billywob.

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.