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


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.