Tulis detektor haiku-w

41

Sebuah haiku adalah puisi dengan tiga baris, dengan 5/7/5 suku kata hitungan, masing-masing.

Sebuah haiku-w adalah puisi dengan tiga baris, dengan 5/7/5 kata hitungan, masing-masing.

Tantangan

Tulis program yang akan mengembalikan true jika inputnya adalah haiku-w, dan false jika tidak.

Input haiku-w yang valid harus terdiri dari 3 baris, dipisahkan oleh baris baru.

  • Baris 1 harus terdiri dari 5 kata, setiap kata dipisahkan oleh spasi.
  • Baris 2 harus terdiri dari 7 kata, setiap kata dipisahkan oleh spasi.
  • Baris 3 harus terdiri dari 5 kata, setiap kata dipisahkan oleh spasi.

Contohnya

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

Hasil: Benar

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

Hasil: Salah


Aturan

  • Ini adalah , jadi jawaban tersingkat dalam byte menang.
  • Lubang kode standar golf berlaku. Kecurangan dilarang.
  • Nilai pengembalian boolean lainnya, seperti 1dan 0, dapat diterima.
  • Daftar panjang-3 string sebagai input juga dapat diterima.
  • Input haiku-w yang valid seharusnya tidak memiliki spasi di depan atau di belakang, atau beberapa spasi yang memisahkan kata.
DomTheDeveloper
sumber
1
Akankah haiku-w selalu mengandung 3 baris?
Kritixi Lithos
1
Iya nih. Jika input berisi lebih dari atau kurang dari 3 baris, program harus mengembalikan false .
DomTheDeveloper
5
Apakah akan ada ruang terdepan atau tertinggal di jalur mana pun? Atau beberapa spasi memisahkan kata?
Greg Martin
8
Omong-omong, klarifikasi seperti ini adalah alasan utama untuk mengirim pertanyaan yang diajukan di Sandbox terlebih dahulu. :)
Greg Martin
11
Poin bonus untuk pengiriman di mana kode itu sendiri adalah haiku-w.
Glorfindel

Jawaban:

25

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

Terima kasih kepada Neil untuk menghemat 13 byte

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

Penjelasan

Ini adalah fungsi panah gemuk yang mengambil array string sebagai argumen. Ini menggantikan setiap baris dengan jumlah kata-katanya. Jika itu haiku-w, asekarang berisi array dari lima, tujuh dan lima lagi. Karena JavaScript tidak memungkinkan kami untuk membandingkan 2 array pada saat yang sama, array dikonversi menjadi string terlebih dahulu, dan kemudian dibandingkan. Ini menghasilkan boolean yang dikembalikan.

Luke
sumber
1
%dan *memiliki prioritas yang sama, jadi Anda tidak perlu ()s, meskipun saya pikir (d*2|5)mungkin juga berfungsi. Anda juga bisa lolos dengan satu &, meskipun saya pikir Anda dapat meningkatkan bahkan dengan menggunakan (b...).length==3>b.some(...length-...).
Neil
Terima kasih atas tipnya tentang tanda kurung. Juga, saya mengubah pendekatan saya, jadi saya tidak secara eksplisit memeriksa panjang lagi.
Luke
1
Ah, kalau begitu, jangan repot-repot dengan perhitungan, gunakan saja a=>a.map(c=>c.split .length)=='5,7,5'.
Neil
Hehe, kamu benar. Aku seharusnya memikirkan itu ...
Luke
Anda masih tidak memerlukan +''- ==stringify jika argumen lain adalah string.
Neil
12

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

Golf

517253==$0=q=q NF NR

Akan menampilkan "517253" untuk True , dan string kosong untuk False .

Dalam awk, nilai numerik bukan nol atau nilai string apa pun tidak benar. Nilai lain apa pun (nol atau string nol, "") salah

Panduan Pengguna Awk GNU

Bagaimana itu bekerja

Setiap pernyataan awk (aturan) terdiri dari pola (atau ekspresi) dengan tindakan terkait:

pattern {action}

Awk akan membaca input baris demi baris (record by record) dan mengevaluasi ekspresi pola untuk melihat apakah tindakan yang sesuai akan dipanggil.

