箱の外で考える-私はそれを正しくやっていますか?


59

枠を超えて考えることは達成する価値のある目標であると聞き続けていますが、うまくやっているかどうかはどうすればわかりますか?

このジレンマを解決するために、理論的には次のような出力を生成するBrainwave-to-ASCII -translatorをすでに作成しました。

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

または

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

これにより、枠外で考えているかどうかを簡単に判断できます。(これら#は出力の一部ではなく、新しい行を表します。)

ただし、バグのために、出力の小さなセクションのみが返される場合があります。

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

        #
       +#
       |#
inking |#

    #
    #

タスク

ascii-reprensentationを読み取り、ボックス内にあるか、その外側にあるか、入力から認識できないかを返すプログラムまたは関数を記述することにより、BrainwaveからASCIIへの変換出力を自動的に分類するのを手伝ってくださいthinking

入力

リストとして、または次を含む改行で区切られた同じ長さの文字列のセット

  • 文字列thinkingまたはその有効なプリまたはサフィックス
  • +-|長方形の箱またはその有効な部分を形成する文字
  • スペース
  • NO#、これらはチャレンジに含まれており、入力行の終わりをマークします。

出力

  • 箱の外にある場合、真のthinking
  • ボックス内にある場合、偽のthinking
  • 入力からボックス内にあるかどうかを判断できない場合、明確な3番目の多分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|、1つ以上のボックス、...)。

真実のテストケースのアイデア:+\n+、言葉で言えばボックスが小さすぎる
破壊可能なレモン

@DestructibleWatermelonありがとう、同様のテストケースを追加します。
ライコニ16

テストケースには、最も基本的なケースはありません。考えているボックス全体と、考えていない言葉全体を含むボックス全体を含むことに注意してください。
アタコ16

ボックス(思考の重複単語のpossiblityありますボックスには)?
ムクルクマール

17
これは境界の悪夢です。
魔法のタコUr

回答:


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その「多分」値として。これは、入力という1つの引数で呼び出す必要があります。他の2つのパラメーターは、コードを短縮するためにのみ存在します。

コメント付きのゴルフの少ないバージョンは次のとおりです。

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バイトを保存しました。bデフォルト引数を使用するように変更[a-z]\w、3バイトを節約し、さらにに変更して、さらに3バイトを節約することにより、Serné 。また、単語の置き換えが非グローバル作る1つのバイトを保存し、変更することにより、5つの以上のバイトを保存"a"する5","する44バイトを保存し、。


で試してみましたconsole.log(f("input"))。動作しているようです。これをゴルフするのは素晴らしい仕事です。
-devRicher

答えはいいですね。私はこれに答えようとしましたが、途中で立ち往生しました。2つの小さなバイトセーバーに気付きました:に変更b=(b,c)b=(b,c="")b2番目の引数として空の文字列を使用して、2つの呼び出しの最後の引数を削除し、合計で2バイトを節約できます(2 * 3-3 =)。また、単語regexを[a-z]+toに短縮して\w+(他の置換の前にこれを行うと、これも数字と一致するため)、さらに3バイト節約できます。
ルーク

PPCGへようこそ。
クリティキシリソス

賞金を受賞。最短回答。素晴らしい仕事、素晴らしい答え。
devRicher

8

パイソン2.7、532の 494 453バイト

これには確かに多くの特別なケースがありました。私の真実と偽の値は、それぞれ文字列「True」と「False」です。私の多分値はインデックスエラーです。トリガーが簡単であり、入力が空の文字列である場合、私のテストケースの1つはそれをトリガーします。正規表現をかなり活用しました。

私は頻繁に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」(またはその部分文字列)のスペルが正しく、ボックスが1つしかないなどです。

編集:保存された10バイトに変更するには、@のais523の提案に感謝ci.count('+')置き換えるのパヴェルの提案@に、3バイトのおかげTrue1<2Falseして2>1、23バイトのいくつかのスペースを削除することで、不要なelseブロック、および2つのバイトを除去すること。

編集2:私の「タブ」は実際には5つのスペースであると親切に指摘し、他のいくつかの改善を提案した@Wheat Wizardのおかげで36バイトを節約しました。


2
印象的。誰かが実際にそれをやった。
devRicher

1
i変わらないと思いますよね?ですから、おそらく引数を指定して呼び出すことはできませんが、で保存i.count('+')するcよりもi.count、いくつかのバイトを保存できます+

1
trueとfalseを1 <2と2 <1に置き換えることができますか?
パベル

1
関数定義で復帰やインデントを行う必要はありません。私が知る限り、インデントに4つのスペースを使用しています。1つのスペースを使用して深さ1、1つのタブで深さ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<

オンラインでお試しください!

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.