Palindrom olan dize permütasyonlarının sayısı


13

Girişiniz küçük İngilizce harflerden oluşan bir dize olacaktır.

Göreviniz, bir palindrom olan orijinal dizenin farklı permütasyonlarının sayısını belirlemektir.

Giriş dizesi 100 harfe kadar. Daha uzun bir dizgide sonuç çok büyük olabilir, bu nedenle çıktı modulo 666013 permütasyon sayısı olmalıdır.

Örneğin,

cababaa -> 3

Olası permütasyonlar:

aabcbaa
abacaba
baacaab

Bu , bu yüzden en kısa cevap kazanır!


2
"Dizenin 100 basamağa sahip olduğu düşünüldüğünde sonuç% 666013 olmalıdır." Eğer öyleyse, karşılık gelen bir test senaryosu eklemek iyi bir fikir olacaktır.
Martin Ender

4
% 666013 hattını anlamıyorum. Bu umut verici bir zorluk ve açıklandıktan sonra yeniden açmak için oy vermeye istekli olurum.

12
Oh, şimdi düzenlenmiş, ne elde ettiğinizi anlıyorum. Bu çizginin zorluğa katkıda bulunduğunu sanmıyorum; çoğunlukla rastgele hassas tamsayıları olmayan dilleri cezalandırır. Normalde "sınırsız tamsayılarla dilinizin varsayımsal bir sürümünde çalıştırılırsa cevap doğru olmalıdır" gibi bir şey yaparız.

7
Bu gerçekten daha fazla test senaryosu kullanabilir.
smls

3
Test senaryoları için öneriler (lütfen bunları doğrulayın): abcdabcddddd -> 120 (tek karakter sayısı yok) , abcdabcdddddd -> 120 (bir tek karakter sayısı) , abcdabcddddddeee -> 0 (iki tek karakter sayısı) , aabbccddeeffgghhiijj -> 298735 (modulodan etkilenir) .
smls

Yanıtlar:


5

Brachylog (2), 15 bayt

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

Çevrimiçi deneyin!

açıklama

{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
Kesinlikle bu "benzersiz bulmak" uygulamak gerekir ...
Fatalize

2
@Fatalize: Evet! Bence "benzersiz sayım" bile 1 baytlık bir temsile değecek zorluklarda yeterli olur. Öte yandan, "modulo 666013" neredeyse kesinlikle değil ;-)

5

05AB1E , 17 16 13 bayt

Jonathon Allan'dan -1 bayt

Emigna ve Adnan'dan -3 bayt

œÙvyÂQO•E›j•%

Açıklama:

œÙ                # 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)

Çevrimiçi deneyin!


1
İçerik,, tabandan dönüştürülen ve haline gelen E›jrakamları temsil eder . Referansın basamaklar için nerede olduğundan emin değilim, ancak bilgi sayfasındaki sıralarıyla aynı çizgide gibi görünüyorlar . @Adnan bizi aydınlatabilir. [14, 116, 45]21414*214^2 + 116*214 + 45 = 666013
Jonathan Allan

1
@Emigna Dili bildiğinizde kolay: D
Jonathan Allan

1
œÙvyÂQ}O•E›j•%
Yine de yığınta

2
@JonathanAllan Basamakların (ve karakterlerin) tamamını burada bulabilirsiniz :).
Adnan

1
Emigna yorumuyla @ üzerine kurulan, kapanış desteği kaldırarak başka byte kaydedebilirsiniz: œÙvyÂQO•E›j•%.
Adnan

4

Perl 6 , 104 108 88 84 bayt

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

Çevrimiçi deneyin!

Nasıl çalışır

Tüm permütasyonları kolayca oluşturamıyorum ve astronomik çalışma sürelerine izin verilse bile filtreleyemiyorum, çünkü Perl 6'nın yerleşik permutationsrutin düz çıkışı 20'den fazla eleman içeren listelere izin vermeyi reddediyor ve görev açıklaması 100'e kadar giriş gerektiriyor karakter.

