Giúp con trai tôi tìm thư của mình


17

Lý lịch

Dựa trên một trò chơi, đứa con bốn tuổi của tôi đã nhận được từ giáo sĩ của mình.

"Mục tiêu" là "tìm" các chữ cái theo một thứ tự nhất định, vd aecdb. Bạn được cấp một chồng thẻ thư, vd daceb. Bạn chỉ có thể tìm kiếm thông qua ngăn xếp theo thứ tự cho trước, mặc dù theo chu kỳ. Khi bạn gặp một lá thư bạn cần, bạn lấy nó ra khỏi ngăn xếp.

Mục tiêu

Đưa ra một thứ tự và một ngăn xếp (hoán vị không trùng lặp của nhau), tìm chuỗi các chữ cái ngăn xếp trên cùng (tất cả đều là ASCII có thể in được) mà bạn thấy trong khi chơi trò chơi.

Ví dụ từng bước

Chúng ta cần tìm thứ tự aecdb, đưa ra ngăn xếp daceb:

Top of stack d: Không phải thứ chúng ta đang tìm kiếm ( a), vì vậy chúng ta thêm nó vào chuỗi: dvà xoay để lấy stack : acebd.

Đầu ngăn xếp a: Có! vì vậy chúng tôi thêm nó vào chuỗi: davà xóa nó khỏi ngăn xếp : cebd.

Top of stack c: Không phải thứ chúng ta đang tìm kiếm ( e), vì vậy chúng ta thêm nó vào chuỗi: dacvà xoay để lấy stack : ebdc.

Đầu ngăn xếp e: Có! vì vậy chúng tôi thêm nó vào chuỗi: dacevà xóa nó khỏi ngăn xếp : bdc.

Top of stack b: Không phải thứ chúng ta đang tìm kiếm ( c), vì vậy chúng ta thêm nó vào chuỗi: dacebvà xoay để lấy stack : dcb.

Top of stack d: Không phải thứ chúng ta đang tìm kiếm ( c), vì vậy chúng ta thêm nó vào chuỗi: dacebdvà xoay để lấy stack : cbd.

Đầu ngăn xếp c: Có! vì vậy chúng tôi thêm nó vào chuỗi: dacebdcvà xóa nó khỏi ngăn xếp : bd.

Top of stack b: Không phải thứ chúng ta đang tìm kiếm ( d), vì vậy chúng ta thêm nó vào chuỗi: dacebdcbvà xoay để lấy stack : db.

Đầu ngăn xếp d: Có! vì vậy chúng tôi thêm nó vào chuỗi: dacebdcbdvà xóa nó khỏi ngăn xếp : b.

Đầu ngăn xếp b: Có! vì vậy chúng tôi thêm nó vào chuỗi: dacebdcbdbvà xóa nó khỏi ngăn xếp : .

Và chúng ta đã hoàn thành. Kết quả là dacebdcbdb.

Thực hiện tham khảo

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

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

Các trường hợp thử nghiệm

try, yrtyrtyry

1234, 43214321432434

ABCDEFGHIJKLMNOPQRSTUVWXYZ, RUAHYKCLQZXEMPBWGDIOTVJNSFRUAHYKCLQZXEMPBWGDIOTVJNSFRUHYKCLQZXEMPWGDIOTVJNSFRUHYKLQZXEMPWGIOTVJNSFRUHYKLQZXMPWGIOTVJNSRUHYKLQZXMPWIOTVJNSRUYKLQZXMPWOTVNSRUYQZXPWOTVSRUYQZXPWTVSRUYQZXWTVSRUYZXWTVSUYZXWTVUYZXWVYZXWYZXYZ

?, ??

a, a a a

abcd, abcdabcd

Câu trả lời:


5

Ba phương thức khá khác nhau đang cho số byte bằng nhau.

Python 2 , 59 byte

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

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

In mỗi ký tự trong dòng riêng của nó.


Python 2 , 59 byte

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

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

Lấy danh sách làm đầu vào và xuất ra một danh sách.


Python 3 , 59 byte

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

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


1
Hừm, tôi nghi ngờ hai phiên bản đầu tiên ... tại sao 99cụ thể?
Erik the Outgolfer

@EriktheOutgolger Ít nhất là số lượng ký tự ASCII có thể in được và ít nhất là độ dài của mỗi đầu vào.
xnor

5

APL (Dyalog Classic) , 21 byte

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

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

Đây là một chuyến tàu tương đương với {∊⍵,(⊂⍵)~¨(,\⍺⊂⍨1,2>/⍺⍋⍵)}

đưa ra hoán vị của đối số phải trong đối số trái

1,2>/so sánh các cặp liên tiếp với >và đặt trước 1

⍺⊂⍨sử dụng mặt nạ boolean ở trên để chia thành các nhóm; 1s trong mặt nạ đánh dấu sự bắt đầu của một nhóm mới

,\ tích lũy của các nhóm

(⊂⍵)~¨ bổ sung của mỗi đối với

⍵, trả trước

làm phẳng như một chuỗi


4

Hàng loạt, 155 byte

@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%

Lấy mục tiêu và xếp chồng làm đầu vào trên STDIN.


4

JavaScript (ES6), 54 byte

Lấy mục tiêu là một chuỗi và ngăn xếp như một mảng các ký tự. Trả về một chuỗi.

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

Các trường hợp thử nghiệm

Làm sao?

