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.

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: (?<=[.?!]).


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


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!'

4

Perl, 27/25

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

Lub z wiersza poleceń:

$perl -nE'say reverse/ |[^.!?]*./g'

Ł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)));

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. 
$ 

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! 

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>

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(".$","");}

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


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

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

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.

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.


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

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. :)


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.”)


0

Ruby, 47 lat

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

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


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)
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.