Dunia berakhir pada ed

21

Diambil langsung dari ACM Winter Programming Contest 2013. Anda adalah orang yang suka mengambil sesuatu secara harfiah. Karena itu, bagimu, akhir Dunia adalah ed; huruf terakhir dari "The" dan "World" disatukan.

Buat program yang mengambil kalimat, dan keluarkan huruf terakhir dari setiap kata dalam kalimat itu dalam ruang sesedikit mungkin (byte paling sedikit). Kata-kata dipisahkan dengan apa pun kecuali huruf dari alfabet (65 - 90, 97 - 122 pada tabel ASCII.) Itu berarti menggarisbawahi, tildes, kuburan, kurung kurawal, dll adalah pemisah. Mungkin ada lebih dari satu pemisah antara setiap kata.

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
sumber
Bisakah Anda menambahkan kotak uji termasuk angka dan garis bawah?
grc
10
Dunia berakhir pada ed? Saya tahu vim dan Emacs tidak bisa mengukur!
Joe Z.
Nah, esai "pria sejati menggunakan ed" telah menjadi bagian dari distribusi Emacs selama yang saya ingat.
JB
Apakah inputnya hanya ASCII?
Phil H

Jawaban:

16

Perl 5, 18 byte

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

Membutuhkan -psaklar baris perintah. Properti yang disebutkan Lhanya cocok dengan karakter huruf A-Za-z. Ada beberapa ratus properti yang dinamai demikian, tetapi ketika berhadapan dengan teks ASCII, sangat sedikit yang menarik. Selain itu \pL, satu-satunya yang lain dari not nyata adalah \pP, yang cocok dengan tanda baca.

Cobalah online!


Perl 5, 17 byte

Peningkatan satu byte oleh Dom Hastings

print/\pL*(\pL)/g

Membutuhkan -n(dan -lmendukung banyak input).

Cobalah online!


Penggunaan sampel

$ 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
sumber
Saya pikir \wjuga cocok dengan angka dan garis bawah.
grc
Hmm, memang. Itu perlu diperbarui.
Primo
2
Cemerlang. Regex adalah solusi yang jelas, tetapi |.tidak jelas (bagi saya, setidaknya).
Peter Taylor
1
Hanya perhatikan -1dalam print/\pL*(\pL)/g, tampaknya keluaran yang sama untuk kasus uji Anda!
Dom Hastings
18

ed, 35 karakter

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

Jadi, dunia berakhir pada ed. Karena saya ingin menjadi terlalu literal, saya memutuskan untuk menulis untuk menulis solusinya dengan ed - dan ternyata itu sebenarnya bahasa pemrograman . Ini mengejutkan pendek, bahkan mempertimbangkan banyak solusi yang lebih pendek sudah ada di utas ini. Akan lebih baik jika saya bisa menggunakan sesuatu selain [a-zA-Z], tetapi mengingat ed bukan bahasa pemrograman, itu sebenarnya cukup baik.

Pertama, saya ingin mengatakan ini hanya mem-parsing baris terakhir dalam file. Dimungkinkan untuk mem-parsing lebih banyak, cukup ketik ,di awal dua baris pertama (rentang "semuanya" yang ditentukan ini, yang bertentangan dengan rentang baris terakhir standar), tetapi itu akan meningkatkan ukuran kode menjadi 37 karakter.

Sekarang untuk penjelasan. Baris pertama melakukan persis apa yang dilakukan solusi Perl (kecuali tanpa dukungan untuk karakter Unicode). Saya belum menyalin solusi Perl, saya baru saja menemukan sesuatu yang serupa secara kebetulan.

Baris kedua mencetak baris terakhir, sehingga Anda bisa melihat hasilnya. Kekuatan garis ketiga berhenti - saya harus melakukannya, jika tidak edakan mencetak ?untuk mengingatkan Anda bahwa Anda belum menyimpan file.

Sekarang untuk bagaimana menjalankannya. Yah, ini sangat sederhana. Jalankan saja eddengan file yang berisi test case, sambil mem-pipkan program saya, seperti itu.

