帮助我的儿子找到他的信


17

背景

基于我四岁的孩子从他的拉比那里得到的游戏。

“目标”是按给定顺序(例如)“查找”字母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

Answers:


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

Haskell49 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的)不起作用。由于运算符具有(:)和(#)优先级,因此它会产生“ ytyty”而不是“ tytyry”
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);}}

输入as 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]

哦,是的,这样输入就更有意义了
大金(Jo King)

怎么样17个字节
Jo King

1
@JoKing-非常好的更改,以使那些多余的路由消失,尽管如此,我还是忍不住要脱掉一个额外的字节:P
鹈鹕

0

Perl,62个字节

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

将其第一个参数(顺序)作为字符列表,将第二个参数(堆栈)作为字符串。

取消高尔夫:

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'
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.