Świat kończy się w wyd

21

Zaczerpnięty z zimowego konkursu programistycznego ACM 2013. Jesteś osobą, która lubi brać rzeczy dosłownie. Dlatego dla was koniec Świata jest wydany; ostatnie litery „The” i „World” zostały połączone.

Stwórz program, który pobiera zdanie, i wypisz ostatnią literę każdego słowa w tym zdaniu na możliwie najmniejszej przestrzeni (jak najmniej bajtów). Słowa są oddzielone tylko literami alfabetu (65–90, 97–122 w tabeli ASCII.) Oznacza to, że znaki podkreślenia, tyldy, groby, nawiasy klamrowe itp. Są separatorami. Między każdym słowem może znajdować się więcej niż jeden separator.

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

beary605
źródło
Czy możesz dodać przypadek testowy zawierający cyfry i podkreślenia?
grc,
10
Świat kończy się w ED? Wiedziałem , że vim i Emacs nie mogą się zmierzyć!
Joe Z.
Cóż, esej „Prawdziwi mężczyźni używają” był częścią dystrybucji Emacsa od tak dawna, jak pamiętam.
JB
Czy dane wejściowe będą tylko ASCII?
Phil H

Odpowiedzi:

16

Perl 5, 18 bajtów

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

Wymaga -pprzełącznika linii poleceń. Nazwana właściwość Lpasuje tylko do znaków literowych A-Za-z. Istnieje kilkaset takich nazwanych właściwości, ale w przypadku tekstu ASCII bardzo niewiele z nich jest interesujących. Poza \pLtym jedyną prawdziwą nutą jest \pP, która pasuje do interpunkcji.

Wypróbuj online!


Perl 5, 17 bajtów

Jednobajtowe ulepszenie Dom Hastings

print/\pL*(\pL)/g

Wymaga -n(i -ldo obsługi wielu wejść).

Wypróbuj online!


Przykładowe użycie

$ 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
primo
źródło
Myślę, że \wpasuje również do cyfr i znaków podkreślenia.
grc,
Hmm, w rzeczy samej. To będzie wymagało aktualizacji.
primo
2
Znakomity. Regex było oczywistym rozwiązaniem, ale |.nie było oczywiste (przynajmniej dla mnie).
Peter Taylor
1
Właśnie zauważyłem -1in print/\pL*(\pL)/g, wyjście wydaje się taki sam dla przypadków testowych!
Dom Hastings
18

ed, 35 znaków

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

Tak więc świat kończy się na ed. Ponieważ lubię być zbyt dosłowny, postanowiłem napisać, aby napisać rozwiązanie w ed - i najwyraźniej jest to faktycznie język programowania . Jest zaskakująco krótki, nawet biorąc pod uwagę wiele krótszych rozwiązań w tym wątku. Byłoby miło, gdybym mógł użyć czegoś innego [a-zA-Z], ale biorąc pod uwagę, że ed nie jest językiem programowania, jest wystarczająco dobry.

Po pierwsze, chciałbym powiedzieć, że analizuje to tylko ostatni wiersz w pliku. Można by parsować więcej, wystarczy wpisać ,na początku dwóch pierwszych wierszy (to określiło zakres „wszystko”, w przeciwieństwie do standardowego zakresu ostatniego wiersza), ale zwiększyłoby to rozmiar kodu do 37 znaków.

Teraz wyjaśnienia. Pierwszy wiersz robi dokładnie to samo, co robi Perl (z wyjątkiem bez obsługi znaków Unicode). Nie skopiowałem rozwiązania Perla, właśnie wynalazłem coś podobnego przez przypadek.

Drugi wiersz wypisuje ostatni wiersz, dzięki czemu można zobaczyć wynik. Trzecia linia zmusza do wyjścia - muszę to zrobić, w przeciwnym edrazie wydrukuje, ?aby przypomnieć, że nie zapisałeś pliku.

Teraz, jak to wykonać. To bardzo proste. Po prostu uruchom edz plikiem zawierającym przypadek testowy, podczas pipetowania mojego programu, w ten sposób.

ed -s testcase < program

-smilczy. Zapobiega to edwysyłaniu brzydkiego rozmiaru pliku na początku. W końcu używam go jako skryptu, a nie edytora, więc nie potrzebuję metadanych. Gdybym tego nie zrobił, ed pokazałby rozmiar pliku, którego inaczej nie mogłem zapobiec.

