Valider un tracé tige-feuille

20

Un tracé de tige et de feuille affiche un groupe de valeurs numériques en groupes, qui sont déterminées par tous sauf le dernier chiffre. Par exemple, supposons que nous ayons cet ensemble de données:

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

Nous pourrions produire ce tracé de tige et de feuille:

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

La tige de la première ligne est 0, donc ses "feuilles" - les chiffres après le |- représentent les valeurs comprises entre 0 inclus et 10 exclus. Les feuilles sur chaque tige sont triées. Des tiges sans feuilles (comme 3) apparaissent toujours dans l'intrigue. La valeur de 101 se situe entre 100 inclus et 110 exclus, donc sa tige est 10 (100 divisé par 10).

Votre défi consiste à vérifier si un morceau de texte est un tracé de tige et de feuille valide. Un tracé valide satisfait ces règles:

  • A exactement une ligne pour chaque tige (c.-à-d. Groupe de 10 larges) dans la plage des données (y compris les tiges au milieu de la plage sans feuilles)
  • N'a pas de tiges en dehors de la plage
  • Toutes les feuilles sont triées par ordre croissant vers la droite
  • Toutes les tiges sont triées en ordre croissant
  • N'a que des caractères numériques (en plus du séparateur |)

Vous n'êtes pas obligé de traiter des nombres qui ont des parties fractionnaires. Vous pouvez approuver ou rejeter des zéros non significatifs supplémentaires dans les tiges, mais une tige vide n'est pas autorisée. Il y aura au moins une valeur. Vous ne pouvez accepter que des espaces supplémentaires après les feuilles de chaque ligne. Vous pouvez supposer une nouvelle ligne de début et / ou de fin. Tous les caractères seront imprimables en ASCII.

Votre fonction ou programme doit retourner ou afficher (à l'écran ou la sortie standard) une valeur véridique pour un tracé valide, ou une valeur falsifiée pour un tracé invalide. Vous pouvez prendre l'entrée de l'entrée standard, d'un fichier, comme une grande chaîne, comme un tableau de chaînes - ce qui est le plus pratique.

Voici quelques cas de test qui sont des tracés valides (séparés par des lignes vides):

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

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

0|0

Voici quelques cas de test qui sont des tracés invalides, avec des commentaires à droite:

|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

C'est le golf de code, donc le code le plus court gagne! Les failles standard ne sont pas autorisées.

Ben N
la source
3
C'est un très beau premier défi, un travail génial! :) J'ajouterais un cas de test invalide qui a une ligne comme 1|2|3dedans.
Lynn
1
Excellent premier défi!
AdmBorkBork
Beau premier défi. Un cas de test que vous pourriez peut-être ajouter est similaire à celui 4|;5|26;6|7qui a la première tige en dehors de la plage, mais à la fin, c'est-à-dire 12|3;13|4559;14|.
Kevin Cruijssen

Réponses:

4

Perl, 47 octets

Comprend +2 pour -0p

Donnez votre avis sur STDIN

stem.pl:

#!/usr/bin/perl -0p
$"="*";$_=/^((??{$_+$n++})\|@{[0..9,"
"]})+$/
Ton Hospel
la source
C'est génial ... Ce truc avec $"est très sympa!
Dada
2

Pip , 60 58 + 1 = 59 octets

Premier coup au problème, pourrait probablement utiliser plus de golf. Utilise l' -rindicateur pour lire les lignes d'entrée de stdin. La sortie est 1vraie, la sortie fausse est 0ou une chaîne vide.

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

Explication et suite de tests en attente, mais en attendant: Essayez-le en ligne!

DLosc
la source
1

JavaScript, 189 octets

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

Solution alternative de même longueur:

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

Définit une fonction anonyme qui prend l'entrée comme une chaîne multiligne.

Je suis sûr qu'il y a plus au golf, alors faites-moi savoir si vous voyez des améliorations possibles.

Explication:

La fonction vérifie un certain nombre de mauvaises choses, et si certaines d'entre elles sont vraies, elle retourne false (en utilisant des OU logiques et un NON)

(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

Dans la solution alternative, la vérification de plusieurs |s dans une ligne se fait à la place dans le premier regex.

DanTheMan
la source
Si vous utilisez testau lieu de exec(vous voulez presque toujours utiliser testsi vous n'avez besoin que d'un résultat booléen`), vous pouvez probablement utiliser bitwise ou au lieu de logique ou.
Neil
Cela vérifie-t-il réellement les tiges en double ou manquantes?
Neil
Vous pouvez enregistrer certains octets en les remplaçant y.some((c,i,a)=>...par y.some(c=>...since iet ane les utilisez pas. Et il semble que z!=z.sort((a,b)=>a-b)cela ne fonctionne pas, il pourrait être remplacé par''+z!=z.sort()
Hedi
1

Lot, 409 octets

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

Prend une entrée sur STDIN, mais se ferme dès qu'il voit une erreur.

Neil
la source