Odwróć zdania

15

Celem tego wyzwania jest uzyskanie danych wejściowych i wyjściowych, ale z odwróconą kolejnością zdań. Przykładowe dane wejściowe:

Hello friend. What are you doing? I bet it is something I want to do too!

Przykładowe dane wyjściowe:

I bet it is something I want to do too! What are you doing? Hello friend.

Jak widać z przykładów, twój program musi radzić sobie ze znakami zapytania, wykrzyknikami i kropkami. Możesz założyć, że każde zdanie ma interpunkcję i spację przed następnym zdaniem. Końcowe spacje / znaki nowej linii są prawidłowe, o ile są czytelne. Najkrótszy kod wygrywa.

Powodzenia!

EDYCJA: Możesz założyć, że w zdaniach nie ma cudzysłowów ani nawiasów, ale jeśli sprawisz, że Twój kod będzie w stanie poradzić sobie z nimi obojgiem, otrzymasz -5 bajtów Przykład danych wyjściowych dla parens / quote:

"Hello, " she said. (I didn't know what she was talking about.) --> (I didn't know what she was talking about.) "Hello, " she said.

źródło
Czy możemy założyć, że nie będzie żadnych cytatów ani nawiasów? Jeśli nie, jak sobie z nimi poradzimy?
BrainSteel
Dokonałem edycji postu, usuwając to.
Czy możesz podać przykład oczekiwanego wyniku dla zdania zawierającego cytaty lub pareny?
mbomb007
6
Jeśli w zdaniu występuje interpunkcja w cudzysłowie lub parens, jak powinniśmy sobie z tym poradzić?
isaacg
2
@ Scimonster Masz na myśli „ie” itp., Prawda? Aha, i proszę o poprawienie mojego cytatu przypadku testowego:"Hello!" she said. (I hesitated. How should I respond? This is too much!) I responded, "Hi there. How are you? What is your cat's name?" without thinking any more about it.
Nie, że Charles

Odpowiedzi:

9

Julia, 45 42 bajtów - 5 bonusów = 37

s->join(reverse(split(s,r"[.?!]\K "))," ")

Tworzy to anonimową funkcję, która akceptuje ciąg wejściowy i zwraca ciąg znaków z odwróconymi zdaniami. Obsługuje to odpowiednio każdy znak specjalny, jednak należy unikać znaków podwójnych cudzysłowów i znaków dolara, w przeciwnym razie nie są one poprawnymi ciągami znaków w Julii.

Niegolfowane + wyjaśnienie:

function f(s)
    # Get individual sentences by splitting on the spaces that
    # separate them. Spaces are identified by matching punctuation
    # then moving the position beyond that match and matching a
    # space. This is accomplished using \K.

    sentences = split(s, r"[.?!]\K ")

    # Reverse the order of the array of sentences.

    reversed_order = reverse(sentences)

    # Join the array elements into a string, separated by a space.

    join(reversed_order, " ")
end

Przykłady:

julia> f("Hello friend. What are you doing? I bet it is something I want to do too!")
"I bet it is something I want to do too! What are you doing? Hello friend."

julia> f("\"Hello, \" she said. (I didn't know what she was talking about.)")
"(I didn't know what she was talking about.) \"Hello, \" she said."

A jeśli nie lubisz patrzeć na znaki ucieczki w danych wyjściowych:

julia> println(f("\"Hello, \" she said. (I didn't know what she was talking about.)"))
(I didn't know what she was talking about.) "Hello, " she said.

Zaoszczędź 3 bajty na wyrażeniu regularnym dzięki Martinowi Büttnerowi! Wcześniej używany lookbehind: (?<=[.?!]).

Alex A.
źródło
Nie sądzę, że to kwalifikuje się do premii ...
Optymalizator
@Optimizer: Jak to nie działa? Działa zgodnie z oczekiwaniami z nawiasami, cytatami itp. Podanymi w poście.
Alex A.
Czy możesz podać link online do przetestowania, na przykład z sekcji bonusowej pytania.
Optymalizator
@Optimizer: Jedyny sposób na uruchomienie najnowszej wersji Julii online wymaga rejestracji i nie obsługuje bezpośrednich łączy. Czy wystarczy umieścić w poście dane wejściowe i wyjściowe?
Alex A.
Pewnie, tak myślę ...
Optymalizator
7

CJam, 23 22 bajtów

Nie jestem pewien, czy to kwalifikuje się do premii, czy nie, ale oto rozwiązanie:

Sq{1$".?!"-{])[}|}%]W%

