写句探测器


41

俳句是三行诗,具有5/7/5 音节计数,分别。

一个俳句-W是诗与三行,有5/7/5 计数,分别。

挑战

编写一个程序,如果输入的是haiku-w,则返回true,否则返回false

有效的haiku-w输入必须包含3行,并用换行符分隔。

  • 第1行必须包含5个字,每个字之间用空格隔开。
  • 第2行必须由7个单词组成,每个单词用空格分隔。
  • 第3行必须包含5个字,每个字用空格隔开。

例子

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

结果:正确

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

结果:错误


规则

  • 这是,因此最短的答案以字节为单位。
  • 适用标准代码高尔夫球漏洞。禁止作弊。
  • 其他布尔返回值(例如10)也是可以接受的。
  • 也可以接受长度为3的字符串列表作为输入。
  • 有效的haiku-w输入不应包含前导或尾随空格,也不能有多个空格分隔单词。

1
句-w总是包含3行吗?
Kritixi Lithos

1
是。如果输入包含多于或少于3行,则程序应返回false
DomTheDeveloper

5
一行上是否会有前导或尾随空格?还是用多个空格分隔单词?
格雷格·马丁

8
顺便说一句,此类澄清是首先在沙箱中发布提出的问题的主要原因。:)
格雷格·马丁

11
代码本身为haiku-w的提交的奖励积分。
Glorfindel

Answers:


25

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

感谢Neil节省了13个字节

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

说明

这是一个带箭头的函数,它将字符串数组作为参数。它用字数替换每一行。如果是haiku-w,则a现在包含五个,七个和五个的数组。由于JavaScript不允许我们同时比较2个数组,因此先将数组转换为字符串,然后再进行比较。这导致返回一个布尔值。


1
%*具有相同的优先级,因此您不需要()s,尽管我认为(d*2|5)也可以。您也可以摆脱一个难题&,尽管我认为通过使用甚至可以改善(b...).length==3>b.some(...length-...)
尼尔

感谢您提供有关括号的提示。另外,我更改了方法,因此不再显式检查长度。
路加福音

1
嗯,在那种情况下,不必理会计算,只需使用即可a=>a.map(c=>c.split .length)=='5,7,5'
尼尔

呵呵,你是对的。我应该想到的……
路加福音

如果另一个参数是字符串,您仍然不需要+''- ==字符串化。
尼尔

12

AWK(GNU Awk), 243028,20字节

打高尔夫球

517253==$0=q=q NF NR

将为True输出“ 517253” ,为False输出空字符串。

在awk中,任何非零数字值或任何非空字符串值均为true。其他任何值(零或空字符串“”)均为false

GNU Awk用户指南

这个怎么运作

每个awk语句(规则)都包含一个模式(或表达式)以及相关的操作:

pattern {action}

Awk将逐行读取输入(逐条记录)并评估模式表达式,以查看是否要调用相应的动作。

上面的代码是没有动作块的独立Awk表达式(模式),{print $0}在这种情况下隐含此代码。

应该从右到左阅读:

q=q NF NR

追加一个Ñ棕土的˚F ields(字)和Ñ的棕土- [R ecords(即,当前的行号),给变量q

这样,在处理适当的Haiku-w时,q将设置为:

  • 51-在第1行上(5个字)
  • 5172-在第2行上(5个字+ 7个字)
  • 517253-在第3行上(5个字+ 7个字+ 5个字)

$0=q

将新计算的q值分配给$ 0(默认情况下,它包含整个当前行/记录)。

517253==$0

将其与适当的Haiku-w的“签名”进行比较(517253),如果存在匹配项,则整个表达式的计算结果为“ true”,并print $0运行相应的操作(隐式),将“ 517253”发送到stdout(正确) ,否则输出将为空(False)。

请注意,即使后面有任意数量的垃圾行,也可以正确识别Haiku-w,但我相信这样可以,例如:

也可以接受长度为3的字符串列表作为输入。

(即我们可以假设输入为3行长)

测试

>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

在线尝试!


2
如果输入由包含575个单词的一行或包含57个和5个单词的两行等组成,则此操作失败
Lynn

@Lynn,是的,暂停,直到解决此问题。
Zeppelin

@Lynn,现在应该修复
齐柏林飞艇

1
非常聪明的修复!:)
Lynn

9

Python,42个字节

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

在线尝试!

将输入作为行列表,单词之间用单个空格分隔。

由于我们保证不会有前导或尾随空格,并且每个单词只会分隔一个空格,因此我们可以通过简单地计算每行中的空格来验证w-haiku。

我们以列表理解的方式进行操作,以创建空间计数列表。如果它是正确的hai句,它应该看起来像[4, 6, 4],因此我们将其与此进行比较并返回结果。


如果您只支持Python 2,可以节省两个字节:map(str.count,l,' ')
vaultah

8

果冻10 9字节

ċ€⁶⁼“¥©¥‘

在线尝试!

说明

ċ€⁶⁼“¥©¥‘  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

