文字の繰り返しが最も多い単語


8

最近、スタックオーバーフローに関する質問がありました。OPは、文字の繰り返しが最も多い文字列内の単語を検索する関数を作成しようとしました。もちろん、数秒で1つ書くのは難しくありません。私は楽しみのために、できるだけ短い時間でJavascriptで1つ作成しました。しかし、私はコードゴルフの専門家ではないので、この単純なプログラムはどれだけ短くできるのでしょうか。


チャレンジ

一連の単語を取り込んで、最も多く繰り返される1文字の単語を返すか印刷するプログラムまたは関数を記述します。

ルール:

  • 繰り返し1文字が最も多い単語を選択します(下の例を参照)

  • 単語に繰り返し文字がない場合は、-1を返します。

  • 2つの単語の繰り返し文字の最大数が同じである場合は、文字列の先頭に近い方の単語を選択します。

  • バイトでの最短の提出が優先されます。

入力

スペースで区切られた1つ以上の単語で構成される文字列を入力として受け取ります。入力は、STDIN(または最も近い代替手段)、コマンドラインパラメーター、または関数の引数から取得できます。

出力

出力をSTDOUTに出力して返します。

文字列を考えますaaabbb cccc。これには2つの単語が含まれています:aaabbbcccc。ワードはaaabbb3持ちa'sおよび3 b' Sを、そしてcccc4有しcさん。したがって、で繰り返される文字の最大数aaabbbは3で、最大ccccは4です。単一の文字が繰り返される最大数の単語を選択するので、の出力はにaaabbb ccccなりますcccc

その他のテストケース:

Today, is the greatest day ever!  --> greatest
This is a great day               --> -1
aaabbb cccc                       --> cccc

複数の単語が同じ文字の繰り返し数を持っている場合はどうなりますか?一部または全部を印刷しますか?
Maltysen 2015

@Maltysen最初の例を見てくださいever
isaacg

@isaacg but greatには、tとeの2つの繰り返しがあります。
Maltysen 2015

2
繰り返し文字の数が何を意味するのかわかりません。私aabbは2文字が繰り返されていると思います。うaaaabb4つの繰り返される文字(第二、第三、第四有すると考えられるa、第二b)、または2つの繰り返し文字(aとがb)。
feersum

1
元の質問はCoderbyteからのものであることに注意してください。私は彼らのウェブサイトで著作権情報を探しました(これはレターカウントIの複製なので)何も見つかりませんでした。
Alex A.

回答:


7

C - GCC - 159 145 135バイト

x=0,w=0,i,j,c;main(int _,char**z){while(--_)for(j=i=0;_[z][i];j=++i,x=c>x?w=_,c:x)for(c=0;j--;)c+=z[_][i]==z[_][j];puts(x?z[w]:"-1");}

少し切り捨てられると更新されます

コンパイル方法:gcc -w cg.c

実行方法:./a.out word1 word2 aass ddaaa ssdddd

出力:ssdddd

出力なし/一致なし:-1

まず、言葉をプログラムの引数として取り込んで少し騙しましたが、GCCで言葉を解析して無料で文字数を計算してもらうのは、やりがいのある報酬でした。

どのように機能しますか?

3つのネストされたループがあります。各単語の最初の増分、次の2つは、値を比較するためにバブルソートを模倣しています。最初の文字はそれ自体と比較されることはなく、後続の各文字は以前の各文字と比較されます。単語に前の単語よりも多くの同じ文字がある場合、その単語はxに格納され、同じ文字の数も格納されます。

GCCの悪用

整数には暗黙のグローバルauto int宣言を使用します。argvをcharではなくintにすることを許可します(現在はchar、これはTODOです)。putsやgetcharなどのデフォルト関数を使用します。また、コンマ演算子を使用して、3項(条件付き)演算子をオーバーロードします。

2バイトを減らしたいですか?

「-1」を* zに置き換え、ファイルに-1という名前を付けます

難読化およびテストされていないプログラム:

int main(int argc, char * argv[])
{
    int word = 0           // Current most repeat letters word
    int count = 0;        // Current most repeat letters
    int i, j, increment; // Counter variables

    while(--argc != 0) // While we have words from program parameters
    {
        for(j = i = 0; argv[argc][i] != '\0'; j = ++i) // Iterate through each letter until end of word
        {
            for(increment = 0; j > 0; j--) // Iterative backwards through each letter
            {
                if(argv[argc][i] == argv[argc][j])
                {
                    increment++;
                }
            }
            if(increment > count) // New greatest lettered word
            {
                word = argc;
                count = increment;
            }
        }
    }

    if(word == 0)
    {
        puts("-1");
    }
    else
    {
        puts(argv[word]);
    }

    return 0;
}

1
PPCGへようこそ!素晴らしいゴルフ。時間があれば、コードがどのように機能するかを説明したいと思います。
Toby Speight 2015

OPの説明を更新
Jake

ノーGCC虐待、ちょうどいくつかの古いスタイルが、通常のC
edc65

それは記録です!おめでとう
Abr001am

4

Pyth、14バイト

eoeS/LNN+czd_1

