Olası Her Döngü Uzunluğu


21

Girdileri alan ve çıktıları sağlayan bir fonksiyonun (veya program), fonksiyonu tekrar tekrar kendi kendine çağırırsanız, sonunda orijinal numaraya ulaşması durumunda bir döngüye sahip olduğu söylenebilir. Örneğin, aşağıdaki işlevi alın:

Input:  n    1 2 3 4 5 6
Output: f(n) 5 7 1 3 4 9

Biz başlarsanız n=1, f(n)=5, f(f(n))=f(5)=4, f(f(f(n)))=f(4)=3, f(f(f(f(n))))=f(3)=1.

Bu yazılmıştır (1 5 4 3). Bu döngüde 4 benzersiz sayı olduğundan, bu 4 uzunluğundaki bir döngüdür.


Buradaki zorluk, mümkün olan her uzunluğa sahip döngüleri olan bir program veya işlev yazmaktır. Yani, uzunluk 1, uzunluk 2 gibi bir döngü olmalıdır.

Ayrıca, işlev / program pozitif tamsayılar için pozitif tamsayılar olmalıdır ve bu olmalı bijective tüm pozitif tamsayılar üzerinde, mümkün olan her çıkış değeri için tam olarak bir giriş değeri olmalıdır, yani. Başka bir deyişle, fonksiyon / program pozitif tamsayıların geçirgenliğini hesaplamalıdır.


Ayrıntılar: STDIN, STDOUT, fonksiyon argümanı, return, vb. Dahil olmak üzere herhangi bir standart giriş / çıkış sistemine izin verilir. Standart boşluklar yasaktır.

Veri türlerinizin sınırlamaları hakkında endişelenmenize gerek yoktur; yukarıdaki özelliklerin yalnızca örneğin bir değere intveya floatherhangi bir değere sahip olabileceği varsayımı altında tutulması gerekir .

Fonksiyonun pozitif tamsayı olmayan girdiler üzerindeki davranışında herhangi bir kısıtlama yoktur ve bu girdiler / çıktılar dikkate alınmaz.


Puanlama bayt cinsinden kod golfüdür, en kısa kod kazanır.


"uzunluğu 1, uzunluğu 2 olan bir döngü olmalı ve böyle" Bu yorumlanmalı mı "şeklinde yorumlanmalı" en az uzunluk 1 olmalı , uzunluk 2 en az biri olmalı, vs. " tam olarak bir uzunluk 1, bir uzunluk 2 ve benzeri bir döngü olabilir ".
Bakuriu

@Bakuriu Her pozitif uzunluktaki en az bir döngü.
isaacg

Yanıtlar:


11

Pyth, 11 8 bayt

.<W-0zz1

Önceki cevabımdan çok daha sıkıcı.

0 basamak içeren her sayı kendisine eşlenir. Başka herhangi bir sayı, rakamları 1 ile döndürülen sayıya eşlenir. Örneğin:

1 -> 1
10 -> 10
15 -> 51 -> 15
104 -> 104
123 -> 231 -> 312 -> 123

8

Python 2, 56 55 54 bayt

n=input()
a=b=1
while a+b<=n:a+=b;b+=1
print(n+~a)%b+a

İşte ilk 21 çıktı:

[1, 3, 2, 6, 4, 5, 10, 7, 8, 9, 15, 11, 12, 13, 14, 21, 16, 17, 18, 19, 20]

Listeyi böyle parçalara ayırırsak, örüntü açıktır:

 1    2  3    4  5  6    7  8  9  10    11  12  13  14  15    16  17  18  19  20  21
[1]  [3, 2]  [6, 4, 5]  [10, 7, 8, 9]  [15, 11, 12, 13, 14]  [21, 16, 17, 18, 19, 20]

Kahretsin, bu benim de uğraştığım kalıp, ancak kapalı bir formda.
orlp

1
İlginç .. a-değerleri A000124 dizisini takip eder . Ama sanırım bunu zaten biliyordun: P
Kade

Bu dizinin oeis.org/A066182 olduğunu unutmayın .
orlp

8

Pyth, 25 bayt