Kode di atas adalah ekspresi awk mandiri (pola) tanpa blok tindakan, yang tersirat {print $0}dalam kasus tersebut.

Itu harus dibaca dari kanan ke kiri:

q=q NF NR

Tambah sebuah N Banyaknya F ields (kata) dan N Banyaknya R ecords (yaitu nomor baris saat ini), untuk variabel q .

Dengan cara ini, saat memproses Haiku-w yang tepat, q akan diatur ke:

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

$0=q

Tetapkan nilai q yang baru dihitung menjadi $ 0 (yang menyimpan seluruh baris / catatan saat ini secara default).

517253==$0

Bandingkan dengan "tanda tangan" untuk Haiku-w (517253) yang tepat, jika ada kecocokan, seluruh ekspresi dievaluasi menjadi "benar" dan tindakan yang sesuai (implisit print $0) dijalankan, mengirimkan "517253" ke stdout (Benar) , jika tidak, output akan kosong (Salah).

Perhatikan bahwa ini akan mengenali Haiku-w dengan benar, bahkan jika itu diikuti oleh jumlah saluran sampah yang sewenang-wenang, tetapi saya yakin itu tidak masalah, seperti:

Daftar panjang-3 string sebagai input juga dapat diterima.

(yaitu kita dapat mengasumsikan input panjangnya 3 baris)

Uji

>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

Cobalah secara Online!

zeppelin
sumber
2
Ini gagal jika input terdiri dari satu baris yang berisi 575 kata, atau dua baris yang berisi 57 dan 5 kata, dll.
Lynn
@ Lynn, benar, menunda, sampai ini diperbaiki.
zeppelin
@ Lynn, harus diperbaiki sekarang
zeppelin
1
Memperbaiki sangat pintar! :)
Lynn
9

Python , 42 byte

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

Cobalah online!

Mengambil input sebagai daftar baris, dengan kata-kata dipisahkan oleh spasi tunggal.

Karena kami dijamin tidak akan ada spasi awal atau spasi, dan hanya spasi tunggal yang akan memisahkan setiap kata, kami dapat memverifikasi w-haiku dengan hanya menghitung spasi di setiap baris.

Kami melakukan ini dalam pemahaman daftar, untuk membuat daftar penghitungan ruang. Jika itu haiku yang benar, itu akan terlihat seperti [4, 6, 4], jadi kami membandingkannya dengan ini dan mengembalikan hasilnya.

FlipTack
sumber
Jika Anda baik-baik saja dengan mendukung hanya Python 2, Anda dapat menyimpan dua byte: map(str.count,l,' ').
vaultah
8

Jelly , 10 9 byte

ċ€⁶⁼“¥©¥‘

Cobalah online!

Penjelasan

ċ€⁶⁼“¥©¥‘  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
mil
sumber
Juga ċ€⁶⁼4,6,4dan ċ€⁶⁼464D¤... Saya tidak dapat menemukan sesuatu yang lebih pendek. (Oh, Anda dapat flip itu, juga: 464D⁼ċ€⁶$)
Lynn
ċ€⁶Ḍ=464berfungsi dengan baik untuk 8.
Jonathan Allan
Sebenarnya, tidak itu tidak , maaf.
Jonathan Allan
7

Batch, 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%

Keluar dengan tingkat kesalahan non-nol segera setelah membaca baris dengan jumlah kata yang salah.

Neil
sumber
1
...... well crap
tbodt
7

Mathematica, 21 byte

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

Fungsi tanpa nama mengambil daftar daftar karakter sebagai input dan pengembalian Trueatau False. Cukup hitung berapa banyak ruang di setiap daftar karakter, yang di bawah aturan tantangan berkorelasi sempurna dengan jumlah kata di setiap baris.

Pengajuan sebelumnya:

Mathematica, 31 byte

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

Fungsi tanpa nama mengambil daftar string sebagai input dan kembali Trueatau False.

Greg Martin
sumber
6

Haskell, 34 33 byte

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

Cobalah online! .

Sunting: terima kasih kepada @xnor untuk satu byte!

nimi
sumber
Yg pd waktunya lebih pendek: f l=[sum[1|' '<-c]|c<-l]==[4,6,4].
xnor
6

Retina , 12 byte

