Interpretuj luźne zakresy

13

Interpretuj luźne zakresy

ListSharp to interpretowany język programowania, który ma wiele funkcji, jedną z nich jest kreator zasięgu oparty na indeksie 1, który działa w następujący sposób:

Definiujesz zakres jako (INT) TO (INT)lub tylko (INT)tam, gdzie oba lub pojedyncze int mogą przejść od wartości minimalnej do maksymalnej wartości int32

Następnie możesz użyć tych zakresów, aby wyodrębnić elementy tablicy bez obawy przekroczenia jej granic


w związku z tym:

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

3 generuje: {3}

Zakresy można dodawać za pomocą ANDoperatora

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

pamiętaj, że działa to również z liczbami ujemnymi

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


Wyzwanie jest następujące:

Wejście

Tablica znaków i poprzednio zdefiniowana klauzula zakresu jako ciąg

Wynik

Elementy w lokalizacjach zakresu na podstawie 1 indeksu (nieistniejące / ujemne indeksy tłumaczą się na pusty znak)


Jak wygrać

Jako wyzwanie do musisz stworzyć program z jak najmniejszą liczbą bajtów do wygrania


Podkreślono, że puste postacie nie istnieją, dlatego należy je ignorować (pokazałem je tutaj tylko po to, aby ułatwić ich zrozumienie, ale pomieszały ludzi)

Przypadki testowe:

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
źródło
3
Czy wolno nam używać 0-indeksu zamiast 1-indeksu jako ciągu wejściowego? Więc klauzula zakresu staje się "0 TO 2"=> {'H', 'e', 'l'}?
Kevin Cruijssen
Tabela ASCII nie ma pustego znaku (z wyjątkiem znaków niedrukowalnych). Co jest złego w korzystaniu z miejsca?
adrianmp
tablica char jest w zasadzie łańcuchem, dlatego puste znaki nie będą po prostu drukowane ani zwracane
downrep_nation 30.09.16
1
Ponadto, czy np. 3 TO 3Kiedykolwiek będzie wejściem i jakie jest oczekiwane wyjście?
Jordan
1
Potrzebujesz kilku przypadków testowych do ANDgenerowania wielu zakresów. Ponadto nie odpowiedziałeś, czy możemy korzystać z indeksowania zerowego, co jest standardem w większości języków.
mbomb007

Odpowiedzi:

5

Python 2 - 239 211 210 bajtów

Dzięki @ mbomb007 i @Cyoce za dalsze granie w golfa w tym rozwiązaniu!

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

Proste podejście. Wypróbowałem generatory i wersję rekurencyjną, ale nie potrafiły pokonać prostych dla każdej pętli. Jestem golfistą noob, więc najprawdopodobniej można to trochę poprawić. Główną wadą tego fragmentu jest to, że zakres jako obiekt listy jest obliczany ponownie za każdym razem, gdy element jest pobierany z tablicy znaków (patrz ostatni wiersz, opis listy). Oznacza r(s)to, że wykonywane są len(r(s)) + 1czasy.

Nieskluczony kod:

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

Przypadki testowe:

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

Wynik:

['H', 'e', 'l']
['o']
['', '', '', '', '', '', '', '', '', '', '', 'H', 'e', 'l', 'l', 'o', ' ', 'W', 'o', 'r', 'l']
['', 'e', 'l']
['o', 'W', ' ', 'o', 'l', 'l']
['', '']
1Darco1
źródło
Świetna pierwsza odpowiedź! Witamy w PPCG!
mbomb007
Możesz skorzystać z Porady dotyczące gry w golfa w Pythonie . Możesz zastąpić 2 spacje dla podwójnego wcięcia jedną kartą. Możesz umieścić kod pod iftym samym wierszem i oddzielić je średnikami. I usuń spację [x] for. Ponadto, 1if b else-1mogą być zastąpione albo b and 1or-1czy 2*bool(b)-1zapisać bajt.
mbomb007
Dzięki! Już spojrzałem na (i próbowałem) użyć. D niektóre z nich. Później ponownie przejrzę wszystkie odpowiedzi. :)
1Darco1
I myślę, że możesz użyć nienazwanego lambda, ponieważ nie jest to rekurencyjne.
mbomb007
1
t+=[int(x)]canbecomet+=int(x),
Cyoce
3

Groovy ( 99 97 bajtów)

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

Wypróbuj tutaj: https://groovyconsole.appspot.com/edit/5155820207603712

