Frasi inverse


15

L'obiettivo di questa sfida è ricevere un input e un output di tale input ma con l'ordine delle frasi invertito. Esempio di input:

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

Esempio di output:

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

Come puoi vedere dagli esempi, il tuo programma deve affrontare punti interrogativi, punti esclamativi e punti. Puoi presumere che ogni frase abbia una punteggiatura e uno spazio prima della frase successiva. Gli spazi finali / le nuove righe sono ok, purché sia ​​leggibile. Il codice più corto vince.

In bocca al lupo!

EDIT: Puoi presumere che le frasi non abbiano virgolette o parentesi, ma se fai in modo che il tuo codice sia in grado di gestire entrambe, otterrai -5 byte Esempio di output per parentesi / virgolette:

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

Possiamo presumere che non ci saranno virgolette o parentesi? In caso contrario, come li gestiamo?
BrainSteel,

Ho apportato una modifica al post chiarendolo.

Puoi fare un esempio dell'output previsto per una frase contenente virgolette o parentesi, per favore?
mbomb007,

6
Se una frase ha punteggiatura tra virgolette o parentesi, come dovremmo gestirla?
isaacg,

2
@Scimonster Vuoi dire "ie", ecc., Giusto? Oh, e per favore modifica la mia citazione del test case in modo che sia:"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.
Non che Charles

Risposte:


9

Julia, 45 42 byte - 5 bonus = 37

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

Questo crea una funzione anonima che accetta una stringa come input e restituisce la stringa con le sue frasi invertite. Questo gestisce in modo appropriato qualsiasi carattere speciale, anche se le doppie virgolette e i segni del dollaro devono essere sfuggiti, altrimenti non sono stringhe valide in Julia.

Ungolfed + spiegazione:

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

Esempi:

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

E se non ti piace guardare le virgolette sfuggite nell'output:

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.

Salvato 3 byte sull'espressione regolare grazie a Martin Büttner! In precedenza questo era un lookbehind: (?<=[.?!]).


Non credo che questo si qualifichi per il bonus ...
Ottimizzatore

@Optimizer: come no? Funziona come previsto tra parentesi, virgolette, ecc. Come indicato nel post.
Alex A.

Puoi fornire un link online per testare, con l'esempio dalla sezione bonus della domanda.
Ottimizzatore

@Optimizer: l'unico modo per eseguire una versione recente di Julia online richiede la registrazione e non supporta i permalink. Basterebbe semplicemente inserire input e output qui nel post?
Alex A.

Certo, immagino ..
Ottimizzatore,

7

CJam, 23 22 byte

Non sono sicuro se questo si qualifica per il bonus o no, ma ecco la soluzione:

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

Espansione del codice (bit obsoleto) :

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

Provalo online qui


Ah, hai pubblicato questo post subito dopo averlo modificato. Ora ricevi un bonus di -5 (solo per renderlo un po 'più difficile) Quindi un bonus di -5 per te! 18 byte, wow, non sono sicuro che sia battibile: P

5

J, 35 32

Gestisce quasi l'input bonus, tranne per il fatto che devo scappare a singoli apostrofi, quindi immagino che non conti. (Inoltre, la mia prima presentazione qui)

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

Uso:

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

O dalla riga di comando:

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

Bello! Puoi ottenere il bonus di -5 con perl -nE 'say reverse/ |[^.?!]*.\)?/g', portando il conteggio totale a 23.
ThisSuitIsBlackNon

2

PHP, 60

echo join(' ',array_reverse(preg_split('/(?<=[?!.])/',$s)));

Puoi usare [?!.]\Kinvece regex ?
Martin Ender,

Inoltre, questo non aggiunge ulteriori spazi nella stringa a meno che tu non includa lo spazio nel modello da dividere?
Martin Ender,

@ MartinBüttner, no, non sarò in grado di ripristinare il segno corretto quando si ricollegano i dati, quindi abbiamo bisogno di qualcosa che non consumi il personaggio.
romaninsh,

2

Bash + coreutils, 40 byte

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

Questo viene letto da STDIN, quindi l'input può essere reindirizzato da un file o semplicemente reindirizzato, ad esempio:

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

Funziona davvero per le parentesi nel senso che (foo bar.)vengono scambiate come unità?
Martin Ender,

@ MartinBüttner Sembra che la domanda sia stata modificata, quindi non posso più richiedere il bonus :(
Digital Trauma

2

Pip , 25 byte

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

Dopo aver aggiunto uno spazio alla stringa di input, troviamo tutti gli indici di . , ?e !, aggiungiamo 2, e utilizzare il^@ operatore split-at per spezzare la stringa in frasi (ognuna con uno spazio finale). Invertire l'elenco ed è stampato automaticamente alla fine del programma. Ecco!

Esempio che mostra le fasi del calcolo principale con input 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! 

No, non lo fai :)
Ottimizzatore

2

Retina , 61 34 33 30 byte

Ringraziamenti a nutki per averlo ridotto di 24 byte.

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

Dove <empty>sta per una linea vuota. Ciò presuppone che #non faccia parte dell'input, ma se ciò non fosse legittimo, potrei sostituirlo con qualsiasi altro personaggio, incluso "(che avrei solo bisogno di gestire per il bonus) o qualcosa di non stampabile. Puoi eseguire il codice in quel modo in un singolo file se usi il -sflag, oppure puoi mettere ogni riga in un file separato e passarli tutti a Retina.

Inversione di questo con una singola sostituzione regex è possibile, ma davvero ingombrante. Anche con i gruppi di bilanciamento .NET avevo bisogno di qualcosa di circa 90 byte, quindi ho provato a farlo in più passaggi.

In Retina, ogni coppia di linee è una fase di sostituzione, dove la prima linea è il modello e la seconda linea è la sostituzione.

^
#

Questa fase prepara semplicemente la stringa per ulteriori elaborazioni. Si antepone a #come marcatore. Questo indicatore indica che tutto ciò che ha davanti è già stato messo nel posto giusto e tutto ciò che deve essere ancora elaborato.

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

Questa fase scambia le frasi, spostando ripetutamente l'ultima frase davanti al #(che si sposta in avanti attraverso la stringa nel processo). Il +`incarica Retina ripetere questa fase finché l'uscita smette di cambiare. Ad esempio, ecco come foo. bar! blah?verrà elaborato l'input :

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

E infine rimuoviamo semplicemente il marker:

#
<empty>

Perché non solo .+=> $0 #e ripetuto (.*?[.!?] )(.*#)=> $2$1?
Nutki,

@nutki Oh, è molto più bello, grazie. :)
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

