すべての文字列を出力する


34

一連の文字を指定すると、それらの文字で構成されたすべての文字列が出力されます。(これはセットのKleeneスターです。)たとえば、の{'a','b'}場合、文字列は次のとおりです。

'', 'a', 'b', 'aa', 'ab', 'ba', 'bb', 'aaa', 'aab', ...

入力:明確な文字の空でないコレクションa..z。これらは、文字または単一文字の文字列です。

出力:それらの文字のすべての文字列、任意の順序、繰り返しなし。文字のリストを文字列として使用できます。

これは無限のリストなので、次の方法で出力できます。

  • ますます多くの文字列を書いて永遠に実行します。これらの文字列は、フラットに区切られた任意の形式で記述できます。つまり、各文字列がどこで終了するかはわかりますが、文字列はグループに分割されません。
  • n入力として数値を取り、n任意のフラットな分離形式で最初の文字列を出力します
  • ジェネレーターオブジェクトから各文字列を順番に取得する
  • 無限のオブジェクトを生成する

一部の文字列に到達することなくセットから無限に多くの文字列を生成することが可能であるため、メソッドが最終的に出力内のすべての文字列を生成することを確認してください。

あなたはそれを出力することはできません

  • n与えられたth文字列の生成n
  • 特定の文字列がセットに属するかどうかを決定するメンバーシップオラクルを提供する

ビルトインは許可されていますが、ほとんどビルトインに依存しているものよりも、操作自体を実装する回答に注意を払うよう投票者にお願いします。


@Cyoceどういう意味かわかりません。文字列を分離する必要があることを明確にしたので、空の文字列に何もないことを通知できます。
xnor

「N番目の文字列の生成」が許可されない理由を説明してください。
CalculatorFeline

4
@CatsAreFluffyそれは判断の電話でした。特に、一部の言語には任意のベース変換が組み込まれているため、N番目の文字列を生成することは、他の方法に比べて簡単すぎ、チャレンジを面白くしなくなると思います。また、クエリではなく、無限のセットを生成するというアイデアを捉えたとは思いませんでした。
xnor

「無限の物体を作り出す」ことを説明できますか?それは、たとえば、プログラムが終了しないために出力が生成されない場合でも、各文字列をスタックにプッシュして(スタック言語の場合)、「永久に」実行できることを意味しますか?
ルイスメンドー

@DonMuesliスタックへの出力は、そのような言語で受け入れられている出力方法ですか?そして、スタックにはいつでもこれらの文字列のみが含まれますか?
-xnor

回答:


26

Python 2、53 56

-3 yield xは、式として使用できることを認識した後。

def f(s):yield'';[(yield w+c)for w in f(s)for c in s]

1バイト短くなります'aa'が、'':ではなくで始まりますS=lambda s:(c+w for f in[str,S]for w in f(s)for c in s)。空の入力に対しても機能しません。
orlp

20

Haskell、24バイト

f s=[]:[b:a|a<-f s,b<-s]

無限リストを作成します。

