Özyinelemeli kısaltmalar


31

Amaç

Gönderen Vikipedi :

Özyinelemeli bir kısaltma, içinde durduğu ifadede kendisini ifade eden bir kısaltmadır.

Amacınız bir dize özyinelemeli bir kısaltma olup olmadığını kontrol etmektir.

  • Kısaltma ilk kelimedir.
  • Sözcükler büyük / küçük harfe duyarlı değildir, tek bir boşlukla ayrılmışlardır.
  • Verilen dize noktalama işareti ve kesme işareti içermez.
  • Her kelimenin yalnızca ilk harfi kısaltmanın bir parçası olabilir.

Ayrıca fonksiyon kelimelerini de vermelisiniz . Basit olması için, her kelime bir fonksiyon kelimesi olarak düşünülebilir.

Örnek

f("RPM Package Manager")         =>     { true, [] }
f("Wine is not an emulator")     =>     { true, ["an"] }
f("GNU is not Unix")             =>     { true, ["is"] }
f("Golf is not an acronym")      =>     { false }  
f("X is a valid acronym")        =>     { true, ["is","a","valid","acronym"] }  

Tam bir program veya bir işlev verebilirsiniz.
Giriş dizesi STDIN'den veya bir işlev argümanı olarak alınabilir.
Çıktı sonucu doğru olabilir / yanlış, 0/1, evet / hayır ...
İşlev kelimeleri listesi (listenin herhangi bir biçimi geçerliyse) ve eğer bu yinelemeli bir kısaltma ise (liste boş olsa bile ) verilmelidir. . İşlev kelimelerinin büyük harflerini korumanız gerekmez.

Kazanan kriterler

Bu bir , en kısa kod kazanır.


4
Fonksiyon kelimelerinin büyük harflerini korumak zorunda mıyız?
algorithmshark

1
Yanlış bir değere eşlik eden bir dizi listenin olması kabul edilebilir mi, yoksa hayır mı?
undergroundmonorail

1
Sözcük listesinin kendisi, boole değerini varlığına göre kodladığından, boole değerini atabilir miyiz?
John Dvorak

5
Hurd, Unix-Replasman Daemon'ların Hird'ini temsil ediyor. Hird, Derinlik Temsil Eden Arayüzlerin Hurd'unu temsil ediyor. Neden buradaki örnekler bunu anlamıyor ve bunların özyinelemeli kısaltmalar olmadığını iddia ediyor?
Konrad Borowski

3
@xfix, wikipedia, bunların karşılıklı olarak özyinelemeli kısaltmalar olduğunu belirtir .
Michael M.

Yanıtlar:


7

GolfScript, 51 50 karakter

{32|}%" "/(1>\{.1<2$1<={;1>}{\}if}/{]!}{]`1" "@}if

Muhtemelen daha fazla golf oynayabilir. STDIN'de girişi ele alır. Boolean 0 / 1'dir.

Çevrimiçi test


Açıklama:

{32|}%      # change everything to lower-case
" "/        # splits the string by spaces
(1>         # takes the first word out and removes the first letter
\           # moves the list of remaining words in front of the acronym word
{           # for every word:
  .1<2$1<=    # compares the first letter of the word with
              # the next unmatched letter of the acronym
  {;1>}       # if they are the same, discard the word and the now-matched letter
  {\}         # otherwise store the word in the stack
  if          # NB. if all letters have been matched, the comparison comes out as false
}/
{]!}        # if there are still unmatched letters, return 0 (`!` non-empty list)
{]`1" "@}   # otherwise, return 1, and display the list of function words
if

22

Regex, .NET lezzet, 62 bayt

(?i)(?<=^\w(?<c>\w)*)( \k<c>(?<-c>)\w+| (?<w>\w+))*$(?(c)(?!))

Burada test edebilirsiniz . Girdi özyinelemeli bir kısaltma ise, bu bir eşleşme wsağlayacaktır ve yakalama grubu tüm işlev sözcüklerini içerecektir. Eğer değilse, o zaman eşleşme olmaz.

