Зірочки вірусні


9

Враховуючи додатне ціле число N ("вірусність"), ваша програма повинна створити ASCII-художній малюнок дерева з двома гілками довжиною N, що простягаються вниз та / або праворуч від верхнього лівого кута.

Напрямок, зроблений кожною гілкою після першої зірочки, може бути вправо або вниз, і цей вибір слід робити випадковим чином 1 на кожному наступному кроці.

Наприклад, при введенні 5, вихід може виглядати так:

***
* ***
**
 **

Дві гілки можуть торкатися (бути на сусідніх клітинках), але не перетинатися (бути в одній клітині), тому наступне заборонено:

***
* *
*****
  *
  *

Приклади

Для введення 1єдиний можливий вихід:

**
*

(Це буде присутнє у всіх дійсних результатах, оскільки дві гілки пройдуть однаковий шлях, це призведе до їх перекриття.)

Можливі виходи для введення 3включають:

***
* *
**
**
***
*
*

Для введення 7:

****
*  **
*   **
*
***
  *

Для введення 10:

****
*  *      
*********
  *
  *****

Це є , тому найкоротша відповідна відповідь (у байтах) виграє.

1. Це повинно бути рівномірно випадковим (тобто 50/50 шансів у кожному напрямку) або наближеним до рівномірно випадкових, як ви можете отримати на звичайному обладнання.


Будь ласка, прокоментуйте, якщо у вас виникли проблеми із споживанням моєї довгої посади - можливо, я можу щось скоротити (я спробую тоді).
нікель

3
Просто навчись цього очікувати. Іноді це зайнято, як усе чортів. Іншим часом тихо, як зараз. Не забувайте, це також Великдень.
Zacharý

Я не дуже впевнений, що не так з моєю посадою. Будь-хто, хто прихильнився, буде таким люб'язним пояснити, будь ласка?
нікель

1
IMO N краще описується як час: P
лише ASCII,

1
Чи можемо ми повернути матрицю 0s і 1s замість пробілів і зірочок?
ділнан

Відповіді:


5

CJam , 58 51 байт

[TT]{_2_m*\f.+{:-},mR}ri*]ee{~\)S*\{'*t}/}%::a:.+N*

Спробуйте в Інтернеті!

Основна ідея полягає в тому, що ми починаємо з, [0 0]а потім багаторазово додаємо 0 або 1 до кожного елемента (переконуючись, що вони ніколи не рівні, за винятком початку, щоб уникнути перекриття), збираючи всі проміжні результати.

[[0 0] [0 1] [0 2] [0 2] [1 3]]

Потім ми створюємо великий масив масивів, де кожен підмасив містить *індекси, задані відповідною парою в початковому масиві та пробіли скрізь.

["*"
 "**"
 "* *"
 "* * "
 " * * "]

Це дає діагональні зрізи вихідної матриці (де переміщення вліво-вправо відповідає переміщенню зверху праворуч донизу ліворуч у фактичній матриці).

Потім ми можемо використовувати ::a:.+для "деагоналізації" та отримання отриманих рядків:

[ "**** "
  "*  *"
  "** "
  " *"
  ""     ]

3

Вугілля деревне , 31 24 байт

F²«J⁰¦⁰F⊕θ«¿ι*↓*≔‽²ι¿KK↗

Спробуйте в Інтернеті! Посилання на багатослівну версію коду. Спочатку я думав, що простіше зробити перший крок випадковим, але виявився гравцем зробити першу гілку передбачуваною. Пояснення:

F²«

Цикл двічі, використовуючи змінну індексу i. (Це насправді перетворюється на неявний список, тому безпечно мутувати iвсередині циклу.)

J⁰¦⁰

Перейти до походження полотна.

F⊕θ«

N+1Часи циклу .

¿ι*↓*

Друкуйте a *, але залиште курсор праворуч або під курсором залежно від значення i.

‽²ι

Рандомізуйте значення iдля наступної ітерації внутрішньої петлі.

¿KK↗

Якщо поточний символ є a *, це означає, що ми друга гілка, і ми пішли вниз замість правої, тому рухайтеся вправо, щоб виправити це. (Перша гілка завжди починається вниз, тому друга гілка завжди буде над нею, це означає, що нам потрібно лише перевірити вертикальне зіткнення.)


Це майже правильно, проте він друкує не Nвеликі гілки, але N-1розміром :)
nicael

