パリンドロームであるストリング順列の数


13

入力は、小さな英語の文字で構成される文字列になります。

あなたの仕事は、パリンドロームである元の文字列の異なる順列の数を決定することです。

入力文字列は最大100文字です。長い文字列の場合、結果は非常に大きくなる可能性があるため、出力は666013を法とする順列の数になります。

例えば、

cababaa -> 3

可能な順列は次のとおりです。

aabcbaa
abacaba
baacaab

これはなので、最短の答えが勝ちです!


2
「文字列が最大100桁である場合、結果は%666013でなければなりません。」その場合、対応するテストケースを含めることをお勧めします。
マーティンエンダー

4
%666013行がわかりません。しかし、これは前途有望な課題であり、説明が済んだら、再開するために投票したいと思います。

12
ああ、今ではそれが編集されました、あなたが何をしているのかわかります。その線が課題に追加されるとは思わない。ほとんどの場合、任意精度の整数を持たない言語を罰します。通常、「制限のない整数を使用して仮想バージョンの言語で実行する場合、答えは正しいはずです」などのことを行います。

7
これにより、さらに多くのテストケースを使用できます。
smls

3
テストケースの提案(ただし、それらを確認してください):(abcdabcddddd -> 120 奇数文字数なし)abcdabcdddddd -> 120 (1行の奇数文字数)abcdabcddddddeee -> 0 (2奇数文字カウント)aabbccddeeffgghhiijj -> 298735 (モジュロによって影響を受けます)
smls

回答:


5

Brachylog(2)、15バイト

{p.↔}ᶠdl%₆₆₆₀₁₃

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

説明

{p.↔}ᶠdl%₆₆₆₀₁₃
{   }ᶠdl          Count (l) the number of distinct (d) results (ᶠ) obtainable by:
 p                  permuting {the input}
  .                 to produce an output
   ↔                that, if reversed, is still the output
        %₆₆₆₀₁₃   then take that number modulo 666013

2
私は間違いなくその「ユニークな検索」を実装する必要があります...
Fatalize

2
@Fatalize:はい!チャレンジでは、「一意のカウント」でさえ十分に頻繁に発生し、1バイトで表現する価値があると思います。一方、「modulo 666013」はほとんど確かにそうではありません;-)

5

05AB1E17 16 13バイト

Jonathon Allanから-1バイト

EmignaおよびAdnanから-3バイト

œÙvyÂQO•E›j•%

説明:

œÙ                # Unique permutations of [implicit] input
  vy              # For each permutation...
    ÂQ            # Check if it is a palindrome
      O           # If so, increment the counter
       •E›j•%     # Modulo 666013 (no clue why this number, or even why this rule is in place)

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


1
内容はE›j[14, 116, 45]baseから変換された数字を表し214、になり14*214^2 + 116*214 + 45 = 666013ます。数字の参照がどこにあるのかはよくわかりませんが、情報ページの順序と一致しているようです(似ていますか?)。@Adnanは私たちを啓発するかもしれません。
ジョナサンアラン

1
@Emigna言語を知っていれば簡単:D
ジョナサンアラン

1
あなただけとにかくスタック上必要な値を持っているとして、あなたは、if文を削除する2つのバイトを保存することができます:œÙvyÂQ}O•E›j•%
Emigna

2
@JonathanAllan数字(および文字)の全範囲はここにあります :)。
アドナン

1
@Emignaのコメントに基づいて、閉じ括弧を削除することで別のバイトを保存できますœÙvyÂQO•E›j•%
アドナン

4

Perl 6の104の 108 88 84バイト

{my &f={[*] 1..$_ div 2}
.comb.Bag{*}.&{(2>.grep(*%2))*f(.sum)/[*]($_».&f)%666013}}

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

使い方

天文学的な実行時間が許可されている場合でも、Perl 6の組み込み機能を使用して、すべての順列を簡単に生成してフィルタリングすることはできません。 permutations。Perl6ルーチンは、20を超える要素のリストの順列を拒否し、タスクの説明には最大100の入力が必要です文字。

