当整数加入队列时


26

介绍

队列是其中元件被抽象数据类型加入到前面(排队)和除去从背面(出列)。这也称为FIFO(先进先出)原则。

最好用一个示例显示:

在此处输入图片说明


挑战

给定一个非空数组,该数组包含正整数表示出(删除元素)的元素,请输出队列的最终列表。

假设X在此示例中表示出队。让我们看一下以下列表:

[45, X, X, 37, 20, X, 97, X, 85]

可以将其转换为以下队列伪代码:

                   Queue
Enqueue 45    ->   45
Dequeue       ->   
Dequeue       ->              (dequeue on an empty queue is a no-op)
Enqueue 37    ->   37
Enqueue 20    ->   20 37
Dequeue       ->   20
Enqueue 97    ->   97 20
Dequeue       ->   97
Enqueue 85    ->   85 97

您可以看到最后的结果是[85, 97],这是此序列的输出。


测试用例

请注意,您可以选择其他任何符号或字符X,只要它不是正整数即可。

[1, X, 2, X, 3, X]      ->     []
[1, 2, X]               ->     [2]
[1, 2, 3]               ->     [3, 2, 1]
[1, 2, X, X, X, 3]      ->     [3]
[1, 2, X, 3, X, 4]      ->     [4, 3]

这是,因此以最少的字节提交为准!


可以是用空格分隔的字符串而不是数组吗?
莱利

@Riley当然,无论最适合你
阿德南

2
我们可以为x使用一个负数(Haskell不支持异构列表)吗?
通用显示名称

2
...或其他非非负整数,例如零或一半?
乔纳森·艾伦

@GenericDisplayName嗯,好点。只要它不是正整数,我就允许它
Adnan'1

Answers:


4

果冻,8字节

F;@Ṗṛ?¥/

使用任何伪造的值(0或为空的可迭代)出队。

在线尝试!

怎么运行的

F;@Ṗṛ?¥/  Main link. Argument: A (array)

       /  Reduce A by the link to the left.
      ¥     Combine the two links to the left into a dyadic chain.
F             Flatten the left argument.
    ṛ?        If the right argument is truthy:
 ;@             Concatenate the right argument and the flattened left argument.
              Else:
   Ṗ            Pop; remove the last element of the flattened left argument.
                This is why flattening is required, as Ṗ doesn't handle integers
                as intended for this challenge.

1
实际上,这不是禁止的。仅禁止使用整数,0为中性。
暴民埃里克(Erik the Outgolfer)'17

这不是我发布答案时所说的,但要多加注意。
丹尼斯

8

Python 2,56 53 50字节

q=[]
for i in input():q=[[i]+q,q[:i]][i<0]
print q

在线尝试!

出队是-1。这个技巧可以轻松地对队列进行pythonic切片。


7

Mathematica,102个字节

绝对不是最短的解决方案,但我无法抗拒,因为这有点不对劲。

