Interpréter les plages lâches

13

Interpréter les plages lâches

ListSharp est un langage de programmation interprété qui possède de nombreuses fonctionnalités, l'une de ces fonctionnalités est un créateur de plage basé sur 1 index qui fonctionne comme ceci:

Vous définissez une plage comme (INT) TO (INT)ou juste (INT)où les deux ou le seul int peuvent aller de la valeur min à max int32

Ensuite, vous pouvez utiliser ces plages pour extraire des éléments d'un tableau sans craindre de dépasser ses limites


par conséquent:

1 TO 5 génère: {1,2,3,4,5}

3 génère: {3}

Les plages peuvent être additionnées à l'aide de l' ANDopérateur

1 TO 5 AND 3 TO 6 génère: {1,2,3,4,5,3,4,5,6}

rappelez-vous que cela fonctionne aussi avec des nombres négatifs

3 TO -3 génère: {3,2,1,0,-1,-2,-3}


Le défi est le suivant:

Contribution

Un tableau de caractères et la clause range précédemment définie sous forme de chaîne

Production

Les éléments aux 1 emplacements basés sur l'index de la plage (les index non existants / négatifs se traduisent par un caractère vide)


Comment gagner

En tant que défi de , vous êtes censé créer le programme avec le nombre d'octets le plus court pour gagner


Il a été souligné que les caractères vides n'existent pas, vous devriez donc les ignorer (je ne les ai montrés ici que pour les rendre plus faciles à comprendre mais cela a dérouté les gens)

Cas de test:

input array is:
{'H','e','l','l','o',' ','W','o','r','l','d'}

range clause:
"1 TO 3" => "Hel"
"5" => "o"
"-10 TO 10" => "Hello Worl"
"0 AND 2 AND 4" => "el"
"8 TO 3" => "oW oll"
"-300 AND 300" => ""
"1 TO 3 AND 3 TO 1" => "HelleH"
"-20 TO 0 AND 1 AND 4" => "Hl"
downrep_nation
la source
3
Sommes-nous autorisés à utiliser 0-index au lieu de 1-index comme chaîne d'entrée? Ainsi, la clause range devient "0 TO 2"=> {'H', 'e', 'l'}?
Kevin Cruijssen
La table ASCII n'a pas de caractère vide (à l'exclusion des caractères non imprimables). Quel est le problème avec l'utilisation de l'espace?
adrianmp
un tableau de caractères est essentiellement une chaîne, donc les caractères vides ne seront pas imprimés ou retournés
downrep_nation
1
En outre, par exemple, sera-t-il 3 TO 3jamais une entrée et quelle est la sortie attendue?
Jordan
1
Vous avez besoin de quelques cas de test pour ANDing plusieurs plages. De plus, vous n'avez pas répondu si nous pouvons utiliser l'indexation à base zéro, qui est standard dans la plupart des langues.
mbomb007

Réponses:

5

Python 2 - 239 211 210 octets

Merci à @ mbomb007 et @Cyoce d' avoir approfondi cette solution!

def r(s):
 t=[]
 for x in s.split("AND"):
  if"T"in x:a=map(int,x.split("TO"));b=2*(a[0]<a[1])-1;t+=range(a[0],a[1]+b,b)
  else:t+=int(x),
 return t
lambda p,v:[(['']+p+['']*max(map(abs,r(v))))[x]for x in r(v)]

Approche directe. Générateurs essayés et une version récursive, mais ils ne pouvaient pas battre le simple pour chaque boucle. Je suis un joueur de golf, donc cela peut très probablement être amélioré un peu. De plus, le principal défaut de cet extrait est que la plage en tant qu'objet liste est à nouveau calculée à chaque fois qu'un élément est récupéré du tableau de caractères (voir dernière ligne, compréhension de la liste). Cela signifie r(s)est exécutélen(r(s)) + 1 fois.

Code non golfé:

def find_range(string):
    result = []

    # Split at each AND and look at each element separately
    for element in string.split("AND"):
        # Element is just a number, so add that number to the result list
        if "TO" not in string:
            result += [int(string)]

        # Generate a list with all the values in between the boundaries 
        # (and the boundaries themselves, of course) and append it to the result list
        else:
            boundaries = map(int, string.split("TO"))
            ascending = boundaries[0] < boundaries[1]

            # range(start, stop, step) returns [start, ..., stop - 1], so extend the stop value accordingly
            # range(8, 3, 1) returns just [], so choose respective step (negative for a descending sequence)
            result += range(boundaries[0], boundaries[1] + (1 if ascending else -1), 1 if ascending else -1)

