Taş-Makas-Makas'ta tekrar etmeyin.


26

Codegolf'un bir Rock-Paper-Scissors turnuvasına sahip olacağına dair söylentiler üzerine kare içermeyen kelimeler konusunu inceleyin . Harflerden oluşan bir kelime R, P, Solduğu kare içermeyen iki kez tekrarlar bir diziyi içermiyorsa. Yani, kelime olarak yazılamaz

a x x b

nerede ave bherhangi bir uzunlukta kelimeleri ve xen azından uzunluğunun bir kelime bir, bütün harflerin yapılmış olup R, P, S.

Görev

Üreten bir program yazın kare içermeyen harflerin kelime R, P, Suzunluğu nsayısı nerede 1 <= n <= 10girdi olarak alınır.

Örnek

Örneğin , uzunluğu 3 olan kare içermeyen kelimeler

RPR, RSR, RPS, RSP, SPS, SRS, SRP, SPR, PRP, PSP, PSR,PRS

ve uzunluğu 4 olan

RPRS, RPSR, RPSP, RSRP, RSPR, RSPS, PRPS, PRSR, PRSP, PSRP, PSRS, PSPR, SRPR, SRPS, SRSP, SPRP, SPRS,SPSR

ve örneğin SPSPveya PRPRücretsiz olmadığını unutmayın.

kurallar

  • Bu kod çözücüdür, en kısa program kazanır, standart boşluklar kapatılır.
  • Kelimeleri yazdırabilir veya bellekte oluşturabilirsiniz.
  • Programınız bir fonksiyon olarak yazılabilir.

Referanslar

Kare içermeyen kelimelere Wikipedia girişi

Verilen uzunlukta kare içermeyen üçlü kelimelerin sayısı https://oeis.org/A006156

İlgili: Keyfi Uzunlukta Üçlü Kare Kare Kelimeler


4
Bunun için bir test durumu n>3iyi bir fikir olacaktır, çünkü tekrarlanan karakterler ve tekrarlanan diziler hakkında bazı karışıklıklar olmuştur.
Laikoni

Lütfen kum kutusundaki planlanan takip hakkında yorum yapın: codegolf.meta.stackexchange.com/a/14133/45211
mschauer

6
"Doğal dil" etiketinin burada geçerli olduğunu düşünmüyorum
Leo,

1
Ah, "kelimeler" "doğal dilde" genişledi, onu kaldırdım.
mschauer

1
Hayır, SP SP karesini içerir
mschauer

Yanıtlar:


20

Ruby, 39 bayt

->n{(?P*n..?S*n).grep_v /[^RPS]|(.+)\1/}

Bu komik biçimde yetersiz işlev, N Ps ve N S'ler arasında alfabetik olarak kalan tüm uzunluktaki N dizgelerini oluşturur, ardından RPS olmayan karakterleri içeren büyük çoğunluğu filtreler. Gerçek squarefree çek sadece Normal İfade geribaşvuru kullanır: (.+)\1.

N = 10 için makul bir sürede biten daha deyimsel 65 bayt :

->n{%w[R P S].repeated_permutation(n).map(&:join).grep_v /(.+)\1/}

Düzenleme: G B. sayesinde bir bayt kaydedildi


Grep_v üzerinde parantez gerekmez, bununla eğik çizgi arasında yalnızca bir boşluk (1 bayt tasarruf edin)
GB

6
"Çok eğlenceli " verimsiz "muhtemelen bu sitede epeyce cevapları açıklıyor.
Fon Monica'nın Davası,

10

Jöle , 15 14 bayt

“RPS”ṗẆ;"f$$Ðḟ

Çevrimiçi deneyin!

Nasıl çalışır

“RPS”ṗẆ;"f$$Ðḟ  Main link. Argument: n

“RPS”ṗ          Cartesian power; yield all strings of length n over this alphabet.
            Ðḟ  Filterfalse; keep only strings for which the quicklink to the left 
                returns a falsy result.
           $      Monadic chain. Argument: s (string)
      Ẇ             Window; yield the array A of all substrings of s.
          $         Monadic chain. Argument: A
       ;"             Concatenate all strings in A with themselves.
         f            Filter; yield all results that belong to A as well.

7

Retina , 28 bayt

+%1`1
R$'¶$`P$'¶$`S
A`(.+)\1

Çevrimiçi deneyin!

Girişi Alır tekli içinde .

açıklama

+%1`1
R$'¶$`P$'¶$`S

Bu , uzunluktan oluşan tüm dizeleri oluşturur . Bunu yapma şeklimiz , her satırdaki ilkini tekrar tekrar değiştirmemizdir . En olarak çizgi düşünelim , maçın önüne her şeydir ve maçtan sonra her şey (onlar konum ve sırasıyla düzenli ifade ikamesi sözdizimi içinde, ancak bu bakış az sezgisel). Biz yerini ile nerede, linefeeds bulunmaktadır. Yani bu ikame tam sonuç aslında ile, hattın üç nüsha olan ile değiştirin , , sırasıyla üç nüsha her birinde. Bu işlem, hepsi değiştirildikten sonra durur .RPSn1<1><>$`$'1R>¶<P>¶<S<R>¶<P>¶<S>1RPS1

