Мир заканчивается в ред


21

Взятые прямо с зимнего соревнования по программированию ACM 2013. Вы человек, который любит понимать вещи буквально. Следовательно, для вас конец Мира предопределен; последние буквы "The" и "World" сцеплены.

Создайте программу, которая принимает предложение, и выводите последнюю букву каждого слова в этом предложении как можно меньше места (наименьшее количество байтов). Слова отделяются чем угодно, кроме букв алфавита (65 - 90, 97 - 122 в таблице ASCII.) Это означает, что подчеркивания, тильды, могилы, фигурные скобки и т. Д. Являются разделителями. Между каждым словом может быть несколько разделителей.

asdf jkl;__zxcv~< vbnm,.qwer| |uiop-> flvmrp
pigs, eat dogs; eat Bob: eat pigs-> ststbts
looc si siht ,gnitirw esreveR-> citwR
99_bottles_of_beer_on_the_wall->sfrnel


Не могли бы вы добавить контрольный пример с цифрами и подчеркиванием?
Grc

10
Мир заканчивается в ред? Я знал, что Vim и Emacs не могут сравниться!
Джо З.

Ну, эссе «Настоящие мужчины используют Эд» было частью дистрибутива Emacs, насколько я себя помню.
JB

Будут ли входы только в формате ASCII?
Фил Х

Ответы:


16

Perl 5, 18 байт

s/\pL*(\pL)|./$1/g

Требуется -pпереключатель командной строки. Именованное свойство Lсоответствует только буквенным символам A-Za-z. Существует несколько сотен таких именованных свойств, но при работе с текстом ASCII очень немногие из них интересны. Кроме того \pL, единственная другая реальная нота \pP, которая соответствует пунктуации.

Попробуйте онлайн!


Perl 5, 17 байт

Однобайтовое улучшение от Dom Hastings

print/\pL*(\pL)/g

Требуется -n-lдля поддержки нескольких входов).

Попробуйте онлайн!


Пример использования

$ more in.dat
asdf jkl;__zxcv~< vbnm,.qwer| |uiop
pigs, eat dogs; eat Bob: eat pigs
looc si siht ,gnitirw esreveR
99_bottles_of_beer_on_the_wall

$ perl -p ends-in-ed.pl < in.dat
flvmrp
ststbts
citwR
sfrnel

Я думаю, \wтакже совпадает с цифрами и подчеркиванием.
grc

Хм, действительно. Это нужно будет обновить.
Примо

2
Brilliant. Regex было очевидным решением, но |.не было очевидным (по крайней мере для меня).
Питер Тейлор

1
Просто заметил -1по прибытии print/\pL*(\pL)/g, кажется, выход то же самое для ваших тестов!
Дом Гастингс

18

изд, 35 знаков

s/[a-zA-Z]*\([a-zA-Z]\)\|./\1/g
p
Q

Итак, мир заканчивается в ред. Поскольку мне нравится быть слишком буквальным, я решил написать, чтобы написать решение с ed - и, очевидно, это на самом деле язык программирования . Он на удивление короток, даже если учесть, что в этой ветке уже есть множество более коротких решений. Было бы лучше, если бы я мог использовать что-то другое [a-zA-Z], но, учитывая, что ed не является языком программирования, на самом деле он достаточно хорош.

Во-первых, я хотел бы сказать, что это анализирует только последнюю строку в файле. Можно было бы проанализировать больше, просто введите ,в начале две первые строки (это указало диапазон «все», а не стандартный диапазон последней строки), но это увеличило бы размер кода до 37 символов.

Теперь для объяснений. Первая строка делает именно то, что делает решение Perl (кроме как без поддержки символов Unicode). Я не скопировал решение Perl, я просто изобрел нечто подобное по стечению обстоятельств.

Вторая строка печатает последнюю строку, чтобы вы могли видеть результат. Третья строка заставляет выйти - я должен это сделать, в противном edслучае напечатал бы, ?чтобы напомнить вам, что вы не сохранили файл.

Теперь о том, как его выполнить. Ну, это очень просто. Просто запустите edфайл, содержащий тестовый пример, пока я пишу мою программу, вот так.

ed -s testcase < program

