息子が手紙を見つけるのを手伝ってください


17

バックグラウンド

私の4歳の彼のラビから得たゲームに基づいています。

「目標」は、特定の順序で文字を「見つける」ことaecdbです。レターカードのスタックが与えられますdaceb。周期的ではありますが、指定された順序でのみスタックを検索できます。必要な手紙に出会ったら、それをスタックから取り出します。

目的

順序とスタック(相互の重複のない順列)を指定すると、ゲームのプレイ中に表示される一連の最上位スタック文字(すべて印刷可能なASCII)を見つけます。

ステップバイステップの例

aecdbスタックを指定して順序を見つける必要がありますdaceb

スタックのトップd:探しているもの(a)ではないため、シーケンスに追加しd、スタックを取得するために回転します:acebd

スタックのトップa:はい!したがって、シーケンスに追加daし、スタックから削除します:cebd

スタックのトップc:探しているもの(e)ではないため、シーケンスに追加しdac、スタックを取得するために回転します:ebdc

スタックのトップe:はい!したがって、シーケンスに追加daceし、スタックから削除します:bdc

スタックのトップb:探しているもの(c)ではないため、シーケンスに追加しdaceb、スタックを取得するために回転します:dcb

スタックのトップd:探しているもの(c)ではないため、シーケンスに追加しdacebd、スタックを取得するために回転します:cbd

スタックのトップc:はい!したがって、シーケンスに追加dacebdcし、スタックから削除します:bd

スタックのトップb:探しているもの(d)ではないため、シーケンスに追加しdacebdcb、スタックを取得するために回転します:db

スタックのトップd:はい!したがって、シーケンスに追加dacebdcbdし、スタックから削除します:b

スタックのトップb:はい!したがって、シーケンスに追加dacebdcbdbし、スタックから削除します:

これで完了です。結果はdacebdcbdbです。

リファレンス実装

def letters(target, stack):
    string = ''
    while stack:
        string += stack[0]
        if stack[0] == target[0]:
            stack.pop(0)
            target = target[1:]
        else:
            stack.append(stack.pop(0))
    return string

print letters('aecdb', list('daceb'))

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

テストケース

tryyrtyrtyry

123443214321432434

ABCDEFGHIJKLMNOPQRSTUVWXYZRUAHYKCLQZXEMPBWGDIOTVJNSFRUAHYKCLQZXEMPBWGDIOTVJNSFRUHYKCLQZXEMPWGDIOTVJNSFRUHYKLQZXEMPWGIOTVJNSFRUHYKLQZXMPWGIOTVJNSRUHYKLQZXMPWIOTVJNSRUYKLQZXMPWOTVNSRUYQZXPWOTVSRUYQZXPWTVSRUYQZXWTVSRUYZXWTVSUYZXWTVUYZXWVYZXWYZXYZ

???

aa a a

abcdabcdabcd

回答:


5

3つのかなり異なるメソッドが等しいバイトカウントを与えています。

Python 2、59バイト

s,t=input()
for c in s*99:
 if c in t:print c;t=t.lstrip(c)

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

各文字を独自の行に出力します。


Python 2、59バイト

lambda s,t:[c==t[0]and t.pop(0)or c for c in s*99if c in t]

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

リストを入力として受け取り、リストを出力します。


Python 3、59バイト

def f(s,t):
 for c in t:p,q=s.split(c);s=q+p;print(end=p+c)

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


1
うーん、私は最初の2つのバージョンに疑いを持っています... 99具体的にはなぜですか?
エリックアウトゴルファー

@EriktheOutgolgerこれは、少なくとも印刷可能なASCII文字の数であり、少なくとも各入力の長さです。
xnor

5

APL(Dyalog Classic)、21バイト

∊⊢,⊢∘⊂~¨(,\⊣⊂⍨1,2>/⍋)

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

これは次と同等の列車です {∊⍵,(⊂⍵)~¨(,\⍺⊂⍨1,2>/⍺⍋⍵)}

左引数に右引数の順列を与える