Konrad Borowski
źródło
Zainstalowałem ed tylko po to.
primo
6

JavaScript, 49

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

Używa wyrażenia regularnego, aby usunąć wszystkie znaki poprzedzające literę, a także wszystkie znaki nieliterowe. Następnie zostaje nam ostatnia litera każdego słowa.

Dzięki Tomsmeding dla miłej poprawy.

grc
źródło
3
Prawdopodobnie można to poprawić, zmieniając wielkość liter w wyrażeniach regularnych, na przykład w:alert(prompt().replace(/.(?=[a-z])|[^a-z]/gi,''))
tomsmeding 11.03.13
6

C, 78

Gra w golfa:

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

Z białymi znakami:

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

Wydajność:

wprowadź opis zdjęcia tutaj

JoeFish
źródło
1
Możesz zapisać 4 bajty, używając deklaracji K&R i domyślnie c:main(c,s)char**s;{for
Toby Speight
5

GNU Sed, 40 38 37

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

Testowanie

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

Uruchom sed:

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

Wydajność:

flvmrp
ststbts
citwR

Wyjaśnienie

Pierwsze podstawienie zastępuje wszystkie granice słów poprzedzone wybraną grupą dopasowania nową linią. Ułatwia to usunięcie wszystkich obcych znaków w drugiej zamianie.

Edytować

  • Użyj flagi bez rozróżniania wielkości liter (-2), dzięki manatwork .
  • Nie licz białych znaków (-1).
Thor
źródło
sed„s spolecenie ma iflagę dla przypadków niewrażliwego dopasowywania: s/[a-z]\b/&\n/gi.
manatwork
@manatwork: dobra uwaga, sprawiłoby, że GNU byłby tylko sedem, ale wygląda na to, że już jest, dzięki.
Thor
\buważa _s za litery, więc jeśli jakieś słowo w teście END z _, ostatnia litera tego słowa nie jest uwzględniona w danych wyjściowych
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

Jeśli potrzebna jest ostateczna new-line, należy wymienić tr -d \\nz paste -sd ''.

Edytować

  • Użyj grep bez rozróżniania wielkości liter (-2), dzięki manatwork .
  • Użyj trzamiast paste(-4), dzięki manatwork .
  • Nie licz białych znaków wokół potoku (-2).
Thor
źródło
Jest dość kreatywny paste -sd '', ale tr -d \\njest krótszy. Jeśli chodzi grep, ma -iprzełącznik sens „ignorować sprawy”, który może sprawić, że krótsza: grep -io '[a-z]\b'.
manatwork
@manatwork, trusuń także ostatnią nową linię. Dzięki temu tryb bez rozróżniania wielkości liter jest oczywiście krótszy.
Thor
nie ma reguły wymagającej ostatecznego nowego wiersza.
manatwork
@manatwork: Mogę się z tym zgodzić, zaktualizowana odpowiedź.
Thor
3

sed, 37 znaków

Równa długość do odpowiedzi Thora , ale myślę, że prościej.

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

Logika jest dość trywialna - zamień sekwencje liter na ostatnią literę, a następnie usuń wszystkie nie-litery.

ugoren
źródło
3

Mathematica, 39

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

Test:

""<>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"}
Mr.Wizard
źródło
Dobry. LetterQpowinienem się nazywać LettersQ:) Nie myślałem o tym do testowania całych łańcuchów.
Dr Belisarius
@belisarius Właściwie dzięki tej konstrukcji jest on stosowany znakowo, więc może być dosłowną literą „LetterQ” i nadal działać.
Mr.Wizard
2

K, 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"
tartin
źródło
2

Scala, 59 (lub 43)

Zakładając, że ciąg jest już w s:

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

Jeśli potrzebujesz czytać z monitu i drukować, zamiast korzystać z danych wyjściowych REPL, przekonwertuj sna readLinei zapakuj println()dla 59.

Rex Kerr
źródło
2

x86: 54 bajty

Załóżmy procedurę cdecl z podpisem 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
użytkownik1354557
źródło
1
Nawiasem mówiąc, zdaję sobie sprawę, że pytanie wymaga programu, a nie rutyny , ale chciałem zrobić coś innego. W przeciwieństwie do stwierdzenia problemu, chyba nie jestem „osobą, która lubi brać rzeczy dosłownie”. : P
użytkownik1354557,
2

