对数刻度用于退出


24

每个人都知道对数刻度适合戒烟者。因此,您必须编写一个程序或函数,该程序或函数以给定底数的对数刻度使条形图无效

条形图输入被视为一个单独的字符串,是一个条形列表,对数刻度条形图的每个条形都由您选择的可打印(或空白)定界符分隔(因此0x09-0x0A + 0x20-0x7E),由您选择的可打印的非空白(so 0x21-0x7E)填充字符组成。

程序或函数输出一个单个字符串,该字符串是一个小节列表,其中每个小节由输入所分隔的相同定界符分隔,并由组成输入的相同填充符组成。

我们选择定界符“ \ n”(一个换行符)和填充符“#”。传递给我们的程序或函数的输入是:

base = 2 和string =

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

该代码将发现这些条的长度为[4,2,6,3]。它将以base 2为基础计算每个长度的反对数,以获取[2^4,2^2,2^6,2^3]= [16,4,64,8]。然后,以线性比例尺格式输出长度:

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

输入输出

您的程序或函数可以以任何合理的格式输入和输出。

输入基数保证为大于1的整数。您可以假定基数小于256。保证字符串输入与regex完全匹配(f+s)+f+,其中fs分别用填充符和分隔符替换。

字符串输出必须完全匹配regex (f+s)+f+,其中fs分别用相同的填充符和分隔符替换。输出可以选择包含尾随换行符。

输出和输入也可以是字符串列表,而不是用子字符串定界,尽管必须能够理解哪个条是哪个。

测试用例