*Main> f "abc"
["","a","b","c","aa","ba","ca","ab","bb","cb","ac","bc","cc","aaa","baa","caa","aba","bba","cba",…

あまりにも悪い(:)<$>s<*>f sと間違った順序を与えるでしょう。ありますf s="":(flip(:)<$>f s<*>s)が、もっと長くなります。
xnor

うん。私は23バイトf s=[]:(f s<**>map(:)s)を見つけましたが、それ<**>はにありませんPrelude
アンデルスカセオルグ16年

11

JavaScript(ES6)、61バイト

function*g(s){yield'';for(let r of g(s))for(c of s)yield c+r}

@feersumのPythonジェネレーターのポート。let必要です。配列内包表記を使用して2バイトを節約します(ES7の提案に失敗しましたが、Firefox 30-57で機能します)。

function*g(s){yield'';[for(r of g(s))for(c of s)yield c+r]}

n上記のジェネレーターによって生成された最初の要素を返す73バイトの代替バージョン:

(s,n)=>Array(n).fill('').map(g=(r,i)=>i--?g(r+s[i%l],i/l|0):r,l=s.length)

JSにはジェネレーターがありますか?:0000000
cat

10

Mathematica、32 31バイト

Do[Echo/@#~Tuples~n,{n,0,∞}]&

編集:

CatsAreFluffyは1バイトを削り落としました。


8

Perl、39 37 35バイト

(最初に古いバージョンについて説明します。新しい短いプログラムは最後にあります)

+3を含む -alp

STDINの文字セットで実行します。例えば perl -alp kleene.pl <<< "a b c"

kleene.pl (このバージョンは34 + 3バイトです):

$#a=$"=","}for(@a){push@a,<{@F}$_>

-F-a入力文字間にスペースがない場合は暗黙的にドロップし、STDINの文字間にコンマを既に挿入している場合は-6(@a=""前のみ})に+2を追加します。

説明:

-alpオプションには、効果的にコードを行います。

BEGIN { $/ = "\n"; $\ = "\n"; }
LINE: while (defined($_ = <ARGV>)) {
    chomp $_;
    our @F = split(' ', $_, 0);
    $#a = $" = ',';
}
foreach $_ (@a) {
    use File::Glob ();
    push @a, glob('{' . join($", @F) . '}' . $_);
}

<>perlでわかるように、readlineに使用されるだけでなく、シェルスタイルのグロビングも実行できます(実際、古代のperlでは、シェルを呼び出すことで実装されていました)。

たとえば<{a,b}{1,2}>"a1","a2","b1","b2"

そのため、要素が含まれている場合は、間@Fにコンマを追加するだけです。補間のデフォルトの中間文字はスペースであり、特別な変数に保存されます$"。設定そう$"すること,になります"{@F}"{a,b}あれば@F=qw(a b)(グロブを文字列として拡大)

実際、のようなものでループするのが本当に好きでしたがglob"{@F}"x$n++、最初の空の行が生成されず、見つかったすべての回避策によってコードが長すぎるという問題にぶつかりました。

したがって、このコードのもう1つの重要な部分はfor、配列をループ処理するためにを使用すると、ループ中に追加の要素を実際にプッシュでき、ループもこれらの新しい要素を取得することです。したがって、ループ内にある場合、たとえば要素"ab"にある場合、リストコンテキストのに<{@F}$_>展開さ<{a,b}ab>れます("aab", "bab")。これらを押す@aと、左に伸びた文字列も利用可能になります

私がまだする必要があるのは、空の文字列でループをプライムすることです。それは使用して行われている$#a = 0,なっ数値コンテキストで0の最初で唯一の要素引き起こす)@aのように動作しますundefをになるために""、私はそれを使用する場合に

改善

実際、この説明のテストを行うことで、最初の空のエントリを適切に処理する成長するグロブを使用する簡単な方法を見つけました。として実行perl -ap kleene0.pl <<< "a b"(したがって、2バイトを追加-ap

kleene0.pl (このバージョンは33 + 2バイトです):

$"=",";print<$z,>;$z.="{@F}";redo

これらのソリューションはすべて、より多くの出力をメモリに保持するため、しばらくするとプログラムが失敗します。また、スカラーコンテキストで使用することで、遅延生成にperl globを使用できますが、プログラムが長くなります。


周りで何が起こっているのか説明してください:<{@F}$_>?ありがとう!
andlrc

6

Pyth、7

<s^LzQQ

ここで試してみてください

これは、からの各数値で入力のデカルト積を計算し、0..n-1それらを結合して、最初ののみを保持しnます。これは、3〜4よりもはるかに大きい数字または文字列の場合、オンラインでタイムアウトします。

または、無限出力を取得するには、Jakubeの回答を参照してください。


5

ゼリー、8 6バイト

⁷³p$Ȯ¿

これは、アルファベットを受け入れ、文字列の無限リストを出力する単項リンクです。オンラインでお試しください!

使い方

⁷³p$Ȯ¿    Monadic link. Argument: A (alphabet)

⁷         Set the return value to '\n'.
     ¿    While loop.
            Condition:
    Ȯ         Print the current return value and return it (always truthy).
            Body:
   $          Combine the two links to the left into a single, monadic link.
 ³              Yield A.
  p             Perform the Cartesian product of A and the current return value,
                updating the return value in the process.

代替バージョン、6バイト(非競合)

R’ḃL}ị

これは、左右の引数としてそれぞれアルファベットと必要な数の文字列を受け入れるダイアディックリンクです。

このバージョンは、このチャレンジがサンドボックス化された後に実装された全単射のベース変換を使用するため、競合しないと考えます。オンラインでお試しください!

使い方

R’ḃL}ị    Dyadic link. Arguments: n (integer), A (alphabet)

R         Range; yield [1, ..., n].
 ’        Decrement; yield [0, ..., n-1].
   L}     Yield l, the length of A.
  ḃ       Convert every i in [0, ..., n-1] to bijective base l.
     ị    For each array of digits, retrieve the corresponding characters of A.


4

CJam、16 10バイト

6バイトを節約してくれたjimmy23013に感謝します。

N{eam*_o}h

入力は、文字ごとに1つのコマンドライン引数です。出力は、各行に1つの文字列です。

オンラインでお試しください!(しかし、すぐにそれを殺します...)

説明

N      e# Push [\n]. At each step this array will contain all strings of length N,
       e# each followed by a linefeed.
{      e# Infinite loop...
  ea   e#   Read command-line arguments.
  m*   e#   Cartesian product: pairs each letter with each string in the list.
  _o   e#   Output all the strings of the current length.
}h

3

Pyth、7バイト

.V0j^zb

@fryの代替。このプログラムは文字列を読み取り、無限に文字列を出力し続けます。

説明:

.V0      for b in (0 to infinity):
    ^zb     compute all strings of length b consisting of the input alphabet
   j        print each one on a separate line

あるいは、以下も機能します。しかし、もう少しハッキーです。

u
M^zH7

3

Haskell、33バイト

k u=do s<-[0..];mapM(\_->u)[1..s]

たとえばk "xyz"、無限のリストです["","x","y","z","xx","xy","xz","yx","yy","yz","zx","zy","zz","xxx",...]


3

MATL、10バイト

0cD`G@Z^DT

オンラインでお試しください!ただし、サーバーでの大きな計算負荷を回避するために、長時間実行したままにしないでください。

プログラムは文字列を動的に表示し、各文字列は異なる行に表示されます。

0cD             % force display of a newline to represent the empty string
   `      T     % infinite do-while loop
    G           % push input, or nothing if no input has been taken yet
     @          % push iteration. Gives 1, 2,... in each iteration
      Z^        % Cartesian power. In the first iteration takes input implicitly 
       D        % display

2

Python 3、95

from itertools import*
def f(x,l=0):
 while 1:print(*combinations_with_replacement(x*l,l));l+=1

itertools関数にそのような長い名前が必要な理由。


3
combinations_with_replacementそれだけの価値はありません。ループを使用する方が短いと確信しています。常に。
mbomb007

2

Ruby、65 60バイト

->a{n=-1;loop{puts a.repeated_permutation(n+=1).map &:join}}

このような長い組み込み名...


1
AFAIK&の前にスペースは必要ありません。putsの代わりにpを使用できます。
ファンドモニカの訴訟

スペースをドロップすることはできません@QPaysTaxes、およびp通話inspectのような出力を生成する引数に[] ["a","b"] ["aa", "ab", ...
ドアノブ

私はあなたの答えを誤解しました。無限の配列を生成し、それを印刷していると思った。ただし、配列ではto_sがエイリアスとして検査されるため、putsとpの出力は同じであると確信しています。ruby-doc.org/core-2.2.0/Array.html#method-i-to_s WRTスペース:チェックしましたか?確かに私は確信していませんが、それについてはかなり確信しています。
ファンドモニカの訴訟

1

Pyke(コミット31)、10 9バイト

=blR.fbtp

説明:

=b         -    set characters for base conversion to eval_or_not(input())
  l        -   len(^)
   R      -  [^, eval_or_not(input()]
    .f    - first_n(^)
      b   -    conv_base(^)
       t  -   ^[-1]
        p -  print(^)

1

Scala、69

def f[A](s:Set[A]):Stream[List[A]]=Nil#::f(s).flatMap(x=>s.map(_::x))

遅延ストリームは、この種のことには非常に便利です。


1

Japt、50 40 34 28バイト

V²o ®s1+Ul)£UgXnH)¯X¦0}Ãâ ¯V

