Ecrire un détecteur de haïku-w

41

Un haïku est un poème à trois lignes, comptant respectivement 5/7/5 syllabes .

Un haïku-w est un poème de trois lignes, avec un nombre de mots de 5/7/5 respectivement.

Défi

Ecrivez un programme qui retournera true si l'entrée est un haiku-w, et false sinon.

Une entrée valide de haiku-w doit comporter 3 lignes, séparées par une nouvelle ligne.

  • La ligne 1 doit comprendre 5 mots, chaque mot étant séparé par un espace.
  • La ligne 2 doit être composée de 7 mots, chaque mot étant séparé par un espace.
  • La ligne 3 doit comprendre 5 mots, chaque mot étant séparé par un espace.

Exemples

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

Résultat: vrai

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

Résultat: faux


Règles

  • C'est du , donc la réponse la plus courte en octets est gagnante.
  • Les échappatoires standard de code-golf s'appliquent. La triche est interdite.
  • Les autres valeurs de retour booléennes, telles que 1et 0, sont acceptables.
  • Une liste de chaînes de longueur 3 en entrée est également acceptable.
  • Les entrées de haiku-w valides ne doivent pas avoir d'espaces de début ou de fin, ni d'espaces multiples séparant des mots.
DomTheDeveloper
la source
1
Est-ce que le haiku-w contient toujours 3 lignes?
Kritixi Lithos
1
Oui. Si l'entrée contient plus de 3 lignes ou moins, le programme doit retourner false .
DomTheDeveloper
5
Y aura-t-il des espaces de début ou de fin sur une ligne? Ou plusieurs espaces séparant des mots?
Greg Martin
8
À propos, de telles clarifications sont une raison principale pour poster d'abord les questions proposées dans le bac à sable . :)
Greg Martin
11
Points bonus pour les envois dont le code est un haiku-w.
Glorfindel

Réponses:

25

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

Merci à Neil d'avoir économisé 13 octets

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

Explication

C'est une fonction de grosse flèche qui prend un tableau de chaînes en argument. Il remplace chaque ligne par son nombre de mots. Si c'est un haiku-w, acontient maintenant un tableau de cinq, sept et cinq encore. Puisque JavaScript ne nous permet pas de comparer 2 tableaux en même temps, le tableau est d'abord converti en chaîne, puis comparé. Cela se traduit par un booléen qui est renvoyé.

Luke
la source
1
%et *ont le même précédent, de sorte que vous n'avez pas besoin de ()s, même si je pense que cela (d*2|5)pourrait également fonctionner. En outre, vous pouvez vous en sortir avec un seul &, bien que je pense que vous pouvez améliorer même cela en utilisant (b...).length==3>b.some(...length-...).
Neil
Merci pour le conseil sur les parenthèses. De plus, j'ai changé d'approche, donc je ne vérifie plus explicitement la longueur.
Luc
1
Ah, dans ce cas, ne vous embêtez pas avec le calcul, utilisez-le a=>a.map(c=>c.split .length)=='5,7,5'.
Neil
Hehe, tu as raison. J'aurais du y penser ...
Luke le
Vous n'avez toujours pas besoin de +''- ==stringifie si l'autre argument est une chaîne.
Neil
12

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

Golfé

517253==$0=q=q NF NR

Produira "517253" pour True et une chaîne vide pour False .

Dans awk, toute valeur numérique non nulle ou toute valeur de chaîne non vide est vraie. Toute autre valeur (zéro ou la chaîne nulle, "") est fausse

Le Guide de l'utilisateur GNU Awk

Comment ça marche

Chaque instruction awk (règle) consiste en un motif (ou une expression) avec une action associée:

pattern {action}

Awk lit l'entrée par ligne (enregistrement par enregistrement) et évalue l'expression du modèle pour voir si une action correspondante doit être appelée.

Le code ci-dessus est une expression Awk autonome (modèle) sans le bloc d'action, ce qui est implicite {print $0}dans ce cas.

Il devrait être lu de droite à gauche:

q=q NF NR

Ajout d' un N mbre de F OMAINES (mots) et N mbre de R ecords ( à savoir le numéro de la ligne en cours), à la variable q .

