Programme de damier triangulaire à auto-validation

10

Un programme en damier est un programme où la valeur ordinale de chaque caractère individuel alterne de pair à impair, à l'exclusion du terminateur de ligne (qui peut être n'importe quelle fin de ligne standard).

Un programme triangulaire est un programme dans lequel chaque ligne a un caractère supplémentaire que la ligne précédente, la première ligne ayant un caractère. Vous n'avez pas besoin de gérer une entrée vide.

Votre tâche consiste à créer un programme qui valide que l'entrée donnée respecte ces critères et génère / renvoie quelque chose de vrai si le programme répond aux critères, ou quelque chose de faux sinon.

Votre programme doit également répondre à ces critères.

Exemples de programmes valides

G
`e
@u^
5r{B

^
cB
+$C
VA01

Règles

  • Votre programme peut commencer par un octet impair ou pair tant que la parité des caractères alterne.
  • Votre programme doit valider les programmes qui commencent par un caractère impair ou pair.
  • Pour les caractères unicode, les valeurs d'octet sous-jacentes doivent avoir une parité alternée.
  • Vous pouvez supposer que l'entrée ne contient que des caractères imprimables. Si votre programme contient des non imprimables, il devrait toujours pouvoir se valider.
  • Votre programme peut inclure une nouvelle ligne de fin, cela n'a pas besoin d'être autorisé par votre validation car vous pouvez supposer que cela est supprimé avant la validation.
  • Les failles standard sont interdites.
  • Le code le plus court en octets, dans chaque langue, gagne.
Dom Hastings
la source
@MartinEnder Merci pour votre contribution! Espérons que cela soit maintenant clair. À ce sujet, aurais-je dû laisser cela dans le bac à sable plus longtemps?
Dom Hastings
1
l'alternance pair / impair est-elle à la fois horizontale et verticale? Je suppose que oui de "damier", mais je ne vois pas où vous le dites.
Ton Hospel
@DomHastings Une semaine semble bien. Si vous n'obtenez aucun commentaire après quelques jours, vous pouvez demander par chat si quelqu'un a d'autres commentaires.
Martin Ender
1
@TonHospel Mes exemples originaux ont fait cela, mais il contredites avec ma description, donc pour cette mise en œuvre, non, il devrait être: E\nOE\nOEO. J'espère que cela pourra aider!
Dom Hastings
2
Mon avis: laissez les réponses supposer que la saisie ne commence ni ne se termine par une nouvelle ligne.
Lynn

Réponses:

3

Stax , 26 octets

L
Y$
i:-
 {2%
*OFyF
%vi =*

Exécutez des cas de test en ligne

J'ai dû introduire 3 personnages indésirables. iest un no-op en dehors de toutes les constructions de boucle. est toujours un no-op. Oplace un 1 sous le haut de la pile, mais la valeur n'est pas utilisée dans le programme.

LY      move input lines into a list and store in Y register
$       flatten
i       no-op
:-      get pairwise differences
{2%*OF  foreach delta, mod by 2, and multiply, then tuck a 1 under the top of stack
yF      foreach line in original input do...
  %v    subtract 1 from length of line
  i=    is equal to iteration index?
  *     multiply

Exécutez celui-ci

récursif
la source
Hé, j'espère que cela ne dérange pas trop votre code, mais vous pouvez supprimer la validation de nouvelle ligne principale.
Dom Hastings
8

C (gcc), 189 octets

j
;l
;b;
d;f␉
(char
␉*␉t) 
{b=*␉t%
2;for␉(␉
j=d=0;j=j
+ 1,␉l=j+ 
1,␉*␉t; ) {
for␉(;l=l- 1
 ;t=t+ 1 )b= 
!b␉,␉d=d+ !(␉*
␉t␉*␉(␉*␉t- 10)
*␉(␉*␉t%2-b) ) ;
d␉|=*␉t- 10;t=t+ 
1 ; }b= !d; } ␉ ␉ 

Essayez-le en ligne!

représente un caractère de tabulation (je suis désolé). Notez qu'il y a plusieurs espaces / tabulations de fin (je suis plus désolé). L'original avec les onglets intacts est mieux visualisé avec :set tabstop=1(les mots ne peuvent exprimer à quel point je suis désolé).

C'est une fonction (appelée f, qui n'est pas immédiatement évidente en y regardant) qui prend une chaîne en argument et retourne soit 0ou 1.

Je pourrais réduire cela d'au moins une et probablement deux lignes ou plus, mais notez que cela devient de plus en plus compliqué et sans effort vers la fin, principalement parce que l'écriture d'un code aussi horrible (même selon les normes PPCG) me faisait me sentir comme une mauvaise personne et je voulais arrêter le plus tôt possible.

L'idée de base est d'éviter les constructions qui rompent nécessairement le format ( ++, +=, return, etc.). Miraculeusement, mots - clés importants comme for, charet while(que je n'ai pas fini à l' aide) arrive à adapter la règle de parité alternée. Ensuite, j'ai utilisé des espaces (parité paire) et des tabulations (parité impaire) comme rembourrage pour que le reste corresponde aux règles.

Poignée de porte
la source
1
Je ne m'attendais pas à voir une solution en C!
Dom Hastings
Si vous isolez la partie solution du programme dans le TIO en plaçant d'autres éléments dans les sections "En-tête" et "Pied de page", il est plus facile pour les gens de vérifier le nombre d'octets.
Jakob
4

Haskell , 1080 1033 octets

;
f=
 g 
ij=f
a =hi
hi = g
hij= ij
g ' ' =0
g '"' =0;
 g '$' =0;
 g '&' =0-0
g '(' =0-0-0
g '*' =0-0-0;
 g ',' =0-0-0;
 g '.' =0-0-0-0
g '0' =0-0-0-0-0
g '2' =0-0-0-0-0;
 g '4' =0-0-0-0-0;
 g '6' =0; g '8' =0
g ':' =0; g '<' =0-0
g '>' =0; g '@' =0-0;
 g 'B' =0; g 'D' =0-0;
 g 'F' =0; g 'H' =0-0-0
g 'J' =0; g 'L' =0-0-0-0
g 'N' =0; g 'P' =0-0-0-0;
 g 'R' =0; g 'T' =0-0-0-0;
 g 'V' =0; g 'X' =0-0-0-0-0
g 'Z' =0; g '^' =0; g '`' =0
g 'b' =0; g 'd' =0; g 'f' =0;
 g 'h' =0; g 'j' =0; g 'l' =0;
 g 'n' =0; g 'p' =0; g 'r' =0-0
