Зворотні речення


15

Мета цього завдання полягає в отриманні вводу та виводу цього входу, але із зворотним порядком речень. Приклад введення:

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.

Як ви можете зрозуміти з прикладів, ваша програма повинна мати справу зі знаками запитання, знаками оклику та періодами. Ви можете припустити, що кожне речення має розділові знаки та пробіл перед наступним реченням. Пробіли / нові рядки в порядку, якщо вони читаються. Найкоротший код виграє.

Удачі!

EDIT: Ви можете припустити, що речення не має лапок або круглих дужок, але якщо ви зробите свій код, щоб він міг працювати з обома цими, тоді ви отримаєте -5 байт. Приклад виведення для парен / цитат:

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

Чи можемо ми припустити, що жодних лапок чи дужок не буде? Якщо ні, то як ми з ними поводимось?
BrainSteel

Вніс редагування публікації, очистивши це.

Чи можете ви навести приклад очікуваного результату для речення, що містить лапки або паролі, будь ласка?
mbomb007

6
Якщо речення має розділові знаки в лапках або паренах, то як ми з ним поводимось?
isaacg

2
@Scimonster Ви маєте на увазі "тобто" і т.д., правда? О, і будь ласка, виправте мою цитату тестового випадку так:"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.
Не те, що Чарльз

Відповіді:


9

Джулія, 45 42 байти - 5 бонус = 37

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

Це створює анонімну функцію, яка приймає рядок як вхідний і повертає рядок із реверсивними реченнями. Це обробляє будь-який спеціальний символ належним чином, хоча подвійні лапки та знаки долара потрібно уникати, інакше вони не є дійсними рядками в Джулії.

Недоліковані + пояснення:

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

Приклади:

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

І якщо вам не подобається дивитись уникнутих лапок у висновку:

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 байти на регулярному виразі завдяки Мартіну Бюттнеру! Раніше це використовували назад ' : (?<=[.?!]).


Я не думаю, що це може бути бонусом ...
Оптимізатор

@Optimizer: Як це не відбувається? Він працює, як очікувалося, в дужках, цитатах тощо, як зазначено в публікації.
Олексій А.

Чи можете ви надати посилання в Інтернеті для тестування, на прикладі бонусного розділу питання.
Оптимізатор

@Optimizer: Єдиний спосіб запуску останньої версії Julia в Інтернеті вимагає реєстрації та не підтримує постійні посилання. Чи достатньо буде просто включити сюди ввід і вихід у пост?
Олексій А.

Звичайно, я думаю ..
Оптимізатор

7

CJam, 23 22 байт

Я не впевнений, кваліфікується це бонус чи ні, але тут іде рішення:

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

Розширення коду (трохи застаріле) :

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

Спробуйте його онлайн тут


Ах, ви написали цю посаду відразу після того, як я її спочатку відредагував. Ви отримуєте -5 бонус зараз (Просто, щоб зробити це трохи важче) Так -5 бонус для вас! 18 байт, уау, не впевнений, чи можна це перемістити: P

5

J, 35 32

Він майже обробляє бонусний внесок, за винятком того, що я повинен уникати одиночних апострофів, тому, мабуть, він не рахується. (Також моє перше подання тут)

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

Використання:

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

4

Перл, 27/25

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

Або з командного рядка:

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

Приємно! Ви можете отримати бонус -5 perl -nE 'say reverse/ |[^.?!]*.\)?/g', довівши свій загальний підрахунок до 23.
ThisSuitIsBlackNot

2

PHP, 60

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

Чи можете ви скористатися регулярним виразом [?!.]\K?
Мартін Ендер

Також це не додає додаткових пробілів у рядок, якщо ви не включите пробіл у шаблон, який потрібно розділити?
Мартін Ендер

@ MartinBüttner, ні, я не зможу відновити належний знак під час приєднання даних назад, тому нам потрібно щось, що не споживає персонажа.
romaninsh

2

Bash + coreutils, 40 байт

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

Це зчитується з STDIN, тому вхід може мені переадресовуватись з файлу або просто передати в нього, наприклад:

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

Чи справді це працює в дужках у тому сенсі, який (foo bar.)заміняється як одиниця?
Мартін Ендер

@ MartinBüttner Схоже, що питання було відредаговано, тому я більше не можу вимагати бонусу :(
Digital Trauma

2

Піп , 25 байт

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

Додавши пробіл до вхідного рядка, ми знаходимо всі показники . , ?і! додайте 2, і використовувати ^@спліт-на операторі , щоб розірвати рядок в пропозиції (кожен із завершальними пробілами). Переверніть список, і він буде надрукований автоматично в кінці програми. Вуаля!

Приклад, що показує етапи основного обчислення з введенням 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! 

Ні, ви не :)
Оптимізатор

2

Сітківка , 61 34 33 30 байт

Кредити нуткам для скорочення цього на 24 байти.

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

Де <empty> стоїть порожній рядок. Це передбачає, що #це не є частиною вводу, але якщо це не є законним, я міг би поміняти його на будь-який інший символ, в т.ч." (з яким мені потрібно було би впоратися лише за бонус) або на щось недруковане. Ви можете запустити такий код в одному файлі, якщо ви використовуєте -sпрапор, або можете скласти кожен рядок в окремий файл і передати їх всім Retina.

