Keyfi rastgele


26

Rastgele eğlencelidir. Puansız zorluklar eğlencelidir.

Bir işlev Yazın, bu tam sayı giriş verilen n, çıktısı bir dizi Tam olarak (düzensiz, benzersiz) narasında rasgele tamsayı 1ve n^2sayıların toplamı eşittir (dahil) bu tür olduğu n^2.

Her geçerli setin sıfır şansı olmayan bir şans olması koşuluyla, rastgelelik tekdüze olmak zorunda değildir .

Bayt cinsinden en kısa cevap (her dilden) kazanır.

Örnekler

Input (n) = 1, Target (n^2) = 1
Sample of possible outputs:
1

Input = 2, Target = 4
Sample of possible outputs:
3, 1
1, 3

Input = 3, Target = 9
Sample of possible outputs:
6, 1, 2
3, 5, 1
4, 3, 2

Input = 4, Target = 16
Sample of possible outputs:
1, 3, 5, 7
2, 4, 1, 9
8, 3, 1, 4

Input = 5, Target = 25
Sample of possible outputs:
11, 4, 7, 1, 2
2, 3, 1, 11, 8
6, 1, 3, 7, 8

Input = 8, Target = 64
Sample of possible outputs:
10, 3, 9, 7, 6, 19, 8, 2
7, 16, 2, 3, 9, 4, 13, 10
7, 9, 21, 2, 5, 13, 6, 1

Bonus Görevi: Verilen izinlerin geçerli sayısını hesaplamak için bir formül var mı n?


2
ilgili , ancak oldukça farklı
Giuseppe