Wyjaśnienie:

  • .replaceAll(" TO ","..") - Zamień na na tradycyjny zakres.
  • .replaceAll(" AND ", ",") - Zastąp wszystkie znaki przecinkiem.
  • "[${...}]" - Otocz go notacją „list” w Groovy.
  • Eval.me(...) - Oceń ciąg jako kod Groovy.
  • .flatten() - Spłaszcz mieszaninę tablicy 2D i tablicy 1D do tablicy 1D.
  • .collect{v[it]} - Zbierz wskaźniki z tablicy w jedną strukturę.

Oto 115 113 bajtowe rozwiązanie usuwające wartości null z wyniku: https://groovyconsole.appspot.com/edit/5185924841340928

Oto 117-bajtowe rozwiązanie, jeśli powiesz, że MUSI być indeksowane na 1 zamiast 0: https://groovyconsole.appspot.com/edit/5205468955803648

Jeśli chcesz, żebym podmienił oryginał na bajt 113/117, daj mi znać.

Urna Magicznej Ośmiornicy
źródło
Jeśli nie podoba mi się, że używam „null” dla znaków, których nie ma, +5 bajtów na końcu dla „-null”, który usuwa wszystkie null z zestawu.
Magic Octopus Urn
1
Uwielbiam ten sprytny zbieg okoliczności
downrep_nation 30.09.16
Nauczyłem się jednak czegoś z tego, nigdy wcześniej nie wiedziałem, że Groovy Eval.me(...); użycie go w praktyce byłoby absurdalnie niepewne, co nadal jest fajną rzeczą.
Magic Octopus Urn
2

C #, 342 bajtów

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

Metoda bez golfa:

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

Pełny program z przypadkami testowymi:

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

Naiwne rozwiązanie, wykorzystujące listę ' 'znaków , która używa jako pustej postaci i wykonuje zadanie. Mając nadzieję na poprawę wkrótce.

adrianmp
źródło
2

Scala, 165 bajtów

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

Wyjaśnienie:

(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
źródło
2

Python 2, 156 155 bajtów

Moja odpowiedź ma kilka podobnych pomysłów jak odpowiedź 1Darco1 , ale stosując inne podejście od samego początku ( odcinanie łańcuchów zamiast list), skończyło się to nieco krócej. Byłoby cztery bajty krótsze, gdyby dozwolone było indeksowanie 0.

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

Wypróbuj online

Na szczęście mogę parsować ciągi zawierające spacje na liczby całkowite. Negatywne indeksowanie w indeksach Pythona od końca łańcucha, więc używam i[-1]albo tej samej i[0]wartości, albo drugiej wartości, jeśli taka istnieje. Następnie muszę dostosować wszelkie ujemne wartości zakresu do bardziej ujemnych, aby nie zadzierały z krojeniem. Pomnożenie wartości ujemnych przez 11**9( 2357947691) uwzględni zakresy przy użyciu minimalnej liczby całkowitej. Następnie po prostu pokrój łańcuch, używając odwrotnego plasterka, jeśli zakres jest odwrócony.

Z indeksowaniem zerowym (151 bajtów):

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
źródło
Dobra robota! Krojenie to zdecydowanie sposób, aby przejść tutaj. Moje rangepodejście jest w gruncie rzeczy po prostu bardzo gadatliwą formą właśnie tego. I nawet pozbyłeś się całej if"T"in x: else:części. +1
1Darco1
2

R, 142 bajty

Zakładając, że poprawnie zrozumiałem wyzwanie, tutaj zakładam, że rjest to wstępnie zdefiniowana klauzula zakresu w formacie łańcuchowym i że tablica wejściowa (w przykładach „Hello world”) jest odczytywana ze standardowego wejścia.

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)

Niektóre przypadki testowe:

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

Niegolfowane / wyjaśnione

Linia 1

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

R ma ładny operator infix, :który generuje sekwencje. 1:5daje [1, 2, 3, 4, 5]i 0:-2daje [0, -1, -2]. Zastępujemy więc TOklauzulę w swobodnym zakresie :.

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

Tłumaczenie ustne ANDjest po prostu konkatenacją. Możemy do tego użyć funkcji c, która z łatwością może przyjąć dowolną liczbę argumentów oddzielonych przecinkami. Więc zastąpić ANDz,

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

a następnie owinąć w całość c(, ).

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

Daje to ciąg znaków, który mógłby wyglądać c( 1 : 5 , 7 ). Wzywamy parsedo konwersji do typu „wyrażenie”, a następnie evaldo oceny wyrażenia. Wynikowa sekwencja liczb jest następnie ponownie przypisywana do zmiennej r.

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

Linia 2

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

Teraz część brzydka - radzenie sobie z łańcuchami w R, które szybko się psują. Najpierw określamy, eże jest to pusty ciąg (będziemy go później potrzebować).

                      e<-""