Bunun yerine, girişin harf frekanslarına dayalı doğrudan bir formül kullanıyorum:

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

    Bir sayıyı yarıya indiren ve onu en yakın tamsayıya yuvarlayan ve sonra bunun faktörünü alan bir yardımcı işlev.

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

    Giriş dizesindeki harf frekanslarını hesaplayın ve kodun geri kalanı için konu haline getirin. Örneğin giriş için abcdabcddddddbu liste olacaktır (2, 2, 2, 7).

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

    Birden fazla tek harf frekansı varsa, sonucu sıfır ile çarpın, çünkü bu durumda palindrom mümkün değildir.

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

    Her bir palindromun "bir tarafında" olacak karakterlerin olası permütasyon sayısını hesaplayın (bu, giriş harfi frekanslarının yarıya indirilmesi ve döşenmesiyle elde edilen çoklukların bulunduğu bir çoklu sete karşılık gelir) . Kullanılan formül bu PDF'den alınmıştır :
    (n 1 + ... + n k )! / (n 1 ! ⋅ ... ⋅n k 1)
    Örneğin, giriş harfi frekansları için (2,2,2,7), palindromun bir tarafındaki harfler çokluklu bir çoklu küme oluşturur (1,1,1,3)ve böylece permütasyon sayısıdır (1+1+1+3)! / (1!⋅1!⋅1!⋅3!) = 120.

  5. % 666.013

    Sonuç modulo 666013'ü alın.


Alternatif yöntemimin geçerli olduğunu görmek güzel !
Jonathan Allan

3

Python3, 81 80 bayt

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

Bu benim bulabileceğim en kısa şey. Permütasyonların daha kolay oluşturulabileceğinden emin değilim ...

açıklama

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.

notlar

  1. Kontrol a==a[::-1]bir boole değeri döndürür, ancak sum(...)işlev bunu dolaylı olarak bir tam sayıya (0 veya 1) verir ve buna göre toplar.
  2. Nesneden öğeleri ayıklamak için , ' splat operatörü ' (gerçek adı değil) kullanmak zorunda permutations(...). Aksi takdirde set ( {...}) yalnızca bir öğe, nesnenin kendisi içerir.
  3. {...}İçeride sadece farklı permütasyonları tutmak için set ( ) kullanıyorum.

Floroid'de bu (neredeyse) z(T(a==aDKaIW(cb(L)))%666013), ancak bunun yerine sonucu yazdırır ve komutu komut satırından alır.

@Jonathan Allan'a bir bayt tasarrufu için teşekkürler ! -> importTarzı değiştirdi

Çevrimiçi deneyin!


3

Jöle , 13 bayt

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

Çevrimiçi deneyin!

Nasıl?

Kaba bir zorlama.

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

Ben inanıyorum bu bu daha verimli yapacak, ama bu 30 byte (düzenleme: Bu pdf onaylamak gibi görünüyor, nezaket SML cevabı ):

Ñ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.

Evet öyle %, mod.
Jonathan Allan

Gah, tam olarak bu cevabı göndermek üzereydim , ama önce oraya ulaşmadım çünkü önce Brachylog cevabını gönderdim. İçinde ikinci bir mesele olduğunu düşünüyorum. Açıkçası Jelly'nin Brachylog'dan daha popüler bir dil olduğunu hatırlamalıyım ve bu yüzden önce bu sunum üzerinde çalışmalıyım.

Vay, bayt için bayt? Başka 13 tane daha var, ama biraz daha az verimli olduğunu düşünüyorum :)
Jonathan Allan

Sayı farklı bir tabanda sıkıştırılmış mı veya ne? : P
Yytsi

TIO sekmden Œ!QŒḂ€S%“µɲ€’. Bu bana biraz benziyor.

2

Mathematica, 46 bayt

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

