跳出框框思考-我做对了吗?


59

我一直在听,跳出框框思考是一个值得实现的目标,但是如何判断我是否成功完成了目标呢?

为了解决这个难题,我已经写了一个Brainwave-to-ASCII转换器,理论上应该产生类似

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

要么

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

这样就很容易判断一个人是否在跳槽。(#不在输出中,代表新行。)

但是,由于错误,有时仅返回输出的较小部分:

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

        #
       +#
       |#
inking |#

    #
    #

任务

请帮助我编写一个程序或函数来自动对Brainwave-to-ASCII -translator输出进行分类,该程序或函数读取ascii表示并返回是否thinking在框中,在框外还是无法从输入中分辨出来。

输入项

一组相同长度的字符串,以列表形式或由包含以下内容的换行符分隔

  • 字符串thinking或有效的前缀或后缀
  • +-|构成矩形框或其有效部分的字符
  • 空格
  • #,这些仅包括在挑战中以标记输入线的末端。

输出量

  • 一个truthy值,如果thinking是外箱
  • 一个falsy值,如果thinking是在框中
  • 如果无法根据输入确定是否在框中,则为第三个可能的thinking

例子

真相:

                   #
 +------+          #
 |      | 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 / falsy值不同,并且是对所有可能-输入相同的选择。这也可能是错误。
  • 您可以假定输入始终是有效的(例如,除了+-ghiknt|,不超过一个框,不包含其他字符,...)。

真实测试用例的想法:+\n+,框太小了一个字
破坏的柠檬

@DestructibleWatermelon谢谢,我将添加一个类似的测试用例。
Laikoni '16

您的测试用例中没有最基本的用例。头脑中包括思考的整个盒子,以及思考之外的整个单词的整个盒子?
ATaco

有没有这个词重叠盒(思想成为了可能,包装盒上的)?
Mukul Kumar

17
jeez,这是一场极端的噩梦。
魔术章鱼缸

Answers:


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返回truefalse-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。通过修改b为使用默认参数来实现Serné ,保存3个字节,然后更改[a-z]\w,再保存3个字节。此外,通过使单词替换非全局,节省了1个字节,并改变保存5个字节"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'1

获得赏金。最短的答案。干得好,答案很棒。
devRicher

8

Python 2.7版,532个 494 453字节

这肯定有很多特殊情况。我的真实和虚假值分别是字符串“ True”和“ False”。我的值也许是一个索引错误,因为它们很容易触发,并且如果输入是空字符串,则我的一个测试用例会触发它,无论如何这都是可能的情况。我充分利用了正则表达式。

我不经常在python中打高尔夫球,因此我敢肯定这可以进一步打高尔夫球,但这是我的代码:

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)。这是一个注释版本,其中exit语句替换为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()

我的解决方案假定输入有效,即“ Thinking”(或其子字符串)的拼写正确,只有一个方框,依此类推。

编辑:保存由于@ ais523的建议10个字节改变ci.count('+'),3个字节由于@取代的Pavel的建议True1<2False2>1通过去除不需要的其他块,23个字节,2个字节通过除去一些空格。

编辑2:感谢@Wheat向导,节省了36个字节,后者善意地指出我的“标签”实际上是5个空格(D'哦!),并提出了其他一些改进。


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<

在线尝试!

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.