Lose Bereiche interpretieren

13

Lose Bereiche interpretieren

ListSharp ist eine interpretierte Programmiersprache mit vielen Funktionen. Eine dieser Funktionen ist ein auf einem Index basierender Range Creator, der folgendermaßen funktioniert:

Sie definieren einen Bereich als (INT) TO (INT)oder genau dort, (INT)wo beide oder der einzelne int von min bis max int32-Wert gehen können

Dann können Sie diese Bereiche verwenden, um Elemente eines Arrays zu extrahieren, ohne befürchten zu müssen, seine Grenzen zu überschreiten


deshalb:

1 TO 5 erzeugt: {1,2,3,4,5}

3 erzeugt: {3}

Bereiche können mit dem ANDOperator addiert werden

1 TO 5 AND 3 TO 6 erzeugt: {1,2,3,4,5,3,4,5,6}

Denken Sie daran, dass dies auch bei negativen Zahlen funktioniert

3 TO -3 erzeugt: {3,2,1,0,-1,-2,-3}


Die Herausforderung ist folgende:

Eingang

Ein Zeichenarray und die zuvor definierte Range-Klausel als Zeichenfolge

Ausgabe

Die Elemente an den 1 indexbasierten Positionen des Bereichs (nicht vorhandene / negative Indizes werden in ein leeres Zeichen übersetzt)


Wie gewinnt man

Als Herausforderung soll das Programm mit der kürzesten Anzahl von zu gewinnenden Bytes erstellt werden


Es wurde darauf hingewiesen, dass leere Zeichen nicht existieren, deshalb sollten Sie sie ignorieren (ich habe sie hier nur gezeigt, um das Verständnis zu erleichtern, aber es verwirrt die Leute).

Testfälle:

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
quelle
3
Dürfen wir 0-Index anstelle von 1-Index als Eingabezeichenfolge verwenden? So wird die Range-Klausel "0 TO 2"=> {'H', 'e', 'l'}?
Kevin Cruijssen
Die ASCII-Tabelle enthält kein leeres Zeichen (ausgenommen nicht druckbare Zeichen). Was ist falsch an der Verwendung von Speicherplatz?
adrianmp
Ein char-Array ist im Grunde genommen eine Zeichenfolge, daher werden leere Zeichen nicht gedruckt oder zurückgegeben
downrep_nation
1
Auch wird zB 3 TO 3jemals ein Input sein und was ist der erwartete Output?
Jordanien
1
Sie benötigen einige Testfälle für ANDMehrfachbereiche. Sie haben auch nicht geantwortet, ob wir eine auf Null basierende Indizierung verwenden können, die in den meisten Sprachen Standard ist.
mbomb007

Antworten:

5

Python 2 - 239 211 210 Bytes

Vielen Dank an @ mbomb007 und @Cyoce für das weitere Golfen dieser Lösung!

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)]

Unkomplizierter Ansatz. Versuchte Generatoren und eine rekursive Version, aber sie konnten das Einfache nicht für jede Schleife übertreffen. Ich bin ein Golf-Neuling, daher kann dies höchstwahrscheinlich einiges verbessert werden. Der Hauptfehler dieses Snippets besteht auch darin, dass der Bereich als Listenobjekt jedes Mal neu berechnet wird, wenn ein Element aus dem Zeichenarray abgerufen wird (siehe letzte Zeile, Listenverständnis). Das heißt r(s)wird len(r(s)) + 1mal ausgeführt .

Ungolfed-Code:

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)]

Testfälle:

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")

Ausgabe:

['H', 'e', 'l']
['o']
['', '', '', '', '', '', '', '', '', '', '', 'H', 'e', 'l', 'l', 'o', ' ', 'W', 'o', 'r', 'l']
['', 'e', 'l']
['o', 'W', ' ', 'o', 'l', 'l']
['', '']
1Darco1
quelle
Tolle erste Antwort! Willkommen bei PPCG!
mbomb007
Sie können von der Anzeige von Tipps zum Golfen in Python profitieren . Sie können 2 Leerzeichen für die doppelte Einrückung durch einen einzelnen Tabulator ersetzen. Sie können den Code ifin die gleiche Zeile setzen und mit Semikolons trennen. Und entfernen Sie den Raum in [x] for. Auch 1if b else-1kann ersetzt werden entweder mit b and 1or-1oder 2*bool(b)-1ein Byte zu speichern.
mbomb007
Vielen Dank! Ich habe bereits einige von ihnen angeschaut und versucht, sie zu benutzen. Sehen Sie sich später noch einmal alle Antworten an. :)
1Darco1
Und ich denke, Sie können einen unbenannten verwenden lambda, da er nicht rekursiv ist.
mbomb007
1
t+=[int(x)]canbecomet+=int(x),
Cyoce
3

Groovy ( 99 bis 97 Bytes)

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

Versuchen Sie es hier: https://groovyconsole.appspot.com/edit/5155820207603712

