Collatz benzeri dizileri analiz etme


12

4 pozitif tamsayı ile Collatz benzeri bir sıra tanımlıyoruz s:

  • n başlangıç ​​değeri
  • d > 1 bölen
  • m > 1 çarpan
  • i artım

(Orijinal Collatz sırasında d = 2 m = 3ve i = 1.)

Verilen bu tamsayılar saşağıdaki şekilde oluşturulacaktır:

  • s(0) = n
  • eğer k > 0ve s(k-1) mod d = 0sonras(k) = s(k-1) / d
  • eğer k > 0ve s(k-1) mod d != 0sonras(k) = s(k-1) * m + i

İle bir örnek dizisi d = 2, m = 3, i = 5ve n = 80olacak s = 80, 40, 20, 10, 5, 20, 10, 5, 20, ....

Her sekans, verilen herhangi bir sınırdan daha yüksek değerlere ulaşacaktır (yani sekans ıraksaktır) veya bazıları tve u( t!=u) için s(t) = s(u)eşitlik doğru olacaksa sonsuz bir döngüye girecektir.

Bizim sorunumuzda, bir dizi elemanının değeri, bu 10^9elemandan önce eleman tekrarından daha büyükse veya hiç değilse 1000, sekans ıraksak olarak kabul edilir.

Görev

Bu pozitif tamsayılar alan bir program ya da işlevi yazmak gerekir d mve igiriş ve çıkış olarak başlangıç değerleri dizileri (sonsuz döngüler ve sapma) tüm farklı bitiş türleri n = 1, 2, 3, ... 999, 1000üretebilir.

Giriş ayrıntıları

  • Girdi bir dize veya liste (veya kendi dilinizde yakın eşdeğer) temsil eden (ortak şekilde) üç pozitif tamsayılar olduğu d, mve ibu sırayla. dve men azından 2. Her iki sayı da büyük değildir 100.

Çıktı ayrıntıları

Çıktı özellikleri biraz garip. Önce örnekleri incelemeye değer olabilir.

  • Standart çıktıya (veya en yakın alternatife) çıktı almalı veya bir dize döndürmelisiniz.
  • Eğer ıraksak sekans mümkünse ilk satır olmalıdır DIVERGENT.
  • Bir dizinin döngüsünün benzersiz bir temsili, en küçük sayının boşluklarla ayrılan son sayı olduğu dönüştür. Örneğin s = 2 1 4 2 1 4 2 1, döngü ise 4 2 1.
  • Takip eden her satırda, her bir benzersiz döngüyü tam olarak sözcüğün önünde bir kez çıkarmalısınız LOOP. ÖrneğinLOOP 4 2 1
  • Döngüler, son elemanlarına göre artan sırada olmalıdır.
  • Sondaki satır başı isteğe bağlıdır.

Örnekler:

İlk satırlar girişlerdir ve sonraki satırlar boş satır çıkana kadar.

2 3 1
LOOP 4 2 1

2 2 6
LOOP 8 4 2 1
LOOP 12 6 3

3 7 8
DIVERGENT
LOOP 15 5 43 309 103 729 243 81 27 9 3 1
LOOP 22 162 54 18 6 2
LOOP 36 12 4

3 9 1
DIVERGENT

6 9 9
DIVERGENT
LOOP 18 3 36 6 1
LOOP 27 252 42 7 72 12 2
LOOP 45 414 69 630 105 954 159 1440 240 40 369 3330 555 5004 834 139 1260 210 35 324 54 9 90 15 144 24 4
LOOP 81 738 123 1116 186 31 288 48 8
LOOP 99 900 150 25 234 39 360 60 10
LOOP 126 21 198 33 306 51 468 78 13

10 10 10
LOOP 20 2 30 3 40 4 50 5 60 6 70 7 80 8 90 9 100 10 1

93 91 92
DIVERGENT
LOOP 2185 198927 2139 23
LOOP 4278 46

Ideone üzerinde Python 3'te referans uygulaması.

Bu kod golf çok kısa giriş kazanır.

Yanıtlar:


5

Python 3, 269 254 252 246 bayt

d,m,i=eval(input())
S=set()
for n in range(1,1001):
 T=X=()
 while len(T)**3<1e9>=n:
  T=(n,)+T;n=[n//d,n*m+i][n%d>0]
  if n in T:I=T.index;L=T[:I(n)+1];M=I(min(L));X=L[M:]+L[:M]
 S|={X}
for x in sorted(S):print(x and"LOOP"or"DIVERGENT",*x[::-1])

(Şimdi birkaç bayt kaydetmek için 10 kat daha yavaş. Tipik kod golf.)

STDIN üzerinden bir liste girin (örn. [2, 3, 1]). Döngüleri standartlaştırmanın daha iyi bir yolu olması gerektiğini düşünüyorum ...

Yaklaşım oldukça basittir - 1000 sayının tamamını test edin ve sadece benzersiz çıktıları alın. Ancak, orada iki küçük hile var:

  • Döngüler, boş olmayan tuples ile temsil edilir, ancak daha da önemlisi, diverjans boş bir tuple ile temsil edilir . Bu iyi çünkü:

    • Bu kesilmez sorted, hatta görünecektir önce tüm döngü küpe
    • Aracılığıyla bir dize seçmemize izin verir x and"LOOP"or"DIVERGENT"
    • *()[::-1] etkilemez print
  • Döngüler geriye doğru "son öğeye göre sırala" yı "lambayı ilk sıraya göre sırala" ya dönüştürerek lambda geçirme ihtiyacını ortadan kaldırır sorted.

Önceki gönderim, 252 bayt

d,m,i=eval(input())
def f(n,T=()):
 x=[n//d,n*m+i][n%d>0];I=T.index
 if x in T:L=T[:I(x)+1];M=I(min(L));return L[M:]+L[:M]
 return()if(T[1000:]or x>1e9)else f(x,(x,)+T)
for x in sorted(set(map(f,range(1,1001)))):print(x and"LOOP"or"DIVERGENT",*x[::-1])

Bu çok daha hızlı.

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.