Validasikan plot batang dan daun

20

Sebuah batang dan daun petak menampilkan sekelompok nilai-nilai numerik dalam kelompok, yang ditentukan oleh semua tapi angka terakhir. Sebagai contoh, misalkan kita memiliki set data ini:

0, 2, 12, 13, 13, 15, 16, 20, 29, 43, 49, 101

Kami dapat menghasilkan plot batang dan daun ini:

0|02
1|23356
2|09
3|
4|39
5|
6|
7|
8|
9|
10|1

Batang baris pertama adalah 0, jadi "daunnya" - digit setelah |- mewakili nilai antara 0 inklusif dan 10 eksklusif. Daun pada setiap batang disortir. Batang tanpa daun (seperti 3) masih muncul di plot. Nilai 101 adalah antara 100 inklusif dan 110 eksklusif, jadi batangnya adalah 10 (100 dibagi 10).

Tantangan Anda adalah untuk memeriksa apakah sepotong teks adalah plot batang dan daun yang valid. Plot yang valid memenuhi aturan ini:

  • Memiliki tepat satu baris untuk setiap batang (yaitu kelompok 10-lebar) dalam rentang data (termasuk batang di tengah rentang tanpa daun)
  • Tidak memiliki batang di luar rentang
  • Semua daun disortir naik ke kanan
  • Semua batang diurutkan naik ke bawah
  • Hanya memiliki karakter numerik (selain pemisah |)

Anda tidak harus berurusan dengan angka yang memiliki bagian pecahan. Anda dapat menyetujui atau menolak angka nol di depan batang, tetapi batang kosong tidak diizinkan. Setidaknya akan ada satu nilai. Anda hanya dapat mengambil ruang ekstra setelah daun di setiap baris. Anda dapat mengasumsikan baris baru yang memimpin dan / atau tertinggal. Semua karakter akan dicetak ASCII.

Fungsi atau program Anda harus mengembalikan atau menampilkan (untuk menyaring atau keluaran standar) nilai kebenaran untuk plot yang valid, atau nilai palsu untuk plot yang tidak valid. Anda dapat mengambil input dari input standar, dari file, sebagai satu string besar, sebagai array string - apa pun yang paling nyaman.

Berikut adalah beberapa kasus uji yang merupakan plot yang valid (dipisahkan oleh garis kosong):

2|00003457
3|35
4|799
5|3

99|3
100|0556
101|
102|
103|8

0|0

Berikut adalah beberapa kasus uji yang plotnya tidak valid, dengan komentar di sebelah kanan:

|0               Blank stem

5|347            Missing a stem (6) in the range
7|9

4|               Has a stem (4) outside the range
5|26
6|7

11|432           Leaves aren't sorted correctly
12|9989

5|357            Stems aren't sorted correctly
4|002
6|1

4|5              Duplicate stem
4|6
4|6
5|1

51114            No stem and leaf separator
609

1|2|03           Multiple separators
2|779|

4|8abcdefg9      Invalid characters
5|1,2,3

75 | 4 6         Invalid characters (spaces)
76 | 2 8 8 9

Ini golf kode, jadi kode terpendek menang! Celah standar tidak diijinkan.

Ben N
sumber
3
Ini adalah tantangan pertama yang sangat bagus, pekerjaan yang luar biasa! :) Saya akan menambahkan test case tidak valid yang memiliki garis seperti 1|2|3di dalamnya.
Lynn
1
Tantangan pertama yang luar biasa!
AdmBorkBork
Tantangan pertama yang bagus. Satu test case yang mungkin bisa Anda tambahkan mirip dengan 4|;5|26;6|7yang memiliki batang pertama di luar kisaran, tetapi pada akhirnya, yaitu 12|3;13|4559;14|.
Kevin Cruijssen

Jawaban:

4

Perl, 47 byte

Termasuk +2 untuk -0p

Berikan masukan pada STDIN

stem.pl:

#!/usr/bin/perl -0p
$"="*";$_=/^((??{$_+$n++})\|@{[0..9,"
"]})+$/
Ton Hospel
sumber
Ini luar biasa ... Trik dengan $"itu sangat bagus!
Dada
2