1,2>/連続するペアを>1と比較して先頭に追加します

⍺⊂⍨上記のブールマスクを使用してグループに分割します。マスクの1は、新しいグループの開始を示します

,\ グループの累積連結

(⊂⍵)~¨ に関してそれぞれの補数

⍵, 付け加える

単一の文字列としてフラット化


4

バッチ、155バイト

@set/pt=
@set/ps=
@set r=
:l
@set c=%s:~,1%
@set r=%r%%c%
@if %c%==%t:~,1% set t=%t:~1%&set c=
@set s=%s:~1%%c%
@if not "%t%"=="" goto l
@echo %r%

STDINの入力としてターゲットとスタックを受け取ります。


4

JavaScript(ES6)、54バイト

ターゲットを文字列として、スタックを文字の配列として受け取ります。文字列を返します。

f=(t,[c,...s])=>t&&c+f(t.slice(c==t[0]||!s.push(c)),s)

テストケース

どうやって?

各反復cで、スタックの一番上の文字を抽出し、最終結果に追加します。次に、パラメータがの結果に依存する再帰呼び出しを実行します。c == t[0]ここで、t[0]は予想される次の文字です。

c一致する場合t[0]

  • c渡すことでターゲット文字列から削除しますt.slice(1)
  • 変更せずにc渡すことでスタックから削除しますs

c一致しない場合t[0]

  • を渡すことでターゲット文字列を変更させません t.slice(0)
  • cスタックの最後にプッシュバックします



3

Haskell49 46バイト

q@(a:b)#(c:d)|a==c=a:b#d|e<-d++[c]=c:q#e
a#_=a

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

かなり簡単です。左の引数は「目標」であり、右の引数はスタックです。目標の先頭がスタックの先頭に一致する場合、先頭に追加し、残りの目標とスタックで繰り返します(先頭にアイテムを追加し直すことはありません)。それ以外の場合は、一番上のアイテムを先頭に追加し、同じ目標で繰り返し、スタックの最後まで一番上のアイテムを読み取ります。目標が空の場合、パターンマッチングは2行目を選択し、空のリストが返されます。

編集:@GolfWolfと@Laikoniのおかげで-3バイト!





1
@GolfWolfの2番目のソリューション(およびライコニのソリューション)は機能しません。(:)および(#)の演算子の優先順位のため、「yrtyry」ではなく「ytrty」が生成されます-user1472751
1


1

Java 8、88バイト

a->b->{for(int c:a)for(char t=0;c!=t;System.out.print(t)){t=b.poll();if(c!=t)b.add(t);}}

char[]and としての入力java.util.LinkedList<Character>java.util.Queue実装)

説明:

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

a->b->{                        // Method with two parameters and no return-type
  for(int c:a)                 //  Loop over the characters of the char-array
    for(char t=0;c!=t;         //   Inner loop until we've found the character in the queue
        System.out.print(t)){  //     After every iteration: print the char `t`
      t=b.poll();              //    Remove the top of the queue, and save it in `t`
      if(c!=t)                 //    If this is not the character we're looking for:
        b.add(t);}}            //     Add it at the end of the queue again

1

> <>38 32バイト

編集:ティールペリカンには、入力メソッドを交換するはるかに優れた><>アプローチがあります