Rozszerzenie kodu (nieco nieaktualne) :

Sq+                      e# Read the input and prepend with a space
   {            }%       e# For each input character
    _".?!"&              e# Copy and check if its one of ., ? and !
           {][}&         e# If it is one of the above, wrap everything till now in an array
                         e# and start a new array to be wrapped next time we get one of those
                         e# three characters. We now have an array of strings, each having
                         e# a single sentence
                  W%     e# Reverse the ordering of these sentences
                    s(   e# Convert to string and remove the first space

Wypróbuj online tutaj

Optymalizator
źródło
Ach, napisałeś ten post zaraz po tym, jak go zredagowałem. Otrzymujesz teraz bonus -5 (żeby było trochę trudniej) Więc więc bonus -5 dla Ciebie! 18 bajtów, wow, nie jestem pewien, czy to do
5

J, 35 32

Prawie obsługuje wkład dodatkowy, z tym że muszę uciec przed pojedynczymi apostrofami, więc myślę, że to się nie liczy. (Również moje pierwsze zgłoszenie tutaj)

f=.;@|.@(]<;.2~'.?!'e.~])@,~&' '

Stosowanie:

f 'Hello friend. What are you doing? I bet it is something I want to do too!'
Adrian17
źródło
4

Perl, 27/25

#!perl -n
print reverse/ |[^.!?]*./g

Lub z wiersza poleceń:

$perl -nE'say reverse/ |[^.!?]*./g'
nutki
źródło
Ładny! Możesz uzyskać premię -5 perl -nE 'say reverse/ |[^.?!]*.\)?/g', dzięki czemu Twoja łączna liczba
wyniesie
2

PHP, 60

echo join(' ',array_reverse(preg_split('/(?<=[?!.])/',$s)));
romaninsh
źródło
Czy możesz [?!.]\Kzamiast tego użyć wyrażenia regularnego ?
Martin Ender
Czy to również nie dodaje dodatkowych spacji do łańcucha, chyba że uwzględnisz spację we wzorcu, według którego chcesz podzielić?
Martin Ender
@ MartinBüttner, nie, nie będę w stanie przywrócić właściwego znaku przy ponownym łączeniu danych, więc potrzebujemy czegoś, co nie pochłonie postaci.
romaninsh
2

Bash + coreutils, 40 bajtów

sed 's/\([?.!]\) */\1\n/g'|tac|tr \\n \ 

Odczytuje to ze STDIN, więc dane wejściowe mogą mnie przekierować z pliku lub po prostu potokować, np .:

$ printf 'Hello friend. What are you doing? I bet it is something I want to do too!' | sed 's/\([?.!]\) */\1\n/g'|tac|tr \\n \ 
I bet it is something I want to do too! What are you doing? Hello friend. 
$ 
Cyfrowa trauma
źródło
Czy to naprawdę działa w nawiasach w tym sensie, że (foo bar.)zamienia się je jako jednostkę?
Martin Ender
@ MartinBüttner Wygląda na to, że pytanie zostało zredagowane, więc nie mogę już ubiegać się o bonus :(
Cyfrowa trauma
2

Pip , 25 bajtów

a.:sRV(a^@2+$ALa@*^".?!")

Po spacje do ciągu wejściowego, znajdziemy wszystkie indeksy ., ?i !dodaj 2, i korzystać z ^@podzielonego na operatora, aby przerwać łańcuch na zdania (każdy ze spacją). Odwróć listę, a zostanie ona automatycznie wydrukowana na końcu programu. Voilà!

Przykład pokazujący etapy głównego obliczenia z danymi wejściowymi A! B? C. D!:

              ^".?!"     ["." "?" "!"]
           a@*           [[7] [4] [1 10]]
        $AL              [7 4 1 10]
      2+                 [9 6 3 12]
   a^@                   ["A! " "B? " "C. " "D! "]
RV(                 )    ["D! " "C. " "B? " "A! "]

                         D! C. B? A! 
DLosc
źródło
Nie, nie wiesz :)
Optymalizator
2

Retina , 61 34 33 30 bajtów

Kredyty dla nutki za zmniejszenie tego o 24 bajty.