Bu does fonksiyon kelimelerin harfleri koruma (ama küçük harf duyarsız maçları).

Ne yazık ki, test adlandırılmış yakalama grubun tüm yapı göstermez, ancak .NET yerde kullanıldığı takdirde, wgrup olur sırayla tüm işlev sözcükleri içerir.

İşte bunu ispatlamak için bir C # pasajı:

var pattern = @"(?i)(?<=^\w(?<c>\w)*)( \k<c>(?<-c>)\w+| (?<w>\w+))*$(?(c)(?!))";
var input = new string[] {
    "RPM Package Manager",
    "Wine is not an emulator",
    "GNU is not Unix",
    "Golf is not an acronym",
    "X is a valid acronym"
};

var r = new Regex(pattern);
foreach (var str in input)
{
    var m = r.Match(str);
    Console.WriteLine(m.Success);
    for (int i = 0; i < m.Groups["w"].Captures.Count; ++i)
        Console.WriteLine(m.Groups["w"].Captures[i].Value);
}

İşte hızlı bir açıklama. Bu kod parçasını kullanarak , adlandırılmış gruptaki kısaltma harflerinin bir yığınını oluşturmak için .NET'in dengeleme gruplarını kullanıyorumc

^\w(?<c>\w)*

İşin püf noktası, yığının en üstündeki ikinci mektuba ve en alttaki son mektuba ihtiyacım var. Ben de bütün bunları kısaltmadan sonraki pozisyona uygun bir gözle yerleştirdim . Bu yardımcı olur, çünkü .NET, sağdan sola doğru görünenlerle eşleşir, bu nedenle ilk önce son harfle karşılaşır.

Bir kez o yığını aldığımda, kelime için dize kelimesinin geri kalanıyla eşleşiyorum. Her iki kelime de kısaltma yığınının üstündeki harfle başlar. Bu durumda o mektubu yığından açtım:

 \k<c>(?<-c>)\w+

Aksi takdirde, yine de kelimeyi eşleştiririm ve wsonra tüm fonksiyon kelimelerini içerecek olan yığına basarım:

 (?<w>\w+)

Sonunda, dizenin sonuna ulaştığımdan $ve ayrıca kısaltmadan gelen tüm harfleri yığının boş olup olmadığını kontrol ederek kullandığımdan emin olun:

(?(c)(?!))

İdeone üzerinde test edin.


1
Büyük düzenli ifade, ancak soru açıkça " Tam bir program veya bir işlev verebilir" ifadesini veriyor .
Diş Fırçası

4
@toothbrush OP buna göre cevabımı diskalifiye etmeye karar verirse, öyle olsun. Ancak bunun, .NET'in düzenli ifade tadı olan (Turing'in tam bir dili değil ve çalışması biraz zahmetli, ancak yine de bir dil olan) dilindeki tam bir program olduğuna dikkat çekebileceğimi düşünüyorum. Her durumda, onu saf-regex yaklaşımıyla çözdüğüm gerçeğini seviyorum ve bu "şıklığı" (eğer yapacaksan) "sadece regex kullanarak" bir C # cevabı yaparak yok etmekten çok diskalifiye edilmiş bir cevabı istiyorum. ".
Martin Ender

Bu benimle iyi. Sadece kaçırdığın halde işaret etmek istemiştim.
Diş Fırçası

1
Bunu sevdim. Regexes Turing-complete bir programlama dili olmayabilir, ancak bunun sayılması gerektiğini düşünüyorum.
Paul Draper

@PaulDraper Aslında, .NET'in regex lezzetinin tam olmadığından bahse girmem bile ... dengeleme grupları ve sağdan sola eşleşen gözbebekleri oldukça güçlü. Örneğin PCRE'nin Turing'in tamamlandığı biliniyor (ki bunun özyinelemesi var, .NET'teki yığınların keyfi yinelemeyi taklit etmek için yeterli olduğundan emin değilim).
Martin Ender

11

Python (158, regex olmadan)

Regexlerden hoşlanmadığımdan değil. Onları tanımıyorum.

