Dünya ed ile bitiyor


21

Doğrudan ACM Kış Programlama Yarışması 2013'ten alınmıştır. Sizleri kelimenin tam anlamıyla almaktan hoşlanan bir kişisiniz. Bu nedenle, sizin için, Dünyanın sonu ed; "ve" dünyasının son harfleri bitiştirildi.

Bir cümle alan bir program yapın ve bu cümle içindeki her kelimenin son harfini mümkün olduğunca az alanda (en az bayt) çıkarın. Kelimeler, alfabedeki harflerden başka hiçbir şeyle ayrılmaz (ASCII masasında 65 - 90, 97 - 122). Bu, alt çizgi, tilde, mezar, kıvrımlı parantez, vb. Anlamına gelir. Her kelime arasında birden fazla ayırıcı olabilir.

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


Rakam ve alt çizgi içeren bir test durumu ekleyebilir misiniz?
grc

10
Dünya ed ile bitiyor mu? Ben biliyordum vim ve Emacs ölçü olamazdı!
Joe Z.

Eh, “gerçek erkekler ed” makalesi, hatırlayabildiğim kadarıyla Emacs dağılımının bir parçası oldu.
JB

Girişler sadece ASCII mi olacak?
Phil H

Yanıtlar:


16

Perl 5, 18 bayt

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

Bir -pkomut satırı anahtarı gerektirir . Adlandırılmış özellik Lyalnızca harf karakterleriyle eşleşiyor A-Za-z. Bu tür yüzlerce özellik var, ancak ASCII metni ile uğraşırken, bunların pek azı ilginç. Ayrıca \pL, gerçek notlardan yalnızca bir tanesi \pPnoktalama işaretleriyle eşleşir.

Çevrimiçi deneyin!


Perl 5, 17 bayt

Dom Hastings'ten bir byte gelişme

print/\pL*(\pL)/g

Gerektirir -n(ve -lbirden fazla girişi desteklemek için).

Çevrimiçi deneyin!


Örnek kullanım

$ 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

\wAyrıca rakam ve alt çizgi ile eşleştiğini düşünüyorum .
grc

Hmm, gerçekten. Bunun güncellenmesi gerekecek.
primo

2
Parlak. Regex açık bir çözümdü, ancak |.açık değildi (en azından benim için).
Peter Taylor

1
Sadece bir fark -1in print/\pL*(\pL)/g, test durumları için aynı çıkışa görünüyor!
Dom Hastings

18

ed, 35 karakter

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

Böylece dünya ed ile bitiyor. Kelimenin tam anlamıyla hazır olmayı sevdiğim için, çözümü ed ile yazmak için yazmaya karar verdim - ve görünüşe göre aslında bir programlama dili . Şaşırtıcı derecede kısa, bu konudaki zaten birçok kısa çözümü göz önünde bulundurarak bile. Başka bir şey kullanabilseydim daha iyi olurdu [a-zA-Z], ama ed bir programlama dili değil, aslında yeterince iyi.

İlk önce, bunun sadece dosyadaki son satırı ayrıştırdığını söylemek istiyorum. Daha fazla ayrıştırmak mümkün olacak, sadece ,iki ilk satırın başına yazmanız (bu, standart son satır aralığının aksine "her şey" aralığında belirtilen) ancak kod boyutunu 37 karaktere çıkaracaktı.

Şimdi açıklamalar için. İlk satır, tam olarak Perl çözümünün yaptığını yapar (Unicode karakterleri için destek olmadan). Perl çözümünü kopyalamadım, sadece tesadüf eseri benzer bir şey icat ettim.

İkinci satır son satırı yazdırır, böylece çıktısını görebilirsiniz. Üçüncü satır kuvvetleri çıkın - Yapmak zorunda aksi edbasacaktır ?Dosyayı kaydettikten değil hatırlatmak için.

Şimdi nasıl çalıştırılacağı için. Çok basit. edProgramımı böyle bağlarken, sadece test senaryosunu içeren dosyayı çalıştırın .

ed -s testcase < program

-sSessiz. Bu ed, başlangıçta çirkin dosya boyutunun çıkmasını önler . Ne de olsa editör değil komut dosyası olarak kullanıyorum, bu yüzden meta verilere ihtiyacım yok. Bunu yapmazsam, ed aksi halde önleyemediğim dosya boyutunu gösterir.


Sadece bunu denemek için ed kurdum.
primo

6

Javascript, 49

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

Bir harften önce gelen tüm karakterleri ve tüm harf olmayan karakterleri kaldırmak için normal bir ifade kullanır. Sonra her kelimenin son harfi ile ayrıldık.

Güzel bir gelişme için tomsmeding sayesinde .


3
alert(prompt().replace(/.(?=[a-z])|[^a-z]/gi,''))
Regex'i büyük /

6

C, 78

golfed:

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

Boşluk ile:

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

Çıktı:

görüntü tanımını buraya girin