入力は"string", number of itemsです。出力は長さでソートされ、アルファベット順が逆になります。オンラインでテストしてください!

使い方

V²  o ®   s1+Ul)£  UgXnH)¯  X¦ 0}Ã â ¯  V
Vp2 o mZ{Zs1+Ul)mX{UgXnH)s0,X!=0}} â s0,V

Vp2 o      // Create the range [0..V²).
mZ{     }  // Map each item Z in this range to:
Zs1+Ul)    //  Take the base-(1+U.length) representation of Z.
mX{     }  //  Map each char X in this to:
XnH        //   Parse X as a base-32 number.
Ug   )     //   Take the char at index -^ in U.
s0,X!=0    //   If X is 0, slice it to an empty string.
â          // Uniquify the result.
s0,V       // Slice to the first V items.

100を超えるアイテムを実行する場合、このバージョンには時間がかかります。より高速なバージョンが必要な場合は、この32バイトのバージョンを試してください

V*2 o ms1+Ul)f@!Xf'0î£UgXnH}ïV

1

シナモンガム、6バイト

0000000: 6801 301c e74b                           h.0..K

シナモンガムはこのチャレンジの後に作られたため、競合しません。

オンラインで試してください(TIOは出力を制限します)。

説明

hシナモンガムを置く形式とモードを生成します。残りの文字列はに圧縮解除され[%s]*ます。次に%s入力が置き換えられ、正規表現に一致するすべての可能な文字列を出力するジェネレータが作成されます。



0

Python、55バイト

s=input();l=['']
for x in l:print x;l+=[x+c for c in s]

これは、feersumの53バイトのソリューションよりも長くなりますが、印刷出力の異なる方法を示しています。リストlは、読み取られる各文字列のすべての1文字のサフィックスを追加することにより、反復処理中に更新されます。

使用するのも同様に長いmapです:

s=input();l=['']
for x in l:print x;l+=map(x.__add__,s) 

Python 3でも同じ長さを実現できますが、のcharを失い、print()入力の展開によってcharを保存します。

s,*l=input(),''
for x in l:print(x);l+=[x+c for c in s]

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