De cette façon, lors du traitement d’un Haiku-w approprié, q sera réglé sur:

  • 51 - sur la ligne 1 (5 mots)
  • 5172 - sur la ligne 2 (5 mots + 7 mots)
  • 517253 - sur la ligne 3 (5 mots + 7 mots + 5 mots)

$0=q

Attribuez la valeur nouvellement calculée de q à 0 $ (qui contient la totalité de la ligne / de l'enregistrement en cours par défaut).

517253==$0

Comparez-le avec une "signature" pour un Haiku-w (517253) correct. S'il existe une correspondance, l'expression entière devient "true" et une action correspondante (implicite print $0) est exécutée, en envoyant "517253" à la sortie standard (True). , sinon la sortie sera vide (False).

Notez que ceci reconnaîtra correctement un Haiku-w, même s'il est suivi d'un nombre arbitraire de lignes de mémoire, mais je crois que c'est correct, comme suit:

Une liste de chaînes de longueur 3 en entrée est également acceptable.

(c’est-à-dire que nous pouvons supposer que l’entrée a une longueur de 3 lignes)

Tester

>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

Essayez-le en ligne!

Zeppelin
la source
2
Cela échoue si l'entrée consiste en une ligne contenant 575 mots ou en deux lignes contenant 57 et 5 mots, etc.
Lynn
@ Lynn, c'est vrai, mettre en attente, jusqu'à ce que cela soit corrigé.
Zeppelin
@ Lynn, devrait être corrigé maintenant
zeppelin le
1
Solution très intelligente! :)
Lynn
9

Python , 42 octets

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

Essayez-le en ligne!

Prend les entrées sous forme de liste de lignes, les mots étant séparés par des espaces simples.

Comme nous sommes assurés qu'il n'y aura pas d'espaces de début ou de fin, et que seuls des espaces séparent chaque mot, nous pouvons vérifier un w-haiku en comptant simplement les espaces de chaque ligne.

Nous faisons cela dans une compréhension de liste, pour créer une liste des comptes d'espace. Si c'est un haïku correct, ça devrait ressembler [4, 6, 4], alors on le compare avec ceci et on retourne le résultat.

FlipTack
la source
Si vous êtes d' accord avec le soutien que Python 2, vous pouvez enregistrer deux octets: map(str.count,l,' ').
vaultah le
8

Gelée , 10 à 9 octets

ċ€⁶⁼“¥©¥‘

Essayez-le en ligne!

Explication

ċ€⁶⁼“¥©¥‘  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
milles
la source
Aussi ċ€⁶⁼4,6,4et ċ€⁶⁼464D¤… je ne trouve rien de plus court, cependant. (Oh, vous pouvez le retourner aussi: 464D⁼ċ€⁶$)
Lynn
ċ€⁶Ḍ=464fonctionne très bien pour 8.
Jonathan Allan
En fait, non , désolé.
Jonathan Allan
7

Lot, 102 octets

@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%

Quitte avec un niveau d'erreur non nul dès qu'il lit une ligne contenant un nombre incorrect de mots.

Neil
la source
1
...... bien merde
tbodt
7

Mathematica, 21 octets

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

Fonction sans nom prenant une liste de listes de caractères en entrée et retour Trueou False. Compte simplement le nombre d'espaces dans chaque liste de caractères, ce qui, selon les règles du défi, correspond parfaitement au nombre de mots de chaque ligne.

Soumission précédente:

Mathematica, 31 octets

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

Fonction sans nom prenant une liste de chaînes en entrée et renvoyant Trueou False.

Greg Martin
la source
6

Haskell, 34 33 octets

f l=[sum[1|' '<-c]|c<-l]==[4,6,4]

Essayez-le en ligne! .

Edit: merci à @xnor pour un octet!

nimi
la source
Pointful est plus courte: f l=[sum[1|' '<-c]|c<-l]==[4,6,4].
xnor
6

Rétine , 12 octets

