Sätze umkehren

15

Das Ziel dieser Herausforderung ist es, eine Eingabe und Ausgabe dieser Eingabe zu erhalten, jedoch mit umgekehrter Satzreihenfolge. Beispiel Eingabe:

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

Beispielausgabe:

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

Wie Sie den Beispielen entnehmen können, muss Ihr Programm mit Fragezeichen, Ausrufezeichen und Punkten umgehen. Sie können davon ausgehen, dass jeder Satz eine Interpunktion und ein Leerzeichen vor dem nächsten Satz enthält. Nachgestellte Leerzeichen / Zeilenumbrüche sind in Ordnung, solange sie lesbar sind. Kürzester Code gewinnt.

Viel Glück!

BEARBEITEN: Sie können davon ausgehen, dass der Satz keine Anführungszeichen oder Klammern enthält, aber wenn Sie dafür sorgen, dass Ihr Code mit beiden umgehen kann, erhalten Sie -5 Byte. Beispielausgabe für Parens / Quotes:

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

quelle
Können wir davon ausgehen, dass es keine Anführungszeichen oder Klammern geben wird? Wenn nicht, wie gehen wir damit um?
BrainSteel
Bearbeitet den Beitrag, um das zu klären.
Können Sie bitte ein Beispiel für die erwartete Ausgabe eines Satzes mit Anführungszeichen oder Parens geben?
mbomb007
6
Wie sollen wir damit umgehen, wenn ein Satz in Anführungszeichen oder in Parentsatzzeichen gesetzt ist?
isaacg
2
@Scimonster Du meinst "ie" usw., oder? Oh, und bitte ändern Sie mein Testfall-Zitat wie folgt:"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.
Nicht dass Charles

Antworten:

9

Julia, 45 42 Bytes - 5 Bonus = 37

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

Dadurch wird eine anonyme Funktion erstellt, die eine Zeichenfolge als Eingabe akzeptiert und die Zeichenfolge mit ihren Sätzen in umgekehrter Reihenfolge zurückgibt. Hiermit werden Sonderzeichen angemessen behandelt, obwohl doppelte Anführungszeichen und Dollarzeichen maskiert werden müssen, da sie sonst in Julia keine gültigen Zeichenfolgen sind.

Ungolfed + Erklärung:

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

Beispiele:

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

Und wenn Sie nicht gerne die ausgeblendeten Anführungszeichen in der Ausgabe betrachten:

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.

3 Bytes beim regulären Ausdruck gespart dank Martin Büttner! Früher verwendete dies ein Lookbehind: (?<=[.?!]).

Alex A.
quelle
Ich glaube nicht, dass dies für den Bonus qualifiziert ist ...
Optimizer
@Optimizer: Wie geht das nicht? Es funktioniert wie erwartet mit Klammern, Anführungszeichen usw., wie im Beitrag angegeben.
Alex A.
Können Sie einen Online-Link zum Testen bereitstellen, mit dem Beispiel aus dem Bonusbereich der Frage.
Optimierer
@Optimizer: Die einzige Möglichkeit, eine aktuelle Version von Julia online auszuführen, erfordert eine Registrierung und unterstützt keine Permalinks. Würde es genügen, einfach Input und Output hier in die Post aufzunehmen?
Alex A.
Sicher, ich denke ..
Optimierer
7

CJam, 23 22 Bytes

Ich bin nicht sicher, ob dies für den Bonus geeignet ist oder nicht, aber hier ist die Lösung:

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

Code-Erweiterung (etwas veraltet) :

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

Probieren Sie es hier online aus

Optimierer
quelle
Ah, du hast diesen Beitrag gleich gemacht, nachdem ich ihn zuerst bearbeitet habe. Du bekommst jetzt einen -5 Bonus (nur um es etwas schwieriger zu machen) Also -5 Bonus für dich! 18 Bytes, wow, nicht sicher, ob das schlagbar ist: P
5

J 35, 32

Es kann fast mit Bonus-Eingaben umgehen, außer dass ich einzelne Apostrophe entfernen muss, also denke ich, dass es nicht zählt. (Auch meine erste Einreichung hier)

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

Verwendung:

f 'Hello friend. What are you doing? I bet it is something I want to do too!'
Adrian17
quelle
4

Perl, 27/25

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

Oder von der Kommandozeile:

$perl -nE'say reverse/ |[^.!?]*./g'
nutki
quelle
Nett! Sie können den -5 Bonus mit erhalten perl -nE 'say reverse/ |[^.?!]*.\)?/g', was Ihre Gesamtzahl auf 23
erhöht
2

PHP, 60

