Haskell a des tuples qui peuvent être écrits comme
(a,b,c)
Mais ce n'est que du sucre syntaxique pour
(,,)a b c
En général, un n tuple peut être formé avec n-1 ,
s entre (
... )
suivi de ses éléments séparés par des espaces. Par exemple, le 7-tuple, (1,2,3,4,5,6,7)
peut être formé par
(,,,,,,)1 2 3 4 5 6 7
Étant donné que Haskell n'a pas de tuples 1, ils ne peuvent pas être formés. Vous ne serez pas non plus tenu responsable des tuples vides.
Les tuples imbriqués peuvent être formés à l'aide de parens pour remplacer l'ordre des opérations.
((1,2),3) == (,)((,)1 2)3
Dans le cadre de notre quête pour supprimer tout le sucre syntaxique de Haskell, je vais vous demander d'écrire un programme qui supprime également le sucre syntaxique des tuples de Haskell.
Votre programme doit prendre un tuple, un tableau ou une chaîne représentant un tuple sucré et doit produire une chaîne représentant un tuple "sans sucre". Les tuples en entrée ne contiendront que des entiers positifs ou d'autres tuples.
Puisque nous jouons ici, votre sortie devrait être courte. Il ne doit pas contenir de
Les espaces. Les espaces doivent être utilisés uniquement pour séparer les arguments d'une fonction de tuple et ne doivent pas apparaître après a
)
ou avant a(
Parenthèses. Les parenthèses ne doivent être utilisées que lors de la création de fonctions de tuple ou lors de l'imbrication de tuples.
C'est une question de code-golf donc les réponses seront notées en octets avec moins d'octets étant mieux.
Cas de test
(1,2) -> (,)1 2
(1,2,3) -> (,,)1 2 3
((1,2),3) -> (,)((,)1 2)3
(1,2,3,4) -> (,,,)1 2 3 4
(1,(2,3)) -> (,)1((,)2 3)
(10,1) -> (,)10 1
,
((1,(2,3)),4,(5,6))
et(1,(2,3),4)
.Réponses:
Haskell ,
169148 octetsEssayez-le en ligne! Prend le tuple sous forme de chaîne.
init.tail.fst.([]%)
est la fonction principale anonyme. Liez-le à egf
et utilisez likef "(3,(14,1),4,7)"
, qui donne"(,,,)3((,)14 1)4 7"
.Pourquoi l'entrée n'est-elle pas fournie en tant que tuple Haskell, demandez-vous? Haskell étant fortement typé, un tuple
(1,2)
a le type(Int,Int)
1 et un tuple(1,(2,3))
a le type(Int,(Int,Int))
. Ainsi une fonction qui accepte le premier type de tuple ne peut pas être appliquée au second type, et surtout il ne peut y avoir de fonction qui prend un tuple arbitraire 2 .Explication:
p:k="(,"
est un moyen court d’affecterp
à'('
etk
à","
.(%)
est la fonction d'analyse et de conversion récursive. Le premier argument est une liste d'entrées de tuple déjà analysées, le deuxième argument est le reste de la chaîne d'origine. Chaque appel renvoie un tuple du tuple converti actuel (sous forme de chaîne et placé entre crochets) et le reste de la chaîne.l%('(':r)
Si la chaîne commence par une parenthèse ouvrante, nous devons analyser une nouvelle entrée de tuple.(y,x:s)<-[]%r
Nous appliquons%
et obtenons récursivement une entrée de tupley
et la chaîne restante divisée en le caractère suivantx
et le reste de la chaînes
.m<-y:l
Nous ajoutons la nouvelle entréey
à la liste actuelle des entrées déjà trouvéesl
et appelons le résultatm
.x
est maintenant soit une virgule,,
soit une parenthèse fermante)
. C'estlast$ <B> :[ <A> |x<',']
juste une façon plus courte d'écrireif x == ')' then <A> else <B>
.,
est le suivant, nous devons analyser récursivement la prochaine entrée:m%(p:s)
nous ajoutons une parenthèse ouvrante afin de nous retrouver dans le bon cas et de passer la liste des entrées déjà trouvéesm
.x == ')'
, nous avons terminé le tuple actuel et devons effectuer la transformation requise:(p:p:(l>>k)++x:foldl(\r x->x++[' '|x>k,r>k]++r)[x]m,s)
p:p:(l>>k)++x:
Si nous avons trouvé n entrées, ilm
a alors n éléments ety
, la liste avant d'ajouter l'élément le plus récemment trouvé, a n-1 entrées. Cela est pratique car nous avons besoin de n-1,
pour unn
tuple d'élément etl>>k
fonctionne sur des listes comme "concaténer la listek
avec elle-même autant de fois quey
d'éléments" . Ainsi, cette première partie donne une chaîne comme"((,,,)"
.foldl(\r x->x++[' '|x>k,r>k]++r)[x]m
concatène les éléments dem
(dans l'ordre inverse, car en ajoutant de nouvelles entrées au frontm
lui-même a été construit dans l'ordre inverse) tout en n'ajoutant que des espaces entre deux éléments s'ils sont tous deux des nombres:[' '|x>k,r>k]
nous vérifions si les entrées actuellesx
etr
sont des nombres en comparant lexicographiquement les à","
- s'ils ne sont pas des nombres, ils sont déjà une représentation de tuple entre crochets, et'(' < ','
détient.l%('(':r)
dès le début échoue, nous nous retrouvons sur la dernière ligne:l%r=lex r!!0
. Cela signifie que nous devons analyser un nombre et renvoyer le nombre et le reste de la chaîne. Heureusement, il y a lalex
fonction qui fait exactement cela (elle analyse le prochain jeton Haskell valide, pas seulement les nombres). Cependant, le tuple résultant est encapsulé dans une liste, nous utilisons donc!!0
pour obtenir le premier élément de la liste.init.tail.fst.([]%)
est la fonction principale qui prend une chaîne et s'applique%
avec une liste vide. Par exemple, pour une entrée"(1,2)"
, appliquer des([]%)
rendements("((,)1 2)","")
, de sorte que le tuple externe et les supports doivent être supprimés.fst
récupère le premier élément du tuple,tail
supprime le crochet de fermeture etinit
le crochet d' ouverture.Edit: Un grand merci à @ Ørjan Johansen pour avoir joué au golf 21 octets au total !
1 En fait, le type est (Num t1, Num t) => (t, t1) , mais c'est une histoire différente.
2 Ignorer les fonctions polymorphes comme id , qui ne peuvent pas réellement fonctionner avec leur entrée.
la source
Desugarable
, mais il faudrait déclarer des instances pourInt
, et tous les types de tuple.g
peut être raccourcifoldr1(\x r->x++[' '|x>k,r>k]++r)
et intégré.show (1,2,3,4,5,6,7,8,9,0,1,2,3,4,5)
dans GHCi, puis ajoutez un,6
à la fin et réessayez.)m<-y:l
, repliez vers la gauche au lieu de la droite et utilisez[x]
comme valeur initiale. Essayez-le en ligne!f
peut être anonyme:init.tail.fst.([]%)
.Haskell,
141 octets138 octets (Merci à Ørjan Johansen)f
a un typeExp -> String
.Entrée: une ression de modèle Haskell
Exp
(c'est-à-dire la représentation AST standard des valeurs Haskell de type arbitraire - en gros, le code Haskell analysé avant la vérification de type); doit représenter un tuple contenant uniquement des nombres entiers non négatifs et d'autres tuples de ce type.Sortie: une chaîne contenant la syntaxe desugared pour cette expression de tuple.
Démo:
la source
")"++
à')':
deux endroits et économiser l'espace après letail
en le déplaçant hors des parenthèses.Haskell , 119 octets
Essayez-le en ligne! Cela utilise un type de données personnalisé
T
pour représenter les tuples, c'est-à-dire qu'un tuple((1,2),3)
est représenté parU[U[I 1,I 2],I 3]
. Exemple d'utilisation:init.tail.f $ U[U[I 1,I 2],I 3]
rendements(,)((,)1 2)3
.la source
Python 2 , 110 octets
Essayez-le en ligne!
Prend a
tuple
.la source
GNU sed,
14982 + 2 = 84 octets+2 octets pour l'
-r
indicateur.Essayez-le en ligne!
Explication
la source
((1,(2,3)),4,(5,6))
et(1,(2,3),4)
.JavaScript, 75 octets
Tableau d'entrée de nombre | tableau, chaîne de sortie.
Merci à Neil, économisez 2 octets
la source
(1/t?' ':0)+v
peut être1/t?' '+v:v
.Mathematica, 94 octets
Contient un non imprimable
U+F4A1
Function
fonction intégrée non imprimable .Prend un
List
entierString
s. Si cela n'est pas autorisé, cela peut être corrigé en ajoutant 10 octets supplémentaires (cette version prend unList
deList
s /Integer
s):la source
Pip , 45 octets
Il s'agit d'une fonction qui prend une liste en argument. Essayez-le en ligne!
Version commentée
la source
JavaScript (ES6),
8884 octetsPrend un tableau d'entiers et de tableaux. Modifier: enregistré 1 octet en utilisant
s+=
au lieu de deux utilisations distinctes des+
. Sauvegardé encore 3 octets maintenant que je peux simplifier le ternaire interne. Si je vole les idées de @ tsh, je peux le ramener à 76 octets:la source
Your program should take either a tuple or a string representing a sugary tuple
Je suppose qu'un tableau de tableaux / entiers devrait convenir.R, 316 octets?
(Je dois sortir et je ne suis pas sûr de la bonne façon de compter les octets ... en plus, ce n'est pas une excellente solution, mais je voulais le poster car j'ai passé le temps à le faire ...)
Cas de test:
la source
JavaScript (ES6), 72 octets
Entrée: tableau contenant des nombres et / ou des tableaux
Sortie: chaîne
Utilisation: f ([...])
Complète tous les cas de test, améliorations bienvenues
la source
C, 308 ou 339 octets
308 ou 339 octets, selon que le passage d'un pointeur à la fin de la chaîne d'entrée est autorisé ou non; la dernière ligne n'est là que pour permettre de passer directement un littéral de chaîne sans avoir à calculer sa longueur.
Explication
Un algorithme assez simple. Il compte le nombre de virgules à la profondeur actuelle, les imprime en tant que constructeur de tuple, puis suit les arguments du tuple, échappés (espaces entre les nombres, tuples imbriqués entre parenthèses), récursivement.
Cas de test et application
la source