したがって、代わりに、入力の文字頻度に基づいた直接式を使用します。

  1. my&f = {[*] 1 .. $ _ div 2}

    数値を半分にして最も近い整数に切り捨ててから、その階乗を取るヘルパー関数。

  2. .comb.Bag {*}。&{};

    入力文字列の文字の頻度を集計し、残りのコードのトピックにします。例えば、入力のabcdabcdddddd場合、これはリストになり(2, 2, 2, 7)ます。

  3. (2> .grep(*%2))*

    奇数文字の頻度が複数ある場合、結果にゼロを掛けてください。その場合、回文は不可能だからです。

  4. f(.sum)/ [*]($ _»。&f)

    各回文の「片側」にある文字の可能な順列の数を計算します(これは、入力文字の頻度を半分にしてフロアリングすることによって得られた多重度を持つ多重集合に対応します)。使用される式は、このPDFからです:
    (n 1 + ... + n k)!/(N 1!⋅...⋅n K 1)
    入力文字周波数用など(2,2,2,7)、上の文字1つの多重有するパリンドローム形多重集合の側(1,1,1,3)、及び順列の数は、このようにあります(1+1+1+3)! / (1!⋅1!⋅1!⋅3!) = 120

  5. %666013

    結果をモジュロ666013で取得します。


私の代替方法が有効であることを見るのは良いことです!
ジョナサンアラン

3

python3、81の 80バイト

from itertools import*
lambda s:sum(a==a[::-1]for a in{*permutations(s)})%666013

これは私が思いつくことができる最短です。順列をより簡単に生成できるかどうかわからない...

説明

lambda s:                       # Anonymous function taking a parameter <s>. 
    sum(                        # Sum the following terms.
        a==a[::-1]              # Check whether the permutation <a> is a palindrome,
        for a in                # for each element <a>,
        {                       # inside a set that can only contain distinct elements.
            *                   # Splat the elements of the following object:
            permutations(s)     # the permutations of the input parameter <s>.
        }                       #
    )%666013                    # Modulo the sum by 666013.

ノート

  1. チェックa==a[::-1]はブール値を返しますが、sum(...)関数は暗黙的に整数(0または1)にキャストし、それに応じて合計します。
  2. オブジェクトから要素を抽出するには、「スプラット演算子」(実際の名前ではない)を使用する必要がありますpermutations(...)。それ以外の場合、セット({...})には1つの要素、つまりオブジェクトのみが含まれます。
  3. セット({...})を使用して、個別の順列のみを内部に保持します。

Floroidでは、これは(ほぼ)z(T(a==aDKaIW(cb(L)))%666013)ですが、代わりに結果を出力し、コマンドラインから入力を受け取ります。

バイトを節約してくれた@Jonathan Allanに感謝します!-> importスタイルを変更しました

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


3

ゼリー、13 バイト

Œ!QŒḂ€S%“µɲ€’

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

どうやって?

ブルートフォーサー。

Œ!QŒḂ€S%“µɲ€’ - Main link: string
Œ!            - all permutations
  Q           - unique
     €        - for each
   ŒḂ         - isPalindromic? (yep a built-in!)
      S       - sum
       %      - mod
        “µɲ€’ - base 250 compressed number 666013

これがより効率的にそれを行うと信じていますが、それは30バイトです(編集:このpdfsmlsの答えおかげでそれを確認するようです):

ÑHḞµS!÷!P$ - Link 1, palindrome count: string a    e.g. 'abcabcd'
Ñ          - call the next link (2) as a monad(a)  e.g. [2, 2, 2, 1]
 H         - halve                                 e.g. [1, 1, 1, 0.5]
  Ḟ        - floor (get pair counts)               e.g. [1, 1, 1, 0]
   µ       - start a new monadic chain - call that p
    S      - sum(p)                                e.g. 3
     !     - factorial                             e.g. 6
         $ - last 2 links as a monad:
       !   -     factorial(p) (vectorises)         e.g. [1, 1, 1, 1]
        P  -     product                           e.g. 1
      :    - integer division                      e.g. 6