0[i:0(1$.
\~~l]1+{$[&
/?=&:&:o:{

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

-sフラグを介して文字の順序を取得し、入力を介してスタックを取得します。

使い方:

0[.... Creates a new empty stack
...... This puts the order of the letters safely away
......

..i:0(1$. Takes input until EOF (-1). This means input is in reverse
..~...    And then teleports to the ~ on this line
......

......      Gets the first character from the beginning of the order
\.~l]1+{$[& And stores it in the register before going to the next line
/.....

......     Output the bottom of the stack
......     Checks if the bottom of the stack is equal to the current character
/?=&:&:o:{ If so, go to the second line, else cycle the stack and repeat

0.....      Pop the extra 0 we collected
\~~l]1+{$[& Pop the value that was equal and get the next character from the order
/.....      And go down to the last line. This will end with an error (which could be avoid with a mere 4 extra bytes


1

> <>21 16バイト

i$\~~
=?\$:{::o@

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

空のスペースを利用して余分なコードの再ルーティングを削除するようにフローが変更されました。(-5バイト)-@JoKingに感謝

> <>、21バイト

i:{:@=?v:o$!
o~i00. >

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

他の<>回答はここにあります。

説明

スタックは、-sフラグを使用した最初の文字セットで始まります。入力は、ユーザーが指定した文字順です。この説明は、コードの流れに従います。

i$\        : Take input, swap the top 2 stack items then move to line 2;
             [1,2,3] -> [1,2,4,3]
  \$:      : Swap the top 2 stack items then duplicate the top item;
             [1,2,4,3] -> [1,2,3,4,4]
     {::o  : Move the stack items 1 left then duplicate the stack top twice and print one;
             [1,2,3,4,4] -> [2,3,4,4,1,1]
=?\      @ : Swap the top three stack items left 1 then do an equal comparison, if equality move to line 1 else continue;
             [2,3,4,4,1,1] -> [2,3,4,1,1,4] -> [2,3,4,1]
  \~~      : Remove the top 2 stack items;
             [2,3,4,1] -> [2,3]

そうそう、そのように入力するのはもっと理にかなっています笑
ジョーキング


1
これらの冗長化が離れて行くのルーティングを作ることは非常に素敵な変化を、私もオフ余分なバイトを取るに抵抗できなかった- @JoKing:のP
ティールペリカン

0

Perl、62バイト

sub{$_=$_[1];for$x(@{$_[0]}){/\Q$x\E/;$z.="$`$&";$_="$'$`"}$z}

最初の引数である順序を文字のリストとして、2番目の引数であるスタックを文字列として受け取ります。

ゴルフをしていない:

sub {
    $_ = $_[1];
    for $x (@{$_[0]}) {
        /\Q$_\E/;
        $z.="$`$&";
        $_ = "$'$`"
    }
    $z
}

これらのあいまいな正規表現変数が何のためにあるのか不思議に思ったことはありませんか?明らかに、彼らはこの正確な挑戦のために設計されました。現在の文字に一致します$x(残念ながら、正規表現の特殊文字の場合はエスケープする必要があります)。これにより、文字列が「一致の前」$`、「一致」$&、および「一致後」に便利に分割され$'ます。巡回検索では、一致する前のすべての文字が明確に表示され、スタックに戻されました。現在のキャラクターも見ましたが、元に戻しませんでした。したがって、「見られる」リストに「一致する前」を追加し、「$z一致後」と「一致する前」の順にスタックを構築します。


0

SNOBOL4(CSNOBOL4)、98バイト

	S =INPUT
	L =INPUT
R	S LEN(1) . X REM . S	:F(END)
	OUTPUT =X
	L POS(0) X =	:S(R)
	S =S X	:(R)
END

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

各文字を改行で印刷します。このバージョンを使用して、すべてを同じ行に印刷します。入力をスタックとして、次にターゲットとして、改行で区切って受け取ります。

	S =INPUT			;*read stack
	L =INPUT			;*read letters
R	S LEN(1) . X REM . S	:F(END)	;*set X to the first letter of S and S to the remainder. If S is empty, goto END.
	OUTPUT =X			;*output X
	L POS(0) X =	:S(R)		;*if the first character of L matches X, remove it and goto R
	S =S X	:(R)			;*else put X at the end of S and goto R
END

0

Perl、44バイト

含み+4のために-lF

ターゲットとしてSTDINのように入力してからスタックします(これは例の逆の順序です)。

(echo daceb; echo aecdb) | perl -lF -E '$a=<>;say,$a=~s/^\Q$_//||push@F,$_ for@F'

末尾の改行を気にしない場合、これは40動作します:

(echo daceb; echo aecdb) | perl -plE '$_=<>=~s%.%s/(.*)\Q$&//s;$_.=$1;$&%reg'
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.