Лісовий шлях


9

Після катастрофічної їзди на каное , ви закінчилися падінням водоспаду в кінці річкових порогів. Ваше каное вибухнуло, але вам вдалося пережити вибух. Однак ваша річкова мандрівка вийшла повністю з карти - тепер ви опинилися загубленими посеред лісу. На щастя, у вас все ще є навички програмування, тому ви вирішили вирізати програму в сторону дерева, щоб допомогти вам знайти шлях через ліс. Однак на дереві не дуже велика площа поверхні, тому ви повинні зробити свою програму якомога коротшою.

Ліс може бути описаний як з nдопомогою n( n > 5) квадратом символів, який буде складатися тільки з малих літер a-z. Приклад лісу:

anehcienwlndm
baneiryeivown
bnabncmxlriru
anhahirrnrauc
riwuafuvocvnc
riwnbaueibnxz
hyirorairener
ruwiiwuauawoe
qnnvcizdaiehr
iefyioeorauvi
quoeuroenraib
cuivoaisdfuae
efoiebnxmcsua

Можливо, ви помітили, що в цьому лісі є діагональна лінія aсимволів, що проходить через нього від лівого верхнього кута до нижнього правого кута. Це "стежка" через ліс, яка приведе вас кудись, якщо ви будете слідувати за нею. Ваше завдання - написати програму, яка знайде єдиний шлях. Зараз я більш детально опишу, що означає «шлях» у цьому виклику.

У цьому виклику "шлях" визначається як лінія, подібна до тієї, яка могла бути сформована за допомогою алгоритму Брезена , але з додатковими вимогами, які:

  • Рядок повинен бути не менше 6 символів
  • Кожна колінеарна (повністю суміжна) група символів у рядку повинна бути однакової довжини .
  • Він розпочнеться на одному краю лісу і закінчиться на протилежному краю (див. Мій коментар тут для опрацювання)

Щоб пояснити другу вимогу більш чітко, розглянемо наступний рядок:

aaa
   aaa
      aaa
         aaa
            aaa

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

a
 aa
   a
    aa
      a
       aa

Цей рядок складається з колінеарних "сегментів", які не всі точно однакової довжини символів (деякі з них мають довжину 1 символу, а деякі - 2). Таким чином, цей не кваліфікується як шлях.

Вашій програмі, надавши карту лісу, визначте символи, які використовуються на шляху. Вхід є тим, що є зручним (наприклад, аргумент командного рядка, STDIN prompt()тощо). Вона не може бути попередньо ініціалізована в змінну. Перша частина вводу - це єдине ціле число, що nпредставляє розмір лісу (ліс - це завжди квадрат). Після цього - пробіл, а потім і весь ліс, як одна струна. Наприклад, приклад лісу буде представлений у якості вхідного матеріалу, як це:

13  anehcienwlndmbaneiryeivownbnabncmxlriruanhahirrnraucriwuafuvocvncriwnbaueibnxzhyirorairenerruwiiwuauawoeqnnvcizdaiehriefyioeorauviquoeuroenraibcuivoaisdfuaeefoiebnxmcsua

Вихід для цього буде:

a

тому що шлях утворюється за допомогою букви a. У лісі буде лише одна стежка. Це код гольфу, тому виграє найменша кількість символів. Якщо у вас є питання, запитайте в коментарях.


Що робити, якщо є кілька шляхів?
Ерік Треслер

@EricTressler У будь-якому лісі буде лише одна стежка. Я відредагую специфікацію, щоб це відобразити.
абсент

Чи може букву шляху використовувати десь в іншому місці, де він не належить до шляху?
Мартін Ендер

Приклад лісу містить це так, ймовірно. Перший а на цій лінії в прикладі лісу не є частиною шляху anhahirrnrauc
Лопата

@ MartinBüttner Так. Але вони не будуть двома шляхами, зробленими з однієї і тієї ж літери в будь-якій точці.
абсент

Відповіді:


3

APL (Діалог 14) (70)

⎕ML←3⋄Z/⍨1=≢¨Z←∪¨(↓⍉F),(↓F),{(⍳≢⍵)⌷¨↓⍵}¨(⊂F),⊂⌽F←⊃{⍵⍴⍨2/⍎⍺}/I⊂⍨' '≠I←⍞

Пояснення:

  • ⎕ML←3: Встановити MLв 3, значення має APL2 значення.
  • I←⍞: прочитати рядок з клавіатури та зберегти його I
  • I⊂⍨' '≠I: розділити Iна пробіли
  • {... }/: застосувати цю функцію до двох результуючих рядків:
    • 2/⍎⍺: оцініть лівий аргумент і повторіть його двічі, задавши розмір матриці
    • ⍵⍴⍨: форматувати правильний аргумент, використовуючи цей розмір
  • F←⊃: розпакуйте його та збережіть у F.
  • {(⍳≢⍵)⌷¨↓⍵}¨(⊂F),⊂⌽F: отримайте діагоналі: з кожного рядка в обох Fі ⌽F(вертикально дзеркально F) отримайте значення у стовпці X, де X - його номер рядка
  • (↓⍉F),(↓F),: отримати рядки та стовпці F
  • Z←∪¨: знайдіть унікальні значення у кожному рядку, стовпчику та діагоналі та збережіть їх Z.

