アナグラムを出力してください!そんなことない!


28

相互のアナグラムである一意の文字列のリストが与えられたら、リスト内の各単語とは異なるそれらの単語のアナグラムを出力します。

文字列は英数字になり、有効なアナグラムが保証されます。

プログラムまたは関数は非決定的である必要はありませんが、同じ入力が与えられた場合、可能なすべての出力が有効である限り、コードを複数回実行すると異なる出力を生成できます。

テストケース

[Input] -> Possible output
-----------------
[ab] -> ba
[aba, aab] -> baa
[123, 132, 231, 312, 321] -> 213
[hq999, 9h9q9, 9qh99] -> 999hq
[abcde123, ab3e1cd2, 321edbac, bcda1e23] -> ba213ecd

回答:


20

Python 3、64バイト

lambda a:[*{*permutations(a[0])}-{*a}][0]
from itertools import*

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


4
しかしitertools、答えはありますか?
MildlyMilquetoast

@MistahFiggins ノミネート
Mr. Xcoder

2015年7月22日の前にMr.Xcoder @
スタン・ストラム

@StanStrum私はちょうどそれを言及した、私はその制限を認識しています。Stewieは言ったように...
ミスターXcoder

1
@ jpmc26はい、この方法f=\で、Try it Onlineヘッダーに入力して、自動TiOバイトカウンターに影響を与えずに関数を匿名のままにすることができます
Mr. Xcoder

9

05AB1E、5バイト

нœ¹мà

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

説明

нœ¹мà

н     // Get the first element of the input list
 œ    // Generate all permutations
  ¹   // Push the input again
   м  // In the permutations list, replace all strings that
      //   are in the input list with empty strings
    à // Pick the string with the greatest lexicographic
      //   index (in this case a non-empty string)


4

ゼリー、6バイト

XŒ!ḟµḢ

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

05AB1EおよびPythの回答より1バイト多い。

説明:

XŒ!ḟµḢ   Main program.
 Œ!      All permutation of...
X        any element from the word list.
   ḟ     Filter out (remove) all the elements in the original word list.
    µ    With the filtered-out list,
     Ḣ   pick the first element.

私が選んだX、それはリストを変更することなく、リストから任意の要素を選択するために、私が知っている最短の方法です(ので、仕事をしない、ḷ/ṛ/長い)、そしてそれはいくつかのランダム性を引き起こすことが起こります。

µここではかなり冗長ですが、それなしで、とペアにされるだろう、それは私がここで必要ではない、「入力の頭からフィルタ」と解釈される(私は必要なものを入力外「フィルタであり、と頭を取得します」)。


4

Javascript、118バイト

function f(a){s=a[0];while(a.indexOf(s)!=-1)s=s.split("").sort(function(){return .5-Math.random()).join("")};return s}

悪いランダマイザーを使用して、各「ランダム」置換を繰り返します。

おそらく間違いなく間違っていますが、悪いランダマイザーは、真のランダム性を取得できないことを意味しますが、すべての順列を取得します。

私にとってはクロムのすべてのケースで動作するようですが、明らかにこの種の悪用の未定義の動作のために、一部のブラウザでは動作しません。

(おそらく非常に未経験の方は、ご自身のソリューションで自由に改善してください)

80バイト

pirateBayのコメントに感謝-多くのバイト

リックのおかげで-4バイト

f=a=>eval('s=[...a[0]].sort(()=>.5-Math.random()).join``;a.indexOf(s)<0?s:f(a)')

FYI矢印関数が許可されています(たとえば、a=>b代わりにfunction(a){return b})。それは多くのバイトを節約します。

うわー、それはかなりのバイトを節約します。
-Imme

s.split("")することができます[...s]。またjoin("")、「参加」することもできます
リック・ヒッチコック

@ThePirateBay私はそうなるのではないかと心配しましたが、それはなぜですか?(ソートが完全にランダムではなく、すべてのシーケンスが可能にすべきであると認識してイム)
Imme

@Imme。これは、87バイトの作業バージョンです。sort関数が返らない0(または少なくとも非常にまれ)ことに注意してください。これが機能しなかった理由です。