# Make the char array 1-indexed by appending an empty char in 0th position
# Add enough empty chars at the end so too large and negative values won't wrap around
interpret = lambda chars, range_expr: [(['']+chars+['']*max(map(abs, find_range(range_expr))))[x] for x in find_range(range_expr)]

Cas de test:

c = list("Hello World")
print interpret(c, "1 TO 3")
print interpret(c, "5")
print interpret(c, "-10 TO 10")
print interpret(c, "0 AND 2 AND 4")
print interpret(c, "8 TO 3")
print interpret(c, "-300 AND 300")

Production:

['H', 'e', 'l']
['o']
['', '', '', '', '', '', '', '', '', '', '', 'H', 'e', 'l', 'l', 'o', ' ', 'W', 'o', 'r', 'l']
['', 'e', 'l']
['o', 'W', ' ', 'o', 'l', 'l']
['', '']
1Darco1
la source
Grande première réponse! Bienvenue chez PPCG!
mbomb007
Vous pouvez bénéficier de la visualisation de Conseils pour le golf en Python . Vous pouvez remplacer 2 espaces pour la double indentation par un seul onglet. Vous pouvez mettre le code suivant la ifsur la même ligne et les séparer par des points-virgules. Et supprimez l'espace dedans [x] for. En outre, 1if b else-1peut être remplacé par une ou l' autre b and 1or-1ou 2*bool(b)-1d'enregistrer un octet.
mbomb007
Merci! J'ai déjà regardé et (essayé) d'utiliser.d certains d'entre eux. Je reverrai toutes les réponses plus tard. :)
1Darco1
Et je pense que vous pouvez utiliser un nom sans nom lambda, car ce n'est pas récursif.
mbomb007
1
t+=[int(x)]canbecomet+=int(x),
Cyoce
3

Groovy ( 99 97 octets)

{n,v->Eval.me("[${n.replaceAll(" TO ","..").replaceAll(" AND ",",")}]").flatten().collect{v[it]}}

Essayez-le ici: https://groovyconsole.appspot.com/edit/5155820207603712

Explication:

  • .replaceAll(" TO ","..") - Remplacez le to par une gamme traditionnelle.
  • .replaceAll(" AND ", ",") - Remplacez tous les ands par une virgule.
  • "[${...}]" - Entourez-le de la notation "liste" dans Groovy.
  • Eval.me(...) - Évaluez la chaîne en tant que code Groovy.
  • .flatten() - Aplatissez le mélange de matrice 2D et de matrice 1D en une matrice 1D.
  • .collect{v[it]} - Collectez les indices du tableau dans une structure unique.

Voici une solution de 115 113 octets supprimant les valeurs nulles de la sortie: https://groovyconsole.appspot.com/edit/5185924841340928

Voici une solution de 117 octets si vous dites qu'elle DOIT être indexée à 1 au lieu de 0: https://groovyconsole.appspot.com/edit/5205468955803648

Si vous voulez que j'échange l'original pour celui de 113/117 octets, faites-le moi savoir.

Urne de poulpe magique
la source
Si vous n'aimez pas que j'utilise "nulls" pour les caractères qui ne sont pas là, +5 octets à la fin pour "-null", qui supprime tous les nulls de l'ensemble.
Magic Octopus Urn
1
J'adore cette intelligente coïncidence
downrep_nation
J'ai cependant appris quelque chose de cela, je ne savais pas que Groovy avait Eval.me(...)jusqu'à présent; étant donné que l'utiliser dans la pratique serait ridiculement précaire, ce qui est toujours cool à savoir.
Magic Octopus Urn
2

C #, 342 octets

a=>r=>{var s=r.Replace(" AND","").Replace(" TO ","|").Split();int b=a.Length,i=0,n,m,j,o;var c=new List<char>();for(;i<s.Length;){var d=s[i++].Split('|');if(d.Length<2)c.Add(b<(n=int.Parse(d[0]))||n<1?' ':a[n-1]);else{o=(m=int.Parse(d[0]))<(n=int.Parse(d[1]))?1:-1;for(j=m;o>0?j<=n:j>=n;j+=o)c.Add(b<j||j<1?' ':a[j-1]);}}return c.ToArray();};

Méthode non golfée:

