Günlük Ölçekleri Bırakanlar için


24

Herkes kütük skalalarının bırakanlar için olduğunu bilir . Bu nedenle, bir taban grafiği verilen bir günlük çizelgesine sahip bir çubuk grafiğini kaldıran bir program veya işlev yazmalısınız .

Çubuk grafik girişi, günlük ölçeği çubuk grafiğinin her çubuğunun seçtiğiniz (yazdırılabilir (veya boşluk)) sınırlayıcı ile ayrıldığı (yani 0x09-0x0A + 0x20-0x7E) ve çubuk listesi olan tek bir dize olarak alınır. seçtiğiniz bir yazdırılabilir beyaz boşluk olmayan (yani 0x21-0x7E) dolgu karakterinden oluşur.

Program veya işlev, her bir çubuğun, giriş tarafından ayrıldığı ve girişin oluşturduğu aynı dolgu karakterinden oluşan, her çubuğun aynı sınırlayıcıyla ayrıldığı, bir çubuk listesi olan tek bir dize verir.

Örnek

"\ N" (bir yeni satır) sınırlayıcı ve "#" dolgu karakterini seçiyoruz. Programımıza veya işleve verilen girdi:

base = 2 ve string =

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

Kod, çubukların uzunluklarının olduğunu bulur [4,2,6,3]. Bu baz ile, her uzunlukta bir anti-log hesaplamak olacaktır 2olsun için [2^4,2^2,2^6,2^3]= [16,4,64,8]. Ardından, uzunluklar doğrusal ölçek çubuğu biçiminde çıkarılır:

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

Giriş çıkış

Programınız veya işleviniz herhangi bir makul formatta giriş ve çıkış yapabilir .

Giriş taban Baz tam regex maç için dize girişi garanti az 256 olduğunu varsayalım olabilir 1'den büyük bir tamsayı olması sağlanır (f+s)+f+, nerede fve ssırasıyla senin dolgu ve sınırlayıcı değiştirilir.

Dize çıktısı (f+s)+f+, sırasıyla aynı dolgu ve sınırlayıcı ile değiştirilen fve syerine regex ile tam olarak uyuşmalıdır . Çıktı isteğe bağlı olarak takip eden bir yeni satıra sahip olabilir.

Çıktı ve girdi aynı zamanda bir alt dizeyle sınırlandırılmak yerine dizelerin bir listesi olabilir, ancak hangi çubuğun hangisi olduğunu anlamak mümkün olmalıdır.

testcases

