คิดนอกกรอบ - ฉันทำถูกไหม?


59

ฉันได้ยินอยู่เสมอว่าการคิดนอกกรอบนั้นเป็นเป้าหมายที่ควรได้รับ แต่ฉันจะบอกได้อย่างไรว่าฉันทำสำเร็จ

เพื่อแก้ปัญหานี้ฉันได้เขียนBrainwave-to-ASCII -translator ซึ่งในทางทฤษฎีควรสร้างผลลัพธ์เช่น

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

หรือ

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

ซึ่งทำให้ค่อนข้างง่ายที่จะบอกว่ามีใครคิดนอกกรอบหรือไม่ (ส่วน#นี้ไม่ได้เป็นส่วนหนึ่งของเอาต์พุตและแสดงบรรทัดใหม่)

อย่างไรก็ตามเนื่องจากข้อผิดพลาดบางครั้งเฉพาะส่วนเล็ก ๆ ของการส่งออกจะถูกส่งกลับ:

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

        #
       +#
       |#
inking |#

    #
    #

งาน

โปรดช่วยฉันจัดประเภทเอาต์พุตคลื่นสมองต่อ ASCIIโดยอัตโนมัติโดยการเขียนโปรแกรมหรือฟังก์ชั่นที่อ่าน ascii-repensentation และคืนค่าว่าthinkingอยู่ในกล่องนอกหรือไม่สามารถบอกได้จากอินพุต

อินพุต

ชุดของสตริงที่มีความยาวเท่ากันไม่ว่าจะเป็นรายการหรือคั่นด้วยการขึ้นบรรทัดใหม่ที่มี

  • สตริงthinkingหรือ pre- หรือคำต่อท้ายที่ถูกต้องของมัน
  • อักขระ+-|ขึ้นรูปกล่องสี่เหลี่ยมหรือชิ้นส่วนที่ถูกต้องของมัน
  • ช่องว่าง
  • ไม่สิ่ง#เหล่านั้นรวมอยู่ในการท้าทายเพื่อทำเครื่องหมายจุดสิ้นสุดของบรรทัดอินพุต

เอาท์พุต

  • 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 ขอบคุณฉันจะเพิ่มกรณีทดสอบที่คล้ายกัน
Laikoni

คุณไม่มีกรณีพื้นฐานที่สุดในกรณีทดสอบของคุณ คิดรวมทั้งกล่องทั้งหมดด้วยความคิดในนั้นและทั้งกล่องด้วยคำทั้งหมดคิดนอก?
ATaco

มีความเป็นไปได้ของคำที่ซ้อนทับกล่อง (คิดบนกล่อง ) หรือไม่?
Mukul Kumar

17
นี่คือฝันร้ายกรณีขอบเขต jeez
Magic Octopus Urn

คำตอบ:


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เป็นของมัน "อาจจะ" คุ้มค่า มันควรจะถูกเรียกว่ามีหนึ่งอาร์กิวเมนต์: อินพุต อีกสองพารามิเตอร์มีอยู่เพื่อย่อรหัสเท่านั้น

นี่คือเวอร์ชัน golfed น้อยพร้อมความคิดเห็น:

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 ไบต์

อันนี้แน่นอนว่ามีกรณีพิเศษมากมาย ค่าความจริงและเท็จของฉันคือสตริง "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)คำตอบเท็จโดยการเรียก นี่คือเวอร์ชันที่มีความเห็นซึ่งคำสั่ง 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()

วิธีแก้ปัญหาของฉันสมมติว่าอินพุตถูกต้องเช่น 'การคิด' (หรือสตริงย่อย) สะกดอย่างถูกต้องมีเพียงกล่องเดียว ฯลฯ

แก้ไข: บันทึก 10 ไบต์ด้วยคำแนะนำของ @ ais523 เพื่อเปลี่ยนcเป็นi.count('+')3 ไบต์ขอบคุณคำแนะนำของ @ Pavel ในการแทนที่Trueด้วย1<2และFalseด้วย2>1ขนาด 23 ไบต์โดยการลบบล็อกอื่นที่ไม่จำเป็นออกและ 2 ไบต์โดยการลบช่องว่างบางส่วนออก

แก้ไข 2: บันทึกแล้ว 36 ไบต์ขอบคุณ @Wheat Wizard ที่กรุณาชี้ให้เห็นว่า 'แท็บ' ของฉันมี 5 ช่องว่าง (D'oh!) และแนะนำการปรับปรุงอื่น ๆ


2
ประทับใจ มีคนทำจริง
devRicher

1
ฉันคิดว่าiไม่เคยเปลี่ยนแปลงใช่ไหม ดังนั้นคุณอาจจะสามารถบันทึกไบต์ได้ด้วยการเก็บi.count('+')ไว้cมากกว่าi.countเพราะคุณไม่เคยเรียกมันว่ามีอาร์กิวเมนต์อะไร+เลย

1
คุณสามารถแทนที่จริงและเท็จด้วย 1 <2 และ 2 <1 ใช่ไหม?
Pavel

1
คุณไม่ต้องปัดแคร่และเยื้องในนิยามฟังก์ชันของคุณ เท่าที่ฉันสามารถบอกได้ว่าคุณใช้ช่องว่าง 4 ช่องสำหรับการเยื้อง คุณสามารถเยื้องลงไปที่ระดับความลึกโดยใช้พื้นที่เดียวและความลึก 2 ด้วยแท็บเดียว
ข้าวสาลีตัวช่วยสร้าง

@Weateat ตัวช่วยสร้างนี้น่าอาย ... ดูเหมือนว่า Atom จะแปลงแท็บเป็น 4 ช่องว่าง ขอบคุณสำหรับคำแนะนำมันโกนออก 36 ไบต์!
ren

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<

ลองออนไลน์!

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.