N Двері, K Мавпи


14

Є N дверей і K мавп. Спочатку всі двері закриваються.

Раунд 1: Перша мавпа відвідує кожну двері і перемикає двері (якщо двері закриваються, вона відкривається; якщо вона відкрита, вона закривається).

Раунд 2 : Перша мавпа відвідує всі двері та перемикає двері. Потім 2-а мавпа відвідує кожну 2-ю двері та перемикає двері.

. . .

. . .

Круглий k: перша мавпа відвідує всі двері та перемикає двері. . . . . . . . . . Kth мавпа відвідує кожну kth двері та перемикає двері.

Введення: NK (розділене одним пробілом)

Вихід: Номери дверей, які відкриті, кожна розділена одним пробілом.

Приклад :

Вхід: 3 3

Вихід: 1 2

Обмеження :

0 <N <101

0 <= K <= N

Примітка :

  • Припустимо, що N дверей пронумеровано від 1 до N, а мавп K пронумеровано від 1 до K

  • Виграє той, хто має найкоротший код. Також виведіть на дисплей вихід для N = 23, K = 21



У мене просто питання, якщо N = K, кожна двері простого числа відчинені, правда?
Fabinout

Чи не @Fabinout НЕ n=k=3буде виводити 1 2так ур неправильно ... і 5 виходів 1 2 4є шаблон , але його багато менше очевидно то , що.
Математичний чиллер

@Fabinout це слід дуже дивного типу набору чисел Фібоначчі, його дуже розвиненої абстрактної математики.
Math chiller

@tryingToGetProgrammingStraight ви праві, мої спогади сказали мені, що відповідь - це список простих чисел, коли це був список квадратних чисел.
Fabinout

Відповіді:


14

АПЛ, 32 28 26

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

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

Пояснення

  • {+/0=⍺|⍨⍳⍵}це функція, яка повертає кількість разів перемикання дверей (лівий аргумент) на круглий (правий аргумент), що дорівнює кількості факторів, що становить ≤ :

    • ⍳⍵ Створити числовий масив від 1 до

    • ⍺|⍨Обчисліть модуль кожного елемента цього масиву

    • 0= Перейдіть на 1, де було 0 і 0 для кожної речі

    • +/ Підсумуйте отриманий масив

  • Зовнішня функція:

    • (⍳⍺), ⍳⍵Створіть масиви від 1 до N та 1 до K

    • ∘.{...}Для кожної пари елементів двох масивів застосуйте функцію. Це дає матрицю кількості перемикань разів, кожен рядок являє собою двері, а кожен стовпець - круглий.

    • +/Підсумовуйте стовпці. Це дає масив кількості перемикань кожної двері протягом усіх раундів.

    • 2|Модуль 2, тому якщо двері відчинені, це 1; якщо він закритий, це 0.

    • (...)/⍳⍺ Нарешті, згенеруйте масив від 1 до N та виберіть лише ті, де у попередньому кроці є масив 1.

  • /⎕ Нарешті, вставте функцію між числами з введення.


EDIT

{(2|+⌿0=(,↑⍳¨⍳⍵)∘.|⍳⍺)/⍳⍺}/⎕
  • ,↑⍳¨⍳⍵Породжуйте всіх "мавп" (Якщо К = 4, то це 1 0 0 0 1 2 0 0 1 2 3 0 1 2 3 4)

    • ⍳⍵Масив від 1 до (K)

    • ⍳¨ Для кожного з них генеруйте масив від 1 до цього числа

    • ,↑Перетворити вкладений масив у матрицю ( ), а потім розплутати до простого масиву ( ,)

  • (,↑⍳¨⍳⍵)∘.|⍳⍺Для кожного числа від 1 до (N), змініть його з кожною мавпою.

  • 0=Перейдіть на 1, де було 0 і 0 для кожної речі. Це дає матрицю перемикань: рядки - це кожна мавпа на кожному раунді, стовпці - двері; 1 означає перемикання, 0 означає відсутність перемикання.

  • +⌿ Підсумовуйте рядки, щоб отримати масив, скільки разів перемикали кожну двері

Інші деталі не змінені


EDIT

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

Використовуйте XOR зменшити ( ≠⌿) замість суми та mod 2 ( 2|+⌿)


Чи був APL розроблений для сценарію гольфу? ;-)
celtschk

@celtschk Так, частково, певним чином. Він був розроблений для вираження алгоритмів стисло.
luser droog

Чому ви використовуєте скорочення dfn {}/замість того, щоб просто брати N і K як аргументи dfn?
Адам

@ Adám Тому що 1) це минуле мене; 2) це питання передує "програмі чи функції" та стандартизації вводу / виводу; 3) ОП спеціально сказала "розділене єдиним пробілом"
TwiNight

Досить справедливо, але принаймні ви можете зберегти байт зi←⍳⍺
Adám,

4

GolfScript, 33 символи

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

Якби двері були пронумеровані, починаючи з нуля, це збереже 3 символи.

Приклади ( онлайн ):

> 3 3
1 2

> 23 21
1 2 4 8 9 16 18 23

3

Математика, 104 чол

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

Приклад:

