Timbangan Log adalah untuk Quitters

24

Semua orang tahu skala log adalah untuk orang yang menyerah . Oleh karena itu, Anda harus menulis sebuah program atau fungsi yang mengurangkan grafik batang dengan skala log yang diberikan basis.

Input grafik batang diambil sebagai string tunggal yang merupakan daftar bar, di mana setiap batang grafik batang skala log dipisahkan oleh pembatas yang dapat dicetak (atau spasi putih) yang Anda pilih (jadi 0x09-0x0A + 0x20-0x7E) dan terdiri dari karakter pengisi non-spasi putih (jadi 0x21-0x7E) yang Anda pilih.

Program atau fungsi menghasilkan string tunggal yang merupakan daftar bilah, di mana setiap bilah dipisahkan oleh pembatas yang sama dengan input yang dipisahkan oleh dan terdiri dari karakter pengisi yang sama dengan input yang dibuat.

Contoh

Kami memilih pembatas "\ n" (satu baris baru) dan karakter pengisi "#". Input yang diteruskan ke program atau fungsi kami adalah:

base = 2 dan string =

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

Kode akan menemukan bahwa panjang bar adalah [4,2,6,3]. Ini akan menghitung anti-log dari setiap panjang dengan basis 2untuk mendapatkan [2^4,2^2,2^6,2^3]= [16,4,64,8]. Kemudian, panjangnya adalah output dalam format bar skala linier:

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

Input output

Program atau fungsi Anda dapat input dan output dalam format yang masuk akal .

Basis input dijamin bilangan bulat lebih besar dari 1. Anda dapat mengasumsikan basis kurang dari 256. Input string dijamin sepenuhnya cocok dengan regex (f+s)+f+, di mana fdan sdiganti dengan filler dan pembatas Anda masing-masing.

Output string harus sepenuhnya cocok dengan regex (f+s)+f+, di mana fdan sdiganti masing-masing dengan filler dan pembatas yang sama. Output secara opsional dapat memiliki baris tambahan.

Output dan input juga dapat berupa daftar string alih-alih dibatasi oleh substring, meskipun harus mungkin untuk memahami bilah mana.

Testcases

