Entre parenthèses claires des trains APL

19

Dans APL, vous pouvez écrire des fonctions tacites, appelées trains . La façon dont ils fonctionnent n'est pas pertinente pour ce défi. Voici les différentes façons de les regrouper en utilisant comme fonction:

⍴      -> ⍴
⍴⍴     -> ⍴⍴
⍴⍴⍴    -> ⍴⍴⍴
⍴⍴⍴⍴   -> ⍴(⍴⍴⍴)
⍴⍴⍴⍴⍴  -> ⍴⍴(⍴⍴⍴)
⍴⍴⍴⍴⍴⍴ -> ⍴(⍴⍴(⍴⍴⍴))
...

L'ordre reste le même. La procédure est que tant qu'il y a strictement plus de 3 fonctions, les 3 dernières fonctions sont regroupées en une seule fonction. Si nous rencontrons un train imbriqué, nous le mettons entre parenthèses avant de continuer. Voici la procédure appliquée à ⍴⍴⍴⍴⍴⍴:

Step 0: ⍴⍴⍴⍴⍴⍴
There are strictly more than 3 functions, repeat.
Step 1: ⍴⍴⍴(⍴⍴⍴)
There are strictly more than 3 functions, repeat.
Step 2: ⍴(⍴⍴(⍴⍴⍴))
There are 3 or less functions, we're done.

Voici la même procédure appliquée à ⍴⍴⍴(⍴⍴)⍴(⍴⍴⍴⍴(⍴⍴⍴))⍴⍴:

Step 0: ⍴⍴⍴(⍴⍴)⍴(⍴⍴⍴⍴(⍴⍴⍴))⍴⍴
There are strictly more than 3 functions, repeat.
We have met a nested train, applying procedure to that first:
  Step 0: ⍴⍴⍴⍴(⍴⍴⍴)
  There are strictly more than 3 functions, repeat.
  We have met a nested train, applying procedure to that first:
    Step 0: ⍴⍴⍴
    There are 3 or less functions, we're done.
  Step 1: ⍴⍴(⍴⍴(⍴⍴⍴))
  There are 3 or less functions, we're done.
Step 1: ⍴⍴⍴(⍴⍴)⍴((⍴⍴(⍴⍴(⍴⍴⍴)))⍴⍴)
There are strictly more than 3 functions, repeat.
We have met a nested train, applying procedure to that first:
  Step 0: ⍴⍴
  There are 3 or less functions, we're done.
Step 2: ⍴⍴⍴((⍴⍴)⍴((⍴⍴(⍴⍴(⍴⍴⍴)))⍴⍴))
There are strictly more than 3 functions, repeat.
Step 3: ⍴(⍴⍴((⍴⍴)⍴((⍴⍴(⍴⍴(⍴⍴⍴)))⍴⍴)))
There are 3 functions or less, we're done.

Contribution

Pour ce défi, la saisie sera simplifiée. Cela signifie que vous pouvez choisir 2 caractères différents pour les parenthèses d'ouverture et de fermeture et 1 caractère pour les fonctions, différents de ceux choisis pour les parenthèses. Les caractères que vous choisissez doivent être cohérents. L'entrée ne sera pas vide et ne contiendra pas de parenthèses sans contenu (c'est-à-dire ()).

Production

Encore une fois, vous pouvez choisir 3 caractères différents, 2 pour les parenthèses et 1 pour les fonctions. Notez qu'ils n'ont pas besoin d'être les mêmes que ceux choisis pour l'entrée, mais ils doivent être cohérents.

Règles

  • S'il existe des parenthèses qui ne contiennent qu'une seule fonction en leur sein dans l'entrée, vous devez les supprimer dans la sortie. Votre sortie peut ne pas contenir de parenthèses inutiles (c'est-à-dire entourant une seule fonction ou entourant la sortie entière).
  • Vous n'avez pas besoin d'implémenter l'algorithme utilisé ici, tant que votre solution est valide pour ce défi.
  • L'entrée et la sortie sont des chaînes au format expliqué dans les sections Entrée et Sortie. L'entrée aura au moins un caractère.
  • L'utilisation des failles standard est strictement interdite.
  • C'est le , donc la réponse la plus courte l'emporte. Cependant, il n'y aura pas de réponse acceptée, car il s'agit d'un concours par langue, et pour encourager la réponse dans les langues dans lesquelles cette tâche entraînerait un code plus long par rapport au code écrit dans d'autres langues.

Cas de test

Les caractères utilisés ici sont ()⍴, vous devez les remplacer par vos caractères choisis.

