Виявити невдалі замки


40

Одним із цікавих аспектів сили тяжіння є те, що, наскільки я знаю, ви не можете просто плавати в повітрі.

Однак, схоже, не всі в Асоціації будівельників випадкових замків знають про цей факт, що призводить до таких замків:

                      #
                      #
    #  #      #  #   ###
    ####      ####   # #
    #### #  # ####   ###
    ##############   ###
    ######  ######   ###
    #####    #####   ###
                     ###
``````````````````````````````

і цей:

                                       # # #    # # #   
                                       ##############
                                       ###  ####  ###
    #  #      #  #      #  #      #  # ###  ####  ### #  #      #  #      #  #      #  #
    ####      ####      ####      #### ############## ####      ####      ####      ####
    #### #  # #### #  # #### #  # #### ## ######## ## #### #  # #### #  # #### #  # ####
    ####################################################################################
    ######  ########  ########  ########  ########  ########  ########  ########  ######
    ###################################    ######    ###################################
    ###################################    ######    ###################################
                                       ##
                                         ##
                                           ##
                                             ##
                                               ##
````````````````````````````````````````````````````````````````````````````````````````````

і навіть цей:

       ##########
   ####   #      ###
#######################
            #
              #
                #
                  #
                    #  # # #
                  #   #  ###
                   #   # ###
                # # #  #  ##
                # # ##   ###
                 #  #  #####
                   #   #####
                  # #  #####
                       #####
                       ## ##
                       #####
                       #####
                       ## ##
                       ## ##
````````````````````````````````````````````

Виклик

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