1
(p / s: Hızlı bir algoritmaya sahipseniz ancak daha fazla bayt alıyorsa, yayınlamak için hız baskısının (şu anda sanal alanda)
beklemesini bekleyin

1
@EriktheOutgolfer Tüm kümeleri oluşturmaktan ve rastgele bir seçim yapmaktan (çok) daha iyi yollar olmasına rağmen, uygulanması daha zordur ve muhtemelen daha uzundur. Onları hız baskısı için sakla.
user202729

2
Set sayısı OEIS A107379'dur .
nwellnhof

1
Her ikiside. Yoruma bakın "Ayrıca n ^ 2'nin n farklı bölümlere bölünme sayısı."
nwellnhof

Yanıtlar:


9

Brachylog (v2), 15 bayt (rastgele) veya 13 bayt (tüm olasılıklar)

rasgele

~lℕ₁ᵐA+√?∧A≜₁ᵐ≠

Çevrimiçi deneyin!

İşlev sunumu (TIO'da tam bir program haline getiren bir sarmalayıcı ile görülür).

açıklama

~lℕ₁ᵐA+√?∧A≜₁ᵐ≠
~l               Specify a property of a list: its length is equal to the input,
    ᵐ              and it is composed entirely of
  ℕ₁                 integers ≥ 1,
       √           for which the square root of the
      +              sum of the list
        ?              is the input.
     A   ∧A      Restricting yourself to lists with that property,
           ≜₁      pick random possible values
             ᵐ       for each element in turn,
              ≠    until you find one whose elements are all distinct.

Tüm olasılıklar

~lℕ₁ᵐ<₁.+√?∧≜

Çevrimiçi deneyin!

Mümkün olan tüm çıktıları üreten İşlev gönderme .

açıklama

~lℕ₁ᵐ<₁.+√?∧≜
~l               Specify a property of a list: its length is equal to the input,
    ᵐ              it is composed entirely of
  ℕ₁                 integers ≥ 1,
     <₁            it is strictly increasing,
         √         and the square root of the
        +            sum of the list
          ?            is the input.
       .   ∧≜    Generate all specific lists with that property.

İşe ∧≜yaradığına oldukça şaşırdım (normalde ∧~≜girdi yerine girdiyi zorlamak için yazmak zorunda kalacaksınız ), ancak girdi çıktı çıktı çıktısı = çıktı varsayımı yani hangi yöne gideceğiniz önemli değil Koş.

Bonus görevi

Olasılıkların sayısı hakkında bir fikir edinmek için, çıkış sayımlarının sırasını vermek için programı ardışık tamsayılarda çalıştıran farklı bir TIO sargısı oluşturdum :

1,1,3,9,30,110,436,1801,7657,33401

OEIS'e yapılan bir gezi, bunun hali hazırda A107379 adlı , bilinen bir dizi olduğunu keşfeder (görünüşte garip sayılarla sınırlarsanız, aynı diziyi elde edersiniz). Sayfa, dizi için birkaç formül listeler (hiçbiri özellikle basit olmasa da, ikincisi değer için doğrudan bir formül gibi görünür, ancak gösterimi anlamıyorum).


İkinci formül "katsayısı x^(n*(n-1)/2)serisi genişleme Product_{k=1..n} 1/(1 - x^k)" (hepsi direkt değil, maalesef)
user202729

"Tamamen farklı" kısıtlamanın rastgele etiketleme adımından (örneğin A≠≜₁ᵐ) önce yerleştirilmesi , çalışma süresini ortalama olarak daha hızlı yapar.
18'de 8

Bunu neden bir topluluk wiki yaptığını anlamıyorum. Bunlar, düzenlemeyi mümkün kılmadan önce düzenlenebilir yayınlara sahip olmanın eski bir yoludur.
boru


7

05AB1E , 11 bayt

nÅœʒDÙQ}sùΩ

Çevrimiçi deneyin veya tüm test durumlarını doğrulayın .

Açıklama:

n             # Take the square of the (implicit) input
              #  i.e. 3 → 9
 Ŝ           # Get all integer-lists using integers in the range [1, val) that sum to val
              #  i.e. 9 → [[1,1,1,1,1,1,1,1,1],...,[1,3,5],...,[9]]
   ʒ   }      # Filter the list to only keep lists with unique values:
    D         # Duplicate the current value
     Ù        # Uniquify it
              #  i.e. [2,2,5] → [2,5]
      Q       # Check if it's still the same
              #  i.e. [2,2,5] and [2,5] → 0 (falsey)
        s     # Swap to take the (implicit) input again
         ù    # Only leave lists of that size
              #  i.e. [[1,2,6],[1,3,5],[1,8],[2,3,4],[2,7],[3,6],[4,5],[9]] and 3
              #   → [[1,2,6],[1,3,5],[2,3,4]]
          Ω   # Pick a random list from the list of lists (and output implicitly)


5

R , 68, 75 48 bayt (rastgele) ve 70 bayt (deterministik)

@ Giuseppe'nin ret örnekleme yöntemi:

function(n){while(sum(F)!=n^2)F=sample(n^2,n);F}

Çevrimiçi deneyin!

Golf orijinali:

function(n,m=combn(1:n^2,n))m[,sample(which(colSums(m)==n^2)*!!1:2,1)]

Çevrimiçi deneyin!

*!!1:2İş garip bir yol kaçınmaktır sampleİlk argüman uzunluğu 1 olduğunda hareket.


@Giuseppe :-) "sabit"
NGM

çok hoş. kullanarak pyerine onu hesaplanması ve bazı bayt kaydetmek gerekir yeniden kullanmanın bir endeks olarak doğrudan.
Giuseppe

1
Bende function(n){while(sum(F)!=n^2)F=sample(n^2,n);F}48 tane var ...
Giuseppe

1
Gibi bir şey ararken J.Doe @ sorunu önlemek için sample(2,1)birlikte olur ki n=2. Bu yüzden rep, bunun asla olmayacağının garantisi. Daha iyi bir yol olabilir ama bu hızlıydı ve ben de kızmıştım sample.
NGM

1
Meta sorunuz bir hayır alırsa , x*!!1:2üzerinde bir byte kaydedebilirsiniz rep(x,2).
J.Doe


4

Java 10, 250 242 222 bayt

