ช่วยลูกชายของฉันค้นหาจดหมายของเขา


17

พื้นหลัง

ขึ้นอยู่กับเกมสี่ปีของฉันได้รับจากอาจารย์ของเขา

ว่า "เป้าหมาย" คือการ "ค้นหา" aecdbตัวอักษรในการสั่งซื้อที่ได้รับเช่น dacebคุณจะได้รับบัตรสแต็คของตัวอักษรเช่น คุณสามารถค้นหาได้จากสแต็กตามลำดับที่กำหนดแม้ว่าจะเป็นแบบวนรอบเท่านั้น เมื่อคุณพบจดหมายที่คุณต้องการคุณจะนำมันออกมาจากกอง

วัตถุประสงค์

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

ตัวอย่างทีละขั้นตอน

เราจำเป็นต้องค้นหาคำสั่งที่aecdbได้รับกองdaceb:

ด้านบนของสแต็คd: ไม่ได้สิ่งที่เรากำลังมองหา ( a) เพื่อให้เราเพิ่มเข้าไปในลำดับ: และหมุนที่จะได้รับสแต็ค:dacebd

ด้านบนของสแต็คa: ใช่! เพื่อให้เราเพิ่มเข้าไปในลำดับ: และนำออกจากสแต็ค:dacebd

ด้านบนของสแต็คc: ไม่ได้สิ่งที่เรากำลังมองหา ( e) เพื่อให้เราเพิ่มเข้าไปในลำดับ: และหมุนที่จะได้รับสแต็ค:dacebdc

ด้านบนของสแต็คe: ใช่! เพื่อให้เราเพิ่มเข้าไปในลำดับ: และนำออกจากสแต็ค:dacebdc

ด้านบนของสแต็คb: ไม่ได้สิ่งที่เรากำลังมองหา ( c) เพื่อให้เราเพิ่มเข้าไปในลำดับ: และหมุนที่จะได้รับสแต็ค:dacebdcb

ด้านบนของสแต็คd: ไม่ได้สิ่งที่เรากำลังมองหา ( c) เพื่อให้เราเพิ่มเข้าไปในลำดับ: และหมุนที่จะได้รับสแต็ค:dacebdcbd

ด้านบนของสแต็คc: ใช่! เพื่อให้เราเพิ่มเข้าไปในลำดับ: และนำออกจากสแต็ค:dacebdcbd

ด้านบนของสแต็คb: ไม่ได้สิ่งที่เรากำลังมองหา ( d) เพื่อให้เราเพิ่มเข้าไปในลำดับ: และหมุนที่จะได้รับสแต็ค:dacebdcbdb

ด้านบนของสแต็คd: ใช่! เพื่อให้เราเพิ่มเข้าไปในลำดับ: และนำออกจากสแต็ค:dacebdcbdb

ด้านบนของสแต็ค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'))

ลองออนไลน์!

กรณีทดสอบ

try, yrtyrtyry

1234, 43214321432434

ABCDEFGHIJKLMNOPQRSTUVWXYZ, RUAHYKCLQZXEMPBWGDIOTVJNSFRUAHYKCLQZXEMPBWGDIOTVJNSFRUHYKCLQZXEMPWGDIOTVJNSFRUHYKLQZXEMPWGIOTVJNSFRUHYKLQZXMPWGIOTVJNSRUHYKLQZXMPWIOTVJNSRUYKLQZXMPWOTVNSRUYQZXPWOTVSRUYQZXPWTVSRUYQZXWTVSRUYZXWTVSUYZXWTVUYZXWVYZXWYZXYZ

?, ??

a, a a a

abcd, abcdabcd

คำตอบ:


5

สามวิธีที่ต่างกันพอสมควรจะนับไบต์เท่ากับ

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
หืมมมฉันสงสัยว่าทั้งสองเวอร์ชันแรก ... ทำไม99โดยเฉพาะ?
Erik the Outgolfer