(anggap pengisi adalah #dan pembatas adalah \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
-
#
#
##
##
#
##
#
#
#
#
##
##
#
#
##
#
-
##
##
####
####
##
####
##
##
##
##
####
####
##
##
####
##
fireflame241
sumber

Jawaban:

6

fungsi kode mesin x86 32-bit, 21 byte

fungsi kode mesin x86-64, 22 byte

Penghematan 1B dalam mode 32-bit membutuhkan penggunaan separator = filler-1, mis fill=0dan sep=/. Versi 22-byte dapat menggunakan pilihan separator dan filler yang sewenang-wenang.


Ini adalah versi 21-byte, dengan input-separator = \n(0xa), output-filler = 0, output-separator = /= filler-1. Konstanta ini dapat dengan mudah diubah.

; 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

Versi 64-bit lebih panjang 1 byte, menggunakan DEC 2-byte atau a mov al, output_separator. Selain itu, kode mesin sama untuk kedua versi, tetapi beberapa nama register berubah (misalnya rcxalih-alih ecxdalam pop).

Sampel keluaran dari menjalankan program pengujian (basis 3):

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

Algoritma :

Ulangi input, lakukan exp *= baseuntuk setiap pengisi char. Pada pembatas dan terminasi nol byte, tambahkan expbyte filler dan kemudian pemisah ke string output dan reset ke exp=1. Sangat nyaman bahwa input dijamin tidak berakhir dengan baris baru dan terminator.

Pada input, nilai byte apa pun di atas separator (perbandingan tidak bertanda) diperlakukan sebagai pengisi, dan nilai byte apa pun di bawah separator diperlakukan sebagai penanda akhir string. (Memeriksa secara eksplisit untuk nol-byte akan mengambil tambahan test al,alvs bercabang pada bendera yang ditetapkan oleh loop dalam).


Aturan hanya memungkinkan pemisah trailing ketika itu adalah baris tambahan. Implementasi saya selalu menambahkan pemisah. Untuk mendapatkan penghematan 1B dalam mode 32-bit, aturan itu memerlukan separator = 0xa ( '\n'ASCII LF = linefeed), filler = 0xb ( '\v'ASCII VT = tab vertikal). Itu tidak ramah terhadap manusia, tetapi memenuhi surat hukum. (Anda dapat hexdump atau
tr $'\v' xoutput untuk memverifikasi bahwa itu berfungsi, atau mengubah konstanta sehingga pemisah dan pengisi keluaran dapat dicetak. Saya juga memperhatikan bahwa aturan tampaknya mengharuskan dapat menerima input dengan isi yang sama / sep digunakan untuk output , tapi saya tidak melihat keuntungan apa pun dari melanggar aturan itu.).


Sumber NASM / YASM. Bangun sebagai kode 32 atau 64-bit, menggunakan %ifhal - hal yang termasuk dalam program pengujian atau ubah saja rcx ke 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

Fungsi mengikuti System86 ABI x86-64, dengan tanda tangan. Fungsi
void str_exp(char *out /*rdi*/, const char *src /*rsi*/, unsigned base /*edx*/);

ini hanya memberi tahu penelepon tentang panjang string keluaran dengan meninggalkan penunjuk satu-melewati-akhir ke dalamnya rdi, sehingga Anda dapat mempertimbangkan ini sebagai nilai pengembalian dalam Konvensi panggilan standar.

Biayanya 1 atau 2 byte ( xchg eax,edi) untuk mengembalikan penunjuk akhir dalam eax atau rax. (Jika menggunakan ABI x32, pointer dijamin hanya 32 bit, kalau tidak kita harus menggunakan xchg rax,rdijika penelepon melewati pointer ke buffer di luar bit 32 rendah.) Saya tidak memasukkan ini dalam versi saya memposting karena ada solusi yang dapat digunakan pemanggil tanpa mendapatkan nilai dari rdi, jadi Anda dapat memanggilnya dari C tanpa bungkus.

Kami bahkan tidak menghentikan null string output atau apa pun, jadi itu hanya diakhiri baris baru. Butuh 2 byte untuk memperbaikinya: xchg eax,ecx / stosb (rcx nol dari rep stosb.)

Cara untuk mengetahui panjang string output adalah:

  • rdi menunjuk ke one-past-the-end dari string on return (sehingga penelepon dapat melakukan len = end-start)
  • penelepon hanya bisa tahu berapa banyak baris dalam input dan menghitung baris baru
  • penelepon dapat menggunakan buffer zeroed besar dan strlen()sesudahnya.

Mereka tidak cantik atau efisien (kecuali untuk menggunakan nilai pengembalian RDI dari pemanggil asm), tetapi jika Anda menginginkannya, jangan panggil fungsi asm golf dari C.: P


Batasan ukuran / rentang

Ukuran string output maksimal hanya dibatasi oleh batasan ruang alamat memori virtual. (Terutama perangkat keras x86-64 saat ini hanya mendukung 48 bit signifikan dalam alamat virtual, terbelah dua karena mereka menandatangani-perluasan alih-alih-nol. Lihat diagram dalam jawaban yang ditautkan .)

Setiap baris hanya dapat memiliki maksimum 2 ** 32 - 1 byte filler, karena saya mengumpulkan eksponensial dalam register 32-bit.

Fungsi ini berfungsi dengan benar untuk basis dari 0 hingga 2 ** 32 - 1. (Benar untuk basis 0 adalah 0 ^ x = 0, yaitu hanya baris kosong tanpa byte filler. Yang benar untuk basis 1 adalah 1 ^ x = 1, jadi selalu 1 pengisi per baris.)

Ini juga sangat cepat pada Intel IvyBridge dan kemudian, terutama untuk baris besar yang ditulis untuk menyelaraskan memori. rep stosbadalah implementasi optimal memset()untuk jumlah besar dengan pointer sejajar pada CPU dengan fitur ERMSB . misal 180 ** 4 adalah 0.97GB, dan membutuhkan 0,27 detik pada Skylake i7-6700k saya (dengan ~ 256k kesalahan halaman lunak) untuk menulis ke / dev / null. (Di Linux driver perangkat untuk / dev / null tidak menyalin data di mana pun, itu hanya kembali. Jadi semua waktu berada di rep stosbdan kesalahan halaman lunak yang dipicu saat menyentuh memori untuk pertama kalinya. Ini sayangnya tidak menggunakan hugepage transparan untuk array di BSS. Mungkin madvise()panggilan sistem akan mempercepatnya.)

Program uji :

Bangun biner statis dan jalankan sebagai ./string-exponential $'#\n##\n###' $(seq 2)basis 2. Untuk menghindari penerapannya atoi, ia menggunakan base = argc-2. (Batas panjang baris perintah mencegah pengujian basis yang sangat besar.)

Pembungkus ini berfungsi untuk string keluaran hingga 1 GB. (Ini hanya membuat panggilan tunggal () system call bahkan untuk string raksasa, tetapi Linux mendukung ini bahkan untuk menulis ke pipa). Untuk menghitung karakter, masukkan wc -catau gunakan strace ./foo ... > /dev/nulluntuk melihat arg ke syscall write.

Ini mengambil keuntungan dari nilai pengembalian RDI untuk menghitung panjang string sebagai argumen untuk 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.

Ini adalah tantangan yang menyenangkan yang meminjamkan dirinya dengan sangat baik untuk asm, terutama x86 string ops . Aturan dirancang dengan baik untuk menghindari keharusan menangani baris baru dan kemudian terminator di akhir string input.

Eksponensial dengan perkalian berulang sama seperti mengalikan dengan penambahan berulang, dan saya perlu mengulang untuk menghitung karakter di setiap baris input.

Saya mempertimbangkan untuk menggunakan satu operan mulatau imullebih lama imul r,r, tetapi penggunaan EAX secara implisit akan bertentangan dengan LODSB.


Saya juga mencoba SCASB daripada memuat dan membandingkan , tetapi saya perlu xchg esi,edisebelum dan sesudah loop dalam, karena SCASB dan STOSB keduanya menggunakan EDI. (Jadi versi 64-bit harus menggunakan ABI x32 untuk menghindari pemotongan pointer 64-bit).

Menghindari STOSB bukanlah suatu pilihan; tidak ada yang sedekat ini. Dan setengah keuntungan menggunakan SCASB adalah AL = filler setelah meninggalkan loop dalam, jadi kita tidak memerlukan pengaturan untuk REP STOSB.

SCASB membandingkan ke arah lain dari apa yang telah saya lakukan, jadi saya perlu membalikkan perbandingan.

Upaya terbaik saya dengan xchg dan scasb. Bekerja, tetapi tidak lebih pendek. ( Kode 32-bit, menggunakaninc / dectrik untuk mengubah filler menjadi separator ).

; 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    

Untuk input ../.../., hasilkan ..../......../../. Saya tidak akan repot menunjukkan hexdump versi dengan separator = newline.

Peter Cordes
sumber
4

Mathematica 41 38 Bytes

-3 Bytes terima kasih kepada LLlAMnYP

Ini mengambil input sebagai daftar string diikuti oleh integer. Output juga merupakan daftar string.

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

Penjelasan:

                   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

Versi lama, 41 Bytes

"#"~StringRepeat~#&/@(#2^StringLength@#)&
Ian Miller
sumber
"" <> "#"~Table~#adalah 3 byte lebih pendek dari "#"~StringRepeat~#, mungkin golf juga lebih jauh.
LLlAMnYP
3

Japt , 7 byte

Mengambil grafik sebagai array string dengan "sebagai filler, dan basis sebagai integer.

£QpVpXl

Cobalah online

Tambahkan }Rke akhir untuk mengambil grafik sebagai string yang dipisahkan baris baru. ( Cobalah )