import java.util.*;n->{for(;;){int i=n+1,r[]=new int[i],d[]=new int[n];for(r[n<2?0:1]=n*n;i-->2;r[i]=(int)(Math.random()*n*n));var S=new HashSet();for(Arrays.sort(r),i=n;i-->0;)S.add(d[i]=r[i+1]-r[i]);if(!S.contains(0)&S.size()==n)return S;}}

@Nwellnhof sayesinde -20 bayt .

Dikkatli olun, Java geliyor ... Diğer dört cevap birleştikçe beş kez 'sadece' oluyor, bu yüzden çok da kötü değil sanırım .. rofl.
Yine de 2 saniyeden daha az bir sürede (birleştirilmiş) n=1geçiyor n=25, bu yüzden muhtemelen bu zorluğun hız versiyonuna (şu anda hala Sandbox'ta) değiştirilmiş bir versiyonunu göndereceğim.

Çevrimiçi deneyin.

Açıklama:

Sahte kodda aşağıdakileri yaparız:

1) boyutunda bir dizi oluşturmak n+1: aşağıdakileri içeren 0, nkare ve n-1aralığında rastgele tam sayı miktarı [0, n squared)
2) kriteri bu dizi
3) boyutu bir ikinci dizi oluşturma nçifti ön farkları ihtiva eden
Bu ilk üç adım bize içeren bir dizi verecek nRasgele tamsayılar ( kare [0, n squared)toplamı aralığındadır n.
4a) Rastgele değerlerin tümü benzersiz değilse veya bunlardan herhangi biri 0 ise: 1
4b adımından tekrar deneyin ) Başka: sonuç olarak bu farklılıklar dizisini döndür

Asıl kod gelince:

import java.util.*;      // Required import for HashSet and Arrays
n->{                     // Method with int parameter and Set return-type
  for(;;){               //  Loop indefinitely
    int i=n+1,           //   Set `i` to `n+1`
        r[]=new int[i];  //   Create an array of size `n+1`
    var S=new HashSet(); //   Result-set, starting empty
    for(r[n<2?           //   If `n` is 1:
           0             //    Set the first item in the first array to:
          :              //   Else:
           1]            //    Set the second item in the first array to:
             =n*n;       //   `n` squared
        i-->2;)          //   Loop `i` in the range [`n`, 2]:
      r[i]=              //    Set the `i`'th value in the first array to:
           (int)(Math.random()*n*n); 
                         //     A random value in the range [0, `n` squared)
    for(Arrays.sort(r),  //   Sort the first array
        i=n;i-->0;)      //   Loop `i` in the range (`n`, 0]:
      S.add(             //    Add to the Set:
        r[i+1]-r[i]);    //     The `i+1`'th and `i`'th difference of the first array
    if(!S.contains(0)    //   If the Set does not contain a 0
       &S.size()==n)     //   and its size is equal to `n`:
      return S;}}        //    Return this Set as the result
                         //   (Implicit else: continue the infinite loop)

1
n=252 saniyenin altında bir sürede etkileyici! Açıklamayı okumak ve nasıl yaptığını görmek zorunda kalacağım. Hala bir bruteforce yöntemi midir?
Skidsdev

Üniforma mı? -
user202729

