Генератор ASCII

Сегодня я наткнулся на CodinGame , сайт с проблемами программирования. Я опишу один из них.

  

Искусство ASCII позволяет вам представлять формы с использованием символов. Если быть точным, в нашем случае эти формы являются словами. Например, слово «MANHATTAN» может отображаться в тексте ASCII следующим образом:

     
 # #  #  ### # #  #  ### ###  #  ###
### # # # # # # # #  #   #  # # # #
### ### # # ### ###  #   #  ### # #
# # # # # # # # # #  #   #  # # # #
# # # # # # # # # #  #   #  # # # #
     

Ваша задача - написать программу, которая может отображать текст в тексте ASCII.

     

INPUT:
  Строка 1: ширина L буквы, представленной в тексте ASCII. Все буквы имеют одинаковую ширину.   Строка 2: высота H буквы, представленной в ASCII-ст. Все буквы имеют одинаковую высоту.   Строка 3: Строка текста T, состоящая из N символов ASCII.   Следующие строки: строка символов ABCDEFGHIJKLMNOPQRSTUVWXYZ? Представлен в искусстве ASCII.

     

ВЫВОД:
  Текст T в искусстве ASCII.
  Символы от a до z показаны в ASCII-искусстве по их эквиваленту в верхнем регистре.
  Символы, которые не входят в интервалы [a-z] или [A-Z], будут отображаться как знак вопроса в ASCII-тесте.

     

ОГРАНИЧЕНИЯ:
  0 <L <30
  0 <H <30
  0 <N <200

Пример ввода:

 20
11
MANHATTAN
 .----------------.  .----------------.  .----------------.  .----------------.  .----------------.  .----------------.  .----------------.  .----------------.  .----------------.  .----------------.  .----------------.  .----------------.  .----------------.  .-----------------. .----------------.  .----------------.  .----------------.  .----------------.  .----------------.  .----------------.  .----------------.  .----------------.  .----------------.  .----------------.  .----------------.  .----------------.  .----------------. 