M%` 
^4¶6¶4$

(Ada spasi tambahan setelah baris pertama)

Cobalah online!

  • M%`  - Hitung jumlah spasi di setiap baris.

    • M - Mode Kecocokan - mencetak jumlah kecocokan.
    • % - untuk setiap baris
    • ` - Pisahkan konfigurasi dan pola regex
    • - hanya sebuah ruang.
  • ^4¶6¶4$ - Harus ada 4, 6, dan 4 spasi, dan tepat tiga garis.

    • cocok dengan baris baru. Selebihnya adalah ekspresi reguler yang sederhana.

Mencetak 1untuk input yang valid, 0untuk yang tidak valid.

Kobi
sumber
4

Python, 58 44 byte

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

-14 oleh tbodt

sagiksp
sumber
Anda diizinkan mengambil input sebagai daftar panjang string 3. Anda dapat menyimpan byte yang dihabiskan menggunakan split("\n").
mil
44 byte:lambda h:[len(l.split())for l in h]==[5,7,5]
tbodt
Seseorang membuat ini lebih pendek untuk mencapai dicoret 44
Charlie
4

Perl , 26 byte

24 byte kode + 2 byte untuk -apflag.

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

Cobalah online!

Dada
sumber
4

Pyth, 9 byte

qj464T/R;

Program yang mengambil input dari daftar "quoted strings"dan hasil cetak Trueatau Falsesesuai kebutuhan.

Suite uji

Bagaimana itu bekerja

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
sumber
4

Japt , 11 byte

Banyak byte yang disimpan berkat @ETHproductions

Ini mengambil array tiga string sebagai input.

®¸lÃ¥"5,7,5

Jalankan secara online!

Oliver
sumber
4

PowerShell , 43 byte

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

Cobalah online!

Penjelasan

Mengambil input sebagai string yang dipisahkan baris baru.

Hapus semua non-spasi putih, lalu periksa untuk melihat bahwa itu cocok dengan "4 spasi, baris baru, 6 spasi, baris baru, 4 spasi baris baru" persis, menggunakan regex.

Grup tangkapan cocok dengan 4 spasi, referensi kembali \1mengacu pada itu. Baris baru disematkan dalam string. Perhatikan bahwa baris kedua regex berisi dua spasi setelah referensi balik.

briantis
sumber
1
Itu adalah pendekatan yang menarik!
Ismael Miguel
4

Pyke, 11 9 byte

dL/uq

Coba di sini!

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

Setelah ubyte ada byte berikut:0x03 0x04 0x06 0x04

Biru
sumber
3

J, 12 byte

4 6 4=#@;:@>

Input adalah daftar string dalam kotak.

Penjelasan

Ini adalah garpu dengan tine kiri konstan. Ini memeriksa hasil dari tine yang tepat #@;:@>,, untuk kesetaraan dengan 4 6 4. Waktu yang tepat menghapus kotak masing-masing ( >), lalu ( @) mengubah setiap string menjadi kata-kata ( ;:), lalu ( @) membutuhkan panjang masing-masing ( #).

Conor O'Brien
sumber
3

R, 48 byte

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

Membaca vektor karakter 3-panjang dari stdin dan bekerja dengan menghitung jumlah spasi. Untuk menghitung jumlah spasi, kami menggunakan str_countdari stringrpaket yang dapat menghitung kejadian berdasarkan pola regex.

Pendekatan alternatif tanpa menggunakan paket bisa berupa:

all(sapply(scan(,""),function(x)length(el(strsplit(x," "))))==c(5,7,5))
Billywob
sumber
Pertama kali saya pernah melihat elsebelumnya, terima kasih untuk itu.
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);}

Versi tidak disatukan:

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

Mengembalikan 1 untuk 5/7/5 urutan yang lain 0.

Testcase positif:

masukkan deskripsi gambar di sini

Abel Tom
sumber
3

C ++, 357 byte

Agak baru untuk kode golf, tetapi ini adalah yang terbaik yang bisa saya lakukan dengan cepat

#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
sumber
4
Selamat datang di PPCG! Tujuan dari kode golf adalah membuat kode Anda sesingkat mungkin; langkah pertama yang baik adalah menghapus semua spasi yang tidak perlu.
ETHproductions
3

Ruby 1.9.3

Bukan golf, tapi itu sendiri haiku-w

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

atau...

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

Sayangnya tidak berfungsi dengan memimpin spasi putih pada baris apa pun, tetapi mengatasi trailing.

ymbirtt
sumber
2

Python 2 , 57 64 byte

Sunting Diperbaiki dengan penambahan 7 byte setelah umpan balik dari @Dada. Terima kasih!

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

Cobalah online!

Bukan jawaban Python terpendek dengan cara panjang tetapi hanya ingin menggunakan trik baru yang saya pelajari baru-baru ini untuk menggunakan input()output dan menyimpan printpernyataan. Mengambil daftar garis sebagai input. Membutuhkan Ctrl C (atau tombol-tekan lainnya dalam hal ini) untuk mengakhiri program (dengan pengecualian) di terminal tetapi berfungsi dengan baik tanpa di TIO.

ElPedro
sumber
4
Ini akan gagal dalam kasus seperti ini .
Dada
Aku akan memberimu @Dada itu. Itu adalah satu ujian berat :)
ElPedro
Diperbaiki dan diuji dengan test case Anda.
ElPedro
2

MATL, 16 byte

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

Input adalah array sel string dan mengembalikan array yang benar atau salah .

Cobalah secara Online

Penjelasan

        % 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
sumber
2

MATLAB / Oktaf, 38 byte

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

Solusi ini menerima array sel string sebagai input, menghitung jumlah spasi di setiap baris dan kemudian membandingkan hasilnya dengan array [4 6 4]dan menghasilkan array yang benar (semua nilai adalah 1) atau falsey (nilai apa pun adalah nol).

Demo online

Suever
sumber
2

Perl 6 , 25 byte

{.lines».words~~(5,7,5)}
seseorang
sumber
2

Clojure, 44 byte

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

Input adalah daftar string. Fungsi hanya menemukan spasi dan menghitungnya. Penjelasan ini adalah Haiku. :)

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

Persyaratan program dan potensi memiliki kurang dari tiga baris, tidak terlalu menyebutkan verbositas Java itu sendiri, menyebabkan kode 'golf' ini menjadi cukup besar ..

Tidak Disatukan:

Coba di sini.

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
sumber
2

SimpleTemplate, 77 byte

Sayangnya, pendekatan ekspresi reguler adalah yang terpendek.

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

Mengharuskan teks diberikan sebagai argumen pertama, dengan baris baru * NIX-style. Ini tidak akan berfungsi dengan baris baru bergaya Windows.

Tidak Disatukan:

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

Berbasis non-regex, 114 bye

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

Ini mengharuskan setiap baris diberikan sebagai argumen ke fungsi.

Tidak Disatukan:

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

Ditumpuk, 22 byte

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

Mengambil input dari atas tumpukan sebagai daftar string karakter, seperti:

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

Penjelasan

[' '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
sumber
2

Java (OpenJDK) , 82 byte

-2 byte terima kasih kepada @ corvus_192!

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

Cobalah online!

Ini terlihat sangat golf tetapi tanpa fungsi peta bawaan , saya tidak dapat menemukan cara yang baik. Iterasi melalui array beberapa byte lebih lama, seperti menulis fungsi peta menggunakan stream.

Ekspresi Lambda mengambil array dari Strings dan mengembalikan Boolean.

Pavel
sumber
Bagaimana jika Anda hanya memiliki dua baris sebagai input, atau empat?
Kevin Cruijssen
@KevinCruijssen menurut op, "Daftar panjang-3 string sebagai input juga dapat diterima". Program saya membutuhkan daftar panjang 3 baris.
Pavel
Anda bisa mendapatkan fungsi peta jika Anda menelepon Arrays.stream, tapi itu cukup lama sehingga mungkin tidak layak digunakan (terutama jika Anda perlu mengimpor Arrays)
Pokechu22
@ Pokechu22 ya saya mencobanya, masih berakhir lebih lama.
Pavel
Anda dapat menggunakan &alih-alih &&menyimpan dua 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
12Me21
sumber
1

R, 100 byte

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

Dibawa sebagai argumen, daftar panjang-3 string. Mungkin tidak akan bermain golf lebih jauh karena bermain golf lebih jauh menjadi jawaban @ Billywob.

BLT
sumber