Ở mỗi lần lặp, chúng tôi trích xuất ký tự ctrên đỉnh của ngăn xếp và nối nó vào kết quả cuối cùng. Sau đó chúng tôi thực hiện một cuộc gọi đệ quy có tham số phụ thuộc vào kết quả của c == t[0], đâu t[0]là ký tự dự kiến ​​tiếp theo.

Nếu cphù hợp t[0]:

  • chúng tôi loại bỏ ckhỏi chuỗi mục tiêu bằng cách vượt quat.slice(1)
  • chúng tôi loại bỏ ckhỏi ngăn xếp bằng cách chuyển skhông thay đổi

Nếu ckhông khớp t[0]:

  • chúng ta để chuỗi đích không thay đổi bằng cách chuyển t.slice(0)
  • chúng tôi đẩy clùi vào cuối ngăn xếp



3

Haskell , 49 46 byte

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

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

Khá đơn giản. Đối số bên trái là "mục tiêu" và bên phải là ngăn xếp. Nếu phần đầu của mục tiêu khớp với đỉnh của ngăn xếp, chúng tôi sẽ đặt trước nó và lặp lại với phần còn lại của mục tiêu và ngăn xếp (mà không cần thêm lại mục trên cùng). Mặt khác, chúng tôi trả trước mục trên cùng và lặp lại với cùng một mục tiêu, đọc mục trên cùng đến cuối ngăn xếp. Khi mục tiêu trống, kết hợp mẫu sẽ chọn dòng thứ hai và danh sách trống được trả về.

EDIT: -3 byte nhờ @GolfWolf và @Laikoni!





1
@GolfWolf giải pháp thứ hai của bạn (và Laikoni) không hoạt động. Nó tạo ra "ytrty" thay vì "yrtyry" vì quyền ưu tiên của nhà điều hành với (:) và (#)
user1472751

1

Sạch , 85 byte

import StdEnv
g l[u:v][a:b]|a==u=g[a:l]v b=g[a:l][u:v](b++[a])
g l[]_=reverse l
f=g[]

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

Xác định hàm flấy một phần [Char][Char], trong đó đối số đầu tiên là mục tiêu và thứ hai là ngăn xếp.


1

Java 8, 88 byte

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

Đầu vào là char[]java.util.LinkedList<Character>( java.util.Queuethực hiện)

Giải trình:

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

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 byte

Chỉnh sửa: Teal pelican có ><>cách tiếp cận tốt hơn ở đây là hoán đổi các phương thức nhập liệu

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

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

Lấy thứ tự của các chữ cái thông qua -scờ và ngăn xếp thông qua đầu vào.

Làm thế nào nó hoạt động:

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 byte

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

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

Flow thay đổi để sử dụng các khoảng trống và loại bỏ mã định tuyến bổ sung. (-5 byte) - Cảm ơn @JoKing

> <> , 21 byte

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

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

Câu trả lời khác> <> có thể được tìm thấy ở đây.

Giải trình

Ngăn xếp bắt đầu với một bộ ký tự ban đầu sử dụng cờ -s. Đầu vào là thứ tự nhân vật cho trước. Giải thích này sẽ theo dòng chảy của mã.

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]

Ồ vâng, nhập nó theo cách đó có ý nghĩa hơn lol
Jo King

Làm thế nào về 17 byte ?
Jo King

1
@JoKing - Thay đổi rất hay để làm cho các định tuyến dư thừa đó biến mất, tôi không thể cưỡng lại việc lấy thêm một byte mặc dù: P
Teal pelican

0

Perl, 62 byte

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

Lấy đối số đầu tiên của nó, thứ tự, như một danh sách các ký tự và thứ hai của nó, ngăn xếp, như một chuỗi.

Ung dung:

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

Bạn có bao giờ tự hỏi tất cả những biến regex tối nghĩa đó là để làm gì không? Rõ ràng, chúng được thiết kế cho thử thách chính xác này. Chúng tôi phù hợp với nhân vật hiện tại $x(không may phải thoát trong trường hợp đó là nhân vật đặc biệt regex). Điều này thuận tiện phân tách chuỗi thành "trước trận đấu" $`, "trận đấu" $&và "sau trận đấu" $'. Trong tìm kiếm theo chu kỳ, chúng tôi thấy rõ mọi nhân vật trước trận đấu và đưa họ trở lại vào ngăn xếp. Chúng tôi cũng thấy nhân vật hiện tại nhưng không đưa nó trở lại. Vì vậy, chúng tôi sẽ thêm "trước trận đấu" vào danh sách "đã thấy" $zvà xây dựng ngăn xếp ra khỏi "sau trận đấu" theo sau "trước trận đấu".


0

SNOBOL4 (CSNOBOL4) , 98 byte

	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

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

In từng chữ cái trên một dòng mới. Sử dụng phiên bản này để có được mọi thứ để in trên cùng một dòng. Lấy đầu vào là ngăn xếp, sau đó nhắm mục tiêu, cách nhau bởi một dòng mới.

	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 byte

Bao gồm +4cho-lF

Cung cấp đầu vào như trên STDIN làm mục tiêu sau đó xếp chồng (đây là thứ tự ngược lại từ các ví dụ):

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

Nếu bạn không nhớ một dòng mới, nó sẽ 40hoạt động:

(echo daceb; echo aecdb) | perl -plE '$_=<>=~s%.%s/(.*)\Q$&//s;$_.=$1;$&%reg'
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.