def f(x):
 s=x.lower().split();w=list(s[0][1:]);s=s[1:];o=[]
 if not w:return 1,s
 [w.pop(0)if i[0]==w[0]else o.append(i)for i in s]
 return(0,)if w else(1,o)

Oh, ayrıca bir de unungolfed versiyonum vardı:

def acronym(string):
    scentence = string.lower().split()
    word = scentence[0][1:]
    scentence = scentence[1:]
    over = []
    if not word: return 1, scentence
    for item in scentence:
        if item[0] == word[0]:
            word = word[1:]
        else:
            over.append(item)
    if word:
        return 0,
    return 1,over

5

Python 2.7 - 131 126 bayt

def f(s):
 s=s.lower().split();a,f=list(s[0]),[]
 for w in s:f+=0*a.pop(0)if a and w[0]==a[0]else[w]
 return(0,)if a else(1,f)

Kısaltmanın ilk kelimesinde harflerin listesini yapar. Ardından, tam dizedeki her kelime için, o kelimenin ilk harfiyle aynıysa, yaptığımız listenin ilk elemanından kurtulun. Aksi takdirde, bu kelimeyi işlev kelimelerinin listesine ekleyin. Çıkmak için, geri dönün not a(python'da, boş listeden başka bir liste True-y'dir ve özyinelemeli bir kısaltma ise liste boştur) ve eğer varsa not a.

Bir hatayı düzeltmek / bazı baytları kurtarmak için bana yardımcı olduğu için @ ace.


Python 2.7.3'te hattın SyntaxError: invalid syntaxsonuna ulaşıyorum return.
pastebin.com 0mr8spkT dilekçesini salı

@ace Huh, test ettiğimde çalıştığına yemin edebilirdim. Bir şey değiştirmiş olmalı ve tekrar test etmeyi unutmuş olmalıyım. Bir düzeltme üzerinde çalışacağım!
undergroundmonorail

Daha for w in s:f+=0*a.pop(0)if a and w[0]==a[0]else[w]kısa olan ve sekmelere dayanmayan kullanabilirsiniz . Açıklamaya gelince return, 0if a else(1,f)hangisinin orijinalinden daha kısa olduğunu buldum .
pastebin.com 0mr8spkT dilekçesini sundu

Oh ve ilk iki ifadeyi aynı satıra koymak için noktalı virgül kullanıyorsanız, bir baytlık girintiden tasarruf edersiniz.
pastebin.com 0mr8spkT dilekçesini salı

1
Hatayı düzeltmenin bir yolunu buldum ama buraya postalamak için geri döndüğümde yorumlarda daha fazla golf oynadın: P
undergroundmonorail

3

Python - 154 karakter

İlk önce golf girişimini kodlayın. Tüm uzun anahtar kelimeler göz önüne alındığında, pitonun bunun için en iyi dil olmadığını düşünüyorum. Ayrıca, bu fonksiyonun kusursuz olduğunu düşünmüyorum. OP'nin girişi için işe yarar, ancak istisnalar hakkında düşünebileceğimden eminim.

def f(s):
    w=s.lower().split();r=list(w[0]);return(True,[x for x in w if x[0]not in r])if len(r)==1 or[x for x in[y[0]for y in w]if x in r]==r else False

156 karakter (yeni satır ve sekme karakterinin her ikisi de sayılır) sayırım, ancak ikisi de gerekmediğinden bu iki karakteri kaldırarak yasal olarak 154 değerine ulaşabilirsin. PPCG'ye hoş geldiniz, btw. :)
undergroundmonorail

3

ECMAScript 6 (105 bayt):

f=s=>(r=(a=s.toUpperCase(i=1).split(' ')).map((w,c)=>c?a[0][i]==w[0]?(i++,''):w:''),a[0].length==i?1+r:0)

Fonksiyonu Firefox'un tarayıcı konsoluna girin ve ardından sadece şu şekilde fonksiyonu çağırın:

f('ABC Black Cats')     // 1,,
f('ABC is Black Cats')  // 1,IS,,
f('ABC Clapping Cats')  // 0