+hK/*J/h@h*8tQ2 2tJ2%-QKJ

Bu, @ Sp3000 ile aynı dizilimdir, ancak kapalı bir şekildedir. Kapalı form:

M (n) = kat ((1 + m² (1 + 8 * (n - 1))) / 2) B (n) = M (n) * (M (n) -1) / 2 f (n) = B (n) + ((n - B (n) + 1) M (n))


5

Python3, 40 bayt

n=input();print([n[1:]+n[0],n]['0'in n])

0 basamak içeren her sayı kendisine eşlenir. Başka herhangi bir sayı, rakamları 1 ile döndürülen sayıya eşlenir. Örneğin:

1 -> 1
10 -> 10
15 -> 51 -> 15
104 -> 104
123 -> 231 -> 312 -> 123

1
Déjà vu! İki dilde görmek için harika!
Denham Coote

3

Ruby, 22 + 1 = 23

Komut satırı işaretiyle -pçalıştır

~/(.)(.?)/
$_=$1+$'+$2

Girdi olarak verildiğinde, bir sayının dizgi gösterimi (takip eden yeni satır olmadan), ilk haneyi sabit tutar, sonra kalanı sola döndürür, böylece 1234olur 1342.

Bu, 21 karaktere kadar azaltılabilir $_=$1+$'+$2if/(.)(.)/, ancak bir uyarı yazdırır.


3

Ruby, 16 + 1 = 17

Komut satırı işaretiyle -pçalıştır

$_=$_[/.0*$/]+$`

Bu benim diğer cevabımdan daha karmaşık bir işlev, ancak daha golf oynuyor (ve takip eden yeni hatlara toleranslı) oluyor. Bu, girişin sıfır olmayan basamağını ve bunun ardından gelen sıfırları alır ve sayının başına taşır. Böylece 9010300olur 3009010. Sıfır olmayan n basamağı olan herhangi bir sayı, n uzunluk döngüsünün bir parçası olacaktır.

Giriş, herhangi bir tabanda STDIN aracılığıyla bir dizedir, çıktı bu tabanda bir dizedir.


2

Python, 43

SP3000 en fonksiyonun tersi , yinelemeli uyguladı.

f=lambda n,k=1:n>k and k+f(n-k,k+1)or n%k+1

Fonksiyon bir döngü izler, ardından iki döngü izler, üç döngü izler ...

(1)(2 3)(4 5 6)(7 8 9 10)(11 12 13 14 15)...

İşlem sayılar üzerinde n%k+1bir kdöngü gibi davranır 1..k. Kullanmak için uygun olanı bulmak için k, her şeyi k=1, ardından k=2, vb. Kadar aşağıya kaydırın n<=k.


2

Pyth, 15 bayt

Şimdiye kadarki en kısa cevap, string işlemleri yerine sayısal işlemleri kullanan.

.|.&Q_=.&_=x/Q2

    Q                input
            /Q2      input div 2
           x   Q     that XOR input
          =          assign that to Q
         _           negate that
       .&       Q    that AND Q
      =              assign that to Q
     _               negate that
  .&                 input AND that
.|               Q   that OR Q

Bu fonksiyonun ikili gösterime etkisi, 1'lerin en sağ bloğunu bir sonraki 0'a genişletmektir; veya 0 yoksa, tek bir 1'e sıfırlamak için:

10010110100000 ↦  
10010110110000 ↦  
10010110111000 ↦  
10010110111100 ↦  
10010110111110 ↦  
10010110111111 ↦
10010110100000  

Pyth, 26 bayt, eğlenceli değişken

.|.&Q_h.&/Q2+Qy=.&/Q2_h.|y

    Q                           input
         /Q2                    input div 2
             Q                  input
                  /Q2           input div 2
                         yQ     twice input
                       .|  Q    that OR input
                     _h         NOT that
                .&              (input div 2) AND that
               =                assign that to Q
              y                 twice that
            +                   input plus that
       .&                       (input div 2) AND that
     _h                         NOT that
  .&                            input AND that
.|                          Q   that OR Q

Gerçekleştirir aynı anda yukarıdaki işlem tüm 1'lerin blokları, sadece en sağdaki tek hala sadece bitsel kullanarak ve aritmetik işlemler.

1000010001001 ↦
1100011001101 ↦
1110011101001 ↦
1111010001101 ↦
1000011001001 ↦
1100011101101 ↦
1110010001001 ↦
1111011001101 ↦
1000011101001 ↦
1100010001101 ↦
1110011001001 ↦
1111011101101 ↦
1000010001001

1

Swift 1.2, 66 bayt

func a(b:Int){var c=0,t=1,n=b
while n>c{n-=c;t+=c++}
print(n%c+t)}
Input:  1,   2, 3,  4, 5, 6,   7, 8, 9, 10,   11, 12, 13, 14, 15
Output: 1,   3, 2,  5, 6, 4,   8, 9, 10, 7,   12, 13, 14, 15, 11

1

Brachylog , 5 bayt

∋0&|↺

Çevrimiçi deneyin!

@ Orlp'nin Pyth cevabının limanı. Basit ve temiz çıkıyor:

∋0    % If input contains a 0 (since input is a single number, "contains" ∋ treats it as an array 
      %   of its digits, so this means "if any of input's digits are 0")
&     % Then output is the input
|     % Otherwise
↺     % Circularly shift the input once, and unify that with the output

Başlangıçta Sp3000 Python çözümü @ port istedim, ancak bir kuyruklu 23 bayt aldı :

⟧∋B-₁⟦++₁A≤?;A--₁;B%;A+

Çevrimiçi deneyin!


0

JavaScript (ES6), 43 bayt

f=(n,i=1,j=1)=>n>j?f(n,++i,j+i):n++<j?n:n-i

0

Matlab (189)

  function u=f(n),if(~n|n==1)u=n;else,u=n;y=factor(n);z=y(y~=2);if ~isempty(z),t=y(y~=max(y));if isempty(t),u=y(end)*2^(nnz(y)-1);else,g=max(t);e=primes(g*2);u=n/g*e(find(e==g)+1);end,end,end

  • İşlev:

    Asal çarpanlarına göre herhangi bir tamsayıyı eşler, sayı sıfır veya 2 ya da 1'e çarpanlara ayrılırsa, sayı kendisine eşlenir, aksi takdirde bu sayının en büyük asal çarpanını seçeriz, ardından kalan farklı asal çarpanları en yakın artırırız. Daha büyük asal faktör sayısını ulaşıncaya kadar biz bu miktarı ulaştığında tüm faktörlerin hepsini üslerin toplamına eşittir, biz dönüp ve tekrar aynı döngüyü yeniden.biggest_prime^nnmax_prime*2^(n-1)


0

Matlab (137)

  function u=h(n),if(~n|n==1)u=n;else,u=n;y=factor(n);z=y(y~=2);if~isempty(z),e=nnz(y);f=nnz(z);if(~mod(e,f)&e-f)u=n/2^(e-f);else,u=u*2;end

  • Biraz benzer bir yaklaşım, {0,1,2 ^ n} 'e eşit olmayan herhangi bir sayıyı, bir üssünde 2tökezleyene kadar 2diğer asal faktörlerin üstlerinin toplamı ile bölünebilene kadar kademeli olarak çarparak . daha sonra bölünerek döngünün başına gideriz 2^(sum of exponents of other primes). diğer numaralar kendilerine eşlenir.
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.