{ }codelper
stackP0348

The pile of lunch trays

The lunch room has one pile where trays are stacked, and it is empty at first. Each tray has a number written on it, and several trays may have the same number. You are given q commands in order. put x puts one tray with number x on top of the pile. take c means c students, one after another, each take the tray on top of the pile. If the pile has fewer than c trays, they take only as many as there are, and the other students leave without a tray. For each take command, print on one line the numbers of the trays taken, in the order they were taken, separated by one space. If no tray was taken at all, print - on that line. After all commands, print on the last line the numbers of the trays left in the pile, from the top down, separated by one space. If no tray is left, print - on the last line.

Input
The first line has q (1 ≤ q ≤ 9,000), and the next q lines have one command each.
1 ≤ x ≤ 1,000,000, 1 ≤ c ≤ 9,000 (all integers, given as plain digits without commas).
The word and the number of a command are separated by one space
Output
One line per take command, then a last line with the trays that are left (numbers as plain digits without commas)
Example 1 · stdin
8
put 3
put 7
put 5
take 2
take 3
take 1
put 4
put 9
stdout
5 7
3
-
9 4
main.py
Input (stdin)

When you run, these lines are fed to input()/stdin in order (the program doesn't stop to ask).

$ Ready

Open this on a computer to write and run code. On mobile you can read the problem and the solutions.

In other languagesShow solutions by language · 8 languages

A stack, where you put on top and take from the top, is spelled differently in each language.
Python uses a list with append and pop(), and JS and TS use an array with push and pop(), so the end is the top.
Java uses push and pop of ArrayDeque, and C# uses Push and Pop of Stack<int>.
C++'s std::stack cannot be walked through, so to write the last line you use push_back and pop_back of a vector.
In C you build it from an array and one number that marks the top.
In Craykon you put with Add and take with RemoveAt(Count - 1).
Trap one: taking from an empty stack behaves differently.
Python's pop() stops with IndexError, Java's ArrayDeque.pop() with NoSuchElementException, and C#'s Pop() with InvalidOperationException.
take 3 in the example comes when only one tray is left, so a program that pops three times without asking whether the pile is empty stops there.
pop_back on an empty vector in C++ and a top position below 0 in C have no defined result at all.
Trap two: pop() in JS gives undefined on an empty array, with no error.
If you store that too, the list is not empty even though nothing was taken, so take 1 in the example prints an empty line instead of - (join writes undefined as an empty string).
In TS the type of pop() is number | undefined, so storing it straight into a number[] is reported as a type error.
Trap three: cutting everything at once with pile[-c:] in Python is handy, but the slice comes out from the bottom side.
The first line of the example becomes 7 5 instead of 5 7.
Trap four: the order when you walk through a whole stack differs as well.
Java's ArrayDeque and C#'s Stack<int> go from the top, but Java's old Stack class goes from the bottom, so the last line of the example becomes 4 9.
A Python list, a JS array, a C++ vector and a Craykon list also go from the bottom, so walk them backwards or reverse them (reversed(pile), pile.reverse(), rbegin(), Reverse()).

Pythonmain.py · 18 lines
import sys lines = sys.stdin.read().split("\n")q = int(lines[0])pile = []  # 리스트의 끝이 더미의 맨 위out = []for i in range(1, q + 1):    cmd, v = lines[i].split()    v = int(v)    if cmd == "put":        pile.append(v)    else:        taken = []        while len(taken) < v and pile:  # 비었는지 먼저 묻고 꺼낸다            taken.append(pile.pop())        out.append(" ".join(map(str, taken)) if taken else "-")out.append(" ".join(map(str, reversed(pile))) if pile else "-")  # 맨 위부터print("\n".join(out))
JavaScriptmain.js · 18 lines
const lines = require("fs").readFileSync(0, "utf8").split("\n");const q = Number(lines[0]);const pile = []; // 배열의 끝이 더미의 맨 위const out = [];for (let i = 1; i <= q; i++) {  const [cmd, t] = lines[i].split(" ");  const v = Number(t);  if (cmd === "put") {    pile.push(v);  } else {    const taken = [];    // 비었는지 먼저 묻고 꺼낸다(빈 배열의 pop()은 오류 없이 undefined를 준다)    while (taken.length < v && pile.length > 0) taken.push(pile.pop());    out.push(taken.length > 0 ? taken.join(" ") : "-");  }}out.push(pile.length > 0 ? pile.reverse().join(" ") : "-"); // 맨 위부터console.log(out.join("\n"));
TypeScriptmain.ts · 24 lines
import { readFileSync } from "node:fs"; const lines: string[] = readFileSync(0, "utf8").split("\n");const q: number = Number(lines[0]);const pile: number[] = []; // 배열의 끝이 더미의 맨 위const out: string[] = [];for (let i = 1; i <= q; i++) {  const [cmd, t] = lines[i].split(" ");  const v: number = Number(t);  if (cmd === "put") {    pile.push(v);  } else {    const taken: number[] = [];    // pop()의 타입은 number | undefined: 비었는지 먼저 묻고 꺼낸다    while (taken.length < v) {      const top: number | undefined = pile.pop();      if (top === undefined) break;      taken.push(top);    }    out.push(taken.length > 0 ? taken.join(" ") : "-");  }}out.push(pile.length > 0 ? pile.reverse().join(" ") : "-"); // 맨 위부터console.log(out.join("\n"));
JavaMain.java · 41 lines
import java.io.BufferedReader;import java.io.IOException;import java.io.InputStreamReader;import java.util.ArrayDeque;import java.util.Deque; public class Main {    public static void main(String[] args) throws IOException {        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));        int q = Integer.parseInt(br.readLine().trim());        Deque<Integer> pile = new ArrayDeque<>(); // push·pop이 맨 위에서 일어난다        StringBuilder sb = new StringBuilder();        for (int i = 0; i < q; i++) {            String[] parts = br.readLine().split(" ");            int v = Integer.parseInt(parts[1]);            if (parts[0].equals("put")) {                pile.push(v);            } else {                int count = 0;                while (count < v && !pile.isEmpty()) { // 비었는지 먼저 묻고 꺼낸다                    if (count > 0) sb.append(' ');                    sb.append(pile.pop());                    count++;                }                if (count == 0) sb.append('-');                sb.append('\n');            }        }        if (pile.isEmpty()) {            sb.append('-');        } else {            boolean first = true;            for (int x : pile) { // ArrayDeque는 맨 위부터 돈다                if (!first) sb.append(' ');                sb.append(x);                first = false;            }        }        System.out.println(sb);    }}
C#Main.cs · 37 lines
using System;using System.Collections.Generic;using System.Text; class Program{    static void Main()    {        int q = int.Parse(Console.ReadLine()!);        var pile = new Stack<int>();        var sb = new StringBuilder();        for (int i = 0; i < q; i++)        {            string[] parts = Console.ReadLine()!.Split(' ');            int v = int.Parse(parts[1]);            if (parts[0] == "put")            {                pile.Push(v);            }            else            {                int count = 0;                while (count < v && pile.Count > 0) // 비었는지 먼저 묻고 꺼낸다                {                    if (count > 0) sb.Append(' ');                    sb.Append(pile.Pop());                    count++;                }                if (count == 0) sb.Append('-');                sb.Append('\n');            }        }        // Stack<T>는 맨 위부터 돈다        sb.Append(pile.Count > 0 ? string.Join(" ", pile) : "-");        Console.WriteLine(sb);    }}
C++main.cpp · 37 lines
#include <iostream>#include <string>#include <vector>using namespace std; int main() {    ios::sync_with_stdio(false);    cin.tie(nullptr);    int q;    cin >> q;    vector<int> pile; // std::stack은 속을 돌 수 없어서 vector를 스택으로 쓴다(끝이 맨 위)    for (int i = 0; i < q; i++) {        string cmd;        int v;        cin >> cmd >> v;        if (cmd == "put") {            pile.push_back(v);        } else {            int count = 0;            while (count < v && !pile.empty()) { // 비었는지 먼저 묻고 꺼낸다                if (count > 0) cout << ' ';                cout << pile.back();                pile.pop_back();                count++;            }            if (count == 0) cout << '-';            cout << '\n';        }    }    if (pile.empty()) cout << '-';    for (auto it = pile.rbegin(); it != pile.rend(); ++it) { // 맨 위부터        if (it != pile.rbegin()) cout << ' ';        cout << *it;    }    cout << '\n';    return 0;}
Cmain.c · 33 lines
#include <stdio.h>#include <string.h> int pile[9000]; /* pile[top - 1]이 더미의 맨 위 */ int main(void) {    int q, top = 0;    if (scanf("%d", &q) != 1) return 0;    for (int i = 0; i < q; i++) {        char cmd[8];        int v;        if (scanf("%7s %d", cmd, &v) != 2) return 0;        if (strcmp(cmd, "put") == 0) {            pile[top++] = v;        } else {            int count = 0;            while (count < v && top > 0) { /* 비었는지 먼저 묻고 꺼낸다 */                if (count > 0) printf(" ");                printf("%d", pile[--top]);                count++;            }            if (count == 0) printf("-");            printf("\n");        }    }    if (top == 0) printf("-");    for (int i = top - 1; i >= 0; i--) { /* 맨 위부터 */        printf("%d", pile[i]);        if (i > 0) printf(" ");    }    printf("\n");    return 0;}
Craykonmain.cray · 37 lines
q = Console.ReadLine().ToNumber();pile = []; // 목록의 끝이 더미의 맨 위for (i = 0; i < q; i++){    parts = Console.ReadLine().Split();    v = parts[1].ToNumber();    if (parts[0] == "put")    {        pile.Add(v);    }    else    {        taken = [];        while (taken.Count < v && pile.Count > 0)        {            taken.Add(pile[pile.Count - 1]);            pile.RemoveAt(pile.Count - 1);        }        if (taken.Count == 0)        {            Console.WriteLine("-");        }        else        {            Console.WriteLine(taken.Join(" "));        }    }}if (pile.Count == 0){    Console.WriteLine("-");}else{    pile.Reverse(); // 맨 위부터    Console.WriteLine(pile.Join(" "));}