^
#
+`(#.*[.!?]) (.+)
$2 $1
#
<empty>

Gdzie <empty>oznacza pustą linię. Zakłada się, że #nie jest to część danych wejściowych, ale jeśli nie jest to uzasadnione, mógłbym zamienić je na dowolną inną postać, w tym "(którą musiałbym poradzić sobie tylko dla bonusu) lub coś, co nie da się wydrukować. Możesz uruchomić taki kod w jednym pliku, jeśli używasz -sflagi, lub możesz umieścić każdą linię w osobnym pliku i przekazać je wszystkie do Retina.

Odwrócenie tego za pomocą pojedynczej zamiany wyrażenia regularnego jest możliwe, ale naprawdę kłopotliwe. Nawet z grupami równoważącymi .NET potrzebowałem czegoś około 90 bajtów, więc zamiast tego próbowałem zrobić to w kilku krokach.

W siatkówce każda para linii jest jednym etapem zastępowania, gdzie pierwsza linia jest wzorem, a druga linia jest zamiennikiem.

^
#

Ten etap po prostu przygotowuje ciąg do dalszego przetwarzania. Przygotowuje #jako marker. Ten znacznik wskazuje, że wszystko przed nim zostało już umieszczone we właściwym miejscu, a wszystko po nim nadal musi zostać przetworzone.

+`(#.*[.!?]) (.+)
$2 $1

Ten etap zamienia zdania, kilkakrotnie przesuwając ostatnie zdanie przed #(podczas tego procesu przesuwa się do przodu przez łańcuch). +`Instruuje Retina powtórzyć ten etap aż wyjście przestaje się zmieniać. Oto przykład, w jaki sposób dane wejściowe foo. bar! blah?zostaną przetworzone:

#foo. bar! blah?
blah? #foo. bar!
blah? bar! #foo.

Na koniec po prostu usuwamy znacznik:

#
<empty>
Martin Ender
źródło
Dlaczego nie tylko .+=> $0 #i powtórzone (.*?[.!?] )(.*#)=> $2$1?
nutki
@nutki Oh, to o wiele ładniejsze, dziękuję. :)
Martin Ender
1

Java, 113

s->{String t[]=s.split("(?<=[\\.?!]) "),u="";for(int i=t.length;i-->0;)u+=t[i]+" ";return u.replaceAll(".$","");}
Ypnypn
źródło
1

JavaScript (ES6) 47 45

Jak powiedziano, jest to proste ćwiczenie wyrażenia regularnego. W javascript:

// ES6 - FireFox only
F=t=>t.match(/\S[^.!?]+./g).reverse().join(' ')

// ES5 - so much longer
function G(t){return t.match(/\S[^.!?]+./g).reverse().join(' ')}

// TEST

alert(G("Hello friend. What are you doing? I bet it is something I want to do too!"))
 

edc65
źródło
Zamierzałem zrobić javascript, ale pobiłaś mnie.
BobTheAwesome
Daje to dodatkowe spacje przed wszystkimi oprócz ostatniego zdania (pierwotnie pierwszego). Nie jestem pewien, czy wszystko jest w porządku, ponieważ zadanie nie jest dobrze zdefiniowane.
nutki
@nutki tak, zgadzam się. Naprawiono
edc65
1

Python 2, 62

Bonus nie ulegnie poprawie, ponieważ prawdopodobnie nie jest wart kosztu bajtu.

import re
print' '.join(re.split('(?<=[?!.]).',input())[::-1])
mbomb007
źródło
To nie kwalifikuje się do premii. Spójrz na przykład premii w pytaniu
Optymalizator
@Optimizer Zajrzyj do historii pytań. W momencie, gdy zaktualizowałem swoje pytanie, aby dodać premię, moje wyniki były zgodne z przykładem. Nic nie wskazywało na to, że nawiasy mogą znajdować się poza okresem.
mbomb007
Myślę, że intencją było to od samego początku. Dobry przykład przyszedł później. Nie oznacza to, że nadal otrzymujesz bonus :) (ja też usunąłem mój)
Optymalizator
1

Matlab (93 bajty)