static char[] f(char[] a, string r)
{
    var s=r.Replace(" AND","").Replace(" TO ","|").Split();
    int b=a.Length,i=0,n,m,j,o;
    var c=new List<char>();
    for(;i<s.Length;)
    {
        var d=s[i++].Split('|');
        if(d.Length<2)
            c.Add(b<(n=int.Parse(d[0]))||n<1?' ':a[n-1]);
        else
        {
            o=(m=int.Parse(d[0]))<(n=int.Parse(d[1]))?1:-1;
            for(j=m;o>0?j<=n:j>=n;j+=o)
                c.Add(b<j||j<1?' ':a[j-1]);
        }
    }

    return c.ToArray();
}

Programme complet avec cas de test:

using System;
using System.Collections.Generic;

namespace InterpretLooseRanges
{
    class Program
    {
        static void PrintCharArray(char[] a)
        {
            for (int i=0; i<a.Length; i++)
                Console.Write(a[i]);
            Console.WriteLine();
        }

        static void Main(string[] args)
        {
            Func<char[],Func<string,char[]>>f= a=>r=>{var s=r.Replace(" AND","").Replace(" TO ","|").Split();int b=a.Length,i=0,n,m,j,o;var c=new List<char>();for(;i<s.Length;){var d=s[i++].Split('|');if(d.Length<2)c.Add(b<(n=int.Parse(d[0]))||n<1?' ':a[n-1]);else{o=(m=int.Parse(d[0]))<(n=int.Parse(d[1]))?1:-1;for(j=m;o>0?j<=n:j>=n;j+=o)c.Add(b<j||j<1?' ':a[j-1]);}}return c.ToArray();};

            char[] ar = {'H','e','l','l','o',' ','W','o','r','l','d'};

            PrintCharArray(f(ar)("1 TO 3"));
            PrintCharArray(f(ar)("5"));
            PrintCharArray(f(ar)("-10 TO 10"));
            PrintCharArray(f(ar)("0 AND 2 AND 4"));
            PrintCharArray(f(ar)("8 TO 3"));
            PrintCharArray(f(ar)("-300 AND 300"));
        }
    }
}

Une solution naïve, utilisant une liste de caractères, qui utilise ' 'comme un caractère vide et fait le travail. Espérant s'améliorer bientôt.

adrianmp
la source
2

Scala, 165 octets

(s:String,r:String)=>r split "AND"map(_ split "TO"map(_.trim.toInt))flatMap{case Array(a,b)=>if(a<b)a to b else a to(b,-1)
case x=>x}map(i=>s lift(i-1)getOrElse "")

Explication:

(s:String,r:String)=> //define a function
r split "AND"         //split the range expression at every occurance of "AND"
map(                  //map each part...
  _ split "TO"          //split at to
  map(                  //for each of these splitted parts, map them to...
    _.trim.toInt          //trim all whitespace and parse as an int
  )                    
)                     //now we have an Array[Array[Int]]
flatMap{              //map each inner Array...
  case Array(a,b)=>if(a<b)a to b else a to(b,-1) //if it has two elements, create a Range
  case x=>x             //otherwise just return it
}                     //and flatten, so we get an Array[Int]
map(i=>               //for each int
  s lift(i-1)         //try to get the char with index i-1, since Scala is zero-based
  getOrElse ""        //otherwise return ""
) 
corvus_192
la source
2

Python 2, 156 155 octets

Ma réponse a des idées similaires à la réponse de 1Darco1 , mais en utilisant une approche différente dès le départ (découpage de chaînes plutôt que listes), cela s'est avéré un peu plus court. Il serait de quatre octets plus court si l'indexation 0 était autorisée.

s,r=input()
o=""
for x in r.split("AND"):
    i=map(int,x.split("TO"));d=2*(i[0]<i[-1])-1
    for _ in-1,0:i[_]-=11**9*(i[_]<0)
    o+=s[i[0]-1:i[-1]+d-1:d]
print o

Essayez-le en ligne

Heureusement, je peux analyser des chaînes contenant des espaces en nombres entiers. Indexation négative dans les index Python à partir de la fin de la chaîne, donc j'utilise i[-1]soit la même valeur que i[0]la deuxième valeur, s'il y en a une. Ensuite, je dois ajuster toutes les valeurs de plage négatives à plus négatives, afin qu'elles ne gâchent pas le découpage. La multiplication des valeurs négatives par 11**9( 2357947691) tiendra compte des plages en utilisant la valeur min entière. Ensuite, coupez simplement la chaîne en utilisant la tranche inverse si la plage est inversée.

