introduction
Ce défi est inspiré de Grime , mon langage de correspondance de motifs 2D. Fondamentalement, vous disposez d'une "grammaire" qui décrit les grilles de caractères bidimensionnelles, et votre travail consiste à générer une grille en fonction de la grammaire. De plus, la grille doit être aussi petite que possible dans un certain sens faible.
Contribution
Votre entrée est une chaîne contenant des caractères ASCII minuscules et les symboles |
et -
. Par souci de simplicité, l'entrée ne contient pas de caractères minuscules répétés. La chaîne est une spécification pour une classe de grilles rectangulaires de caractères, et elle est analysée de gauche à droite en utilisant une pile comme suit.
- Étant donné un caractère en minuscule
c
, poussez dans la pile unem×n
grille du caractèrec
, pour toutm, n ≥ 1
. - Étant donné un tuyau
|
, faites éclater deux grillesA
etB
de la pile (B
était en haut), et poussez la grilleAB
obtenue en concaténantB
à droite deA
. Cela nécessite celaA
etB
avoir une hauteur égale. - Étant donné un trait d'union
-
, faites éclater deux grillesA
etB
de la pile (B
était en haut), et poussez la grilleA/B
obtenue en concaténantB
au bas deA
. Cela nécessite celaA
etB
avoir une largeur égale.
Il est garanti que pour certains choix de m
et n
effectués pendant le processus d'analyse (qui peuvent être différents pour chaque lettre), la spécification d'entrée décrit correctement un rectangle, qui est laissé sur la pile à la fin.
Production
Votre sortie est une grille rectangulaire de caractères spécifiée par l'entrée. La grille doit être minimale dans le sens où la suppression d'une ligne ou d'une colonne la rendrait non valide. Vous pouvez renvoyer une chaîne séparée par des sauts de ligne (avec ou sans retour à la ligne), un tableau 2D de caractères ou un tableau de chaînes, selon le format le plus pratique.
Notez que vous n'êtes pas obligé de traiter l'entrée exactement comme décrit ci-dessus; la seule chose importante est que votre sortie soit correcte.
Exemple
Considérez la spécification
par-s||e-
Tout d'abord, nous choisissons de pousser un 1×2
rectangle de p
, et des 1×1
rectangles de a
et r
(la raison en sera claire plus tard). Ensuite, nous les pop a
et r
rectangles, et pousser leur concaténation verticale
a
r
Ensuite, nous poussons un 1×2
rectangle de s
, le pop et le rectangle ci-dessus, et poussons leur concaténation horizontale
as
rs
Ensuite, nous pop ce rectangle et le p
rectangle, et poussons leur concaténation
pas
prs
Enfin, nous poussons un 3×1
rectangle de e
, le pop et le rectangle ci-dessus, et poussons la concaténation verticale
pas
prs
eee
C'est la sortie du programme, ou au moins l'une des possibilités. Notez que même si
ppas
ppas
pprs
eeee
est également généré par la spécification, ce n'est pas une sortie valide, car de nombreuses lignes et colonnes peuvent être supprimées.
Comme exemple plus subtil, considérez
co|m|p|il|e|r|-
Cette spécification génère le rectangle
comp
iler
qui est une sortie valide. Cependant, il génère également
commp
iiler
ce qui est également valable, car aucune ligne ou colonne ne peut être supprimée sans l'invalider.
Règles
Vous pouvez donner un programme complet ou une fonction. Le nombre d'octets le plus bas gagne et les failles standard sont interdites.
Cas de test supplémentaires
Vous pouvez les utiliser pour tester votre programme.
Input:
a
Output:
a
Input:
co|mp|l|-ex|i|f|-y|
Example output:
cccoy
mplly
exify
Input:
ja-r|g-o|ni-|ze|d-|
Example output:
jronze
arondd
ggoidd
Input:
un|co|p-yr|i|gh-t-ab|-|le-||-
Example output:
unnnnnnn
coyriggl
ppyrihhe
ppyritte
ppyriabe
n
etm
sont choisis de manière non déterministe. Il est garanti que des valeurs appropriées existent, mais c'est le travail de votre programme de les trouver.un|co|p-|yr|i|gh--t-ab|-|le-||-
est impossible à valider. Le dernier-
a une arité de 2, alors qu'il n'y a qu'un seul élément sur la pile.Réponses:
K,
123110 octetsJ'ai utilisé une approche similaire à la solution de cardboard_box.
Ce programme est une série de définitions d'aide suivies d'une fonction tacite qui prend une chaîne comme argument de droite. Reformatage pour la lisibilité et attribution de la fonction finale comme
f
:Exemple d'utilisation:
Testé en utilisant Kona, mais il fonctionnera également en oK si vous remplacez le
:
dans la définition def
par$
- k5 a changé la syntaxe de "cond".Un point clé est de reconnaître que faire une annexe verticale est la transposition de l'annexe horizontale de la transposition des deux matrices. (Voir la définition
v
.) Je pense qu'il y a encore de la place pour faire sortir quelques personnages ici et là. Si quelqu'un est intéressé par une explication plus détaillée, je peux en fournir une.Éditer:
Mise à jour du programme en haut de cette entrée. Version non golfée:
Optimisations de longueur notables incluent l'utilisation de « dot appliquer » en
a
remplaçant le « cond » avec l' indexation de listef
(moins efficace, mais plus court) et le remplacement des termes de la formea[b;c]
dans lesa[b]c
cas permis par regroupement. Comme je n'utilise plus "cond" ni aucune primitive différente entre k3 et k5, cette version fonctionne maintenant en oK sans modification.la source
Prolog, 539 octets
Explication
Nous commençons par le prédicat
g
, qui prend une chaîne, le convertissons en une liste de caractères et appelons lep
prédicat (analyse) avec une pile vide comme deuxième argument.Le prédicat
p
s'appelle récursivement avec une pile modifiée de manière appropriée (recherchez[H|T]
les modèles de déstructuration et de constructeur). Lorsqu'il est appelé dans le cas de base, où la liste d'entrée est vide,p
imprime l'élément unique de la pile. Si la pile contient moins ou plus d'un élément à ce stade, cela signifie que nous avons une chaîne d'entrée vide, une mauvaise chaîne d'entrée ou un bogue (avec une chaîne emtpy, le prédicat échoue (Prolog ditNo
), mais rien n'est imprimé, ce qui est correct, car nous ne devons rien imprimer pour les chaînes vides).Résoudre
La pile contient une description des rectangles construits, notés
S:W:H
, où seS
trouve une représentation symbolique du rectangle,W
sa largeur etH
sa hauteur (remarque,A:B
est le sucre syntaxique pour le:(A,B)
tuple avec un foncteur nommé:
; il est juste plus court à écrire que d'avoir un tuple avec préfixe).Les spécifications avec
A
etB
sous-rectangleS
peuvent être:h(A,B)
: concat horizontal de A et Bv(A,B)
: concat vertical de A et Bf(C)
: remplir avec C, où C est un code de caractèreLes largeurs et hauteurs des grilles sont des variables de programmation par contraintes: pendant la concaténation verticale (resp. Horizontale), la largeur (resp. Hauteur) des rectangles manipulés est unifiée, tandis que la hauteur résultante (resp. Largeur) est contrainte d'être la somme de la hauteur de chaque sous-grille (resp. la largeur).
L'étape de labellisation à la fin du processus instancie les variables tout en respectant les contraintes, en utilisant les valeurs minimales possibles (c'est une propriété de l'ordre dans lequel les solutions sont essayées).
J'aurais peut-être obtenu une réponse plus courte en utilisant le même raisonnement que celui fait dans d'autres réponses, sans contraintes, mais c'est trop tard maintenant.
Notez également que le domaine par défaut des variables étant défini sur
1..100
, il existe une limitation sur les tailles possibles des grilles. La limite supérieure peut être modifiée si nécessaire. Les implications en termes de performances sont que cela pourrait prendre beaucoup de temps pour déterminer qu'une solution particulière n'admet aucune solution. J'ai dit " pourrait " car les contraintes sont susceptibles d'élaguer considérablement la recherche exponentielle. Si vous trouvez une chaîne d'entrée difficile / coûteuse à rejeter, veuillez la partager.Impression
La partie impression est intéressante car il existe une sorte d' algorithme de lancer de rayons sur la structure: j'itère sur chaque cellule de la grille résultante, de point
(1,1)
en point(W,H)
et appelle lew
prédicat pour imprimer le contenu de la grille dans l'arborescence principale, à cet emplacement (bien sûr, une nouvelle ligne est imprimée après le traitement de chaque ligne).Dans
w
, les positions sont relatives à la grille actuelle (la grille racine définit les coordonnées absolues).Lors de l'impression d'une
h(A,B)
structure au point(X,Y)
, j'imprime inconditionnellement dans les deux branches:A
au point(X,Y)
, etB
au point(H,Y)
, oùH
estX
moins la largeur deA
.Les branches feuilles de l'arborescence,
f(C)
enfin, impriment le caractèreC
, si l'emplacement relatif est à l'intérieur de la grille, ou ne font rien. C'est ainsi que je peux imprimer le contenu de la grille dans le flux de sortie, de haut en bas, de gauche à droite. Aucun tableau réel n'est produit.Les tests
Test de fonctionnement:
la source
No actual arrays are produced.
c'est ainsi que cela doit être fait. Trop fort dans ce cas, car la grammaire est si simple et il y a des raccourcis.Python 2.7, 259
g
est une fonction qui prend une spécification et donne un tableau 2D de caractères. Si vous voulez une version plus conviviale, ajoutez cette ligne pour lui faire prendre une spécification de stdin et imprimer la grille:Cas de test
Explication
La stratégie est simple: si une grille
G
est valide pour une spécificationS
, la répétition de la colonne la plus à droite deG
donne également une spécification valide pourS
, et il en va de même pour la répétition de la ligne du bas (la preuve en est par induction structurelle activéeS
). Par conséquent, lorsque nous voulons concaténer deux rectangles, nous pouvons simplement ajouter la dernière colonne / ligne de la plus petite jusqu'à ce qu'ils correspondent en taille (c'est ce que fait la fonction p).la source
Haskell,
388367352 octetsUtilisation:
f "par-s||e-"
->["pas","prs","eee"]
Test avec jolie impression:
Comment ça marche: la fonction
#
analyse la chaîne d'entrée dans l'arborescenceC
qui est soit une feuilleL
contenant le caractère à imprimer, soit un nœudN
.N
peut être a) une jonction côte à côte (t==2
), b) une jonction haut-bas (t==1
) ou c) un carré d'une seule lettre (t==0
). Tous les nœuds ont un champ largeur et hauteur et un enfant gauche et droit. Après l'analyse,p
imprime le nœud racine restant en ajustant récursivement la taille (largeur x hauteur) de ses nœuds enfants et en les joignant.Edit: sortie sous forme de liste de lignes au lieu d'une jolie impression
la source
JavaScript (ES6), 283
295Modifier Maintenant, cette solution JS (très jouée au golf) est au moins plus courte que la solution Python de référence (assez jouable au golf).
Similaire à cardboard_box, en répétant simplement la colonne la plus à gauche ou la ligne la plus en haut.
Non golfé C'est ma première solution non golfée.
Tester dans la console Firefox / FireBug
Production
la source
Python 3, 251 octets
Voici la réponse de référence que j'ai promise, j'ai joué un peu plus loin.
Il s'agit d'un programme complet qui prend la chaîne de STDIN et l'imprime sur STDOUT. L'approche est la même que celle de cardboard_box: pousser un tableau 1x1 pour un caractère, et dupliquer les lignes si nécessaire pour la concaténation.
Explication détaillée
T
transpose une liste donnée de listes. La majorité du travail est effectué par l'zip(*m)
échange de lignes en colonnes, le reste convertit simplement le résultat en une liste de listes, carzip
retourne un générateur de tuples.E(a,b)
renvoiea
son premier élément répété suffisamment de fois pour correspondre à la longueur deb
. Notez que la multiplication d'une liste par un nombre négatif donne la liste vide, donc si elleb
est plus courte quea
, cela renvoiea
.H(a,b)
renvoie la concaténation horizontale dea
etb
, la plus courte étant allongéeE
si nécessaire.s
est la pile.for
boucle, nous parcourons la chaîne d'entrée et la remplaçonss
par une nouvelle valeur: si elle est|
(supérieure àz
), nous popons deux valeurs et poussons leurH
, si elle est-
(inférieure àa
), nous popons deux valeurs, transposons, alimentonsH
, transposer à nouveau et pousser le résultat, ou sinon pousser un tableau 1x1 avec la lettre.s
.la source