4

Haskell、58バイト

-1バイト。Laikoniのおかげで修正。

import Data.List
f l=[i|i<-permutations$l!!0,all(/=i)l]!!0

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

Data.List順列のためにインポートする価値はないかもしれませんが、ええ。


1
でバイトを保存できますnotElem。誰かがインポートに勝る置換関数を見つけた場合、私は驚かれるでしょう、私の最短のアプローチはインポートの29バイトに対して60バイトです。
ライコニ

1
43バイトの順列関数を次に示しますが、これは重複する空きリスト専用です。
ライコニ

1
また、$前に不足しているため、ソリューションは現在機能していませんl!!0
ライコニ




3

Japt7 6バイト

@Shaggyのおかげで-1バイト

á kN ö

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

入力文字列を配列ではなく複数の入力として受け取ります。ランダムな順列を出力します。に切り替えög、代わりに最初のものを取得します。

説明

á kN ö  Implicit input: N = array of input strings
á       Get all permutations of the first input string
  kN    Remove all input strings from those
     ö  Get a random element from the array. Implicit output

ナッツ、あなたはそれに私を打った。入力を個別の文字列として受け取り、でバイトを保存できますá kN ö
シャギー

@Shaggy最初の入力項目を取得するのに最適な方法です。それを覚えておく必要があります。ありがとう!
ジャスティンマリナー

2

MATL1513、12のバイト

1X)Y@Z{GX-1)

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

Sanchisesのおかげで2バイト節約されました。setdiff(...,'rows')否定よりも短く、ismember(...,'rows')1つの重複を回避します。Luis Mendoのおかげで、配列ではなくセルに切り替えることで、もう1バイト節約しました。

説明:

MATLAB / Octaveの同等物も含まれています。

                 % Implicitly grab input x containing cells of strings
1X)              % Get first cell. Equivalent to x{1}
   Y@            % All permutations of first row input. Equivalent to p=perms(y)
      Z{         % Convert the list of permutations to a cell array
        G        % Grab input again      
         X-      % setdiff, comparing the input cells with the permutations
           1)    % The first of the results

入力はformatのいずれかでなければなりません{'abc', 'acb'}


2

Python 3、78バイト

lambda a:[x for x in permutations(a[0])if~-(x in a)][0]
from itertools import*

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

Xcoder氏のおかげで-1バイト


if x not in aであるif~-(x in a)ために178
氏Xcoder

@ Mr.Xcoder。という意味78ですか?

@ThePirateBayはい、そうです...おっと!
ミスターXcoder

1
どの程度66のバイト
-NieDzejkob

1
@NieDzejkobそれは印象的に短いです。必要に応じて投稿する必要があります
-HyperNeutrino

2

ピップ、11バイト

@:_NIgFIPMa

入力をコマンドライン引数として受け取ります。オンラインでお試しください!

説明

          a  1st cmdline arg
        PM   List of all permutations
      FI     Filter on this function:
  _NIg         Permutation not in cmdline args
@:           First element of resulting list (with : meta-operator to lower precedence)
             Autoprint

2

Python 3、87バイト

これは、これまでのところ、置換組み込みもランダムシャッフル/ソートも使用していない唯一の提出であると思います。長くなりますが、アルゴリズムはかなりきれいだと思います。

lambda L:[p for s in L for i,c in enumerate(s)for p in[c+s[:i]+s[i+1:]]if~-(p in L)][0]

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

説明

私たちがやっていることは基本的にこれです:

def unique_anagram(string_list):
    for string in string_list:
        for i, char in enumerate(string):
            # Move the character to the beginning of the string
            permutation = char + string[:i] + string[i+1:]
            if permutation not in string_list:
                return permutation

これが機能することの証明です:

ストリングのために、1つの文字を選択してそれを前に動かすことによって得られたストリングのセットとしてS定義front(S)してください。たとえば、です。SSfront(ABCDE){ABCDE, BACDE, CABDE, DABCE, EABCD}