还有ċ€⁶⁼4,6,4ċ€⁶⁼464D¤……我找不到更短的东西。(哦,你可以将其翻转,太:464D⁼ċ€⁶$
林恩

ċ€⁶Ḍ=464工作正常,8
乔纳森·艾伦

其实,对不起。
乔纳森·艾伦

7

批处理,102字节

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

读取错误字数的行后,立即以非零错误级别退出。


1
......废话
tbodt

7

Mathematica,21个字节

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

未命名函数,将字符列表作为输入并返回TrueFalse。只需计算每个字符列表中有多少空格,在挑战的规则下,这些空格与每行中的单词数完美相关。

先前提交的内容:

Mathematica,31个字节

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

未命名函数,将字符串列表作为输入并返回TrueFalse


6

Haskell,34 33字节

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

在线尝试!

编辑:感谢@xnor一个字节!


贴题较短:f l=[sum[1|' '<-c]|c<-l]==[4,6,4]
xnor

6

视网膜,12字节

M%` 
^4¶6¶4$

(第一行后面有一个空格)

在线尝试!

  • M%`  -计算每行中的空格数。

    • M -比赛模式-打印比赛次数。
    • % -每行
    • ` -单独的配置和正则表达式模式
    • -只是一个空间。
  • ^4¶6¶4$ -应该有4、6和4个空格,正好是三行。

    • 匹配换行符。其余的是一个简单的正则表达式。

打印1有效输入,0无效输入。


4

Python,58 44字节

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

-14来自tbodt


您可以将输入作为长度为3的字符串列表。您可以使用保存字节split("\n")
英里

44个字节:lambda h:[len(l.split())for l in h]==[5,7,5]
tbodt

有人让它变得更短以达到划破44
查理(Charlie)


4

Pyth,9个字节

qj464T/R;

输入列表"quoted strings"并打印的程序TrueFalse适当的程序。

测试套件

这个怎么运作

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

PowerShell,43个字节

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

在线尝试!

说明

将输入作为换行符分隔的字符串。

删除所有非空格,然后使用正则表达式检查它是否完全匹配“ 4个空格,换行,6个空格,换行,4个空格换行”。

捕获组匹配4个空格,后向引用引用\1该空格。换行符嵌入在字符串中。请注意,正则表达式的第二行在反向引用之后包含两个空格。


1
这是一个有趣的方法!
伊斯梅尔·米格尔

4

Pyke,11个 9字节

dL/uq

在这里尝试!

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

u字节有以下字节:0x03 0x04 0x06 0x04


3

J,12个字节

4 6 4=#@;:@>

输入是装箱的字符串列表。

说明

这是带有恒定左齿的叉子。这将检查右叉齿的结果是否与#@;:@>相等4 6 4。正确的时间将每个(>)拆箱,然后(@)将每个字符串转换为单词(;:),然后(@)占用每个(#)的长度。


3

R,48个字节

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

从stdin读取一个3长度的字符向量,并通过计算空格数来工作。要计算的空格数,我们使用str_count来自 stringr可指望基于正则表达式模式发生包。

不使用软件包的替代方法可能是:

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

我第一次见过el,对此表示感谢。
BLT

3

C 142字节

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

非高尔夫版本:

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

对于5/7/5序列返回1,否则返回0。

阳性测试用例:

在此处输入图片说明


3

C ++,357字节

高尔夫编程的新手,但这是我能快速做到的最好

#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
欢迎来到PPCG!打高尔夫球的目的是使您的代码尽可能短。一个好的第一步是删除所有不必要的空格。
ETHproductions

3

Ruby 1.9.3

不打高尔夫球,但本身就是hai句

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

要么...

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

不幸的是,它不适用于任何行上的前导空格,但可以应付尾随。


2

Python 2中57 64个字节

编辑在@Dada反馈后,添加了7个字节已更正。谢谢!

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

在线尝试!

从长远来看,这并不是最短的Python答案,而只是想使用我最近学到的input()用于显示输出和保存print语句的新技巧。将行列表作为输入。需要Ctrl C(或与此有关的任何其他按键)在终端中终止程序(有例外),但在没有TIO的情况下可以正常工作。


4
这将在类似情况下失败这一个
达达(Dada)

我给你@Dada。那是一个严重的测试案例:)
ElPedro

已对测试用例进行更正和测试。
ElPedro

2

MATL,16个字节

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

输入是字符串的单元格数组,并返回一个true或false数组

在线尝试

说明

        % 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 /八度,38字节

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

此解决方案接受字符串的单元格数组作为输入,计算每行中的空格数,然后将结果与数组进行比较 [4 6 4]并生成一个true(所有值均为1)或false(任何值均为零)数组。

在线演示



2

Clojure,44个字节

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

输入是字符串列表。函数仅查找空格并对其进行计数。这个解释是Hai句。:)


2

Java 7,154个字节

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

程序要求以及少于三行或更多行的潜力,而不必太提及Java的冗长性,这导致此'golf'代码非常庞大。

取消高尔夫:

在这里尝试。

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个字节

可悲的是,正则表达式的方法最短。

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

要求使用* NIX样式的换行符将文本作为第一个参数。这不适用于Windows风格的换行符。

取消高尔夫:

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

基于非正则表达式的114个byes

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

这要求每行都作为函数的参数给出。

取消高尔夫:

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

堆叠,22字节

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

从堆栈顶部获取输入作为字符串列表,例如:

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

说明

[' '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个字节

-2个字节,感谢@ corvus_192!

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

在线尝试!

它看起来很适合打高尔夫球,但没有内置的地图功能,我找不到很好的方法。遍历数组要长几个字节,就像使用流编写map函数一样。

Lambda表达式采用字符串数组并返回布尔值。


如果只有两行或四行输入怎么办?
凯文·克鲁伊森

@KevinCruijssen根据操作,“也可以接受长度为3的字符串列表作为输入”。我的程序采用长度为3的行列表。
帕维尔

如果调用Arrays.stream,您可以获得map函数,但是它足够长,可能不值得使用(特别是如果需要导入Arrays
Pokechu22

@ Pokechu22是的,我尝试过,但最终还是更长了。
帕维尔

您可以使用&而不是&&保存两个字节
corvus_192

2

SmileBASIC,96 94字节

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字节

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

将长度为3的字符串列表作为参数。可能不会再打高尔夫球了,因为进一步打高尔夫球会将其变成@Billywob的答案。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.