Girdi olarak karakterlerin bir listesini alır.

Çok verimsiz, çünkü aslında girdinin tüm permütasyonlarını üretir ve daha sonra palindromik olanları sayar.


0Dize garip çokluk (gibi "abcdabcddddddeee") ile oluşan birden çok harf varsa, bu yanlış bir olumlu yanıt verir düşünüyorum .
Greg Martin

@GregMartin Teşekkürler, düzeltildi. Bu zaten gereksiz yere karmaşıktı.
Martin Ender

2

Mathematica, 68 bayt

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

Karakter olarak bir liste girdi olarak alan ve bir tamsayı döndüren saf işlev. Martin Ender'in Mathematica cevabı kadar kısa değil , ancak yine de smls'in Perl 6 cevabı ile aynı yaklaşım gibi görünen sevimli bir yaklaşım .

İlk olarak, t=Last/@Tally@#/2girdideki tüm farklı karakterlerin sayılarını bölü olarak hesaplar 2; sonra i=Flooroluşan fraksiyonları aşağı yuvarlar t. Girişin palindromik permütasyonlarının, orijinal sayımlar arasında en fazla bir tek sayı olduğunda, yani en fazla bir fraksiyon olduğunda tam olarak var olduğunu unutmayın t. Bunu sadece t-i(kullanarak Tr) tüm öğelerini toplayarak test edebiliriz : cevap daha küçükse 1, palindromik permütasyonlar vardır, aksi halde değil.

Eğer varsa, o zaman ipermütasyonların sol yarısında keyfi olarak ayarlanabilen farklı karakterlerin sayısını temsil eder. Bunu yapmanın yollarının sayısı, MultinomialMathematica'nın yerleşik olduğu katsayıdır (belirli faktörlerin bir bölümü).


1

k, 23 bayt

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

OK kullanılıyorsa veya cmbyoksa, prmyerine kullanın cmb.



1

C ++ 14, 161 bayt

Adsız lambda girişinin std::stringreferans parametre ile olduğu ve geri döndüğü varsayılarak .

#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));}

Ungolfed ve kullanımı:

#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

Yakut, 67 57 52 59 karakter

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

Codegolf başvuruları parçacıklar değil uygun programlar / fonksiyonlar / lambdas olmalıdır . Ben Ruby programcısı değilim ama sanırım bunu içine alarak lambdaya dönüştürebilirsin ->s{ }, değil mi?
smls

Ayrıca, belgelere dayanarak , (s.size)argüman gereksiz değil mi?
smls

1
Ruby 2.4'te test ettim ve o da olmadan çalışıyor .to_a.
smls

@smls ruby ​​2.3.3 üzerinde çalışmıyor ( undefined method # <Enumerator` için uniq '), ancak doğru ruby ​​2.4 üzerinde çalışıyor, teşekkürler :)
Dorian

Sonuç alınmalı mod 666013mı?
NonlinearFruit


0

MATL, 13 bayt

Y@Xu!"@tP=Avs

MATL Online'da deneyin

açıklama

        % 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 bayt

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

Çevrimiçi deneyin!

Açıklama:

qe! {_ W% =}%: + 666013% e # Tam program.
qe # Tüm girişleri alın.
 E! e # Tüm benzersiz permütasyonları alın.
   {_W% =} e # Bir listenin palindrom olup olmadığını kontrol etme işlevi.
    _ e # Yinelenen ToS.
     W% e # Ters ToS (Push -1, ToS'un modüler indeksi).
       = e # ToS'nin SToS'a eşit olup olmadığını kontrol edin.
         % e # Harita.
          : + e # Toplam (Ekleyerek azalt).
            666013 e # Push 666013.
                  % e # Modulo.


0

Ohm, 17 bayt

I⌐:_₧?¡;;¼,

Açıklama:

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

0

PHP, 182 Bayt

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);

Çevrimiçi sürüm

Yıkmak

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);
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.