Pip , 60 58 + 1 = 59 byte

Pertama menusuk pada masalah, mungkin bisa menggunakan lebih banyak golf. Menggunakan -rflag untuk membaca jalur input dari stdin. Output yang sebenarnya adalah 1, output yang salah adalah 0atau string kosong.

g=a+,#g&a@vNE'|NEg@v@v&$&{Y(a^'|1)a@`^\d+\|\d*$`&SNy=^y}Mg

Penjelasan dan test suite tertunda, tetapi sementara itu: Cobalah online!

DLosc
sumber
1

JavaScript, 189 byte

(x,y=x.split`
`.map(a=>a.split`|`),z=y.map(a=>a[0]))=>!(/[^0-9|\n]|^\|/m.exec(x)||/^\d+\|\n|\|$/.exec(x)||y.some((c,i,a)=>c.length!=2||c[1]!=[...c[1]].sort().join``)||z!=z.sort((a,b)=>a-b))

Solusi alternatif dengan panjang yang sama:

(x,y=x.split`
`.map(a=>a.split`|`),z=y.map(a=>a[0]))=>!(/[^0-9|\n]|^\||^.*\|.*\|.*$/m.exec(x)||/^\d+\|\n|\|$/.exec(x)||y.some((c,i,a)=>c[1]!=[...c[1]].sort().join``)||z!=z.sort((a,b)=>a-b))

Menentukan fungsi anonim yang mengambil input sebagai string multiline.

Saya yakin masih banyak yang bisa dilakukan dalam golf, jadi beri tahu saya jika Anda melihat kemungkinan peningkatan.

Penjelasan:

Fungsi memeriksa sejumlah hal buruk, dan jika ada yang benar, ia mengembalikan false (menggunakan OR logis dan TIDAK)

(x,y=x.split("\n").map(a=>a.split`|`),          //y is input in pairs of stem and leaves
z=y.map(a=>a[0]))                               //z is stems
=>                                              //defines function
!(                                              //logical not
/[^0-9|\n]|^\|/m.exec(x)                        //checks for invalid chars and blank stems
||/^\d+\|\n|\|$/.exec(x)                        //checks for stems out of range
||y.some((c,i,a)=>c.length!=2                   //checks for multiple |s in a line
||c[1]!=[...c[1]].sort().join``))               //checks if leaves are in wrong order
||z!=z.sort((a,b)=>a-b))                        //checks for stems in wrong order

Dalam solusi alternatif, memeriksa beberapa |s dalam satu garis dilakukan sebagai bagian dari regex pertama.

DanTheMan
sumber
Jika Anda menggunakan testalih-alih exec(Anda hampir selalu ingin menggunakan testjika Anda hanya membutuhkan hasil boolean`) maka Anda mungkin dapat menggunakan bitwise atau sebagai ganti dari logika atau.
Neil
Apakah ini benar-benar memeriksa duplikat atau batang yang hilang?
Neil
Anda bisa menghemat beberapa byte menggantikan y.some((c,i,a)=>...oleh y.some(c=>...karena idan atidak digunakan. Dan sepertinya z!=z.sort((a,b)=>a-b)tidak berfungsi itu bisa digantikan oleh''+z!=z.sort()
Hedi
1

Batch, 409 byte

echo off
set/pp=||exit/b1
set t=
set i=%p:|=&set t=%
if "%t%"=="" exit/b1
for /f "delims=0123456789" %%s in ("%i%")do exit/b1
:l
set t=-
set s=%p:|=&set t=%
if "%s%"=="" exit/b1
if not "%s%"=="%i%" exit/b1
set/ai+=1
for /f "delims=0123456789" %%s in ("%t%")do exit/b1
:m
if "%t:~1,1%"=="" goto n
if %t:~0,1% gtr %t:~1,1% exit/b1
set t=%t:~1%
goto m
:n
set/pp=&&goto l
if "%t%"=="" exit/b1

Mengambil input pada STDIN, tetapi keluar segera setelah melihat kesalahan.

Neil
sumber