@nicael Вибачте, виправлено.
Ніл

Напевно, ви вже бачили це занадто багато разів, але: 23 байти
лише для ASCII,

3

Java 10, 273 272 268 239 байт

n->{var c=new char[++n][n];for(var d:c)java.util.Arrays.fill(d,' ');for(int i=0,j=0,k=0,l=0,r=0,s=0,t=0,u=0;n-->0;){c[i+=r][j+=s]=c[k+=t][l+=u]=42;do{r=t=2;r*=Math.random();t*=Math.random();s=r^1;u=t^1;}while(i+r==k+t&j+s==l+u);}return c;}

Спробуйте його онлайн тут .

Дякуємо Кевіну Крейсейну за те, що він займався 29 байтами.

Негольована версія:

n -> { // lambda taking an int as argument
    var c = new char[++n][n]; // the output; increment the virality since the root does not count
    for(var d : c) // for every line
        java.util.Arrays.fill(d,' '); // initialize it with spaces
    for(int i = 0, j = 0, // coordinates of the first branch
            k = 0, l = 0, // coordinates of the second branch
            r = 0, s = 0, // offsets for the first branch, one will be 0 and the other 1 always except for the first '*' where the two branches overlap
            t = 0, u = 0; // offsets for the second branch, one will be 0 and the other 1 always except for the first '*' where the two branches overlap
        n-- > 0; ) { // decrement virality and repeat as many times
        c[i+=r][j+=s] = c[k+=t][l+=u] = 42; // move according to offsets and place an '*' for each branch, 42 is ASCII code
        do { // randomly pick offsets for both branches
            r = t = 2; // Math.random() provides results in [0,1)
            r *= Math.random(); // flip a coin for the first branch
            t *= Math.random(); // flip another coin for the second
            s = r^1; // set s to 0 if r=1, to 1 if r=0
            u = t^1; // set u to 0 if t=1, to 1 if t=0
        } while(i+r==k+t&j+s==l+u); // repeat if the branches overlap
    }
    return c; // return the output
}

239 байт (я лише do{}трохи змінив речі всередині (і розмістив вкладки в першій частині for-loop). PS: У вашій початковій відповіді 0.5можна було б також пограти в гольф .5.
Кевін Круїссен

@KevinCruijssen виглядає так, що мені потрібно працювати над математикою. дякую :-)
OOBalance

3

Perl 5 , 208 124 122 118 байт

118 байт без нових рядків, відступів та коментарів. Бере N від stdin:

@b=1..2;                            #number of branches is 2
for(1..<>){                         #add length <> (the input) to each branch
  ($x,$y)=@$_                       #get where current branch has its tip now
 ,.5>rand?$x++:$y++                 #increase either x or y
 ,$o[$y][$x]++&&redo                #try again if that place is already occupied
 ,$_=[$x,$y]                        #register new tip of current branch
   for@b                            #...and do all that for each branch 
}
say map$_||!$i++?'*':$",@$_ for@o;  #output the branches

Спробуйте в Інтернеті!


Приємно, але він друкує гілки на 1 зірочку коротше, ніж вони повинні бути :)
nicael

Будь ласка, подивіться приклади моїх запитань ще раз:
nicael

Ой, я змінився 2..$Nна 1..shiftтеперішній час, а також поголив кілька байт.
Kjetil S.

1
Хороша відповідь! Ви можете зберегти кілька байтів за допомогою <>та введення замість shiftаргументів, а також переупорядкувати, якщо ви зателефонуєте, randщоб уникнути паронів. Вам не потрібно завершувати завдання на @oбудь-яке. Я спробував використовувати, @b=([],[]);що, здається, працює, але я не експериментував занадто багато, тому, можливо, я пропустив крайню справу. Сподіваюся, вони трохи допоможуть!
Дом Гастінгс

