{ }codelper
printing without newlineP0404

A banner printed with a digit font

A digit banner machine prints a digit string in large letters using a font given in the input. The font has one picture for each digit from 0 to 9. Each picture has h rows, and each row is a string made only of # and .. All rows of one picture have the same length, and that length is called the width of that digit. Different digits may have different widths. The digits of the string s are put into blocks one by one, from left to right. Inside a block the pictures are placed side by side from left to right, with one column made only of . inserted between every two neighbouring pictures. The width of a block is the sum of the widths of its pictures plus the number of inserted columns. The first digit of s goes into the first block. For every later digit: if the current block's width would still be at most W after adding it, it goes into the current block; if the width would exceed W, a new block is started and the digit goes there. Print the blocks in the order they were made. A block is printed as h lines, and its k-th line is the k-th rows of its pictures joined from left to right with one . between neighbours. So each line is exactly as long as the block's width, and no inserted . appears at the start or the end of a line. Print one empty line between two neighbouring blocks. Print no empty line before the first block or after the last block.

Input
The first line holds the picture height h and the block width limit W, separated by a single space. The next 10×h lines hold the picture of 0, the picture of 1, …, the picture of 9 in that order, h lines each. The last line holds the digit string s. 1 ≤ h ≤ 8. Every picture's width is between 1 and 8, and the widest picture's width ≤ W ≤ 80, so a block holding a single picture never exceeds W. s consists only of the digits 0–9, and its length is between 1 and 1,000.
Output
h lines per block, with one empty line between neighbouring blocks
Example 1 · stdin
3 7
###
#.#
###
#
#
#
##.
.#.
.##
###
.##
###
#.#
###
..#
.##
.#.
##.
#..
###
###
##
.#
.#
###
###
###
###
###
..#
01230
stdout
###.#
#.#.#
###.#

##..###
.#...##
.##.###

###
#.#
###
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