| .--------------. || .--------------. || .--------------. || .--------------. || .--------------. || .--------------. || .--------------. || .--------------. || .--------------. || .--------------. || .--------------. || .--------------. || .--------------. || .--------------. || .--------------. || .--------------. || .--------------. || .--------------. || .--------------. || .--------------. || .--------------. || .--------------. || .--------------. || .--------------. || .--------------. || .--------------. || .--------------. |
| |      __      | || |   ______     | || |     ______   | || |  ________    | || |  _________   | || |  _________   | || |    ______    | || |  ____  ____  | || |     _____    | || |     _____    | || |  ___  ____   | || |   _____      | || | ____    ____ | || | ____  _____  | || |     ____     | || |   ______     | || |    ___       | || |  _______     | || |    _______   | || |  _________   | || | _____  _____ | || | ____   ____  | || | _____  _____ | || |  ____  ____  | || |  ____  ____  | || |   ________   | || |    ______    | |
| |     /  \     | || |  |_   _ \    | || |   .' ___  |  | || | |_   ___ `.  | || | |_   ___  |  | || | |_   ___  |  | || |  .' ___  |   | || | |_   ||   _| | || |    |_   _|   | || |    |_   _|   | || | |_  ||_  _|  | || |  |_   _|     | || ||_   \  /   _|| || ||_   \|_   _| | || |   .'    `.   | || |  |_   __ \   | || |  .'   '.     | || | |_   __ \    | || |   /  ___  |  | || | |  _   _  |  | || ||_   _||_   _|| || ||_  _| |_  _| | || ||_   _||_   _|| || | |_  _||_  _| | || | |_  _||_  _| | || |  |  __   _|  | || |   / _ __ `.  | |
| |    / /\ \    | || |    | |_) |   | || |  / .'   \_|  | || |   | |   `. \ | || |   | |_  \_|  | || |   | |_  \_|  | || | / .'   \_|   | || |   | |__| |   | || |      | |     | || |      | |     | || |   | |_/ /    | || |    | |       | || |  |   \/   |  | || |  |   \ | |   | || |  /  .--.  \  | || |    | |__) |  | || | /  .-.  \    | || |   | |__) |   | || |  |  (__ \_|  | || | |_/ | | \_|  | || |  | |    | |  | || |  \ \   / /   | || |  | | /\ | |  | || |   \ \  / /   | || |   \ \  / /   | || |  |_/  / /    | || |  |_/____) |  | |
| |   / ____ \   | || |    |  __'.   | || |  | |         | || |   | |    | | | || |   |  _|  _   | || |   |  _|      | || | | |    ____  | || |   |  __  |   | || |      | |     | || |   _  | |     | || |   |  __'.    | || |    | |   _   | || |  | |\  /| |  | || |  | |\ \| |   | || |  | |    | |  | || |    |  ___/   | || | | |   | |    | || |   |  __ /    | || |   '.___`-.   | || |     | |      | || |  | '    ' |  | || |   \ \ / /    | || |  | |/  \| |  | || |    > `' <    | || |    \ \/ /    | || |     .'.' _   | || |    /  ___.'  | |
| | _/ /    \ \_ | || |   _| |__) |  | || |  \ `.___.'\  | || |  _| |___.' / | || |  _| |___/ |  | || |  _| |_       | || | \ `.___]  _| | || |  _| |  | |_  | || |     _| |_    | || |  | |_' |     | || |  _| |  \ \_  | || |   _| |__/ |  | || | _| |_\/_| |_ | || | _| |_\   |_  | || |  \  `--'  /  | || |   _| |_      | || | \  `-'  \_   | || |  _| |  \ \_  | || |  |`\____) |  | || |    _| |_     | || |   \ `--' /   | || |    \ ' /     | || |  |   /\   |  | || |  _/ /'`\ \_  | || |    _|  |_    | || |   _/ /__/ |  | || |    |_|       | |
| ||____|  |____|| || |  |_______/   | || |   `._____.'  | || | |________.'  | || | |_________|  | || | |_____|      | || |  `._____.'   | || | |____||____| | || |    |_____|   | || |  `.___.'     | || | |____||____| | || |  |________|  | || ||_____||_____|| || ||_____|\____| | || |   `.____.'   | || |  |_____|     | || |  `.___.\__|  | || | |____| |___| | || |  |_______.'  | || |   |_____|    | || |    `.__.'    | || |     \_/      | || |  |__/  \__|  | || | |____||____| | || |   |______|   | || |  |________|  | || |    (_)       | |
| |              | || |              | || |              | || |              | || |              | || |              | || |              | || |              | || |              | || |              | || |              | || |              | || |              | || |              | || |              | || |              | || |              | || |              | || |              | || |              | || |              | || |              | || |              | || |              | || |              | || |              | || |              | |
| '--------------' || '--------------' || '--------------' || '--------------' || '--------------' || '--------------' || '--------------' || '--------------' || '--------------' || '--------------' || '--------------' || '--------------' || '--------------' || '--------------' || '--------------' || '--------------' || '--------------' || '--------------' || '--------------' || '--------------' || '--------------' || '--------------' || '--------------' || '--------------' || '--------------' || '--------------' || '--------------' |
 '----------------'  '----------------'  '----------------'  '----------------'  '----------------'  '----------------'  '----------------'  '----------------'  '----------------'  '----------------'  '----------------'  '----------------'  '----------------'  '----------------'  '----------------'  '----------------'  '----------------'  '----------------'  '----------------'  '----------------'  '----------------'  '----------------'  '----------------'  '----------------'  '----------------'  '----------------'  '----------------' 

Пример вывода:

  .----------------.  .----------------.  .-----------------. .----------------.  .----------------.  .----------------.  .----------------.  .----------------.  .-----------------.