ĠL€ - Link 2, count characters: string a           e.g. 'abcabcd'
Ġ   - group indexes                                e.g. [[1, 4], [2, 5], [3, 6], 7]
 L€ - length of €ach                               e.g. [2, 2, 2, 1]

ÇḂS⁼LḂ$aÑ%“µɲ€’ - Main link: string a              e.g. 'abcabcd'
                - first check to see if any palindromes will be possible:
Ç               - last link (2) as a monad         e.g. [2, 2, 2, 1]
 Ḃ              - mod 2                            e.g. [0, 0, 0, 1]
  S             - sum                              e.g. 1
      $         - last two links as a monad:
    L           -     length(a string)             e.g. 7
     Ḃ          -     mod 2                        e.g. 1
   ⁼            - equal?                           e.g. 1 (1 when palindromes are possible)
       a        - and
        Ñ       - next link as a monad             e.g. 6
         %“µɲ€’ - mod 666013, as in the brute force version.

はい、それ%はmodです。
ジョナサンアラン

ああ、ちょうどこの答えを投稿しようとしていましたが、最初にBrachylogの回答を投稿したので、間に合いませんでした。ほんの少しの問題だと思います。明らかに、JellyはBrachylogよりも人気のある言語であることを覚えておく必要があります。そのため、最初にその提案に取り組む必要があります。

うわー、バイトバイバイト?他にも13個ありますが、やや効率が悪いと思います:)
ジョナサンアラン

番号は別のベースで圧縮されていますか?:P
Yytsi

[TIO]タブからŒ!QŒḂ€S%“µɲ€’。それは私とバイト単位で同一に見えます。

2

Mathematica、46バイト

Permutations@#~Count~_?PalindromeQ~Mod~666013&

入力として文字のリストを受け取ります。

入力のすべての順列を実際に生成してから回文の順列をカウントするため、ひどく非効率的です。


0文字列に奇数の多重度で発生する複数の文字がある場合(など"abcdabcddddddeee")、これは間違って肯定的な答えを与えると思います。
グレッグマーティン

@GregMartinありがとう、修正。とにかくこれは不必要に複雑でした。
マーティンエンダー

2

Mathematica、68バイト