(假设填充#符为,分隔符为\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
-
#
#
##
##
#
##
#
#
#
#
##
##
#
#
##
#
-
##
##
####
####
##
####
##
##
##
##
####
####
##
##
####
##

Answers:


6

x86 32位机器码功能,21字节

x86-64机器码功能,22字节

以32位模式保存1B时,需要使用分隔符= filler-1,例如fill=0sep=/。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

使用2字节DEC或a的64位版本要长1字节mov al, output_separator。除此之外,两个版本的机器代码都相同,但是某些寄存器名称发生了变化(例如,rcx而不是ecx中的pop)。

运行测试程序(基于3)的样本输出:

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

算法

循环输入,exp *= base处理每个填充符。在定界符和终止的零字节上,将exp填充符字节附加在后面,然后将分隔符附加到输出字符串,然后重置为exp=1。确保输入不以换行符终止符结尾非常方便。

输入时,分隔符上方的任何字节值(无符号比较)均视为填充符,分隔符下方的任何字节值均视为字符串结尾标记。(显式检查零字节将对test al,al内部循环设置的标志进行额外的分支。)


规则仅在尾随换行符时才允许尾随分隔符。我的实现总是附加分隔符。 要在32位模式下保存1B,该规则要求分隔符= 0xa('\n'ASCII LF =换行符),填充符= 0xb('\v'ASCII VT =垂直制表符)。 那不是很人性化,但是满足法律要求。(您可以进行十六进制转储或
tr $'\v' x输出以验证其是否有效,或更改常数以使输出分隔符和填充符可打印。我还注意到规则似乎要求其接受与用于输出的填充/分隔符相同的输入。 ,但我认为违反该规则不会有任何收获。)


NASM / YASM源。使用%if测试程序附带的内容构建为32位或64位代码,或者仅将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进行调用。

我们甚至不对输出字符串或其他任何内容进行null终止,因此仅以换行符终止。需要花费2个字节来解决:(xchg eax,ecx / stosb rcx从开始为零rep stosb)。

找出输出字符串长度的方法是:

  • rdi指向返回时字符串的最后一位(因此调用方可以执行len = end-start)
  • 调用方可以知道输入中有多少行并计算换行符
  • 调用者可以使用较大的归零缓冲区,strlen()然后再使用。

它们不是很漂亮或效率很高(除了使用来自asm调用者的RDI返回值),但是如果需要,则不要从C调用golfed asm函数。


大小/范围限制

最大输出字符串大小仅受虚拟内存地址空间限制。(主要是当前的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功能的CPU上具有对齐指针的大量计数器的最佳实现。例如180 ** 4为0.97GB,在我的i7-6700k Skylake(带有〜256k个软页面错误)上需要0.27秒的时间写入/ dev / null。(在Linux上,用于/ dev / null的设备驱动程序不会将数据复制到任何地方,它只会返回。因此,所有时间都在rep stosb和中,而软页面错误则是在首次触摸内存时触发的。它是不幸的是,没有对BSS中的阵列使用透明的大页面。可能madvise()系统调用会加快它的速度。)

测试程序

生成一个静态二进制文件并按./string-exponential $'#\n##\n###' $(seq 2)基本2 运行。为避免实现atoi,它使用base = argc-2。(命令行长度限制阻止测试可笑的大基数。)

该包装器适用于最大1 GB的输出字符串。(即使对于巨大的字符串,它也只进行单个write()系统调用,但是Linux甚至为写入管道也支持此调用)。要计算字符,请通过管道wc -c或使用strace ./foo ... > /dev/null来查看写入系统调用的arg。

这利用RDI返回值将字符串长度计算为的arg 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。很好地设计了规则,以避免必须先处理换行符,然后再处理输入字符串末尾的终止符。

具有重复乘法的指数就像具有重复加法的乘法一样,无论如何,我都需要循环以计算每个输入行中的字符数。

我考虑使用单操作数mulimul代替更长的操作数imul r,r,但是其隐式使用EAX会与LODSB冲突。


我还尝试了SCASB而不是load and compare,但是我需要xchg esi,edi在内循环之前和之后,因为SCASB和STOSB都使用EDI。(因此,64位版本必须使用x32 ABI以避免截断64位指针)。

避免使用STOSB并不是一种选择。没有什么比这更短了。使用SCASB的一半好处是在离开内循环之后AL = filler,因此我们不需要为REP STOSB进行任何设置。

SCASB与我一直在做的事情相反,因此我需要颠倒比较。

我最好的尝试与xchg和scasb。可行,但并不短。(32位代码,使用inc/ dec技巧将填充符更改为分隔符)。

; 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    

对于的输入../.../.,产生..../......../../。我不会费心地显示带有eparator = 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'5

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

MATL14 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你完全正确。感谢您的关注。我在最新编辑中犯了一个错误。我已经回滚到以前的版本,ehich是正确的
Luis

从说明中无法弄清楚它是如何工作的-然后我单击了TIO!:D
毛茸茸的

1
@Shaggy我刚刚添加了此版本的解释,希望更清晰!
路易斯·门多

3

哈斯克尔 37 33字节

由于sudee,减少了4个字节

\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,2017年

@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>为(十进制)一元进制的基数(即基数)。数学库处理基本转换和指数。一种 ; 放在开始处,以供日后识别。

第二个,在结束之前匹配基数,然后匹配;的许多行。如果这与整个事物匹配,那么它会切断基础。剩下uf和答案;

最后一个在开始时仅与一元匹配,然后匹配一个;答案。然后,它将答案再次转换为一元,而没有;

因为输出与第一个正则表达式不匹配,所以它不会无限循环,因此输出了我们的解决方案。



2

罗达(Röda),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 ["##","#","###","#"]return ["#########","###","###########################","###"]

使用mapM putStrLn $ f 3 ["##","#","###","#"]以获得更赏心悦目的输出:

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

只在这里发表评论,因为我无法评论您删除的帖子...试试sum[sum[]^sum[],sum[]^sum[]]
与Orjan约翰森

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完成谢谢
约尔格Hülsermann

1

果冻,7 个字节

ṁL*@¥¥€

取和返回条形列表(自身的字符列表,AKA字符串)的单子链接很灵活。

在线尝试!(页脚通过将元素与换行符连接来修饰结果列表。)

怎么样?

ṁ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 '17

是的,可能会有更短的解决方案……
乔纳森·艾伦

@JonathanAllan恐怕没有。
暴民埃里克(Erik the Outgolfer)'17年

@ETHproductions实际上是一个整体链接。解释可能只是一行。
暴民埃里克(Erik the Outgolfer)'17年

1

Ruby,29个字节

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

在线尝试!

是的,我上周发现?#产生了一个单字符字符串。我不知道为什么存在此功能,但是我很高兴它确实存在。


1
?X运算符X是某个字符,是“获取该字符的默认表示形式”运算符。在Ruby <1.9中,它将返回字符的Unicode代码点,因为这是字符的定义方式,但是现在它返回包含字符的字符串。这是向Ruby中更统一的Unicode处理转变的一部分。
图特尔曼(Tutleman)'17年

@Turtleman,为什么有歇斯底里的葡萄干 ?X要使用?$由于熟悉Perl,因此存在许多Ruby的怪异约定,例如-variables过多。
ymbirtt

1

JavaScript(ES8),39个字节

使用currying语法,将基数作为整数,将图形作为字符串数组,其中任何字符作为填充符。

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's

嗯,不知道那是哪里来的-试图通过电话打高尔夫球的危险。感谢您指出@ETHproductions。
毛茸茸的

0

Mathematica,86个字节

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

输入

[“ #### \ n ## \ n ###### \ n ###”,2]


ok ... Fixed ......
J42161217 '51

0

八度,42字节

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

*字符串输入/输出与正则表达式不完全匹配,但是可以理解哪个条是哪个。

一个函数以输入为基础,bs包含一个二维字符数组,"!"输出也是一个字符数组。

在线尝试!

说明:

                       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

木炭,11字节

NβWS«PXβLι↓

在线尝试!链接是详细版本的代码。I / O是一个字符串列表-(请注意,您需要使用空行来终止该列表)。


0

V,27个字节

基本思想是,我们'向每行(n ^ 0)添加一个,然后为每行将#替换为。最后我换所有的再次'[input] * ''#

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

在线尝试!


0

R,35个字节

function(s,b)strrep('#',b^nchar(s))

一个匿名函数,它将字符串作为列表和基础,并返回字符串列表。

在线尝试!


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是基数。返回输出字符串列表。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.