Here one line is built from pieces of several pictures before the line ends.
So the outer loop is the row (0 to h-1) and the inner loop is the pictures in the block — if you print all h rows of one picture before moving to the next, the digits stack downwards instead of sideways.
Each language writes without a newline differently.
Python uses print(x, end="") (plain print(x) adds \n), JS/TS use process.stdout.write(x) (console.log always ends the line; calling write tens of thousands of times is slow, so the solution appends the pieces to a string and writes it once), Java has print and println (the solution collects output in a PrintWriter for speed and calls flush() at the end), C# has Write and WriteLine, C uses fputs / putchar / printf, C++ uses std::cout << x (you add '\n' yourself), and Craykon has Console.Write(x) and Console.WriteLine(x).
In Craykon, Console.WriteLine("") just ends the line.
Trap one: using an output function that ends the line.
Python print(glyph[row]), or puts instead of fputs in C (puts appends a newline), breaks the line after every piece, so the example's first line comes out as just ###.
Trap two: adding . after every picture leaves one . at the end of each line (the example's first line becomes ###.#.).
Many judges forgive trailing spaces, but . is a visible character, so it is simply wrong.
Put the . in front of every picture except the first.
Trap three: measuring the block width wrongly.
Adding a picture grows the width by its width plus 1 for the gap column.
Leave out the gap and the example puts 0, 1 and 2 in one block (real width 9); compare with < W instead of ≤ W and the second block (2 and 3, width exactly 7) is split in two.
Trap four: the empty line goes only between blocks.
Forget it and the blocks run together; print it before every block and the output starts with an empty line.
Print it before every block from the second one on.

Pythonmain.py · 31 lines
import sys tokens = sys.stdin.read().split()h, w_max = int(tokens[0]), int(tokens[1])font = []for d in range(10):    font.append(tokens[2 + d * h: 2 + (d + 1) * h])s = tokens[2 + 10 * h] # 숫자들을 덩어리로 나눈다blocks = []width = 0for ch in s:    glyph = font[int(ch)]    gw = len(glyph[0])    if blocks and width + 1 + gw <= w_max:        blocks[-1].append(glyph)        width += 1 + gw    else:        blocks.append([glyph])        width = gw for b, block in enumerate(blocks):    if b > 0:        print()    for row in range(h):        for i, glyph in enumerate(block):            if i > 0:                print(".", end="")            print(glyph[row], end="")        print()
JavaScriptmain.js · 35 lines
const tokens = require("fs").readFileSync(0, "utf8").trim().split(/\s+/);const h = Number(tokens[0]);const maxWidth = Number(tokens[1]);const font = [];for (let d = 0; d < 10; d++) font.push(tokens.slice(2 + d * h, 2 + (d + 1) * h));const s = tokens[2 + 10 * h]; // 숫자들을 덩어리로 나눈다const blocks = [];let width = 0;for (const ch of s) {  const glyph = font[Number(ch)];  const gw = glyph[0].length;  if (blocks.length > 0 && width + 1 + gw <= maxWidth) {    blocks[blocks.length - 1].push(glyph);    width += 1 + gw;  } else {    blocks.push([glyph]);    width = gw;  }} // console.log는 늘 줄을 바꾼다. 조각을 문자열에 이어 붙였다가 process.stdout.write로 한 번에 쓴다let out = "";blocks.forEach((block, b) => {  if (b > 0) out += "\n";  for (let row = 0; row < h; row++) {    block.forEach((glyph, i) => {      if (i > 0) out += ".";      out += glyph[row];    });    out += "\n";  }});process.stdout.write(out);
TypeScriptmain.ts · 36 lines
import { readFileSync } from "node:fs";const tokens: string[] = readFileSync(0, "utf8").trim().split(/\s+/);const h: number = Number(tokens[0]);const maxWidth: number = Number(tokens[1]);const font: string[][] = [];for (let d = 0; d < 10; d++) font.push(tokens.slice(2 + d * h, 2 + (d + 1) * h));const s: string = tokens[2 + 10 * h]; // 숫자들을 덩어리로 나눈다const blocks: string[][][] = [];let width = 0;for (const ch of s) {  const glyph = font[Number(ch)];  const gw = glyph[0].length;  if (blocks.length > 0 && width + 1 + gw <= maxWidth) {    blocks[blocks.length - 1].push(glyph);    width += 1 + gw;  } else {    blocks.push([glyph]);    width = gw;  }} // console.log는 늘 줄을 바꾼다. 조각을 문자열에 이어 붙였다가 process.stdout.write로 한 번에 쓴다let out: string = "";blocks.forEach((block, b) => {  if (b > 0) out += "\n";  for (let row = 0; row < h; row++) {    block.forEach((glyph, i) => {      if (i > 0) out += ".";      out += glyph[row];    });    out += "\n";  }});process.stdout.write(out);
JavaMain.java · 48 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 h = Integer.parseInt(st.nextToken());        int maxWidth = Integer.parseInt(st.nextToken());        String[][] font = new String[10][h];        for (int d = 0; d < 10; d++)            for (int r = 0; r < h; r++)                font[d][r] = in.readLine().trim();        String s = in.readLine().trim();         // 숫자들을 덩어리로 나눈다        List<List<String[]>> blocks = new ArrayList<>();        int width = 0;        for (char ch : s.toCharArray()) {            String[] glyph = font[ch - '0'];            int gw = glyph[0].length();            if (!blocks.isEmpty() && width + 1 + gw <= maxWidth) {                blocks.get(blocks.size() - 1).add(glyph);                width += 1 + gw;            } else {                List<String[]> block = new ArrayList<>();                block.add(glyph);                blocks.add(block);                width = gw;            }        }         // print는 줄을 바꾸지 않고, println은 바꾼다        PrintWriter out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(System.out)));        for (int b = 0; b < blocks.size(); b++) {            if (b > 0) out.println();            List<String[]> block = blocks.get(b);            for (int row = 0; row < h; row++) {                for (int i = 0; i < block.size(); i++) {                    if (i > 0) out.print('.');                    out.print(block.get(i)[row]);                }                out.println();            }        }        out.flush();    }}
C#Main.cs · 56 lines
using System;using System.Collections.Generic;using System.IO; class Program{    static void Main()    {        string[] first = Console.ReadLine().Split(' ', StringSplitOptions.RemoveEmptyEntries);        int h = int.Parse(first[0]);        int maxWidth = int.Parse(first[1]);        var font = new string[10][];        for (int d = 0; d < 10; d++)        {            font[d] = new string[h];            for (int r = 0; r < h; r++) font[d][r] = Console.ReadLine().Trim();        }        string s = Console.ReadLine().Trim();         // 숫자들을 덩어리로 나눈다        var blocks = new List<List<string[]>>();        int width = 0;        foreach (char ch in s)        {            string[] glyph = font[ch - '0'];            int gw = glyph[0].Length;            if (blocks.Count > 0 && width + 1 + gw <= maxWidth)            {                blocks[^1].Add(glyph);                width += 1 + gw;            }            else            {                blocks.Add(new List<string[]> { glyph });                width = gw;            }        }         // Write는 줄을 바꾸지 않고, WriteLine은 바꾼다        var output = new StreamWriter(Console.OpenStandardOutput());        for (int b = 0; b < blocks.Count; b++)        {            if (b > 0) output.WriteLine();            for (int row = 0; row < h; row++)            {                for (int i = 0; i < blocks[b].Count; i++)                {                    if (i > 0) output.Write('.');                    output.Write(blocks[b][i][row]);                }                output.WriteLine();            }        }        output.Flush();    }}
C++main.cpp · 42 lines
#include <iostream>#include <string>#include <vector>using namespace std; int main() {    int h, maxWidth;    cin >> h >> maxWidth;    vector<vector<string>> font(10, vector<string>(h));    for (int d = 0; d < 10; d++)        for (int r = 0; r < h; r++) cin >> font[d][r];    string s;    cin >> s;     // 숫자들을 덩어리로 나눈다    vector<vector<int>> blocks;    int width = 0;    for (char ch : s) {        int digit = ch - '0';        int gw = (int)font[digit][0].size();        if (!blocks.empty() && width + 1 + gw <= maxWidth) {            blocks.back().push_back(digit);            width += 1 + gw;        } else {            blocks.push_back({digit});            width = gw;        }    }     // cout << 는 줄을 바꾸지 않는다. 줄바꿈은 '\n'으로 직접 넣는다    for (size_t b = 0; b < blocks.size(); b++) {        if (b > 0) cout << '\n';        for (int row = 0; row < h; row++) {            for (size_t i = 0; i < blocks[b].size(); i++) {                if (i > 0) cout << '.';                cout << font[blocks[b][i]][row];            }            cout << '\n';        }    }    return 0;}
Cmain.c · 42 lines
#include <stdio.h>#include <string.h> char font[10][8][9]; /* 숫자 10개 × 줄 8개 × (글자 8개 + '\0') */char s[1001];int blockStart[1001]; /* 덩어리마다 첫 숫자의 자리 */ int main(void) {    int h, maxWidth;    scanf("%d %d", &h, &maxWidth);    for (int d = 0; d < 10; d++)        for (int r = 0; r < h; r++)            scanf("%8s", font[d][r]);    scanf("%1000s", s);    int n = (int)strlen(s);     /* 숫자들을 덩어리로 나눈다 */    int blocks = 0, width = 0;    for (int i = 0; i < n; i++) {        int gw = (int)strlen(font[s[i] - '0'][0]);        if (blocks > 0 && width + 1 + gw <= maxWidth) {            width += 1 + gw;        } else {            blockStart[blocks++] = i;            width = gw;        }    }    blockStart[blocks] = n;     /* puts는 끝에 줄바꿈을 붙이므로 fputs·putchar로 이어 쓴다 */    for (int b = 0; b < blocks; b++) {        if (b > 0) putchar('\n');        for (int row = 0; row < h; row++) {            for (int i = blockStart[b]; i < blockStart[b + 1]; i++) {                if (i > blockStart[b]) putchar('.');                fputs(font[s[i] - '0'][row], stdout);            }            putchar('\n');        }    }    return 0;}
Craykonmain.cray · 55 lines
첫줄 = Console.ReadNumbers();h = 첫줄[0];최대너비 = 첫줄[1];글꼴 = [];for (d = 0; d < 10; d++){    그림 = [];    for (r = 0; r < h; r++)    {        그림.Add(Console.ReadLine().Trim());    }    글꼴.Add(그림);}s = Console.ReadLine().Trim(); // 숫자들을 덩어리로 나눈다덩어리들 = [];너비 = 0;foreach (c in s){    숫자 = c.ToNumber();    그림너비 = 글꼴[숫자][0].Length;    if (덩어리들.Count > 0 && 너비 + 1 + 그림너비 <= 최대너비)    {        덩어리들[덩어리들.Count - 1].Add(숫자);        너비 += 1 + 그림너비;    }    else    {        덩어리들.Add([숫자]);        너비 = 그림너비;    }} // 콘솔.쓰기는 줄을 바꾸고, 콘솔.이어쓰기는 바꾸지 않는다for (b = 0; b < 덩어리들.Count; b++){    if (b > 0)    {        Console.WriteLine("");    }    덩어리 = 덩어리들[b];    for (줄 = 0; 줄 < h; 줄++)    {        for (i = 0; i < 덩어리.Count; i++)        {            if (i > 0)            {                Console.Write(".");            }            Console.Write(글꼴[덩어리[i]][줄]);        }        Console.WriteLine("");    }}