Penjelasan

    :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.
Shaggy
sumber
3

MATL , 14 11 byte

Y'iw^1HL(Y"

Pembatas adalah ruang. Filler adalah karakter apa pun selain ruang.

Cobalah online!

Penjelasan

       % 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
Luis Mendo
sumber
Ini sepertinya tidak berhasil; panjang setiap baris dalam output untuk kasus uji yang Anda masukkan dalam TIO Anda harus 9,3,27,9 tetapi sebaliknya 6,3,9,3.
Shaggy
@ Shaggy Anda benar sekali. Terima kasih telah memperhatikan. Saya membuat kesalahan dalam edit terbaru saya. Saya telah memutar kembali ke versi sebelumnya, ehich benar
Luis Mendo
Tidak dapat mengetahui cara kerjanya dari penjelasan - lalu saya mengklik TIO! : D
Shaggy
1
@ Shaggy Saya baru saja menambahkan penjelasan untuk versi ini, semoga lebih jelas!
Luis Mendo
3

Haskell , 37 33 byte

4 byte dicukur berkat sudee

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

Deskripsi:

\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

Yang mengecewakan, ini 2 byte lebih pendek dari versi pointfree cara-sulit dibaca:

map.(flip replicate '#'.).(.length).(^)
Julian Wolf
sumber
Input harus berupa string tunggal
bartavelle
@artavelle, belum tentu.
Shaggy
Itulah yang saya mengerti dengan Masukan grafik batang diambil sebagai string tunggal ...
bartavelle
1
@bartavelle: Output dan input juga dapat berupa daftar string bukannya dibatasi oleh substring, meskipun harus mungkin untuk memahami bilah mana yang mana.
Julian Wolf
2
Anda bisa menggantinya replicate(b^length x)'#'dengan '#'<$[1..b^length x].
sudee
3

