属于回文的字符串排列数


13

您的输入将是由小英文字母组成的字符串。

您的任务是确定作为回文的原始字符串的不同排列的数量。

输入字符串最多包含100个字母。在较长的字符串的情况下,结果可能会很大,因此输出应为模数666013的排列数。

例如,

cababaa -> 3

可能的排列是:

aabcbaa
abacaba
baacaab

这是,所以最短的答案会成功!


2
“鉴于字符串最多包含100位数字,结果必须为%666013。” 如果是这样,最好包括一个相应的测试用例。
Martin Ender

4
我不了解%666013行。不过,这是一个充满希望的挑战,一旦得到解释,我将愿意投票决定重新开放。

12
哦,现在已经编辑好了,我明白了您的意思。我不认为这条线会增加挑战。它主要只是惩罚没有任意精度整数的语言。通常,我们会做类似“如果在无限制整数的假设版本中运行,答案应该是正确的”。

7
这实际上可能会使用更多的测试用例。
smls

3
测试用例的建议(但请对其进行验证):(abcdabcddddd -> 120 无奇数字符)abcdabcdddddd -> 120 (一个奇数字符数)abcdabcddddddeee -> 0 (两个奇数字符数)aabbccddeeffgghhiijj -> 298735 (受模数影响)
smls

Answers:


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

乔纳森·艾伦的-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]被从基转换214,并成为14*214^2 + 116*214 + 45 = 666013。我不太确定数字的引用在哪里,但是它们似乎与信息页上的顺序一致(是否?)。@Adnan可能会启发我们。
乔纳森·艾伦,

1
@Emigna Easy,当您知道该语言时:D
Jonathan Allan

1
您可以保存2个字节来删除if语句,因为无论如何您只有堆栈上需要的值:œÙ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例行处理拒绝排列超过20个元素的列表,并且任务描述最多需要输入100个字符。

因此,我改用基于输入字母频率的直接公式:

  1. 我的&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 ķ 1)
    ,例如,对于输入的字母频率(2,2,2,7),上的字母一个回文形式与多重一个多重的侧(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. 我必须使用“ splat运算符 ”(不是真实名称)从object中提取元素permutations(...)。否则,set({...})将只包含一个元素,即对象本身。
  3. 我使用set({...})仅保留内部的不同排列。

在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个字节(编辑:此PDF似乎也印证了它,礼貌的SML的答案):

Ñ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。
乔纳森·艾伦,

Gah,我正好要确切发布此答案,但由于我先发布了Brachylog答案,所以没有及时到达那里。我想这是第二要务。显然,我应该记住,果冻是一种比Brachylog更流行的语言,因此我应该首先处理该提交。

哇,一个字节一个字节?我也有13个,但认为效率略低:)
Jonathan Allan

数字是以不同的底数压缩的还是什么?:P
Yytsi'2

在我的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。请注意,当原始计数中最多有一个奇数时,即当中最多有一个小数时,输入的回文排列正好存在t。我们可以通过简单地将t-i(使用Tr)的所有元素加起来进行测试:如果答案小于1,则有回文排列,否则就没有。

如果存在,则i表示排列左半部分中不同字符的计数,可以任意排列。精确的处理方法就是MultinomialMathematica内置的系数(某些阶乘的商)。


1

k,23个字节

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

如果使用oKcmb不存在,请使用prm代替cmb



1

C ++ 14,161字节

如未命名的lambda,假设输入是类似的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

Ruby,67 57 52 59个字符

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

Codegolf提交的内容应为适当的程序/功能/ lambda,而不是摘要。我不是Ruby程序员,但是我认为您可以通过将其包装在Lambda中来->s{ },不是吗?
smls

另外,根据文档(s.size)论点是否多余?
smls '17

1
我在Ruby 2.4上进行了测试,但它也可以正常工作.to_a
smls '17

@smls在ruby 2.3.3上不起作用(undefined method uniq'对于#<Enumerator`),但对它在ruby 2.4上起作用,谢谢:)
Dorian

结果是否必须采取mod 666013
NonlinearFruit

1

Japt20 18字节

á f_¥Zw} l %666013

由于ETHproductions,节省了2个字节。

在线尝试!


很好,这就是我要做的。您可以保存两个字节用f_¥Zw},因为_是短期的Z{Z
ETHproductions

á fêS â l %666013会为您节省一个字节。
powelles

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#获取所有唯一排列。
   {_W%=} e#用于检查列表是否是回文的函数。
    _ e#重复的ToS。
     W%e#反向ToS(推-1,ToS的模块化索引)。
       = e#检查ToS是否等于SToS。
         %e#地图。
          :+ e#Sum(加减)。
            666013 e#按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);
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.