⍴                          -> ⍴
⍴                          -> ⍴
⍴⍴                         -> ⍴⍴
⍴⍴⍴                        -> ⍴⍴⍴
⍴⍴⍴⍴                       -> ⍴(⍴⍴⍴)
⍴⍴⍴⍴⍴⍴⍴⍴⍴⍴⍴⍴⍴⍴⍴            -> ⍴⍴(⍴⍴(⍴⍴(⍴⍴(⍴⍴(⍴⍴(⍴⍴⍴))))))
⍴⍴⍴⍴⍴(⍴⍴⍴)⍴⍴(⍴(⍴⍴⍴)⍴⍴⍴)⍴⍴⍴ -> ⍴(⍴⍴(⍴⍴((⍴⍴⍴)⍴(⍴(⍴(⍴⍴⍴)(⍴⍴⍴))(⍴⍴⍴)))))
(⍴⍴⍴)(⍴⍴⍴)(⍴⍴⍴)            -> (⍴⍴⍴)(⍴⍴⍴)(⍴⍴⍴)
(⍴⍴⍴)(⍴⍴⍴)⍴⍴⍴              -> (⍴⍴⍴)(⍴⍴⍴)(⍴⍴⍴)
⍴⍴(⍴)⍴⍴                    -> ⍴⍴(⍴⍴⍴)
((⍴⍴))                     -> ⍴⍴
⍴⍴((⍴⍴))⍴⍴                 -> ⍴⍴((⍴⍴)⍴⍴)

Ce défi a été publié dans le bac à sable. Si vous disposez des privilèges requis, vous pouvez consulter le post du bac à sable ici .

Erik le Outgolfer
la source
2
Je pense que Fully est un meilleur titre que Clearly .
Adám
@ Adám, je m'attendais à cette réponse de référence, mais elle n'obtiendra pas beaucoup de votes positifs;)
Erik the Outgolfer
@ Adám La partie Clairement dans le titre fait référence au fait que vous devez supprimer les parenthèses inutiles. Entièrement est quelque chose que vous êtes censé faire quand vous répondez à un défi, p
Erik le Outgolfer
Est-il vrai que cette fonction sera toujours idempotente?
Esolanging Fruit

Réponses:

7

APL (Dyalog Classic) , 71 68 65 63 octets

0{⍵≡⍕⍵:⍵⋄⍬≡⍵:'⍬'1=≢⍵:⍺∇⊃⍵⋄3≥≢⍵:⍺⌽')(',⍣⍺∊1∇¨⍵⋄⍺∇¯3(↓,∘⊂1∇↑)⍵}⍎

Essayez-le en ligne!

Les personnages que je choisi pour I / O sont '(', ')'et '⍬'.

Cette solution est elle-même un train APL.

analyse l'entrée comme s'il s'agissait d'un tableau imbriqué - un arbre avec des vecteurs numériques vides ( ) comme feuilles.

Le dfn (ie lambda - { }) parcourt récursivement l'arbre et le convertit en une chaîne correctement entre parenthèses. L'argument de gauche contrôle si des parenthèses doivent être ajoutées au niveau actuel si nécessaire.

Le dfn gère les cas suivants en fonction du bon argument:

  • si c'est déjà une chaîne ( ⍵≡⍕⍵), retournez-la

  • si c'est le cas , retournez le caractère'⍬'

  • s'il s'agit d'un singleton, il suffit de creuser plus profondément ( est le symbole d'un appel récursif)

  • si sa longueur est ≤3, recoupez pour chacun des éléments et entourez ()si nécessaire

  • sinon, recurse pour le 3-tail, ajouter tout sauf le 3-tail, et recurse à nouveau

ngn
la source
On dirait 63 caractères, la plupart d'entre eux Unicode. Quel codage de caractères produit 63 octets pour cela? Je fais 141 octets en UTF8.
Corey
@Corey Meta post pertinent .
Adám
@ Adám Merci pour cela. J'ai regardé mais je ne savais pas quoi chercher pour obtenir cette réponse.
Corey
3

Python 2 , 224 208 204 octets

-16 octets grâce à M. Xcoder -4 octets grâce aux ovs

r=str.replace
p='p'
def c(l):
 while len(l)>3:l=l[:-3]+(l[-3:],)
 return l and map(c,l)or l
print r(r(r(r(r(`c(eval(r(r(r(input(),'(p)',p),p,'[],'),')','),')))`,'[]',p),*'[('),*'])'),' ',''),',','')[1:-1]

Essayez-le en ligne! ou Essayez tous les cas de test

Le code peut être divisé en 3 étapes principales:
conversion de l'entrée en liste imbriquée et remplacement (p)->p. La fonction unique psera remplacée par une liste vide.

eval(r(r(r(input(),'(p)',p),p,'[],'),')','),'))