g 't' =0; g 'v' =0; g 'x' =0-0-0
g 'z' =0; g '\92' =0-0; g '|' =0;
 g '~' =0; g y = 1 ;z=0; i(-0)z=z;
 i m('\10':y ) ="y"; ; ; ; ; ; ; ; 
i m(mnmnmnmnm:y ) = i(m - 1 ) y ; ; 
i k m ="y"; ; k i [ ] =01<1010101010;
 k m('\10':y ) = k(m + 1 )(i m y ) ; ;
 k m y =01>10; m o = k 1$'\10':o ; ; ; 
o i('\10':y ) = o i y ; ; ; ; ; ; ; ; ; 
o i(k:y )|g k<i = o(1 - i ) y ; ; ; ; ; ;
 o i(k:y )|g k>i = o(1 - i ) y ; ; ; ; ; ;
 o i [ ] =01<10; o i y =01>10;v=01>10101010
s y|o 1 y = m y|o(-0) y = m y ; s y =v; ; ; 

Essayez-le en ligne!

Explication

Cela a été une tâche très intéressante pour Haskell.

Parité

Pour commencer, nous avons besoin d'un moyen de déterminer si un caractère a un point de code pair ou impair. La façon normale de le faire est d'obtenir le point de code et de le modifier par 2. Cependant, comme vous le savez peut-être, obtenir le point de code d'un caractère nécessite une importation qui, en raison de la restriction de la source, signifie qu'il ne peut pas être utilisé. Un Haskeller plus expérimenté penserait à utiliser la récursivité. Charfont partie de la Enumclasse de type afin que nous puissions obtenir leurs prédécesseurs et successeurs. Cependant pred, ils succsont également inutilisables car ils n'alternent pas la parité des octets.