ここで、可能性のあるすべてのアナグラム(問題の説明に従って)が含まれLLいないアナグラムのリストを検討します。私たちは、文字列が存在することを示したいSL、このようなfront(S)少なくとも一つのアナグラム含まれているS'ではありませんL

矛盾として、すべての文字列Sin Lに対して、すべての文字列in front(S)もinであると仮定しLます。一連の「正面」の動きを介して、任意の文字列の任意の順列を生成できることに注意してください。たとえば、取得するには

ABCDE -> BAEDC

我々はできる

ABCDE -> CABDE -> DCABE -> EDCAB -> AEDCB -> BAEDC

SinについてL、すべてのS'in front(S)もであると仮定しましたL。これは、すべてがS''front(S')あることを意味Lします。したがって、Sがinの場合L、のすべての順列SもになりLます。その後L、アナグラムの完全なセット、矛盾する必要があります。

したがって、in にない置換が少なくとも1つあることが保証されているため、in がin にないL文字列Sが存在する必要があります。QED。LS'front(S)L

コードはin front(S)ごとSに繰り返し処理を実行し、in ではないLを選択S'Lます。上記の結果により、少なくとも1つのS'資格があります。



1

JavaScript(ES7)、172バイト

f=(a,s=a[0],b=[...s],k=b.findIndex((e,i)=>s[i-1]>e))=>a.includes(s)?f(a,(~k?(t=b[k],b[k]=b[l=a.findIndex(e=>e>t)],b[l]=t,b.map((e,i)=>i<k?b[k+~i]:e)):b.reverse()).join``):s

配列に含まれていない配列の最初の要素の最初の辞書式順列を見つけます。


1

Kotlin、104バイト

{var r=""
do{r=it[0].map{it to Math.random()}.sortedBy{(_,b)->b}.fold("",{a,(f)->a+f})}while(r in it)
r}

美化

{
    var r = ""
    do {
        r = it[0].map { it to Math.random() }
            .sortedBy { (_, b) -> b }
            .fold("", { a, (f) -> a + f })
    } while (r in it)
    r
}

テスト

var ana: (List<String>) -> String =
{var r=""
do{r=it[0].map{it to Math.random()}.sortedBy{(_,b)->b}.fold("",{a,(f)->a+f})}while(r in it)
r}

fun main(args: Array<String>) {
    println(ana(listOf("ab")))
}



1

R、89バイト

x=scan(,'');repeat{a=paste(sample(el(strsplit(x[1],''))),collapse='');if(!a%in%x)break};a

最初のエントリから文字を繰り返しサンプリングし(相互のアナグラムである必要があるため)、それらのサンプルの1つが元のリストにないときに停止します。




1

PHP、70バイト

$j=1;while($j){$g=str_shuffle($_GET[0]);$j=in_array($g,$_GET);}echo$g;

0のインデックス付き取得値を入力するか、オンラインで試してください。

非ゴルフ

$j=1; //set truty value
while($j){ 
    $g=str_shuffle($_GET[0]); //shuffle the first anagram of the set
    $j=in_array($g,$_GET); //see if in the set, if false, the loop ends
}
echo $g;

do{...}while($j);代わりに2バイトを保存します$j=1;while($j){...}。インプレース定義を使用して$g、中括弧を取り除きます(4バイトを節約します)。
タイタス


1

アタッシュ、16バイト

&\S@{!S@_[0]Ø_}

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

説明

&\S@{!S@_[0]Ø_}
    {         }    lambda (input: `_`)
        _[0]       first element of the given array
       @           pass to:
     !                 on each permutation:
      S                cast to string
            Ø      without any member of
             _     the input
                   this gives all anagrams not in the input
   @               then
&\S                "first string element"
&                  spread input array over each individual arguments
 \                 tale first argument
  S                as a string

代替案

17バイト{&\S! !S@_[0]Ø_}

18バイト{&\S! !Id@_[0]Ø_}

19バイト{&\S!(!Id)@_[0]Ø_}

26バイト{&\S!Permutations@_[0]Ø_}

26バイト{&\S!Permutations[_@0]Ø_}

