再帰的な頭字語


31

目的

ウィキペディアから:

再帰的な頭字語は、それが意味する表現で自分自身を指す頭字語です。

あなたの目標は、文字列が再帰的な頭字語であるかどうかを確認することです。

  • 頭字語は最初の言葉です
  • 単語は大文字と小文字を区別せず、単一のスペースで区切られます。
  • 指定された文字列には、句読点やアポストロフィが含まれていません。
  • 各単語の最初の文字のみが頭字語の一部になります。

関数の単語も指定する必要があります。簡単にするために、すべての単語を機能単語と見なすことができます。

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

完全なプログラムまたは機能を提供できます。
入力文字列は、STDINから、または関数の引数として取得できます。
出力結果はtrue / false、0/1、yes / noの
いずれかです。関数ワードリスト(リストの任意の形式が有効)は、これが再帰頭字語である場合にのみ(リストが空であっても)指定する必要があります。機能語の大文字を保持する必要はありません。

受賞基準

これは、最短のコードが勝ちます。


4
機能語の大文字化を維持する必要がありますか?
algorithmshark

1
False値を伴う文字列のリストを持つことは容認されますか、それともnoですか?
地下

1
単語リスト自体は、その存在によってブール値をエンコードするため、ブール値を省略できますか?
ジョンドヴォルザーク

5
Hurdは、Hird of Unix-Replaceing Daemonsの略です。Hirdは、Hurd of Interfaces Representing Depthの略です。ここの例がそれを理解せず、それらが再帰的な頭字語ではないと主張するのはなぜですか?
コンラッドボロスキー

3
@xfix、ウィキペディアはそれらが相互に再帰的な頭字語であると述べています。
マイケルM.

回答:


7

GolfScript、51 50文字

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

それはおそらくさらにゴルフすることができます。STDINで入力を受け取ります。ブール値は0/1です。

オンラインでテストする


説明:

{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

正規表現、.NETフレーバー、62バイト

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

ここでテストできます。入力が再帰的な頭字語の場合、これにより一致が生成wされ、キャプチャグループにはすべての機能語が含まれます。一致しない場合、一致するものはありません。

これにより、関数ワードの大文字化維持されます(ただし、大文字と小文字は区別されません)。

残念ながら、テスターは名前付きキャプチャグループのスタック全体を表示しませんが、.NETのどこかで使用した場合、wグループはすべての機能語が順番に含まれます。

これを証明するC#スニペットを次に示します。

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

ここに簡単な説明があります。このスニペットを使用して、.NETのバランスグループを使用して、名前付きグループの頭字語のスタックを構築していますc

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

秘trickは、スタックの上に2番目の文字が必要で、最後に1文字が必要なことです。そのため、このすべてを、頭字語のの位置一致する読みに入れました。.NETは後読みを右から左に一致させるため、最後の文字が最初に検出されるため、これが役立ちます。

そのスタックを取得したら、残りの文字列を単語ごとに一致させます。いずれかの単語は、頭字語スタックの上の文字で始まります。その場合、スタックからその文字をポップします:

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

それ以外の場合は、とにかく単語を照合し、wスタックにプッシュします。スタックにはすべての機能単語が含まれます。

 (?<w>\w+)

最後に、文字列の末尾に到達したことを$確認し、スタックが空であることを確認して、頭字語のすべての文字を使い果たしたことを確認します。

(?(c)(?!))

ideoneでテストします。


1
すばらしい正規表現ですが、質問には明確に「完全なプログラムまたは関数を指定できます」と記載されています。
歯ブラシ

4
@toothbrush OPがそれに基づいて私の回答を失格と決定した場合、それである。しかし、これは.NETの正規表現フレーバーである言語の完全なプログラム(チューリングの完全な言語ではなく、実行するのが少し面倒ですが、それでも言語)であると指摘できると思います。いずれにせよ、私は純粋な正規表現のアプローチで解決したという事実が好きであり、「正規表現を使用したC#回答」にすることでその「優雅さ」を破壊するよりも失格にしたい「。
マーティンエンダー

大丈夫です。あなたがそれを見逃した場合に備えて、私はそれを指摘したかったです。
歯ブラシ

1
私はそれが好きです。正規表現はチューリング完全なプログラミング言語ではないかもしれませんが、これは重要だと思います。
ポールドレーパー

@PaulDraper実際、.NETの正規表現フレーバーがチューリング完全でないことに賭けさえしません。バランスグループと右から左に一致する後読みは非常に強力です。また、たとえば、PCREはチューリング完全であることが知られています(再帰があること、.NETのスタックが任意の反復をエミュレートするのに十分かどうかわかりません)。
マーティンエンダー

11

Python(158、正規表現なし)

正規表現が嫌いというわけではありません。私はそれらを知らないということです。

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)

ああ、私はまた、無料版も持っていました。

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バイト

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)