Оскільки "ліс" прямокутний, якщо є дійсний шлях, це означає, що один з них буде складатися лише з одного символу, який є символом шляху, так:

  • Z/⍨1=≢¨Z: візьміть ті підрядні масиви, Zякі мають лише один елемент.

Це відображатиме символи для всіх дійсних шляхів, але оскільки має бути лише один, який не має значення.


4

Луа - 506 380 - байт

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

a=io.read"*l"n=a:match("%d+")+0 m=a:match"[a-z]+"o=""for i=1,n do for k=1,n^2,n do o=o..m:sub(i+k-1,i+k-1)end end q={m,o}for g=1,n^2 do for u=1,2 do l=q[u]:sub(g,g)for r=1,n do i=1 t=0 e=0 while i do s,e=q[u]:find(l:rep(r),e+1)if s then x=s-(e-s)-i-1 print(s,i,r,n,r)if x==n or x==n-2 or t==0 then t=t+1 i=s end else i=nil end end if t*r==n then print(l)os.exit()end end end end

Його можна перевірити за допомогою:

lua divisorPath.lua "input"

Якщо з'явиться дикий претендент, я погляну, щоб пограти у свій код, на що він вартий.

Оновлення : гольф на честь тих, хто підніметься над нами. Поки я був на ньому, мені довелося виправити свій код на розпізнаний шлях, що йде справа наліво. На жаль


3

MATLAB - 270 символів

Далі визначається функція, xяка приймає лісовий рядок як аргумент і повертає символ, що представляє дійсний "шлях" через ліс, за умови поданих правил.

function F=x(s),A=sscanf(s,'%d%s');n=A(1);A=reshape(A(2:end),n,n);for c=A(:)',B=A==c;for i=1:n,if~mod(n,i),C=[kron(eye(i),ones(n/i,1)),zeros(n,n-i)];for j=0:n-i,f=@(B)sum(sum(B&circshift(C,[0,j]))==n;D=fliplr(B);if f(B)|f(B')|f(D)|f(D'),F=char(c);end;end;end;end;end;end

Нескорочена версія є

function F = x(s)
    A = sscanf( s, '%d %s' );
    n = A(1);
    A = reshape( A(2:end), n,n );
    for c = A(:)'
        B = A==c;
        for i = 1:n
            if ~mod( n, i )
                C = [kron( eye(i), ones( n/i,1 ) ), zeros( n,n-i )];
                for j = 0:n-i
                    f = @(B) sum(sum( B & circshift( C, [0 j] ))) == n;
                    D = fliplr(B);
                    if f(B) | f(B') | f(D) | f(D')
                        F = char(c);
                    end
                end
            end
        end
    end
end

Основна передумова - побудувати булеву маску для кожного можливого допустимого шляху та повернути будь-який символ, функція індексу якого в матриці охоплює будь-яку маску. Для цього створюються лише вертикальні або вертикальні маски зворотнього косого кута, але лісова матриця порівнюється у всіх чотирьох орієнтаціях: ідентичність, перевернута, повернена на 90 °, повернута повернена на 90 °.

Функція працює для будь-якого n. Прикладом його виклику в командному рядку є

x('13 anehcienwlndmbaneiryeivownbnabncmxlriruanhahirrnraucriwuafuvocvncriwnbaueibnxzhyirorairenerruwiiwuauawoeqnnvcizdaiehriefyioeorauviquoeuroenraibcuivoaisdfuaeefoiebnxmcsua')

ans =

    a

3

Пітон - 384 325 275

Цей алгоритм в основному перевіряє перший і останній рядок матриці на відповідність символів, а потім обчислює довжину кожного сегмента рядка

012345
------
aaVaaa|0
aaVaaa|1
aaaVaa|2
aaaVaa|3
aaaaVa|4
aaaaVa|5

У наведеному вище прикладі:
V в першому рядку знаходиться в індексі 2, V в останньому рядку в індексі 4.
Отже, довжина кожного сегмента рядка буде n / (4-2) +1 = 2 з n = 6 .

Потім він перевіряє, чи рядок дійсний.

Для того, щоб знайти шлях зліва направо, він міняє рядки стовпцями і робить те ж саме знову.

Редагувати: Неможливо досягти 270 (Чорт ти Python і твій проклятий відступ !!)

n,m=raw_input().split()
n,r=int(n),range
t=r(n)
a=[m[i:i+n]for i in r(0,n*n,n)]
for v in a,["".join([a[i][j]for i in t])for j in t]:
 for i in t:
  for j in t:
   p=1-2*(j-i<0);d,c=p*(j-i)+1,v[0][i]
   if 6<=sum([v[z][i+(z/(n/d))*p*(n%d==0)]==c for z in t])==n:print c;exit()
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.