-sмолчит. Это предотвращает edвывод некрасивого размера файла в начале. В конце концов, я использую его как скрипт, а не как редактор, поэтому мне не нужны метаданные. Если бы я не сделал этого, ed показал бы размер файла, который я не мог бы предотвратить иначе.


Я установил ed только для того, чтобы попробовать это.
Примо

6

Javascript, 49

alert(prompt().replace(/.(?=[a-z])|[^a-z]/gi,''))

Он использует регулярное выражение для удаления всех символов, которые идут перед буквой, а также всех не буквенных символов. Тогда мы остаемся с последней буквой каждого слова.

Спасибо tomsmeding за хорошее улучшение.


3
Вероятно, вы можете улучшить это, сделав регулярное выражение без alert(prompt().replace(/.(?=[a-z])|[^a-z]/gi,''))
учета

6

С, 78

Golfed:

main(int c,char**s){for(;c=*s[1]++;)isalpha(c)&&!isalpha(*s[1])?putchar(c):0;}

С пробелами:

main(int c,char**s)
{
  for(;c=*s[1]++;)
    isalpha(c)&&!isalpha(*s[1])?putchar(c):0;
}

Выход:

введите описание изображения здесь


1
Вы можете сохранить 4 байта, используя декларацию K & R и значения по умолчанию c:main(c,s)char**s;{for
Тоби Спейт

5

GNU Sed, 40 38 37

s/[a-z]\b/&\n/g; s/[^\n]*\(.\)\n/\1/g

тестирование

cat << EOF > data.txt
asdf jkl;__zxcv~< vbnm,.qwer| |uiop
pigs, eat dogs; eat Bob: eat pigs
looc si siht ,gnitirw esreveR
EOF

Запустите sed:

sed 's/[A-Za-z]\b/&\n/gi; s/[^\n]*\(.\)\n/\1/g' data.txt

Выход:

flvmrp
ststbts
citwR

объяснение

Первая замена заменяет все границы слов, которым предшествует желаемая группа соответствия, новой строкой. Это позволяет легко удалить все посторонние символы во второй замене.

редактировать

  • Используйте флаг без учета регистра (-2), спасибо manatwork .
  • Не считайте пробелы (-1).

sed«S sкоманда имеет iфлаг для случаев нечувствительным соответствия: s/[a-z]\b/&\n/gi.
Манатворк

@manatwork: хорошая мысль, это сделало бы только GNU sed, но, похоже, это уже так, спасибо.
Тор

\bсчитает _с , чтобы быть буквы, так что если какие - либо слова в тесте END с _, последняя буква этого слова на не включены в выходные
Marty Neal

3

Grep and Paste, 36 34 28

> echo 'asdf jkl;__zxcv~< vbnm,.qwer| |uiop' | grep -io '[a-z]\b' | tr -d \\n
flvmrp

> echo 'pigs, eat dogs; eat Bob: eat pigs'   | grep -io '[a-z]\b' | tr -d \\n
ststbts

echo 'looc si siht ,gnitirw esreveR'         | grep -io '[a-z]\b' | tr -d \\n
citwR

Если требуется последняя новая строка, замените tr -d \\nна paste -sd ''.

редактировать

  • Используйте нечувствительный к регистру grep (-2), спасибо manatwork .
  • Используйте trвместо paste(-4), спасибо manatwork .
  • Не считайте пробелы вокруг трубы (-2).

Довольно креативно с этим paste -sd '', но tr -d \\nкороче. Что касается grep, он имеет -iпереключатель значение «игнорировать регистр», который может сделать его короче: grep -io '[a-z]\b'.
Манатворк

@manatwork, trтакже удалите последний перевод строки. Режим без учета регистра, конечно, короче, спасибо.
Тор

нет правила, требующего окончательного перевода строки.
Манатворк

@ Manatwork: я могу согласиться с этим, обновленный ответ.
Тор

3

sed, 37 символов

Равная длина ответа Тора , но, думаю, проще.

s/[a-z]*\([a-z]\)/\1/ig;s/[^a-z]*//ig

Логика вполне тривиальна - замените последовательности букв их последней буквой, а затем удалите все не-буквы.


3

Математика, 39

""<>StringCases[#,(__~~x_)?LetterQ:>x]&

Тест:

""<>StringCases[#,(__~~x_)?LetterQ:>x]& /@
 {"asdf jkl;__zxcv~< vbnm,.qwer| |uiop",
  "pigs, eat dogs; eat Bob: eat pigs",
  "looc si siht ,gnitirw esreveR",
  "99_bottles_of_beer_on_the_wall"}
{"flvmrp", "ststbts", "citwR", "sfrnel"}

Хороший. LetterQдолжен называться LettersQ:) Я не думал об этом для тестирования целых строк.
Доктор Велизарий

@belisarius На самом деле, с этой конструкцией она применяется символьно, поэтому она может быть буквальным «LetterQ» и все еще работать.
Mr.Wizard

2

К, 49

{last'f@&"b"$#:'f:"|"\:@[x;&~x in,/.Q`a`A;:;"|"]}

,

k){last'f@&"b"$#:'f:"|"\:@[x;&~x in,/.Q`a`A;:;"|"]}"asdf jkl;__zxcv~< vbnm,.qwer| |uiop"
"flvmrp"
k){last'f@&"b"$#:'f:"|"\:@[x;&~x in,/.Q`a`A;:;"|"]}"pigs, eat dogs; eat Bob: eat pigs"
"ststbts"
k){last'f@&"b"$#:'f:"|"\:@[x;&~x in,/.Q`a`A;:;"|"]}"looc si siht ,gnitirw esreveR"
"citwR"