echo join(' ',array_reverse(preg_split('/(?<=[?!.])/',$s)));
romanisch
quelle
Können Sie [?!.]\Kstattdessen den regulären Ausdruck verwenden?
Martin Ender,
Fügt dies auch keine zusätzlichen Leerzeichen in die Zeichenfolge ein, es sei denn, Sie fügen das zu teilende Leerzeichen in das Muster ein?
Martin Ender,
@ MartinBüttner, nein, ich kann das richtige Vorzeichen beim Zusammenfügen von Daten nicht wiederherstellen, also brauchen wir etwas, das das Zeichen nicht verbraucht.
Romaninsh
2

Bash + Coreutils, 40 Bytes

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

Dies liest von STDIN, so dass Eingaben von einer Datei umgeleitet oder einfach weitergeleitet werden können, zB:

$ 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. 
$ 
Digitales Trauma
quelle
Funktioniert das wirklich für Klammern in dem Sinne, dass diese (foo bar.)als Einheit getauscht werden?
Martin Ender
@ MartinBüttner Sieht so aus, als ob die Frage bearbeitet wurde, sodass ich den Bonus nicht mehr beanspruchen kann :(
Digitales Trauma
2

Pip , 25 Bytes

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

Nach dem Anhängen eines Leerzeichens an die Eingabezeichenfolge finden wir alle Indizes von ., ?und !, addieren 2 und verwenden den ^@Operator split-at, um die Zeichenfolge in Sätze zu unterteilen (jeweils mit einem nachgestellten Leerzeichen). Kehren Sie die Liste um und sie wird am Ende des Programms automatisch gedruckt. Voilà!

Beispiel mit den Stufen der Hauptberechnung mit Eingabe 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
quelle
Nein, das tust du nicht :)
Optimierer
2

Retina , 61 34 33 30 Bytes

Dank an nutki für die Reduzierung um 24 Byte.

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

Wobei <empty>für eine Leerzeile steht. Dies setzt voraus, dass dies #nicht Teil der Eingabe ist, aber wenn dies nicht legitim ist, könnte ich es gegen jedes andere Zeichen "austauschen , einschließlich (das ich nur für den Bonus behandeln müsste) oder etwas Unbedruckbares. Sie können den Code wie -sfolgt in einer einzelnen Datei ausführen, wenn Sie das Flag verwenden, oder Sie können jede Zeile in eine separate Datei einfügen und sie alle an Retina übergeben.

Dies mit einem einzigen Regex-Austausch rückgängig zu machen ist möglich, aber sehr umständlich. Selbst mit .NET-Bilanzgruppen benötigte ich ungefähr 90 Bytes, also versuchte ich es stattdessen in mehreren Schritten.

In der Netzhaut ist jedes Linienpaar eine Ersetzungsstufe, wobei die erste Linie das Muster und die zweite Linie die Ersetzung ist.

^
#

In dieser Phase wird der String einfach für die weitere Verarbeitung vorbereitet. Es geht a #als Marker voran . Dieser Marker zeigt an, dass alles davor bereits an der richtigen Stelle platziert wurde und alles danach noch verarbeitet werden muss.

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

In dieser Phase werden die Sätze vertauscht, indem der letzte Satz vor dem Satz wiederholt verschoben wird #(der sich dabei durch die Zeichenfolge vorwärts bewegt). Das +`weist Retina an, diese Phase zu wiederholen, bis sich die Ausgabe nicht mehr ändert. Als Beispiel sehen Sie hier, wie die Eingabe foo. bar! blah?verarbeitet wird:

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

Und zum Schluss entfernen wir einfach den Marker:

#
<empty>
Martin Ender
quelle
Warum nicht einfach .+=> $0 #und wiederholt (.*?[.!?] )(.*#)=> $2$1?
Nutki
@nutki Oh, das ist viel schöner, danke. :)
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
quelle
1

JavaScript (ES6) 47 45

Wie es heißt, ist es eine einfache Regex-Übung. In 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
quelle
Ich wollte Javascript machen, aber du hast mich geschlagen.
BobTheAwesome
Dies erzeugt zusätzliche Leerzeichen vor allen bis auf den letzten Satz (ursprünglich den ersten). Ich bin mir nicht sicher, ob es in Ordnung ist, da die Aufgabe nicht sehr genau definiert ist.
Nutki
@nutki ja, ich stimme zu. Feste
edc65
1

Python 2, 62

Wird sich für den Bonus nicht verbessern, da es wahrscheinlich die Bytekosten nicht wert ist.

