Oraciones inversas

15

El objetivo de este desafío es recibir una entrada y salida de esa entrada pero con el orden de las oraciones invertido. Entrada de ejemplo:

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

Salida de ejemplo:

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

Como puede ver en los ejemplos, su programa tiene que lidiar con signos de interrogación, signos de exclamación y puntos. Puede suponer que cada oración tiene una puntuación y un espacio antes de la siguiente oración. Los espacios finales / líneas nuevas están bien, siempre y cuando sea legible. El código más corto gana.

¡Buena suerte!

EDITAR: puede suponer que las oraciones no tienen comillas ni paréntesis, pero si hace que su código sea capaz de lidiar con ambos, obtendrá -5 bytes Salida de ejemplo para 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.

fuente
¿Podemos suponer que no habrá citas o paréntesis? Si no, ¿cómo los manejamos?
BrainSteel
Hizo una edición en la publicación aclarando eso.
¿Puede dar un ejemplo de salida esperada para una oración que contiene comillas o parens, por favor?
mbomb007
66
Si una oración tiene puntuación entre comillas o parens, ¿cómo debemos tratarla?
isaacg
2
@Scimonster Te refieres a "ie", etc., ¿verdad? Ah, y modifique mi cita del caso de prueba para que sea:"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.
No es que Charles

Respuestas:

9

Julia, 45 42 bytes - 5 bonus = 37

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

Esto crea una función anónima que acepta una cadena como entrada y devuelve la cadena con sus oraciones invertidas. Esto maneja cualquier carácter especial de manera apropiada, aunque se deben escapar las comillas dobles y los signos de dólar, de lo contrario no son cadenas válidas en Julia.

Ungolfed + explicación:

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

Ejemplos:

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

Y si no le gusta mirar las comillas escapadas en la salida:

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.

¡Ahorré 3 bytes en la expresión regular gracias a Martin Büttner! Anteriormente, esta utiliza una búsqueda hacia atrás: (?<=[.?!]).

Alex A.
fuente
No creo que esto califique para la bonificación ...
Optimizer
@Optimizer: ¿Cómo no? Funciona como se espera con paréntesis, citas, etc. como se indica en la publicación.
Alex A.
¿Puede proporcionar un enlace en línea para probar, con el ejemplo de la sección de bonificación de la pregunta.
Optimizador de
@Optimizer: la única forma de ejecutar una versión reciente de Julia en línea requiere registro y no admite enlaces permanentes. ¿Sería suficiente simplemente incluir entradas y salidas aquí en la publicación?
Alex A.
Claro, supongo ..
Optimizer
7

CJam, 23 22 bytes

No estoy seguro de si esto califica para el bono o no, pero aquí está la solución:

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

Expansión de código (poco anticuado) :

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

Pruébalo en línea aquí

Optimizador
fuente
Ah, hiciste esta publicación justo después de que la edité al principio. Ahora obtienes una bonificación de -5 (solo para hacerlo un poco más difícil) ¡Entonces una bonificación de -5 para ti! 18 bytes, wow, no estoy seguro si eso es vencible: P
5

J, 35 32

Casi maneja la entrada de bonificación, excepto que tengo que escapar de apóstrofes individuales, por lo que supongo que no cuenta. (Además, mi primera presentación aquí)

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

Uso:

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

Perl, 27/25

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

O desde la línea de comando:

$perl -nE'say reverse/ |[^.!?]*./g'
nutki
fuente
¡Agradable! Puede obtener la bonificación de -5 perl -nE 'say reverse/ |[^.?!]*.\)?/g', con lo que su recuento total es 23.
ThisSuitIsBlackNot
2

PHP, 60

echo join(' ',array_reverse(preg_split('/(?<=[?!.])/',$s)));
romaninsh
fuente
¿Puedes usar la expresión regular en su [?!.]\Klugar?
Martin Ender
Además, ¿esto no agrega espacios adicionales en la cadena a menos que incluya el espacio en el patrón para dividir?
Martin Ender
@ MartinBüttner, no, no podré restablecer el signo adecuado al volver a unir datos, por lo que necesitamos algo que no consuma el carácter.
romaninsh
2

Bash + coreutils, 40 bytes

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

Esto se lee desde STDIN, por lo que la entrada puede redirigirse desde un archivo o simplemente canalizarse, por ejemplo:

$ 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. 
$ 
Trauma digital
fuente
¿Esto realmente funciona para paréntesis en el sentido, que (foo bar.)se intercambia como una unidad?
Martin Ender
@ MartinBüttner Parece que la pregunta se editó, por lo que ya no puedo reclamar el bono :(
Digital Trauma
2

Pip , 25 bytes

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

Después de agregar un espacio a la cadena de entrada, encontramos todos los índices de ., ?y !, sumamos 2, y usamos el ^@operador de división para dividir la cadena en oraciones (cada una con un espacio final). Invierta la lista y se imprimirá automáticamente al final del programa. Voilà!

Ejemplo que muestra las etapas del cálculo principal con entrada 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
fuente
No, no lo haces :)
Optimizador
2

Retina , 61 34 33 30 bytes

Créditos a nutki por reducir esto en 24 bytes.

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

Donde se <empty>encuentra una línea vacía. Esto supone que #no es parte de la entrada, pero si eso no es legítimo, podría cambiarlo por cualquier otro personaje, incluido "(que solo tendría que manejar para la bonificación) o algo no imprimible. Puede ejecutar el código de esa manera en un solo archivo si usa la -sbandera, o puede poner cada línea en un archivo separado y pasarlas todas a Retina.