@ user202729 Bunu nasıl kanıtlayacağımdan emin olmama rağmen, sanırım öyle. Java yerleşimi tekdüzedir ve bunu [0, n squared)ilk aralıkta rastgele değerler elde etmek için kullanır ve ardından sıralanan rastgele değerler arasındaki farkları hesaplar ( 0satır başı ve izler dahil n squared. Bu farklılıkların aynı olduğundan eminim. Ama yine de , bunu kanıtlamak için nasıl emin değilim rastgelelik tutarlılığı tbh gerçekten benim uzmanlık değil..
Kevin Cruijssen

3
Farklılıklar dizisinden asla okumaz dmısın yoksa bir şey mi özlüyorum?
nwellnhof


4

Perl 6 , 41 bayt

{first *.sum==$_²,(1..$_²).pick($_)xx*}

Çevrimiçi deneyin!

  • (1 .. $_²) Giriş numarasının 1 ile 1 arasındaki kareler
  • .pick($_) rastgele bu aralığın ayrı bir altkümesini seçer.
  • xx * önceki ifadeyi sonsuza dek kopyalar
  • first *.sum == $_² giriş numarasının karesini toplayan bu numara kümelerinin ilki seçer


2

Pyth, 13 12 bayt

Ofq*QQsT.cS*

Burada çevrimiçi deneyin . Çevrimiçi tercümanın 5'ten büyük girişler için bir MemoryError ile çalıştığını unutmayın.

Ofq*QQsT.cS*QQQ   Implicit: Q=eval(input())
                 Trailing QQQ inferred
          S*QQQ   [1-Q*Q]
        .c    Q   All combinations of the above of length Q, without repeats
 f                Keep elements of the above, as T, where the following is truthy:
      sT            Is the sum of T...
  q                 ... equal to...
   *QQ              ... Q*Q?
O                 Choose a random element of those remaining sets, implicit print

Düzenleme: alternatif bir yaklaşım kullanarak bir bayt kaydetti. Önceki versiyon: Of&qQlT{IT./*


2

Python 3 , 136 134 127 121 114 bayt

from random import*
def f(n):
	s={randint(1,n*n)for _ in range(n)}
	return len(s)==n and sum(s)==n*n and s or f(n)

Çevrimiçi deneyin!

Bir yorumcu beni düzeltti ve bu şimdi f (1) yerine f (5) yerine özyineleme derinliğine çarptı. Gerçek bir rakip cevap olmaya çok daha yakın.

Bir keresinde f (5) yaptığını gördüm ve bunu karıştırmaya uygulamaya çalışıyorum.

Bazı lambda ifadeleri yapmaya çalıştım s=..., ama bu baytlarda yardımcı olmadı. Belki başka biri bununla bir şeyler yapabilir: s=(lambda n:{randint(1,n*n)for _ in range(n)})(n)

Kevin'a 7 bayt daha tıraş ettiğin için teşekkürler.


1
Yani bu, eğer biri geçersizse kümeyi "yeniden oluşturmak" için özyinelemeyi kullanır. Senin koduyla Kesinlikle yanlış bir şey eğer 's vurma yineleme derinliği f(1)en generable olmalıdır yalnızca olası dizisi n=1olan [1]burada kaldırılacak gereksiz boşluk bir sürü Ayrıca. Unutmayın, bu bir kod golf mücadelesi, bu nedenle amaç en düşük bayt sayısını elde etmektir
Skidsdev

1
range(1,n)-> range(n)Bence hatayı çözmeliyim.
Jonathan Allan,

1
Bu , hatanızı düzeltmeli ve ayrıca gereksiz beyaz boşlukları da kaldırmalıdır. Golf
oynamak

1
Özyineleme 5 ila 4 arasında bir miktar kötüleşse de, iki return ifadenizi bu şekilde birleştirebilirsiniz: return len(s)==n and sum(s)==n*n and s or f(n)( Çevrimiçi 114 bayt deneyin ).
Kevin Cruijssen

1
Hepsini tek bir hatta alabilirsiniz. 111 bayt
Jo King,

2

APL (Dyalog Unicode) , 20 bayt SBCS

Anonim önek lambda.

{s=+/c←⍵?s←⍵*2:c⋄∇⍵}

Çevrimiçi deneyin!

{} "Dfn";tartışma

⍵*2 tartışmayı çöz

s← atama s( s için )

⍵?n1'den rasgele endeksleri  bul … sdeğiştirmeden

c← atama c( c andidate için)

+/ onları topla

s= karşılaştırmak s

: eğer eşitse

  c adayı iade et

 Başka

  ∇⍵ tartışmayı tekrarla


Bunu gördün mü, benim ve H.PWiz en 18 byte?
ngn

@ Hayır Hayır, açıkça değil, ancak göndermeden önce APL çözümü gönderilmediğini kontrol ettim. Neden hiç biriniz olmadı didn't
Adám

iyi, bir keresinde golf oynadım ve meyve bahçesine gösterdiğimde, gönderecek hiçbir teşvik yok :)
ngn

@ Senin için, hayır, ama benim için var.
16’da

1
şüphesiz ve bence APL'yi popülerleştirmek için harika bir iş çıkarıyorsun. Daha kısa çözümler bulunduğunu bildiğinizden emin oldum ve muhtemelen bunlardan birini (veya bir varyasyonunu) açıklamak daha iyidir
ngn

2

APL (Dyalog Klasik) , 18 bayt

(≢?≢×≢)⍣(0=+.-∘≢)⍳

Çevrimiçi deneyin!

kullanımları ⎕io←1

sayıları üretir 1 2 ... n

(... )⍣(...) sağdaki işlev doğru dönene kadar soldaki işlevi uygulamaya devam et

uzunluk n

≢?≢×≢n1 ile 2 arasında rastgele farklı tam sayılar seçebilirn

+.-∘≢ uzunluğu her sayıdan ve toplamdan çıkartın

0= toplam 0 ise, döngüyü durdurun, aksi takdirde tekrar deneyin


1

MATL , 18 13 bayt

`xGU:GZrtsGU-

Çevrimiçi deneyin!

`	# do..while:
x	# delete from stack. This implicitly reads input the first time
	# and removes it. It also deletes the previous invalid answer.
GU:	# paste input and push [1...n^2]
GZr	# select a single combination of n elements from [1..n^2]
tsGU-	# is the sum equal to N^2? if yes, terminate and print results, else goto top

Bunu R - rasgele karakterlerde neredeyse hiç geçerli bir program üretmeyeceğim.
NGM

@ ngm hahaha Bir açıklama sırası olduğunu varsayalım.
Giuseppe

1

Japt, 12 bayt

²õ àU ö@²¥Xx

Dene

                 :Implicit input of integer U
²                :U squared
 õ               :Range [1,U²]
   àU            :Combinations of length U
      ö@         :Return a random element that returns true when passed through the following function as X
        ²        :  U squared
         ¥       :  Equals
          Xx     :  X reduced by addition

OP tarafından yapılan bir yoruma göre, çıktıdaki elementlerin sırası önemli değil, bu yüzden iyi àolmalı.
Kamil Drakari

Teşekkürler, @KamilDrakari. Güncellenmiş.
Shaggy

1

Java (JDK) , 127 bayt

n->{for(int s;;){var r=new java.util.TreeSet();for(s=n*n;s>0;)r.add(s-(s-=Math.random()*n*n+1));if(r.size()==n&s==0)return r;}}

Çevrimiçi deneyin!

Kritere uyan bir kümeye kadar sonsuz döngü.

Umarım vaktin vardır, çünkü bu çok sloooooow! Zaman aşımına uğramadan 10'a bile gidemez.


Sen golf 3 değiştirerek bayt can if(r.size()==n&s==0)için if(r.size()+s==n).
Kevin Cruijssen

@KevinCruijssen Ben de düşündüm, ama hayır yapamam çünkü s -1 olabilir ve n boyut olabilir () - 1.
Olivier Grégoire

Ah bekleyin, sete öğeler eklemeye devam edin s>0, böylece boyut daha büyük olabilir n. Tamam, bu durumda gerçekten işe yaramaz. nsabit, ancak ne yazık ki hem sve r.size()altına veya üstüne her ikisi de olabilir değişkenlerdir 0ve nsırasıyla.
Kevin Cruijssen

1

Toplu iş, 182 145 bayt

@set/an=%1,r=n*n,l=r+1
@for /l %%i in (%1,-1,1)do @set/at=n*(n-=1)/2,m=(r+t+n)/-~n,r-=l=m+%random%%%((l-=x=r+1-t)*(l^>^>31)+x-m)&call echo %%l%%

Açıklama: Sayıların azalan sırayla seçilmesi koşuluyla izin verilen minimum ve maksimum değerleri hesaplar ve aralık içinde rastgele bir değer seçer. Bir giriş örneği 4:

  • 16 sola başlıyoruz. Kalan 3 seçenekten en az 6 toplaması gerektiğinden 11 veya daha fazla toplayamayız, çünkü en az 6 seçmemiz gerekir; 16 için yeterli. 6'dan 10'a rasgele bir değer seçiyoruz, 6 diyoruz.
  • 10 tane kaldı. 8 ya da daha fazlasını seçemiyoruz çünkü kalan 2 seçenekte en az 3'e eklenmeli. Bu gerçekleştiği için, 6 ya da daha fazlasını seçemeyiz çünkü en son 6 tane seçtik. Ayrıca en az 5 seçmemiz gerekiyor, çünkü yalnızca 4 seçersek, kalan 2 seçim toplam 15 için 5'e eklenebilir. 5'den 5'e (!), Rastgele bir değer seçiyoruz.
  • 5 tane kaldı. 5 veya daha fazlasını seçemiyoruz, çünkü kalan seçim en az 1 değere eklenmeli ve ayrıca son 5 seçim yaptık. Ayrıca en az 3 seçmemiz gerekiyor, çünkü sadece 2 seçersek, kalan seçim sadece 1, toplamda 14 olur. Rastgele bir değer seçiyoruz, 3'ten 4'e, yani 4.
  • 1 tane kaldı. Görünen o ki, algoritma 1 ila 1 aralığını seçiyor ve son sayı olarak 1'i seçiyoruz.

1

JavaScript, 647 291 261 260 259 251 239 bayt

Orijinal sürümde -10 baytlık @Veskah ve "Ah, tüm setleri çıkarırken, meydan rastgele bir kişinin geri dönmesini ister"

(n,g=m=n**2,r=[...Array(g||1)].map(_=>m--).sort(_=>.5-Math.random()).slice(-n),c=_=>eval(r.join`+`),i=_=>r.includes(_))=>[...{*0(){while(g>1&&c()!=g){for(z of r){y=c();r[m++%n]=y>g&&!(!(z-1)||i(z-1))?z-1:y<g&&!i(z+1)?z+1:z}}yield*r}}[0]()]

Çevrimiçi deneyin!

n^21 tabanlı dizinlerden oluşan bir dizi oluşturun , diziyi rastgele sıralayın, diziden nelemanları dilimleyin . Rastgele elemanların toplamı rastgele elemanların n^2döngü dizisine eşit olmasa da ; dizi elemanlarının toplamı büyükse n^2ve akım elemanı -1sıfıra eşit değilse veya akım elemanı -1akım dizisinde değilse 1; dizi toplamı küçükse n^2ve geçerli öğe +1dizide değilse, 1öğeye ekleyin . Dizi toplamı n^2kopma döngüsüne eşitse , çıktı dizisi.


1
Z.join'i bir değişkene çekerek 637 bayt vek++
Veskah

@Veskah İki whiledöngü de muhtemelen parametreleri kabul eden tek bir fonksiyonun gövdesine indirgenebilir; ve if..elseifadeler için koşullu operatörleri (üçlü) değiştirebilir ; Kodun golf için ayarlanması muhtemel olmayan diğer bölümleri arasında; letifadeleri kaldırarak .
misafir 271314

@Veskah 601 bayt yerine üçlüif..else
misafir271314

1
Oh evet, tüm takımları çıkarıyorsunuz, oysa meydan rastgele bir takımın geri gönderilmesini istiyor (Daha fazla detay için OP yorumlarına bakınız)
Veskah

@ Veskah Mücadeleyi ve örnekleri yanlış yorumlamış olmalı ya da " Bonus Görev: Bir verilen için geçerli permütasyon sayısını hesaplamak için bir formül var mı n?" . eğer algoritma sürekli n^2bir fonksiyon çağrısında üretilen çıktı dizileri için beklenen sonucu sürekli döndürdüyse test etmek ve eşzamanlı olarak bu soruna benzeyen N-boyutlu N ^ N dizisi ile karşılaştırmak .
misafir 271314

0

Japt , 20 bayt

²õ ö¬oU íUõ+)Õæ@²¥Xx

Çevrimiçi deneyin!

Son derece yoğun bir şekilde "Üniform olmayan" rastgelelikten faydalanır, hemen hemen her zaman ntoplanacak ilk tek sayıları çıkarır n^2. Teoride başka bir geçerli set çıkartabilir, ancak bunu sadece küçük için onaylayabildim n.

Açıklama:

²õ                      :Generate the range [1...n^2]
   ö¬                   :Order it randomly
     oU                 :Get the last n items
        í   )Õ          :Put it in an array with...
         Uõ+            : The first n odd numbers
              æ_        :Get the first one where...
                  Xx    : The sum
                ²¥      : equals n^2


0

C (gcc) , 128 125 bayt

p(_){printf("%d ",_);}f(n,x,y,i){x=n*n;y=1;for(i=0;++i<n;p(y),x-=y++)while(rand()&&(n-i)*(n-i+1)/2+(n-i)*(y+1)+y<x)y++;p(x);}

Çevrimiçi deneyin!

Ceilingcat sayesinde -3 bayt

NOT: Olasılık üniformadan çok uzaktır. Ne demek istediğimin açıklamasına bakın ve çalıştığını test etmek için daha iyi bir araç (dağılımı tek tipe yakınlaştırarak [ancak hala ondan çok ağlayarak]).

Nasıl?

Temel fikir, çoğaltmalar için endişelenmemek için yalnızca artan sayıları seçmektir. Ne zaman bir sayı seçersek, izin veriliyorsa sıfırlama şansımız yoktur.

Bir sayıyı atlayıp atlamayacağımıza karar xvermek için ulaşılacak toplam kalan kkısmı, hala kullanmak zorunda olduğumuz element sayısını ve ymevcut aday değerini bilmemiz gerekir . Hala seçebileceğimiz en küçük sayı,

y+(y+1)+(y+2)+...
geçerli değere eklendi. Özellikle yukarıdaki ifadenin daha küçük olmasını istiyoruz x. Formül olacak
k(k+1)2+k(y+1)+y<x
Maalesef, C'deki tamsayı kesme nedeniyle bu formülü yeniden düzenleme konusunda biraz dikkatli olmalıyız, bu yüzden gerçekten golf oynamak için bir yol bulamadım.

Bununla birlikte, mantık, yyukarıdaki denklemi sağlayanları atma şansına sahip olmaktır .

Kod

p(_){printf("%d ",_);}  // Define print(int)
f(n,x,y,i){             // Define f(n,...) as the function we want
    x=n*n;              // Set x to n^2
    y=1;                // Set y to 1
    for(i=0;++i<n;){    // n-1 times do...
        while(rand()&&  // While rand() is non-zero [very very likely] AND
            (n-i)*      // (n-i) is the 'k' in the formula
            (n-i+1)/2+  // This first half takes care of the increment
            (n-i)*(y+1) // This second half takes care of the y+1 starting point
            +y<x)       // The +y takes care of the current value of y
        y++;            // If rand() returned non-zero and we can skip y, do so
    p(y);               // Print y
    x-=y++;             // Subtract y from the total and increment it
    }p(x);}             // Print what's left over.

Daha iyi test belirtilen numara kodunu içerir değiştirilmesi rand()&&ile rand()%2&&herhangi bir y yerine bir 1'den, atlanır 50-50 şansı vardır, böylece RAND_MAX, herhangi bir Y kullanılması ihtimali.


Birisi benim matematiği tutarlılık için kontrol etse çok sevinirim. Ayrıca, bu tür bir çözümün rastgele rastgele hız mücadelesini basitleştirebildiğini de merak ediyorum. Formül, cevaba bir üst ve alt sınır yerleştirir, bu aralıktaki tek tip rastgele sayı, tek tip rastgele sonuçlara neden olur mu? Neden olmadığını anlamıyorum - ama bir süredir pek çok kombinatorik yapmadım.
LambdaBeta

Öner p(y),x-=y++)while(rand()&&(i-n)*((~n+i)/2+~y)+y<x)y++;yerine){while(rand()&&(n-i)*(n-i+1)/2+(n-i)*(y+1)+y<x)y++;p(y);x-=y++;}
ceilingcat

@ceilingcat Bulduğun bu küçük gelişmeleri seviyorum. Genel algoritmaya her zaman o kadar odaklanırım ki, uygulama için optimize etmeyi unuttum (temelde otopilot golf moduna geçtim, işe yaramaz bir golf kaynağına sahip olduğumda - bu yüzden çok tasarrufu özlüyorum)
LambdaBeta

Hey, bu sentaks golflerine sahip olan sadece sen değilsin. Bunun gibi pek çok C / C ++ cevabında ufak gelişmeler görüyorum (sizinkiler dışında, @ceilingcat genellikle bunları engeller).
Zacharı

Evet, ikinizin muhtemelen en aktif C / C ++ atıcıları olduğunuzu fark ettim (golf analojisini son birkaç vuruşa genişletmek için kullanabilir miyiz? Neden olmasın!). Her zaman beni etkiliyor golf kodunu geliştirmek için yeterince iyi anlayabiliyorsun.
LambdaBeta

0

Temiz , 172 bayt

import StdEnv,Math.Random,Data.List
? ::!Int->Int
?_=code{
ccall time "I:I"
}
$n=find(\s=length s==n&&sum s==n^2)(subsequences(nub(map(inc o\e=e rem n^2)(genRandInt(?0)))))

Çevrimiçi deneyin!


0

Python (2 veya 3), 84 bayt

from random import*;l=lambda n,s=[]:(sum(s)==n*n)*s or l(n,sample(range(1,n*n+1),n))

Çevrimiçi deneyin!

Yaklaşık l'de maksimum tekrarlama derinliği vurur (5)



0

Mathematica 40 bayt

RandomChoice[IntegerPartitions[n^2, {n}]]

1
Her şeyden önce n ^ 2, 2 ^ n değil. İkincisi, programınız bir fonksiyon olmalı ve aynı zamanda bir de golf oynamalıdır. Bunu dene RandomChoice@IntegerPartitions[#^2,{#}]&
J42161217

1
Ayrıca sonuç (sıralanmamış, benzersiz) olmalıdır, ancak bu işlev her ikisinde de başarısız olur
J42161217 25:18

0

Wolfram Dili (Mathematica) , 49 bayt

(While[Tr[s=RandomSample[Range[#^2],#]]!=#^2];s)&

Çevrimiçi deneyin!

Golfed sürümü @ J42161217 tarafından.


Wolfram Dili (Mathematica) , 62 bayt

Range[#-1,0,-1]+RandomChoice@IntegerPartitions[#*(#+1)/2,{#}]&

Çevrimiçi deneyin!

Nasıl çalışır

Temelde bu Math.SE sorusuna dayanarak . Bölümleri almak içinn2 içine n farklı parçalar, bölümleri almak n2-(n2-n)/2=(n2+n)/2 yerine ve ekle 0n-1Her eleman için. Mathematica, bölmeleri azalan sırayla verdiğinden,n-10 bunun yerine eklendi.


Bonus Görevine cevap

Bonus Görevi: Verilen izinlerin geçerli sayısını hesaplamak için bir formül var mı n?

Evet. Tanımlamakpart(n,k) as the number of partitions of n into exactly k parts. Then it satisfies the following recurrence relation:

part(n,k)=part(n1,k1)+part(nk,k)

You can understand it as "If a partition contains a 1, remove it; otherwise, subtract 1 from every term". More explanation here on another Math.SE question. Combined with the initial conditions part(n,1)=1 and n<kpart(n,k)=0, you can compute it with a program. The desired answer will be:

part(n2+n2,n)

which is, in Mathematica:

Length@IntegerPartitions[#*(#+1)/2,{#}]&

Try it online!


This is code golf.. 49 bytes (While[Tr[s=RandomSample[Range[#^2],#]]!=#^2];s)&
J42161217
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.