상자 밖에서 생각하기-제대로하고 있습니까?


59

상자 밖에서 생각하는 것이 달성해야 할 목표라고 계속 들었지만, 성공적으로하고 있는지 어떻게 알 수 있습니까?

이 딜레마를 해결하기 위해 이미 Brainwave-to-ASCII 변환기를 작성했습니다. 이론적으로는 다음과 같은 출력을 생성해야합니다.

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

또는

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

상자 밖에서 생각하고 있는지 아닌지를 쉽게 알 수 있습니다. ( #출력의 일부가 아니며 새 줄을 나타냅니다.)

그러나 버그로 인해 때때로 출력의 작은 섹션 만 반환됩니다.

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

        #
       +#
       |#
inking |#

    #
    #

작업

ascii-reprensentation을 읽고 상자 안에 있는지 , 상자 외부에 있는지 또는 입력에서 알 수 없는지를 반환하는 프로그램이나 함수를 작성 하여 Brainwave-to-ASCII- 번역기 출력 을 자동으로 분류하도록 도와주십시오 thinking.

입력

목록으로 포함되거나 개행으로 구분되는 길이가 같은 문자열 세트

  • 문자열 thinking또는 유효한 접두사 또는 접미사
  • +-|직사각형 상자 또는 그 유효한 부분을 형성하는 문자
  • 공백
  • NO# , 입력 라인의 끝을 표시하기위한 시도에만 포함됩니다.

산출

  • 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+, 상자에 너무 작은 상자
Destructible Lemon

@DestructibleWatermelon 감사합니다. 비슷한 테스트 사례를 추가하겠습니다.
Laikoni

테스트 사례에서 가장 기본적인 사례가 없습니다. 생각이 담긴 상자 전체와 생각이 담긴 상자 전체를 포함하는 마음?
ATaco December

상자와 겹치는 단어가있을 가능성이 있습니까 ( 상자에 대한 생각 )?
Mukul Kumar

17
이것은 경계 사건의 악몽입니다.
Magic Octopus Urn

답변:


11

자바 스크립트 (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)))

이 함수 ftrue, 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;
};

이것으로 많은 즐거움을 가졌습니다. 감사!

편집 : @ L 덕분에 6 바이트를 절약했습니다. Serné b는 기본 인수를 사용하도록 수정 하고 3 바이트를 저장하고로 변경 [a-z]하여 3 바이트를 \w더 절약합니다. 또한, 단어 교체 비전 만들기 1 바이트를 저장하고, 변경하여 5 개 이상의 바이트를 저장 "a"5","44 바이트를 저장.


로 시도했습니다 console.log(f("input")). 작동하는 것 같습니다. 골프를 잘 했어요.
devRicher

정답입니다. 나는 이것에 대답하려고 노력했고, 도중에 막혔다. 나는이 작은 바이트 보호기주의 : 변화 b=(b,c)에를 b=(b,c=""), 그리고 당신은에 두 통화의 마지막 인자를 제거 할 수 있습니다 b(* 3-3 2 =) 총 3 바이트를 저장, 두 번째 인수로 빈 문자열. 또한, 당신의 단어 정규식이 단축 될 수 있습니다 [a-z]+\w+3 개 이상의 바이트를 저장 (이 또한 숫자와 일치하기 때문에, 다른을 대체하기 전에이 작업을 수행 참조).
Luke

PPCG에 오신 것을 환영합니다.
Kritixi Lithos

현상금이 수여되었습니다. 최단 답변. 훌륭한 직업, 놀라운 답변.
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). 다음은 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 바이트 덕분 True1<2False함께 2>1불필요한 다른 블록을 제거하여 23 바이트, 일부 구역을 제거하여 2 바이트.

편집 2 : @Wheat Wizard 덕분에 36 바이트가 절약되어 내 '탭'이 실제로 5 칸 (D' oh!)이며 다른 개선 사항을 제안했습니다.


2
감동적인. 누군가 실제로 해냈습니다.
devRicher

1
i절대 변하지 않는 것 같아요 ? 따라서 인수가 아닌 다른 코드로 호출하지 않기 때문에 저장 i.count('+')하는 c대신 바이트를 절약 할 수 i.count있습니다 +.

1
true와 false를 1 <2와 2 <1로 바꿀 수 있습니다.
Pavel

1
함수 정의에서 캐리지 리턴과 들여 쓰기를 할 필요는 없습니다. 내가 알 수있는 한 들여 쓰기에 4 개의 공백을 사용하고 있습니다. 하나의 공간을 사용하고 하나의 탭으로 깊이 2를 사용하여 깊이를 들여 쓸 수 있습니다.
밀 마법사

@WheatWizard는 이것이 당황 스럽습니다 ... Atom이 탭을 4 개의 공백으로 변환 한 것처럼 보입니다. 조언 주셔서 감사합니다, 그것은 36 바이트를 깎았습니다!
ren

8

펀칭, 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<

온라인으로 사용해보십시오!

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.