Czytamy ze standardowego wejścia i konwertujemy ciąg znaków na tablicę pojedynczych znaków, dzieląc pusty ciąg. (Np. Przechodzimy z „Cześć” do [„H”, „i”].). Zwraca to listę o długości 1, więc musimy poprosić o pierwszy element, [[1]]aby uzyskać tablicę, z którą możemy pracować. Ugh, ostrzegałem cię, że to bałagan.

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

Indeksy R zaczynają się od 1 i mają ładną funkcję z liczbami ujemnymi. Załóżmy, że xjest ['a', 'b', 'c']. Dzwonienie x[1]nic dziwnego powraca 'a'. Wywołanie x[-1]zwraca wszystkie x oprócz indeksu 1, tj ['b', 'c']. To fajna funkcja, ale oznacza, że ​​musimy uważać na nasze negatywne wskaźniki tego problemu. Na razie zwracamy tylko elementy tablicy wejściowej z indeksem >0i przypisujemy wynik do o.

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

Linia 3

Jest jednak problem! Dla indeksów, które są większe niż długość tablicy, R po prostu zwraca NAwartości. Potrzebujemy go, aby zwrócić puste ciągi. Zatem redefiniujemy elementy, odla których is.na(o)ma TRUEbyć pusty ciąg.

o[is.na(o)]=e

Linia 4

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

Wreszcie, jak radzimy sobie z ujemnymi (i zerowymi) wskaźnikami? Wszystkie muszą zwrócić pusty ciąg, więc powtarzamy pusty ciąg N razy, gdzie N jest liczbą indeksów <1.

  rep(e,sum(r<1))

Na koniec łączymy wcześniej zdefiniowaną oz tą (potencjalnie pustą) listą.

c(      ...      ,o)
rturnbull
źródło
2

JavaScript (ES6), 141

Nienazwana funkcja z 2 parametrami, pierwszy to tablica znaków (może być także ciągiem znaków), drugi to ciąg znaków zawierający definicję zakresu.

Zwracana wartość to tablica, w której każdy element może być pojedynczym znakiem lub wartością js undefined. Po zszeregowaniu skutkuje to sekwencją rozdzielonych przecinkami znaków, których niezdefiniowanie jest pokazane jako „pusty” znak - jako przypadki testowe w pierwszej wersji pytania.
Za pomocą tej opcji .joinmożesz uzyskać wynik łańcucha podobny do wyniku uzyskanego w przypadku testowym w bieżącej wersji pytania.

(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

Mniej golfa

(
 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

Test

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
źródło
1

Perl - 110 bajtów

Wywołanie skryptu w wierszu polecenia z ciągiem jako pierwszym argumentem i zakresem jako drugim.

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

Usunięto zaciemnienie:

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
źródło
1

Python 2, 146 bajtów

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

Wszystkie testy są w idealnym stanie

Dzieli klauzulę sna „AND”, dzieli każdą z powstałych pod-klauzul na „TO”, konwertuje otrzymane ciągi na intużycie map. Każdy z wyników będzie zawierał 1 lub 2 elementy (1, jeśli w podsekcji nie było „TO”).
Konstruuje zakresy oparte na 0 dla każdego z nich, używając parametru kroku zakresu jako 1 lub -1, sprawdzając wartości o indeksach 0 i -1 (lista z jednym wpisem ma ten wpis przy obu indeksach).
Przebiega przez te zakresy i konstruuje listę danych wyjściowych, jeśli podane indeksy są in-range ( if 0<=i<len(a)).

Jonathan Allan
źródło
0

Galaretka , 28 27 25 bajtów

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

TryItOnline (będzie również działał z łańcuchem zamiast tablicy znaków)

W jaki sposób?

œṣ⁾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
źródło
0

Clojure 232 230 229 bajtów

Och, jaki potwór stworzyłem ... Ale tak naprawdę było 260, kiedy miałem go zgłosić.

Edycja: usunięty z miejsca #(get r %_""), (if_(< f t)i (take-nth 2_%)(oznaczonych jako _).

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

Mniej golfa:

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

Używa clojure.string/splitpodziału przez „AND” i „”,take-nth upuszcza „TO” między liczbami całkowitymi, dopasowanie argumentów funkcji obsługuje przypadek 1 lub 2 argumentów i to wszystko.

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

NikoNyrh
źródło
Możesz usunąć wiele bajtów, usuwając spacje w ogóle, szczególnie między #znakami.
clismique
Czy na pewno mogę usunąć odstęp między nimi #? Próbowałem bez powodzenia, „scalono” go z poprzednim tokenem. Och, jeszcze jedno miejsce do usunięcia %.
NikoNyrh,