Les échelles de journal sont pour les démissionnaires

24

Tout le monde sait que les échelles de journal sont destinées aux abandons . Par conséquent, vous devez écrire un programme ou une fonction qui supprime un graphique à barres avec une échelle logarithmique en fonction d'une base.

L'entrée du graphique à barres est considérée comme une chaîne unique qui est une liste de barres, où chaque barre du graphique à barres de l'échelle logarithmique est séparée par le délimiteur imprimable (ou espace) de votre choix (donc 0x09-0x0A + 0x20-0x7E) et composé d'un caractère de remplissage non imprimable (donc 0x21-0x7E) de votre choix.

Le programme ou la fonction génère une chaîne unique qui est une liste de barres, où chaque barre est séparée par le même délimiteur que l'entrée a été séparée et est composée du même caractère de remplissage que l'entrée était composée.

Exemple

Nous choisissons un délimiteur de "\ n" (une nouvelle ligne) et un caractère de remplissage de "#". L'entrée transmise à notre programme ou fonction est:

base = 2 et chaîne =

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

Le code constaterait que les longueurs des barres sont [4,2,6,3]. Il calculerait l'anti-log de chaque longueur avec base 2pour obtenir [2^4,2^2,2^6,2^3]= [16,4,64,8]. Ensuite, les longueurs sont sorties au format de barre d'échelle linéaire:

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

Entrée sortie

Votre programme ou fonction peut entrer et sortir dans n'importe quel format raisonnable .

La base d'entrée est garantie d'être un entier supérieur à 1. Vous pouvez supposer que la base est inférieure à 256. L'entrée de chaîne est garantie pour correspondre parfaitement à l'expression régulière (f+s)+f+, où fet ssont remplacés respectivement par votre remplissage et délimiteur.

La sortie de la chaîne doit correspondre entièrement à l'expression régulière (f+s)+f+, où fet ssont remplacés respectivement par le même remplissage et délimiteur. La sortie peut éventuellement avoir une nouvelle ligne de fin.

La sortie et l'entrée peuvent également être une liste de chaînes au lieu d'être délimitées par une sous-chaîne, bien qu'il doit être possible de comprendre quelle barre est laquelle.

Cas de test