(doldurucunun #ve sınırlayıcının olduğunu varsayalım \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
-
#
#
##
##
#
##
#
#
#
#
##
##
#
#
##
#
-
##
##
####
####
##
####
##
##
##
##
####
####
##
##
####
##

Yanıtlar:


6

x86 32 bit makine kodu işlevi, 21 bayt

x86-64 makine kodu fonksiyonu, 22 bayt

32-bit modunda tasarrufu 1B, örneğin ayırıcı = dolgu maddesi-1, kullanılmasını gerektirir fill=0ve sep=/. 22 baytlık sürüm isteğe bağlı bir ayırıcı ve doldurucu seçimi kullanabilir.


Bu, giriş ayırıcı = \n(0xa), çıkış dolgu = 0, çıkış ayırıcı = /= dolgu-1 olan 21 baytlık versiyondur . Bu sabitler kolayca değiştirilebilir.

; 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 bit sürümü, 2 bayt DEC veya a kullanılarak 1 bayt daha uzundur mov al, output_separator. Bunun dışında, makine kodu iki versiyonu için aynıdır, ancak bazı kayıt adları değişiklik (örneğin rcxyerine ecxde pop).

Test programının çalıştırılmasından gelen örnek çıktı (temel 3)

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

Algoritma :

exp *= baseHer dolgu maddesi için giriş yaparak giriş yapın . Sınırlayıcılarda ve sonlandırıcı sıfır baytta, expçıkış dizesine dolgu baytlarını ve ardından bir ayırıcı ekleyip sıfırlayın exp=1. Bu girdi bir satır hem sonuna kadar garanti olduğunu çok uygun ve bir terminatör.

Girişte, ayırıcının üstündeki herhangi bir bayt değeri (işaretsiz karşılaştırma) dolgu maddesi olarak kabul edilir ve ayırıcının altındaki herhangi bir bayt değeri dizge sonu işaretçisi olarak değerlendirilir. (Sıfır bayt için açıkça kontrol etmek test al,al, iç döngü tarafından ayarlanan bayraklarda dallanma vs.


Kurallar sadece takip eden bir yeni satır olduğunda takip eden bir ayırıcıya izin verir. Uygulamam her zaman ayırıcıyı ekler. 1B'nin 32 bit modda tasarrufunu sağlamak için, bu kural ayırıcı = 0xa ( '\n'ASCII LF = satır besleme), dolgu = 0xb ( '\v'ASCII VT = dikey sekme) gerektirir. Bu çok insan dostu değil, ancak kanunun mektubunu karşılar. (Çalışıp
tr $'\v' xçalışmadığını doğrulamak için hexdump veya çıktısını alabilir ya da çıktı ayırıcı ve doldurucu yazdırılabilir olacak şekilde sabiti değiştirebilirsiniz. , ama bu kuralı çiğnemekten kazanacak bir şey göremiyorum.).


NASM / YASM kaynağı. %ifTest programına dahil olanları kullanarak 32 veya 64 bit kod olarak oluşturun veya sadece rcx'i ecx olarak değiştirin.

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

İşlev, imza ile birlikte x86-64 SystemV ABI'yi izler,
void str_exp(char *out /*rdi*/, const char *src /*rsi*/, unsigned base /*edx*/);

yalnızca arayan kişi için çıkış dizgesinin uzunluğunu bir son işaretçi bırakarak bildirir rdi, böylece geri dönüş değerini olmayan bir değer olarak değerlendirebilirsiniz. -standart arama sözleşmesi.

Son xchg eax,ediimleci eax veya rax olarak döndürmek 1 veya 2 byte'a ( ) mal olur. (X32 ABI kullanıyorsa, işaretçilerin yalnızca 32 bit olduğu garantilidir, aksi takdirde xchg rax,rdiarayan kişinin düşük 32 bit dışındaki bir arabellek için bir işaretçi geçirmesi durumunda kullanmamız gerekir .) Bunu sürümüne dahil etmedim. Gönderen, arayanın değeri almadan kullanabileceği geçici çözümler olduğundan rdi, bunu C 'yi sarmalayıcı olmadan da çağırabilirsin.

Çıkış dizgisini veya başka bir şeyi null sonlandırmıyoruz, bu yüzden sadece newline sonlandırıldı. Bunu düzeltmek 2 bayt alır: xchg eax,ecx / stosb (rcx sıfırdan rep stosb.)

Çıktı dizgisi uzunluğunu bulmanın yolları şunlardır:

  • rdi, döndürülen dizenin sonundan birine işaret eder (böylece arayan kişi len = end-start yapabilir)
  • arayan kişi girişte kaç satır olduğunu bilir ve yeni satırları sayar.
  • arayan, büyük sıfırlanmış bir tampon kullanabilir ve strlen()daha sonra.

Güzel ya da verimli değiller (bir asm arayandan RDI dönüş değerini kullanmak hariç), ancak bunu yapmak istiyorsanız, golflü asm işlevlerini C'den çağırmayın: P


Boyut / aralık sınırlamaları

Maksimum çıktı dizesi boyutu yalnızca sanal bellek adres alanı sınırlamaları ile sınırlıdır. (Temel olarak mevcut x86-64 donanımı, sanal adreslerde yalnızca 48 önemli bit'i destekler , sıfır olarak uzatmak yerine işaret-uzadıklarından ikiye bölünürler. Bağlantılı cevaptaki şemaya bakın .)

Her bir satır en fazla 2 ** 32 - 1 dolgu baytına sahip olabilir, çünkü ben üsteli bir 32 bitlik kayıt defterinde biriktiriyorum.

İşlev 0 - 2 ** 32 - 1 arasındaki tabanlar için doğru çalışır (Temel 0 için 0 = x = 0, yani yalnızca dolgu baytı olmayan boş satırlar. Temel 1 için doğru 1 ^ x = 1, yani her zaman Satır başına 1 dolgu.)

Ayrıca Intel IvyBridge ve sonrasında cayır cayır yanan hızlı, özellikle de büyük satırlar hizalanmış belleğe yazılmış. ERMSB özelliğine sahip CPU'larda hizalı işaretçiler bulunan büyük sayımların rep stosboptimum bir uygulamasıdırmemset() . örn. 180 ** 4 0,97 GB'dir ve i7-6700k Skylake'imde (~ 256k yumuşak sayfa hatasıyla) yazmak / 0.25 saniye sürer / dev / null. (Linux'ta / dev / null aygıt sürücüsü verileri hiçbir yere kopyalamaz, yalnızca geri döner. Bu nedenle, her rep stosbzaman belleğe ilk kez dokunduğunuzda tetikleyen yumuşak sayfa hatalarında bulunur. Maalesef BSS'deki dizi için şeffaf sarmallar kullanmamaya çalışıyorum. Muhtemelen bir madvise()sistem çağrısı hızlandırabilir.)

Test programı :

Statik bir ikili yapı oluşturun ve ./string-exponential $'#\n##\n###' $(seq 2)taban 2 için çalıştırın . Bir uygulanmasını önlemek atoiiçin kullanır base = argc-2. (Komut satırı uzunluğu sınırları gülünç büyük tabanların test edilmesini önler.)

Bu sarıcı, 1 GB'a kadar çıktı dizeleri için çalışır. (Sadece tek bir write () sistemini devasa karakter dizileri için bile çağırır, fakat Linux bunu borulara yazmak için bile destekler). Karakterleri saymak için, ya içine girin wc -cya strace ./foo ... > /dev/nullda yazma sistemindeki argümanı görmek için kullanın .

Bu, dize uzunluğunu bir argüman olarak hesaplamak için RDI dönüş değerinden yararlanır 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.

Bu, özellikle x86 string ops için kendini çok iyi ödünç veren eğlenceli bir mücadeleydi . Kurallar, yeni bir satırın ardından giriş dizesinin sonunda bir sonlandırıcı kullanmak zorunda kalmamak için güzel bir şekilde tasarlanmıştır.

Tekrarlanan çarpma ile bir üstel tekrarlanan toplama ile çarpma gibidir ve yine de her giriş satırındaki karakterleri saymak için döngü yapmam gerekiyordu.

Bir işlenen mulveya imuldaha uzun süre imul r,rkullanmak yerine , ancak EAX'in örtük kullanımı LODSB ile çakışacaktır.


Ayrıca yük ve karşılaştırma yerine SCASB'yi denedim , ancak xchg esi,ediiç döngüden önce ve sonra gerekliydi , çünkü SCASB ve STOSB'de EDI kullanılıyor. (64-bit sürümünün 64-bit işaretçilerin kesilmesini önlemek için x32 ABI kullanması gerekir).

STOSB'den kaçınmak bir seçenek değildir; başka hiçbir şey kısa herhangi bir yere yakın değildir. Ve SCASB kullanmanın yararının yarısı, iç döngüyü terk ettikten sonra AL = dolgu maddesidir, bu nedenle REP STOSB için herhangi bir kurulum gerekmez.

SCASB, yaptığımdan farklı bir yönde karşılaştırıyor, bu yüzden karşılaştırmaları tersine çevirmem gerekiyordu.

Xchg ve scasb ile en iyi girişimim. Çalışır, ancak daha kısa değildir. ( Dolguyu ayırıcıya değiştirmek için inc/ dectrick'i kullanan 32 bit kod ).

; 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    

Bir giriş için ../.../.üretir ..../......../../. Ayırıcı = newline olan sürümde bir hexdump göstererek uğraşmayacağım.


4

Mathematica 41 38 Bayt

LLIAMnYP sayesinde -3 Bayt

Bu girdiyi tam sayı izleyen dizge listesi olarak alır. Çıktı ayrıca dizelerin bir listesidir.

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

Açıklama:

                   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

Eski versiyon, 41 Bayt

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

"" <> "#"~Table~#3 byte daha kısadır "#"~StringRepeat~#, muhtemelen daha ileride golf oynamaktadır.
LLIAMnYP

3

Japt , 7 bayt

Grafiği ", dolgu maddesiyle birlikte bir dizi dizesi , üsse bir tamsayı olarak alır.

£QpVpXl

Çevrimiçi deneyin

}RGrafiği yerine yeni satır ayrılmış bir dize olarak almak için sonuna ekleyin . ( Dene )


açıklama

    :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 bayt

Y'iw^1HL(Y"

Sınırlayıcı alandır. Dolgu, boşluktan başka bir karakterdir.

Çevrimiçi deneyin!

açıklama

       % 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

Bu işe görünmüyor; TIO'nuza dahil ettiğiniz test durumu için çıktıdaki her satırın uzunluğu 9,3,27,9 olmalıdır, bunun yerine 6,3,9,3 olmalıdır.
Shaggy

@Shaggy Tamamen haklısın. Fark ettiğiniz için teşekkürler. Son düzenlememde bir hata yaptım. Önceki sürüme geri döndüm, ehich haklı
Luis Mendo

Bunun açıklamadan nasıl çalıştığını çözemedik - sonra TIO'ya tıkladım! : D
Shaggy

1
@Shaggy Sadece bu sürüm için bir açıklama ekledim, umarım daha net!
Luis Mendo

3

Haskell , 37 33 bayt

Sudee sayesinde 4 byte tıraş

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

Açıklama:

\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

Hayal kırıklığı yaratan bir şekilde , bu, okunması zor noktadan daha zor olan 2 sürümden daha kısa:

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

Giriş tek bir dize olmalıdır
bartavelle

@ bartavelle, mutlaka değil.
Shaggy

Anladığım kadarıyla Çubuk grafik girişi tek bir dize olarak alınmıştır ...
bartavelle

1
@bartavelle: Çıktı ve giriş, alt
Julian Wolf

2
Sen yerini alabilir replicate(b^length x)'#'ile '#'<$[1..b^length x].
dava

3

ReRegex , 105 bayt

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

Çevrimiçi deneyin!

ReRegex, Retina'nın çirkin kuzeni gibi , kendi fantezi operatörlerine sahip olmak yerine, Düzenli İfadeler için tüm çabayı gösteren gibidir.

Tabii ki, o da vardır #importve #inputher ikisi de hardcoding girişini kaydetmek ve tekrar tekrar aynı ifadeleri tekrar yazmaya.

Açıklaması.

Giriş şeklini alır:

2
____
__
______
___

STDIN’de

________________
____
________________________________________________________________
________

İlk olarak, program , elbette tamamen ReRegex ile yazılmış olan Matematik Kitaplığını içe aktarır. Bunun büyük kısmı daha sonra üç normal ifadedir.

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

İlki girdi tabanımızla eşleşiyor ve ondan sonra bir tekdüze hat arıyor. o zaman, bu satırı ;$1^d<$4>, taban olan (Ondalık) Unary'nin gücüyle değiştirir. Matematik kütüphanesi temel dönüşümü ve üsleri işler. A; daha sonra bitmiş olarak tanımlamak için başlangıçta yerleştirilir.

İkincisi, sonlandırmadan önce kaide, ardından birçok satırlar; Eğer her şey uyuyorsa, tabandan fırlar. sadece cevaplar ve cevaplar ile ayrılmak ;.

Sonuncusu, başlangıçta sadece unary eşleşir, isteğe bağlı olarak, sonra bir ;cevap. Daha sonra, bu cevabı tekrar olmadan birliğe çevirir ;.

Çıktı ilk regex ile eşleşmediğinden, sonsuz döngü oluşturmaz ve bu nedenle çözümümüz çıkarılır.



2

Röda , 19 bayt

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

Çevrimiçi deneyin!

Bir diziyi girdi olarak alır ve çıktı olarak bir değer akışını döndürür.

açıklama

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 bayt

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

Çevrimiçi deneyin! Örnek kullanım: f 3 ["##","#","###","#"]döndürür ["#########","###","###########################","###"].

mapM putStrLn $ f 3 ["##","#","###","#"]Görsel olarak daha hoş bir çıktı elde etmek için kullanın :

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

Buraya sadece yorum yapıyorum çünkü sildiğiniz yayınla ilgili yorum yapamam ... deneyin sum[sum[]^sum[],sum[]^sum[]].
Ørjan Johansen

2

05AB1E , 9 bayt

Çubuklar boşluklarla ayrılmıştır, çıkış karakteri giriş karakteriyle aynıdır.

¬Š#€gm×ðý

Çevrimiçi deneyin!

¬Š#€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 Bayt

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

Çevrimiçi deneyin!


Bu, regex tarafından izin verilmeyen öncü bir yeni satırla döner. Bunu düzeltmek [str_pad]."\n"yerine "\n".[str_pad](+1 byte) kullanabilirsiniz. Ayrıca, doldurucunun ne olduğunu varsayabilir, böylece $l[0]değiştirerek iki bayttan tasarruf edebilirsiniz "#".
fireflame241

@ fireflame241 Teşekkür Etti
Jörg Hülsermann

1

Jöle , 7 bayt

ṁL*@¥¥€

Dolgu karakterini çubukların (karakterlerin listesi, AKA dizeleri) listelerini alan ve döndüren tek boyutlu bir bağlantı esnektir.

Çevrimiçi deneyin! (altbilgi, öğelerini newlines ile birleştirerek ortaya çıkan listeyi güzelleştirir.)

Nası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 "########")

Alternatif 7-byter: ṁ"L€*@¥- her çubuğun ( L€) uzunluğunu alın , basebu güce ( *@) yükselin , daha sonra "listeyi sıkıştırın ( ) ve ikisi arasında kalıp kalıbını ( ) uygulayın.


4 hızlı ve 3 gerçek bağlantı? Bu zorluk veri akışını kontrol etmekte oldukça ağır ...
ETHproductions

Evet, daha kısa bir çözüm olabilir ...
Jonathan Allan

@ JonathanAllan Korkarım yok.
Outgolfer Erik

@ETHproductions Aslında bir bütün olarak bir bağlantı. Açıklama hemen hemen bir satır olabilirdi.
Outgolfer Erik

1

Ruby , 29 bayt

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

Çevrimiçi deneyin!

Evet, geçen hafta ?#tek karakterli bir string ürettiğini öğrendim . Bu özelliğin neden var olduğunu bilmiyorum ama yaptığına sevindim.


1
?XOperatör, Xbazı karakter, "Bu karakterin varsayılan temsilini olsun" operatörüdür. Ruby <1.9'da, karakterin Unicode kod noktasını döndürür, çünkü karakterler bu şekilde tanımlanır, ancak şimdi karakteri içeren bir dize döndürür. Ruby'de daha tutarlı Unicode kullanımına doğru genel bir değişimin parçası.
Tutleman

@Turtleman, neden ?Xkullanıldığı için herhangi bir histerik kuru üzüm var mı? Ruby'nin çok sayıdaki sözleşmesi, değişkenlerin çokluğu gibi, $Perl'e aşinalık yüzünden var.
ymbirtt

1

JavaScript (ES8), 39 bayt

Karıştırma sözdizimini kullanarak tabanı bir tamsayı, grafiği ise dolgu maddesi olarak herhangi bir karakter içeren bir dizge dizisi olarak alır.

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

Dene

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 bayt

Bu sürüm, grafiği yeniden doldurucu olarak herhangi bir karakterle, yeni satır ayrılmış bir dize olarak alır.

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

mRegex'deki bayrağa ihtiyacınız olduğunu düşünmeyin , varsayılan olarak .yeni satırlarla eşleşmiyor.
ETHProductions

Hmm, nereden geldiğini bilmiyorum - bir telefondan golf oynamaya çalışmak tehlikesi. Gösterdiğiniz için teşekkürler, @ETHproductions.
Shaggy

0

Mathematica, 86 bayt

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

giriş

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


Tamam ... Sabit ......
J42161217

0

Oktav, 42 bayt

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

* Dize giriş / çıkış, regex ile tam olarak eşleşmiyor, ancak hangi çubuğun hangisi olduğunu anlamak mümkün.

Bir fonksiyon giriş üssü bve 2D karakterleri siçeren bir karakter dizisi olarak kabul edilir "!"ve çıktı aynı zamanda karakter dizisidir.

Çevrimiçi deneyin!

Açıklama:

                       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 bayt

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

Giriş formatı

Giriş aşağıdaki biçimde gereklidir:

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

0

Kömür , 11 bayt

NβWS«PXβLι↓

Çevrimiçi deneyin! Bağlantı, kodun ayrıntılı bir versiyonudur. G / Ç, -karakter dizelerinin bir listesidir (listeyi sonlandırmak için boş bir satıra ihtiyacınız olduğunu unutmayın).


0

V , 27 bayt

Temel fikir bir ekleme olduğunu 'her satır (n ^ 0) ve sonra her biri için #biz yerine 'doğrultusunda s [input] * '. Sonunda ben her takas 'için #tekrar

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

Çevrimiçi deneyin!


0

R , 35 bayt

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

dizeleri bir liste ve taban olarak alan ve dizelerin bir listesini döndüren isimsiz bir işlev.

Çevrimiçi deneyin!


0

05AB1E , 10 bayt

U|v1Xygm×,

Filer karakteri 1ve sınırlayıcı yeni bir satırdır.

Çevrimiçi deneyin!

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

Retina , 62 bayt

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

;#+;|¶.*$

Çevrimiçi deneyin! Sonuçta, bir çubuk grafik sadece bir tek sayıların listesi. Grafiği ( #s'yi kullanarak ) ardından ondalık basamağıyla (karışıklığı önlemek için) girişi alır . Açıklama: İlk değiştirme öneki 1 ve grafiğin her satırının tabanı. İkinci değiştirme daha sonra üçüncü satır sıfır olmadıkça, her satırdaki ilk sayıyı ikinci ile çarpar. Üçüncü değiştirme daha sonra her satırdaki üçüncü numarayı azaltır. Bu iki değişiklik, üçüncü sayı sıfır olana kadar tekrar edilir. Son değiştirme, tabanı her yerde siler ve istenen sonucu bırakır.



0

Alice , 23 bayt

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

Çevrimiçi deneyin!

Sadece pes etmedim, ama kullandığım noktaya dikkat etmeyi çok istiyorum ! zamanda dolgu maddesi olarak gibi . Bu kesinlikle okuyucunun dikkatini çekecek.

açıklama

Program kardinal ve ordinal modlar arasında geçiş yaptığında daha net olması için aynalar bu açıklamada korunur.

/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 bayt

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

Giriş dizelerinin listesi ilk parametrededir @^a. İkinci parametre $^bbazdır. Çıkış dizelerinin bir listesi döndürülür.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.