ReRegex , 105 byte

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

Cobalah online!

ReRegex seperti sepupu jelek Retina yang memberikan semua upaya untuk Ekspresi Reguler, daripada memiliki operator mewahnya sendiri.

Tentu saja, ia juga memiliki #importdan #inputmenyimpan input hardcoding, dan menulis ulang ekspresi yang sama berulang-ulang.

Dijelaskan.

Mengambil input dalam bentuk:

2
____
__
______
___

pada STDIN, dan memberikan output seperti

________________
____
________________________________________________________________
________

Pertama, program ini mengimpor Perpustakaan Matematika , yang tentu saja sepenuhnya ditulis dalam ReRegex. Bagian terbesar dari ini adalah tiga ekspresi reguler.

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

Yang pertama cocok dengan basis input kami, dan mencari garis unary setelahnya. kemudian, ganti baris itu dengan;$1^d<$4> , yang merupakan dasar, dengan kekuatan Unimal (Dalam Desimal). Perpustakaan Math menangani konversi basis dan eksponen. SEBUAH ; ditempatkan di awal untuk mengidentifikasi nanti setelah selesai.

Yang kedua, cocok dengan basis, lalu banyak baris;, sebelum berakhir. Jika ini cocok dengan semuanya, ia akan terlepas dari pangkalan. meninggalkan uf hanya dengan jawaban dan ;s.

Yang terakhir, cocok hanya unary di awal, secara opsional, lalu ;jawaban. Kemudian mengubah jawaban itu menjadi unary lagi, tanpa ;.

Karena output tidak cocok dengan regex pertama, itu tidak berulang, jadi solusi kami dikeluarkan.