| .--------------. || .--------------. || .--------------. || .--------------. || .--------------. || .--------------. || .--------------. || .--------------. || .--------------. |
| | ____    ____ | || |      __      | || | ____  _____  | || |  ____  ____  | || |      __      | || |  _________   | || |  _________   | || |      __      | || | ____  _____  | |
| ||_   \  /   _|| || |     /  \     | || ||_   \|_   _| | || | |_   ||   _| | || |     /  \     | || | |  _   _  |  | || | |  _   _  |  | || |     /  \     | || ||_   \|_   _| | |
| |  |   \/   |  | || |    / /\ \    | || |  |   \ | |   | || |   | |__| |   | || |    / /\ \    | || | |_/ | | \_|  | || | |_/ | | \_|  | || |    / /\ \    | || |  |   \ | |   | |
| |  | |\  /| |  | || |   / ____ \   | || |  | |\ \| |   | || |   |  __  |   | || |   / ____ \   | || |     | |      | || |     | |      | || |   / ____ \   | || |  | |\ \| |   | |
| | _| |_\/_| |_ | || | _/ /    \ \_ | || | _| |_\   |_  | || |  _| |  | |_  | || | _/ /    \ \_ | || |    _| |_     | || |    _| |_     | || | _/ /    \ \_ | || | _| |_\   |_  | |
| ||_____||_____|| || ||____|  |____|| || ||_____|\____| | || | |____||____| | || ||____|  |____|| || |   |_____|    | || |   |_____|    | || ||____|  |____|| || ||_____|\____| | |
| |              | || |              | || |              | || |              | || |              | || |              | || |              | || |              | || |              | |
| '--------------' || '--------------' || '--------------' || '--------------' || '--------------' || '--------------' || '--------------' || '--------------' || '--------------' |
 '----------------'  '----------------'  '----------------'  '----------------'  '----------------'  '----------------'  '----------------'  '----------------'  '----------------' 

Это , поэтому обычная проверка входных данных, обработка аргументов и обработка данных были пропущены. Мой код набирает 100% (что означает, что это ошибка для всех случаев), но похоже, что это могло быть более кратким.

Там много циклов, что, вероятно, плохо. Именование, возможно, было бы лучше. Я не строго придерживался наименования, заданного назначением, так как программа, проверяющая код, все равно.

l = int(raw_input())
h = int(raw_input())
text_source = raw_input()
ascii_rows = []
alphabet = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ?'
for d in xrange(h):
    ascii_row = raw_input()
    ascii_rows.append(ascii_row)

output = ['']

for i in xrange(h-1):
    output.append('')

for character in text_source:
    found = False
    for ascii in xrange(len(alphabet)):
        if character.upper() == alphabet[ascii]:
            found = True
            for it in xrange(h):
                output[it] += ascii_rows[it][l * ascii:l * (ascii + 1)]
    if not found:
        for it in xrange(h):
            output[it] += ascii_rows[it][l * ascii:l * (ascii + 1)]

for row in output:
    print row
11 голосов | спросил Mast 8 +03002015-10-08T00:29:47+03:00312015bEurope/MoscowThu, 08 Oct 2015 00:29:47 +0300 2015, 00:29:47

4 ответа


6

Краткая петля

Всякий раз, когда вам понадобится индекс элемента и , используйте enumerate() . Это сокращает нас до:

for character in text_source:
    found = False
    for idx, letter in enumerate(alphabet):
        if character.upper() == letter:
            found = True
            for it in xrange(h):
                output[it] += ascii_rows[it][l * idx:l * (idx + 1)]
    if not found:
        for it in xrange(h):
            output[it] += ascii_rows[it][l * len(alphabet):]

Затем, когда вы зацикливаете, пока не найдете что-то, и если у вас есть чек, вы можете использовать for. .. break ... else , Это позволяет избежать found:

for character in text_source:
    for idx, letter in enumerate(alphabet):
        if character.upper() == letter:
            for it in xrange(h):
                output[it] += ascii_rows[it][l * idx:l * (idx + 1)]
            break # no reason to keep checking anything
    else:
        # wasn't found

ascii_rows

Прямо сейчас, каждый из ваших ascii_rows - это полная строка , и вы захватываете соответствующий фрагмент как ты иди. Однако вместо этого, если бы вы сделали все, что было в порядке, это упростило бы ваш алгоритм.

Давайте добавим этот chunker :

def chunks(l, n):
    """Yield successive n-sized chunks from l."""
    for i in xrange(0, len(l), n):
        yield l[i:i+n]

, с помощью которого мы можем написать:

ascii_rows = [list(chunks(raw_input(), l)) for _ in xrange(h)]

Как только мы его разложим, нам не нужно делать какое-либо умножение. Таким образом, наш исходный цикл может быть сокращен далее:

for character in text_source:
    for idx, letter in enumerate(alphabet):
        if character.upper() == letter:
            for it in xrange(h):
                output[it] += ascii_rows[it][idx]
            break
    else:
        for it in xrange(h):
            output[it] += ascii_rows[it][-1]