import re
print' '.join(re.split('(?<=[?!.]).',input())[::-1])
mbomb007
quelle
Dies qualifiziert nicht für den Bonus. Schauen Sie sich das Bonusbeispiel in der Frage an
Optimizer
@Optimizer Im Fragenverlauf nachsehen. Als ich meine Frage aktualisiert habe, um den Bonus hinzuzufügen, stimmte meine Ausgabe mit dem Beispiel überein. Nichts deutete darauf hin, dass sich eine Klammer außerhalb eines Zeitraums befinden könnte.
mbomb007
Ich denke, die Absicht war dies nur von Anfang an. Ein gutes Beispiel kam später. Bedeutet nicht, dass du den Bonus noch bekommst :) (Meins habe ich auch entfernt)
Optimizer
1

Matlab (93 Bytes)

y=[32 input('','s')];y=sortrows([cumsum(ismember(y,'?!.'),'reverse');y]',1)';disp(y(4:2:end))
  • Dies setzt voraus, dass die Eingabe keine führenden oder nachfolgenden Leerzeichen enthält
  • Verwendet Standardeingabe und -ausgabe
  • Getestet in Matlab 2014b
Luis Mendo
quelle
1

Rubin 41

Die anderen Ruby-Antworten haben nicht genug WTF.

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

Dies funktioniert zumindest in Ruby 2. Wenn der Schalter aund Fin 1.8.7 funktioniert, können Sie wahrscheinlich $_=drei Zeichen speichern.

Kehrt jede Zeile auf stdin um und druckt auf stdout:

$ ruby foo.rb <<< "Hello. Hi. How are you? Good, you? fine, thanks."
fine, thanks. Good, you? How are you? Hi. Hello.
daniero
quelle
Könnten Sie bitte die Antwort erklären.
Mhmd
1

Ruby, 48 (42 ohne die Puts) Bytes

reverse_sentence.rb

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

Verwendung:

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

Ausgabe:

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

Kritik mehr als willkommen.

DickieBoy
quelle
2
Kritik: Sie haben "Satz" falsch geschrieben.
Alex A.
6 Zeichen speichern: .join(" ")=>*" "
daniero
@AlexA. Bestes Feedback aller Zeiten!
DickieBoy
@ daniero danke, schön zu wissen
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."
tmartin
quelle
0

C # - LINQPAD - 93 - 5 = 88 Bytes

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

C # -Konsolenanwendung 189 - 5 = 184 Byte

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

Regex schamlos von Alex A. ausgepeitscht :)

jzm
quelle
Sie können 7 Bytes einsparen, indem Sie Ihre Anwendung namespace Systemdann innerhalb dieses using Linq;usingText.RegularExpressionsSpeichers 2x einfügen system.
Damals,
Ich glaube nicht, dass dies für den Bonus qualifiziert ist. Schauen Sie sich das Bonusbeispiel in der Frage an
Optimizer
0

Clojure - 44 71 Zeichen

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

Verbesserte und vereinfachte RE, unnötige Leerzeichen beseitigt.

Die Ausgabe ist eine Folge der Sätze in der Originalzeichenfolge, wobei die Reihenfolge der Sätze umgekehrt ist:

Input: "Hallo Freund. Was machst du? Ich wette, das ist etwas, was ich auch tun möchte!" Ausgabe: ("Ich wette, das ist etwas, was ich auch tun möchte!" "Was machst du?" "Hallo Freund.")

Bob Jarvis - Setzen Sie Monica wieder ein
quelle
0

Rubin, 47

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

Dank an Martin Büttner für das Speichern einiger Charaktere.

Mhmd
quelle
1
Sie können die Eingabe von STDIN mit lesen gets, um ein Byte zu speichern, mit drucken $><<, um Byte zu speichern (kein Leerzeichen erforderlich) und die Zeichenfolge mit verbinden *'', um zwei Bytes zu speichern.
Martin Ender,
@ Martinbüttner danke für den vorschlag, ich würde allerdings nicht mit dem einlesen von stdin anfangen. Einfach, weil es eine nachgestellte neue Zeile geben wird.
Mhmd
Eigentlich denke ich, dass Ihr Code derzeit zu einem führenden Platz führen wird.
Martin Ender
mmm, du hast recht. Ich werde sehen, was ich tun soll.
Mhmd
0

CJam, 21 Bytes

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

Dies funktioniert, indem die Leerzeichen nach !s, .s und ?s in die Zahl 1 umgewandelt werden (weder das Zeichen 1 noch das Zeichen mit dem Codepunkt 1, sodass die Eingabe diese weiterhin enthalten kann), bei 1 geteilt wird, die Reihenfolge der resultierenden Blöcke umgekehrt und verbunden wird durch Leerzeichen.

Probieren Sie es online im CJam-Interpreter aus .

Wie es funktioniert

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
quelle