If[i=Floor[t=Last/@Tally@#/2];Tr[t-i]<1,Multinomial@@i,0]~Mod~666013

文字のリストを入力として受け取り、整数を返す純粋な関数。Martin EnderのMathematicaの回答ほど短くはありませんが、それでもかわいいアプローチです。これはsmlsのPerl 6の回答と同じアプローチのようです。

最初、 t=Last/@Tally@#/2に、入力内のすべての個別の文字の数を2; で割って計算します。次に、i=Floorで発生する端数を切り捨てますt。入力のパリンドローム順列は、元のカウントに最大で1つの奇数が存在する場合、つまり、に最大で1つの小数がある場合に存在することに注意してくださいtt-i(を使用してTr)のすべての要素を単純に加算することにより、それをテストできます。答えが以下の場合1、回文順列が存在し、そうでない場合は存在しません。

もしあれば、 i、順列の左半分にある個別の文字のカウントを表します。これは任意に配置できます。それを行う方法の数はMultinomial、Mathematicaに組み込まれている係数(特定の階乗の商)とまったく同じです。


1

k、23バイト

{666013!+/{x~|x}'cmb x}

oKを使用する場合、またはcmb存在しない場合は、のprm代わりに使用しますcmb



1

C ++ 14、161バイト

名前のないラムダは、入力が類似してstd::stringおり、参照パラメーターを介して戻ると想定しています。

#import<algorithm>
[](auto s,int&n){auto a=s.begin(),b=s.end();std::sort(a,b);n=0;do n=(n+std::equal(a,b,s.rbegin()))%666013;while(std::next_permutation(a,b));}

ゴルフをしないと使用法:

#include<iostream>
#include<string>

#import<algorithm>
auto f=
[](auto s,int&n){
 auto a=s.begin(),b=s.end();
 std::sort(a,b);
 n=0;
 do
  n=(n+std::equal(a,b,s.rbegin()))%666013;
 while(std::next_permutation(a,b));
}
;

using namespace std;


int main(){
 string s;
 s = "cababaa";
 s = "abcdabcddddd";
 int n;
 f(s,n);
 cout << n << endl;
}

1

ルビー、67 57 52 59文字

->s{s.chars.permutation.uniq.count{|t|t.reverse==t}%666013}

Codegolfの提出は、スニペットではなく、適切なプログラム/関数/ラムダでなければなりません。私はRubyプログラマーではありませんが、これをラッピングすることでラムダに変えることができると思い->s{ }ますか?
SMLS

また、ドキュメントに基づいて、(s.size)引数は冗長ではありませんか?
smls

1
Ruby 2.4でテストしましたが、これも機能し.to_aません。
smls

@smlsはruby 2.3.3(undefined method #<Enumerator`のuniq ')では機能しませんが、右はruby 2.4で機能します。ありがとう:)
ドリアン

結果を取得する必要がありmod 666013ますか?
NonlinearFruit


0

MATL、13バイト

Y@Xu!"@tP=Avs

MATL Online試しください

説明

        % Implicitly grab input as a string
Y@      % Compute all permutations of the inputs (one per row)
Xu      % Determine the unique rows
!       % Take the transpose so each permutation is a column
"       % For each unique permutation
  @     % Take this permutation
  tP=A  % Duplicate it, reverse it, and compare (yields 1 for palindrome and 0 otherwise)
  v     % Vertically concatenate the entire stack
  s     % Compute the sum of all elements
        % Implicitly end for loop and display the result

0

CJam、19バイト

qe!{_W%=}%:+666013%

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

説明:

qe!{_ W%=}%:+ 666013%e#完全なプログラム。
qe#すべての入力を取得します。
 e!e#すべての一意の順列を取得します。
   {_W%=} e#リストが回文であるかどうかを確認する関数。
    _ e#複製ToS。
     W%e#Reverse ToS(プッシュ-1、ToSのモジュラーインデックス)。
       = e#ToSがSToSと等しいかどうかを確認します。
         %e#マップ。
          :+ e#Sum(加算による削減)。
            666013 e#Push 666013。
                  %e#モジュロ。


0

オーム、17バイト

I⌐:_₧?¡;;¼,

説明:

I⌐:_₧?¡;;¼,  ■Main wire
I⌐:     ;    ■for _ in permutations(input()){
   _₧? ;     ■  if(palindrome(_)){
      ¡      ■    counter++;
       ;     ■  }
        ;    ■}
         ¼,  ■print(counter)

0

PHP、182バイト

function f($a,$b=1){return$a?f($a-1,bcmul($a,$b)):$b;}$a=count_chars($argv[1],$r=1);foreach($a as$v){$c+=$v%2?:0;$c>1?die("0"):$z+=$f=$v/2^0;$r=bcmul(f($f),$r);}echo bcdiv(f($z),$r);

オンライン版

壊す

function f($a,$b=1){  #Factorial
    return$a?f($a-1,bcmul($a,$b)):$b;
}
$a=count_chars($argv[1],$r=1); # Array count for every char
foreach($a as$v){
    $c+=$v%2?:0; # counter mod 2 ==1
    $c>1?die("0"):$z+=$f=$v/2^0; # end program if there are 2 chars which cannot divide by 2
    $r=bcmul(f($f),$r);
}
echo bcdiv(f($z),$r);
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.