Suy nghĩ bên ngoài hộp - Tôi đang làm đúng không?


59

Tôi cứ nghe rằng suy nghĩ bên ngoài chiếc hộp là một mục tiêu đáng để đạt được, nhưng làm thế nào tôi có thể biết nếu tôi thực hiện thành công?

Để giải quyết vấn đề nan giải này, tôi đã viết một bộ chuyển đổi Brainwave-to-ASCII mà theo lý thuyết sẽ tạo ra các kết quả đầu ra như

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

hoặc là

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

Điều này làm cho nó khá dễ dàng để biết liệu người ta có suy nghĩ bên ngoài hộp hay không. ( #Không phải là một phần của đầu ra và đại diện cho các dòng mới.)

Tuy nhiên, do lỗi đôi khi chỉ một phần nhỏ hơn của đầu ra được trả về:

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

        #
       +#
       |#
inking |#

    #
    #

Nhiệm vụ

Vui lòng giúp tôi tự động phân loại đầu ra của bộ điều khiển Brainwave-to-ASCII bằng cách viết chương trình hoặc chức năng đọc phần lặp lại và trả về dù thinkingcó trong hộp, bên ngoài nó hay không thể biết được từ đầu vào.

Đầu vào

Một tập hợp các chuỗi có cùng độ dài dưới dạng danh sách hoặc được phân tách bằng các dòng mới chứa

  • chuỗi thinkinghoặc tiền tố hoặc hậu tố hợp lệ của chúng
  • các ký tự +-|tạo thành một hộp hình chữ nhật hoặc các phần hợp lệ của nó
  • không gian
  • KHÔNG# , những điều đó chỉ được bao gồm trong thử thách để đánh dấu các đầu của dòng đầu vào.

Đầu ra

  • một truthy giá trị nếu thinkinglà ngoài vòng cấm địa
  • một falsy giá trị nếu thinkinglà trong hộp
  • một giá trị thứ ba khác biệt có thể có giá trị nếu không thể xác định được từ đầu vào cho dù thinkingcó trong hộp hay không

Ví dụ

Sự thật:

                   #
 +------+          #
 |      | 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")
---#

Là đầu vào chuỗi:

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

Giả mạo:

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

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

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

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

-#
n#
-#

Là đầu vào chuỗi:

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

Có lẽ:

thinking#

g|#

think#
-----#

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

   +--#
   |  #

# (empty input)

Là đầu vào chuỗi:

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

Quy tắc

  • Đây là , vì vậy hãy cố gắng sử dụng càng ít byte càng tốt.
  • Các thể giá trị có thể được chọn tự do miễn là nó khác với giá trị truthy / falsy và là như nhau cho tất cả có lẽ-đầu vào. Nó cũng có thể là một lỗi.
  • Bạn có thể giả sử rằng đầu vào luôn hợp lệ (ví dụ: không chứa ký tự nào khác ngoài +-ghiknt|, không quá một hộp, ...).

Ý tưởng cho trường hợp kiểm tra trung thực : +\n+, hộp quá nhỏ cho một từ
Lemon

@DeststallibleWateriwi Cảm ơn, tôi sẽ thêm một trường hợp thử nghiệm tương tự.
Laikoni

Bạn không có trường hợp cơ bản nhất trong trường hợp thử nghiệm của bạn. Tâm trí bao gồm toàn bộ hộp với suy nghĩ trong đó, và toàn bộ hộp với toàn bộ suy nghĩ bên ngoài nó?
ATaco

Có một khả năng của từ chồng lên hộp (suy nghĩ trên hộp )?
Mukul Kumar

17
Đây là một cơn ác mộng trường hợp ranh giới, jeez.
Bạch tuộc ma thuật Urn

Câu trả lời:


11

Javascript (ES6), 274 263 byte

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)))

Hàm ftrả về true, falsehoặc -1là giá trị "có thể" của nó. Nó nên được gọi với một đối số: đầu vào. Hai tham số khác chỉ tồn tại để rút ngắn mã.

Đây là một phiên bản ít chơi gôn hơn với các bình luận:

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;
};

Có rất nhiều niềm vui với điều này. Cảm ơn!

Chỉnh sửa: Đã lưu 6 byte nhờ @L. Serné bằng cách sửa đổi bđể sử dụng một đối số mặc định, lưu 3 byte và thay đổi [a-z]thành \w, tiết kiệm thêm 3 byte. Cũng tiết kiệm được 5 byte bằng cách làm cho việc thay thế từ phi toàn cầu, tiết kiệm 1 byte, và thay đổi "a"đến 5","để 4, tiết kiệm 4 byte.