Erläuterung:

  • .replaceAll(" TO ","..") - Ersetzen Sie das bis durch einen herkömmlichen Bereich.
  • .replaceAll(" AND ", ",") - Ersetzen Sie alle und durch ein Komma.
  • "[${...}]" - Umgeben Sie es mit der "Listen" -Notation in Groovy.
  • Eval.me(...) - Bewerten Sie den String als Groovy-Code.
  • .flatten() - Reduzieren Sie die Mischung aus 2D-Array und 1D-Array zu einem 1D-Array.
  • .collect{v[it]} - Sammeln Sie die Indizes aus dem Array in einer einzigen Struktur.

Hier ist eine 115 113-Byte-Lösung, die Nullen aus der Ausgabe entfernt: https://groovyconsole.appspot.com/edit/5185924841340928

Hier ist eine 117-Byte-Lösung, wenn Sie sagen, dass sie bei 1 statt bei 0 indiziert werden MUSS: https://groovyconsole.appspot.com/edit/5205468955803648

Wenn Sie möchten, dass ich das Original gegen das 113/117-Byte-1 austausche, lassen Sie es mich wissen.

Magic Octopus Urn
quelle
Wenn Sie nicht möchten, dass ich "Nullen" für die Zeichen verwende, die nicht vorhanden sind, +5 Bytes am Ende für "-null", wodurch alle Nullen aus der Menge entfernt werden.
Magic Octopus Urn
1
Ich liebe diesen klugen Zufall
downrep_nation
Ich habe etwas daraus gelernt, wusste aber nie, dass Groovy es Eval.me(...)bis jetzt getan hat. in der Praxis wäre es lächerlich unsicher, noch eine coole Sache zu wissen.
Magic Octopus Urn
2

C #, 342 Bytes

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();};

Ungolfed-Methode:

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();
}

Volles Programm mit Testfällen:

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"));
        }
    }
}

Eine naive Lösung unter Verwendung einer Zeichenliste, die ' 'als Leerzeichen verwendet wird und die Aufgabe erledigt. Ich hoffe, mich bald zu verbessern.

adrianmp
quelle
2

Scala, 165 Bytes

(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 "")

Erläuterung:

(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
quelle
2

Python 2, 156 155 Bytes

Meine Antwort hat einige ähnliche Ideen wie die Antwort von 1Darco1 , aber durch die Verwendung eines anderen Ansatzes von Anfang an ( Aufteilen von Zeichenfolgen anstelle von Listen) wurde sie deutlich kürzer. Es wäre vier Bytes kürzer, wenn die Indizierung mit 0 zulässig wäre.

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

Probieren Sie es online aus

Glücklicherweise kann ich Zeichenfolgen, die Leerzeichen enthalten, in ganze Zahlen zerlegen. Negative Indizierung in Python-Indizes ab dem Ende der Zeichenfolge, daher verwende ich i[-1]entweder den gleichen i[0]oder den zweiten Wert, falls vorhanden. Dann muss ich auf alle negativen Bereichswerte einstellen mehr negativ, so werden sie nicht verwirren mit dem Aufschneiden. Wenn Sie negative Werte mit 11**9( 2357947691) multiplizieren, werden Bereiche mit einem ganzzahligen Mindestwert berücksichtigt. Schneiden Sie dann einfach die Zeichenfolge mit dem umgekehrten Schnitt, wenn der Bereich umgekehrt ist.

Mit Null-Indexierung (151 Bytes):

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
quelle
Gut gemacht! Schneiden ist definitiv der richtige Weg, um hierher zu kommen. Mein rangeAnsatz ist im Grunde nur eine super wortreiche Form von genau dem. Und du hast sogar den ganzen if"T"in x: else:Teil losgeworden . +1
1Darco1
2

R, 142 Bytes

Unter der Annahme, dass ich die Herausforderung richtig verstanden habe, gehe ich hier davon aus, dass res sich um die vordefinierte Range-Klausel im String-Format handelt und dass das Eingabearray (in den Beispielen "Hello world") aus stdin gelesen wird.

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)

Einige Testfälle:

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] "" ""

Ungolfed / erklärt

Linie 1

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

R hat einen netten Infix-Operator, :der Sequenzen erzeugt. 1:5gibt [1, 2, 3, 4, 5]und 0:-2gibt [0, -1, -2]. Daher ersetzen wir die TOKlausel im losen Bereich durch :.

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

Dolmetschen ANDist nur Verkettung. Wir können dafür die Funktion verwenden c, die in der Lage ist, eine beliebige Anzahl von Argumenten durch Kommas zu trennen. So ersetzen wir ANDmit,

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

und dann wickeln die ganze Sache in c(, ).

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

Dies ergibt eine Zeichenkette, die so aussehen könnte c( 1 : 5 , 7 ). Wir rufen parseauf, in den Typ "expression" umzuwandeln und dann evalden Ausdruck auszuwerten. Die resultierende Zahlenfolge wird dann der Variablen neu zugewiesen r.

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

Zeile 2

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

Nun zum hässlichen Teil - Umgang mit Strings in R, die schnell chaotisch werden. Zuerst definieren wir eeine leere Zeichenkette (wir werden diese später brauchen).

                      e<-""

