Мислення поза коробкою - чи я це роблю правильно?


59

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

Для вирішення цієї дилеми я вже написав перекладач Brainwave-ASCII, який теоретично повинен давати результати

                    #
   +------------+   #
   |   thinking |   #
   |            |   #
   +------------+   #
                    #

або

                   #
 +------+          #
 |      | thinking #
 |      |          #
 |      |          #
 +------+          #
                   #

які дозволяють досить легко сказати, думає хтось поза коробкою чи ні. (Вони #не є частиною результату і являють собою нові рядки.)

Однак через помилку іноді повертається лише менша частина виводу:

   |         |         #
   +---------+         #
    thinking           #

        #
       +#
       |#
inking |#

    #
    #

Задача

Будь ласка, допоможіть мені автоматично класифікувати вихідний перекладач Brainwave-to-ASCII , написавши програму або функцію, яка зчитує репрезентацію ascii та повертає, чи thinkingзнаходиться в полі, поза ним, чи він не міг сказати з вводу.

Вхідні дані

Набір рядків однакової довжини або як список, або розмежоване новими рядками, що містять

  • рядок thinkingабо їх дійсні префікси або суфікси
  • символи, що +-|утворюють прямокутну коробку або дійсні її частини
  • пробіли
  • НІ# , вони включені лише в завдання, щоб позначити кінці рядків введення.

Вихід

  • truthy значення , якщо thinkingзнаходиться поза коробки
  • falsy значення , якщо thinkingв коробці
  • виразний третій, можливо, значення, якщо його не можна визначити з вхідних даних, чи thinkingє в полі чи ні

Приклади

Truthy:

                   #
 +------+          #
 |      | thinking #
 |      |          #
 |      |          #
 +------+          #
                   #

   |         |         #
   +---------+         #
    thinking           #

        #
       +#
       |#
       |#
inking |#

thinking #
-------+ #

 ++ # (thinking is not in the box, so it must be outside)
 ++ # (this is also the smallest possible box)

+ #
 t#

+----+# (The box is not wide enough to contain "thinking")

---# (The box is not high enough to contain "thinking")
---#

Як рядок введення:

"                   \n +------+          \n |      | thinking \n |      |          \n |      |          \n +------+          \n                   "
"   |         |         \n   +---------+         \n    thinking           "
"        \n       +\n       |\n       |\ninking |"
"thinking \n-------+ "
" ++ \n ++ "
"+ \n t"
"+----+"
"---\n---"
"g++"
"k\n+"

Фальсі:

                    #
   +------------+   #
   |   thinking |   #
   |            |   #
   +------------+   #
                    #

  +---------------#
  |               #
  |               #
  |   thinking    #

      | #
king  | #
------+ #

+---#
|thi#
+---#

-#
n#
-#

Як рядок введення:

"                    \n   +------------+   \n   |   thinking |   \n   |            |   \n   +------------+   \n                    "
"  +---------------\n  |               \n  |               \n  |   thinking    "
"      | \nking  | \n------+ "
"+---\n|thi\n+---"
"-\nn\n-"

Може бути:

thinking#

g|#

think#
-----#

|          |# (box large enough to possibly contain the string)
|          |#

   +--#
   |  #

# (empty input)

Як рядок введення:

"thinking"
"g|"
"|t"
"-\ni"
"h\n-"
"think\n-----"
"|          |\n|          |"
"   +--\n   |  "
""

Правила

  • Це , тому постарайтеся використовувати якомога менше байтів.
  • Значення, можливо, може бути вибране вільно, якщо воно відрізняється від значення truthy / falesy і є однаковим для всіх можливостей. Це також може бути помилка.
  • Ви можете припустити, що вхід завжди дійсний (наприклад, не містить інших символів +-ghiknt|, не більше одного поля, ...).

Ідея для пробного тесту:, +\n+скринька занадто мала для слова
руйнівний лимон

@DestructibleWatermelon Спасибі, я додам подібний тестовий випадок.
Лайконі

У ваших тестових випадках у вас немає найосновніших випадків. Розум, включаючи всю скриньку з думкою в ній, і всю скриньку з усім словом, що думає поза ним?
ATaco

Чи є можливість слова перекривати коробку (думаючи про коробку )?
Мукул Кумар

17
Це прикордонний кошмар, джез.
Чарівна урва восьминога

Відповіді:


11

Javascript (ES6), 274 263 байт

f=(a,b=(b,c="")=>a=a.replace(b,c),c=b=>b.test(`,${a},`))=>(b(/\w+/,5),b(/\+/g,1),b(/\-/g,2),b(/\|/g,3),b(/\n/g,4),c(/[13][2 ]{0,7}[13]|[12] *4 *[12]/)||(b(/ /g),b(/43+(?=4)/g),!c(/353|24542|12+435|21453|35412|5342+1/)&&(!c(/^([^1]*|([^15]*1){1,2}[^15]*)$/)||-1)))

Функція fповертає true, falseабо -1як його "можливо" значення. Його слід викликати одним аргументом: введенням. Два інших параметра існують лише для скорочення коду.

Ось менш гольф-версія з коментарями:

var f = (input) => {
    var replace = (re, s) => input = input.replace(re, s);
    var test = re => re.test(input);

    /*
        Replace some "special" characters with ones that are shorter to put in a regex.
        "+" --> "1"
        "-" --> "2"
        "|" --> "3"
        "\n" --> ","
    */
    replace(/\+/g,1);
    replace(/\-/g,2);
    replace(/\|/g,3);
    replace(/\n/g,',');

    /*
        Shorten the word, if there is one, to just a single character "a".
    */
    replace(/[a-z]+/g,'a');

    /*
        Append a newline to the beginning and end of the input.
    */
    input = ','+input+',';

    /*
        Test the size of the box. These are the cases covered:
        /[13][2 ]{0,7}[13]/ : A horizontal edge or middle section has an inner width of fewer than 8 characters.
        /[12] *, *[12]/     : There are two horizontal edges in a row, with no space between.

        If either of these match, the word must be outside of the box. Return the truthy value (true).
    */
    if (test(/[13][2 ]{0,7}[13]|[12] *, *[12]/)) return true;

    /*
        Remove any spacing from the input. It it unnecessary from this point onwards.
    */
    replace(/ /g,'');

    /*
        Remove any lines with only vertical bars. These are also unnecessary.
    */
    replace(/,3+(?=,)/g,'');

    /*
        Edge / corner cases (heh). These are the cases covered:
        /3a3/    : two vertical bars with the word between.
        /2,a,2/  : two horizontal bars with the word between.
        /12+,3a/ : word inside the top left corner.
        /21,a3/  : word inside the top right corner.
        /3a,12/  : word inside the bottom left corner.
        /a3,2+1/ : word inside the bottom right corner.

        If any of these match, the word is inside the box. Return the falsy value (false).
    */
    if (test(/3a3|2,a,2|12+,3a|21,a3|3a,12|a3,2+1/)) return false;

    /*
        "Maybe" cases. These are the cases covered:
        /^[^1]*$/                : Input contains no corners, and may or may not contain a word.
        /^([^1a]*1){1,2}[^1a]*$/ : Input contains 1 or 2 corners, and no word.

        If either of these match, assuming the previous test cases have not been hit,
        we cannot tell if the word is inside or outside the box. Return the maybe value (-1).
    */
    if (test(/^([^1]*|([^1a]*1){1,2}[^1a]*)$/)) return -1;

    /*
        If none of the previous cases matched, the word must be outside of the box. Return the truthy value (true).
    */
    return true;
};

З цим весело повеселилось. Дякую!

Редагувати: Збережено 6 байт завдяки @L. Serné шляхом модифікації bвикористовувати аргумент за замовчуванням, економлячи 3 байта, і зміна [a-z]в \w, економлячи більше 3 байта. Також збережено ще 5 байт, зробивши заміну слова неглобальним, зберегти 1 байт та змінити "a"на 5та, ","щоб 4зберегти 4 байти.


Спробував с console.log(f("input")). Здається, працює. Чудова робота з гольфу в цьому.
devRicher

Гарна робота на відповідь. Я спробував відповісти на це, і я застряг наполовину. Я помітив 2 маленьких байти-хранитель: зміна b=(b,c)в b=(b,c=""), а потім ви можете видалити останній аргумент з двох викликів bз нового рядка в якості другого аргументу, збереження (2 * 3-3 =) 3 байта в цілому. Крім того, ви можете скоротити слово regex з [a-z]+до \w+(зробіть це до того, як інший замінить, оскільки це також буде відповідати цифрам), зберігаючи ще 3 байти.
Лука

Ласкаво просимо до PPCG та приємної першої відповіді!
Kritixi Lithos

Нагороджений щедротою. Найкоротша відповідь. Чудова робота, дивовижна відповідь.
devRicher

8

Python 2.7, 532 494 453 байт

У цього впевнено було багато особливих випадків. Мої значення truthy та хибності - це рядки "True" та "False" відповідно. Моє значення, можливо, - це помилка індексу, оскільки їх легко запустити, і один з моїх тестових випадків викликає це, якщо вхід є порожнім рядком, що, можливо, так і є. Я використав регулярні вирази зовсім небагато.

Я не займаюсь гольфами в пітоні часто, тому впевнений, що це могло би бути ще більше, але ось мій код:

import re
def e(s):exit(str(s))
i=input()
T=1<2
F=2<1
a=len(i)+1
c=i.count('+')
s='[a-z]'
x=re.search
p=x(s,i)
k=x('\+.*'+s,i)
l=x(s+'.*\|',i)
r=x('\|.*'+s,i)
f=i.find('+')
g=i[f-1]=='-'and f>0
if x('\-.*\n.*\-',i):e(T)
if x('\+.{0,7}\+',i):e(T)
if c>1 and not p:i[a]
if c>3:e(not(r and l))
if c>0:
 if r and l:e(F)
 if g:
    if l:e(F)
    if p or k:e(T)
    i[a]
 if r or k:e(F)
 if p:e(T)
 i[a]
if x('-.*\s[a-z].*\s-',i):e(F)
if x('\|.*[a-z].*\|',i):e(F)
i[a]

У моїй версії для гольфу я відображаю відповідь Правда / Неправда, зателефонувавши exit(bool as string). Ось коментована версія, в якій оператори виходу замінюються операторами return, і все переміщено у функцію:

import re
i=input()
T=True
F=False
def z():
    # some variables and shortcuts useful for testing

    # length of input +1. Used to throw an index out of bounds error on 'maybe'
    a=len(i)+1
    # c for i.Count()
    c=i.count
    # string used in regular expressions often
    s='[a-z]'
    # shorten regeX calls
    x=re.search
    # p is true is 'thinking' is Present on canvas
    p=x(s,i)
    # k is true if 'thinking' is Right of a 'Korner' (corner)
    k=x('\+.*'+s,i)
    # l is true if 'thinking' is Left of a pipe (|)
    l=x(s+'.*\|',i)
    # r is true if 'thinking' is right of a pipe
    r=x('\|.*'+s,i)
    # f is First corner (+) index
    f=i.find('+')

    # g is true if box is facing riGht (i.e. there is a dash before the first +)
    # for example, '---+' indicates the box faces right. if the + is the 0th
    # character, then the box must be facing left.
    # Note that this assignment also checks for the empty string 'maybe'
    # case, which is signalled by an IndexOutofBounds error
    # CASE 1: Empty Input
    # ex: ''
    g=i[f-1]=='-' and f>0

    # Begin testing all possible scenarios

    # CASE 2: Box is too short (vertically)
    # ex: ------
    #     ------
    if x('\-.*\n.*\-',i):return T

    # CASE 3: box is too short (horizontally)
    # ex: ||
    if x('\+.{0,7}\+',i):return T

    # CASE 4: box is not too short yet no corners (+) or text are present on canvas
    # ex:
    # |       |         --------
    # |       |   or
    # |       |         --------
    # this is a maybe case, so throw out of bounds error
    if c('+')>1 and not p:i[a]

    # CASE 5: Four corners visible (whole box visible)
    # ex: +---+
    #     | X |
    #     +---+
    # return false if text is both right of and left of pipes (i.e. in box)
    if c('+')>3:return not(r and l)

    # CASE 6: one or two corners visible
    # ex:
    # ----+        |    |          |
    #     |    or  +----+   or  ---+  etc
    # ----+
    # in this case, we idenify which way the box faces
    if c('+')>0:

        # CASE 6-A: Text is between two pipes
        # ex:
        #     |   X   |
        #     +-------+
        # if text is between pipes (box is extending from top or bottom of
        # canvas), then it is inside box
        if r and l:return F

        # CASE 6-B: Box faces right
        # if the box is riGht-facing, ex:
        # ----+
        #     |    or  ----+  etc
        # ----+            |
        if g:

            # CASE 6-B-a: Letters are left of a pipe or a + in a right facing box
            # ----+
            #  X  |   or  ----+
            # ----+         X |
            if l :return F

            # CASE 6-B-b: Letters are right of a pipe or + in a right facing box
            # ----+
            #     | X  or  ----+
            # ----+            | X
            if p or k:return T

            # CASE 6-B-c: right-facing otherwise
            # otherwise, it is a 'maybe' case
            # use an index out of bounds error to signal 'maybe'
            i[a]

        # CASE 6-C: Box faces left (or letters are on canvas yet not inside box)
        # ex:
        #   +----
        #   |        or   +---  or
        #   +----         |
        else:

            # CASE 6-C-a: Letters are right of a pipe or a + in a left facing box
            # if letters are right of pipe, they are inside box, ex:
            #   +----
            #   | X       or   +---  or X +---
            #   +----          | X        |
            if r or k:return F

            # CASE 6-C-b: Letters are left of a pipe in a left facing box
            # ex:
            #     +----
            #   X |        or     +---
            #     +----         X |

            # CASE 6-C-c: Letters are on canvas yet not left or right of
            # a pipe or a + (they must therefore be outside the box)
            # ex:
            #  |     |
            #  +-----+
            #     X
            if p:return T

            # CASE 6-C-d: text is not visible on canvas, and only part of the box is
            # ex:
            #  |     |
            #  +-----+
            #
            # this is a 'maybe' case, as text is off canvas
            # use an index out of bounds error to signal 'maybe'
            i[a]

    # CASE 7: No corners visible, nonempty input

    # CASE 7-A: No corners visible, letters sandwitched between dashes
    # ex:
    # -----
    #   X
    # -----
    # if there are no corners, yet letters are sandwitched between dashes,
    # then word is in box
    if x('-.*\s[a-z].*\s-',i):return F

    # CASE 7-B: No corners visible, letters sandwitched bewteen pipes
    # ex: |  X  |
    # in this case, word is inside box
    if x('\|.*[a-z].*\|',i):return F

    # If none of the above cases are met, it is a maybe, so throw the error
    i[a]

print z()

Моє рішення передбачає, що введення дійсне, тобто "Мислення" (або його підрядки) написано правильно, є лише одне поле тощо.

Редагувати: Збережено 10 байт завдяки пропозиції @ ais523 змінити cна i.count('+'), 3 байти завдяки пропозиції @ Павла замінити Trueна 1<2та Falseз 2>1, 23 байти шляхом видалення непотрібного блоку else та 2 байти шляхом видалення деяких пробілів.

Редагувати 2: Збережено 36 байтів завдяки майстру @Wheat, який люб’язно зазначив, що мої «вкладки» насправді були 5 пробілами (D'oh!) Та запропонував деякі інші вдосконалення.


2
Вражає. Хтось насправді це зробив.
devRicher

1
Я думаю, що iніколи не змінюється, правда? Таким чином, ви, ймовірно, можете зберегти деякі байти, зберігаючи i.count('+')в, cа не i.count, як ви ніколи не називаєте це жодним аргументом, але +.

1
Ви можете замінити істинне і хибне на 1 <2 і 2 <1, правда?
Павло

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

@WheatWizard добре це хизує ... схоже, Atom перетворював вкладки на 4 місця. Дякуємо за пораду, вона збрила 36 байт!
рен

8

Befunge, 535 байт

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

Повертає , 1якщо думати поза коробки, 0якщо думати , всередині коробки, і -1для можливо .

p10p20p130p140p150p9-:60p70p"~":80p90pvp8p04+1:g04p03:$p9g04+g9g\<<
0$$$$"xxxx"5p041p031p$_v#!-+55:_v#`0:~<p05+1g
v01g04$_v#*`\"|"\`"-"::<>0g\8\p"0"-!!40g1-\8\p:4-!:00g0`*!:00g\6\p40g\8\p00g!*4v
>p50g20p>8%:30g88+*+:3-v4v\-1g05!!*-"3"\-"4"::p\7\g05!!-3:+*+88g8g04:p00+g00*g0<
v!*-"3"\-"5"::p\6\g04!!<!>>7\p::"C"-\"3"-*!!50g\9\p"0"-!!50g1-\9\p:5-!:40g9g48*v
>!40g1-\6\p::"S"-\"3"-*!^>0#4g#p9#\g#94#\8#g*#0-#5!#p*#\5#70#\g#-*^#84g9g04:!*`<
>80g60g-8`90g70g-1`**+!:10g80g`60g10g`20g90g`70g20g`+++!!*\!-.@
^!g01***`"}"g09`"}"g08`g070`g060<

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

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