{ }codelper
map lookupparametersreturn valuesP0147

Warehouse reorder report

A warehouse ledger lists n kinds of items.
The first line gives n, and each of the next n lines gives one item as "name stock low target pack" separated by single spaces.
The next line gives the number of shipping records m, and each of the next m lines gives a record "name quantity".
For each record, subtract the quantity from that item's stock.
Subtract even when the stock is short, so stock may become negative (backorders).
Ignore records whose name is not in the ledger.
After all records, reorder in whole packs every item whose stock is less than its low level.
The number of packs is the smallest count with stock + count × pack ≥ target.
If the stock equals or exceeds the low level, do not reorder.
Compute the pack count in a function that takes (stock, low, target, pack) and returns the count.
Print the number of ignored records on the first line.
Then print "name packs" for each item to reorder, one per line, in ledger order.
If nothing needs reordering, print a single line "-".

Input
1 ≤ n ≤ 100, 0 ≤ m ≤ 2000.
0 ≤ stock ≤ 10,000, 1 ≤ low ≤ target ≤ 10,000, 1 ≤ pack ≤ 1000, 1 ≤ quantity ≤ 1000 (all integers).
Names are 1 to 10 lowercase English letters or digits, distinct within the ledger
Output
The number of ignored records, then "name packs" lines in ledger order, or "-"
Example 1 · stdin
4
bolt 30 20 100 25
nut 12 15 60 10
washer 5 5 40 8
gear 2 10 10 4
5
bolt 18
spring 3
nut 2
gear 7
bolt 1
stdout
1
bolt 4
nut 5
gear 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

The core is looking up items by name and a function that takes four values and returns one.
Looking up a name that is not in the ledger behaves differently.
Python items[name] stops with KeyError, so ask with in first or use get.
JS/TS Map.get returns undefined, Java get returns null, and C# items[name] throws KeyNotFoundException, so use TryGetValue.
C++ items[name] inserts the missing name, so search with find, and Craykon also stops on a missing key, so ask items.Contains(name) (items.있나(name)) first.
C has no map, so compare against the name table in turn (only 100 items).
Output is in ledger order, so the map's iteration order matters too.
Python dict, JS/TS Map and Craykon Dict (사전) keep insertion order, but Java HashMap scrambles it and C++ std::map walks in sorted order.
So Java uses LinkedHashMap, and C# and C++ keep a separate list of the order (C# Dictionary order is not guaranteed).
The pack count is the ceiling division (target − stock + pack − 1) ÷ pack.
Trap: in C, Java and C#, ceil((t - s) / p) has already divided integers, so the ceiling does nothing.
In JS/TS Math.ceil((t - s) / p) is right, because / is real division.
Craykon writes Mathf.Quot(t - s + p - 1, p) (수학.몫(t - s + p - 1, p)).
One more: an item at its low level is not reordered, so use <.

