N Kapı, K Maymun


14

N kapı ve K maymunları var. Başlangıçta tüm kapılar kapalıdır.

1. Tur: 1. maymun her kapıyı ziyaret eder ve kapıyı açar (kapı kapalıysa, açılır; açıksa kapanır).

2. Tur : 1. maymun her kapıyı ziyaret eder ve kapıyı açar. Sonra 2. maymun her 2. kapıyı ziyaret eder ve kapıyı açar.

. . .

. . .

Yuvarlak k: 1. maymun her kapıyı ziyaret eder ve kapıyı açar. . . . . . . . . . Kth maymun her kth kapıyı ziyaret eder ve kapıyı açar.

Girdi: NK (tek boşlukla ayrılmış)

Çıktı: Her biri tek bir boşlukla ayrılmış açık kapı numaraları.

Örnek :

Giriş: 3 3

Çıktı: 1 2

Kısıtlamalar :

0 <N <101

0 <= K <= N

Not :

  • N kapıların 1'den N'ye ve K maymunlarının 1'den K'a kadar numaralandığını varsayın

  • En kısa koda sahip olan kazanır. Ayrıca, N = 23, K = 21 için ekran çıkışı



Sadece bir sorum var, eğer N = K, her asal sayı kapısı açık, değil mi?
Fabinout

@Fabinout hayır çok yanlış n=k=3çıktı 1 2... ve 5 çıktı 1 2 4bir desen var ama onun çok daha az belirgin.
Matematik soğutucu

@Fabinout çok gelişmiş bir soyut matematiği olan çok garip bir Fibonacci sayı kümesi izler.
Matematik soğutucu

@tryingToGetProgrammingStraight haklısın, anılarım bana cevabın kare sayıların listesi olduğu zaman asal sayıların listesi olduğunu söyledi.
Fabinout

Yanıtlar:


14

APL, 32 28 26

{(2|+/(⍳⍺)∘.{+/0=⍺|⍨⍳⍵}⍳⍵)/⍳⍺}/⎕

⎕:
      23 21
 1 2 4 8 9 16 18 23 

Açıklama

  • {+/0=⍺|⍨⍳⍵}kapının (sol argüman) turda (sağ argüman) geçiş sayısını döndüren bir işlevdir , bu da faktörlerin sayısına eşittir :

    • ⍳⍵ 1'den 1'e kadar sayısal dizi oluştur

    • ⍺|⍨Dizinin her öğesinin modülünü hesapla

    • 0= Diğer her şey için 0 ve 0 olduğu yerde 1 olarak değiştirin

    • +/ Ortaya çıkan diziyi topla

  • Dış fonksiyonu:

    • (⍳⍺), ⍳⍵1'den N'ye ve 1'den K'ya diziler oluşturun

    • ∘.{...}İki dizinin her bir öğesi için işlevi uygulayın. Bu, değiştirilen sayıların bir matrisini verir, her sıra bir kapıyı ve her sütun bir turu temsil eder.

    • +/Sütunları toplayın. Bu, her kapının tüm turlarda kaç kez değiştirildiğini gösteren bir dizi verir.

    • 2|Modül 2, eğer bir kapı açıksa, bu 1'dir; kapalıysa 0 olur.

    • (...)/⍳⍺ Son olarak, 1'den N'ye kadar bir dizi oluşturun ve yalnızca önceki adımda dizide 1 olanları seçin.

  • /⎕ Son olarak, işlevi girişteki sayılar arasına yerleştirin.


DÜZENLE

{(2|+⌿0=(,↑⍳¨⍳⍵)∘.|⍳⍺)/⍳⍺}/⎕
  • ,↑⍳¨⍳⍵Tüm "maymunları" üret (K = 4 ise, bu 1 0 0 0 1 2 0 0 1 2 3 0 1 2 3 4)

    • ⍳⍵1'den (K) ' ye kadar dizi

    • ⍳¨ Bunların her biri için 1'den bu sayıya kadar dizi oluşturun

    • ,↑Yuvalanmış diziyi bir matrise ( ) dönüştürün ve ardından basit bir diziye ( ,) çözün

  • (,↑⍳¨⍳⍵)∘.|⍳⍺1'den (N) ' ye kadar olan her sayı için, her maymunla değiştirin.

  • 0=Diğer her şey için 0 ve 0 olduğu yerde 1 olarak değiştirin. Bu bir geçiş matrisi verir: Satırlar her turda her maymun, sütunlar kapılardır; 1 bir değiştirme, 0 bir değiştirme anlamına gelir.

  • +⌿ Her kapının kaç kez değiştirildiğini görmek için satırları toplayın

