验证茎叶图


20

茎叶情节显示在组一串数值的,这是由所有,但最后一位决定。例如,假设我们有以下数据集:

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

我们可以生成此茎叶图:

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

第一行的主干为0,因此其“叶子”(位于-之后的数字)|代表0(含0)和10(不含)之间的值。每个茎上的叶子都经过分类。没有叶子的茎(如3)仍出现在图中。101的值在100包含和110之间,因此它的词干为10(100除以10)。

您面临的挑战是检查一段文字是否是有效的茎叶图。有效地块满足以下规则:

  • 数据范围内的每个茎(即10个宽的组)正好有一行(包括中间没有叶子的茎)
  • 没有茎超出范围
  • 所有叶子按升序排列
  • 所有茎都按升序排列
  • 仅包含数字字符(除分隔符外|

您不必处理具有小数部分的数字。您可以批准或拒绝词干中多余的前导零,但不允许使用空白词干。至少会有一个值。您只能在每行的叶子后面假设多余的空格。您可以假设前导和/或尾随换行符。所有字符均为可打印ASCII。

您的函数或程序应返回或输出(到屏幕或标准输出)有效绘图的真实值,或无效绘图的错误值。您可以将标准输入,文件中的输入当作一个大字符串,作为一个字符串数组-最为方便。

以下是一些有效的测试用例(用空行分隔):

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

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

0|0

这是一些无效的测试用例,在右边有注释:

|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

这是代码高尔夫球,所以最短的代码获胜!不允许出现标准漏洞。


3
这是一个非常不错的第一个挑战,非常棒的工作!:)我将添加一个无效的测试用例,其中包含这样的一行1|2|3
林恩

1
出色的第一个挑战!
AdmBorkBork

不错的第一个挑战。您可能要添加的一个测试用例4|;5|26;6|7与第一个词干超出范围但在结尾处(即)相似12|3;13|4559;14|
凯文·克鲁伊森

Answers:


4

Perl,47个字节

包括+2 -0p

在STDIN上输入

stem.pl

#!/usr/bin/perl -0p
$"="*";$_=/^((??{$_+$n++})\|@{[0..9,"
"]})+$/

$"太棒了...这个招很不错!
达达

2

点子60 58 +1 = 59字节

首先刺入这个问题,可能会使用更多的高尔夫球。使用该-r标志从stdin读取输入行。真实的输出是1,错误的输出为0或为空字符串。

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

说明和测试套件正在等待中,但与此同时:在线试用!


1

JavaScript,189字节

(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))

等长替代解决方案:

(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))

定义一个匿名函数,该函数将输入作为多行字符串。

我敢肯定高尔夫还有更多东西,所以如果您看到任何可能的改进,请告诉我。

说明:

该函数检查许多不良情况,如果其中任何一项为true,则返回false(使用逻辑OR和NOT)

(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

在替代解决方案中,|作为第一个正则表达式的一部分来检查一行中是否存在多个。


如果您使用test而不是exectest如果只需要布尔结果,几乎总是想使用),那么您可以使用按位或而不是逻辑或。
尼尔

这实际上检查重复或缺失的词干吗?
尼尔

你可以节省一些字节替换y.some((c,i,a)=>...y.some(c=>...,因为ia没有被使用。似乎z!=z.sort((a,b)=>a-b)不起作用,可以用''+z!=z.sort()
Hedi

1

批次,409个字节

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

在STDIN上接受输入,但是一旦看到错误就退出。

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.