Xi, 32

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

Xi jest językiem wciąż w fazie beta, ale wydaje się, że działa dobrze z golfem kodowym, więc pomyślałem, że równie dobrze mogę pokazać jeszcze jedno krótkie i funkcjonalne rozwiązanie (i trochę reklamować język :-)).

arshajii
źródło
2

Mathematica 62 57 52

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

Testowanie

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}*)
Dr Belizariusz
źródło
Przez pomyłkę zredagowałem twój, ale potem go wycofałem. Ups
DavidC
2

Python3, 59 znaków

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

Prawidłowo dotyczy wielkich liter i znaków podkreślenia. W 2 jest przekazać re.subdo re.IGNORECASEflagi bez konieczności użycia re.I.

Nolen Royalty
źródło
2

Python, 76 znaków

import re;print "".join(re.findall("([a-zA-Z])(?=$|[^a-zA-Z])",raw_input()))

indrajeet
źródło
Możesz usunąć spację później print.
trzęsienie ziemi
Skróć, przenosząc do Pythona 3:import re;print(*re.findall("([a-zA-Z])(?=$|[^a-zA-Z])",input()),sep='')
Steven Rumbalski
1

Python 3.x, 64 bajty

import re;print(''.join(a[-1] for a in re.split('\W+',input())))
Michael0x2a
źródło
2
Ostatni przykład nie działa. Ponadto występuje błąd, jeśli linia zaczyna się lub kończy separatorem
AMK
Możesz wcześniej usunąć spację for.
Bakuriu
1

Lua, 42 lata

print(((...):gsub('.-(.)%f[%A]%A*','%1')))

Przykład użycia: lua script.lua "asdf jkl;__zxcv~< vbnm,.qwer| |uiop"

Egor Skriptunoff
źródło
1

Mathematica 71 47 45 61

Wróć do tablicy kreślarskiej po tym, jak @belisarius znalazł błąd w kodzie.

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

Testowanie

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”}

DavidC
źródło
\\wpasuje _, więc nie działa (na przykład)"asdf jkl__zxcv~<vbnm,.qwer| |uiop"
Dr. belisarius
Row@StringTake[ StringCases[#, LetterCharacter ..], -1] &@"asdf jkl__zxcv~<vbnm,.qwer| |uiop"Daj mi czekać flvmrp, ale #~StringCases~RegularExpression@"\\w\\b" <> "" &@"asdf jkl__zxcv~<vbnm,.qwer| |uiop"wraca fvmrptutaj. Czy otrzymujemy te same wyniki?
Dr Belisarius
@belisarius Miałeś rację co do błędu w mojej wcześniejszej wersji. Testowałem to z niewłaściwym ciągiem!
DavidC
Hehe, +1 ponownie
Dr. Belisarius
@belisarius, zobacz odpowiedź, którą opublikowałem. Jeśli jest poprawny, jest krótszy.
Mr.Wizard
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

Wkład: 435_ASDC__uio;|d re;fG o55677jkl..f

Wydajność: CodeGolf


To rozwiązanie można skrócić do 67 znaków, jeśli zezwolisz, aby na początku były uwzględniane znaki cofania (kod ASCII 8). Dane wyjściowe będą wizualnie identyczne.

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

To samo wejście, (wizualnie) to samo wyjście. <BS>ma być znakiem backspace.

trzęsienie ziemi
źródło
1

DO#

Metoda, 105 bajtów: (zakłada użycia dla System, System.Text.RegularExpressions i System.Linq)

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

Program, 211 bajtów:

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())));}}
It'sNotALie.
źródło
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
Gaffi
źródło
1

Ruby 2.0, 25 (+1) znaków

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

Należy uruchomić za pomocą -pprzełącznika:

 $ ruby -p ed.rb <<< "asdf jkl;__zxcv~< vbnm,.qwer| |uiop"