Donc, cela nous laisse assez coincés, nous ne pouvons pratiquement pas faire de manipulation avec les caractères. La solution est de tout coder en dur. Nous pouvons représenter (la plupart) même les caractères comme des littéraux, les probabilités avec lesquelles nous avons des problèmes parce qu'ils 'sont étranges, donc ils ne peuvent pas être à côté du caractère lui-même, ce qui rend le littéral impossible d'exprimer la plupart des caractères impairs. Nous codons donc en dur tous les octets pairs, puis ajoutons un catch all pour les octets impairs à la fin.

Les octets problématiques

Vous pouvez remarquer qu'il existe certains octets pairs pour lesquels des littéraux ne peuvent pas être créés en les encapsulant entre guillemets simples. Ce sont les non imprimables, les nouvelles lignes et \. Nous n'avons pas à nous soucier des non imprimables, tant que nous n'en utilisons aucun, nous n'avons pas besoin de le vérifier. En fait, nous pouvons toujours utiliser d'étranges non imprimables, comme tab, je n'en ai tout simplement pas besoin. Le retour à la ligne peut être ignoré car il sera de toute façon supprimé du programme. (Nous pourrions inclure la nouvelle ligne, car son point de code est plutôt pratique, mais nous n'en avons pas besoin). Cela laisse \, a maintenant \le point de code 92, qui est commodément un nombre impair suivi d'un nombre pair, \92alterne donc entre les evens et les cotes donc le littéral'\92'est parfaitement valable. Plus tard, lorsque nous aurons besoin de représenter une nouvelle ligne, nous remarquerons qu'elle a heureusement cette même propriété '\10'.

Problèmes d'espacement

Maintenant, pour commencer à écrire du code réel, nous devons pouvoir mettre un nombre important de caractères sur une seule ligne. Pour ce faire, j'ai écrit la casquette:

;
f=
 g 
ij=f
a =hi
hi = g
hij= ij

La casquette ne fait rien d'autre que d'être Haskell valide. J'avais initialement espéré faire des définitions qui nous aideraient dans le code plus tard, mais ce n'est pas le cas. Il existe également des moyens plus simples de créer un plafond, par exemple des espaces et des points-virgules, mais ils n'économisent pas d'octets de cette manière, je n'ai donc pas pris la peine de le modifier.

Hardcoder

Alors maintenant que j'ai assez d'espace sur une ligne, je commence à coder en dur les valeurs. C'est surtout assez ennuyeux, mais il y a quelques choses intéressantes. Pour une fois que les lignes commencent à devenir encore plus longues, nous pouvons utiliser ;pour mettre plusieurs déclarations sur une ligne, ce qui nous permet d'économiser une tonne d'octets.

La seconde est que, comme nous ne pouvons pas toujours commencer une ligne avec un de gtemps en temps, nous devons indenter un peu les lignes. Maintenant, Haskell se soucie vraiment de l'indentation, donc il s'en plaindra. Cependant, si la dernière ligne avant la ligne en retrait se termine par un point-virgule, cela sera autorisé. Pourquoi? Je n'ai pas le moindre, mais ça marche. Il suffit donc de se rappeler de mettre les points-virgules à la fin des lignes.

Blocs fonctionnels

Une fois le hardcoder terminé, la navigation se fait en douceur jusqu'à la fin du programme. Nous devons construire quelques fonctions simples. Je construis d'abord une version de drop, appelée i. iest différent de ce dropque si nous essayons de passer au-delà de la fin de la chaîne, il retourne simplement "y". iest différent de drop également en ce que s'il tente de supprimer une nouvelle ligne, il reviendra "y", ceux-ci seront utiles car plus tard, lorsque nous vérifierons que le programme est un triangle, cela nous permettra de revenir Falselorsque la dernière ligne n'est pas terminée, ou lorsque une ligne se termine tôt.

Ensuite, nous avons kqui vérifie en fait qu'une chaîne est triangulaire. kest assez simple, il faut un nombre et une chaîne . Si est vide, il revient . Si la chaîne commence par une nouvelle ligne, elle supprime la nouvelle ligne et caractères du premier plan. Il rappelle ensuite avec et la nouvelle chaîne. Si la chaîne ne commence pas par une nouvelle ligne, elle retourne .s s n n + 1nssTruenkn+1False

Nous faisons ensuite un alias pour k, m. mest juste kavec 1dans le premier argument, et une nouvelle ligne est ajoutée au second argument.

Ensuite, nous avons o. oprend un nombre et une chaîne. Il détermine si les octets de chaîne (ignorant les nouvelles lignes) alternent en parité (en utilisant notre g) en commençant par le numéro d'entrée.

Enfin, nous avons squi fonctionne oavec les deux 1et 0, si l'un ou l'autre réussit, il s'en remet m. S'il échoue, il revient simplement False. C'est la fonction que nous voulons. Il détermine que l'entrée est triangulaire et alternée.

Ad Hoc Garf Hunter
la source
1
Une chaîne triangulaire commence par une ligne à 1 caractère, pas une ligne vide.
Jakob
@Jakob Je pense que c'est stupide mais c'était une solution assez facile.
Ad Hoc Garf Hunter
3

05AB1E , 34 26 octets

¶
¡D
©€g
´ā´Q
´sJÇÈ
¥Ä{´нP

Essayez-le en ligne!

Prend l'entrée comme une chaîne multiligne (entrée entre "" " ). Explications à venir plus tard.

Kaldo
la source
1
Sauf si j'ai mal compris les règles, le programme doit également pouvoir valider la saisie en commençant par une nouvelle ligne.
Emigna
@Emigna Je pense que votre programme ne doit pouvoir valider une nouvelle ligne principale que s'il commence lui-même par une nouvelle ligne principale.
Ton Hospel
Je n'ai aucune idée si c'est correct (je suis horrible à lire les spécifications): Essayez-le en ligne!
Urne de poulpe magique
@MagicOctopusUrn Votre réponse me semble correcte mais je me pose des questions sur l'entrée: sommes-nous autorisés à la prendre comme un tableau? Dans votre lien, votre première entrée est un espace vide, pas un caractère de nouvelle ligne.
Kaldo
1
Hé, j'espère que cela ne dérange pas trop votre code, mais vous pouvez supprimer la validation de nouvelle ligne principale.
Dom Hastings
1

Java 10, 209 octets

Un lambda vide prenant un itérable ou un tableau de byte. Indique vrai en retournant normalement, faux en lançant une exception d'exécution. Le programme s'attend à ce que la dernière ligne soit correctement terminée, c'est-à-dire se termine par un caractère de nouvelle ligne. La dernière ligne du programme est également terminée.

Tout est fait sous UTF-8, avec l'interprétation que "caractère" fait référence aux points de code Unicode.

Les tabulations sont remplacées par des espaces dans cette vue.

d
->
{  
long
f= 1,
 h=0 ,
c = - 1
,e ;for 
( byte a:
 d) {var b
=(e = a^10)
<1&e>- 1 ;f=
b?( h ^ f)> 0
?0/0 : f+ 1: f
;h=b?0 :a>-65 ?
h+ 1: h; c =b? c
:c>=0 & ( (c^a )&
1 )<1 ?0/0 :a ; } 
/*1010101010101*/ }

Essayez-le en ligne

Vidage hexadécimal

Revenez avec xxd -p -rsur Unix.

640a2d3e0a7b20090a6c6f6e670a663d20312c0a09683d30092c0a63203d
202d20310a2c65203b666f72090a28096279746520613a0a096429207b76
617209620a3d2865203d20615e3130290a3c3126653e2d2031203b663d0a
623f280968095e0966293e09300a3f302f30093a09662b20313a09660a3b
683d623f30093a613e2d3635203f0a682b20313a09683b2063203d623f20
630a3a633e3d30092609280928635e612029260a3120293c31203f302f30
093a61203b207d200a2f2a313031303130313031303130312a2f207d0a

Non golfé

d -> {
    long f = 1, h = 0, c = ~h, e;
    for (byte a : d) {
        var b = (e = a^10) < 1 & e > -1;
        f = b ?
            (h^f) > 0 ? 0/0 : f + 1
            : f
        ;
        h = b ? 0 :
            a > -65 ? h + 1 : h
        ;
        c = b ? c :
            c >= 0 & ((c^a) & 1) < 1 ? 0/0 : a
        ;
    }
}

fest le nombre attendu de caractères sur la ligne en cours, hest le nombre de caractères vus jusqu'à présent sur la ligne en cours, cest le dernier octet vu, et best de savoir si aest la nouvelle ligne.

La condition a > -65teste s'il as'agit du premier octet d'un caractère. Cela fonctionne parce que les caractères à un octet (ASCII) ne sont pas négatifs dans le complément à deux de 8 bits, le premier octet des caractères plus longs a une forme binaire 11xxxxxx(au moins -64 dans le complément à deux) et les octets non en tête de ces caractères sont de la forme 10xxxxxx, au plus -65 en complément à deux. ( Source )

Lorsqu'un personnage viole le motif triangulaire ou en damier (c'est-à-dire qu'un saut de ligne apparaît tôt ou tard ou qu'un octet de mauvaise parité apparaît), la branche gauche du ternaire correspondant (en affectation à fou c) s'active et la méthode lève une exception arithmétique.

Jakob
la source
0

Python 3 (3,4?), 350 octets

Un défi délicat pour un langage aussi particulier sur les espaces blancs que Python 3. La soumission s'imprime 0ou 1à la sortie standard et plante pour certaines entrées. Le programme s'attend à ce que la dernière ligne soit correctement terminée, c'est-à-dire se termine par un caractère de nouvelle ligne. La dernière ligne du programme est également terminée. UTF-8 est utilisé pour vérifier la parité des octets.

Les tabulations sont remplacées par des espaces dans cette vue.

0
i\
= 1
t=(#
 '0'*
 0) ;(
g,) =(#
 open (1
, "w"),) 
k = eval (
'p' + 'rin'
 + 't' ) #01
for  a in (#0
open ( 0) ):#0
#01010101010101
 a = a [:- 1 ] #
 if ( len (a )<i\
or len (a )>i ):[\
k('0' ),1 /0] #0101
 i, t= -~i, t+ a #01
(k( 2-len ({(c^i )&1\
 for  i,c in  eval (#0
 "enu"+"m"+"erate")(#01
 eval ( " byte"+"s")( t#
,' u8' ) ) } ) ) ) #01010

Fonctionne pour moi avec Python 3.4.2; ne fonctionne sur aucun Python 3 sur TIO. Il me semble que c'est un bug dans les interprètes de TIO.

Vidage hexadécimal

Revenez avec xxd -p -rsur Unix.

300a695c0a3d20310a743d28230a202730272a0a093029203b280a672c29
203d28230a206f70656e0928310a2c09227722292c29200a6b203d206576
616c09280a277027202b202772696e270a202b202774272029202330310a
666f7209206120696e092823300a6f70656e092809302920293a23300a23
30313031303130313031303130310a2061203d2061205b3a2d2031205d20
230a2069660928096c656e09286120293c695c0a6f72096c656e09286120
293e6920293a5b5c0a6b2827302720292c31202f305d2023303130310a20
692c09743d202d7e692c09742b2061202330310a286b2809322d6c656e09
287b28635e69202926315c0a09666f720920692c6320696e09206576616c
092823300a0922656e75222b226d222b2265726174652229282330310a20
6576616c092809220962797465222b22732229280974230a2c2720753827
20292029207d202920292029202330313031300a
Jakob
la source