Думать нестандартно - правильно ли я делаю?


59

Я постоянно слышу, что нестандартное мышление - это цель, которую стоит достичь, но как я могу определить, успешно ли я это делаю?

Чтобы решить эту дилемму, я уже написал переводчик Brainwave-to-ASCII, который в теории должен давать такие результаты, как

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

или же

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

что позволяет довольно легко определить, мыслит ли человек нестандартно или нет. (Не #являются частью вывода и представляют новые строки.)

Однако из-за ошибки иногда возвращается только меньшая часть вывода:

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

        #
       +#
       |#
inking |#

    #
    #

Задание

Пожалуйста, помогите мне автоматически классифицировать выходные данные Brainwave-to-ASCII -translator, написав программу или функцию, которая читает ascii-reprensentation и возвращает информацию о том, 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+"

Falsy:

                    #
   +------------+   #
   |   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 / falsy значения и является одинаковым для всех , может быть-входов. Это также может быть ошибкой.
  • Вы можете предположить, что входные данные всегда действительны (например, не содержит никаких других символов кроме +-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=""), и затем вы можете удалить последний аргумент двух вызовов to bс пустой строкой в ​​качестве второго аргумента, сохранив (2 * 3-3 =) 3 байта. Кроме того, вы можете сократить слово regex от [a-z]+до \w+(сделайте это до замены других, потому что это также будет соответствовать цифрам), сохранив еще 3 байта.
Лука

Добро пожаловать в PPCG и хороший первый ответ!
Критиси Литос

Награжден наградами. Кратчайший ответ. Отличная работа, потрясающий ответ.
devRicher

8

Python 2.7, 532 494 453 байта

У этого наверняка было много особых случаев. Моими истинными и ложными значениями являются строки «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]

В моей версии для гольфа я показываю ответ True / False по телефону exit(bool as string). Вот закомментированная версия, в которой операторы выхода заменены на операторы возврата, и все было перенесено в функцию:

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 байта благодаря предложению @ Pavel заменить Trueна 1<2и Falseс 2>123 байтов путем удаления ненужного блока else, и 2 байта путем удаления некоторых пробелов.

Редактировать 2: Сохранено 36 байт благодаря @Wheat Wizard, который любезно указал, что мои «вкладки» на самом деле были 5 пробелами (черт!) И предложил некоторые другие улучшения.


2
Впечатляет. Кто-то на самом деле сделал это.
devRicher

1
Я думаю, что iникогда не меняется, верно? Таким образом, вы, вероятно, могли бы сохранить несколько байтов, сохраняя i.count('+')в, cа не i.count, как вы никогда не вызываете это ни с каким аргументом, кроме +.

1
Вы можете заменить true и false на 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.