Diğer parçalar değiştirilmez


DÜZENLE

{(≠⌿0=(,↑⍳¨⍳⍵)∘.|⍳⍺)/⍳⍺}/⎕

≠⌿Toplam ve mod 2 ( 2|+⌿) yerine XOR reduce ( ) kullanın


APL golf senaryosu için mi tasarlandı? ;-)
celtschk

@celtschk Evet, kısmen, bir bakıma. Algoritmaları kısaca ifade etmek için tasarlanmıştır.
luser droog

Neden {}/sadece N ve K'yi dfn'ye argüman olarak almak yerine bir dfn indirgemesi kullanıyorsunuz?
Ad

@ Adám Çünkü 1) bu beni aşıyor; 2) bu soru "program veya fonksiyon" ve G / Ç standartlaştırmasından önce gelir; 3) OP özellikle "tek bir boşlukla ayrılmış" dedi
TwiNight

Yeterince adil, ama en azından bir bayt kaydedebilirsinizi←⍳⍺
Adám

4

GolfScript, 33 karakter

~:k;),1>{0\{1$)%!k@-&^}+k,/}," "*

Kapılar sıfırdan başlayarak numaralandırıldıysa 3 karakter kazandırır.

Örnekler ( çevrimiçi ):

> 3 3
1 2

> 23 21
1 2 4 8 9 16 18 23

3

Mathematica, 104 karakter