頭字語の最初の単語の文字のリストを作成します。次に、完全な文字列の各単語について、その単語の最初の文字と同じ場合は、作成したリストの最初の要素を取り除きます。それ以外の場合は、その単語を機能単語のリストに追加します。出力するには、not a(Pythonでは、空のリスト以外のリストはTrue-yで、再帰的な頭字語の場合はリストは空です)を返しnot aます。

エラーの修正/いくつかのバイトの保存を支援してくれた@aceに感謝します。


Python 2.7.3ではSyntaxError: invalid syntax、最後になりreturnます。
user12205

@aceフー、テストしたときにうまくいくと誓ったかもしれない。何かを変更して、もう一度テストするのを忘れたに違いありません。修正に取り組みます!
地下

for w in s:f+=0*a.pop(0)if a and w[0]==a[0]else[w]短く、タブに依存しないものを使用できます。return声明、私が見つかりました。0if a else(1,f)あなたのオリジナルよりも短くなっています。
user12205

ああ、セミコロンを使用して最初の2つのステートメントを同じ行に配置すると、1バイトのインデントが保存されます。
user12205

1
エラーを修正する方法を見つけましたが、私がここに戻って投稿したとき、あなたはコメントでそれをさらにゴルフダウンしていました:P
undergroundmonorail

3

Python-154文字

初めてのゴルフの試み。すべての長いキーワードを考えると、PythonはPythonに最適な言語ではないと考えています。また、この関数は絶対に安全だとは思いません。OPの入力に対しては機能しますが、例外を考えることができると確信しています。

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文字をカウントします(改行文字とタブ文字の両方がカウントされます)が、実際にはどちらも必要ないので、これらの2文字を削除することで合法的に154まで減らすことができます。PPCGへようこそ、ところで。:)
地下

3

ECMAScript 6(105バイト):

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)

Firefoxのブラウザコンソールで関数を入力し、次のように関数を呼び出します。

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

ルールに完全には準拠していません:The function words list ... must be given if and only if this is a recursive acronym。これは、それらに関係なく警告します。
MT0

@ MT0 OK。その要件に気付かなかった。書き直せるかどうか確認します。
歯ブラシ

@ MT0コードを更新しました。
歯ブラシ

2

Haskell-287バイト

最短のエントリではありません(これはHaskellです、あなたは何を期待していましたか?)、しかしまだ書くのはとても楽しいです。

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

でテスト済み

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

期待される出力

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

非ゴルフ

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文字

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)

テスト:

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

レボル-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]]

ゴルフをしていない:

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]
]

テスト済み:

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]

出力:

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

1

ジュリア-116バイト

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)

少ないゴルフ:

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)

0端部には、アレイを含有する出力し、それ以外の場合は0を、それが出力させる1機能語が続きます。例えば:

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バイト

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

オンラインでお試しください!

入力が再帰的な頭字語である場合、出力変数を介して関数ワードを出力し、そうでない場合は失敗します。

   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.

機能語は、(純粋としてこれを処理し、出力することなく、)、それがあるため、わずか12バイトに出てくる∧Zt-3のために落下させることができる、Yと交換することができる.-1のために、そして最も重要;0zpᵐz{ċ₂ˢ}ᵐZhと交換することができるためなんと-13:ḷṇ₁Xh.∧X⊇hᵐc


0

コブラ-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

ルビー-173

もっとよくなるはず...

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

funcを呼び出す:

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

出力:

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

0

Java-195

残念ながら、Javaにはタプルサポートが組み込まれていません。

したがって、これはブール値を「b」に、関数の単語リストを「x」に格納するクラスです。

ここで、関数はクラスのコンストラクターです。

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

テスト

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#にはタプルがありますが、ソリューションの作業中にこれを思いつきました。 string[]null単に真偽、空の手段を意味しn、真の要素手段n機能語。
Num Lock

私もそれをやりたいです。ただし、OPでは、ブール値を指定する必要があります。Jan Dvorakのコメントへの返信を参照してください。
2014年

元の投稿で結果の編集を見つけることができないように見えるので、コメントは気にしません。そして、私がやったとしても、それは明らかに「ブール値を指定する」と言うだけです。そして、でも答え自体にそれが言う「出力結果が真/偽のすることができ、0/1、はい/いいえ... +」私は「*ヌル/ NOT NULLで省略記号で拡張可能性がある」...
テンキー

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

テスト:

$ 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

コーヒースクリプト-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}

たとえば、次のように呼び出します。 z "GNU is not Unix"

コンパイルされた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
    };
  }
};

文字列を単語に分割し、各単語をループします。単語の最初の文字が頭字語の次の文字と一致しない場合、単語は保存されます。カウンター(g)は、スキップされた単語数を追跡するために使用されます。スキップされた単語の数に頭字語の長さを加えたものがフレーズの長さと一致する場合、一致したため、1とスキップされた単語を返します。そうでない場合、有効ではなかったため、0を返します。


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

パイソン(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`
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.