ed -s testcase < program

-sdiam. Ini mencegah eddari menghasilkan ukuran file yang jelek di awal. Bagaimanapun, saya menggunakannya sebagai skrip, bukan editor, jadi saya tidak perlu metadata. Jika saya tidak melakukan itu, ed akan menunjukkan ukuran file yang saya tidak bisa mencegah sebaliknya.

Konrad Borowski
sumber
Saya menginstal ed hanya untuk mencoba ini.
Primo
6

Javascript, 49

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

Itu menggunakan ekspresi reguler untuk menghapus semua karakter yang datang sebelum huruf, serta semua karakter non-huruf. Lalu kita pergi dengan huruf terakhir dari setiap kata.

Terima kasih kepada Tom untuk perbaikan yang bagus.

grc
sumber
3
Anda mungkin dapat meningkatkan ini dengan membuat regex case-insensitive, seperti di:alert(prompt().replace(/.(?=[a-z])|[^a-z]/gi,''))
tommeding
6

C, 78

Golf:

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

Dengan spasi putih:

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

Keluaran:

masukkan deskripsi gambar di sini

JoeFish
sumber
1
Anda dapat menyimpan 4 byte dengan menggunakan deklarasi K&R dan melakukan default 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

Pengujian

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

Jalankan sed:

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

Keluaran:

flvmrp
ststbts
citwR

Penjelasan

Substitusi pertama menggantikan semua batas kata, yang didahului oleh grup pertandingan yang diinginkan, dengan baris baru. Ini membuatnya mudah untuk menghapus semua karakter asing di substitusi kedua.

Edit

  • Gunakan flag case-insensitive (-2), terima kasih manatwork .
  • Jangan hitung spasi putih (-1).
Thor
sumber
sed's sperintah memiliki ibendera untuk kasus-kasus yang cocok sensitif: s/[a-z]\b/&\n/gi.
manatwork
@manatwork: poin bagus, ini akan membuatnya hanya GNU, tapi sepertinya sudah, terima kasih.
Thor
\bmenganggap _s sebagai huruf, jadi jika ada kata dalam tes AKHIR dengan _, huruf terakhir kata itu tidak termasuk dalam output
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

Jika baris baru final diperlukan, ganti tr -d \\ndengan paste -sd ''.

Edit

  • Gunakan case- insepitive grep (-2), terima kasih manatwork .
  • Gunakan trbukan paste(-4), terima kasih manatwork .
  • Jangan hitung spasi putih di sekitar pipa (-2).
Thor
sumber
Cukup kreatif dengan itu paste -sd '', tetapi tr -d \\nlebih pendek. Mengenai grep, ia memiliki -isaklar arti “abaikan”, yang dapat membuatnya lebih pendek: grep -io '[a-z]\b'.
manatwork
@manatwork, trhapus juga baris terakhir. Mode case-sensitive tidak tentu saja lebih pendek, terima kasih.
Thor
tidak ada aturan yang mewajibkan baris baru final.
manatwork
@manatwork: Saya setuju dengan itu, jawaban yang diperbarui.
Thor
3

sed, 37 karakter

Panjangnya sama dengan jawaban Thor , tetapi, saya pikir, lebih sederhana.

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

Logikanya cukup sepele - ganti urutan huruf dengan huruf terakhir mereka, lalu hapus semua non-huruf.

ugoren
sumber
3

Mathematica, 39

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

Uji:

""<>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"}
Tuan Penyihir
sumber
Bagus LetterQharus dipanggil LettersQ:) Saya belum memikirkannya untuk menguji seluruh string.
Dr. belisarius
@belisarius Sebenarnya, dengan konstruk ini diterapkan karakter-bijaksana, sehingga bisa menjadi "LetterQ" literal dan masih berfungsi.
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"
tmartin
sumber
2

Scala, 59 (atau 43)

Dengan asumsi string sudah ada di s:

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

Jika Anda perlu membaca dari prompt dan mencetak daripada menggunakan output REPL, konversikan ske readLinedan masukkan println()59.