(supposez que le remplissage est #et le délimiteur \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
la source

Réponses:

6

Fonction de code machine x86 32 bits, 21 octets

Fonction de code machine x86-64, 22 octets

L'économie 1B en mode 32 bits nécessite l'utilisation de separator = filler-1, par exemple fill=0et sep=/. La version 22 octets peut utiliser un choix arbitraire de séparateur et de remplissage.


Il s'agit de la version à 21 octets, avec séparateur d'entrée = \n(0xa), remplisseur de 0sortie = , séparateur de sortie = /= remplisseur-1. Ces constantes peuvent être facilement modifiées.

; 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

La version 64 bits est plus longue de 1 octet, utilisant un DEC de 2 octets ou un mov al, output_separator. En dehors de cela, le code machine est le même pour les deux versions, mais certains noms de registre changent (par exemple rcxau lieu de ecxdans pop).

Exemple de résultat de l'exécution du programme de test (base 3):

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

Algorithme :

Faites une boucle sur l'entrée, exp *= basepour chaque caractère de remplissage. Sur les délimiteurs et l'octet zéro de fin, ajoutez des expoctets de remplissage, puis un séparateur à la chaîne de sortie et réinitialisez-le exp=1. Il est très pratique de garantir que l'entrée ne se termine pas à la fois par une nouvelle ligne et un terminateur.

En entrée, toute valeur d'octet au-dessus du séparateur (comparaison non signée) est traitée comme un remplissage et toute valeur d'octet au-dessous du séparateur est traitée comme un marqueur de fin de chaîne. (La vérification explicite d'un octet zéro prendrait un test al,albranchement supplémentaire par rapport aux indicateurs définis par la boucle interne).


Les règles n'autorisent un séparateur de fin que lorsqu'il s'agit d'une nouvelle ligne de fin. Mon implémentation ajoute toujours le séparateur. Pour obtenir l'enregistrement 1B en mode 32 bits, cette règle nécessite un séparateur = 0xa ( '\n'ASCII LF = saut de ligne), filler = 0xb ( '\v'ASCII VT = tabulation verticale). Ce n'est pas très convivial pour l'homme, mais satisfait à la lettre de la loi. (Vous pouvez hexdump ou
tr $'\v' xla sortie pour vérifier qu'elle fonctionne, ou changer la constante pour que le séparateur et le remplisseur de sortie soient imprimables. J'ai également remarqué que les règles semblent exiger qu'il puisse accepter l'entrée avec le même remplissage / sep qu'il utilise pour la sortie , mais je ne vois rien à gagner à enfreindre cette règle.).


Source NASM / YASM. Construisez en code 32 ou 64 bits, en utilisant les %iféléments inclus avec le programme de test ou changez simplement rcx en 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

La fonction suit l'ABI SystemV x86-64, avec signature.
void str_exp(char *out /*rdi*/, const char *src /*rsi*/, unsigned base /*edx*/);

Elle n'informe l'appelant que de la longueur de la chaîne de sortie en lui laissant un pointeur un-la-fin rdi, vous pouvez donc considérer cela comme la valeur de retour dans un non - convention d'appel standard.

Cela coûterait 1 ou 2 octets ( xchg eax,edi) pour retourner le pointeur de fin en eax ou rax. (Si vous utilisez l'ABI x32, les pointeurs sont garantis à seulement 32 bits, sinon nous devons utiliser xchg rax,rdiau cas où l'appelant passe un pointeur vers un tampon en dehors des 32 bits bas.) Je n'ai pas inclus cela dans la version que je suis la publication car il existe des solutions de contournement que l'appelant peut utiliser sans obtenir la valeur rdi, vous pouvez donc l'appeler à partir de C sans wrapper.

Nous ne terminons même pas null la chaîne de sortie ou quoi que ce soit, donc c'est seulement terminé par une nouvelle ligne. Il faudrait 2 octets pour corriger cela: xchg eax,ecx / stosb (rcx est zéro à partir de rep stosb.)

Les moyens de connaître la longueur de la chaîne de sortie sont les suivants:

  • rdi pointe vers un bout de la fin de la chaîne au retour (pour que l'appelant puisse faire len = end-start)
  • l'appelant peut simplement savoir combien de lignes étaient en entrée et compter les retours à la ligne
  • l'appelant peut utiliser un grand tampon mis à zéro et strlen()ensuite.

Ils ne sont pas jolis ou efficaces (sauf pour utiliser la valeur de retour RDI d'un appelant asm), mais si vous le souhaitez, n'appelez pas les fonctions asm golfées de C.: P


Limites de taille / gamme

La taille maximale de la chaîne de sortie n'est limitée que par les limitations de l'espace d'adressage de la mémoire virtuelle. (Principalement, le matériel x86-64 actuel ne prend en charge que 48 bits significatifs dans les adresses virtuelles, divisés en deux car ils signent-étendent au lieu de zéro-étendent. Voir le diagramme dans la réponse liée .)

Chaque ligne ne peut avoir qu'un maximum de 2 ** 32 - 1 octets de remplissage, car j'accumule l'exponentielle dans un registre 32 bits.

La fonction fonctionne correctement pour les bases de 0 à 2 ** 32 - 1. (Correct pour la base 0 est 0 ^ x = 0, c'est-à-dire juste des lignes vides sans octets de remplissage. Correct pour la base 1 est 1 ^ x = 1, donc toujours 1 charge par ligne.)

Il est également incroyablement rapide sur Intel IvyBridge et versions ultérieures, en particulier pour les grandes lignes écrites dans la mémoire alignée. rep stosbest une implémentation optimale de memset()pour les grands nombres avec des pointeurs alignés sur les CPU avec la fonction ERMSB . Par exemple, 180 ** 4 fait 0,97 Go et prend 0,27 seconde sur mon i7-6700k Skylake (avec ~ 256 k de défauts de page) pour écrire dans / dev / null. (Sur Linux , le pilote de périphérique pour / dev / null ne copie pas les données partout, il retourne juste. Donc , tout le temps est en rep stosbet les douces fautes de page qui se déclenche lorsque touchant la mémoire pour la première fois. Il est malheureusement, n'utilise pas d'énormes pages transparentes pour le tableau dans le BSS. Un madvise()appel système pourrait probablement l' accélérer.)

Programme de test :

Construisez un binaire statique et exécutez comme ./string-exponential $'#\n##\n###' $(seq 2)pour la base 2. Pour éviter d'implémenter un atoi, il utilise base = argc-2. (Les limites de longueur de ligne de commande empêchent de tester des bases ridiculement grandes.)

Ce wrapper fonctionne pour les chaînes de sortie jusqu'à 1 Go. (Il ne fait qu'un seul appel système write () même pour des chaînes gigantesques, mais Linux le prend en charge même pour l'écriture dans des tuyaux). Pour compter les caractères, canalisez wc -cou utilisez strace ./foo ... > /dev/nullpour voir l'argument de l'appel système d'écriture.

Cela tire parti de la valeur de retour RDI pour calculer la longueur de chaîne comme argument pour 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.

C'était un défi amusant qui se prêtait très bien à asm, en particulier aux opérations de chaîne x86 . Les règles sont bien conçues pour éviter d'avoir à gérer une nouvelle ligne puis un terminateur à la fin de la chaîne d'entrée.

Une exponentielle avec multiplication répétée est tout comme la multiplication avec addition répétée, et j'avais besoin de boucler pour compter les caractères dans chaque ligne d'entrée de toute façon.

J'ai envisagé d'utiliser un opérande mulou imulau lieu du plus long imul r,r, mais son utilisation implicite d'EAX entrerait en conflit avec LODSB.


J'ai également essayé SCASB au lieu de charger et de comparer , mais j'avais besoin xchg esi,ediavant et après la boucle interne, car SCASB et STOSB utilisent tous deux EDI. (La version 64 bits doit donc utiliser l'ABI x32 pour éviter de tronquer les pointeurs 64 bits).

Éviter STOSB n'est pas une option; rien d'autre n'est aussi court. Et la moitié des avantages de l'utilisation de SCASB est que AL = filler après avoir quitté la boucle intérieure, nous n'avons donc pas besoin de configuration pour REP STOSB.

SCASB compare dans l'autre sens par rapport à ce que j'avais fait, j'ai donc dû inverser les comparaisons.

Ma meilleure tentative avec xchg et scasb. Fonctionne, mais n'est pas plus court. ( Code 32 bits, en utilisant la astuce inc/ decpour changer le remplissage en séparateur ).

; 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    

Pour une entrée de ../.../., produit ..../......../../. Je ne vais pas prendre la peine de montrer un vidage hexadécimal de la version avec separator = newline.

Peter Cordes
la source
4

Mathematica 41 38 octets

-3 octets grâce à LLlAMnYP

Cela prend l'entrée comme une liste de chaînes suivie d'un entier. La sortie est également une liste de chaînes.

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

Explication:

                   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

Ancienne version, 41 octets

"#"~StringRepeat~#&/@(#2^StringLength@#)&
Ian Miller
la source
"" <> "#"~Table~#est 3 octets plus court que "#"~StringRepeat~#, probablement jouable au golf également.
LLlAMnYP
3

Japt , 7 octets

Prend le graphique comme un tableau de chaînes avec "comme remplissage et la base comme entier.

£QpVpXl

Essayez-le en ligne

Ajoutez }Rà la fin afin de prendre le graphique comme une chaîne séparée par des sauts de ligne. ( Essayez-le )


Explication

    :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.
Hirsute
la source
3

MATL , 14 11 octets

Y'iw^1HL(Y"

Le délimiteur est l'espace. Filler est tout autre personnage que l'espace.

Essayez-le en ligne!

Explication

       % 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
la source
Cela ne semble pas fonctionner; la longueur de chaque ligne dans la sortie du scénario de test que vous avez inclus dans votre TIO devrait être de 9,3,27,9 mais à la place, elle est de 6,3,9,3.
Shaggy
@Shaggy Vous avez tout à fait raison. Merci d'avoir remarqué. J'ai fait une erreur dans mon dernier montage. Je suis revenu à la version précédente, ce qui est correct
Luis Mendo
Impossible de comprendre comment cela fonctionnait à partir de l'explication - alors j'ai cliqué sur le TIO! : D
Shaggy
1
@Shaggy Je viens d'ajouter une explication pour cette version, j'espère plus claire!
Luis Mendo
3

Haskell , 37 33 octets

4 octets rasés grâce à sudee

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

La description:

\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

Malheureusement, ceci est 2 octets beaucoup plus court que la version sans point beaucoup plus difficile à lire:

map.(flip replicate '#'.).(.length).(^)
Julian Wolf
la source
L'entrée doit être une seule chaîne
bartavelle
@bartavelle, pas nécessairement.
Shaggy
C'est ce que je comprends par L'entrée du graphique à barres est prise comme une seule chaîne ...
Bartavelle
1
@bartavelle: La sortie et l'entrée peuvent également être une liste de chaînes au lieu d'être délimitées par une sous-chaîne, mais il doit être possible de comprendre quelle barre est laquelle.
Julian Wolf
2
Vous pouvez remplacer replicate(b^length x)'#'par '#'<$[1..b^length x].
sudee
3

ReRegex , 105 octets

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

Essayez-le en ligne!

ReRegex est comme le vilain cousin de Retina qui donne tout l'effort aux expressions régulières, au lieu d'avoir ses propres opérateurs sophistiqués.

Bien sûr, il a également #importet #inputpour enregistrer les deux entrées de codage en dur, et réécrire les mêmes expressions encore et encore.

Expliqué.

Prend des informations sous la forme de:

2
____
__
______
___

sur STDIN, et donne une sortie comme

________________
____
________________________________________________________________
________

Premièrement, le programme importe la bibliothèque mathématique , qui bien sûr est entièrement écrite en ReRegex. La majeure partie de ceci est alors trois expressions régulières.

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

Le premier correspond à notre base d'entrée et cherche une ligne d'unaire après lui. il remplace alors cette ligne par ;$1^d<$4>, qui est la base, par la puissance de l'Unaire (en décimal). La bibliothèque Math gère la conversion de base et l'exposant. UNE ; est placé au début pour l'identifier plus tard comme terminé.

Le second correspond à la base, puis à plusieurs lignes de;, avant de se terminer. Si cela correspond à l'ensemble, il se détache de la base. laissant uf avec juste les réponses et l' ;art.

Le dernier, correspond juste unaire au début, éventuellement, puis une ;réponse. Il transforme ensuite cette réponse en unaire à nouveau, sans le ;.

Parce que la sortie n'est pas assortie par la première expression régulière, elle ne boucle pas indéfiniment, et donc notre solution est sortie.

ATaco
la source
2

Python 2 , 52 36 octets

L'entrée et la sortie sont considérées comme des tableaux de chaînes. #est le remplisseur.

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

Essayez-le en ligne!

totalement humain
la source
2

Röda , 19 octets

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

Essayez-le en ligne!

Prend un tableau en entrée et renvoie un flux de valeurs en sortie.

Explication

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
la source
2

Haskell , 32 octets

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

Essayez-le en ligne! Exemple d'utilisation: f 3 ["##","#","###","#"]retours ["#########","###","###########################","###"].

Utilisez mapM putStrLn $ f 3 ["##","#","###","#"]pour obtenir une sortie plus agréable visuellement:

#########
###
###########################
###
Laikoni
la source
Je commente simplement ici car je ne peux pas commenter le message que vous avez supprimé ... essayez sum[sum[]^sum[],sum[]^sum[]].
Ørjan Johansen
2

05AB1E , 9 octets

Les barres sont séparées par des espaces, le caractère de sortie est le même que le caractère d'entrée.

¬Š#€gm×ðý

Essayez-le en ligne!

¬Š#€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
la source
1

PHP, 69 octets

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

Essayez-le en ligne!

Jörg Hülsermann
la source
Cela revient avec une nouvelle ligne principale, ce qui n'est pas autorisé par l'expression régulière. Vous pouvez utiliser [str_pad]."\n"au lieu de "\n".[str_pad]pour résoudre ce problème (+1 octet). En outre, vous pouvez supposer ce qu'est le remplisseur, vous pouvez donc enregistrer deux octets en le remplaçant $l[0]par "#".
fireflame241
@ fireflame241 Terminé Merci
Jörg Hülsermann
1

Gelée , 7 octets

ṁL*@¥¥€

Un lien monadique prenant et renvoyant des listes de barres (elles-mêmes des listes de caractères, des chaînes AKA) le caractère de remplissage est flexible.

Essayez-le en ligne! (le pied de page embellit la liste résultante en joignant ses éléments à des retours à la ligne.)

Comment?

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

Alternative à 7 octets: ṁ"L€*@¥- obtenir la longueur de chaque barre ( L€), augmenter baseà cette puissance ( *@), puis compresser ( ") la liste et appliquer la dyade de moule ( ) entre les deux.

Jonathan Allan
la source
4 rapides et 3 liens réels? Ce défi est assez lourd pour contrôler le flux de données ...
ETHproductions
Ouais, il pourrait y avoir une solution plus courte disponible ...
Jonathan Allan
@JonathanAllan J'ai bien peur qu'il n'y en ait pas.
Erik the Outgolfer
@ETHproductions Il s'agit en fait d'un seul lien dans son ensemble. L'explication aurait pu être à peu près une seule ligne.
Erik the Outgolfer
1

Rubis , 29 octets

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

Essayez-le en ligne!

Oui, j'ai découvert la semaine dernière qui ?#produit une chaîne à un seul caractère. Je n'ai aucune idée de la raison pour laquelle cette fonctionnalité existe, mais je suis sûr qu'elle est heureuse.

ymbirtt
la source
1
L' ?Xopérateur, où se Xtrouve un caractère, est l' opérateur "obtenir la représentation par défaut de ce caractère". Dans Ruby <1.9, il retournerait le point de code Unicode du caractère, car c'est ainsi que les caractères étaient définis, mais maintenant il renvoie une chaîne contenant le caractère. Cela fait partie d'un changement général vers une gestion Unicode plus cohérente dans Ruby.
Tutleman
@Turtleman, existe-t-il un raisin hystérique pour pourquoi ?Xest-il utilisé? Beaucoup de conventions plus bizarres de Ruby, comme la pléthore de $variables, existent en raison de la familiarité avec Perl.
ymbirtt
1

JavaScript (ES8), 39 octets

Prend la base comme un entier et le graphique comme un tableau de chaînes avec n'importe quel caractère comme remplissage, en utilisant la syntaxe de curry.

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

Essayez-le

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>


Alternative, 49 octets

Cette version prend le graphique comme une chaîne séparée par des sauts de ligne, toujours avec n'importe quel caractère comme remplissage.

b=>s=>s.replace(/.+/g,m=>m.padEnd(b**m.length,m))
Hirsute
la source
Ne pensez pas que vous avez besoin du mdrapeau sur l'expression régulière, par défaut .ne correspond pas aux nouvelles lignes.
ETHproductions
Hmm, je ne sais pas d'où ça vient - les dangers d'essayer de jouer au golf à partir d'un téléphone. Merci de l'avoir signalé, @ETHproductions.
Shaggy
0

Mathematica, 86 octets

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

contribution

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

J42161217
la source
ok ... Fixe ......
J42161217
0

Octave, 42 octets

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

* La chaîne d'entrée / sortie ne correspond pas complètement à l'expression rationnelle mais il est possible de comprendre quelle barre est laquelle.

Une fonction prend comme base d'entrée bet un tableau 2D de caractères scontenant "!"et la sortie est également un tableau de caractères.

Essayez-le en ligne!

Explication:

                       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
la source
0

CJam, 20 octets

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

Format d'entrée

L'entrée est requise dans le format suivant:

"##
####
######"2
Roman Gräf
la source
0

Fusain , 11 octets

NβWS«PXβLι↓

Essayez-le en ligne! Le lien est vers la version détaillée du code. Les E / S sont une liste de chaînes de -caractères (notez que vous avez besoin d'une ligne vide pour terminer la liste).

Neil
la source
0

V , 27 octets

L'idée de base est que nous ajoutons un 'à chaque ligne (n ^ 0), puis pour chacun, #nous remplaçons le 's dans la ligne par [input] * '. À la fin, j'ai 'à #nouveau tout échangé contre

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

Essayez-le en ligne!

nmjcman101
la source
0

R , 35 octets

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

une fonction anonyme qui prend les chaînes comme une liste et la base, et retourne une liste de chaînes.

Essayez-le en ligne!

Giuseppe
la source
0

05AB1E , 10 octets

U|v1Xygm×,

Le caractère filer est 1 et le délimiteur est une nouvelle ligne.

Essayez-le en ligne!

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
la source
0

Rétine , 62 octets

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

;#+;|¶.*$

Essayez-le en ligne! Après tout, un graphique à barres n'est qu'une liste de nombres unaires. Prend l'entrée comme le graphique (en utilisant #s) suivi de la base en décimal (pour éviter toute confusion). Explication: Les premiers préfixes de remplacement 1 et la base de chaque ligne du graphique. Le deuxième remplacement multiplie ensuite le premier nombre sur chaque ligne par la seconde, tant que le troisième nombre est différent de zéro. Le troisième remplacement décrémente ensuite le troisième numéro sur chaque ligne. Ces deux remplacements sont répétés jusqu'à ce que le troisième nombre devienne zéro. Le dernier remplacement supprime la base partout, laissant le résultat souhaité.

Neil
la source
0

Alice , 23 octets

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

Essayez-le en ligne!

Non seulement je ne suis pas un lâcheur, mais je suis tellement déterminé à bien faire valoir que j'utilise ! comme remplissage. Cela attirera certainement l'attention du lecteur.

Explication

Des miroirs sont conservés dans cette explication pour le rendre plus clair lorsque le programme bascule entre les modes cardinal et 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
la source
0

Perl 6 , 26 octets

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

La liste des chaînes d'entrée est dans le premier paramètre, @^a. Le deuxième paramètre $^best la base. Une liste de chaînes de sortie est renvoyée.

Sean
la source