Повернути це за допомогою однієї заміни регулярного виразу можливо, але насправді громіздко. Навіть з балансуючими групами .NET мені знадобилося щось близько 90 байт, тому натомість я намагався робити це в кілька кроків.

У Retina кожна пара рядків є однією стадією заміни, де перший рядок є візерунком, а другий рядок - заміною.

^
#

Цей етап просто готує рядок для подальшої обробки. Це передує a# як маркер. Цей маркер вказує на те, що все перед ним вже поставлено в потрібне місце, і все після нього ще потрібно обробити.

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

Цей етап замінює речення, повторно переміщуючи останнє речення перед #(що рухається вперед через рядок у процесі). +`Інструктує Retina повторити цей етап , поки вихід не перестане змінюватися. Як приклад, ось як foo. bar! blah?оброблятиметься вхід :

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

І нарешті ми просто знімаємо маркер:

#
<empty>

Чому б не просто .+=> $0 #і повторити (.*?[.!?] )(.*#)=> $2$1?
nutki

@nutki О, це набагато приємніше, дякую. :)
Мартін Ендер

1

Ява, 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

Як зазначено, це звичайна вправа з виразкою. У 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!"))
 


Я збирався робити javascript, але ти перебив мене на це.
BobTheAwesome

Це створює додаткові пробіли перед усіма, крім останнього речення (спочатку першого). Не впевнений, чи це добре, оскільки завдання не дуже чітко визначене.
нутки

@nutki так, я згоден. Виправлено
edc65

1

Пітон 2, 62

Не збирається поліпшуватися за бонус, оскільки, мабуть, не варто витрачати байт.

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

Це не може отримати бонус. Подивіться на приклад бонусу у питанні
оптимізатор

@Optimizer Подивіться історію питань. У той час, коли я оновлював своє запитання щодо додавання бонусу, мій результат відповідав прикладу. Нічого не вказувало на те, що дужки можуть бути поза періодом.
mbomb007

Я думаю, що наміром було таке лише з самого початку. Хоча пізній приклад прийшов пізніше. Це не означає, що ви все одно отримуєте бонус :) (я теж видалив мій)
Optimizer

1

Матлаб (93 байти)

y=[32 input('','s')];y=sortrows([cumsum(ismember(y,'?!.'),'reverse');y]',1)';disp(y(4:2:end))
  • Це передбачає, що введення не містить провідної чи кінцевої пробілів
  • Використовує стандартний вхід і вихід
  • Випробуваний у Matlab 2014b

1

Рубін 41

В інших відповідях Рубі недостатньо WTF.

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

Це принаймні працює в Ruby 2. Якщо aіF перемикач працює в 1.8.7, я думаю , ви могли б впасти , $_=щоб зберегти три символи.

Відміняє кожен рядок на stdin та друкує до stdout:

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

Скажіть, будь ласка, відповідь.
Mhmd

1

Рубі, 48 (42 без пропусків) байт

reverse_sentence.rb

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

Використання:

ruby reverse_sentence.rb '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.

Критика більш ніж вітається.


2
Критика: "Вирок" ви написали неправильно.
Олексій А.

зберегти 6 символів: .join(" ")=>*" "
daniero

@AlexA. Найкращий відгук!
DickieBoy

@daniero дякую, приємно знати
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 байт

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

C # Console App 189 - 5 = 184 байт

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

regex безсоромно відбився від Алекса А. :)


Ви можете зберегти 7 байтів, помістивши програму namespace Systemпотім у межах цього using Linq;usingText.RegularExpressionsекономії в 2 рази system.
ldam

Я не думаю, що це може бути бонусом. Подивіться на приклад бонусу у питанні
оптимізатор

0

Clojure - 44 71 символів

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

Покращена та спрощена система RE, усунуто зайвий пробіл.

Вихід - це послідовність речень у початковому рядку з порядком речень, перевернутим:

Вхід: "Здрастуй, друже. Що ти робиш? Гадаю, це теж те, що я хочу зробити!" Вихід: ("Я думаю, що це теж я хочу зробити!", "Ти що робиш?", "Привіт друг".)


0

Рубі, 47

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

кредити Мартіну Бюттнеру за збереження деяких персонажів.


1
Ви можете прочитати вхід з STDIN, getsщоб зберегти байт, роздрукувати його, $><<щоб зберегти байт (не потрібно місця) та приєднати рядок до, *''щоб зберегти два байти.
Мартін Ендер

@ MartinBüttner дякую за пропозицію, я б не хотів читати з вхідних даних зі STDIN. Просто тому, що з'явиться нова лінія.
Mhmd

Власне, я думаю, що ваш код в даний час призведе до провідного простору.
Мартін Ендер

ммм, ти маєш рацію. Я побачу, що мені робити.
Mhmd

0

CJam, 21 байт

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

Це працює, перетворюючи пробіли після !s, .s і ?s в число 1 (не the символ 1, ні символ з кодовою точкою 1, тому вхід все ще може містити їх), розбиваючись на 1, змінюючи порядок отриманих фрагментів і з'єднуючись пробілами.

Спробуйте його в Інтернеті інтерпретаторі CJam .

Як це працює

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)
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.