ATaco
sumber
2

Python 2 , 52 36 byte

Input dan output diambil sebagai array string. #adalah pengisi.

lambda s,n:['#'*n**len(l)for l in s]

Cobalah online!

benar-benar manusiawi
sumber
2

Röda , 19 byte

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

Cobalah online!

Mengambil array sebagai input dan mengembalikan aliran nilai sebagai output.

Penjelasan

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
Kritixi Lithos
sumber
2

Haskell , 32 byte

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

Cobalah online! Contoh penggunaan: f 3 ["##","#","###","#"]pengembalian ["#########","###","###########################","###"].

Gunakan mapM putStrLn $ f 3 ["##","#","###","#"]untuk mendapatkan hasil yang lebih menyenangkan secara visual:

#########
###
###########################
###
Laikoni
sumber
Hanya berkomentar di sini karena saya tidak dapat mengomentari pos yang Anda hapus ... coba sum[sum[]^sum[],sum[]^sum[]].
Ørjan Johansen
2

05AB1E , 9 byte

Bar dipisahkan oleh spasi, karakter output sama dengan karakter input.

¬Š#€gm×ðý

Cobalah online!

¬Š#€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
kalsowerus
sumber
1

PHP, 69 Bytes

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

Cobalah online!

Jörg Hülsermann
sumber
Ini kembali dengan baris baru terkemuka, yang tidak diizinkan oleh regex. Anda dapat menggunakan [str_pad]."\n"alih-alih "\n".[str_pad]memperbaiki ini (+1 byte). Selain itu, Anda dapat mengasumsikan pengisi apa, sehingga Anda dapat menyimpan dua byte $l[0]dengan mengubahnya "#".
fireflame241
@ fireflame241 Selesai Terima Kasih
Jörg Hülsermann
1

Jelly , 7 byte

ṁL*@¥¥€

Tautan monadik yang mengambil dan mengembalikan daftar bilah (daftar karakter itu sendiri, string AKA) karakter pengisi fleksibel.

Cobalah online!(footer menyiapkan daftar hasil dengan menggabungkan elemen-elemennya dengan baris baru.)

Bagaimana?

ṁ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 "########")

Alternatif 7-byter: ṁ"L€*@¥- dapatkan panjang masing-masing bar ( L€), naikkan baseke kekuatan itu ( *@), lalu zip ( ") daftar dan yang menerapkan angka dua cetakan ( ) di antara keduanya.

Jonathan Allan
sumber
4 quicks dan 3 tautan aktual? Tantangan ini cukup berat untuk mengendalikan aliran data ...
ETHproduksi
Ya, mungkin ada solusi lebih pendek yang tersedia ...
Jonathan Allan
@ Jonathan Allan Saya khawatir tidak ada.
Erik the Outgolfer
@ ETHproductions Ini sebenarnya satu tautan secara keseluruhan. Penjelasannya bisa jadi hanya satu baris.
Erik the Outgolfer
1

Ruby , 29 byte

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

Cobalah online!

Ya, saya menemukan minggu lalu yang ?#menghasilkan string karakter tunggal. Saya tidak tahu mengapa fitur ini ada, tapi saya senang itu.

ymbirtt
sumber
1
The ?Xoperator, di mana Xbeberapa karakter, adalah "mendapatkan representasi default karakter ini" operator. Di Ruby <1.9, itu akan mengembalikan titik kode Unicode karakter, karena itulah cara karakter didefinisikan, tetapi sekarang mengembalikan string yang berisi karakter. Ini adalah bagian dari perubahan umum menuju penanganan Unicode yang lebih konsisten di Ruby.
Tutleman
@Turtleman, apakah ada kismis histeris mengapa ?Xdigunakan? Banyak konvensi Ruby yang unik, seperti kebanyakan $-variables, ada karena keakraban dengan Perl.
ymbirtt
1

JavaScript (ES8), 39 byte