У [1]: = {n, k} = FromDigits / @ StringSplit @ InputString []; Оберіть [Range @ n, OddQ @ DivisorSum [#, якщо [#> k, 0, k + 1 - #] &] & ] ~ Рядок ~ ""

? 23 21

Вихід [1] = 1 2 4 8 9 16 18 23


1
Ви можете збити ще 15 символів від розбору введення, припустивши вхідний потік, наприклад: {n,k}=%~Read~{Number,Number}.
Маркс Томас

3

Рубі, 88

На основі відповіді @ manatwork.

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

Ці хитрі глобалі завжди порушують підкреслення синтаксису!


Вибачте, але 90 символів ( редакція 2 ) та 86 символів ( редакція 3 ), здається, баггі: в їхніх результатах з'явилося нове число, 22.
манатура

@manatwork гарний дзвінок, я думаю, що це я виправив зараз ціною двох символів. Я відчуваю, що цей countбіт можна було вдосконалити далі, я б хотів, щоб у рубінів був вбудований #sumметод для таких речей:>
Пол Престидж

Оце Так! Дійсно вражений.
манатура

3

Пітон 3, 97 84

Якщо мавпа з’являється в парній кількості раундів, це зовсім не зміниться. Якщо мавпа з’являється рівномірну кількість разів, це те саме, що рівно в один раунд.

Таким чином, деякі мавпи можуть бути залишені, а іншим потрібно лише один раз перемикати двері.

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

Вихід для 23 21:

1 2 4 8 9 16 18 23

Розумне використання встановлених операцій! Я думаю , що ви можете скоротити range(2-K%2,K+1,2)до range(K,0,-2).
xnor

Або ще краще, замініть forцикл whileциклом:while K>0:r^=set(range(K,N+1,K));K-=2
xnor

@xnor: спасибі, це чудово!
Відновіть Моніку

2

R - 74

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

Моделювання:

> 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}

Ось (крихітна) читана версія:

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

ДЕМО скрипка

я повинен зазначити, що він починає рахувати з 0 (технічно помилка по одному)


Ви можете видалити свій 3-й рядок, якщо ви зміните другий рядок на " b=Array(n);Це ініціалізує масив як n довжину, заповнену невизначеним. ! Невизначено правда, тому перший пропуск мавпи перетворить це все на правду.
path411

@ path411 дякую вам дуже! Я здивований, я забув, як працює "правильна" заява масиву! ви можете почувати себе вільно+1
Math chiller

Цікаво. Здається, ваша єдина, яку я бачив досі, і, схоже, отримує аналогічну відповідь, як моя для N = 23, K = 21. Єдиною різницею є те, що виходить за одним, який включає 0 та виключає 23.
Іссі

З'ясував, що з моїм не так, і ця проблема має ту саму проблему. На кожен раунд ви відправляєте лише одну мавпу через усі двері. Однак, згідно специфікацій виклику, через кожний раунд повинні проходити мавпи $ i - де $ i - кількість раунду, на якому ви проходите.
Іссі

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:

1 2 4 8 9 16 18 23  

Тестується в Chrome, але не використовує будь-яких фантазійних нових функцій ECMAScript, тому він повинен працювати в будь-якому браузері!

Я знаю, що я ніколи не виграю проти інших записів і що @tryingToGetProgrammingStrainght вже подав запис у JavaScript, але я не отримав таких самих результатів для N = 23, K = 21, як усі інші отримували з цим, тому я подумав, що я я б ходив у моїй власній версії.

Редагувати : джерело з коментарями (переглядаючи це ще раз, я помітив місця, щоб зберегти ще 3 символи, тому його, мабуть, можна вдосконалити ...)

(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

хороша робота! якщо ви також надасте читану та коментовану версію, я, мабуть,+1
Math chiller

Відповідь оновлено! Оскільки я не можу коментувати вашу відповідь, щоб додати до коментаря @ path411, ви можете встановити b = [], а порожні індекси все ще не визначені, і це заощадить вам ще 6 символів!
Дом Гастінгс

Я це зробив уже ....
Math chiller

1

Рубін - 65 символів

(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 

Ось розрахунок у псевдокоді:

  • Нехай s (d) - кількість дотиків дверей d після k раундів.
  • s (d) = сума (m = 1..m = k) (d% m == 0? (n-m + 1): 0)
  • дверцята d відкрита після k раундів, якщо s (d)% 2 = 1 (або> 0)

Якщо ви не впевнені, що вираз для s (d) правильний, подивіться на це так:

  • Нехай s (d, r) - кількість дотиків дверей d після об'їзду r.
  • s (d, k) - s (d, k-1) = сума (m = 1, .., m = k) (d% m == 0? 1: 0)
  • s (d, k-1) - s (d, k-2) = сума (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), який дорівнює s (d, k)

Дуже лаконічно! Звідки ж nі kзвідки беруться? І висновок, здається, розділений новими рядками, а не пробілами.
Пол Престиджедж

1

PowerShell: 132

Код для гольфу:

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

Без гольфу, коментований код:

# 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

О, я бачу, у чому моя проблема. Я неправильно зрозумів питання - це не проблема 100 шаф. Це що, взятий на висічку! Для цього знадобиться трохи більше роботи ...
Ізі

1
Солодке! Зафіксувавши його для задоволення вимог виклику, належним чином викреслили лише коефіцієнт посилення в 6 символів.
Іссі

0

Powershell, 66 байт

На основі Cary Swoveland в відповідь .

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

Тестовий сценарій:

$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"
}

Вихід:

True: 1 2
True: 1 2 4 8 9 16 18 23
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.