Avec indexation zéro (151 octets):

s,r=input()
o=""
for x in r.split("AND"):
    i=map(int,x.split("TO"));d=2*(i[0]<i[-1])-1
    for _ in-1,0:i[_]-=11**9*(i[_]<0)
    o+=s[i[0]:i[-1]+d:d]
print o
mbomb007
la source
Bon travail! Découper est certainement la voie à suivre ici. Mon rangeapproche est fondamentalement juste une forme super verbeuse d'exactement cela. Et vous vous êtes même débarrassé de toute la if"T"in x: else:partie. +1
1Darco1
2

R, 142 octets

En supposant que j'ai bien compris le défi, je suppose que rc'est la clause de plage prédéfinie au format chaîne et que le tableau d'entrée ("Hello world", dans les exemples) est lu à partir de stdin.

r=eval(parse(t=paste("c(",gsub("AND",",",gsub("TO",":",r)),")")))
o=strsplit(readline(),e<-"")[[1]][r[r>0]]
o[is.na(o)]=e
c(rep(e,sum(r<1)),o)

Quelques cas de test:

r="1 TO 3"
[1] "H" "e" "l"

r="5"
[1] "o"

r="-10 TO 10"
[1] ""  ""  ""  ""  ""  ""  ""  ""  ""  ""  ""  "H" "e" "l" "l" "o" " " "w" "o" "r" "l"

r="0 AND 2 AND 4"
[1] ""  "e" "l"

r="8 TO 3"
[1] "o" "w" " " "o" "l" "l"

r="-300 AND 300"
[1] "" ""

Non golfé / expliqué

Ligne 1

r=eval(parse(t=paste("c(",gsub("AND",",",gsub("TO",":",r)),")")))

R a un bon opérateur infixe :qui génère des séquences. 1:5donne [1, 2, 3, 4, 5]et 0:-2donne [0, -1, -2]. Donc, nous remplaçons la TOclause dans la plage lâche par :.

                                         gsub("TO",":",r)

L'interprétation ANDn'est qu'une concaténation. Nous pouvons utiliser la fonction cpour cela, qui peut facilement prendre un nombre arbitraire d'arguments, séparés par des virgules. Nous remplaçons donc ANDpar,

                          gsub("AND",",",      ...       )

puis envelopper le tout dans c(, ).

               paste("c(",              ...               ,")")

Cela donne une chaîne de caractères qui pourrait ressembler c( 1 : 5 , 7 ). Nous appelons parseà convertir pour taper "expression" puis evalà évaluer l'expression. La séquence de nombres résultante est ensuite réaffectée à la variable r.

r=eval(parse(t=                     ...                        ))

Ligne 2

o=strsplit(readline(),e<-"")[[1]][r[r>0]]

Maintenant, pour la partie laide - traiter les chaînes en R, qui devient rapidement désordonné. D'abord, nous définissons ecomme une chaîne vide (nous en aurons besoin plus tard).

                      e<-""

Nous lisons dans stdin et convertissons la chaîne de caractères en un tableau de caractères individuels en divisant la chaîne vide. (Par exemple, nous passons de "Hi" à ["H", "i"].) Cela renvoie une liste de longueur 1, nous devons donc demander le premier élément [[1]]pour obtenir un tableau avec lequel nous pouvons travailler. Ugh, je vous ai prévenu que c'était désordonné.

  strsplit(readline(), ... )[[1]]

Les index R commencent à 1 et ont une fonctionnalité intéressante avec des nombres négatifs. Supposons que ce xsoit ['a', 'b', 'c']. Appeler x[1]sans surprise revient 'a'. L'appel x[-1]renvoie tout x sauf l' index 1, c'est-à-dire ['b', 'c']. C'est une fonctionnalité intéressante, mais cela signifie que nous devons être prudents avec nos indices négatifs pour ce problème. Donc pour l'instant, nous renvoyons simplement les éléments du tableau d'entrée avec index >0, et attribuons le résultat à o.

o=               ...             [r[r>0]]

Ligne 3

Cependant, il y a un problème! Pour les indices supérieurs à la longueur du tableau, R renvoie simplement des NAvaleurs. Nous en avons besoin pour renvoyer des chaînes vides. Donc , nous redéfinissons les éléments opour lesquels is.na(o)est TRUEd'être la chaîne vide.

o[is.na(o)]=e

Ligne 4

c(rep(e,sum(r<1)),o)

