To look at the bytes in a file, a dump table is printed.
The first line gives the number of bytes n, the number of bytes per row w, and the address s of the first byte.
The second line gives the n bytes in order.
Group the bytes from the front, w at a time, and write one row per group. The last row may have fewer than w bytes.
Counting from 0, the address of the k-th byte is s + k.
A row is made of the following four parts, written one after another.
First, write the address of the row's first byte as eight lowercase hexadecimal digits, followed by a colon (:). If it has fewer digits, fill the front with 0.
Second, for each byte write one space and then the byte as two uppercase hexadecimal digits (10 is 0A).
Third, if the row has fewer than w bytes, write three spaces for each missing byte.
Fourth, write two spaces and |, then one character per byte, and close with |. If the byte's value is from 32 to 126, write the ASCII character with that code; otherwise write a period (.).
A group whose bytes are all the same, in count and in value, as the group just before it gets no row.
When such unwritten rows come one after another, however many there are, write a single line holding only * in their place.
At the very end write a line of the form n bytes, sum S. n and S are decimal, and S is the sum of the values of all the bytes.
Input
1 ≤ n ≤ 6000, 1 ≤ w ≤ 16, 0 ≤ s, s + n ≤ 4294967296. Each byte is an integer from 0 to 255, and the bytes are separated by single spaces
Output
The dump rows (with * in place of unwritten rows) and the final n bytes, sum S line
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
Writing a number in hexadecimal with a fixed number of digits is spelled differently in each language. Python uses f"{b:02X}" and f"{a:08x}", C uses printf("%02X", b) and printf("%08llx", a), Java uses String.format("%02X", b) and String.format("%08x", a), and C# uses b.ToString("X2") and a.ToString("x8"): one format sets the base, the digit count and the letter case together. In JS/TS b.toString(16) is lowercase and does not fix the width, so you chain toUpperCase() and padStart(2, "0"). C++ sets manipulators, as in std::cout << std::hex << std::setfill('0') << std::setw(2) << b. Craykon has no hexadecimal format, so you build it yourself, picking one digit with rest % 16 and shrinking with Mathf.Quot(rest, 16), and you get the character with Str.FromCode(b). Trap one: without zero fill (Python {b:X}) a byte below 16 becomes one digit. In the first example 10 comes out as A instead of 0A and everything after it shifts by one column. Trap two: toString(16) in JS is lowercase, so without toUpperCase()6C comes out as 6c. Addresses are lowercase, bytes are uppercase. Trap three: in C++ std::hex, std::setfill and std::uppercase stay on once set (only std::setw applies to just the next value). If you do not switch back with std::dec, the last line of the first example becomes 13 bytes, sum 621. Trap four: when the last row is short, not writing three spaces per missing byte pulls the | forward (third row of the first example). Trap five: only codes up to 126 are written as characters. 127 (DEL) is not a visible character. With b <= 127, the second row of the first example gets character 127 itself instead of .. Trap six: however many times the same group repeats, * is written once. In the second example two rows are left out but there is one * line. Trap seven: addresses go up to 4294967295, which does not fit in a 32-bit int (about 2.1 billion). Reading the address with int.Parse in C# stops with OverflowException. Hold it in long long in C/C++ and long in Java/C#. The examples do not show this case (it appears when s is 2147483648 or more).
Pythonmain.py · 22 lines
n, w, s = map(int, input().split())data = list(map(int, input().split()))out = []prev = None # 바로 앞 줄의 바이트들starred = False # 생략 표시 *를 이미 썼는가for i in range(0, n, w): row = data[i:i + w] if row == prev: if not starred: out.append("*") starred = True continue prev = row starred = False # 바이트는 대문자 16진수 두 자리, 모자란 칸은 빈칸 세 개 hexes = "".join(f" {b:02X}" for b in row) + " " * (w - len(row)) text = "".join(chr(b) if 32 <= b <= 126 else "." for b in row) # 주소는 소문자 16진수 여덟 자리 out.append(f"{s + i:08x}:{hexes} |{text}|")out.append(f"{n} bytes, sum {sum(data)}")print("\n".join(out))
JavaScriptmain.js · 26 lines
const lines = require("fs").readFileSync(0, "utf8").split("\n");const [n, w, s] = lines[0].trim().split(/\s+/).map(Number);const data = lines[1].trim().split(/\s+/).map(Number);const out = [];let prev = ""; // 바로 앞 줄의 바이트 부분(주소 뺀 문자열)let starred = false; // 생략 표시 *를 이미 썼는가let sum = 0;for (let i = 0; i < n; i += w) { const row = data.slice(i, i + w); for (const b of row) sum += b; // 바이트는 대문자 16진수 두 자리, 모자란 칸은 빈칸 세 개 const hexes = row.map((b) => " " + b.toString(16).toUpperCase().padStart(2, "0")).join("") + " ".repeat(w - row.length); if (hexes === prev) { if (!starred) out.push("*"); starred = true; continue; } prev = hexes; starred = false; const text = row.map((b) => (b >= 32 && b <= 126 ? String.fromCharCode(b) : ".")).join(""); // 주소는 소문자 16진수 여덟 자리 out.push(`${(s + i).toString(16).padStart(8, "0")}:${hexes} |${text}|`);}out.push(`${n} bytes, sum ${sum}`);console.log(out.join("\n"));
TypeScriptmain.ts · 29 lines
import { readFileSync } from "node:fs";const lines: string[] = readFileSync(0, "utf8").split("\n");const [n, w, s]: number[] = lines[0].trim().split(/\s+/).map(Number);const data: number[] = lines[1].trim().split(/\s+/).map(Number);const hex = (value: number, width: number): string => value.toString(16).padStart(width, "0");const out: string[] = [];let prev = ""; // 바로 앞 줄의 바이트 부분(주소 뺀 문자열)let starred = false; // 생략 표시 *를 이미 썼는가let sum = 0;for (let i = 0; i < n; i += w) { const row: number[] = data.slice(i, i + w); for (const b of row) sum += b; // 바이트는 대문자 16진수 두 자리, 모자란 칸은 빈칸 세 개 const hexes: string = row.map((b) => " " + hex(b, 2).toUpperCase()).join("") + " ".repeat(w - row.length); if (hexes === prev) { if (!starred) out.push("*"); starred = true; continue; } prev = hexes; starred = false; const text: string = row.map((b) => (b >= 32 && b <= 126 ? String.fromCharCode(b) : ".")).join(""); // 주소는 소문자 16진수 여덟 자리 out.push(`${hex(s + i, 8)}:${hexes} |${text}|`);}out.push(`${n} bytes, sum ${sum}`);console.log(out.join("\n"));
JavaMain.java · 45 lines
import java.io.*;import java.util.*;public class Main { public static void main(String[] args) throws IOException { BufferedReader in = new BufferedReader(new InputStreamReader(System.in)); StringTokenizer st = new StringTokenizer(in.readLine()); int n = Integer.parseInt(st.nextToken()); int w = Integer.parseInt(st.nextToken()); long s = Long.parseLong(st.nextToken()); // 주소는 2^31을 넘을 수 있어 long st = new StringTokenizer(in.readLine()); int[] data = new int[n]; long sum = 0; for (int i = 0; i < n; i++) { data[i] = Integer.parseInt(st.nextToken()); sum += data[i]; } StringBuilder out = new StringBuilder(); boolean starred = false; // 생략 표시 *를 이미 썼는가 for (int i = 0; i < n; i += w) { int len = Math.min(w, n - i); // 바로 앞 줄(i - w부터 w개)과 바이트가 모두 같은가 if (i > 0 && len == w && Arrays.equals(data, i, i + w, data, i - w, i)) { if (!starred) out.append("*\n"); starred = true; continue; } starred = false; out.append(String.format("%08x:", s + i)); // 소문자 16진수 여덟 자리 for (int j = 0; j < w; j++) { if (j < len) out.append(String.format(" %02X", data[i + j])); // 대문자 두 자리 else out.append(" "); } out.append(" |"); for (int j = 0; j < len; j++) { int b = data[i + j]; out.append(b >= 32 && b <= 126 ? (char) b : '.'); } out.append("|\n"); } out.append(n).append(" bytes, sum ").append(sum).append('\n'); System.out.print(out); }}
C#Main.cs · 43 lines
using System;using System.Text;class Program{ static void Main() { string[] head = Console.ReadLine().Split(' ', StringSplitOptions.RemoveEmptyEntries); int n = int.Parse(head[0]); int w = int.Parse(head[1]); long s = long.Parse(head[2]); // 주소는 2^31을 넘을 수 있어 long int[] data = Array.ConvertAll(Console.ReadLine().Split(' ', StringSplitOptions.RemoveEmptyEntries), int.Parse); var output = new StringBuilder(); bool starred = false; // 생략 표시 *를 이미 썼는가 long sum = 0; for (int i = 0; i < n; i += w) { int len = Math.Min(w, n - i); var row = new ReadOnlySpan<int>(data, i, len); foreach (int b in row) sum += b; // 바로 앞 줄(i - w부터 w개)과 바이트가 모두 같은가 if (i > 0 && row.SequenceEqual(new ReadOnlySpan<int>(data, i - w, w))) { if (!starred) output.Append("*\n"); starred = true; continue; } starred = false; output.Append((s + i).ToString("x8")).Append(':'); // 소문자 16진수 여덟 자리 for (int j = 0; j < w; j++) { if (j < len) output.Append(' ').Append(data[i + j].ToString("X2")); // 대문자 두 자리 else output.Append(" "); } output.Append(" |"); foreach (int b in row) output.Append(b >= 32 && b <= 126 ? (char)b : '.'); output.Append("|\n"); } output.Append($"{n} bytes, sum {sum}\n"); Console.Write(output); }}
C++main.cpp · 45 lines
#include <algorithm>#include <iomanip>#include <iostream>#include <vector>int main() { std::ios::sync_with_stdio(false); std::cin.tie(nullptr); int n, w; long long s; // 주소는 2^31을 넘을 수 있어 long long std::cin >> n >> w >> s; std::vector<int> data(n); long long sum = 0; for (int& b : data) { std::cin >> b; sum += b; } bool starred = false; // 생략 표시 *를 이미 썼는가 for (int i = 0; i < n; i += w) { int len = std::min(w, n - i); // 바로 앞 줄(i - w부터 w개)과 바이트가 모두 같은가 if (i > 0 && len == w && std::equal(data.begin() + i, data.begin() + i + w, data.begin() + i - w)) { if (!starred) std::cout << "*\n"; starred = true; continue; } starred = false; // hex, setfill, uppercase는 한 번 걸면 계속 남고, setw는 바로 다음 값 하나에만 걸린다 std::cout << std::hex << std::setfill('0'); std::cout << std::nouppercase << std::setw(8) << s + i << ':'; std::cout << std::uppercase; for (int j = 0; j < w; j++) { if (j < len) std::cout << ' ' << std::setw(2) << data[i + j]; else std::cout << " "; } std::cout << " |"; for (int j = 0; j < len; j++) { int b = data[i + j]; std::cout << (b >= 32 && b <= 126 ? static_cast<char>(b) : '.'); } std::cout << "|\n"; } std::cout << std::dec << n << " bytes, sum " << sum << '\n'; // 10진수로 되돌린다}
Cmain.c · 42 lines
#include <stdio.h>#include <string.h>static unsigned char data[6000];int main(void) { int n, w; long long s; /* 주소는 2^31을 넘을 수 있어 long long */ scanf("%d %d %lld", &n, &w, &s); long long sum = 0; for (int i = 0; i < n; i++) { int b; scanf("%d", &b); data[i] = (unsigned char)b; sum += b; } int starred = 0; /* 생략 표시 *를 이미 썼는가 */ for (int i = 0; i < n; i += w) { int len = n - i < w ? n - i : w; /* 바로 앞 줄(i - w부터 w개)과 바이트가 모두 같은가 */ if (i > 0 && len == w && memcmp(data + i, data + i - w, (size_t)w) == 0) { if (!starred) puts("*"); starred = 1; continue; } starred = 0; printf("%08llx:", (unsigned long long)(s + i)); /* 소문자 16진수 여덟 자리 */ for (int j = 0; j < w; j++) { if (j < len) printf(" %02X", data[i + j]); /* 대문자 두 자리 */ else printf(" "); } printf(" |"); for (int j = 0; j < len; j++) { unsigned char b = data[i + j]; putchar(b >= 32 && b <= 126 ? b : '.'); } puts("|"); } printf("%d bytes, sum %lld\n", n, sum); return 0;}
Craykonmain.cray · 65 lines
// 수를 16진수 문자열로 바꾼다(자리 수만큼 앞을 0으로 채움)십육진수(값, 자리, 숫자들){ 결과 = ""; 남은 = 값; for (k = 0; k < 자리; k++) { 결과 = 숫자들[남은 % 16] + 결과; 남은 = Mathf.Quot(남은, 16); } return 결과;}첫줄 = Console.ReadNumbers();n = 첫줄[0];w = 첫줄[1];s = 첫줄[2];data = Console.ReadNumbers();이전 = ""; // 바로 앞 줄의 바이트 부분(주소 뺀 문자열)별표씀 = false; // 생략 표시 *를 이미 썼는가합 = 0;out = "";for (i = 0; i < n; i += w){ 바이트들 = ""; 글자들 = ""; for (j = 0; j < w; j++) { if (i + j < n) { b = data[i + j]; 합 += b; 바이트들 = 바이트들 + " " + 십육진수(b, 2, "0123456789ABCDEF"); if (b >= 32 && b <= 126) { 글자들 = 글자들 + Str.FromCode(b); } else { 글자들 = 글자들 + "."; } } else { 바이트들 = 바이트들 + " "; } } if (바이트들 == 이전) { if (!별표씀) { out = out + "*\n"; } 별표씀 = true; } else { 이전 = 바이트들; 별표씀 = false; out = out + 십육진수(s + i, 8, "0123456789abcdef") + ":" + 바이트들 + " |" + 글자들 + "|\n"; }}out = out + n + " bytes, sum " + 합 + "\n";Console.Write(out);