Oldukça kurallara uymayan: The function words list ... must be given if and only if this is a recursive acronym. Bu ne olursa olsun onları uyaracaktır.
MT0

@ MT0 Tamam. Bu gereksinimi fark etmedim. Bakalım yeniden yazabilir miyim?
Diş fırçası

@ MT0 Kodu şimdi güncelledim.
Diş Fırçası

2

Haskell - 287 bayt

En kısa giriş değil (hey bu Haskell, ne bekliyordun?), Ama yine de yazmak çok eğlenceli.

import Data.Char
import Data.List
f""w=map((,)False)w
f _[]=[]
f(a:as)(cs@(c:_):w) 
 |toLower a==toLower c=(True,cs):f as w
 |True=(False,cs):f(a:as)w
g s=if(length$filter(fst)d)==length v
  then Just$map(snd)$snd$partition(fst)d 
  else Nothing
 where 
  w=words s
  v=head w
  d=f v w

İle test edildi

map (g) ["RPM Package Manager","Wine is not an emulator","GNU is not Unix","Golf is not an acronym","X is a valid acronym"]

Beklenen çıktı

[Just [],Just ["an"],Just ["is"],Nothing,Just ["is","a","valid","acronym"]]

Ungolfed

import Data.Char
import Data.List

f :: String -> [String] -> [(Bool, String)]
f "" w = map ((,) False) w
f _ [] = []
f (a:as) ((c:cs):w) | toLower a == toLower c = (True, c:cs) : f as w
                    | otherwise = (False, c:cs) : f (a:as) w

g :: String -> Maybe [String]
g s = if (length $ filter (fst) d) == (length v)
          then Just $ map (snd) $ snd $ partition (fst) d 
          else Nothing
  where w = words s
        v = head w
        d = f v w

2

JavaScript (ECMAScript 6) - 97 Karakterler

f=x=>(r=(a=x.toLowerCase(i=0).split(' ')).filter(y=>y[0]!=a[0][i]||i-i++),i==a[0].length?[1,r]:0)

Testler:

f("RPM Package Manager")
[1, []]

f("GNU is not Unix")
[1, ["is"]]

f("X is an acronym")
[1, ["is", "an", "acronym"]]

f("Golf is not an acronym")
0

f("Wine is not an emulator")
[1, ["an"]]

1

Rebol - 133

f: func[s][w: next take s: split s" "y: collect[foreach n s[either n/1 = w/1[take w][keep n]]]reduce either/only w: empty? w[w y][w]]

Ungolfed:

f: func [s] [
    w: next take s: split s " "
    y: collect [
        foreach n s [
            either n/1 = w/1 [take w][keep n]
        ]
    ]
    reduce either/only w: empty? w [w y][w]
]

Şununla test edildi:

foreach t [
    "RPM Package Manager"  "Wine is not an emulator"  
    "GNU is not Unix"      "Golf is not an acronym"  
    "X is a valid acronym"
][probe f t]

Çıktı:

[true []]
[true ["an"]]
[true ["is"]]
[false]
[true ["is" "a" "valid" "acronym"]]

1

Julia - 116 bayt

f(w)=(a=split(lowercase(w));L=1;A=a[];while a!=[];a[][1]==A[1]?A=A[2:]:(L=[L,a[]]);a=a[2:];A>""||return [L,a];end;0)

Daha Az Golf:

f(w)=(
 a=split(lowercase(w))
 L=1
 A=a[]
 while a!=[]
  if a[][1]==A[1]
   A=A[2:]
  else
   L=[L,a[]]
  end
  a=a[2:]
  if !(A>"")
   return [L,a]
  end
 end
0)

0Ucunda bir dizi içeren verir Aksi takdirde, 0 değerini çıkış yapan 1fonksiyon kelime takip eder. Örneğin:

julia> f("RPM Package Manager")
1-element Array{Any,1}:
 1

julia> f("Golf is not an acronym")
0

julia> f("GNU is not Unix")
2-element Array{Any,1}:
 1    
  "is"

julia> f("X is a valid acronym")
5-element Array{Any,1}:
 1         
  "is"     
  "a"      
  "valid"  
  "acronym"

