ログスケールは禁煙者向け


24

ログスケールが禁煙者用であることは誰もが知っています。したがって、ベースが指定されたログスケールで棒グラフを非終了にするプログラムまたは関数を作成する必要があります。

バーグラフ入力は、バーのリストである単一の文字列として取得されます。ここで、ログスケールバーグラフの各バーは、選択可能な印刷可能(または空白)区切り文字(0x09-0x0A + 0x20-0x7E)で区切られます。選択可能な印刷可能な非空白(0x21-0x7E)フィラー文字で構成されます。

プログラムまたは関数は、バーのリストである単一の文字列を出力します。各バーは、入力と同じ区切り文字で区切られ、入力と同じフィラー文字で構成されます。

「\ n」(1つの改行)の区切り文字と「#」のフィラー文字を選択します。プログラムまたは関数に渡される入力は次のとおりです。

base = 2 およびstring =

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

コードでは、バーの長さがであることがわかります[4,2,6,3]2get [2^4,2^2,2^6,2^3]= を底とする各長さの対数を計算します[16,4,64,8]。次に、長さが線形スケールバー形式で出力されます。

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

入出力

プログラムまたは関数は、適切な形式で入出力できます

入力されたベースは、あなたがベースが完全に正規表現と一致する文字列の入力が保証されて256未満であると仮定することができる1以上の整数大きいことが保証され(f+s)+f+、ここで、fおよびsはそれぞれ自分の充填剤および区切り文字で置き換えられます。

文字列出力はregex (f+s)+f+と完全に一致する必要がfありsます。ここでおよびは、それぞれ同じフィラーとデリミタで置き換えられます。出力には、オプションで末尾の改行が含まれる場合があります。

出力と入力は、部分文字列で区切られるのではなく、文字列のリストにもなりますが、どのバーがどのバーであるかを理解できる必要があります。

テストケース

(フィラーが#、デリミタがであると仮定します\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

x86 32ビットマシンコード関数、21バイト

x86-64マシンコード関数、22バイト

32ビットモードで1Bを保存するには、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またはを使用し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 =垂直タブ)が必要です。 それはあまり人間に優しいものではありませんが、法律の文字を満たします。(hexdumpまたは
tr $'\v' x出力を使用して、動作を確認するか、出力セパレーターとフィラーが印刷可能になるように定数を変更できます。また、ルールは、出力に使用するのと同じfill / sepで入力を受け入れる必要があるように見えます) 、しかし、私はその規則を破ることから得られるものは見当たらない。)


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,edieaxまたはraxでエンドポインターを返すには、1または2バイト()かかります。(x32 ABIを使用している場合、ポインターは32ビットのみであることが保証されています。そうでないxchg rax,rdi場合、呼び出し側が下位32ビット以外のバッファーにポインターを渡す場合に使用する必要があります。)私はこれをバージョンに含めませんでしたこれは、呼び出し元がから値を取得せずに使用できる回避策があるため、rdiラッパーなしでCから呼び出すことができるためです。

出力文字列などをnullで終了することもしないので、改行のみで終了します。それを修正するには2バイトかかりますxchg eax,ecx / stosb (rcxは0からrep stosbです)。

出力文字列の長さを調べる方法は次のとおりです。

  • rdiは、戻り時に文字列の末尾の1つを指します(したがって、呼び出し元はlen = end-startを実行できます)
  • 呼び出し側は、入力に含まれる行数を知ることができ、改行をカウントできます。
  • 呼び出し元は大きなゼロバッファーを使用でき、strlen()その後も使用できます。

それらはきれいでも効率的でもありません(asm呼び出し元からRDI戻り値を使用する場合を除く)が、それが必要な場合は、Cからゴルフasm関数を呼び出さないでください。


サイズ/範囲の制限

最大出力文字列サイズは、仮想メモリのアドレス空間の制限によってのみ制限されます。(主に現在のx86-64ハードウェアは仮想アドレスで48ビットのみをサポートし、ゼロ拡張ではなく符号拡張のため半分分割されますリンクされた回答の図を参照してください。)

32ビットのレジスタに指数を蓄積するため、各行には最大2 ** 32-1フィラーバイトしか含めることができません。

この関数は、0〜2 ** 32-1の基数に対して正しく機能します(基数0の修正は0 ^ x = 0、つまり、フィラーバイトのない空白行です。基数1の修正は1 ^ x = 1なので、常に1行に1つのフィラー。)