Une fonction récursive pour appliquer la règle "3 ou moins" sur la liste actuelle et s'appeler sur toutes les sous-listes.

def c(l):
 while len(l)>3:l=l[:-3]+(l[-3:],)
 return l and map(c,l)or l

Beaucoup de remplacements à formater au format de sortie souhaité

r(r(r(r(r(`c(...)`,'[]',p),*'[('),*'])'),' ',''),',','')[1:-1]
Barre
la source
1
Cela ne simplifie pas ((pp))(ou p((pp))p).
Martin Ender
2

CJam , 56 octets

Beats APL!

lW%~]]]{{_,{K_,({~}|}&}%{_,3>}{3/(aa\+:~}w}:K~~`1>W<W%S/

Essayez-le en ligne!

Cela fonctionne (je pense) et je ne sais pas pourquoi ...

Les caractères d'entrée sont ][Tpour ()⍴et les caractères de sortie sont ][0pour ()⍴(oui, cela signifie qu'ils sont inversés par rapport à ce que vous attendez; par exemple, vous pouvez passer TTT]TT[T]TTTT]TTT[[TT).

Présentation de haut niveau

Le programme fonctionne avec l'entrée vers l'arrière, car c'est plus pratique. Pour analyser l'entrée, nous exploitons l'analyseur de CJam - inverser et exécuter l'entrée fournit la forme analysée (vers l'arrière) de l'entrée.

Nous définissons ensuite une procédure K. Kfait la plupart du travail pour notre soumission, et il fonctionne comme suit:

  • Le tableau d'entrée sera un mélange de zéros et de sous-tableaux non vides. Identifiez les sous-tableaux et appliquez-les récursivement K. Le résultat devrait être un autre tableau, et si ce tableau se compose d'un seul élément, décompressez-le (cela supprime les parenthèses redondantes).
  • Tant que le résultat comporte plus de trois éléments, regroupez ses trois premiers (et non ses trois derniers; rappelez-vous que l'entrée est en cours de traitement en arrière) dans une seule liste.
  • Renvoie le résultat.

En appliquant Kà l'entrée, nous obtenons la forme correctement entre parenthèses de l'entrée (la seule chose à noter est que nous enveloppons réellement l'entrée dans une liste singleton et la déballons ensuite; la raison en est que nous voulons l'extrait de code qui déballe les singletons à appliquer au programme de niveau supérieur, et pas seulement à ses sous-tableaux). Ensuite, nous appliquons simplement une mise en forme minimale pour obtenir notre résultat.

Quelques explications pour les morceaux de golf

Le golf dont je suis le plus fier utilise ,pour effectuer la vérification entre les nombres entiers et les tableaux.

  • Si le haut de la pile est un entier n , ,génère la plage [0..n) . Puisque le seul entier que nous rencontrerons est 0, cela nous donne toujours la liste vide [], qui est falsey.
  • Si le haut de la pile est un tableau, ,prend sa longueur. Puisque tous les tableaux que nous rencontrons seront non vides, cela nous donne toujours un entier positif, ce qui est vrai.

Un autre golf qui pourrait être intéressant est la méthode que j'utilise pour regrouper les trois premiers éléments du tableau; il est quelque peu similaire à ma soumission «Golf de code d'interprète de langage complet Turing» . CJam n'a pas un moyen court de diviser un tableau en deux parties (vous pouvez essayer de découper la première partie puis l'autre partie tout en conservant le tableau et l'index d'origine sur la pile, mais cela ne fonctionne pas très bien) , donc ce que je fais à la place est l'utilisation 3/, qui regroupe un tableau en blocs de 3. Je peux ensuite retirer le premier élément (, encapsuler le tableau deux fois aa, puis l'ajouter au début de la liste \+. La raison pour laquelle nous encapsulons le tableau deux fois est que nous devons retirer une couche avec :~, car nous venons de regrouper le reste du tableau en sections également.

Esolanging Fruit
la source
Nitpick: cela bat APL sans builtins .
Erik the Outgolfer
@EriktheOutgolfer Assez juste.
Esolanging Fruit
0

JavaScript (ES6), 149 146 octets

i='a';f=s=>s==(s=s[R='replace'](/\((\w+)\)/,(q,t)=>(f[q=i+=0]=f(t),q)))&&s==(s=s[R](/(?!^)((a0+|p){3})$/,"($1)"))?s[R](/a0+/g,t=>`(${f[t]})`):f(s)
<textarea cols=80 id=I>ppp(pp)p(pppp(ppp))pp</textarea><br>
<button onclick=O.innerText=f(I.value)>Run</button><br>
<pre id=O></pre>

Utilise ()p, bien que vous utilisiez une lettre différente, vous pouvez simplement changer le pvers la fin.

ETHproductions
la source