Весы журнала для лодырей


24

Все знают, что шкалы логов предназначены для лодырей . Следовательно, вы должны написать программу или функцию, которая снимает гистограмму с масштабом журнала, заданным основанием.

Ввод гистограммы принимается в виде единой строки, представляющей собой список баров, где каждый столбец гистограммы лог-шкалы отделяется выбранным для печати (или пробелом) разделителем (т. Е. 0x09-0x0A + 0x20-0x7E) и составлен из печатного непробельного (т. е. 0x21-0x7E) символа наполнителя по вашему выбору.

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

пример

Мы выбираем разделитель «\ n» (одна новая строка) и символ-заполнитель «#». Входные данные, переданные нашей программе или функции:

база = 2 и строка =

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

Код найдет, что длина столбцов [4,2,6,3]. Это вычислит анти-лог каждой длины с основанием, 2чтобы получить [2^4,2^2,2^6,2^3]= [16,4,64,8]. Затем длины выводятся в формате линейной шкалы:

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

Ввод, вывод

Ваша программа или функция может вводить и выводить данные в любом приемлемом формате .

Входное основание гарантированно будет целым числом больше 1. Вы можете предположить, что базовое значение меньше 256. Строковый ввод гарантированно полностью соответствует регулярному выражению (f+s)+f+, где fи sзаменены вашим заполнителем и разделителем соответственно.

Вывод строки должен полностью соответствовать регулярному выражению (f+s)+f+, где fи sзаменяются тем же самым заполнителем и разделителем соответственно. Выходные данные могут дополнительно иметь завершающий символ новой строки.

Выходные данные и входные данные также могут быть списком строк вместо того, чтобы разделяться подстрокой, хотя должна быть возможность понять, какая строка является какой.

Testcases

