Обнаружить провальные замки


40

Одним из интересных аспектов гравитации является то, что, насколько я знаю, нельзя просто плавать в воздухе.

Однако, кажется, не все в Ассоциации Строителей Случайных Замков знают об этом факте, что приводит к таким замкам, как этот:

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

и этот:

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

и даже этот:

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

Вызов

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

правила

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

Контрольные примеры

Falsy

  • Все примеры приведены выше.
  • # # # # 
    #### ####
    #### # # ####
    ##############
    ###### ######
    ## ### #####
    (Нет земли.)
  • # 
    ### ####
    #### # # ####
    ##############
    ###### ######
    ##### # ####
    `` `` `` `` `` `` ``
    (Верхний блок не связан ни горизонтально, ни вертикально.)
  •    
    `` `
    (Нет замка.)


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

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

Truthy

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

Удачи!


Можем ли мы предположить, что все строки ввода будут одинаковой длины (то есть заполнены пробелами)?
smls

@smls Нет, вы не можете предполагать, что ввод будет дополнен.
user2428118

1
@smls Re # 1 и # 2: Я на самом деле хотел указать, что представления не должны обрабатывать это, но теперь я вижу, что это не так, как я записал это. Поскольку еще не опубликовано ни одного решения, которое бы справлялось с этими вещами, я обновлю вопрос, чтобы было ясно, что вам не нужно обращаться с ними. Re # 3: Я не могу придумать ситуацию, когда код правильно обрабатывал бы тестовые примеры 2, 4 и 6 Falsy и все же не смог обнаружить ситуацию, когда вообще нет блоков, соединенных с землей. Re # 4: Я не уверен, что вы подразумеваете под этим. Разве это уже не обрабатывается тестовым набором № 1 « Правда» ?
user2428118


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. Она все равно будет выглядеть иначе после разрешения отсоединенных замков.
17

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>чтобы сделать его немного быстрее.

объяснение

Я проверяю, что из каждого #существует путь к a `, и что существует хотя бы один #. Недавно я добавил команды вращения в 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

Python 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 плоский список всех символов после заполнения каждого. линия. (Новые строки исчезли.)

Тогда составьте список , где каждый не пробел смежна по крайней мере , один обратный апостроф заменяется на обратный апостроф, и продолжать до тех пор никаких изменений не произошло (когда старый список 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.