Come si dice, è un semplice esercizio di regex. 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!"))
 


Stavo per fare javascript, ma mi hai battuto.
BobTheAwesome

Questo produce spazi extra prima di tutti tranne l'ultima frase (originariamente la prima). Non sono sicuro che sia OK, poiché l'attività non è molto ben definita.
Nutki,

@nutki sì, sono d'accordo. Risolto
edc65

1

Python 2, 62

Non migliorerà per il bonus, poiché probabilmente non vale il costo in byte.

import re
print' '.join(re.split('(?<=[?!.]).',input())[::-1])

Questo non è idoneo per il bonus. Guarda l'esempio di bonus nella domanda
Optimizer,

@Optimizer Cerca nella cronologia delle domande. Al momento in cui ho aggiornato la mia domanda per aggiungere il bonus, il mio output corrispondeva all'esempio. Nulla indicava che la parentesi potesse essere al di fuori di un periodo.
mbomb007,

Penso che l'intenzione fosse questa solo dall'inizio. Un esempio solido è venuto dopo. Non significa che ricevi ancora il bonus :) (ho rimosso anche il mio)
Optimizer

1

Matlab (93 byte)

y=[32 input('','s')];y=sortrows([cumsum(ismember(y,'?!.'),'reverse');y]',1)';disp(y(4:2:end))
  • Ciò presuppone che l'input non contenga spazi iniziali o finali
  • Utilizza input e output standard
  • Testato in Matlab 2014b

1

Ruby 41

Le altre risposte di Ruby non hanno abbastanza WTF.

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

Questo funziona almeno in Ruby 2. Se l' opzione ae Ffunziona in 1.8.7, suppongo che potresti lasciar perdere$_= per salvare tre caratteri.

Inverte ogni riga su stdin e stampa su stdout:

$ ruby foo.rb <<< "Hello. Hi. How are you? Good, you? fine, thanks."
fine, thanks. Good, you? How are you? Hi. Hello.

Potresti spiegare la risposta, per favore.
Mhmd,

1

Ruby, 48 (42 senza il put) byte

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

Produzione:

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

Critica più che benvenuta.


2
Critica: hai scritto "frase" in modo errato.
Alex A.

salva 6 caratteri: .join(" ")=>*" "
daniero

@AlexA. Il miglior feedback di sempre!
DickieBoy,

@daniero grazie, bello sapere
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 byte

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

App console C # 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 frustato sfacciatamente da Alex A. :)


Puoi salvare 7 byte inserendo la tua applicazione in namespace Systemquel using Linq;usingText.RegularExpressionssalvataggio 2x system.
ldam,

Non penso che questo si qualifichi per il bonus. Guarda l'esempio di bonus nella domanda
Optimizer,

0

Clojure - 44 71 caratteri

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

RE migliorata e semplificata, eliminati gli spazi bianchi non necessari.

L'output è una sequenza delle frasi nella stringa originale, con l'ordine delle frasi invertito:

Input: "Ciao amico. Cosa stai facendo? Scommetto che è qualcosa che voglio fare anch'io!" Output: ("Scommetto che è qualcosa che voglio fare anch'io!" "Cosa stai facendo?" "Ciao amico.")


0

Ruby, 47

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

crediti a Martin Büttner , per aver salvato alcuni personaggi.


1
È possibile leggere l'input da STDIN con getsper salvare un byte, stamparlo con $><<per salvare byte (non è necessario uno spazio) e unire la stringa con *''per salvare due byte.
Martin Ender,

@ MartinBüttner grazie per il suggerimento, non vorrei andare a leggere dall'input di STDIN, però. Semplicemente perché ci sarà una nuova riga finale.
Mhmd,

In realtà, penso che il tuo codice al momento si tradurrà in uno spazio iniziale.
Martin Ender,

mmm, hai ragione. Vedrò cosa dovrei fare.
Mhmd,

0

CJam, 21 byte

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

Funziona ruotando gli spazi dopo !s, se .s? s nel numero 1 (non il carattere 1 né il carattere con il punto di codice 1, quindi l'input può ancora contenere quelli), suddividendo a 1, invertendo l'ordine dei blocchi risultanti e unendo dagli spazi.

Provalo online nel CJam .

Come funziona

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)
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.