Revertir esto con un solo reemplazo de expresiones regulares es posible, pero realmente engorroso. Incluso con los grupos de equilibrio de .NET, necesitaba algo de alrededor de 90 bytes, así que intenté hacerlo en varios pasos.

En Retina, cada par de líneas es una etapa de reemplazo, donde la primera línea es el patrón y la segunda línea es el reemplazo.

^
#

Esta etapa simplemente prepara la cadena para su posterior procesamiento. Precede a #como un marcador. Este marcador indica que todo lo que está frente a él ya se ha colocado en el lugar correcto, y todo lo que queda después aún debe procesarse.

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

Esta etapa intercambia las oraciones, moviendo repetidamente la última oración frente a la #(que se mueve hacia adelante a través de la cadena en el proceso). Le +`indica a Retina que repita esta etapa hasta que la salida deje de cambiar. Como ejemplo, así es como foo. bar! blah?se procesaría la entrada :

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

Y finalmente simplemente eliminamos el marcador:

#
<empty>
Martin Ender
fuente
¿Por qué no solo .+=> $0 #y repetido (.*?[.!?] )(.*#)=> $2$1?
nutki
@nutki Oh, eso es mucho mejor, gracias. :)
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
fuente
1

JavaScript (ES6) 47 45

Como se dijo, es un simple ejercicio de expresiones regulares. En 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
fuente
Iba a hacer javascript, pero me ganaste.
BobTheAwesome
Esto produce espacios adicionales antes de todos menos la última oración (originalmente la primera). No estoy seguro si está bien, ya que la tarea no está muy bien definida.
nutki
@nutki sí, estoy de acuerdo. Solucionado
edc65
1

Pitón 2, 62

No va a mejorar la bonificación, ya que probablemente no valga la pena el costo del byte.

import re
print' '.join(re.split('(?<=[?!.]).',input())[::-1])
mbomb007
fuente
Esto no califica para el bono. Mire el ejemplo de bonificación en la pregunta
Optimizer
@Optimizer Busque en el historial de preguntas. En el momento en que actualicé mi pregunta para agregar el bono, mi salida coincidía con el ejemplo. No había nada que indicara que los paréntesis pudieran estar fuera de un punto.
mbomb007
Creo que la intención fue esto solo desde el principio. Sin embargo, un ejemplo sólido llegó más tarde. No significa que todavía recibas la bonificación :) (también eliminé la mía)
Optimizer
1

Matlab (93 bytes)

y=[32 input('','s')];y=sortrows([cumsum(ismember(y,'?!.'),'reverse');y]',1)';disp(y(4:2:end))
  • Esto supone que la entrada no contiene espacios iniciales o finales
  • Utiliza entrada y salida estándar
  • Probado en Matlab 2014b
Luis Mendo
fuente
1

Rubí 41

Las otras respuestas de Ruby no tienen suficiente WTF.

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

Esto al menos funciona en Ruby 2. Si el interruptor ay Ffunciona en 1.8.7, supongo que podría caer$_= para guardar tres caracteres.

Invierte cada línea en stdin e imprime en stdout:

$ ruby foo.rb <<< "Hello. Hi. How are you? Good, you? fine, thanks."
fine, thanks. Good, you? How are you? Hi. Hello.
daniero
fuente
¿Podría por favor explicar la respuesta?
Mhmd
1

Ruby, 48 (42 sin los put) bytes

reverse_sentence.rb

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

Uso:

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

Salida:

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

Críticas más que bienvenidas.

DickieBoy
fuente
2
Crítica: Deletreaste "oración" incorrectamente.
Alex A.
guardar 6 caracteres: .join(" ")=>*" "
daniero
@AlexA. ¡La mejor retroalimentación!
DickieBoy
@daniero gracias, es bueno saberlo
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
fuente
0

C # - LINQPAD - 93 - 5 = 88 bytes

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

Aplicación de consola C # 189 - 5 = 184 bytes

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

expresión regular descaradamente azotado de Alex A. :)

jzm
fuente
Puede guardar 7 bytes colocando su aplicación namespace Systemdentro de ese using Linq;usingText.RegularExpressionsahorro 2x system.
señora
No creo que esto califique para el bono. Mire el ejemplo de bonificación en la pregunta
Optimizer
0

Clojure - 44 71 caracteres

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

RE mejorada y simplificada, elimina espacios en blanco innecesarios.

La salida es una secuencia de las oraciones en la cadena original, con el orden de las oraciones invertidas:

Entrada: "Hola amigo. ¿Qué estás haciendo? ¡Apuesto a que es algo que también quiero hacer!" Salida: ("¡Apuesto a que es algo que también quiero hacer!", "¿Qué estás haciendo?", "Hola amigo").

Bob Jarvis - Restablece a Monica
fuente
0

Ruby, 47

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

Créditos a Martin Büttner , por salvar algunos personajes.

Mhmd
fuente
1
Puede leer la entrada de STDIN con getspara guardar un byte, imprimirla $><<para guardar el byte (sin necesidad de espacio) y unir la cadena con *''para guardar dos bytes.
Martin Ender
@ MartinBüttner, gracias por la sugerencia, sin embargo, no iría con la lectura de la entrada de STDIN. Simplemente porque habrá una nueva línea final.
Mhmd
En realidad, creo que su código resultará en un espacio líder.
Martin Ender
mmm, tienes razón. Veré qué debo hacer.
Mhmd
0

CJam, 21 bytes

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

Esto funciona girando espacios después de !s, .sy? s en el número 1 (no el carácter 1 ni el carácter con el punto de código 1, por lo que la entrada aún puede contener esos), dividiendo en 1, invirtiendo el orden de los fragmentos resultantes y uniendo por espacios.

Pruébelo en línea en intérprete de CJam .

Cómo funciona

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
fuente