1

Brachylog , 29 bayt

ḷṇ₁XhY∧X;0zpᵐz{ċ₂ˢ}ᵐZhhᵐcY∧Zt

Çevrimiçi deneyin!

Girdi özyinelemeli bir kısaltma ise işlev sözcüklerini çıktı değişkeni üzerinden çıktılar, değilse başarısız olur.

   X                             X is
ḷ                                the input lowercased
 ṇ₁                              and split on spaces,
    hY                           the first element of which is Y
      ∧                          (which is not X).
       X  z                      X zipped
        ;0                       with zero,
           pᵐ                    with all pairs permuted (creating a choicepoint),
             z                   zipped back,
              {   }ᵐ             and with both resulting lists
               ċ₂ˢ               losing all non-string elements,
                    Z            is Z.
                      hᵐ         The first elements of the elements of
                    Zh           the first element of Z
                        cY       concatenated are Y
                          ∧      (which is not Z).
                           Zt    The last element of Z is the output.

İşlev kelimelerinin çıktısını almak zorunda kalmadan (buna saf bir olarak bakılıyor ), sadece 12 byte ∧Ztçıkabiliyor , çünkü -3'e bırakılabiliyor, -1 Yile değiştirilebiliyor .ve en önemlisi ;0zpᵐz{ċ₂ˢ}ᵐZhile değiştirilebiliyor : bir kuyruklu -13:ḷṇ₁Xh.∧X⊇hᵐc


0

Kobra - 187

def f(s as String)
    l=List<of String>(s.split)
    a=l[0]
    l.reverse
    o=0
    for c in a,for w in l.reversed
        if c==w[0]
            l.pop
            o+=1
            break
    x=o==a.length
    print x,if(x,l,'')

0

Yakut - 173