Pythonmain.py · 35 lines
import sys  def packs_needed(stock, low, target, pack):    """재고가 기준보다 적으면, 목표에 닿는 가장 적은 묶음 수. 아니면 0."""    if stock >= low:        return 0    return (target - stock + pack - 1) // pack   # 올림 나눗셈  lines = sys.stdin.read().split("\n")n = int(lines[0])items = {}    # 이름 → [재고, 기준, 목표, 묶음]order = []    # 장부에 적힌 차례for line in lines[1:n + 1]:    name, *nums = line.split()    items[name] = list(map(int, nums))    order.append(name) m = int(lines[n + 1])ignored = 0for line in lines[n + 2:n + 2 + m]:    name, qty = line.split()    if name in items:        items[name][0] -= int(qty)    else:        ignored += 1 print(ignored)report = []for name in order:    p = packs_needed(*items[name])    if p > 0:        report.append(f"{name} {p}")print("\n".join(report) if report else "-")
JavaScriptmain.js · 31 lines
const lines = require("fs").readFileSync(0, "utf8").split("\n"); // 재고가 기준보다 적으면, 목표에 닿는 가장 적은 묶음 수. 아니면 0.function packsNeeded(stock, low, target, pack) {  if (stock >= low) return 0;  return Math.ceil((target - stock) / pack);} const n = Number(lines[0]);const items = new Map(); // 이름 → { stock, low, target, pack } (Map은 넣은 차례를 지킨다)for (const line of lines.slice(1, n + 1)) {  const [name, ...nums] = line.trim().split(" ");  const [stock, low, target, pack] = nums.map(Number);  items.set(name, { stock, low, target, pack });} const m = Number(lines[n + 1]);let ignored = 0;for (const line of lines.slice(n + 2, n + 2 + m)) {  const [name, qty] = line.trim().split(" ");  const item = items.get(name); // 없으면 undefined  if (item !== undefined) item.stock -= Number(qty);  else ignored++;} const report = [];for (const [name, it] of items) {  const p = packsNeeded(it.stock, it.low, it.target, it.pack);  if (p > 0) report.push(`${name} ${p}`);}console.log(`${ignored}\n${report.length > 0 ? report.join("\n") : "-"}`);
TypeScriptmain.ts · 39 lines
import { readFileSync } from "node:fs";const lines: string[] = readFileSync(0, "utf8").split("\n"); interface Item {  stock: number;  low: number;  target: number;  pack: number;} // 재고가 기준보다 적으면, 목표에 닿는 가장 적은 묶음 수. 아니면 0.function packsNeeded(stock: number, low: number, target: number, pack: number): number {  if (stock >= low) return 0;  return Math.ceil((target - stock) / pack);} const n = Number(lines[0]);const items = new Map<string, Item>(); // Map은 넣은 차례를 지킨다for (const line of lines.slice(1, n + 1)) {  const [name, ...nums] = line.trim().split(" ");  const [stock, low, target, pack] = nums.map(Number);  items.set(name, { stock, low, target, pack });} const m = Number(lines[n + 1]);let ignored = 0;for (const line of lines.slice(n + 2, n + 2 + m)) {  const [name, qty] = line.trim().split(" ");  const item = items.get(name); // Item | undefined  if (item !== undefined) item.stock -= Number(qty);  else ignored++;} const report: string[] = [];for (const [name, it] of items) {  const p = packsNeeded(it.stock, it.low, it.target, it.pack);  if (p > 0) report.push(`${name} ${p}`);}console.log(`${ignored}\n${report.length > 0 ? report.join("\n") : "-"}`);
JavaMain.java · 43 lines
import java.io.*;import java.util.*; public class Main {    // 재고가 기준보다 적으면, 목표에 닿는 가장 적은 묶음 수. 아니면 0.    static int packsNeeded(int stock, int low, int target, int pack) {        if (stock >= low) return 0;        return (target - stock + pack - 1) / pack; // 올림 나눗셈(나눌 수가 양수일 때)    }     public static void main(String[] args) throws IOException {        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));        int n = Integer.parseInt(br.readLine().trim());        // LinkedHashMap은 넣은 차례를 지킨다(HashMap은 차례가 섞인다)        Map<String, int[]> items = new LinkedHashMap<>();        for (int i = 0; i < n; i++) {            String[] p = br.readLine().trim().split(" ");            items.put(p[0], new int[] {                Integer.parseInt(p[1]), Integer.parseInt(p[2]), Integer.parseInt(p[3]), Integer.parseInt(p[4]) });        }        int m = Integer.parseInt(br.readLine().trim());        int ignored = 0;        for (int i = 0; i < m; i++) {            String[] p = br.readLine().trim().split(" ");            int[] it = items.get(p[0]); // 없으면 null            if (it != null) it[0] -= Integer.parseInt(p[1]);            else ignored++;        }        StringBuilder out = new StringBuilder();        out.append(ignored).append('\n');        int lines = 0;        for (Map.Entry<String, int[]> e : items.entrySet()) {            int[] it = e.getValue();            int packs = packsNeeded(it[0], it[1], it[2], it[3]);            if (packs > 0) {                out.append(e.getKey()).append(' ').append(packs).append('\n');                lines++;            }        }        if (lines == 0) out.append("-\n");        System.out.print(out);    }}
C#Main.cs · 49 lines
using System;using System.Collections.Generic;using System.Text; class Program{    // 재고가 기준보다 적으면, 목표에 닿는 가장 적은 묶음 수. 아니면 0.    static int PacksNeeded(int stock, int low, int target, int pack)    {        if (stock >= low) return 0;        return (target - stock + pack - 1) / pack; // 올림 나눗셈(나눌 수가 양수일 때)    }     static void Main()    {        int n = int.Parse(Console.ReadLine().Trim());        var items = new Dictionary<string, int[]>(); // 이름 → {재고, 기준, 목표, 묶음}        var order = new List<string>();              // 장부 차례(Dictionary의 차례는 약속되지 않는다)        for (int i = 0; i < n; i++)        {            string[] p = Console.ReadLine().Trim().Split(' ');            items[p[0]] = new[] { int.Parse(p[1]), int.Parse(p[2]), int.Parse(p[3]), int.Parse(p[4]) };            order.Add(p[0]);        }        int m = int.Parse(Console.ReadLine().Trim());        int ignored = 0;        for (int i = 0; i < m; i++)        {            string[] p = Console.ReadLine().Trim().Split(' ');            if (items.TryGetValue(p[0], out int[] it)) it[0] -= int.Parse(p[1]);            else ignored++;        }        var sb = new StringBuilder();        sb.Append(ignored).Append('\n');        int lines = 0;        foreach (string name in order)        {            int[] it = items[name];            int packs = PacksNeeded(it[0], it[1], it[2], it[3]);            if (packs > 0)            {                sb.Append(name).Append(' ').Append(packs).Append('\n');                lines++;            }        }        if (lines == 0) sb.Append("-\n");        Console.Write(sb);    }}
C++main.cpp · 47 lines
#include <iostream>#include <string>#include <unordered_map>#include <vector> struct Item {    std::string name;    int stock, low, target, pack;}; // 재고가 기준보다 적으면, 목표에 닿는 가장 적은 묶음 수. 아니면 0.int packs_needed(int stock, int low, int target, int pack) {    if (stock >= low) return 0;    return (target - stock + pack - 1) / pack; // 올림 나눗셈(나눌 수가 양수일 때)} int main() {    int n;    std::cin >> n;    std::vector<Item> items(n);                 // 장부 차례    std::unordered_map<std::string, int> where; // 이름 → 몇째 물건    for (int i = 0; i < n; i++) {        Item& it = items[i];        std::cin >> it.name >> it.stock >> it.low >> it.target >> it.pack;        where[it.name] = i;    }    int m, ignored = 0;    std::cin >> m;    for (int i = 0; i < m; i++) {        std::string name;        int qty;        std::cin >> name >> qty;        auto found = where.find(name); // [ ]로 읽으면 없는 이름이 0번으로 새로 들어간다        if (found != where.end()) items[found->second].stock -= qty;        else ignored++;    }    std::cout << ignored << "\n";    int lines = 0;    for (const Item& it : items) {        int p = packs_needed(it.stock, it.low, it.target, it.pack);        if (p > 0) {            std::cout << it.name << " " << p << "\n";            lines++;        }    }    if (lines == 0) std::cout << "-\n";}
Cmain.c · 48 lines
#include <stdio.h>#include <string.h> #define MAXN 100 static char names[MAXN][11];static int stock[MAXN], low[MAXN], target[MAXN], pack[MAXN];static int n; /* 재고가 기준보다 적으면, 목표에 닿는 가장 적은 묶음 수. 아니면 0. */static int packs_needed(int s, int lo, int t, int p) {    if (s >= lo) return 0;    return (t - s + p - 1) / p; /* 올림 나눗셈(나눌 수가 양수일 때) */} /* 이름 찾기: 몇째 물건인지, 없으면 -1 */static int find(const char *name) {    for (int i = 0; i < n; i++)        if (strcmp(names[i], name) == 0) return i;    return -1;} int main(void) {    scanf("%d", &n);    for (int i = 0; i < n; i++)        scanf("%10s %d %d %d %d", names[i], &stock[i], &low[i], &target[i], &pack[i]);    int m, ignored = 0;    scanf("%d", &m);    for (int i = 0; i < m; i++) {        char name[11];        int qty;        scanf("%10s %d", name, &qty);        int at = find(name);        if (at != -1) stock[at] -= qty;        else ignored++;    }    printf("%d\n", ignored);    int lines = 0;    for (int i = 0; i < n; i++) {        int p = packs_needed(stock[i], low[i], target[i], pack[i]);        if (p > 0) {            printf("%s %d\n", names[i], p);            lines++;        }    }    if (lines == 0) puts("-");    return 0;}
Craykonmain.cray · 50 lines
// 재고가 기준보다 적으면, 목표에 닿는 가장 적은 묶음 수. 아니면 0.묶음수(stock, low, target, pack){    if (stock >= low)    {        return 0;    }    return Mathf.Quot(target - stock + pack - 1, pack); // 올림 나눗셈} n = Console.ReadLine().ToNumber();items = Dict(); // 이름 → [재고, 기준, 목표, 묶음]for (i = 0; i < n; i++){    p = Console.ReadLine().Trim().Split();    items[p[0]] = [p[1].ToNumber(), p[2].ToNumber(), p[3].ToNumber(), p[4].ToNumber()];} m = Console.ReadLine().ToNumber();ignored = 0;for (i = 0; i < m; i++){    p = Console.ReadLine().Trim().Split();    if (items.Contains(p[0]))    {        it = items[p[0]];        it[0] = it[0] - p[1].ToNumber();    }    else    {        ignored++;    }} Console.WriteLine(ignored);lines = 0;foreach (name in items.Keys){    it = items[name];    packs = 묶음수(it[0], it[1], it[2], it[3]);    if (packs > 0)    {        Console.WriteLine(name + " " + packs);        lines++;    }}if (lines == 0){    Console.WriteLine("-");}