Đã thử với console.log(f("input")). Có vẻ để làm việc. Tuyệt vời về việc chơi golf này.
devR Rich

Công việc tốt trên câu trả lời. Tôi đã cố gắng trả lời điều này, và tôi bị kẹt giữa chừng. Tôi nhận thấy 2 trình tiết kiệm byte nhỏ: thay đổi b=(b,c)thành b=(b,c="")và sau đó bạn có thể xóa đối số cuối cùng của hai lệnh gọi bvới một chuỗi rỗng làm đối số thứ hai, tiết kiệm tổng cộng (2 * 3-3 =) 3 byte. Ngoài ra, bạn có thể rút ngắn regex từ [a-z]+thành \w+(làm điều này trước khi thay thế khác, bởi vì điều này cũng sẽ khớp với các chữ số) tiết kiệm thêm 3 byte.
Lu-ca

Chào mừng bạn đến với PPCG và câu trả lời đầu tiên tốt đẹp!
Kritixi Lithos

Được thưởng tiền thưởng. Câu trả lời ngắn nhất. Công việc tuyệt vời, câu trả lời tuyệt vời.
devR Rich

8

Python 2.7, 532 494 453 byte

Điều này chắc chắn đã có rất nhiều trường hợp đặc biệt. Giá trị trung thực và giả của tôi lần lượt là các chuỗi "Đúng" và "Sai". Giá trị có thể của tôi là Lỗi chỉ mục, vì chúng dễ kích hoạt và một trong những trường hợp thử nghiệm của tôi sẽ kích hoạt nó nếu đầu vào là một chuỗi rỗng, dù sao đó cũng là trường hợp có thể xảy ra. Tôi đã sử dụng các biểu thức thông thường khá một chút.

Tôi không chơi gôn trên trăn thường xuyên, vì vậy tôi chắc chắn rằng điều này có thể được đánh gôn nhiều hơn, nhưng đây là mã của tôi:

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]

Trong phiên bản chơi gôn của mình, tôi hiển thị câu trả lời Đúng / Sai bằng cách gọi exit(bool as string). Đây là một phiên bản được nhận xét, trong đó các câu lệnh thoát được thay thế bằng câu lệnh trả về và mọi thứ đã được chuyển vào một hàm:

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()

Giải pháp của tôi giả định rằng đầu vào là hợp lệ, tức là 'Suy nghĩ' (hoặc các chuỗi con của nó) được viết đúng chính tả, chỉ có một hộp duy nhất, v.v.

Chỉnh sửa: Đã lưu 10 byte nhờ đề xuất của @ ais523 để thay đổi cthành i.count('+')3 byte nhờ đề xuất thay thế Truebằng 1<2Falsebằng 2>123 byte của @ Pavel bằng cách xóa một khối khác không cần thiết và 2 byte bằng cách xóa một số khoảng trắng.

Chỉnh sửa 2: Đã lưu 36 byte nhờ @Wheat Wizard, người vui lòng chỉ ra rằng 'tab' của tôi thực sự là 5 khoảng trắng (D'oh!) Và đề xuất một số cải tiến khác.


2
Ấn tượng. Ai đó thực sự đã làm nó.
devR Rich

1
Tôi nghĩ ikhông bao giờ thay đổi, phải không? Vì vậy, bạn có thể có thể tiết kiệm một số byte bằng cách lưu trữ i.count('+')trong chơn là i.count, như bạn không bao giờ gọi nó với bất kỳ tranh cãi nhưng +.

1
Bạn có thể thay thế đúng và sai bằng 1 <2 và 2 <1, phải không?
Pavel

1
Bạn không phải trả lại vận chuyển và thụt lề trong định nghĩa chức năng của bạn. Theo như tôi có thể nói với bạn là sử dụng 4 khoảng trắng để thụt lề. Bạn có thể thụt vào độ sâu một bằng cách sử dụng một khoảng trắng và độ sâu 2 bằng một tab duy nhất.
Thuật sĩ lúa mì

@WheatWizard, điều này thật xấu hổ ... có vẻ như Atom đã chuyển đổi các tab thành 4 khoảng trắng. Cảm ơn vì lời khuyên, nó đã loại bỏ 36 byte!
ren

8

Befunge, 535 byte

Điều này không hay, và không thể cạnh tranh với các câu trả lời hiện có, nhưng đó là điều tốt nhất tôi có thể đạt được trong Befunge.

Trả 1nếu suy nghĩ bên ngoài hộp, 0nếu suy nghĩ bên trong hộp, và -1cho lẽ .

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<

Hãy thử trực tuyến!

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.