Rex Kerr
sumber
2

x86: 54 byte

Asumsikan rutin cdecl dengan tanda tangan 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
pengguna1354557
sumber
1
Ngomong-ngomong, saya menyadari pertanyaannya menanyakan program dan bukan rutinitas , tetapi saya ingin melakukan sesuatu yang berbeda. Bertentangan dengan pernyataan masalah, saya kira saya bukan "orang yang suka mengambil sesuatu secara harfiah". : P
user1354557
2

Xi, 32

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

Xi adalah bahasa yang masih dalam fase beta, tetapi tampaknya bekerja dengan baik dengan kode golf jadi saya pikir saya mungkin juga menunjukkan solusi pendek dan fungsional lainnya (dan beriklan sedikit bahasa :-)).

arshajii
sumber
2

Mathematica 62 57 52

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

Pengujian

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}*)
Belisarius
sumber
Saya salah mengedit milik Anda, tetapi kemudian mengembalikannya. Ups.
DavidC
2

Python3, 59 karakter

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

Berurusan dengan benar dengan huruf kapital dan garis bawah. 2 adalah untuk lulus re.subdengan re.IGNORECASEbendera tanpa harus menggunakan re.I.

Royalti yang Dicuri
sumber
2

Python, 76 karakter

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

indrajeet
sumber
Anda dapat menghapus ruang setelah print.
flornquake
Dipendekkan dengan porting ke Python 3:import re;print(*re.findall("([a-zA-Z])(?=$|[^a-zA-Z])",input()),sep='')
Steven Rumbalski
1

Python 3.x, 64 byte

import re;print(''.join(a[-1] for a in re.split('\W+',input())))
Michael0x2a
sumber
2
Contoh terakhir tidak berfungsi. Juga, kesalahan terjadi jika garis dimulai atau diakhiri dengan pemisah
AMK
Anda dapat menghapus ruang sebelumnya for.
Bakuriu
1

Lua, 42

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

Contoh penggunaan: lua script.lua "asdf jkl;__zxcv~< vbnm,.qwer| |uiop"

Egor Skriptunoff
sumber
1

Mathematica 71 47 45 61

Kembali ke papan gambar, setelah @belisarius menemukan kesalahan dalam kode.

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

Pengujian

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
sumber
\\wcocok _, sehingga tidak berfungsi untuk (misalnya)"asdf jkl__zxcv~<vbnm,.qwer| |uiop"
Dr. belisarius
Tunggu Row@StringTake[ StringCases[#, LetterCharacter ..], -1] &@"asdf jkl__zxcv~<vbnm,.qwer| |uiop"beri saya flvmrp, tetapi #~StringCases~RegularExpression@"\\w\\b" <> "" &@"asdf jkl__zxcv~<vbnm,.qwer| |uiop"kembali ke fvmrpsini. Apakah kita mendapatkan hasil yang sama ??
Dr. belisarius
@belisarius Anda benar tentang kesalahan pada versi saya sebelumnya. Saya mengujinya dengan string yang salah!
DavidC
Hehe, +1 lagi
Dr. belisarius
@belisarius kawan, silakan lihat jawaban yang saya posting. Jika benar itu lebih pendek.
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

Memasukkan: 435_ASDC__uio;|d re;fG o55677jkl..f

Keluaran: CodeGolf


Solusi ini dapat disingkat menjadi 67 karakter jika Anda mengizinkan output untuk memasukkan karakter backspace (kode ASCII 8) di awal. Outputnya akan identik secara visual.

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

Input yang sama, (secara visual) output yang sama. <BS>dimaksudkan untuk menjadi karakter backspace.

gempa bumi
sumber
1

C #

Metode, 105 byte: (mengasumsikan penggunaan untuk System, System.Text.RegularExpressions and System.Linq)

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

Program, 211 byte:

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())));}}
Itu adalah Notalie.
sumber
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
sumber
1

Ruby 2.0, 25 (+1) karakter

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