Wir lesen aus stdin und konvertieren die Zeichenkette in ein Array einzelner Zeichen, indem wir die leere Zeichenkette aufteilen. (ZB gehen wir von "Hi" nach ["H", "i"].) Dies gibt eine Liste der Länge 1 zurück, also müssen wir nach dem ersten Element fragen [[1]], um ein Array zu erhalten, mit dem wir arbeiten können. Ugh, ich habe dich gewarnt, das war chaotisch.

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

R-Indizes beginnen bei 1 und haben eine nette Funktion mit negativen Zahlen. Angenommen, xist ['a', 'b', 'c']. Es ist x[1]nicht überraschend, wenn Sie anrufen 'a'. Das Aufrufen x[-1]gibt alle x außer index zurück 1, dh ['b', 'c']. Dies ist eine coole Funktion, bedeutet aber, dass wir mit unseren negativen Indizes für dieses Problem vorsichtig sein müssen. Im Moment geben wir nur die Elemente des Eingabearrays mit Index zurück >0und weisen das Ergebnis zu o.

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

Zeile 3

Es gibt jedoch ein Problem! Bei Indizes, die länger als das Array sind, gibt R nur NAWerte zurück. Wir brauchen es, um leere Zeichenketten zurückzugeben. Also haben wir die Elemente neu zu definieren , ofür die is.na(o)ist TRUEdie leere Zeichenkette zu sein.

o[is.na(o)]=e

Zeile 4

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

Wie gehen wir mit den negativen (und Null-) Indizes um? Sie alle müssen die leere Zeichenfolge zurückgeben, daher wiederholen wir die leere Zeichenfolge N-mal, wobei N die Anzahl der Indizes ist, die vorhanden sind <1.

  rep(e,sum(r<1))

Schließlich verknüpfen wir die zuvor definierte oListe mit dieser (möglicherweise leeren) Liste.

c(      ...      ,o)
rturnbull
quelle
2

JavaScript (ES6), 141

Unbenannte Funktion mit 2 Parametern, wobei der erste das Zeichenarray ist (kann auch eine Zeichenfolge sein), der zweite die Zeichenfolge, die die Bereichsdefinition enthält.

Der Rückgabewert ist ein Array, in dem jedes Element entweder ein einzelnes Zeichen oder der js-Wert sein kann undefined. Wenn diese Zeichenfolge als String definiert ist, wird eine Folge von durch Kommas getrennten Zeichen als "leeres" Zeichen angezeigt - als Testfälle in der ersten Version der Frage.
Mit .joinkönnen Sie ein Zeichenfolgenergebnis erhalten, das der Testfallausgabe in der aktuellen Version der Frage ähnelt.

(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

Weniger golfen

(
 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

Prüfung

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
quelle
1

Perl - 110 Bytes

Aufrufen des Skripts in der Befehlszeile mit der Zeichenfolge als erstem Argument und dem Bereich als zweitem.

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

Enttarnt:

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
quelle
1

Python 2, 146 Bytes

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)]

Alle Tests sind auf ideone

Teilt die Klausel sauf "AND", teilt jede der resultierenden Unterklauseln auf "TO", konvertiert die resultierenden Zeichenfolgen in intusing map. Die Ergebnisse enthalten entweder 1 oder 2 Elemente (1, wenn in der Unterklausel kein "TO" vorhanden war).
Erstellt für jeden dieser Bereiche 0-basierte Bereiche unter Verwendung des Schrittparameters range als 1 oder -1, indem die Werte bei den Indizes 0 und -1 überprüft werden (eine Liste mit einem Eintrag enthält diesen Eintrag bei beiden Indizes).
Durchläuft diese Bereiche und erstellt eine Liste der Ausgabe, wenn die bereitgestellten Indizes in range ( if 0<=i<len(a)) sind.

Jonathan Allan
quelle
0

Jelly , 28 27 25 Bytes

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

TryItOnline (funktioniert auch mit einem String anstatt mit einem Array von Zeichen)

Wie?

œṣ⁾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
quelle
0

Clojure 232 230 229 Bytes

Oh, was für ein Monster, das ich erschaffen habe ... Aber eigentlich war das 260, als ich es einreichen wollte.

Edit: entfernt , um einen Raum aus #(get r %_""), (if_(< f t)und (take-nth 2_%)(als _).

(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 "))))))))

Weniger golfen:

(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)))))

Verwendet clojure.string/split, um durch "AND" und "" zu teilen,take-nth löscht "TO" zwischen ganzen Zahlen, der Funktionsargumentvergleich behandelt den Fall von 1 oder 2 Argumenten und das ist es.

Aufrufkonvention: (f "Hello World" "1 TO 3 AND 2 AND 8 TO 2")

NikoNyrh
quelle
Sie können eine Menge Bytes entfernen, indem Sie im Allgemeinen Leerzeichen entfernen, insbesondere zwischen den #Zeichen.
Clismique
Sind Sie sicher, dass ich ein Leerzeichen zwischen irgendwelchen entfernen könnte #? Ich habe es ohne Erfolg versucht, es wird mit dem vorherigen Token "zusammengeführt". Oh, noch ein Platz, den du vorher entfernen musst %.
NikoNyrh