Intel IvyBridge以降では、特にアラインされたメモリに書き込まれる大きな行の場合、非常に高速です。 ERMSB機能を備えたCPU上に位置合わせされたポインターを持つ大数rep stosbmemset()ための最適な実装です。たとえば、180 ** 4は0.97GBで、i7-6700k Skylake(〜256kのソフトページフォールト)で/ dev / nullに書き込むには0.27秒かかります。(Linuxでは、/ dev / nullのデバイスドライバーはデータをどこにもコピーせず、単に戻ります。そのため、すべての時間はrep stosb、メモリに初めて触れるときにトリガーされるソフトページフォールトにあります。残念ながら、BSSの配列に透過的なhugepagesを使用していません。おそらく、madvise()システムコールがそれを高速化するでしょう。

テストプログラム

静的バイナリをビルドし、./string-exponential $'#\n##\n###' $(seq 2)ベース2の場合と同じように実行atoiしますbase = argc-2。(コマンドラインの長さの制限により、途方もなく大きなベースのテストができなくなります。)

このラッパーは、最大1 GBの出力文字列に対して機能します。(巨大な文字列に対しても単一のwrite()システムコールのみを行いますが、Linuxはパイプへの書き込みに対してもこれをサポートしています)。文字をカウントwc -cするstrace ./foo ... > /dev/nullには、パイプを使用するか、書き込みsyscallの引数を確認するために使用します。

これは、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に非常に適した楽しい挑戦でした。ルールは、入力文字列の最後で改行とターミネータを処理する必要がないようにうまく設計されています。

繰り返される乗算を伴う指数関数は、繰り返される加算を伴う乗算に似ています。とにかく各入力行の文字をカウントするためにループする必要がありました。

私が使用して考えられて1をオペランドmulまたはimul代わりに長いのimul r,rが、EAXの暗黙的な使用はLODSBと競合します。


loadとcompareの代わりにSCASBも試しましたがxchg esi,edi、SCASBとSTOSBの両方がEDIを使用するため、内部ループの前後に必要でした。(したがって、64ビットバージョンでは、64ビットポインターの切り捨てを回避するためにx32 ABIを使用する必要があります)。

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    

の入力に対して../.../.、を生成し..../......../../ます。separator = newlineを使用したバージョンの16進ダンプを表示することはありません。


4

Mathematica 41 38バイト

LLlAMnYPのおかげで-3バイト

これは、整数が続く文字列のリストとして入力を受け取ります。出力も文字列のリストです。

""<>"#"~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~#"#"~StringRepeat~#、よりも3バイト短く、おそらくさらにゴルフ可能です。
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

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は正しいです
ルイスメンドー

説明からそれがどのように機能していたのか理解できませんでした-それから私はクリックしてTIOに行きました!:D
シャギー

1
@Shaggyこのバージョンの説明を追加しました。
ルイスメンドー

3

Haskell37 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

@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で、次のような出力を提供します

________________
____
________________________________________________________________
________

まず、プログラムは数学ライブラリをインポートします。これは、もちろん完全にReRegexで書かれています。その大部分は3つの正規表現です。

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

最初は入力ベースに一致し、その後に単項の行を探します。次に、その行を;$1^d<$4>基数である(10進数の)単項の累乗で置き換えます。数学ライブラリは、基本変換と指数を処理します。A; 開始時に配置され、後で終了と識別されます。

2番目は、ベースに一致し、次に;の多くの行が終了前に一致します。これが全体と一致する場合、ベースから切り取られます。ufに答えと;s だけを残します。

最後は、開始時に単項式に一致し、オプションで;回答に一致します。次に、その答えを単項式に変換します;

出力は最初の正規表現と一致しないため、無限にループしないため、ソリューションが出力されます。



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[]]
Ørjanヨハンセン

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]変更することで2バイトを節約できます"#"
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し、その累乗(*@)に上げてから"、リストと2つの間に金型ダイアッド()を適用します。


4つのクイックと3つの実際のリンク?この課題は、データの流れを制御する上で非常に重いです
...-ETHproductions

うん、可能な短いソリューション...があるかもしれない
ジョナサン・アラン

@JonathanAllanいないのではないかと心配です。
エリックアウトゴルファー

@ETHproductions実際には、全体として1つのリンクです。説明はほとんど1行でした。
エリックアウトゴルファー

1

ルビー、29バイト

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

オンラインでお試しください!

ええ、私は先週?#、1文字の文字列を生成することを発見しました。この機能が存在する理由はわかりませんが、存在することを嬉しく思います。


1
?Xオペレータ、Xいくつかの文字ですが、「この文字のデフォルトの表現を取得」オペレータです。Ruby <1.9では、文字のUnicodeコードポイントを返します。これは文字の定義方法であるためですが、現在は文字を含む文字列を返します。これは、Rubyでのより一貫したUnicode処理への一般的な移行の一部です。
タトルマン

@タートルマン、なぜ?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]


OK ...修正
済み...-J42161217

0

オクターブ、42バイト

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

*文字列の入出力は正規表現と完全には一致しませんが、どのバーがどのバーであるかを理解することは可能です。

関数は、入力ベースとしてb、次sを含む文字の2D配列を受け取ります"!"、出力も文字の配列です。

オンラインでお試しください!

説明:

                       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

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 を使用して)、10進数の基が続きます(混乱を避けるため)。説明:最初の置換は、グラフの各行の1とベースをプレフィックスします。2番目の置換は、3番目の数値がゼロでない限り、各行の最初の数値に2番目の数値を乗算します。3番目の置換は、各行の3番目の数値をデクリメントします。これらの2つの置換は、3番目の数値がゼロになるまで繰り返されます。最後の置換では、すべてのベースが削除され、目的の結果が残ります。



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ます。2番目のパラメーター$^bはベースです。出力文字列のリストが返されます。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.