Harus dijalankan dengan -psakelar:

 $ ruby -p ed.rb <<< "asdf jkl;__zxcv~< vbnm,.qwer| |uiop"
flvmrp
daniero
sumber
Silakan tentukan rubyversinya. 1.9.2 keluaran “# <Enumerator: 0x9f65e10> # <Enumerator: 0x9f65d98> # <Enumerator: 0x9f65d34> # <Enumerator: 0x9f65cd0>”.
manatwork
Kamu benar. Saya benar-benar lupa bahwa saya menginstalnya, tetapi versi Ruby saya saat ini adalah 2.0 ( ruby 2.0.0p0 (2013-02-24 revision 39474). Saat menjalankan program dengan versi 1.8.7 ini menghasilkan nilai ASCII! Tidak tahu ada begitu banyak perbedaan antar versi.
daniero
Terima kasih, pasti harus memperbarui Ruby saya. (. Kedua penafsir dan pengetahuan) Kelompok menangkap kedua tidak diperlukan: gsub(/(\w+)\W*/){$1[-1]}.
manatwork
Oh, tentu saja tidak. Terima kasih, diperbarui :)
daniero
1

Retina , 16 byte

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

Cobalah online!

Penjelasan

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
Leo
sumber
1

Java 8, 43 byte

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

Port @ mbomb007 adalah jawaban Retina .

Penjelasan:

Cobalah 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

Penjelasan tambahan untuk regex:

"(?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
sumber
1
Itu sebenarnya (?i)untuk bendera.
Jakob
0

Smalltalk , Squeak / Pharo flavor
122 char dengan format tradisional untuk metode ini ditambahkan ke String:

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

62 karakter di Pharo 1.4, dengan format regex dan aneh

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

J: 60 karakter (atau 38 karakter untuk versi yang kurang benar)

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

Jika kami bersedia membiarkan program terputus setiap kali ada kata yang berakhir dengan titik dua atau garis bawah, maka kami dapat menyederhanakannya menjadi 38 karakter.

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

Contoh dijalankan:

    (#~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
sumber
1
38 Bytes (untuk versi yang benar): (#~[:2&|64 90 96 122&I.@(u:inv)){:&>;:, atau 43 byte untuk versi non-eksplisit: (#~[:2&|64 90 96 122&I.@(u:inv))@:({:@>)@;:. Ini menggunakan kata kerja indeks interval I.,, yang diartikan 64 90 96 122sebagai himpunan interval (__, 64] (64, 90], (90, 96], (96, 122], (122, _), dan mengembalikan indeks iterval yang dimiliki argumennya, kode ascii dari char. Jika indeks ini aneh, ini bukan abjad.
Bolce Bussiere
@ BolceBussiere tidak bekerja dengan garis bawah karena alasan tertentu (test case terakhir).
FrownyFrog
@FrownyFrog ah, saya mengerti, ;:interpretabc_ sebagai satu kata karena nama variabel dapat berisi garis bawah. +10 byte untuk ditambahkan (#~~:&'_'), mungkin perbaikan yang tidak efisien
Bolce Bussiere
@ BolceBussiere itu hanya '_'-.~atau sesuatu yang serupa.
FrownyFrog
0

Ada dalam PHP . 197 byte :( Saya pemula

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

DIedit Sekarang ini 171 byte

<?$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
sumber
1
Untuk golf, Anda harus sedapat mungkin mengurangi nama variabel Anda menjadi satu karakter.
Gaffi
1
diedit. Terima kasih sudah memberi tahu saya. Saya baru di sini.
Sasori
Yakin. Anda mungkin juga ingin mencari di sini untuk bantuan tambahan khusus 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;}}adalah 149, jika berhasil.
Magic Gurita Guci
\W|_tidak termasuk digit; jadi Anda harus menambah \dregex Anda atau menggunakan/[^a-z]+/i
Titus
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
sumber
0

Japt v2, 16 byte

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

Cobalah

Shaggy
sumber
Saya pikir Anda bisa melakukan f"%l(?!%l)" q(tidak bekerja di v2 karena parser tidak suka (?)
ETHproduksi