r=Reverse@{##}&
a_~f~b___:=b
f[a_,b___,]:=b
ToExpression[{"r[","f["~Table~StringCount[#,"]"],#}<>"]"]&

在一些辅助函数之后,它定义了一个纯函数,该函数将字符串作为输入:在字符串中,数字用逗号分隔(空格是可选的);出队特征是"]"; 并且列表的前面或后面没有定界符。例如,OP中的第一个示例将作为字符串输入"45,],],37,20,],97,],85"。函数的输出是数字列表。

该函数计算"]"输入字符串中有多少出队,将那么多副本附加"f["到字符串的前面,然后用包围整个对象"r[...]"。在上面的示例中,这产生了"r[f[f[f[f[45,],],37,20,],97,],85]"; 注意括号是平衡的。

然后,ToExpression将结果字符串解释为一段Mathematica代码并执行它。f方便地定义该函数以保留除第一个参数外的所有参数(并且也忽略尾随逗号;无论如何,这都是处理空队r列出队的必要条件),并将所得的数字序列按正确的顺序转换为数字列表。


第3行中的逗号是否b___,应该存在?它可以工作,但是逗号会因此变成红色。(而且,第2行和第3行有什么区别?)
numbermaniac

1
好的眼睛:)第2行等效于f[a_,b___]:=b(不带逗号),而第3行等效于f[a_,b___,Null]:=b。在这两种情况下,都b___引用任意数量的参数(包括所有参数)。第3行更为具体,因此在适当的情况下总是在第2行之前使用。因此,该函数将f忽略其第一个参数,并且如果该参数为,还将忽略其最后一个参数Null。这对于处理使空队列出队很有必要。请注意,典型的输入将产生类似的表达式r[f[f[f[5,3,],2,],],11],其中每个逗号之前]再次表示a Null
格雷格·马丁

1
哇,很棒 :)。顺便说一句,我认为它实际上是102个字节。您可能在末尾算了一个额外的换行符。
numbermaniac

4

视网膜,30字节

1+`\d+,(.*?)X,?|^X,
$1
O^$`\d+

在线尝试!

重复删除第一个数字(不一定是立即删除),后跟一个X与that XX在字符串开头的。然后反转剩余的数字。


4

JavaScript,70 63 53 50 43字节

感谢@Neil用x.map代替了for循环和三元表达式来释放10个字节

感谢@Arnauld打高尔夫球3个字节

感谢@ETHproductions打高尔夫球7个字节

x=>(t=[],x.map(a=>+a?t=[a,...t]:t.pop()),t)

在线尝试!

出队可以是非true以外的任何非数字值。


如果您使用三元数而不是if 语句,则将更短;如果您使用量map而不是循环,则将更短;如果您使用表达式而不是块,则将更短。请参阅提示
尼尔

我已经发布了我工作的第一个版本。然后我吃了晚餐:P
fəˈnɛtɪk

您可以x=>(t=[],x.map(a=>a>0?t.unshift(a):t.pop()),t)return
ETHproductions'Apr

x=>x.map(a=>a>0?t.unshift(a):t.pop(),t=[])&&t更短。
Neil

(或者说就a?足够了吗?)
Neil

3

Mathematica,46 45字节

感谢ngenisis节省了1个字节。

Reverse[#//.{_Integer:0,a___,X,b___}:>{a,b}]&

使用模式匹配,与我的Retina答案基本相同。我们反复匹配第一个数字X,并将其与第一个数字一起删除(如果存在)。完成后,我们反转列表。


3

纯净重击,72

输入作为命令行参数给出。

for a;{
[ ${a/X} ]&&q=(${a:n++,0} ${q[@]})||((n-=n>0))
}
echo ${q[@]::n}

在线尝试



3

MATL13 12字节

vi"@?@wh}IL)

输入是一个数字数组,0用于“出队”。

输出是用空格分隔的数字。空结果显示为空。

在线尝试!验证所有测试用例

说明

v        % Concatenate stack contents: gives []. This will grow to represent the queue
i        % Input numeric array
"        % For each entry in the input array
  @?     %   If current entry is non-zero
    @wh  %     Prepend current entry to the queue
  }      %   Else
    IL)  %     Remove last element from the queue
         %   End (implicit)
         % End (implicit)
         % Display (implicit)

3

Haskell,41个 40字节

l#a|a>0=a:l|l>[]=init l|1>0=l

功能是foldl(#)[](还包括在字节数中,中间有一个分隔字节)

在线尝试!

X是任何非正整数

编辑:-1字节感谢妮米


您可以翻转最后两个后卫以保存一个字节:|l>[]=init l|1>0=l
nimi

3

朱莉娅78 76 73 57字节

f(a)=(q=[];[x<1?q=q[2:end]:push!(q,x)for x=a];reverse(q))

感谢哈里森·格罗丁(Harrison Grodin)为朱莉娅(Julia)打高尔夫球的出色建议。用三进制替换if / else,用列表理解替换for / end,以节省16个字节。

f(a)=(q=[];for x in a if x<1 q=q[2:end]else q=[q...,x]end end;reverse(q))

删除了一些不必要的空间,以节省3个字节。

在允许负数或零之前:

f(a)=(q=[];for x in a if x==:X q=q[2:end] else q=[q...,x] end end;r everse(q))

取消高尔夫:

function dequeue(list)
    queue = []

    for x in list
        if x < 1
            queue = queue[2:end]
        else
            queue = [queue..., x]
        end
    end

    reverse(queue)
end

我对朱莉娅很陌生。可能会有更好的方法。用途:X为X,这是在朱莉娅的象征。更新:现在允许使用0,对X使用0(或任何负数),并保存两个字符。再次更新以删除一些我没有意识到不需要的空白。


2

05AB1E12 11字节

感谢Riley,节省了一个字节

)Evyai¨ëy¸ì