1
K&R bildirimini kullanarak ve varsayılan ayarları kullanarak 4 byte kazanabilirsiniz 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

Test yapmak

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

Sed çalıştırın:

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

Çıktı:

flvmrp
ststbts
citwR

açıklama

İlk yer değiştirme, istenen eşleşme grubunun önündeki tüm sözcük sınırlarını yeni bir satırla değiştirir. Bu, ikinci ikamede tüm yabancı karakterleri çıkarmayı kolaylaştırır.

Düzenle

  • Büyük küçük harf duyarsız bayrak (-2) kullanın .
  • Boşlukları saymayın (-1).

sedbireyin skomut vardır ivakalar duyarsız eşleştirme için bayrak: s/[a-z]\b/&\n/gi.
Manatwork

@ yönetim: iyi nokta, bu sadece GNU'yu baştan çıkarır, ama zaten öyle görünüyor, teşekkürler.
Thor

\bgördüğü _s testi herhangi kelimeler eğer öyleyse, harfler olmak END ile _bu kelimenin son harfi çıktıda dahil değildir,
Marty Neal

3

Grep ve Yapıştır, 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

Son bir yeni satır gerekiyorsa değiştirin tr -d \\nile paste -sd ''.

Düzenle

  • Kullanım örneği duyarsız grep (2), sayesinde manatwork .
  • Kullanım tryerine paste(-4), teşekkürler manatwork .
  • Borunun etrafındaki boşlukları saymayın (-2).

Oldukça yaratıcı paste -sd '', ancak tr -d \\ndaha kısa. İlgili grep, sahip olduğu -idaha kısa bir hale gelebilir, “davayı görmezden” anahtarı anlamı: grep -io '[a-z]\b'.
Manatwork

@ manatwork, trson yeni satırı da silin. Büyük küçük harf duyarsız modu elbette daha kısa, teşekkürler.
Thor

Son satırın yapılmasını gerektiren hiçbir kural yoktur.
Manatwork

@ yönetimsel: Buna katılıyorum, güncellenmiş cevap.
Thor

3

sed, 37 karakter

Thor'un cevabına eşit uzunluk , ama sanırım daha basit.

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

Mantık oldukça önemsizdir - harf dizilerini son harfleriyle değiştir, sonra tüm harfleri sil.


3

Mathematica, 39

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

Ölçek:

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

İyi bir. LetterQçağrılmalı LettersQ:) Bütün dizeleri sınamak için hiç düşünmedim.
Dr. Belisarius

@belisarius Aslında, bu yapı ile karakter bazında uygulanır, bu nedenle değişmez bir "LetterQ" olabilir ve hala çalışabilir.
Sihirbaz,

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"

2

Scala, 59 (veya 43)

Dize zaten olduğu varsayılarak s:

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

Eğer bir istem okuma ve REPL çıkışı, dönüştürmek kullanmak yerine yazdırmak gerekiyorsa setmek readLineve sarmak println()59 için.


2

x86: 54 bayt

İmzayla birlikte bir cdecl yordamı varsayalım 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
Bu arada, soruyu bir rutinden değil programdan istediğini anlıyorum, ancak farklı bir şey yapmak istedim. Sorun ifadesinin aksine, sanırım sonuçta "bir şeyleri anlamayı seven" bir insan değilim. : P
user1354557

2

Xi, 32

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

Xi hala beta aşamasında olan bir dil, ancak kod golf ile iyi çalışıyor gibi gözüküyor, bu yüzden başka bir kısa ve işlevsel çözüm gösterebileceğimi düşündüm (ve dili biraz :-) duyurdum).


2

Mathematica 62 57 52

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

Test yapmak

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}*)

Yanlışlıkla seninkileri düzenledim ama sonra geri aldım. Hata.
DavidC

2

Python3, 59 karakter

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

Doğru, büyük harflerle ve alt çizgilerle ilgilenir. 2 geçmektir kullanımına gerek kalmadan bayrak .re.subre.IGNORECASEre.I


2

Python, 76 karakter

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


Sonra boşluğu kaldırabilirsiniz print.
Flornquake,

Python 3'e taşınmasıyla import re;print(*re.findall("([a-zA-Z])(?=$|[^a-zA-Z])",input()),sep='')
kısaltılmış

1

Python 3.x, 64 bayt

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

2
Son örnek çalışmıyor. Ayrıca, çizgi bir ayırıcıyla başlarsa veya biterse bir hata oluşur
AMK

Önce boşluğu kaldırabilirsiniz for.
Bakuriu

1

Lua, 42

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

Kullanım örneği: lua script.lua "asdf jkl;__zxcv~< vbnm,.qwer| |uiop"


1

Mathematica 71 47 45 61

Çizim tahtasına geri döndükten sonra, @belisarius kodda bir hata buldu.

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

Test yapmak

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


\\weşleşir _, bu nedenle işe yaramazsa (örneğin)"asdf jkl__zxcv~<vbnm,.qwer| |uiop"
Dr. belisarius