デモンストレーション。 テストハーネス。

eoeS/LNN+czd_1
                  Implicit: z = input(), d = ' '
         czd      chop z on delimeter d.
        +   _1    Add an -1 to the end of the list.
 o                Order the list by
  eS              the maximum of
    /LN           the occurence count in the word
       N          of letters in the word.
                  (If we are mapping over -1, this will give -1/-1 = 1)
                  Since Python's sort is stable, this will leave -1 at the end if
                  all words have maximum repetition count 1.
e                 Take the final element of the resulting list and print it.

まだ機能していないようです。feersumのコメントに従って、「aaaabb」は4回の繰り返しを持つ必要があるため、「最も素晴らしい」よりも多くなります。しかし、pyth.herokuapp.com /…はそれでも最大のものを提供します。
Maltysen 2015

l前に置く.-ことはそれをするようです。
Maltysen、2015

@マルティセンそうです、私は愚かで、文字列ソートを使おうとしました。
isaacg

これは短くて美しいです。
Derek款會功夫2015

@Derek読取會功夫ありがとう!賛成投票を検討してください。
isaacg 2015

2

K、35バイト(-1の要件がありません。気づきましたが、スリープする時間です)

{1#w[>{|/{#:&:x=y}[x]'x}'w:" "\:x]}

使い方:

1テイク

1#

索引付けされた単語の

w[

昇順で配置するインデックス

>

最大

|/

どこを数える

#:&:

文字列=文字

x=y

単語の各文字について

'x

w(words)がある各単語について

'w:

スペースで区切られた文字列

\:x

明らかに、英語の説明では、表現力と読みやすさのために少し正確さを犠牲にしました。面白かったです。


1
,-1関数の最後に追加することで要件に従うことができると思います。
kirbyfan64sos

コロンは#:&:文脈からそれらをモナド形式として解析する必要があるため、コロンは省略できるはずです。@大括弧の代わりにインデックスを使用し、の代わりに最初に(*)を使用することもでき1#ます。
JohnE、2015

2

Haskell、100バイト

import Data.List
f=g.last.sort.map((,)=<<last.sort.map length.group.sort).words
g(1,_)="-1"
g(_,w)=w

使用例:f "Today, is the greatest day ever!"->"greatest"

使い方:

                                                words  -- split input at spaces into list of words
          map(                                 )       -- for each word
              (,)=<<                                   -- build a pair, where the second element is the word itself
                                                       -- and the first element is made by
                                           sort        -- sort the letters
                                      group            -- group equal letters
                            map length                 -- take length of each group
                        sort                           -- sort the lengths
                    last                               -- take the last
                                                       -- now we have a list of (l,w) pairs where l is how often the most frequent letter occurs for word w
     sort                                              -- sort the list
 last                                                  -- take last element
g                                                      -- call g which checks the "-1" case 

Haskell、79 77バイト(テストされていません)

import Data.List
last.sortOn(last.sort.map length.group.sort).words.(++" -1")

これはsortOnData.List私がインストールしていないv4.8.0.0以降を使用しているため、テストできません。


2

CJam、25バイト

lS/{_$e`$W=0=(\}%2/$W=~W?

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

説明:

lS/   Get input and split at spaces.
{     Start of loop over all words.
  _     Copy, need to keep original word.
  $     Sort letters.
  e`    RLE.
  $     Sort RLE result. Sort is increasing by count.
  W=    Get last count/letter pair, which corresponds to largest count.
  0=    Extract count from pair.
  (     Decrement count, so that it has a falsy value when the count is 1.
  \     Swap count and word, so that we can sort the pairs by count.
}%    End of loop over words.
2/    Split list into pairs, which are the count/word pairs.
$     Sort the pairs.
W=    Get last one, which is the largest count.
~     Unwrap the pair.
W?    Output word if count is truthy, -1 otherwise.

2

Python 2、97 77バイト

かなり単純なソリューションで、入力(引用符で囲まれた)を、単語と繰り返し文字の数を含むタプルにマップするだけです。最大値を取得し、最も繰り返される文字がまったく繰り返される場合は単語を出力し、そうでない場合は-1を出力します。

最大値を見つけるためのキーが不要になるように、入力の順序を並べ替えることで20(!)バイトを節約しました。

j=max((max(map(x.count,x)),x)for x in input().split())
print[-1,j[1]][j[0]>1]

1

SWI-Prolog、158 154 149バイト

a(A,R):-split_string(A," ","",B),findall(X:Z,(member(Z,B),string_codes(Z,D),length(D,L),sort(D,E),length(E,M),X is M-L,X<0),S),sort(S,[_:R|_]);R= -1.

例:a("Today, is the greatest day ever!",R).出力R = "greatest" .


1

JavaScriptが、86 111 108のバイト

s=>(l=(x=s.split` `,r=x.map(l=>(/(.)\1+/.exec(l)||[''])[0].length),x)[r.indexOf(k=Math.max(...r))],k<2?-1:l)

間違いなくゴルフが可能で、-1全体で約20バイトが追加されました。


1

R、107バイト

w=scan(,"");l=sapply(w,function(x)max(table(strsplit(x,"")[[1]])));cat(ifelse(max(l)>1,w[which.max(l)],-1))

これはSTDINから読み取り、STDOUTに出力します。

非ゴルフ+説明:

# Read a string and split it into a vector on spaces
w <- scan(, "")

# Get the maximum number of letter repeats in each element of w
l <- sapply(w, function(x) max(table(strsplit(x, "")[[1]])))

# If the largest number in l is 1, print -1, otherwise get the word
cat(ifelse(max(l) > 1, w[which.max(l)], -1)

1

C#166バイト

string a(string i){var z=i.Split(' ');int g=1,c=0;var m="-1";foreach(var w in z)foreach(var l in w.Distinct()){c=w.Where(x=>x==l).Count();if(c>g){g=c;m=w;}}return m;}

簡単なコーディング。ここでは特別なことは何もありません。

C#はコードゴルフを吸う:-/


1

JavaScript(ES7?)、99

配列内包表記を使用します。これはFirefoxに実装されていますが、EcmaScript 6には含まれていません。

以下のスニペットを使用してテストする(Firefoxのみ)

f=s=>s.split(' ').map(w=>[for(c of(l=[m=0],w))(n=l[c]=-~l[c])>m?m=n:0]&&m>x&&(x=m,v=w),x=1,v=-1)&&v

// TEST
out=x=>O.innerHTML+=x+'\n';

test=x=>out(x+' -> '+f(x))

;["aaabbb cccc","This is a great day","Today, is the greatest  day ever a!"]
.forEach(t=>test(t));
<pre id=O></pre>
Try:<input id=I><button onclick='test(I.value),I.value=""'>-></button>

非ゴルフ、そしてより互換性

function f(s)
{
  v = -1;
  x = 1;
  s.split(' ')
  .forEach(function(w){
    l=[];
    m=0;
    w.split('').forEach(function(c){
      n=l[c]=-~l[c];
      if (n>m) m=n;
    })
    if (m>x) x=m,v=w;
  })
  return v;
}

// TEST
out=function(x) { O.innerHTML+=x+'\n' }

test=function(x) { out(x+' -> '+f(x)) }

;["aaabbb cccc","This is a great day","Today, is the greatest  day ever a!"]
.forEach(function(t) { test(t)} );
<pre id=O></pre>
Try:<input id=I><button onclick='test(I.value),I.value=""'>-></button>


1

Python、58

max('-1',*input().split(),key=lambda w:len(w)-len(set(w)))

1

C(167)

double m,k,n=k=2,*O,V[256];char*f(char*c,char*s){return*c?((*O=!((n+=!(*c*=*c!=32))>1.1/modf(*(O=V+*c),&m))*m+1/n+1)>k)?f(c+!!(k=*O),c):f(c+1,s):s?!*s?s+1:f(c,s-1):0;}

それを試してみてください

これはどのように作動しますか?

  • 関数は、別の再帰関数の内部で1つの内部再帰的関数であり、insider関数は、最初の関数によって包含文字が返される文字列の先頭を取得します。
  • 最大数は、ASCIIテーブルで文字をハッシュすることによって与えられます。

1

Q(44バイト)

{w l?0|/l:{max(#:)'[(=)x]}'[w:" "vs"-1 ",x]}

ない

{
    words:" " vs "-1 ",x;
    counts:{max count each group x} each words;
    : words counts ? max counts;
}

1

Haskell 96バイト


r o=(last.sort.map length$(group.sort)o,o)
w p=n$maximum(map(r)(words p))
n (1,_)="-1"
n (_,w)=w

「」


rは、単語を取り、タプルを返す関数です。(n,w)ここnで、は、単語内で最も多く出現する文字の出現回数ですw。たとえばlet x="norep", y="dnredundant"、次にr x=(1,norep), r y=(3,ndredundant)

w スペースで区切られた多数の単語を含む文字列を取得する関数であり、

  1. リストをスペースで分割する words p

  2. foreach単語のリストを作成する (n,w)

  3. 最大のタプルn(オカレンスカウンター)を取得します

  4. nが1に等しい場合は、単に文字列を返し、-1それ以外の場合は(タプルの2番目のコンポーネントに格納されている)単語自体を返します。

例えば取る p="Today, is the greatest day ever!"

  1. 作り出す ["Today,","is","the","greatest","day","ever!"]

  2. [(1,"Today,"),(1,"is"),(1,"the"),(2,"greatest"),(1,"day"),(2,"ever!")]

  3. (2、 "最大")

  4. 2!= 1 greatestが解決策です!


1

Pure Bash(外部コマンドなし)129バイト

これはかなり長いですが、それでも他の長いエントリのいくつかと比較して有利です。

m=1
w=-1
for b;{
declare -A a
for((i=0;i<${#b};i++));{
c=${b:$i:1}
let a[$c]++
d=${a[$c]}
((d>m))&&w=$b&&m=$d
}
unset a
}
echo $w

一部の構成要素に完全に満足しているわけではありません。その内部forループを使用する必要があるのは面倒です。助言がありますか?

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