Обратные предложения


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.

Как видно из примеров, ваша программа имеет дело с вопросительными знаками, восклицательными знаками и точками. Можно предположить, что каждое предложение имеет пунктуацию и пробел перед следующим предложением. Завершающие пробелы / переводы строки в порядке, если они читабельны. Самый короткий код выигрывает.

Удачи!

РЕДАКТИРОВАТЬ: Вы можете предположить, что предложения не имеют кавычек или скобок, но если вы сделаете свой код способным справиться с обоими из них, то вы получите -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
Если предложение содержит пунктуацию в кавычках или в скобках, как нам с этим бороться?
Исаак

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 "))," ")

Это создает анонимную функцию, которая принимает строку в качестве входных данных и возвращает строку с обращенными предложениями. Это обрабатывает любой специальный символ надлежащим образом, хотя двойные кавычки и знаки доллара должны быть экранированы, иначе они не являются допустимыми строками в Julia.

Ungolfed + объяснение:

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: единственный способ запустить последнюю версию 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

Perl, 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, нет, я не смогу восстановить правильный знак при объединении данных, поэтому нам нужно что-то, что не будет поглощать символ.
Романиньш

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

Retina , 61 34 33 30 байт

Кредиты Nutki для сокращения этого на 24 байта.

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

Где <empty>обозначает пустую строку. Предполагается, что #это не является частью ввода, но если это не законно, я мог бы заменить его на любой другой символ, включая" (который мне нужно было бы обработать только для бонуса) или что-то непечатное. Вы можете запустить такой код в одном файле, если вы используете-s флаг, или вы можете поместить каждую строку в отдельный файл и передать их все в Retina.

Поменять это с помощью одной замены регулярных выражений возможно, но действительно громоздко. Даже с балансировочными группами .NET мне нужно что-то около 90 байт, поэтому я попытался сделать это в несколько этапов.

В Retina каждая пара линий представляет собой одну стадию замены, где первая строка - это шаблон, а вторая - это замена.

^
#

Этот этап просто подготавливает строку для дальнейшей обработки. Это выглядит #как маркер. Этот маркер указывает на то, что все, что находится перед ним, уже размещено в нужном месте, и все, что после него, все еще необходимо обработать.

+`(#.*[.!?]) (.+)
$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

@nutki да, я согласен. Исправлено
edc65

1

Python 2, 62

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

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

Это не претендует на бонус. Посмотрите на пример бонуса в вопросе
Оптимизатор

@Optimizer Посмотрите в истории вопроса. В то время, когда я обновил свой вопрос, чтобы добавить бонус, мой результат соответствовал примеру. Ничто не указывало на то, что скобки могут быть за пределами периода.
mbomb007

Я думаю, что намерение было это только с самого начала. Твердый пример пришел позже, хотя. Это не значит, что вы по-прежнему получаете бонус :) (я тоже снял свой)
Оптимизатор

1

Matlab (93 байта)

y=[32 input('','s')];y=sortrows([cumsum(ismember(y,'?!.'),'reverse');y]',1)';disp(y(4:2:end))
  • Это предполагает, что входные данные не содержат начальные или конечные пробелы
  • Использует стандартный ввод и вывод
  • Проверено в Matlab 2014b

1

Рубин 41

В других ответах по Ruby не хватает WTF.

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

По крайней мере , работает в Рубине 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(" ")=>*" "
Даньеро

@AlexA. Лучший отзыв когда-либо!
DickieBoy

@daniero спасибо, приятно знать
DickieBoy

1

к, 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 # 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()));}}

регулярное выражение беззастенчиво порется от Алекса А. :)


Вы можете сэкономить 7 байтов, поместив ваше приложение в namespace Systemэтом using Linq;usingText.RegularExpressionsсохранении 2x 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 (не символ 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.