Bekle Row@StringTake[ StringCases[#, LetterCharacter ..], -1] &@"asdf jkl__zxcv~<vbnm,.qwer| |uiop"bana verir flvmrp, ama buraya #~StringCases~RegularExpression@"\\w\\b" <> "" &@"asdf jkl__zxcv~<vbnm,.qwer| |uiop"döner fvmrp. Aynı sonuçları mı alıyoruz ??
Dr. Belisarius

@belisarius Önceki sürümümdeki hata konusunda haklıydınız. Yanlış dize ile test ediyordum!
DavidC,

Hehe, tekrar +1
Dr. belisarius

@belisarius beyleri, lütfen gönderdiğim cevaba bakınız. Eğer doğru ise daha kısa.
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

Giriş: 435_ASDC__uio;|d re;fG o55677jkl..f

Çıktı: CodeGolf


Çıktının başında geri al karakterlerini (ASCII kodu 8) içermesine izin verirseniz , bu çözüm 67 karaktere kısaltılabilir . Çıkış görsel olarak aynı olacaktır.

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

Aynı giriş, (görsel olarak) aynı çıkış. <BS>geri alma karakteri olduğu anlamına gelir.


1

C #

Metod, 105 bayt: (System, System.Text.RegularExpressions ve System.Linq için kullanımları varsayar)

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

Program, 211 bayt:

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) karakter

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

-pAnahtar ile çalıştırılmalıdır :

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

Lütfen rubysürümü belirtin . 1.9.2 "# <Numaralandırıcı: 0x9f65e10> # <Numaralandırıcı: 0x9f65d98> # <Numaralandırıcı: 0x9f65d34> # <Numaralandırıcı: 0x9f65cd0>" çıkışını verir.
Manatwork

Haklısın. Yüklediğimi tamamen unutmuştum, ancak şu anki Ruby sürümüm 2.0 ( ruby 2.0.0p0 (2013-02-24 revision 39474). Programı 1.8.7 sürümüyle çalıştırırken, bir ASCII değeri verir! Sürümler arasında çok fazla fark olduğunu bilmiyordum.
daniero

Teşekkürler, kesinlikle Ruby'mi güncellemem gerekecek. (. Yorumlayıcı ve bilgi Hem) ikinci tespit grubu gerekli değildir: gsub(/(\w+)\W*/){$1[-1]}.
Manatwork

Oh, elbette değil. Teşekkürler, güncellendi :)
daniero

1

Retina , 16 bayt

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

Çevrimiçi deneyin!

açıklama

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


1

Java 8, 43 bayt

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

Limanı @ mbomb007 'ın Retina cevap .

Açıklama:

Çevrimiçi deneyin.

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

Regex için ek açıklama:

"(?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
Bu aslında (?i)bayrak için.
Jakob

0

Smalltalk , Squeak / Pharo lezzet
122 karakter geleneksel biçimlendirme ile Dize'ye eklendi:

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

Regex ve garip biçimlendirme ile Pharo 1.4, 62 karakter

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

0

J: 60 karakter (veya daha az doğru sürüm için 38 karakter)

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

Kolon veya alt çizgi ile biten kelimeler olduğunda programın çalışmasına izin vermeye hazırsak, o zaman bunu 38 karaktere kadar basitleştirebiliriz.

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

Örnek çalışma:

    (#~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
(Doğru sürümü için) 38 Bayt: (#~[:2&|64 90 96 122&I.@(u:inv)){:&>;:ya olmayan bir açık versiyonu için 43 bayt: (#~[:2&|64 90 96 122&I.@(u:inv))@:({:@>)@;:. Bu, aralıklar kümesi olarak I.yorumlayan ve karakterin ascii kodunun argümanının ait olduğu iterval'in indeksini döndüren range index fiilini kullanır. Bu indeks tuhafsa alfabetik değil. 64 90 96 122(__, 64] (64, 90], (90, 96], (96, 122], (122, _)
Bolce Bussiere

@BolceBussiere nedense alt çizgi ile çalışmaz (son sınama durumu).
FrownyFrog

@ FrownyFrog ah, neden görüyorum, değişken isimler alt çizgi içerebildiğinden tek kelime olarak ;:yorumlanıyor abc_. +10 bayt (#~~:&'_'), muhtemelen verimsiz bir düzeltme eklemek için
Bolce Bussiere

@BolceBussiere bu '_'-.~ya da benzer bir şey.
FrownyFrog

0

Bu öyle PHP . 197 bayt :( Ben acemi

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

EDITED Şimdi 171 bayttır

<?$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
Golf için, değişken adlarınızı en az tek karaktere düşürmeniz gerekir.
Gaffi

1
düzenledi.Bunu söylediğiniz için teşekkürler. Ben burada yeniyim.
Sasori

Emin. Ayrıca, PHP’ye özgü ek yardım için buraya bakmak isteyebilirsiniz .
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;}}149 ise çalışır.
Magic Octopus Urn

\W|_rakamları içermez; yani \d/[^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"

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.