2

Скала, 59 (или 43)

Предполагая, что строка уже в s:

s.split("[^a-zA-Z]+").map(_.last).mkString

Если вам нужно читать из приглашения и печатать, а не использовать вывод REPL, преобразуйте sв readLineи оберните в println()течение 59.


2

x86: 54 байта

Предположим, подпрограмма cdecl с подписью void world_end(char *input, char *output):

60 8b 74 24 24 8b 7c 24 28 33 d2 8a 0e 8a c1 24
df 3c 41 72 08 3c 5a 77 04 8a d1 eb 09 84 d2 74
05 88 17 47 33 d2 46 84 c9 75 e0 84 d2 74 03 88
17 47 88 0f 61 c3

1
Кстати, я понимаю, что вопрос требует программы, а не рутины , но я хотел сделать что-то другое. Вопреки постановке проблемы, я думаю, что я не "человек, который любит воспринимать вещи буквально" в конце концов. : P
user1354557

2

Си, 32

println$ @{=>.-1}<>input re"\W+"

Язык Xi все еще находится на стадии бета-тестирования, но, похоже, он хорошо работает с Code Golf, поэтому я решил, что с таким же успехом могу показать еще одно короткое и функциональное решение (и немного прорекламировать язык :-)).


2

Mathematica 62 57 52