@EriktheOutgolger เป็นอย่างน้อยจำนวนอักขระ ASCII ที่พิมพ์ได้และอย่างน้อยความยาวของแต่ละอินพุต
xnor

5

APL (Dyalog Classic)ขนาด 21 ไบต์

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

ลองออนไลน์!

นี่คือรถไฟเทียบเท่ากับ {∊⍵,(⊂⍵)~¨(,\⍺⊂⍨1,2>/⍺⍋⍵)}

ให้การเรียงสับเปลี่ยนของอาร์กิวเมนต์ที่ถูกต้องในอาร์กิวเมนต์ซ้าย

1,2>/เปรียบเทียบคู่ที่ต่อเนื่องกันด้วย>และเติม 1

⍺⊂⍨ใช้หน้ากากบูลีนด้านบนเพื่อแบ่งออกเป็นกลุ่ม 1s ในรูปแบบการทำเครื่องหมายจุดเริ่มต้นของกลุ่มใหม่

,\ การต่อข้อมูลสะสมของกลุ่ม

(⊂⍵)~¨ ส่วนประกอบของแต่ละส่วนด้วยความเคารพ

⍵, ย่อหน้า

แผ่เป็นสตริงเดียว


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

Haskell , 49 46 ไบต์

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

ลองออนไลน์!

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

แก้ไข: -3 ไบต์ขอบคุณ @GolfWolf และ @Laikoni!





1
@GolfWolf โซลูชันที่สองของคุณ (และของ Laikoni) ไม่ทำงาน มันสร้าง "ytrty" แทน "yrtyry" เพราะลำดับความสำคัญของโอเปอเรเตอร์ที่มี (:) และ (#)
user1472751

1

สะอาด , 85 ไบต์

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[]

ลองออนไลน์!

กำหนดฟังก์ชั่นบางส่วนfขายทำ[Char]และ[Char]ที่อาร์กิวเมนต์แรกคือเป้าหมายและสองคือสแต็ค


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[]และ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]

โอ้ใช่แล้วการป้อนข้อมูลด้วยวิธีนี้ทำให้รู้สึกสมเหตุสมผลมากขึ้น
โจคิง

วิธีการเกี่ยวกับ17 ไบต์ ?
Jo King

1
@JoKing - การเปลี่ยนแปลงที่ดีมากที่จะทำให้การกำหนดเส้นทางซ้ำซ้อนเหล่านั้นหายไปฉันไม่สามารถต้านทานต่อการเพิ่มไบต์พิเศษได้แม้ว่า: P
Teal pelican

0

Perl, 62 ไบต์

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

รับอาร์กิวเมนต์แรกลำดับเป็นรายการของอักขระและตัวที่สองคือ stack เป็นสตริง

Ungolfed:

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

คุณเคยสงสัยหรือไม่ว่าตัวแปร regex ที่คลุมเครือทั้งหมดนั้นมีไว้เพื่ออะไร? เห็นได้ชัดว่าพวกเขาถูกออกแบบมาสำหรับความท้าทายที่แน่นอนนี้ เราจับคู่กับตัวละครปัจจุบัน$x(ซึ่งน่าเสียดายที่ต้องหนีในกรณีที่เป็นตัวอักษรพิเศษของ regex) นี้สิ่งอำนวยความสะดวกแยกสตริงเข้า "ก่อนที่จะมีการแข่งขัน" $`"จับคู่" $&และ $'"หลังการแข่งขัน" ในการค้นหาแบบวนรอบเราเห็นตัวละครทุกตัวอย่างชัดเจนก่อนการแข่งขันและนำกลับเข้าไปในสแต็ก เรายังเห็นตัวละครปัจจุบัน แต่ไม่ได้ใส่กลับ ดังนั้นเราจึงเพิ่ม "ก่อนการแข่งขัน" ในรายการ "เห็น" $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.