26バイト{(Permutations[_@0]Ø_)@0}

26バイト&\S##~`Ø#Permutations@&\S

27バイトLast@{Permutations[_@0]Ø_}

27バイト`@&0@{Permutations[_@0]Ø_}

28バイトLast##~`Ø#Permutations@&{_}

28バイトLast##~`Ø#Permutations@Last

28バイトFirst@{Permutations[_@0]Ø_}

30バイト{NestWhile[Shuffle,`in&_,_@0]}

33バイト{If[(q.=Shuffle[_@0])in _,$@_,q]}

33バイト{q.=Shuffle[_@0]If[q in _,$@_,q]}

34バイト{If[Has[_,q.=Shuffle[_@0]],$@_,q]}


0

J、25バイト

((A.~i.@!@#)@{.@:>){.@-.>

入力はボックス化された文字列のリストです-4 8 $ 'abcde123'、 'ab3e1cd2'、 '321edbac'、 'bcda1e23'として文字列のリストを明示的に宣言することはこのように公平であると感じました。

私はコードの@混乱を好まないのですが、今回はシリアル化された動詞がたくさんあります。

使い方:

                         >  - unboxes the strings
 (                 )        - left verb of the fork as follows:
             @{.@:>         - unbox and take the first string
  (         )               - finds all permutations of the first string
      i.@!@#                - a list 0 .. the factorial of the length of the 1st string
   A.~                      - anagram index, all permutations
                    {.@-.   - remove the inital strings and take the first of the remaining

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


1
21バイトの入力をテーブルとして取得します{.@(-.~i.@!@#@{.A.{.)オンラインでお試しください!
ジョナ

0

05AB1E、5バイト

нœIмà

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

説明

нœIмà full program with implicit input i
н     push first element of i
 œ    push all permutations
  I   push input i
   м  remove all elements of i from the permutations
    à extract greatest element and print implicitly

@ThePirateBayが見つけたのとほぼ同じ答え。


0

JavaScript、87バイト

a=>eval('for(s=[...a[0]];(a+[]).includes(k=s.sort(a=>~-(Math.random``*3)).join``););k')

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

この回答は、Immeの回答に基づいています(大幅に変更されていますが)。彼はコメントで、これは別の答えであるべきだと提案した。

古いアプローチの問題は、sort実装に完全に依存しているためです。標準では、ソート関数の呼び出し順序が保証されていないため、理論的には、最初または2番目のテストケースで終了することはありません。

このアプローチは数バイト長くなりますが、がMath.random返されない場合でも、制約された時間で終了することを保証します.5


0

CJam、11バイト

q~_0=m!\m0=

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

説明

q~  e# Read input and evaluate: ["123" "132" "231" "312" "321"]
_   e# Duplicate:               ["123" "132" "231" "312" "321"] ["123" "132" "231" "312" "321"]
0=  e# First:                   ["123" "132" "231" "312" "321"] "123"
m!  e# Permutations:            ["123" "132" "231" "312" "321"] ["123" "132" "213" "231" "312" "321"]
\   e# Swap:                    ["123" "132" "213" "231" "312" "321"] ["123" "132" "231" "312" "321"]
m0  e# Subtract, push 0:        ["213"] 0
    e# (m is used instead of - when in front of a digit)
=   e# Get item:                "213"

あなたの説明にタイプミスがあるかもしれないと思う-あなたのコードが与える答えはあなたの説明が言うものとは異なる
-MildlyMilquetoast

0

Perl 6、42バイト

{(.[0],*.comb.pick(*).join...*∉$_)[*-1]}

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

入力の要素がなくなるまで、入力の最初の文字列をランダムにシャッフルします。

説明:

{(.[0],*.comb.pick(*).join...*∉$_)[*-1]}
{                                      }   # Anonymous code block
 (                        ...    )   # Create a sequence
  .[0],   # The first element is the first element of the input
       *.comb.pick(*).join   # Each element is the previous one shuffled
                             *∉$_   # Until it is not in the input
                                  [*-1]   # Return the last element
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.