Daha iyi olabilir...

 f=->s{a=[];o={};s=s.split;r=true;s[0].each_char{|c|s.each{|w| w[0]=~/#{c}/i?(o[c]=1;a<<w if o[c]):(o[c]=0 if !o[c])}};r,a=false,s if o.values&[0]==[0];!r ?[r]:[r,(s-(a&a))]}

Fonksiyonu çağırmak:

p f.call('RPM Package Manager')
p f.call('Wine is not an emulator')
p f.call("GNU is not Unix")
p f.call("Golf is not an acronym")
p f.call("X is a valid acronym")

Çıktı :

[true, []]
[true, ["an"]]
[true, ["is"]]
[false]
[true, ["is", "a", "valid", "acronym"]]

0

Java - 195

Maalesef, Java yerleşik destek içermiyor.

Yani, bu boole 'b' de ve 'x' de fonksiyon kelimesi listesini saklayan bir sınıftır.

Burada, fonksiyon sınıfın kurucusudur.

static class R{boolean b;String[]x;R(String s){String v=" ",i="(?i)",f=s.split(v)[0],r=i+f.replaceAll("(?<=.)",".* ");if(b=(s+=v).matches(r))x=(s.replaceAll(i+"\\b["+f+"]\\S* ","")+v).split(v);}}

Ölçek

public class RecursiveAcronyms {
public static void main(String args[]) {
    String[] tests = {
            "RPM Package Manager",
            "Wine is not an emulator",
            "GNU is not Unix",
            "Golf is not an acronym",
            "X is a valid acronym"
        };
    for (String test:tests) {
        R r = new R(test);
        System.out.print(r.b);
        if (r.b) for (String s:r.x) System.out.print(" "+s);
        System.out.print("\n");
    }
}
static class R{boolean b;String[]x;R(String s){String v=" ",i="(?i)",f=s.split(v)[0],r=i+f.replaceAll("(?<=.)",".* ");if(b=(s+=v).matches(r))x=(s.replaceAll(i+"\\b["+f+"]\\S* ","")+v).split(v);}}}

C # 'nin tüperleri var, ama çözümüm üzerinde çalışırken bununla karşılaştım: sadece geri dönün string[]: nullsadece yanlış, boş anlamına gelir, nelemanlar ise nfonksiyon sözcükleriyle gerçek olur .
Num Lock

Bunu da yapmak isterim. Bununla birlikte OP, booleanın ne olursa olsun sağlanması gerektiğini belirtir. Jan Dvorak'ın yorumuna verilen cevaba bakınız.
Vectorized

Orijinal yayında sonuçlandırılmış bir düzenleme göremediğim için yorumları umursamıyorum. Ve yapsam bile , açıkça açıkça " booleanı belirtmek " diyor . Ve cevabın kendisinde bile " Çıktı sonucu doğru / yanlış, 0/1, evet / hayır ... +" olabilir, ki bu, elipslerde "* null / null değil" ile genişletebilirim ...
Num Kilitleme

0

Awk - 145

awk -v RS=' ' '{c=tolower($0)};NR==1{w=c};{t=substr(c,1,1)!=substr(w,NR-s,1);if(t){f=f" "c;s++};a=a||t};END{print a&&(s>NR-length(w))?"N":"Y|"f}'

Ölçek:

$ cat gcp.sh
#!/bin/sh
f() {
echo "$1:"
echo "$1"|awk -v RS=' ' '{c=tolower($0)};NR==1{w=c};{t=substr(c,1,1)!=substr(w,NR-s,1);if(t){f=f" "c;s++};a=a||t};END{print a&&(s>NR-length(w))?"N":"Y|"f}'
}
f "RPM Package Manager"
f "Wine is not an emulator"
f "Wine is not an appropriate emulator"
f "GNU is not Unix"
f "Golf is not an acronym"
f "Go is not an acronym"
f "Go is a valid acronym OK"
f "X is a valid acronym"
f "YAML Ain't Markup Language"

$ ./gcp.sh
RPM Package Manager:
Y|
Wine is not an emulator:
Y| an
Wine is not an appropriate emulator:
Y| an appropriate
GNU is not Unix:
Y| is
Golf is not an acronym:
N
Go is not an acronym:
N
Go is a valid acronym OK:
Y| is a valid acronym
X is a valid acronym:
Y| is a valid acronym

YAML Ain't Markup Language:
Y|

0

Kahve yazısı - 144

z=(a)->g=" ";b=a.split g;c=b[0];d=[];(d.push(e);g++)for e,f in b when e[0].toLowerCase()!=c[f-g].toLowerCase();if(g+c.length==f)then{1,d}else{0}

Örneğin, ile arayın: z "GNU is not Unix"

Derlenmiş JS:

var z;
z = function(a) {
  var b, c, d, e, f, g, _i, _len;
  g = " ";
  b = a.split(g);
  c = b[0];
  d = [];
  for (f = _i = 0, _len = b.length; _i < _len; f = ++_i) {
    e = b[f];
    if (e[0].toLowerCase() !== c[f - g].toLowerCase()) {
      d.push(e);
      g++;
    }
  }
  if (g + c.length === f) {
    return {
      1: 1,
      d: d
    };
  } else {
    return {
      0: 0
    };
  }
};

Dizeyi sözcüklere böler ve sonra her bir kelime boyunca döner. Sözcüğün ilk karakteri kısaltmadaki ile aynı değilse, sözcük saklanır. Bir sayacın ( g) kaç sözcüğün atlandığını izlemek için kullanılır. Atlanan kelimelerin sayısı ve kısaltmanın uzunluğu, ifadenin uzunluğuyla eşleşirse eşleşir, bu nedenle 1 ve atlanan kelimeleri döndür. Değilse geçerli değildi, bu yüzden 0 değerini döndürün.


0

C # - 234

Tuple<bool,string[]> f(string w) {var l=w.ToLower().Split(' ');var o=new List<string>();int n=0;var a=l[0];foreach(var t in l){if(n>=a.Length||a[n]!=t[0])o.Add(t);else n++;}var r=n>=a.Length;return Tuple.Create(r,r?o.ToArray():null);}

0

Python (108)

l=raw_input().lower().split()
a=l[0]
e=[]
for w in l:d=w[0]!=a[0];a=a[1-d:];e+=[w]*d  
b=a==''
print b,b*`e`
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.