Turn the sizes (in bytes) in a file list into units that are easy for people to read.
The first line gives the number of files n.
Each of the next n lines gives a file name, one space and the size s, in that order.
A file name may contain spaces.
The units are B, KiB, MiB, GiB and TiB, where 1 KiB = 1024 B, 1 MiB = 1024 KiB, 1 GiB = 1024 MiB and 1 TiB = 1024 GiB.
If s is less than 1024, write "s B" (for example 1023 B).
Otherwise pick the largest unit whose size in bytes is at most s, and write s divided by that unit, rounded to one decimal place.
Round to the one-decimal number nearest to the exact quotient, and when it is exactly halfway between two, take the larger (1.25 → 1.3, 1.249… → 1.2).
If the rounded value becomes 1024.0, switch to the next larger unit and write 1.0 (TiB has no larger unit, but 1024.0 TiB never happens in this range).
With any unit other than B, always write the value with one decimal (for example 1.0 KiB, 4.5 GiB).
For each file print one line "name: size".
Input
1 ≤ n ≤ 1,000, 0 ≤ s ≤ 100,000,000,000,000 (10^14), names are 1 to 40 characters of English letters, digits, dots, underscores, hyphens and spaces, never start or end with a space, and never have two spaces in a row
Output
one line "name: size" per file
Example 1 · stdin
5
notes.txt 1023
icon.png 1024
My Photo 2024.jpg 1280
backup part 1.zip 1048575
movie.mkv 4831838208
stdout
notes.txt: 1023 B
icon.png: 1.0 KiB
My Photo 2024.jpg: 1.3 KiB
backup part 1.zip: 1.0 MiB
movie.mkv: 4.5 GiB
main.py
Error List00F8 ↓ · ⇧F8 ↑
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
Start with the line-reading trap. Names contain spaces, so do not read word by word; read the whole line and cut it at the last space. Python input().rsplit(" ", 1), JS/TS lastIndexOf(" "), Java BufferedReader.readLine() with lastIndexOf, C# Console.ReadLine() with LastIndexOf, C fgets with strrchr (remove the trailing newline), C++ std::getline with rfind. C++ std::cin >> name and C scanf("%s") stop at a space, so "My Photo 2024.jpg" becomes "My". With Java Scanner, calling nextLine() after nextInt() reads only the newline left on the first line and returns an empty string. Craykon Console.ReadLine() returns the whole line but has no member that finds the last space, so split it with Split(" "), take the last piece as the size, and join the rest back with GetRange and Join(" ") (names have single spaces, so the original name comes back). Powers: 1024^k is Python/JS/TS 1024 ** k, Java/C# Math.pow/Math.Pow, C pow, C++ std::pow, and the last four return a double. They are exact for powers of two, but if you compute with integers anyway, multiplying by 1024 step by step is cleaner (Craykon has no power operator, so it multiplies). 1024^4 = 2^40 overflows a 32-bit int, so Java and C# need long, C and C++ long long. The rounding trap: 1280 B is exactly 1.25 KiB. Python f"{x:.1f}"/round(x, 1) and C/C++ printf("%.1f") send an exact half to the even side and give 1.2, while JS toFixed(1) gives 1.3. Since languages disagree, do the rounding yourself with integers. The rounded value × 10 is the quotient of (20 × s + d) ÷ (2 × d) (d = 1024^k), and halves always go up. Because d is a power of two, the floating-point division in JS, TS and Craykon gives this quotient exactly too. The last trap is a size like 1048575 B, which is 1023.999… KiB and rounds to 1024.0. Then move up one unit and write 1.0 MiB.
Pythonmain.py · 23 lines
UNITS = ["B", "KiB", "MiB", "GiB", "TiB"]def human(s): if s < 1024: return f"{s} B" k = 1 while k < 4 and 1024 ** (k + 1) <= s: k += 1 d = 1024 ** k # 정수 거듭제곱이라 정확하다 t = (20 * s + d) // (2 * d) # 소수 첫째 자리까지 반올림한 값 × 10 (0.5는 올림) if t >= 10240 and k < 4: # 1024.0이 되면 다음 단위로 k += 1 d *= 1024 t = (20 * s + d) // (2 * d) return f"{t // 10}.{t % 10} {UNITS[k]}"n = int(input())for _ in range(n): line = input() name, size = line.rsplit(" ", 1) # 이름에 빈칸이 있을 수 있어 마지막 빈칸에서 자른다 print(f"{name}: {human(int(size))}")
JavaScriptmain.js · 24 lines
const lines = require("fs").readFileSync(0, "utf8").split("\n");const UNITS = ["B", "KiB", "MiB", "GiB", "TiB"];const human = (s) => { if (s < 1024) return s + " B"; let k = 1; while (k < 4 && 1024 ** (k + 1) <= s) k++; let d = 1024 ** k; // 2의 거듭제곱이라 number로 정확하다 let t = Math.floor((20 * s + d) / (2 * d)); // 소수 첫째 자리까지 반올림한 값 × 10 (0.5는 올림) if (t >= 10240 && k < 4) { // 1024.0이 되면 다음 단위로 k++; d *= 1024; t = Math.floor((20 * s + d) / (2 * d)); } return Math.floor(t / 10) + "." + (t % 10) + " " + UNITS[k];};const n = Number(lines[0]);const out = [];for (let i = 1; i <= n; i++) { const line = lines[i]; const cut = line.lastIndexOf(" "); // 이름에 빈칸이 있을 수 있어 마지막 빈칸에서 자른다 out.push(line.slice(0, cut) + ": " + human(Number(line.slice(cut + 1))));}console.log(out.join("\n"));
TypeScriptmain.ts · 25 lines
import { readFileSync } from "node:fs";const lines: string[] = readFileSync(0, "utf8").split("\n");const UNITS: string[] = ["B", "KiB", "MiB", "GiB", "TiB"];const human = (s: number): string => { if (s < 1024) return s + " B"; let k = 1; while (k < 4 && 1024 ** (k + 1) <= s) k++; let d: number = 1024 ** k; // 2의 거듭제곱이라 number로 정확하다 let t: number = Math.floor((20 * s + d) / (2 * d)); // 소수 첫째 자리까지 반올림한 값 × 10 (0.5는 올림) if (t >= 10240 && k < 4) { // 1024.0이 되면 다음 단위로 k++; d *= 1024; t = Math.floor((20 * s + d) / (2 * d)); } return Math.floor(t / 10) + "." + (t % 10) + " " + UNITS[k];};const n = Number(lines[0]);const out: string[] = [];for (let i = 1; i <= n; i++) { const line: string = lines[i]; const cut: number = line.lastIndexOf(" "); // 이름에 빈칸이 있을 수 있어 마지막 빈칸에서 자른다 out.push(line.slice(0, cut) + ": " + human(Number(line.slice(cut + 1))));}console.log(out.join("\n"));
JavaMain.java · 35 lines
import java.io.BufferedReader;import java.io.InputStreamReader;public class Main { static final String[] UNITS = {"B", "KiB", "MiB", "GiB", "TiB"}; static String human(long s) { if (s < 1024) return s + " B"; int k = 1; long d = 1024; while (k < 4 && d * 1024 <= s) { // 1024를 곱해 가며 거듭제곱(long이라 넘치지 않는다) d *= 1024; k++; } long t = (20 * s + d) / (2 * d); // 소수 첫째 자리까지 반올림한 값 × 10 (0.5는 올림) if (t >= 10240 && k < 4) { // 1024.0이 되면 다음 단위로 k++; d *= 1024; t = (20 * s + d) / (2 * d); } return t / 10 + "." + t % 10 + " " + UNITS[k]; } public static void main(String[] args) throws Exception { BufferedReader in = new BufferedReader(new InputStreamReader(System.in)); int n = Integer.parseInt(in.readLine().trim()); StringBuilder out = new StringBuilder(); for (int i = 0; i < n; i++) { String line = in.readLine(); // 줄 전체를 읽는다 int cut = line.lastIndexOf(' '); // 이름에 빈칸이 있을 수 있어 마지막 빈칸에서 자른다 out.append(line, 0, cut).append(": ").append(human(Long.parseLong(line.substring(cut + 1)))).append('\n'); } System.out.print(out); }}
C#Main.cs · 40 lines
using System;using System.Text;class Program{ static readonly string[] Units = { "B", "KiB", "MiB", "GiB", "TiB" }; static string Human(long s) { if (s < 1024) return s + " B"; int k = 1; long d = 1024; while (k < 4 && d * 1024 <= s) // 1024를 곱해 가며 거듭제곱(long이라 넘치지 않는다) { d *= 1024; k++; } long t = (20 * s + d) / (2 * d); // 소수 첫째 자리까지 반올림한 값 × 10 (0.5는 올림) if (t >= 10240 && k < 4) // 1024.0이 되면 다음 단위로 { k++; d *= 1024; t = (20 * s + d) / (2 * d); } return $"{t / 10}.{t % 10} {Units[k]}"; } static void Main() { int n = int.Parse(Console.ReadLine()); var sb = new StringBuilder(); for (int i = 0; i < n; i++) { string line = Console.ReadLine(); // 줄 전체를 읽는다 int cut = line.LastIndexOf(' '); // 이름에 빈칸이 있을 수 있어 마지막 빈칸에서 자른다 sb.Append(line, 0, cut).Append(": ").Append(Human(long.Parse(line.Substring(cut + 1)))).Append('\n'); } Console.Write(sb); }}
C++main.cpp · 32 lines
#include <iostream>#include <string>const std::string UNITS[] = {"B", "KiB", "MiB", "GiB", "TiB"};std::string human(long long s) { if (s < 1024) return std::to_string(s) + " B"; int k = 1; long long d = 1024; while (k < 4 && d * 1024 <= s) { // 1024를 곱해 가며 거듭제곱(long long이라 넘치지 않는다) d *= 1024; k++; } long long t = (20 * s + d) / (2 * d); // 소수 첫째 자리까지 반올림한 값 × 10 (0.5는 올림) if (t >= 10240 && k < 4) { // 1024.0이 되면 다음 단위로 k++; d *= 1024; t = (20 * s + d) / (2 * d); } return std::to_string(t / 10) + "." + std::to_string(t % 10) + " " + UNITS[k];}int main() { std::string line; std::getline(std::cin, line); int n = std::stoi(line); for (int i = 0; i < n; i++) { std::getline(std::cin, line); // 줄 전체를 읽는다(>>는 빈칸에서 멈춘다) auto cut = line.rfind(' '); // 이름에 빈칸이 있을 수 있어 마지막 빈칸에서 자른다 std::cout << line.substr(0, cut) << ": " << human(std::stoll(line.substr(cut + 1))) << '\n'; }}
Cmain.c · 40 lines
#include <stdio.h>#include <stdlib.h>#include <string.h>static const char* UNITS[] = {"B", "KiB", "MiB", "GiB", "TiB"};void print_human(long long s) { if (s < 1024) { printf("%lld B\n", s); return; } int k = 1; long long d = 1024; while (k < 4 && d * 1024 <= s) { /* 1024를 곱해 가며 거듭제곱(long long이라 넘치지 않는다) */ d *= 1024; k++; } long long t = (20 * s + d) / (2 * d); /* 소수 첫째 자리까지 반올림한 값 × 10 (0.5는 올림) */ if (t >= 10240 && k < 4) { /* 1024.0이 되면 다음 단위로 */ k++; d *= 1024; t = (20 * s + d) / (2 * d); } printf("%lld.%lld %s\n", t / 10, t % 10, UNITS[k]);}int main(void) { char line[128]; fgets(line, sizeof line, stdin); int n = atoi(line); for (int i = 0; i < n; i++) { fgets(line, sizeof line, stdin); /* 줄 전체를 읽는다(끝의 줄바꿈까지) */ line[strcspn(line, "\n")] = '\0'; char* cut = strrchr(line, ' '); /* 이름에 빈칸이 있을 수 있어 마지막 빈칸에서 자른다 */ *cut = '\0'; printf("%s: ", line); print_human(atoll(cut + 1)); } return 0;}
Craykonmain.cray · 40 lines
UNITS = ["B", "KiB", "MiB", "GiB", "TiB"];반올림열배(s, d){ // 소수 첫째 자리까지 반올림한 값 × 10 (0.5는 올림). d가 2의 거듭제곱이라 나눗셈이 정확하다 return Mathf.Quot(20 * s + d, 2 * d);}사람단위(s){ if (s < 1024) { return s + " B"; } k = 1; d = 1024; while (k < 4 && d * 1024 <= s) { d *= 1024; // 거듭제곱 연산자가 없으니 1024를 곱해 간다 k += 1; } t = 반올림열배(s, d); if (t >= 10240 && k < 4) { k += 1; // 1024.0이 되면 다음 단위로 d *= 1024; t = 반올림열배(s, d); } return Mathf.Quot(t, 10) + "." + t % 10 + " " + UNITS[k];}n = Console.ReadLine().ToNumber();for (i = 0; i < n; i++){ // 이름에 빈칸이 있을 수 있어 줄 전체를 읽고 마지막 조각을 크기로 쓴다(이름 안의 빈칸은 하나씩) 조각 = Console.ReadLine().Split(" "); 크기 = 조각[조각.Count - 1].ToNumber(); 이름 = 조각.GetRange(0, 조각.Count - 1).Join(" "); Console.WriteLine(이름 + ": " + 사람단위(크기));}