Enfin, comment gérer les indices négatifs (et nuls)? Ils ont tous besoin de retourner la chaîne vide, donc nous répétons la chaîne vide N fois, où N est le nombre d'indices qui le sont <1.

  rep(e,sum(r<1))

Enfin, nous concaténons le précédemment défini oà cette liste (potentiellement vide).

c(      ...      ,o)
rturnbull
la source
2

JavaScript (ES6), 141

Fonction sans nom avec 2 paramètres, le premier étant le tableau de caractères (peut être une chaîne non plus), le second la chaîne contenant la définition de la plage.

La valeur de retour est un tableau où chaque élément peut être soit un seul caractère, soit la valeur js undefined. Une fois stratifié, cela se traduit par une séquence de caractères séparés par des virgules ayant undefined indiqué comme le caractère "vide" - comme les cas de test dans la première version de la question.
L' utilisation , .joinvous pouvez obtenir un résultat de chaîne similaire à la sortie de cas de test dans la version actuelle de la question.

(l,r,u,z=[])=>(r+' E').replace(/\S+/g,x=>x>'T'?u=t:x>'A'?[...Array((t-(w=(u=u||t)-(d=+u<t?1:-1)-1)-1)*d)].map(_=>z.push(l[w+=d]),u=0):t=x)&&z

Moins golfé

(
 l, r, // input paramaters, array/string and string
 u,    // local variable start at 'undefined'
 z=[]  // local variable, will contain the ouput
) => 
  (r+' E') // add an end marker
  .replace( /\S+/g, x=> // execute for each nonspace substring
    x > 'T' // check if 'TO'
    ? u = t // if 'TO' save first value in u (it's a string so even 0 is a truthy value)
    : x > 'A' // check if 'AND' or 'E'
      ? (
          u = u||t, // if u is falsy, it's a single value range t -> t
          d = +u < t ? 1 :-1, // direction of range up or down,comparison has to be numeric, so the leading +
          w = u - d - 1, // starting value (decrement by 1 as js array are 0 based)
          u = 0, // set u to falsy again for next round
          [...Array((t - w - 1) * d)] // build the array of required number of elements
          .map(_ => z.push(l[w+=d])) // iterate adding elements of l to z
        )
      : t = x // if not a keyword, save value in t
  ) && z // return output in z

Tester

f=
(l,r,u,z=[])=>(r+' E').replace(/\S+/g,x=>x>'T'?u=t:x>'A'?[...Array((t-(w=(u=u||t)-(d=+u<t?1:-1)-1)-1)*d)].map(_=>z.push(l[w+=d]),u=0):t=x)&&z

function run(x)
{
  R.value=x;
  O.textContent=f(L.value,x)
}

run("10 TO 5 AND 5 TO 10")
<table>
<tr><td>Base string</td><td><input id=L value="Hello World"></td></tr>
<tr><td>Custom range</td><td><input id=R ><button onclick='run(R.value)'>-></button></td></tr>
<tr><td>Output</td><td><pre id=O></pre></td></tr>
<tr><td>Test case ranges</td><td>
<select id=T onchange='run(this.value)'>
<option/>  
<option value="1 TO 3">1 TO 3 =&gt; {'H','e','l'}</option>
<option value="5">5 =&gt; {'o'}</option>
<option value="-10 TO 10">-10 TO 10 =&gt; {'','','','','','','','','','','','H','e','l','l','o',' ','W','o','r','l'}</option>
<option value="0 AND 2 AND 4">0 AND 2 AND 4 =&gt; {'','e','l'}
"8 TO 3" => {'o','W',' ','o','l','l'}</option>
<option value="-300 AND 300">-300 AND 300 =&gt; {'',''}</option>
<option value="1 TO 3 AND 3 TO 1">1 TO 3 AND 3 TO 1 =&gt; "HelleH"</option>
<option value="-20 TO 0 AND 1 AND 4">-20 TO 0 AND 1 AND 4 =&gt; "Hl"</option>
</select>
</td></tr>
</table>

edc65
la source
1

Perl - 110 octets

Appel du script dans la ligne de commande avec la chaîne comme premier argument et la plage comme second.