(предположим, что заполнитель #и разделитель \n)

base
-
input string
-
output string
-----
2
-
####
##
######
###
-
################
####
################################################################
########
-----
3
-
##
#
###
#
-
#########
###
###########################
###
-----
100
-
#   I am not the delimiter
###  nor the filler
-
Anything (You do not have to handle input which does not match the regex)
-----
1
-
###
#######
###################################################
- 
Anything (You do not have to handle bases less than or equal to 1).
-----
5
-
####
##
###
#
-
#################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################    
#########################
#############################################################################################################################
#####
-----
2
-
#
#
##
##
#
##
#
#
#
#
##
##
#
#
##
#
-
##
##
####
####
##
####
##
##
##
##
####
####
##
##
####
##

Ответы:


6

32-битная функция машинного кода x86, 21 байт

Функция машинного кода x86-64, 22 байта

Сохранение 1B в 32-битном режиме требует использования separator = filler-1, например, fill=0и sep=/. 22-байтовая версия может использовать произвольный выбор разделителя и заполнителя.


Это 21-байтовая версия, с входным разделителем = \n(0xa), выходным заполнителем = 0, выходным разделителем = /= заполнителем-1. Эти константы могут быть легко изменены.

; see the source for more comments
; RDI points to the output buffer,  RSI points to the src string
; EDX holds the base
; This is the 32-bit version.
; The 64-bit version is the same, but the DEC is one byte longer (or we can just mov al,output_separator)
08048080 <str_exp>:
 8048080:       6a 01           push   0x1
 8048082:       59              pop    ecx           ; ecx = 1 = base**0
 8048083:       ac                      lods   al,BYTE PTR ds:[esi]  ; skip the first char so we don't do too many multiplies

; read an input row and accumulate base**n as we go.
08048084 <str_exp.read_bar>:
 8048084:       0f af ca        imul   ecx,edx       ; accumulate the exponential
 8048087:       ac              lods   al,BYTE PTR ds:[esi]
 8048088:       3c 0a           cmp    al,0xa        ; input_separator = newline
 804808a:       77 f8           ja     8048084 <str_exp.read_bar>
 ; AL = separator or terminator
 ; flags = below (CF=1) or equal (ZF=1).  Equal also implies CF=0 in this case.

 ; store the output row
 804808c:       b0 30           mov    al,0x30       ; output_filler
 804808e:       f3 aa           rep stos BYTE PTR es:[edi],al  ; ecx bytes of filler
 8048090:       48              dec    eax           ; mov al,output_separator 
 8048091:       aa              stos   BYTE PTR es:[edi],al  ;append delim

 ; CF still set from the inner loop, even after DEC clobbers the other flags
 8048092:       73 ec           jnc    8048080 <str_exp>  ; new row if this is a separator, not terminator

 8048094:       c3              ret    

08048095  <end_of_function>
; 0x95 - 0x80 = 0x15 = 21 bytes

64-битная версия на 1 байт длиннее, с использованием 2-байтового DEC или a mov al, output_separator. Кроме этого, машинный код одинаков для обеих версий, но некоторые имена регистров меняются (например, rcxвместо ecxв pop).

Пример выходных данных при запуске тестовой программы (база 3):

$ ./string-exponential $'.\n..\n...\n....' $(seq 3);echo 
000/000000000/000000000000000000000000000/000000000000000000000000000000000000000000000000000000000000000000000000000000000/

Алгоритм :

Зацикливание на входе, делая exp *= baseдля каждого заполнителя char. На разделителях и завершающем нулевом байте добавьте expбайты заполнителя, а затем разделитель к выходной строке и сбросьте на exp=1. Очень удобно, что ввод гарантированно не заканчивается как новой строкой, так и разделителем.

На входе любое значение байта выше разделителя (сравнение без знака) обрабатывается как заполнитель, а любое значение байта ниже разделителя обрабатывается как маркер конца строки. (При явной проверке нулевого байта потребуется дополнительная test al,alветвь против ветвления для флагов, установленных внутренним циклом).


Правила допускают только конечный разделитель, когда это завершающий перевод строки. Моя реализация всегда добавляет разделитель. Для сохранения 1B в 32-битном режиме это правило требует разделитель = 0xa ( '\n'ASCII LF = перевод строки), filler = 0xb ( '\v'ASCII VT = вертикальная табуляция). Это не очень удобно для человека, но удовлетворяет букве закона. (Вы можете использовать hexdump или
tr $'\v' xвыходные данные, чтобы убедиться, что он работает, или изменить константу, чтобы разделитель и заполнитель выходных данных были пригодны для печати. ​​Я также заметил, что правила, по-видимому, требуют, чтобы он мог принимать входные данные с той же заливкой / разделением, которую он использует для вывода. , но я не вижу никакой выгоды от нарушения этого правила.)


Источник NASM / YASM. Создайте как 32- или 64-битный код, используя %ifматериал, включенный в тестовую программу, или просто измените rcx на ecx.

input_separator equ 0xa  ; `\n` in NASM syntax, but YASM doesn't do C-style escapes

output_filler equ '0'                 ; For strict rules-compliance, needs to be input_separator+1
output_separator equ output_filler-1  ; saves 1B in 32-bit vs. an arbitrary choice
    ;; Using output_filler+1 is also possible, but isn't compatible with using the same filler and separator for input and output.

global str_exp
str_exp:                        ; void str_exp(char *out /*rdi*/, const char *src /*rsi*/,
                                ;              unsigned base /*edx*/);
.new_row:
    push   1
    pop    rcx                  ; ecx=1 = base**0

    lodsb                       ; Skip the first char, since we multiply for the separator
.read_bar:
    imul   ecx, edx             ; accumulate the exponential
    lodsb
    cmp    al, input_separator
    ja .read_bar                ; anything > separator is treated as filler
    ; AL = separator or terminator
    ; flags = below (CF=1) or equal (ZF=1).  Equal also implies CF=0, since x-x doesn't produce carry.

    mov    al, output_filler
    rep stosb                   ; append ecx bytes of filler to the output string
%if output_separator == output_filler-1
    dec   eax         ; saves 1B in the 32-bit version.  Use dec even in 64-bit for easier testing
%else
    mov    al, output_separator
%endif
    stosb                       ; append the delimiter

    ; CF is still set from the .read_bar loop, even if DEC clobbered the other flags
    ; JNC/JNB here is equivalent to JE on the original flags, because we can only be here if the char was below-or-equal the separator
    jnc .new_row            ; separator means more rows, else it's a terminator
    ; (f+s)+f+ full-match guarantees that the input doesn't end with separator + terminator
    ret

Функция следует за x86-64 SystemV ABI с сигнатурой.
void str_exp(char *out /*rdi*/, const char *src /*rsi*/, unsigned base /*edx*/);

Она только информирует вызывающую сторону о длине выходной строки, оставляя указатель на один конец за ней rdi, так что вы можете рассмотреть это возвращаемое значение в не стандартное соглашение о вызовах.

xchg eax,ediЧтобы вернуть указатель конца в eax или rax, потребуется 1 или 2 байта ( ). (Если используется x32 ABI, указатели гарантированно будут только 32-битными, в противном случае мы должны использовать xchg rax,rdiв случае, если вызывающая сторона передает указатель на буфер за пределами младших 32-битных.) Я не включил это в версию, которую я отправка сообщений, потому что существуют обходные пути, которые может использовать вызывающая сторона без получения значения rdi, поэтому вы можете вызывать ее из C без оболочки.

Мы даже не заканчиваем нулем выходную строку или что-то еще, так что это только символ новой строки. Чтобы исправить это, потребуется 2 байта: xchg eax,ecx / stosb (rcx - ноль с rep stosb.)

Способы определения длины выходной строки:

  • rdi указывает на один конец строки при возврате (так что вызывающая сторона может сделать len = end-start)
  • вызывающая сторона может просто знать, сколько строк было на входе, и считать новые строки.
  • вызывающая сторона может использовать большой обнуленный буфер и strlen()впоследствии.

Они не симпатичны и не эффективны (за исключением использования возвращаемого значения RDI от вызывающей стороны asm), но если вы хотите, то не вызывайте asm-функции golfed из C.: P


Ограничения размера / диапазона

Максимальный размер выходной строки ограничен только адресным пространством виртуальной памяти. (Главным образом, текущее оборудование x86-64 поддерживает только 48 значащих бит в виртуальных адресах, разделенных пополам, потому что они расширяются по знаку вместо нулевого. См. Схему в связанном ответе .)

Каждая строка может иметь максимум 2 ** 32 - 1 байта-заполнителя, поскольку я накапливаю экспоненту в 32-битном регистре.

Функция работает правильно для базисов от 0 до 2 ** 32 - 1. (Правильно для базы 0 - 0 ^ x = 0, то есть просто пустые строки без байтов-заполнителей. Правильно для базы 1 - 1 ^ x = 1, поэтому всегда 1 наполнитель на строку.)

Это также невероятно быстро для Intel IvyBridge и более поздних версий, особенно для больших строк, записываемых в выровненную память. rep stosbявляется оптимальной реализацией memset()для больших подсчетов с выровненными указателями на процессорах с функцией ERMSB . например, 180 ** 4 равен 0,97 ГБ и занимает 0,27 секунды на моем i7-6700k Skylake (с ~ 256k мягких ошибок страниц) для записи в / dev / null. (В Linux драйвер устройства для / dev / null нигде не копирует данные, он просто возвращает данные. Таким образом, все время обнаруживаются rep stosbи программные сбои страниц, которые возникают при первом касании памяти. к сожалению, не использовать прозрачные огромные страницы для массива в BSS. Вероятно, madvise()системный вызов ускорит это.)

Тестовая программа :

Создайте статический двоичный файл и запустите как ./string-exponential $'#\n##\n###' $(seq 2)для базы 2. Чтобы избежать реализации atoi, он использует base = argc-2. (Ограничения длины командной строки не позволяют проверять смехотворно большие базы.)

Эта оболочка работает для строк вывода до 1 ГБ. (Это делает только один системный вызов write () даже для гигантских строк, но Linux поддерживает это даже для записи в каналы). Для подсчета символов введите wc -cили используйте, strace ./foo ... > /dev/nullчтобы увидеть arg для системного вызова write.

При этом используется возвращаемое значение RDI для вычисления длины строки в качестве аргумента write().

;;; Test program that calls it
;;; Assembles correctly for either x86-64 or i386, using the following %if stuff.
;;; This block of macro-stuff also lets us build the function itself as 32 or 64-bit with no source changes.

%ifidn __OUTPUT_FORMAT__, elf64
%define CPUMODE 64
%define STACKWIDTH 8    ; push / pop 8 bytes
%define PTRWIDTH 8
%elifidn __OUTPUT_FORMAT__, elfx32
%define CPUMODE 64
%define STACKWIDTH 8    ; push / pop 8 bytes
%define PTRWIDTH 4
%else
%define CPUMODE 32
%define STACKWIDTH 4    ; push / pop 4 bytes
%define PTRWIDTH 4
%define rcx ecx      ; Use the 32-bit names everywhere, even in addressing modes and push/pop, for 32-bit code
%define rsi esi
%define rdi edi
%define rsp esp
%endif


global _start
_start:
    mov  rsi, [rsp+PTRWIDTH + PTRWIDTH*1]  ; rsi = argv[1]
    mov  edx, [rsp]          ; base = argc
    sub  edx, 2              ; base = argc-2  (so it's possible to test base=0 and base=1, and so ./foo $'xxx\nxx\nx' $(seq 2) has the actual base in the arg to seq)
    mov  edi, outbuf         ; output buffer.  static data is in the low 2G of address space, so 32-bit mov is fine.  This part isn't golfed, though

    call str_exp             ; str_exp(outbuf, argv[1], argc-2)
    ;  leaves RDI pointing to one-past-the-end of the string
    mov  esi, outbuf

    mov  edx, edi
    sub  edx, esi               ; length = end - start

%if CPUMODE == 64 ; use the x86-64 ABI
    mov  edi, 1                 ; fd=1 (stdout)
    mov  eax, 1                 ; SYS_write  (Linux x86-64 ABI, from /usr/include/asm/unistd_64.h)
    syscall                     ; write(1, outbuf, length);

    xor edi,edi
    mov eax,231   ; exit_group(0)
    syscall


%else  ; Use the i386 32-bit ABI (with legacy int 0x80 instead of sysenter for convenience)
    mov ebx, 1
    mov eax, 4                  ; SYS_write (Linux i386 ABI, from /usr/include/asm/unistd_32.h)
    mov ecx, esi  ; outbuf
    ; 3rd arg goes in edx for both ABIs, conveniently enough
    int 0x80                    ; write(1, outbuf, length)

    xor ebx,ebx
    mov eax, 1
    int 0x80     ; 32-bit ABI _exit(0)
%endif


section .bss
align 2*1024*1024 ; hugepage alignment (32-bit uses 4M hugepages, but whatever)
outbuf:    resb 1024*1024*1024 * 1
; 2GB of code+data is the limit for the default 64-bit code model.
; But with -m32, a 2GB bss doesn't get mapped, so we segfault.  1GB is plenty anyway.

Это было забавное испытание, которое очень хорошо подействовало на asm, особенно на x86 string ops . Правила хорошо разработаны, чтобы избежать необходимости обрабатывать символ новой строки, а затем терминатор в конце входной строки.

Экспонента с повторным умножением - это то же самое, что умножение с повторным сложением, и мне все равно нужно было выполнить цикл для подсчета символов в каждой строке ввода.

Я рассмотрел использование одного операнда mulили imulвместо более длинного imul r,r, но его неявное использование EAX будет конфликтовать с LODSB.


Я также попробовал SCASB вместо загрузки и сравнения , но мне нужно было xchg esi,ediдо и после внутреннего цикла, потому что SCASB и STOSB оба используют EDI. (Таким образом, 64-битная версия должна использовать x32 ABI, чтобы избежать усечения 64-битных указателей).

Избегать STOSB не вариант; ничто иное не может быть настолько коротким. И половина преимущества использования SCASB заключается в том, что AL = заполнитель после выхода из внутреннего цикла, поэтому нам не нужно настраивать REP STOSB.

SCASB сравнивает в другом направлении с тем, что я делал, поэтому мне нужно было отменить сравнение.

Моя лучшая попытка с xchg и scasb. Работает, но не короче. ( 32-битный код, используя inc/ dectrick для изменения заполнителя на разделитель ).

; SCASB version, 24 bytes.  Also experimenting with a different loop structure for the inner loop, but all these ideas are break-even at best
; Using separator = filler+1 instead of filler-1 was necessary to distinguish separator from terminator from just CF.

input_filler equ '.'    ; bytes below this -> terminator.  Bytes above this -> separator
output_filler equ input_filler       ; implicit
output_separator equ input_filler+1  ; ('/') implicit

 8048080:       89 d1                   mov    ecx,edx    ; ecx=base**1
 8048082:       b0 2e                   mov    al,0x2e    ; input_filler= .
 8048084:       87 fe                   xchg   esi,edi
 8048086:       ae                      scas   al,BYTE PTR es:[edi]

08048087 <str_exp.read_bar>:
 8048087:       ae                      scas   al,BYTE PTR es:[edi]
 8048088:       75 05                   jne    804808f <str_exp.bar_end>
 804808a:       0f af ca                imul   ecx,edx           ; exit the loop before multiplying for non-filler
 804808d:       eb f8                   jmp    8048087 <str_exp.read_bar>   ; The other loop structure (ending with the conditional) would work with SCASB, too.  Just showing this for variety.
0804808f <str_exp.bar_end>:

; flags = below if CF=1 (filler<separator),  above if CF=0 (filler<terminator)
; (CF=0 is the AE condition, but we can't be here on equal)
; So CF is enough info to distinguish separator from terminator if we clobber ZF with INC

; AL = input_filler = output_filler
 804808f:       87 fe                   xchg   esi,edi
 8048091:       f3 aa                   rep stos BYTE PTR es:[edi],al
 8048093:       40                      inc    eax         ; output_separator
 8048094:       aa                      stos   BYTE PTR es:[edi],al
 8048095:       72 e9                   jc     8048080 <str_exp>   ; CF is still set from the inner loop
 8048097:       c3                      ret    

Для ввода ../.../., выдает ..../......../../. Я не собираюсь показывать hexdump версии с разделителем = newline.


4

Mathematica 41 38 байт

-3 байта благодаря LLlAMnYP

Это берет ввод как список строк, сопровождаемых целым числом. Вывод также является списком строк.

""<>"#"~Table~#&/@(#2^StringLength@#)&

Объяснение:

                   StringLength@# & - find length of each string in first input
                   #2^               & - raise to power of second input
                /@(                 )  - Uses each of these numbers on an inner function of ...
    "#"~Table~#&                       - Create arrys of specific length using character "#"
 ""<>                                  - Join arrays of characters together to make strings

Старая версия, 41 байт

"#"~StringRepeat~#&/@(#2^StringLength@#)&

"" <> "#"~Table~#на 3 байта короче "#"~StringRepeat~#, вероятно, также пригоден для игры в гольф.
LLlAMnYP

3

Japt , 7 байт

Принимает график как массив строк с "заполнителем, а основание - как целое число.

£QpVpXl

Попробуйте онлайн

Добавьте }Rв конец, чтобы вместо этого взять график в виде строки, разделенной новой строкой. ( Попробуй это )


объяснение

    :Implicit input of array U.
£   :Map over the array, replacing each element with ...
Q   :the " character ...
p   :repeated ...
V   :integer input ...
p   :to the power of ...
Xl  :the length of the current element times.
    :Implicit output of result.

3

MATL , 14 11 байт

Y'iw^1HL(Y"

Разделитель это пространство. Наполнитель - это любой символ, кроме пробела.

Попробуйте онлайн!

объяснение

       % Implicit input: string
       %   STACK: '## # ### #'
Y'     % Run-length encoding
       %   STACK: '# # # #', [2 1 1 1 3 1 1]
i      % Input: number
       %   STACK: '# # # #', [2 1 1 1 3 1 1], 3
w      % Swap
       %   STACK: '# # # #', 3, [2 1 1 1 3 1 1]
^      % Power, element-wise
       %   STACK: '# # # #', [9 3 3 3 9 3 3]
1      % Push 1
       %   STACK: '# # # #', [9 3 3 3 27 3 3], 1
HL     % Push [2 2 1j]. When used as an index, this means 2:2:end
       %   STACK: '# # # #', [9 3 3 3 27 3 3], 1, [2 2 1j]
(      % Write specified value at specified entries
       %   STACK: '# # # #', [9 1 3 1 27 1 3]
Y"     % Run-length decoding
       %  STACK: '######### ### ########################### ###'
       % Implicit display

Это не похоже на работу; длина каждой строки в выходных данных для тестового примера, который вы включили в свой TIO, должна составлять 9,3,27,9, но вместо этого она равна 6,3,9,3.
Лохматый

@ Shaggy Вы совершенно правы. Спасибо, что заметили. Я сделал ошибку в своем последнем редактировании. Я откатился на предыдущую версию, что правильно
Луис Мендо

Не могу понять, как это работает, из объяснения - тогда я нажал на TIO! : D
Лохматый

1
@ Shaggy Я только что добавил объяснение этой версии, надеюсь, понятнее!
Луис Мендо

3

Haskell , 37 33 байта

4 байта сбрили благодаря sudee

\b->map(\x->'#'<$[1..b^length x])

Описание:

\b->                               -- take an integer b as the first input input
    map(\x->                    )  -- apply the following to every element x in the second input
            '#'<$[1..b^length x]   ---- replicate '#' (b^(length x)) times

К сожалению, это на 2 байта намного короче, чем версия без всякого смысла:

map.(flip replicate '#'.).(.length).(^)

На входе должна быть одна строка
bartavelle

@ bartavelle, не обязательно.
Лохматый

Это то, что я понимаю под вводом гистограммы в виде одной строки ...
bartavelle

1
@bartavelle: выходные данные и входные данные также могут быть списком строк, а не разделяться подстрокой, хотя должна быть возможность понять, какая строка является какой.
Джулиан Вольф

2
Вы можете заменить replicate(b^length x)'#'на '#'<$[1..b^length x].
sudee

3

ReRegex , 105 байт

#import math
(\d+)\n((;.*\n)*)(_+)/$1\n$2;$1^d<$4>/^\d+\n((;\d+\n?)+)$/$1/^((_*\n)*);(\d+)/$1u<$3>/#input

Попробуйте онлайн!

ReRegex похож на уродливого двоюродного брата Retina, который прилагает все усилия к регулярным выражениям, вместо того, чтобы иметь свои собственные причудливые операторы.

Конечно, он также имеет #importи #inputдля сохранения ввода жесткого кода, и перезаписи одних и тех же выражений снова и снова.

Разъяснения.

Принимает вход в виде:

2
____
__
______
___

на STDIN, и дает вывод, как

________________
____
________________________________________________________________
________

Во-первых, программа импортирует Math Library , которая, конечно, полностью написана на ReRegex. Основная часть этого составляет три регулярных выражения.

(\d+)\n((;.*\n)*)(_+)   ->  $1\n$2;$1^d<$4>
^\d+\n((;\d+\n?)+)$     ->  $1
^((_*\n)*);(\d+)        ->  $1u<$3>

Первый соответствует нашей входной базе и ищет строку унарного после него. затем он заменяет эту строку на ;$1^d<$4>(которая является основой) степенью (в десятичной) унарной. Библиотека Math обрабатывает базовое преобразование и показатель степени. А; помещен в начало, чтобы идентифицировать это позже как законченный.

Второй, соответствует основанию, затем много строк;, до окончания. Если это соответствует всей вещи, она отрывается от базы. оставив уф только с ответами и ;с.

Последнее, совпадает только с одинарным в начале, по желанию, затем с ;ответом. Затем он снова превращает этот ответ в унарный, без ;.

Поскольку вывод не соответствует первому регулярному выражению, он не зацикливается бесконечно, и поэтому выводится наше решение.



2

Рёда , 19 байт

f n,s{s|["#"*n^#_]}

Попробуйте онлайн!

Принимает массив в качестве входных данных и возвращает поток значений в качестве выходных данных.

объяснение

f n,s{s|["#"*n^#_]}              n is the number and s is the array of strings consisting of #s
      s|                         Push the each value of s to the stream
        [        ]               For each push
         "#"*                     "#" repeated
             n^#_                 n raised to the length of the string

2

Haskell , 32 байта

f b=map$foldr(\_->([1..b]>>))"#"

Попробуйте онлайн! Пример использования: f 3 ["##","#","###","#"]возврат ["#########","###","###########################","###"].

Используйте mapM putStrLn $ f 3 ["##","#","###","#"]для получения более визуально приятного вывода:

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

Просто комментирую здесь, потому что я не могу комментировать пост, который вы удалили ... попробуйте sum[sum[]^sum[],sum[]^sum[]].
Орджан Йохансен

2

05AB1E , 9 байтов

Полосы разделены пробелами, выходной символ такой же, как входной символ.

¬Š#€gm×ðý

Попробуйте онлайн!

¬Š#€gm×ðý   Arguments: n, s
¬           Head, get bar character
 Š          Rearrange stack to get: s, n, bar-character
  #         Split s on spaces
   €g       Map to length
     m      n to that power
      ×     That many bar-characters
       ðý   Join on space
            Implicit output

1

PHP, 69 байт

<?foreach($_GET[1]as$l)echo str_pad("",$_GET[0]**strlen($l),"#")."
";

Попробуйте онлайн!


Возвращается с новой строкой, которая не разрешена регулярным выражением. Вы можете использовать [str_pad]."\n"вместо того, "\n".[str_pad]чтобы исправить это (+1 байт). Кроме того, вы можете предположить, что такое заполнитель, поэтому вы можете сохранить два байта $l[0], изменив его на "#".
fireflame241

@ fireflame241 Готово Спасибо
Йорг Хюльсерманн

1

Желе , 7 байт

ṁL*@¥¥€

Монадическая ссылка, берущая и возвращающая списки баров (сами списки символов, строки АКА), символ-заполнитель является гибким.

Попробуйте онлайн! (нижний колонтитул преобразует результирующий список, объединяя его элементы с символами новой строки)

Как?

ṁL*@¥¥€ - Main link: list of list of characters, bars; number, base
     ¥€ - last two links as a dyad for €ach bar in bars:
    ¥   -   last two links as a dyad:
 L      -     length (of a bar)
  *@    -     exponentiate (swap @rguments) (base ^ length)
ṁ       -   mould like (e.g. moulding "##" like 8 yields "########")

Альтернативный 7-байтовый: ṁ"L€*@¥- получить длину каждого столбца ( L€), поднять baseдо этой степени ( *@), затем сжать ( ") список и применить к нему матрицу плесени ( ).


4 квика и 3 актуальные ссылки? Эта задача довольно сложна для управления потоком данных ...
ETHproductions

Да, возможно, существует более короткое решение ...
Джонатан Аллан

@JonathanAllan Боюсь, что нет.
Эрик Outgolfer

@ETHproductions На самом деле это одна ссылка в целом. Объяснение могло быть в значительной степени одной строкой.
Эрик Outgolfer

1

Рубин , 29 байт

->x,y{x.map{|z|?#*y**z.size}}

Попробуйте онлайн!

Да, я узнал на прошлой неделе, что ?#получается односимвольная строка. Я понятия не имею, почему эта функция существует, но я уверена, что она есть.


1
?XОператор, где Xесть какой- то символ, является «получить представление по умолчанию этого символа» оператор. В Ruby <1.9 он возвращает кодовую точку Unicode символа, потому что именно так символы были определены, но теперь он возвращает строку, содержащую символ. Это часть общего перехода к более последовательной обработке Unicode в Ruby.
Tutleman

@Turtleman, есть ли истерический изюм для чего ?Xиспользуется? Многие причудливые соглашения Ruby, такие как множество $переменных, существуют из-за знакомства с Perl.
ymbirtt

1

JavaScript (ES8), 39 байт

Принимает основание как целое число, а граф - как массив строк с любым символом в качестве заполнителя, используя синтаксис каррирования.

b=>a=>a.map(x=>x.padEnd(b**x.length,x))

Попытайся

f=
b=>a=>a.map(x=>x.padEnd(b**x.length,x))
oninput=_=>o.innerText=f(i.value)(j.value.split`\n`).join`\n`
o.innerText=f(i.value=2)((j.value=`####\n##\n######\n###`).split`\n`).join`\n`
*{box-sizing:border-box}#i,#j{margin:0 0 5px;width:200px}#j{display:block;height:100px
<input id=i type=number><textarea id=j></textarea><pre id=o>


Альтернатива, 49 байтов

Эта версия принимает график в виде строки, разделенной новой строкой, снова с любым символом в качестве заполнителя.

b=>s=>s.replace(/.+/g,m=>m.padEnd(b**m.length,m))

Не думайте, что вам нужен mфлаг в регулярном выражении, по умолчанию .он не соответствует переводу строки.
ETHproductions

Хм, не знаю, откуда это взялось - опасность пытаться играть в гольф с телефона. Спасибо за указание, @ETHproductions.
Лохматый

0

Mathematica, 86 байт

(s=#2^StringLength[StringSplit@#1];StringJoin/@Table[Table["#",s[[i]]],{i,Length@s}])&

вход

["#### \ n ## \ n ###### \ n ###", 2]


хорошо ... Исправлено ......
J42161217

0

Октава, 42 байта

@(b,s)[(1:max(k=b.^sum(s'>32)')<=k)+32 '']

* Строка ввода / вывода не полностью соответствует регулярному выражению, но можно понять, какая строка является какой.

Функция принимает в качестве входной базы bи двумерный массив символов, sсодержащий "!"выходные данные, а также массив символов.

Попробуйте онлайн!

Объяснение:

                       s'>32               % logical array of input represents 1 for filler and 0 for spaces
                   sum(     )'             % an array containing length of each string 
              k=b.^                        % exponentiate ( lengths of output)
        1:max(                )            % range form 1 to max of output lengths
                               <=k         % logical array of output represents 1 for filler and 0 for spaces
      [(                          )+32 ''] % convert the logical array to char array.

0

CJam, 20 байтов

q~:A;N/{,A\#"#"e*N}%

Формат ввода

Ввод требуется в следующем формате:

"##
####
######"2


0

V , 27 байтов

Основная идея состоит в том, что мы добавляем a 'к каждой строке (n ^ 0), а затем для каждой #мы заменяем 's в строке на [input] * '. В конце я поменял все 'на #снова

Àé'ld0ÎA'
ò/#
"_xÓ'/"òÍ'/#

Попробуйте онлайн!



0

05AB1E , 10 байтов

U|v1Xygm×,

Символ файла - 1это разделитель, а новая строка.

Попробуйте онлайн!

U          # Store the base in X
 |         # Get the rest of input as a list of lines
  v        # For each...
   1       #   Push 1
    X      #   Push the base
     y     #   Push this bar
      g    #   Get the length
       m   #   Push a**b
        ×, #   Print a string of #s with that length

0

Сетчатка , 62 байта

ms`^(?=.*¶(.*))
#;$1$*#;
{`#(?=#*;(#+);#)
$1
}m`#$

;#+;|¶.*$

Попробуйте онлайн! Ведь гистограмма - это просто список унарных чисел. Принимает входные данные в виде графика (используя #s), за которым следует основание в десятичном формате (чтобы избежать путаницы). Объяснение: Первые префиксы замены 1 и основание каждой строки графика. Вторая замена затем умножает первое число в каждой строке на вторую, пока третье число не равно нулю. Третья замена затем уменьшает третье число в каждой строке. Эти две замены повторяются до тех пор, пока третье число не станет равным нулю. Последняя замена удаляет базу везде, оставляя желаемый результат.



0

Алиса , 23 байта

/'/dI
\I!wO&K/h.n$@?~E&

Попробуйте онлайн!

Мало того, что я не лодырь, но я настолько полон решимости сделать точку правильно, что я использую ! в качестве наполнителя. Это, безусловно, привлечет внимание читателя.

объяснение

Зеркала сохранены в этом объяснении, чтобы сделать его более понятным, когда программа переключается между кардинальным и порядковым режимами.

/I/!/wI&/h.n$@?~E&\'!dOK

/I                        % input base
  /!/                     % store onto tape as integer
     w                    % push return address
      I                   % input next line
       &/h                % get length (by adding 1 for each character in the string)
          .n$@            % terminate if zero
              ?~E         % get base from tape and raise to power
                 &\'!     % push "!" onto the stack that many times
                     d    % combine into a single string
                      O   % output string with newline
                       K  % return to stored address (without popping it from the return address stack)

0

Perl 6 , 26 байт

{map '#'x$^b** *.comb,@^a}

Список входных строк находится в первом параметре @^a. Второй параметр $^b- это база. Список выходных строк возвращается.

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.