M%` 
^4¶6¶4$

(il y a un espace de fin après la première ligne)

Essayez-le en ligne!

  • M%`  - Comptez le nombre d'espaces dans chaque ligne.

    • M - Mode de correspondance - affiche le nombre de correspondances.
    • % - pour chaque ligne
    • ` - configuration séparée et motif regex
    • - juste un espace.
  • ^4¶6¶4$ - Il devrait y avoir 4, 6 et 4 espaces et exactement trois lignes.

    • correspond aux nouvelles lignes. Le reste est une simple expression régulière.

Imprime 1pour une entrée valide, 0pour invalide.

Kobi
la source
4

Python, 58 44 octets

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

-14 par tbodt

Sagiksp
la source
Vous avez le droit de prendre l’entrée sous la forme d’une liste de 3 chaînes de longueur. Vous pouvez enregistrer les octets utilisés split("\n").
miles
44 octets:lambda h:[len(l.split())for l in h]==[5,7,5]
samedi
Quelqu'un fait ça plus court pour atteindre barré 44
Charlie
4

Perl , 26 octets

24 octets de code + 2 octets pour les -apdrapeaux.

$m.=@F}{$_=$m==575&$.==3

Essayez-le en ligne!

Dada
la source
4

Pyth, 9 octets

qj464T/R;

Un programme qui prend la saisie d'une liste de "quoted strings"et imprime Trueou Falseselon le cas.

Suite de tests

Comment ça marche

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
TheBikingViking
la source
4

Japt , 11 octets

Économisez beaucoup d'octets grâce à @ETHproductions

Cela prend un tableau de trois chaînes en entrée.

®¸lÃ¥"5,7,5

Courez en ligne!

Oliver
la source
4

PowerShell , 43 octets

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

Essayez-le en ligne!

Explication

Prend l'entrée en tant que chaîne séparée par une nouvelle ligne.

Supprime tous les espaces non blancs, puis vérifie qu'il correspond "4 espaces, nouvelle ligne, 6 espaces, nouvelle ligne, 4 espaces nouvelle ligne" à l'aide d'une expression régulière.

Le groupe de capture correspond à 4 espaces, le backreference s'y \1réfère. Les nouvelles lignes sont incorporées dans la chaîne. Notez que la deuxième ligne de l'expression rationnelle contient deux espaces après la référence arrière.

briantiste
la source
1
C'est une approche intéressante!
Ismael Miguel le
4

Pyke, 11 à 9 octets

dL/uq

Essayez-le ici!

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

Après l' uoctet, il y a les octets suivants:0x03 0x04 0x06 0x04

Bleu
la source
3

J, 12 octets

4 6 4=#@;:@>

L'entrée est une liste encadrée de chaînes.

Explication

Ceci est une fourche avec une dent gauche constante. Ceci vérifie le résultat de la tâche droite #@;:@>, pour l’égalité avec 4 6 4. Le bon moment décompresse chaque ( >), then ( @) convertit chaque chaîne en mots ( ;:), then (@ ) prend la longueur de each ( #).

Conor O'Brien
la source
3

R, 48 octets

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

Lit un vecteur de caractères de 3 longueurs à partir de stdin et fonctionne en comptant le nombre d'espaces. Pour compter le nombre d'espaces, nous utilisons lestr_count du stringrpackage qui peut compter les occurrences basé sur un modèle de regex.

Une approche alternative sans utiliser de paquet pourrait être:

all(sapply(scan(,""),function(x)length(el(strsplit(x," "))))==c(5,7,5))
Billywob
la source
C'est la première fois que je vois ça el, merci pour ça.
BLT
3

C 142 octets

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);}

Version non-golfée:

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);
}

Retourne 1 pour la séquence 5/7/5 sinon 0.

Un test positif:

entrez la description de l'image ici

Abel Tom
la source
3

C ++, 357 octets

Une sorte de nouveau code au golf, mais c'est le mieux que je puisse faire rapidement

#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;
}
Ricardo Iglesias
la source
4
Bienvenue chez PPCG! Le but du code golf est de rendre votre code le plus court possible; une bonne première étape serait de supprimer tous les espaces inutiles.
ETHproductions
3

Ruby 1.9.3

Pas de golf, mais est lui-même un haïku-w

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

ou...

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

Malheureusement, ne fonctionne pas avec les espaces blancs de début sur les lignes, mais résiste au trailing.

Ymbirtt
la source
2

Python 2 , 57 64 octets

Éditer Corrigé avec l'ajout de 7 octets après les commentaires de @Dada. Merci!

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

Essayez-le en ligne!

Ce n’est pas la réponse Python la plus courte de loin mais je voulais simplement utiliser le nouveau truc que j’ai appris récemment à utiliser input()pour afficher la sortie et enregistrer une printdéclaration. Prend une liste de lignes en entrée. Requiert Ctrl C (ou toute autre pression sur une touche) pour terminer le programme (avec une exception) dans un terminal mais fonctionne correctement sans TIO.

ElPedro
la source
4
Cela échouera dans des cas comme celui-ci .
Dada
Je vais vous donner ça @ Dada. C'est un cas de test sérieux :)
ElPedro
Corrigé et testé avec votre cas de test.
ElPedro
2

MATL, 16 octets

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

L'entrée est un tableau de cellules de chaînes et retourne un tableau de vérité ou de falsey .

Essayez-le en ligne

Explication

        % 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
Suever
la source
2

MATLAB / Octave, 38 octets

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

Cette solution accepte un tableau de cellules de chaînes en entrée, compte le nombre d'espaces dans chaque ligne, puis compare le résultat au tableau. [4 6 4] et génère un tableau de vérité (toutes les valeurs sont 1) ou de falsey (toute valeur est égale à zéro).

Démo en ligne

Suever
la source
2

Clojure, 44 octets

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

L'entrée est une liste de chaînes. Fonction ne trouve que des espaces et les compte. Cette explication est un haïku. :)

NikoNyrh
la source
2

Java 7, 154 octets

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);}}

L'exigence du programme et le potentiel d'avoir moins ou plus de trois lignes, sans parler du langage de Java lui-même, font que ce code "joué au golf" est plutôt volumineux.

Ungolfed:

Essayez ici.

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);
  }
}
Kevin Cruijssen
la source
2

SimpleTemplate, 77 octets

Malheureusement, l'expression habituelle est la plus courte.

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

Requiert que le texte soit donné comme premier argument, avec des nouvelles lignes de style * NIX. Cela ne fonctionnera pas avec les nouvelles lignes de style Windows.

Ungolfed:

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

Non basé sur regex, 114 byes

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

Cela nécessite que chaque ligne soit donnée comme argument de la fonction.

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}
Ismael Miguel
la source
2

Empilés, 22 octets

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

Prend les entrées du haut de la pile sous forme de liste de chaînes de caractères, en tant que telles:

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

Explication

[' '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)
Conor O'Brien
la source
2

Java (OpenJDK) , 82 octets

-2 octets grâce à @ corvus_192!

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

Essayez-le en ligne!

Il a l'air tellement golfable mais sans une fonction de carte intégrée, je ne peux pas trouver un bon moyen. La itération dans la matrice prend quelques octets de plus, tout comme l'écriture d'une fonction de carte à l'aide de flux.

L'expression Lambda prend un tableau de chaînes et renvoie un booléen.

Pavel
la source
Que faire si vous n'avez que deux lignes en entrée ou quatre?
Kevin Cruijssen le
@KevinCruijssen selon l'op, "Une liste de chaînes de longueur 3 en tant qu'entrée est également acceptable". Mon programme prend une liste de lignes de longueur 3.
Pavel
Vous pourriez obtenir une fonction de carte si vous appelez Arrays.stream, mais c'est assez long pour que cela ne vaille pas la peine d'être utilisé (surtout si vous devez importer Arrays)
Pokechu22
@ Pokechu22 ouais j'ai essayé ça, ça finissait toujours par être plus long.
Pavel
Vous pouvez utiliser &au lieu de &&pour sauvegarder deux octets
corvus_192
2

SmileBASIC, 96 94 octets

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
12Me21
la source
1

R, 100 octets

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

Prend comme argument une liste de chaînes de longueur 3. Ne jouerez probablement plus au golf, car cela le transforme en la réponse de @ Billywob.

BLT
la source