Улучшенный поиск по-прежнему

Существует find() для строк. Он вернет индекс или -1 при ошибке. Достаточно достаточно, мы хотим -1 при сбое!

Таким образом, нам даже не нужен цикл:

for character in text_source:
    idx = alphabet.find(character.upper())
    for it in xrange(h):
        output[it] += ascii_rows[it][idx]

Понимание MOAR?

Мы могли бы просто переписать весь бизнес в парах понимания:

indices = [alphabet.find(letter.upper()) for letter in text_source]
output = (''.join(ascii_rows[it][idx] for idx in indices)
          for it in xrange(h))
print '\n'.join(output)
ответил Barry 8 +03002015-10-08T04:25:00+03:00312015bEurope/MoscowThu, 08 Oct 2015 04:25:00 +0300 2015, 04:25:00
6

Ваш ascii_rows почти составляет определение шрифта. Я думаю, что где-то в программе должен быть font = something , и я бы предпочел, чтобы something включить понимание списка.

Я говорю почти , потому что вы сохраняете ascii_rows в довольно сырой форме. В результате ваш цикл for character in text_source: … довольно сложный. То, что вам не хватает, - это лучшая структура данных. В приведенном ниже решении я разделил работу по определению шрифта (часть инструкции font = …) и работу по составлению output (часть инструкции output = …).

Собственно, ascii является немного неправильным. В alphabet[ascii], ascii выглядит так, как будто быть кодовым значением ASCII, но это не так.

Переменные флагов, такие как found, являются неэлегантными. Неизбежно необходимо (повторно) инициализировать флаг, возможно установить флаг и проверить флаг. В этом случае всей потребности можно избежать с помощью dict.get() .

from string import ascii_uppercase

# Read input
l = int(raw_input())
h = int(raw_input())
text_source = raw_input().upper()
font_source = [raw_input() for _ in range(h)]

# Define the font
repertoire = ascii_uppercase + '?'
font = [
    { char: row[l*i : l*(i+1)] for i, char in enumerate(repertoire) }
    for row in font_source
]

# Generate output
output = "\n".join(
    ''.join(row.get(char) or row['?'] for char in text_source)
    for row in font
)
print(output)
ответил 200_success 9 +03002015-10-09T07:00:04+03:00312015bEurope/MoscowFri, 09 Oct 2015 07:00:04 +0300 2015, 07:00:04
3

Вместо ручного ввода алфавита вы можете просто использовать модуль string. Он имеет константу прописных букв ascii.

from string import ascii_uppercase as alphabet

Хотя вам нужно добавить вручную ?.

ответил SuperBiasedMan 8 +03002015-10-08T14:09:54+03:00312015bEurope/MoscowThu, 08 Oct 2015 14:09:54 +0300 2015, 14:09:54
0

Я решил его с помощью вложенного списка. Не уверен, что вы можете получить более сжатые, если это ваша цель.

l = int(raw_input())
h = int(raw_input())
text_source = raw_input().upper() # put the upper() here to make the code below easier to read
ascii_rows = []
for d in xrange(h):
    ascii_row = raw_input()
    ascii_rows.append(ascii_row)

def ascii_index(c):
    # '[' comes after 'Z' in the ascii chart.
    # ord('A') == 65, so this function returns a number
    # that can be used as an index into the ascii_row strings.
    return (ord('[') if c < 'A' or c > 'Z' else ord(c)) - 65

# No need for xrange(), just loop the data structures.
print("\n".join(["".join([ row[l*ascii_index(c):l*(ascii_index(c)+1)] for c in text_source]) for row in ascii_rows ]))
ответил RobertB 9 +03002015-10-09T02:32:20+03:00312015bEurope/MoscowFri, 09 Oct 2015 02:32:20 +0300 2015, 02:32:20

Похожие вопросы

Популярные теги

security × 330linux × 316macos × 2827 × 268performance × 244command-line × 241sql-server × 235joomla-3.x × 222java × 189c++ × 186windows × 180cisco × 168bash × 158c# × 142gmail × 139arduino-uno × 139javascript × 134ssh × 133seo × 132mysql × 132