Row@StringTake[StringCases[#,LetterCharacter..],-1]&

тестирование

l = {"asdf jkl;__zxcv~<vbnm,.qwer| |uiop", 
     "pigs,eat dogs;eat Bob:eat pigs", 
     "looc si siht,gnitirw esreveR"}

Row@StringTake[StringCases[#,LetterCharacter..],-1]&/@ l
(*{flvmrp,ststbts,citwR}*)

Я по ошибке отредактировал ваш, но потом откатил. По электронной почте Ой.
DavidC

2

Python3, 59 символов

import re;print(re.sub('.(?=[a-z])|[^a-z]','',input(),0,2))

Правильно разбирается с заглавными буквами и подчеркиванием. 2 должен пройти re.subна re.IGNORECASEфлаг без необходимости использования re.I.



1

Python 3.x, 64 байта

import re;print(''.join(a[-1] for a in re.split('\W+',input())))

2
Последний пример не работает. Также возникает ошибка, если строка начинается или заканчивается разделителем
AMK

Вы можете удалить пространство раньше for.
Бакуриу


1

Mathematica 71 47 45 61

Вернемся к чертежной доске, после того как @belisarius обнаружил ошибку в коде.

StringCases[#, RegularExpression["[A-Za-z](?![A-Za-z])"]] <> "" &

тестирование

l = {"asdf jkl;__zxcv~<vbnm,.qwer| |uiop", "asdf jkl__zxcv~<vbnm,.qwer| |uiop", 
"pigs,eat dogs;eat Bob:eat pigs", "looc si siht,gnitirw esreveR"};

StringCases[#, RegularExpression["[A-Za-z](?![A-Za-z])"]] <> "" & /@ l

{"flvmrp", "flvmrp", "ststbts", "citwR"}


\\wсоответствует _, так что это не работает для (например)"asdf jkl__zxcv~<vbnm,.qwer| |uiop"
д-р belisarius

Ожидание Row@StringTake[ StringCases[#, LetterCharacter ..], -1] &@"asdf jkl__zxcv~<vbnm,.qwer| |uiop"дает мне flvmrp, но #~StringCases~RegularExpression@"\\w\\b" <> "" &@"asdf jkl__zxcv~<vbnm,.qwer| |uiop"возвращается fvmrpсюда. Получаем ли мы одинаковые результаты?
Доктор Велизарий

@belisarius Вы были правы насчет ошибки в моей предыдущей версии. Я проверял это с неправильной строкой!
DavidC

Хе-хе, +1 снова
д-р Велизарий

@belisarius, ребята, пожалуйста, посмотрите ответ, который я разместил. Если это правильно, это короче.
Мистер Волшебник

1

Python 2, 88 80 75 69 68

s=p=''
for c in raw_input()+' ':a=c.isalpha();s+=p[a:];p=c*a
print s

Входные данные: 435_ASDC__uio;|d re;fG o55677jkl..f

Выход: CodeGolf


Это решение может быть сокращено до 67 символов, если вы разрешите выводу включать символы возврата (код ASCII 8) в начале. Вывод будет визуально идентичным.

s=p='<BS>'
for c in raw_input()+p:a=c.isalpha();s+=p[a:];p=c*a
print s

Тот же вход, (визуально) тот же выход. <BS>должен быть символом возврата.


1

C #

Метод, 105 байт: (предполагается использование для System, System.Text.RegularExpressions и System.Linq)

string R(string i){return string.Concat(Regex.Split(i,"[^a-zA-Z]").Where(x=>x!="").Select(n=>n.Last()));}

Программа, 211 байт:

using System;using System.Text.RegularExpressions;using System.Linq;class A{static void Main(){Console.WriteLine(string.Concat(Regex.Split(Console.ReadLine(),"[^a-zA-Z]").Where(x=>x!="").Select(n=>n.Last())));}}

1

VBA, 147 161

Sub a(s)
For n=0 To 255:m=Chr(n):s=Replace(s,IIf(m Like"[A-Za-z]","",m)," "):Next
For Each r In Split(s," "):t=t & Right(r,1):Next
MsgBox t
End Sub

1

Ruby 2.0, 25 (+1) символов

gsub(/(\w+)\W*/){$1[-1]}

Должен быть запущен с -pвыключателем:

 $ ruby -p ed.rb <<< "asdf jkl;__zxcv~< vbnm,.qwer| |uiop"
flvmrp

Пожалуйста, укажите rubyверсию. 1.9.2 выводит «# <Enumerator: 0x9f65e10> # <Enumerator: 0x9f65d98> # <Enumerator: 0x9f65d34> # <Enumerator: 0x9f65cd0>».
manatwork

Вы правы. Я полностью забыл, что установил его, но моя текущая версия Ruby - 2.0 ( ruby 2.0.0p0 (2013-02-24 revision 39474). При запуске программы с версией 1.8.7 она выводит значение ASCII! Не знал, что между версиями так много различий.
Даньеро

Спасибо, обязательно придется обновить мой Ruby. (. И переводчик и знание) Вторая группа записи не является необходимой: gsub(/(\w+)\W*/){$1[-1]}.
manatwork

О, конечно это не так. Спасибо, обновлено :)
daniero



1

Java 8, 43 байта

s->s.replaceAll("(?i).(?=[a-z])|[^a-z]","")

Порт @ mbomb007 в ответ Retina .

Объяснение:

Попробуйте онлайн.

s->  // Method with String as both parameter and return-type
  s.replaceAll("(?i).(?=[a-z])|[^a-z]","")
     //  Remove every match of this regex, and return as result

Дополнительное объяснение для регулярного выражения:

"(?i).(?=[a-z])|[^a-z]"  // Main regex to match
 (?i)                    //  Case insensitive
     .                   //   Any character
      (?=[a-z])          //   Followed by a letter (as positive look-ahead)
               |[^a-z]   //   or a non-letter

""                       // Replace it with: nothing

1
Это на самом деле (?i)для флага.
Якоб

0

Smalltalk , вкус Squeak / Pharo
122 символа с традиционным форматированием для этого метода добавлен в строку:

endOfWords
    ^(self subStrings: (CharacterSet allCharacters select: #isLetter) complement) collect: #last as: String

62 символа в Pharo 1.4, с регулярным выражением и странным форматированием

endOfWords^''join:(self regex:'[a-zA-Z]+'matchesCollect:#last)

0

J: 60 символов (или 38 символов для менее правильной версии)

(#~e.&(,26&{.&(}.&a.)"0(97 65))){:&>;:]`(' '"_)@.(e.&'_:')"0

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

(#~e.&(,26&{.&(}.&a.)"0(97 65))){:&>;:

Образец прогона:

    (#~e.&(,26&{.&(}.&a.)"0(97 65))){:&>;:]`(' '"_)@.(e.&'_:')"0'asdf jkl;__zxcv~< vbnm,.qwer| |uiop'
flvmrp
    (#~e.&(,26&{.&(}.&a.)"0(97 65))){:&>;:]`(' '"_)@.(e.&'_:')"0'pigs, eat dogs; eat Bob: eat pigs'
ststbts
    (#~e.&(,26&{.&(}.&a.)"0(97 65))){:&>;:]`(' '"_)@.(e.&'_:')"0'99_bottles_of_beer_on_the_wall'
sfrnel

1
38 байт (для правильной версии): (#~[:2&|64 90 96 122&I.@(u:inv)){:&>;:или 43 байта для не-явной версии: (#~[:2&|64 90 96 122&I.@(u:inv))@:({:@>)@;:. При этом используется глагол индекса интервала, I.который интерпретируется 64 90 96 122как набор интервалов (__, 64] (64, 90], (90, 96], (96, 122], (122, _)и возвращает индекс итервала, которому принадлежит его аргумент, код ascii символа char. Если этот индекс нечетный, он не в алфавитном порядке.
Болс Бюссьер

@BolceBussiere по какой-то причине не работает с подчеркиванием (последний контрольный пример).
FrownyFrog

@FrownyFrog ах, я понимаю почему, ;:интерпретируется abc_как одно слово, так как имена переменных могут содержать подчеркивания. +10 байт, чтобы добавить (#~~:&'_'), вероятно, неэффективное исправление
Bolce Bussiere

@BolceBussiere это просто '_'-.~или что-то подобное.
FrownyFrog

0

Это на PHP . 197 байт :( Я новичок

$l=$_GET['line'];
$l=preg_replace('/(\W|_)+/',' ',$l);
$s=explode(' ',$l);
foreach($s as $d){
$a=substr($d,-1,1);
$o=ORD($a);
if(($o>=97 && $o<=122) || ($o>=65 && $o<=90)){
echo $a;
  }
}

Отредактировано Теперь это 171 байт

<?$l=$_GET['l'];$l=preg_replace('/(\W|_)+/',' ',$l);$s=explode(' ',$l);foreach($s as $d){$a=substr($d,-1,1);$o=ORD($a);if(($o>=97&&$o<=122)||($o>=65&&$o<=90)){echo$a;}}

1
Для гольфа вы должны как можно меньше сокращать имена переменных до отдельных символов.
Гаффи

1
отредактировал это. Спасибо за сообщение. Я новичок здесь.
Сасори

Конечно. Вы также можете поискать здесь дополнительную справочную информацию по PHP.
Гаффи

foreach((' ',preg_replace('/(\W|_)+/',' ',$_GET['line'])) as $d){$a=substr($d,-1,1);$o=ORD();if(($o>=97 && $o<=122) || ($o>=65 && $o<=90)){echo $a;}}149, если это работает.
Волшебная Урна Осьминога

\W|_исключает цифры; так что вы должны добавить \dк своему регулярному выражению или использовать/[^a-z]+/i
Titus

0

К 30

q)k)f:{x@&-1=-':(1_x," ")in,/.Q`a`A}
q)f "asdf jkl;__zxcv~< vbnm,.qwer| |uiop"
"flvmrp"
q)f "pigs, eat dogs; eat Bob: eat pigs"
"ststbts"
q)f "looc si siht ,gnitirw esreveR"
"citwR"
q)f "99_bottles_of_beer_on_the_wall"
"sfrnel"

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.