在线尝试!

说明

出队用任何字母表示。

)             # wrap stack in a list (pushes empty list)
 Ev           # for each y in evaluated input
   yai        # if y is a letter
      ¨       # remove the first element of the list
       ëy¸ì   # else, prepend y to the list

2

GNU Sed,43岁

使用-r-n标志的得分包括+2 。

G
s/X\n( *|(.*)\b\S+ *)$/\2/
s/\n/ /
h
$p

在线尝试

说明

                            # Implicitly read the next line
G                           # append a newline, then the contents of the hold space
s/X\n( *|(.*)\b\S+ *)$/\2/  # If the input was an X, remove it, the newline, and any element at the end
s/\n/ /                     # Otherwise if the input was not an X, it is simply enqueued by removing the newline between it and the rest of the line
h                           # save a copy of the queue to the hold space
$p                          # since we're using -n to suppress output at the end of processing each input line, then this explicit print is required in the last line

2

PHP,85字节

<?$r=[];foreach($_GET as$v)is_int($v)?array_unshift($r,$v):array_pop($r);print_r($r);

-8个字节,$v而不是is_int($v)每个出队值都属于false


2

Python 3中95 94个字节

def f(x):q=[];[*map(lambda s:exec(("q.pop(0)"if q else"","q+=[s]")[s!="X"]),x)];print(q[::-1])

在线尝试!

同样是94个字节:

def f(x):q=[];[*map(lambda s:exec((("","q.pop(0)")[q>[]],"q+=[s]")[s!="X"]),x)];print(q[::-1])

2

Perl 5,28 +1 = 29字节

28个字节的代码+ -p标志。

/\d/?$\=$_.$\:$\=~s/.*
$//}{

在线尝试!

它使用字符串($\)作为队列:当输入包含整数(时/\d/?,我们将其附加在$\$\=$_.$\)的开头,否则,我们将使用删除最后一个s/.*\n$//。)在末尾,$\由于-pflag(和那些无与伦比的}{)。


其他方法:

  • 33个字节,使用数组作为队列(我认为这是在Perl中最自然的方法,但不是最短的方法):

    /X/?pop@F:unshift@F,$_}{$_="@F"

    在线尝试!

  • 52字节,使用正则表达式和reverse(恰好与Martin Ender的Retina答案完全相同-多亏了我在上面保存了2个字节)。反转列表需要很多字符,因为要保留整数,我必须将字符串转换为数组以对其进行反转,然后再将其转换为字符串以进行打印。(say for而不是$_=join$",可以节省2个字节,但是它需要-Eor -M5.010而不是那么有趣)。

    s/\d+ (.*?)X ?|^X/$1/&&redo;$_=join$",reverse split

    在线尝试!


1

Python 3,107个字节

def f(x):
 r = []
 for i in x:exec("try:r.pop(0)\nexcept:8;r+=i,".split(";")[type(i)==int])
 return r[::-1]

Dequeuer可以是任何非数字值。

在线尝试


1

批处理,160字节

@set s=.
@for %%n in (%*)do @if %%n==X (call set s=%%s:* =%%)else call set s=%%s:~,-1%%%%n .
@set t=
@for %%n in (%s:~,-1%)do @call set t= %%n%%t%%
@echo%t%

这比需要的要难。

  • 尽管Batch可以枚举拆分字符串的结果,但是它不能轻易地从枚举中删除元素。
  • 它可以删除第一个项目,但前提是至少有一个项目。否则会产生垃圾。

这意味着我a)需要有一个不会被删除的队列结束标记,并且b)必须从头到尾操纵队列,因此新项目将被插入到结束标记之前,这样就可以从前面删除旧项目,这意味着I c)必须在打印队列之前将其反转。


1

PHP,70个字节