for(split AND,pop@ARGV){$_>0?print+(split//,"@ARGV")[$_-1]:0for(/(.+)TO(.+)/?($1>$2?reverse$2..$1:$1..$2):$_)}

Désobscurci:

for $subrange (split 'AND', $ARGV[1]) {
    for $index ($subrange =~ /(.+)TO(.+)/
        ? ($1 > $2 ? reverse $2..$1 : $1..$2) # All indices of that range
        : $subrange) # Otherwise, an index only
    {
        if ($index > 0) {
            # Here, 'split' returns an array of all characters
            print((split //, $ARGV[0])[$index - 1]);
        }
    }
}
Maxim Bernard
la source
1

Python 2, 146 octets

lambda s,a:[a[i]for x in[map(int,c.split('TO'))for c in s.split('AND')]for i in range(x[0]-1,x[-1]-2*(x[-1]<x[0]),1-2*(x[-1]<x[0]))if 0<=i<len(a)]

Tous les tests sont à idéone

Fractionne la clause, ssur "ET", fractionne chacune des sous-clauses résultantes sur "TO", convertit les chaînes résultantes en intutilisant map. Les résultats auront chacun 1 ou 2 éléments (1 si aucun "TO" n'était présent dans la sous-clause).
Construit des plages basées sur 0 pour chacune d'elles en utilisant le paramètre d'étape de plage comme 1 ou -1 en inspectant les valeurs aux index 0 et -1 (une liste avec une entrée a cette entrée aux deux index).
Exécute ces plages et construit une liste de la sortie, si les index fournis sont dans la plage ( if 0<=i<len(a)).

Jonathan Allan
la source
0

Gelée , 28 27 25 octets

œṣ⁾TOj”rV
œṣ“Ñþ»Ç€Ff⁹J¤ị⁹

TryItOnline (fonctionnera également avec une chaîne au lieu d'un tableau de caractères)

Comment?

œṣ⁾TOj”rV - Link 1, construct sub-range: subclause
  ⁾TO     - string "TO"
œṣ        - split on sublists
     j    - join with
      ”r  - character "r"
        V - evaluate as Jelly code
                (r is the Jelly dyad for inclusive range, which works just like TO
                 when no r is present the string evaluates to the number:
                 " -20 "       evaluates to -20;
                 " -20 r -19 " evaluates to [-20,-19];
                 " 3 r -3 "    evaluates to [3,2,1,0,-1,-2,-3]; etc.)

œṣ“Ñþ»Ç€Ff⁹J¤ị⁹ - Main link: range clause, array 
  “Ñþ»          - compression of the string "AND"
œṣ              - split on sublists
      ǀ        - call the last link (1) as a monad for each
        F       - flatten list
            ¤   - nilad and link(s) as a nilad
          ⁹     - right argument (the array)
           J    - range for length [1,2,...,len(array)]
         f      - filter keep
                      (Jelly indexing is modular so keep only in-bound indexes)
             ị⁹ - index into the array
Jonathan Allan
la source
0

Clojure 232 230 229 octets

Oh quel monstre j'ai créé ... Mais en réalité c'était 260 quand j'étais sur le point de le soumettre.

Edit: retiré d' un espace de #(get r %_""), (if_(< f t)et (take-nth 2_%)(comme indiqué _).

(let[S clojure.string/split](fn[r s](apply str(map #(get r %"")(mapcat #(apply(fn([f][(dec f)])([f t](if(< f t)(range(dec f)t)(reverse(range(dec t)f)))))%)(map #(mapv read-string(take-nth 2%))(map #(S % #" ")(S s #" AND "))))))))

Moins golfé:

(def f (let[S clojure.string/split]
         (fn[r s] (->> (map #(S % #" ") (S s #" AND "))
                       (map #(mapv read-string (take-nth 2 %)))
                       (mapcat #(apply(fn
                                        ([f][(dec f)])
                                        ([f t](if (< f t)
                                                (range (dec f) t)
                                                (reverse (range (dec t) f)))))  %))
                       (map #(get r % ""))
                       (apply str)))))

Utilise clojure.string/splitpour diviser par "ET" et "",take-nth supprime "TO" entre les entiers, la correspondance d'arguments de fonction gère le cas de 1 ou 2 arguments et c'est tout.

Convention d'appel: (f "Hello World" "1 TO 3 AND 2 AND 8 TO 2")

NikoNyrh
la source
Vous pouvez supprimer un grand nombre d'octets en supprimant les espaces en général, en particulier entre les #caractères.
clismique
Êtes-vous sûr de pouvoir supprimer un espace entre tous #? Je l'ai essayé sans succès, il est "fusionné" avec le jeton précédent. Oh, encore un espace à retirer avant %là.
NikoNyrh