Mengambil basis sebagai integer dan grafik sebagai array string dengan karakter apa pun sebagai pengisi, menggunakan sintaks currying.

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

Cobalah

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>


Alternatif, 49 byte

Versi ini mengambil grafik sebagai string yang dipisahkan baris baru, lagi dengan karakter apa pun sebagai pengisi.

b=>s=>s.replace(/.+/g,m=>m.padEnd(b**m.length,m))
Shaggy
sumber
Jangan berpikir Anda memerlukan mbendera di regex, secara default .tidak cocok dengan baris baru.
ETHproduksi
Hmm, tidak tahu dari mana datangnya - bahaya mencoba bermain golf dari telepon. Terima kasih telah menunjukkannya, @ETHproductions.
Shaggy
0

Mathematica, 86 byte

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

memasukkan

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

J42161217
sumber
ok ... Tetap ......
J42161217
0

Oktaf, 42 byte

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

* String input / output tidak sepenuhnya cocok dengan regex tetapi dimungkinkan untuk memahami bilah mana yang mana.

Fungsi diambil sebagai basis input bdan array 2D yang sberisi karakter"!" dan output juga merupakan array karakter.

Cobalah online!

Penjelasan:

                       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.
rahnema1
sumber
0

CJam, 20 byte

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

Masukkan format

Input diperlukan dalam format berikut:

"##
####
######"2
Roman Gräf
sumber
0

Arang , 11 byte

NβWS«PXβLι↓

Cobalah online! Tautan adalah untuk mengucapkan versi kode. I / O adalah sebagai daftar string -karakter (perhatikan bahwa Anda memerlukan baris kosong untuk mengakhiri daftar).

Neil
sumber
0

V , 27 byte

Ide dasarnya adalah bahwa kita menambahkan a 'ke setiap baris (n ^ 0), dan kemudian untuk masing-masing #kita mengganti 's di baris dengan [input] * '. Pada akhirnya saya bertukar semua 'untuk #lagi

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

Cobalah online!

nmjcman101
sumber
0

R , 35 byte

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

fungsi anonim yang mengambil string sebagai daftar dan basis, dan mengembalikan daftar string.

Cobalah online!

Giuseppe
sumber
0

05AB1E , 10 byte

U|v1Xygm×,

Karakter filer adalah 1 dan pembatas adalah baris baru.

Cobalah online!

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
Riley
sumber
0

Retina , 62 byte

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

;#+;|¶.*$

Cobalah online! Bagaimanapun, grafik batang hanyalah daftar angka-angka yang tidak diperhatikan. Mengambil input sebagai grafik (menggunakan #s) diikuti oleh basis dalam desimal (untuk menghindari kebingungan). Penjelasan: Awalan pengganti pertama 1 dan dasar untuk setiap baris grafik. Penggantian kedua kemudian mengalikan angka pertama pada setiap baris dengan yang kedua, selama angka ketiga bukan nol. Penggantian ketiga kemudian menurunkan angka ketiga di setiap baris. Kedua penggantian ini diulangi sampai angka ketiga menjadi nol. Penggantian terakhir menghapus basis di mana-mana, meninggalkan hasil yang diinginkan.

Neil
sumber
0

Alice , 23 byte

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

Cobalah online!

Bukan saja saya bukan orang yang gampang menyerah, tetapi saya juga berkomitmen untuk membuat poin dengan tepat yang saya gunakan ! sebagai pengisi. Itu pasti akan mendapat perhatian pembaca.

Penjelasan

Cermin dipertahankan dalam penjelasan ini untuk membuatnya lebih jelas ketika program beralih antara mode kardinal dan ordinal.

/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)
Nitrodon
sumber
0

Perl 6 , 26 byte

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

Daftar string input ada di parameter pertama @^a,. Parameter kedua $^badalah basis. Daftar string keluaran dikembalikan.

Sean
sumber