foreach($argv as$v)+$v?$r[]=$v:array_shift($r);krsort($r);print_r($r);

1

C#,115个字节+33个字节供使用

l=>{var r=new List<int>();foreach(var n in l)if(n<0)try{r.RemoveAt(0);}catch{}else r.Add(n);r.Reverse();return r;};

在执行入队和出队操作后返回整数列表的匿名方法。负整数用于从队列中删除元素。

完整的程序,包含未使用的方法和测试用例:

using System;
using System.Collections.Generic;

public class Program
{
    static void PrintList(List<int> list)
    {
        var s = "{";
        foreach (int element in list)
            s += element + ", ";
        if (s.Length > 1)
            s += "\b\b";
        s += "}";
        Console.WriteLine(s);
    }

    public static void Main()
    {
        Func<List<int>, List<int>> f =
        l =>
        {
            var r = new List<int>();
            foreach (var n in l)
                if (n < 0)
                    try
                    {
                        r.RemoveAt(0);
                    }
                    catch
                    { }
                else
                    r.Add(n);
            r.Reverse();
            return r;
        };

        // test cases:
        var list = new List<int>(new[]{1, -1, 2, -1, 3, -1});   // {}
        PrintList(f(list));

        list = new List<int>(new[]{1, 2, -1});  // {2}
        PrintList(f(list));

        list = new List<int>(new[]{1, 2, 3});   // {3, 2, 1}
        PrintList(f(list));

        list = new List<int>(new[]{1, 2, -1, -1, -1, 3});   // {3}
        PrintList(f(list));

        list = new List<int>(new[]{1, 2, -1, 3, -1, 4});    // {4, 3}
        PrintList(f(list));
    }
}

1

Scala,97个字节

type S=Seq[_];def f(a:S,b:S):S=a match{case h::t=>f(t,if(h==0)b dropRight 1 else h+:b);case _=>b}

作为输入,f将带有的列表0作为“ dequeue”元素。它使用带有第二个参数(b)的尾递归,用作累加器。最初b是空SeqNil)。

说明:

type S=Seq[_]                               // defines a type alias (save 1 byte since Seq[_] is used 3 times)
def f(a: S, b: S): S = {                    // a is the initial list, b is an accumulator
    a match {                           
        case h::t =>                        // if a is non-empty
            f(t,                            // recursive call to f with 1st parameter as the tail
                if (h==0) b dropRight 1     // if h == 0 (dequeue) then remove last element of b,
                else h+:b                   // otherwise, just add h at the beginning of b in recursive call
            )
        case _ => b                         // when the list is empty, return b (final result)
    }
}

注: b dropRight 1代替b.tail,以避免例外:tail of empty list

测试用例 :

f(Seq(45, 0, 0, 37, 20, 0, 97, 0, 85), Nil)     // List(85, 97)
f(Seq(1, 0, 2, 0, 3, 0), Nil)                   // List()
f(Seq(1, 2, 0), Nil)                            // List(2)
f(Seq(1, 2, 3), Nil)                            // List(3, 2, 1)
f(Seq(1, 2, 0, 0, 0, 3), Nil)                   // List(3)
f(Seq(1, 2, 0, 3, 0, 4), Nil)                   // List(4, 3)

f也可以使用其他类型(String,,char...,甚至是这些类型的异构列表!):

f(Seq(false, '!', "world", 0, "Hello"), Nil)    // List(Hello, world, !)

1

REXX,115个字节

arg n
do while n>''
  parse var n m n
  if m=X then pull
  else queue m
  end
o=
do while queued()>0
  pull a
  o=a o
  end
say o

取一个以空格分隔的字符串,打印一个以空格分隔的字符串


1

C ++,122个 119字节

#import<list>
void f(std::list<int>o,std::list<int>&q){for(int i:o)if(i)q.push_front(i);else if(q.size())q.pop_back();}

0表示出队。

在线尝试!


1

Swift 3,70个字节

假设我们有一个像 let x = [1, 2,-1,3,-1,4]

print(x.reduce([].prefix(0)){(a,i)in return i>0 ?[i]+a:a.dropLast(1)})

请注意,这[].prefix(0)是一种获取空ArraySlice的狡猾方法

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.