Правила

  • Введення подається у вигляді рядка.
  • Всі діючі замки спочивати на поверхні, ````````. (Якщо рядок введення не містить поверхні, замок недійсний.)
  • Ви можете припустити, що всі дані відповідають цим критеріям:
    • Поверхня завжди буде рівною.
    • Поверхня завжди буде як мінімум такою ж широкою, як замок, тому зліва чи справа від землі не буде блоків.
    • Вхід ніколи не буде #нижче поверхні.
    • Вхід буде містити лише символи, задані в цьому виклику. ( #, `пробіл або новий рядок.)
    • Ви можете припустити, що вхід завжди буде містити принаймні один символ.
  • Блоки з'єднуються, якщо вони розташовані або горизонтально, або вертикально. Діагональ не рахується!
    • Підключено:
      #	or	##
      #
    • Не з'єднано:
      #      or	# #	or	 #
      #
      #
  • Замки повинні існувати, щоб бути дійсними. (Іншими словами, вхідні дані без будь-якого #повинні давати помилкове значення.)
  • Вхід буде містити лише символи, задані в цьому виклику. ( #, `пробіл або новий рядок.)
  • Ви можете припустити, що вхід завжди буде містити принаймні один символ.
  • Застосовуються стандартні правила вводу / виводу та лазівки .

Тестові справи

Фальсі

  • Всі приклади, наведені вище.
  • # # # # 
    #### ####
    #### # # ####
    ##############
    ###### ######
    ## ### #####
    (Без землі.)
  • # 
    ### ####
    #### # # ####
    ##############
    ###### ######
    ##### # ####
    `` `` `` `` `` `` `
    (Верхній блок не з'єднаний ні горизонтально, ні вертикально.)
  •    
    `` `
    (Немає замку.)


  • # # # # # #
    ##############
    ##### ## #####
    # # # # # # # # # # #### #### # # # # # # # #
    #### #### #### #### ## #### ## #### #### #### ####
    ## ## # # #### # #### # #### # #### # # #### # #### # #### # # ####
    #################################################################### ##################################
    ###### ######## ## ###### ########################################################### ##
    ################################################### ##############################
    #################################################################### ###########################
    `` `` `` `` `` `` `` `` `` `` `` `` `` `` `` `` `` `` `` `` `` `` `` `` `` `` `` `` `` `` `` `` `` `` ` `` `` `` `` `` `` ``
    (Центральна вежа не з'єднана з іншою частиною замку, оскільки немає горизонтально або вертикально сусідніх блоків, що з'єднують її.)
  •    
    (Немає замку.)

  • (Немає замку, лише один символ нового рядка.)
  • # # 
    #
    `` `` `` `
    (Крайній правий блок не з'єднаний ні горизонтально, ні вертикально.)
  •    
    `` `
    (Немає замку.)

Truthy

  • # 
    `
  • # # # # 
    #### ####
    #### # # ####
    ##############
    ###### ######
    ## ### #####
    `` `` `` `` `` `` ``
  •                       # 
    #
    # # # # ###
    #### #### #
    #### # #### ###
    ##################
    # ###### ### #####
    ##### ##### ###
    ##### ##### ###
    `` `` `` `` `` `` `` `` `` `` `` `` `` `` ``
  •                                        # # # # # #    
    #################
    #### ###
    # # # # # # # ### #### ### # # # # # # # #
    #### #### #### #### ################## #### #### ## ##
    #### # #### # # #### # #### ## ############# # #### # # ## ## # # ####
    ############################################## ####################################################
    ## ###### ########################################################### #### ######
    ############################################ # ######################################
    #################################################################### ###########################
    `` `` `` `` `` `` `` `` `` `` `` `` `` `` `` `` `` `` `` `` `` `` `` `` `` `` `` `` `` `` `` `` `` `` `` `` `` `` `` `` `` `` `` `
  •                       #### ### 
    # #### ###
    # ###
    # ##
    #
    ###
    #####
    #######
    #########
    ### ## #####
    ##### #####
    ###### ######
    #################
    # ### ########## #
    #############
    #############
    #############
    ###### ######
    ###### ######
    ##############
    #############
    #############
    #############
    ###### ##### #
    ###### ######
    #############
    #############
    ########### ##
    #############
    ###### ######
    ###### ######
    ########### ##
    #############
    #############
    #############
    ######### ####
    ##### ##########
    ##### #####
    #####
    `` `` `` `` `` `` `` `` `` ``
  •                                                 
    ####
    #####
    ######
    ####
    ####
    #####
    ########
    ##########
    #### ######
    ###########
    ############
    ##############
    ##### ## ##############
    ########### #################
    ###########################################
    ####### #################################
    ################# ####################
    ############################## ####
    ############################
    ################## #
    `` `` `` `` `` `` `` `` `` `` `` `` `` `` `` `` `` `` `` `` `` `` `

Удачі!


Чи можемо ми припустити, що всі рядки вводу будуть однакової довжини (тобто заповнені пробілами)?
smls

@smls Ні, ви не можете припустити, що вкладка буде прокладена.
користувач2428118

1
@smls Re # 1 і # 2: Я насправді мав намір уточнити, що подання не повинно впоратися з цим, але тепер я бачу, що це не так, як я це записав. Оскільки поки що не розміщено жодних рішень, які б вирішували ці речі, я оновлю це питання, щоб зрозуміло, що вам не доведеться їх обробляти. Re # 3: Я не можу реально придумати ситуацію, коли код правильно би обробляв тестовий випадок Falsy 2, 4 і 6, але все ж не вдається виявити ситуацію, коли блоків зовсім не підключено до землі. Re # 4: Я не впевнений, що ти маєш на увазі під цим. Хіба це вже не обробляється тестом Труті №1?
користувач2428118


2
Банановий замок? НАЙКРАЩИЙ ЗАМІК ВСЕ
Меттью Рох

Відповіді:


11

Равлики , 21 18 байт

-3 байти через додаткові обмеження на введення, відредаговані на виклик.

!{t=\#!(\#o`+\`}\#

На жаль, складність часу є факторіальною, тому більшість вхідних даних не можна виконати.

Виходи 0 для хибних випадків і кількість #справжніх справ.

                 ,,
!{ t             ,, Assert that nowhere in the grid,
    =\#          ,, there is a '#'
    !(           ,, such that there does not exist
        (\# o)+  ,, an orthogonally connected path of '#'
        \`       ,, ending at a '`'
    )            ,,
}                ,,
\#               ,, Match '#' at starting position

Це не визнає приклад, який ви опублікували у відповіді Згарба як замок. Я нічого не бачу в правилах, який би сказав, що їх не слід визначати як замки? Правила лише кажуть, що це замок, якщо кожен #з'єднаний із землею.
Мартін Ендер

@ Zgarb Ні, в поясненні +є помилка - насправді 1 або більше разів, а не 0. це все одно буде виглядати інакше після дозволу відключених замків.
feersum

9

Октава, 53 51 байт

@(s)([~,n]=bwlabel(s>32,4))|n==1&&nnz(diff(+s)==61)

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

* Оскільки виникла вимога перевірити наявність порожнього введення, відповідь повернена до моєї першої редагування

Пояснення:

nnz(s)                       check for empty input
([~,n]=bwlabel(s~=' ',4))    label nonempty regions and count number of labels

n==1                         check if number of labels is 1.

nnz(diff(+s)==61)            check if blocks connected to the surface

6

Грим , 29 байт

C=\`|\#&<0C>oX
e`\#&C!v#!&\##

Спробуйте в Інтернеті! Більшість тестових випадків вичерпано на TIO. Замінити <0C>з , <0CoF>щоб зробити його трохи швидше.

Пояснення

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

C=\`|\#&<0C>oX  First line:
C=               Define nonterminal C as
  \`             the literal `
    |            or
     \#          the literal #
       &<  >     which is contained in a larger rectangle
         0C      containing said literal adjacent to a match of C
            oX   rotated by any multiple of 90 degrees.
e`\#&C!v#!&\##  Second line:
e`               Match entire input against this pattern:
         !       does not
       v#        contain
  \#             the literal #
    &C!          which is not a match of C,
          &      and
             #   contains
           \#    the literal #.

6

JavaScript (ES6), 197 196 байт

f=(s,l=Math.max(...s.split`\n`.map(t=>t.length)),t=s.replace(/^.*/g,t=>t+' '.repeat(l-t.length)),u=t.replace(eval('/(#|`)([^]{'+l+'})?(?!\\1)[#`]/g'),'`$2`'))=>t==u?/#/.test(s)>/#/.test(t):f(s,l,u)

Де \nпредставляє буквальний символ нового рядка. Намагається видалити всі #s по одному, знайшовши один із сусідніх до a `і змінивши його на a `. Повертається, trueякщо #спочатку був принаймні один, але всі були вилучені. Версія, що потребує додаткового введення для 118 117 байт:

f=(s,t=s,u=t.replace(eval('/(#|`)([^]{'+s.search`\n`+'})?(?!\\1)[#`]/'),'`$2`'))=>t==u?/#/.test(s)>/#/.test(t):f(s,u)

5

Perl 6 , 180 байт

{?/\#/&&?all map ->\c{my \b=[map {[$^a.comb]},.lines];sub f(\y,\x){with b[y;x] ->$_ {b[y;x]=0;/\#/??f(y+(1|-1),x)|f(y,x+(1|-1))!!/\`/??1!!|()}}(|c)},map {|($++X ^$^a.comb)},.lines}

Перевіряє, чи містить вхід щонайменше один #, і чи кожен #може знайти шлях до а `.

Швидше неефективна, тому що наведення маршруту вимушене за допомогою рекурсивної функції, яка завжди відвідує всі інші #ті ж підключені області (тобто не має короткого замикання).

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


5

Пітон 3 , 214 206 байт

def f(s):
 C=s.split('\n');n=max(map(len,C));o=[''];C=[*''.join(t.ljust(n)for t in C+o)]
 while C>o:o=C;C=['`'if z>' 'and'`'in{C[i+y]for y in(1,-1,n,-n)}else z for i,z in enumerate(C)]
 return'#'in{*s}-{*C}

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

Перший рядок тут присвячений прокладці всіх рядків на однакову довжину: ми розділяємо рядок ( s.split('\n')на один знак коротший за s.splitlines()), знаходимо максимальну довжину рядка та присвоюємо C вирівняний список усіх символів після прокладки кожного рядок. (Нові рядки пішли.)

Потім ми робимо список, де кожен непробільний символ, що примикає щонайменше до одного backtick, замінюється backtick, і продовжуємо, поки не відбулося жодної зміни (коли старий список oдорівнює C. Ми можемо порівняти з C>oзамість того, C!=oщо замінюємо # (ASCII 35 ) з `(ASCII 96) може збільшити лише лексикографічне впорядкування списку.)

Якщо не залишилося жодного #, і принаймні один був присутній спочатку, замок дійсний.

  • Збережено вісім байтів, перевіряючи на # у встановленій різниці, а не '#'in s and'#'not in C
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.