{n,k}=FromDigits/@StringSplit@InputString[];Select[Range@n,OddQ@DivisorSum[#,If[#>k,0,k+1-#]&]&]~Row~" "

Misal:

[1]: = {n, k} = FromDigits / @ StringSplit @ InputString []; [Range @ n, OddQ @ DivisorSum [#, Eğer [#> k, 0, k + 1 - #] &] & ] ~ Satır ~ ""

? 23 21

Çıkış [1] = 1 2 4 8 9 16 18 23


1
: Sen mesela, bir giriş akışı üstlenerek giriş ayrıştırma kapalı başka bir 15 karakter vuruş yapabilir {n,k}=%~Read~{Number,Number}.
Marcks Thomas

3

Ruby, 88

@ Manatwork'ün cevabına dayanarak.

gets;~/ /
$><<(1..$`.to_i).select{|d|(1..k=$'.to_i).count{|m|d%m<1&&(k-m+1)%2>0}%2>0}*$&

Bu tehlikeli küreseller her zaman sözdizimi vurgulamayı kırıyor!


Üzgünüz, ancak 90 karakter ( revizyon 2 ) ve 86 karakter ( revizyon 3 ) buggy gibi görünüyor: sonuçlarında 22 yeni bir sayı ortaya çıktı.
manatwork

@manatwork iyi çağrı, sanırım şimdi iki karakter pahasına düzelttim. Bu countbit daha da geliştirilebilir gibi hissediyorum , keşke yakut böyle #sumşeyler için yerleşik bir yöntem olsaydı :>
Paul Prestidge

Vaov! Gerçekten etkilendim.
manatwork

3

Python 3, 97 84

Bir maymun çift sayıda turda ortaya çıkarsa, bu hiç bir değişiklik olmaz. Bir maymun eşit sayıda ortaya çıkarsa, bu bir turdakiyle aynıdır.

Böylece bazı maymunlar dışarıda bırakılabilir ve diğerleri sadece bir kez kapı değiştirmelidir.

N,K=map(int,input().split())
r=set()
while K>0:r^=set(range(K,N+1,K));K-=2
print(*r)

Çıktı 23 21:

1 2 4 8 9 16 18 23

Set operasyonlarının akıllı kullanımı! Sana kısaltmak düşünüyorum range(2-K%2,K+1,2)için range(K,0,-2).
xnor

Ya da daha iyisi, fordöngüyü bir whiledöngü ile değiştirin :while K>0:r^=set(range(K,N+1,K));K-=2
xnor

@xnor: teşekkürler, bu harika!
Monica

2

R - 74

x=scan(n=2);cat(which(colSums((!sapply(1:x[1],`%%`,1:x[2]))*x[2]:1)%%2>0))

Simülasyon:

> x=scan(n=2);cat(which(colSums((!sapply(1:x[1],`%%`,1:x[2]))*x[2]:1)%%2>0))
1: 23 21
Read 2 items
1 2 4 8 9 16 18 23

2

javascript 148 127

function e(n,k){b=array(n);d=[];function a(c){for(i=0;i<n;i+=c)b[i]=!b[i];c<k&&a(c+1)}a(1);for(i in b)b[i]&&d.push(i);return d}

İşte bir (küçük bit) okunabilir versiyonu:

function e(n, k) {     //define N and K
     b = array(n); //declare all doors as closed
     d = [];     //create array later used to print results

     function a(c) {   //(recursive) function that does all the work
         for (i = 0; i < n; i += c)  //increment by c until you reach N and...
              b[i] = !b[i];  //toggle said doors
         c < k && a(c + 1)  //until you reach k, repeat with a new C (next monkey)
     }
     a(1); //start up A

     for (i in b) b[i] && d.push(i); //convert doors to a list of numbers
     return d //NO, i refuse to explain this....
}   //closes function to avoid annoying errors

DEMO keman

i 0 (teknik olarak bir off-by-one hatası) saymaya başlar unutmayın


2. satırı olarak değiştirirseniz 3. satırınızı kaldırabilirsiniz b=Array(n);Bu, dizinizi tanımsız ile doldurulmuş n uzunluğu olarak başlatır. ! undefined doğrudur, bu yüzden ilk maymun pasosu hepsini gerçeğe dönüştürecektir.
path411

@ path411 çok teşekkür ederim! im şaşırdım nasıl "uygun" dizi bildirimi çalışır unuttum! çekinmeyin+1
Matematik soğutucu

İlginç. Görünüşe göre N = 23, K = 21 için benimkine benzer bir cevap aldım. Tek fark, 0'ı içeren ve 23'ü içeren tek tek sorunlardır.
Iszi

Benimki ile ilgili neyin yanlış olduğunu anladım ve bunun da aynı sorunu var. Her tur için tüm kapılardan sadece bir maymun gönderiyorsunuz. Ancak, meydan okuma özellikleri başına, her turda çalışan $ i maymun olması gerekir - burada $ i üzerinde olduğunuz turun sayısıdır.
Iszi

2

JavaScript, 153

(function(g){o=[],f=g[0];for(;i<g[1];i++)for(n=0;n<=i;n++)for(_=n;_<f;_+=n+1)o[_]=!o[_];for(;f--;)o[f]&&(l=f+1+s+l);alert(l)})(prompt().split(i=l=s=' '))

N = 23, K = 21 için çıkış:

1 2 4 8 9 16 18 23  

Chrome'da test edilmiştir, ancak yeni ECMAScript özelliklerini kullanmaz, bu nedenle herhangi bir tarayıcıda çalışmalıdır!

Diğer girişlere karşı asla kazanamayacağımı ve @tryingToGetProgrammingStrainght'in zaten JavaScript'te bir giriş gönderdiğini biliyorum, ancak N = 23, K = 21 için aynı sonuçları almıyordum, bu yüzden herkes bunu elde ediyordu kendi versiyonum var.

Düzenleme : açıklamalı kaynak (buna tekrar bakarken, başka bir 3 karakteri kaydetmek için yerleri gördüm, bu yüzden muhtemelen hala geliştirilebilir ...)

(function(g) {
    // initialise variables, set f to N
    o = [], f = g[0];

    // round counter
    // since ++' ' == 1 we can use the same variable set in args
    for (; i < g[1]; i++)
        // monkey counter, needs to be reset each round
        for (n = 0 ; n <= i; n++)
            // iterate to N and flip each Kth door
            for (_ = n; _ < f; _ += n + 1)
                // flip the bits (as undef is falsy, we don't need to initialise)
                // o[_] = !~~o[_]|0; // flips undef to 1
                o[_] = !o[_]; // but booleans are fine
    // decrement f to 0, so we don't need an additional counter
    for (;f--;)
        // build string in reverse order
        o[f] && (l = f + 1 + s + l); // l = (f + 1) + ' ' + l
    alert(l)
    // return l // use with test
// get input from user and store ' ' in variable for use later
})(prompt().split(i = l = s = ' '))
// })('23 21'.split(i = l = s = ' ')) // lazy...

// == '1 2 4 8 9 16 18 23  '; // test

iyi iş! Ayrıca okunabilir ve yorumlanmış bir sürüm sağlarsanız ben muhtemelen+1
Matematik chiller

Yanıt güncellendi! Cevabınıza yorum yapamadığım için, @ path411'in yorumuna eklemek için b = [] ayarlayabilir ve boş dizinler hala tanımsızdır ve bu size 6 karakter daha kazandırır!
Dom Hastings

Bunu zaten yaptım ....
Matematik soğutucu

1

Ruby - 65 karakter

(1..n).each{|d|
t=0
(1..k).each{|m|t+=n-m+1 if d%m==0}
p d if t%2>0}

n = 23, k = 21 # => 1 2 4 8 9 16 18 23 

İşte sözde kodda hesaplama:

  • S (d), d turundan sonra d kapısına dokunma sayısı olsun.
  • s (d) = toplam (m = 1..m = k) (d% m == 0? (n-m + 1): 0)
  • s (d)% 2 = 1 (veya> 0) ise d kap, k turdan sonra açıktır

S (d) ifadesinin doğru olduğuna ikna olmadıysanız, şuna şu şekilde bakın:

  • S (d, r), d turundan sonra d kapısına dokunma sayısı olsun.
  • s (d, k) - s (d, k-1) = toplam (m = 1, .., m = k) (d% m == 0? 1: 0)
  • s (d, k-1) - s (d, k-2) = toplam (m = 1, .., m = (k-1)) (d% m == 0? 1: 0)
  • ...
  • s (d, 2) - s (d, 1) = d% 2 == 0? 1: 0
  • s (d, 1) = 1
  • s (d) için s (d, k) 'ye eşit olan yukarıdaki ifadeyi elde etmek üzere her iki tarafı toplayın

Çok özlü! Peki nereden geliyor nve kgeliyor? Ve çıktı boşluklardan ziyade satırsonu ile ayrılmış gibi görünüyor.
Paul Prestidge

1

Güç Kabuğu: 132

Golf Kodu:

$n,$k=(read-host)-split' ';0|sv($d=1..$n);1..$k|%{1..$_|%{$m=$_;$d|?{!($_%$m)}|%{sv $_ (!(gv $_ -Va))}}};($d|?{(gv $_ -Va)})-join' '

Golf Yapılmayan, Yorumlanan Kod:

# Get number of doors and monkeys from user as space-delimited string.
# Store number of doors as $n, number of monkeys as $k.
$n,$k=(read-host)-split' ';

# Store a list of doors in $d.
# Create each door as a variable set to zero.
0|sv($d=1..$n);

# Begin a loop for each round.
1..$k|%{

    # Begin a loop for each monkey in the current round.
    1..$_|%{

        # Store the current monkey's ID in $m.
        $m=$_;

        # Select only the doors which are evenly divisible by $m.
        # Pass the doors to a loop.
        $d|?{!($_%$m)}|%{

            # Toggle the selected doors.
            sv $_ (!(gv $_ -Va))
        }
    }
};

# Select the currently open doors.
# Output them as a space-delimited string.
($d|?{(gv $_ -Va)})-join' '

# Variables cleanup - don't include in golfed code.
$d|%{rv $_};rv n;rv d;rv k;rv m;

# NOTE TO SELF - Output for N=23 K=21 should be:
# 1 2 4 8 9 16 18 23

Sorunumun ne olduğunu anlıyorum. Bu - Soruyu yanlış değil 100 Dolaplar sorunu. Bu bir çentik aldı! Bu biraz daha fazla iş gerektirecek ...
Iszi

1
Tatlı! Zorluk gereksinimlerini doğru bir şekilde karşılamak için düzeltme, sonunda sadece 6 karakter kazanmıştır.
Iszi

0

Powershell, 66 bayt

Cary Swoveland en dayanarak cevap .

param($n,$k)1..$n|?{$d=$_
(1..$k|?{($n-$_+1)*!($d%$_)%2}).Count%2}

Test komut dosyası:

$f = {

param($n,$k)1..$n|?{$d=$_
(1..$k|?{($n-$_+1)*!($d%$_)%2}).Count%2}

}

@(
    ,(3, 3   , 1,2)
    ,(23, 21 , 1, 2, 4, 8, 9, 16, 18, 23)
) | % {
    $n,$k,$expected = $_
    $result = &$f $n $k
    "$("$result"-eq"$expected"): $result"
}

Çıktı:

True: 1 2
True: 1 2 4 8 9 16 18 23
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.