y=[32 input('','s')];y=sortrows([cumsum(ismember(y,'?!.'),'reverse');y]',1)';disp(y(4:2:end))
  • Zakłada się, że dane wejściowe nie zawierają początkowych ani końcowych spacji
  • Wykorzystuje standardowe wejście i wyjście
  • Testowane w Matlabie 2014b
Luis Mendo
źródło
1

Rubinowy 41

Inne odpowiedzi Ruby nie mają wystarczającej ilości WTF.

#!ruby -apF(?<=[.!?])\s
$_=$F.reverse*" "

Działa to przynajmniej w Ruby 2. Jeśli przełącznik ai Fdziała w 1.8.7, myślę, że możesz upuścić, $_=aby zapisać trzy postacie.

Odwraca każdą linię na standardowym ekranie i drukuje na standardowe wyjście:

$ ruby foo.rb <<< "Hello. Hi. How are you? Good, you? fine, thanks."
fine, thanks. Good, you? How are you? Hi. Hello.
daniero
źródło
Czy możesz wyjaśnić odpowiedź.
Mhmd
1

Ruby, 48 (42 bez puttów) bajtów

reverse_sentence.rb

puts $*[0].scan(/\S[^.!?]+./).reverse.join(" ")

Stosowanie:

ruby reverse_sentence.rb 'Hello friend. What are you doing? I bet it is something I want to do too!'

Wynik:

I bet it is something I want to do too! What are you doing? Hello friend.

Krytyka bardziej niż mile widziana.

DickieBoy
źródło
2
Krytyka: niepoprawnie przeliterowałeś „zdanie”.
Alex A.,
zapisz 6 znaków: .join(" ")=>*" "
daniero
@AlexA. Najlepsza opinia!
DickieBoy,
@daniero dzięki, miło wiedzieć
DickieBoy
1

k, 31

{1_,/|(0,1+&x in"?!.")_x:" ",x}

.

k){1_,/|(0,1+&x in"?!.")_x:" ",x} "Hello friend. What are you doing? I bet it is something I want to do too!"
"I bet it is something I want to do too! What are you doing? Hello friend."
tartin
źródło
0

C # - LINQPAD - 93 - 5 = 88 bajtów

void Main(){string.Join(" ",Regex.Split(Console.ReadLine(),"(?<=[.?!]) ").Reverse()).Dump();}

Aplikacja konsoli C # 189 - 5 = 184 bajty

using System;using System.Linq;using System.Text.RegularExpressions;class P{static void Main(){Console.WriteLine(string.Join(" ",Regex.Split(Console.ReadLine(), "(?<=[.?!]) ").Reverse()));}}

regex bezwstydnie chłostał Alex A. :)

jzm
źródło
Możesz zapisać 7 bajtów, umieszczając aplikację w namespace Systemtym using Linq;usingText.RegularExpressionsoszczędności 2x system.
dam
Nie sądzę, że to kwalifikuje się do premii. Spójrz na przykład premii w pytaniu
Optymalizator
0

Clojure - 44 71 znaków

(defn rs[s](reverse(re-seq #"\S.+?[.!?]"s)))

Ulepszone i uproszczone RE, wyeliminowane niepotrzebne białe znaki.

Dane wyjściowe to sekwencja zdań w oryginalnym ciągu znaków z odwróconą kolejnością zdań:

Wejście: „Witaj przyjacielu. Co robisz? Założę się, że to też coś, co chcę zrobić!” Wyjście: („Założę się, że to też chcę zrobić!” „Co robisz?” „Witaj przyjacielu.”)

Bob Jarvis - Przywróć Monikę
źródło
0

Ruby, 47 lat

$><<gets.strip.split(/(?<=[.?!]) /).reverse*' '

Podziękowania dla Martina Büttnera za uratowanie niektórych postaci.

Mhm
źródło
1
Możesz odczytać dane wejściowe ze STDIN za pomocą, getsaby zapisać bajt, wydrukować za pomocą, $><<aby zapisać bajt (bez potrzeby spacji) i połączyć ciąg z, *''aby zapisać dwa bajty.
Martin Ender
@ MartinBüttner dziękuję za sugestię, ale nie chciałbym czytać z wkładu STDIN. Po prostu dlatego, że pojawi się nowa linia.
Mhmd
Właściwie myślę, że twój kod spowoduje obecnie powstanie wiodącej przestrzeni.
Martin Ender
mmm, masz rację. Zobaczę co powinienem zrobić.
Mhmd
0

CJam, 21 bajtów

1q{1?_"!.?"-}%1a/W%S*

Działa to poprzez zamianę spacji po !s, .si ?na cyfrę 1 (nie znak 1 ani znak o punkcie kodowym 1, więc dane wejściowe mogą nadal zawierać je), dzielenie na 1, odwracanie kolejności wynikowych fragmentów i łączenie według spacji.

Wypróbuj online w interpretatorze CJam .

Jak to działa

1                     e# B := 1
 q                    e# Q := input()
  {         }%        e# for each C in Q (map):
   1?                 e#   C := B ? C : 1
     _"!.?"-          e#   B := string(C).strip("!.?")
              1a/     e# Q := Q.split([1])
                 W%   e# Q := reverse(Q)
                   S* e# Q := Q.join(" ")
                      e# print(Q)
Dennis
źródło