A`(.+)\1

Son olarak, tekrarı içeren tüm satırları atıyoruz.


Ben defalarca değiştirilen olurdu 1(.*)ile $1R¶$1P¶$1Sancak bayt sayısı aynıdır.
Neil,

6

Kabuğu , 15 14 bayt

Zgarb sayesinde -1 bayt!

fȯεfoE½QΠR"RPS

Çevrimiçi deneyin!

Doğru uzunlukta tüm olası dizileri oluşturur ve yalnızca tüm alt dizileri (boş olan hariç) iki farklı yarıdan oluşan dizileri tutar.

Kahretsin, Jelly'i burada yenmek istedim.


3
Jelly ile bağlamak için 14 bayt .
Zgarb


5

Java 8, 285 277 bayt

import java.util.*;Set r=new HashSet();n->p("",((1<<3*n)+"").replaceAll(".","PRS"),n)void p(String p,String s,int n){int l=s.length(),i=0;if(l<1&&(s=p.substring(0,n)).equals(s.replaceAll("(.*)\\1","")))r.add(s);for(;i<l;p(p+s.charAt(i),s.substring(0,i)+s.substring(++i,l),n));}

Java neredeyse her zaman ayrıntılı olmasına rağmen, bu durumda kesinlikle böyle bir meydan okuma için doğru dil değildir. Alt dizilerle permütasyon oluşturmak performans açısından yetersiz ve verimsizdir.

Yine de kesinlikle biraz daha golf oynanabilir.

-Jakob sayesinde -8 bayt .

Açıklama:

Burada dene. (Performans 3'ün üzerindeki test durumları için çok kötü, ancak yerel olarak çalışıyor ..)

import java.util.*;   // Required import for Set and HashSet

Set r=new HashSet();  // Result-Set on class-level

n->                   // Method with integer parameter and no return-type
  p("",((1<<3*n)+"").replaceAll(".","PRS"),n)
                      //  Get all permutations and save them in the Set
                      // End of method (implicit / single-line return-statement)

void p(String p,String s,int n){
                      // Separated method with 2 String & int parameters and no return-type
  int l=s.length(),   //  The length of the second input-String
      i=0;            //  Index-integer, starting at 0
  if(l<1              //  If the length is 0,
     &&(s=p.substring(0,n)).equals(s.replaceAll("(.*)\\1","")))
                      //  and it doesn't contain a repeated part:
    r.add(s);         //   Add it to the result-Set
  for(;i<l;           //  Loop (2) from 0 to `l`
    p(                //   Recursive-call with:
      p+s.charAt(i),  //    Prefix-input + the character of the second input at index `i`
      s.substring(0,i)+s.substring(++i,l),
                      //    and the second input except for this character
      n)              //    and `n`
  );                  //  End of loop (2)
}                     // End of separated method

1
Bu nasıl lambda hakkında: n->p("",((1<<3*n)+"").replaceAll(".","PRS"),n). Ayrıca, neden değil refactor for(;i<1;p(...));için while(i<l)p(...);?
Jakob

@ Jakob Teşekkürler. Ve ben her zaman for(;...;)dürüst olmak gerekirse kodlama-hobbit dışından kullanırım . En kötü durum, aynı bayt sayımıdır while(...), en iyi durum baytları kurtarmak için for-döngüsüne bir şey yerleştirilebilir. Bu yüzden whilekod kodlamada hiç kullanmamaya çalışıyorum, çünkü hiçbir zaman byte-count'e asla fayda sağlamaz. Ya arttırır ya da aynı kalır, bu yüzden şahsen daha iyi okunabilirlikle uğraşmıyorum. ;)
Kevin Cruijssen

1
Evet, golf kodumu belirli bir bayt sayısında mümkün olduğunca okunaklı kılmaya çalışıyorum. Muhtemelen boşuna bir takip!
Jakob

Bekle, lambda gerçekten burada mı çalışıyor? Biraz dikkatsizdim ... Bu bir n PRS dizisi üretir, oysa asıl döngünüz 2 ^ ( n -2) dizisi olan bir tane üretti .
Jakob

@ Jakob nkez "PRS" doğru. Maden daha fazla üretiyordu çünkü baytları kurtardı (ve performansı düşürdü, ama bunu kodlayıcı ile umursayan). ;)
Kevin Cruijssen



4

Perl 5 , 37 bayt

sub r{grep!/(.+)\1/,glob"{R,S,P}"x<>}

Çevrimiçi deneyin!

İşlev, kare serbest dizgelerin bir dizisini döndürür.

Açıklaması:

globGirişine eşit uzunlukta R, S, ve P tüm kombinasyonlarını üretir. Bu grepifade, kare olmayanları filtrelemektedir.


Brace genişlemesinin mükemmel kullanımı!
Dom Hastings

3

R , 97 bayt

cat((x=unique(combn(rep(c('p','r','s'),n),n<-scan(),paste,collapse='')))[!grepl("(.+)\\1",x,,T)])

Çevrimiçi deneyin!

combn(rep(c('p','r','s'),n),n,paste,collapse='')Bütün hesaplar nile karakterlik dizeleri p, r, sama ne yazık ki biz onu uniquify ve normal ifade eşleşmesi olanlar almak o kadar çok (*), kopyalar (.+)\1perl tarzı eşleme özelliğini kullanarak, o zaman çıkan liste çıktı.

(*) teknik olarak, 3nharflerin tüm kombinasyonlarını bir defada p,r,s3 kez tekrarlanan şekilde üretir n, ardından doğrudan dizeleri paste(..., collapse='')hesaplamak yerine her bir kombinasyona uygulanır 3^n, ancak bu bir expand.grid(gerçek Kartezyen ürünü) ' dan daha golfcüdür .


3

JavaScript (Firefox 30-57), 69 bayt

f=n=>n?[for(x of f(n-1))for(y of'RPS')if(!/(.+)\1/.test(y+=x))y]:['']

Tüm kare içermeyen kelimelerin alt dizeleri de kare içermez olduğundan kontrol tekrarlı olarak yapılabilir.



2

JavaScript (ES6), 93 bayt

n=>[...Array(3**n)].map(g=(d=n,i)=>d?'RPS'[i%3]+g(d-1,i/3|0):'').filter(s=>!/(.+)\1/.test(s))

Tüm sayıları 0 - 3ⁿ ((yastıklı yastıklı)) taban (3) kullanarak RPSrakam olarak kullanır ve kare içermeyen kelimeler için filtreler.


2

Julia, 88

f(n)=[filter(A->!ismatch.(r"(.+)\1",join(A)),Iterators.product(repeated("RPS",n)...))...]

Hiçbir şey fantezi.


1

C # / LINQ, 169

Enumerable.Range(0,(int)Math.Pow(3,n)).Select(i=>string.Concat(Enumerable.Range(1,n).Select(p=>"PRS"[(i/(int)Math.Pow(3,n-p))%3]))).Where(s=>!Regex.IsMatch(s,@"(.+)\1"))

Bunu yapmanın daha iyi bir yolu olmalı :)



1

k, 56 bayt

f:{$[x;(,/"RPS",/:\:f x-1){x@&~~/'(2,y)#/:x}/1_!x;,""]}

Yerel regex eksikliği k'yı bir kez daha eğrinin arkasına koyuyor. Özyinelemeli bir çözüm kullandım, çünkü onu uygulayacak karakterler daha basit bir kare ücretsiz kontrolle kaydedildi.

$[ test ; if-true ; if-false ]

k'nin üçlü operatörüdür, burada sıfır olmayan uzunluk için ilginç şeyler yaparız ve sıfır uzunluklu kelimeler istenirse tek bir boş dize döndürürüm.

(,/"RPS",/:\:f x-1)

"RPS" nin kartezyen ürününü ve tüm n-1 uzunluk kare içermeyen kelimeleri alır. , /: \: sağdaki her bir öğeyi sola birleştirerek bir uzunluk 3 dizisi verir. , / bunu bir uzunluk 3n dizisine düzleştirir.

{x@&~~/'(2,y)#/:x}

her dizginin ilk n harfini alır ve onu ikinci n ile karşılaştırır, daha sonra diziyi yalnızca uyuşmadıkları yerlere indirger. Önceki sonucun karesiz olduğunu bildiğimiz için, yalnızca ilk karakterden başlayan alt dizilerin eşleşmeye ihtiyacı var - buradaki kontrolü basitleştirmek, özyineleme uygulamak için harcanan karakterlere değdi. En sonunda,

/1_!x

lambda'yı, her alt dize uzunluğu boyunca 1 ila (kelime uzunluğu) -1 arasında yinelenen, sola ayarlanan ilk sonuca uygular. ! x, 0'dan x-1'e bir liste oluşturur, ardından 1_ ilk öğeyi kaldırır (çünkü 0 uzunluklu alt diziler her zaman eşleşir)

Birkaç karakterden fedakarlık yaparak .zs işlev ismine güvenmek yerine kendi kendine referans vermek için kullanabiliriz ve n-1 uzunluğuna kadar olan alt dizileri kontrol etmek yerine performans için zemini (n / 2) kontrol edin. Tüm uzunluğu 49 kelimeyi (bunun 5207706 olan) bir 7700k üzerinde yaklaşık 120 saniyede bulur, bunun üstünde 4GB serbest 32-bit k sınırına rastlarım.

{$[x;(,/"RPS",/:\:.z.s x-1){x@&~~/'(2,y)#/:x}/1+!_x%2;,""]}

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.