flvmrp
daniero
źródło
Proszę podać rubywersję. 1.9.2 wyprowadza „# <Enumerator: 0x9f65e10> # <Enumerator: 0x9f65d98> # <Enumerator: 0x9f65d34> # <Enumerator: 0x9f65cd0>”.
manatwork
Masz rację. Zupełnie zapomniałem, że go zainstalowałem, ale moja obecna wersja Ruby to 2.0 ( ruby 2.0.0p0 (2013-02-24 revision 39474). Podczas uruchamiania programu z wersją 1.8.7 wyświetla on wartość ASCII! Nie wiedziałem, że istnieje tak wiele różnic między wersjami.
daniero
Dzięki, na pewno będę musiał zaktualizować mój Ruby. (. Zarówno interpretera i wiedza) Druga grupa wychwytywanie nie jest konieczne: gsub(/(\w+)\W*/){$1[-1]}.
manatwork
Och, oczywiście, że nie. Dzięki, zaktualizowano :)
daniero
1

Siatkówka , 16 bajtów

Li, -1|""`[a-z]+

Wypróbuj online!

Wyjaśnienie

Li, -1|""`[a-z]+
L         [a-z]+        List all the sequences of letters in the input
 i                      case insensitive
  ,                     Keep all the results
    -1                  but only the last character for each of them
      |""               Use the empty string as separator
Lew
źródło
1

Java 8, 43 bajty

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

Port odpowiedzi Retina @ mbomb007 .

Wyjaśnienie:

Wypróbuj online.

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

Dodatkowe wyjaśnienie wyrażenia regularnego:

"(?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
Kevin Cruijssen
źródło
1
To tak naprawdę (?i)dotyczy flagi.
Jakob
0

Smalltalk , Squeak / Pharo flavour
122 char z tradycyjnym formatowaniem tej metody dodany do String:

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

62 znaki w Pharo 1.4, z wyrażeniem regularnym i dziwnym formatowaniem

endOfWords^''join:(self regex:'[a-zA-Z]+'matchesCollect:#last)
aka.nice
źródło
0

J: 60 znaków (lub 38 znaków w przypadku mniej poprawnej wersji)

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

Jeśli chcemy, aby program się zepsuł, gdy tylko słowa kończą się dwukropkiem lub znakiem podkreślenia, możemy uprościć to do 38 znaków.

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

Przykładowy przebieg:

    (#~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
SL2
źródło
1
38 bajtów (dla poprawnej wersji): (#~[:2&|64 90 96 122&I.@(u:inv)){:&>;:lub 43 bajtów dla non-wyraźnej wersji: (#~[:2&|64 90 96 122&I.@(u:inv))@:({:@>)@;:. Używa to czasownika indeksu interwału I., który interpretuje 64 90 96 122jako zestaw interwałów (__, 64] (64, 90], (90, 96], (96, 122], (122, _), i zwraca indeks iterval, do którego należy jego argument, kod ascii znaku. Jeśli ten indeks jest nieparzysty, nie jest alfabetyczny.
Bolce Bussiere
@BolceBussiere z jakiegoś powodu nie działa z podkreśleniami (ostatni przypadek testowy).
FrownyFrog,
@FrownyFrog ah, rozumiem dlaczego, ;:interpretuje abc_jako jedno słowo, ponieważ nazwy zmiennych mogą zawierać podkreślenia. +10 bajtów do dodania (#~~:&'_'), prawdopodobnie nieefektywna poprawka
Bolce Bussiere
@BolceBussiere, które jest po prostu '_'-.~lub coś podobnego.
FrownyFrog,
0

To jest w PHP . 197 bajtów :( Jestem początkujący

$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;
  }
}

ZMIENIONO Teraz jest 171 bajtów

<?$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;}}
Sasori
źródło
1
W golfie należy maksymalnie ograniczyć nazwy zmiennych do co najmniej pojedynczych znaków.
Gaffi
1
edytowałem to. Dzięki, że mi powiedziałeś. Jestem tu nowy.
Sasori
Pewnie. Możesz także poszukać tutaj dodatkowej pomocy specyficznej dla PHP.
Gaffi
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;}}ma 149, jeśli to działa.
Magic Octopus Urn
\W|_nie obejmuje cyfr; więc powinieneś dodać \ddo wyrażenia regularnego lub użyć/[^a-z]+/i
Tytus
0

K 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"
rrr
źródło
0

Japt v2, 16 bajtów

r/\L*\l+)\L*/@YÌ

Spróbuj

Kudłaty
źródło
Myślę, że możesz to zrobić f"%l(?!%l)" q(nie działa w v2, ponieważ parser nie lubi (?)
ETHproductions