1
У радах для гри в гольф в сторінці Perl мають деякі корисні поради, не забудьте перевірити це! Хай щастить!
Дом Гастінгс



1

PHP, 118 байт

for($r="*",$w=$argn+2;$argn--;$r[$q+=rand(0,$r[$q+1]<"*")?:$w]=$r)$r[$p+=rand(!$i++,1)?:$w]=$r;echo wordwrap($r,$w-1);

для оператора Елвіса потрібен PHP 5.4 або пізнішої версії. Замінити ?:з ?1:для старіших PHP.

Запустіть як трубу -nRабо спробуйте в Інтернеті .


1
Як мені перевірити інший ввід?
нікель

@nicael: Ви можете змінити аргумент на лінії$argBak=$argn=
Гален Іванов

Добре! Не впевнений, чи це приємний спосіб чи не "прийняти" цей вклад, але нехай громада вирішить шляхом голосування
nicael

@nicael У TiO просто замініть значення для $argn. У реальному середовищі $argnпоходить від STDIN, якщо ви запускаєте його як трубу -R. Тоді він виконає код для кожного рядка введення (але я впевнений, що PHP не знімає змінні між собою; тому явні послідовні запуски швидше уникають поганих сюрпризів.)
Тит,

0

Червоний , 195 190 байт

func[n][g: func[s][i: 0 d: s while[i < n][b/(d): #"*"until[r: 1 if 1 = random 2[r: n + 1]b/(d + r) =#" "]d: d + r
i: i + 1]]b:""loop n[loop n[append b" "]append b"^/"]b/1: #"*"g n + 2 g 2 b]

Спробуйте в Інтернеті!

Читає:

f: func[n][
    g: func[s][
        i: 0
        d: s
        while[i < n][
            b/(d): #"*"
            until[
                r: 1 if 1 = random 2[r: n + 1]
                b/(d + r) = #" "
            ]
            d: d + r
            i: i + 1
        ]
    ]
    b: ""
    loop n[loop n[append b " "]append b "^/"]
    b/1: #"*"
    g n + 2
    g 2
    b
]

0

Желе , 50 43 41 байт

2ḶẊ⁸С+\‘Ṗ
⁸ÇU;Ǥ⁻Q$¿
‘,þ`⁼€þÇS+»þ`Ị$ị⁾* 

Спробуйте в Інтернеті!

Це було справді весело писати. Може бути якийсь набагато більш оптимальний метод. Можливо, в цьому методі можна також зайнятися деяким гольфом.

Одразу після того, як я опублікував це, я зрозумів, що можу використовувати ,þ`замість цього aþ,""oþ`Ɗ.


0

R , 148 142 байт

n=scan();`~`=sample;o=r=k=1;l=c(1,n);for(i in 1:n){r=r+l~1;t=l~1;k=k+"if"(k+t-r,t,l[l!=t]);o=c(o,r,k)};write(c(" ","*")[1:n^2%in%o+1],1,n,,"")

Спробуйте в Інтернеті!

Крім того, хоча це не відповідає специфікації виходу, ви можете виділити дві гілки: Спробуйте в Інтернеті!

Пояснення:

Починаючи з індексу 1, ми випадковим чином вибираємо правий або лівий хід для гілки r, додаючи nабо 1, відповідно. Потім вибираємо інший правий або лівий хід для гілки k, і якщо вона перетинатиметься куди rйде, вибираємо інший напрямок. Потім ми використовуємо rі kяк індекси m, встановлюючи ці значення як "*". Ітерація n-1разів, потім ми друкуємо результат.



0

Пітон 2 , 191 187 176 байт

from random import*
n=input()
p,q=c=1,1j;s={p,q,0}
exec'z=choice(c);q,p=p+[z,1+1j-z][p+z in s],q;s|={q};'*2*~-n
R=range(n+1)
for y in R:print''.join(' *'[y+x*1jin s]for x in R)

Спробуйте в Інтернеті!

Python має вбудовану підтримку складних чисел форми a+bj; це робить деякі 2-D проблеми трохи простежуванішими ...

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