Dicas para jogar golfe em 05AB1E

28

Você tem alguma dica sobre no 05AB1E , um idioma de golfe criado por Adnan ?

Suas dicas devem ser pelo menos um pouco específicas para 05AB1E.

Poste uma dica por resposta.

Oliver Ni
fonte
2
Da avaliação: Perguntas sobre dicas estão no tópico.
mbomb007 17/09

Respostas:

20

Como não fazia parte do Wiki nas páginas do GitHub do 05AB1E (acho que deveria), vou adicioná-lo aqui agora que eu mesmo o entendo melhor.

Como usar o dicionário?

05AB1E possui o seguinte arquivo de dicionário words.ex, contendo todas as palavras que ele conhece. Mas como acessamos as palavras neste dicionário? Vamos dar a palavra "testing"como exemplo:

"testing"pode ser encontrado na linha 1453 do arquivo de dicionário. Como as duas primeiras linhas não são palavras e precisamos da palavra indexada com 0, subtraímos 3.
Portanto, agora temos o índice (1450 ), mas como usá-lo?

Abrimos e iniciamos uma string compactada com . Em seguida, examinamos a segunda coluna do arquivo info.txt . (Assim é 00; é 01; etc.)
No caso em que "testing"isso significa î(14) e» (50).

A String compactada para "testing"é, portanto: “ Experimente online. Como em quase todos os trechos de código 05AB1E, o final é opcional se você não acessa a sequência, portanto, sem funcionar também neste caso .

Algumas coisas a serem observadas:

Todos os caracteres que não possuem nenhum índice no arquivo info.txt podem ser usados ​​como estão. Isso pode ser útil para adicionar um spara produzir uma palavra plural em vez de singular ou usar pontuação como ,.?!por exemplo.
ÿ(interpolação de sequência) também pode ser usado quando você deseja inserir valores da pilha dentro da sequência.
NOTA: Todo caractere solto que não possui nenhum índice no arquivo info.txt conta como uma palavra para os tipos de compactação abaixo.

Existem diferentes tipos de strings compactadas que você pode usar:

  • ': Use uma única palavra compactada como está (não é 'necessário rastrear ) - 'î»: "testing"
  • : Utiliza duas palavras compactadas com delimitador de espaço (não é necessário rastrear ) - „î»î»: "testing testing"
  • : Utiliza três palavras compactadas com delimitador de espaço (não é necessário rastrear ) - …î»î»î»: "testing testing testing"
  • : Pegue a string compactada com delimitador de espaço - “î»î»“: "testing testing"
  • : Pegue a sequência compactada como está, sem espaços implícitos - ’î»î»’: "testingtesting"
  • : Pegue a sequência compactada na caixa de título com delimitador de espaço - ”î»î»”: "Testing Testing"
  • : Pegue a sequência compactada em letras maiúsculas completas com delimitador de espaço - ‘î»î»‘: "TESTING TESTING"

Aqui está um programa útil para obter a string compactada com base em uma entrada de palavras delimitada por espaço:

'“? lAð«Ã#¸˜ vyU "€‚ƒ„…†‡ˆ‰Š‹ŒŽ•–—™š›œžŸ¡¢£¤¥¦§¨©ª«¬®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖ×ØÙÚÛÜÝÞßàáâãäåæçèéêëìíîï" Dâ vy"“ÿ“".V XlQi y?1#] '“,

Experimente online.

Este programa irá:

  1. Pegue a entrada como minúscula, remova qualquer caractere não alfabético (exceto espaços) e, em seguida, divida as palavras por espaços ( lAð«Ã#) ou agrupe as palavras em uma lista se apenas uma palavra for inserida ( ¸˜)
  2. Loops sobre cada palavra ( vyU)
  3. Em seguida, possui um loop interno sobre cada palavra compactada do dicionário ( "€...ï"Dâvy), que ele tentará executar como programa 05AB1E ( "“ÿ“".V)
  4. E se for igual à palavra atual, ela será impressa e quebrará o loop interno XlQiy?1#

Com uma entrada, good bye worlda saída seria, portanto “‚¿Þ¡‚ï“. Experimente online.

NOTA: Você ainda precisa ver se a palavra existe no dicionário para que este gerador funcione e ignorará quaisquer caracteres especiais ou palavras no plural. Somente as palavras exatamente iguais no dicionário serão encontradas.

Aqui está um exemplo em que eu uso …Ÿ™‚ï!a string "olá mundo!" e ’‚¿Þ¡ ÿ ‚ï!’para a string "adeus, mundo!". Observe como os espaços e o ponto de exclamação são usados ​​como estão, porque eles não têm índices no arquivo info.txt. Além disso, ele usaÿ para inserir o "cruel" que estava no topo da pilha, que infelizmente não fazia parte do dicionário (mas ainda era compactado usando o método na seção abaixo).

Como comprimir seqüências de caracteres que não fazem parte do dicionário?

Embora o arquivo de dicionário words.ex seja muito grande (10.000 palavras para ser exato), pode acontecer que você precise de uma palavra que não faça parte dela ou de uma string que seja simplesmente sem sentido. Então, há uma maneira de comprimir esses também?
Certamente, usando.• , que é uma sequência compactada com base em alfabeto 255 de base. NOTA: Este método pode ser usado apenas para caracteres no alfabeto e espaços em minúsculas.

Aqui está um programa útil para converter uma palavra / string na string comprimida baseada em alfabeto base-255:

vAyk})> 27β 255B ".•ÿ•"

Experimente online..

O que este programa acima faz é:

  • vAyk})>: Pegue os índices do alfabeto indexados em 1 das letras individuais da entrada, com os espaços se tornando o índice 0
  • 27β: Converta esses índices da base 27 em um único número
  • 255B: Converta esse número em Base-255 usando a própria página de código do 05AB1E
  • ".•ÿ•": Coloca um início .•e um final antes dessa sequência compactada

Aqui está um exemplo de resposta onde o @Kaldo usa .•zíΘ•para compactar a palavra "ganso".

Como comprimir números inteiros grandes?

Digamos que queremos usar um número muito grande para algo, mas não pode realmente ser recuperado por cálculos de pow. Por exemplo, digamos que queremos acessar o número inteiro grande18238098189071058293 por qualquer motivo.

Nesse caso, podemos usar um inicial e um final para compactar um número no formato [1-9][0-9]+.
O número do exemplo acima se tornará •15Y₁Ò'Θpc•. Experimente online. Novamente, assim como na string de dicionário compactada, o final pode ser removido opcionalmente .

Opcionalmente, quando o número inteiro é pequeno o suficiente para que apenas dois caracteres compactados tenham que ser usados, podemos usar Ž, nesse caso, não precisaremos de um byte à direita para fechá-lo e o número inteiro será compactado em 3 bytes em vez de 4. Para Por exemplo, o número inteiro 13562resultaria •rl•, mas como ele usa apenas dois caracteres, pode ser Žrl.

Além disso, os números no intervalo [101, 355]podem ser compactados em 2 bytes usando Ƶmais um caractere adicional da página de códigos do 05AB1E. Por exemplo, Ƶ–pode ser usado para o número inteiro 250. Aqui uma visão geral de todos os números disponíveis. Esses caracteres são convertidos da Base-255 para a Base-10 e, em seguida, são adicionados 101 (já que os números no intervalo [0,100]já são 1 ou 2 bytes).

Como são esses 15Y₁Ò'Θpce rlcriados? Muito simples, o número é convertido na Base-255 usando a própria página de código do 05AB1E. Então você pode usar o seguinte programa para obter um número de comprimido, para o qual ele irá usar Ƶ., Ž..ou •...•, dependendo do tamanho do inteiro comprimido:

101 355Ÿså i 101-255B"Ƶÿ" ë 255B Dg2Qi "Žÿ" ë "•ÿ•"

Experimente online.

Aqui está um exemplo de resposta onde @Emigna usa •3Èñ•para o número inteiro 246060.

Como comprimir listas inteiras?

Às vezes, você deseja compactar uma lista inteira de números inteiros em vez de um único número. Por exemplo, digamos que queremos a lista [5,93,17,83,4,44,32,19,4,45,83,90,0,14,3,17,17,81]por qualquer motivo. Nesse caso, podemos usar o seguinte: •4βŸ{©£MG]q‡dZΘp•94в Experimente online.

Aqui está um programa útil para gerar esse número compactado e a base na qual queremos converter:

Z>© β 255B ®s"•ÿ•ÿв"

Experimente online.

O que este programa acima faz é:

  • Z>: Obtenha o número máximo + 1 da lista de entrada ( ©: e armazene-o no registro)
  • β: Converte a lista de entrada da base max+1em um único número
  • 255B: Comprima esse número único (como fizemos na seção acima)
  • ®s"•ÿ•ÿв": Retorna o resultado no formato: número inicial, compactado,, max + 1, à direitaв

Aqui está um exemplo de resposta onde eu uso •4Œ”dóŒfÝŸĀTUÕáOyÖOÀÁàu¼6¹₆Žr‡_›y³eß₂©ǝ²ƶ"SAÎAñ'¡û†Ø(•91вpara compactar a lista [85,30,29,39,28,37,33,88,31,40,34,89,35,41,32,90,36,38,42,43,44,60,45,61,46,62,47,63,48,64,49,65,81,50,66,51,67,52,68,53,69,86,54,70,87,55,71,56,72,82,57,73,79,80,58,74,59,75,76,77,78,83,84].
PS: Nesta resposta •6j|eDEJÞó(ÍêΓλùÄÞKüzHÇ-ø`JδŠ₂+Öηôî®À8†6/ðÎ6ùøΓ°ÓĆ;ˆ©Ā•2ôexiste uma alternativa de bytes iguais (57), pois todos os números têm exatamente dois dígitos. Em alguns casos (especialmente em pequenas listas), essa pode ser uma alternativa mais curta.

Compactação inteira vs Compactação de lista inteira:

Com estes dois, pode ir de qualquer maneira. Às vezes, uma lista compactada é mais curta, às vezes um número inteiro compactado, às vezes uma alternativa completamente diferente é mais curta. Portanto, sempre use seu próprio julgamento e suas habilidades de golfe para possivelmente melhorar ainda mais as coisas, em vez de confiar nos geradores acima. Aqui estão alguns exemplos:

[44, 59]( usado nesta resposta de @Emigna ):

[2,4,6,0]( usado nesta resposta de @Emigna ):

  • •3ā•7в são 6 bytes (gerados pelo gerador de lista inteira compactada)
  • Ž3ā7в é de 5 bytes
  • Mas, neste caso, Ž9¦Scom 4 bytes seria a melhor opção (número inteiro compactado 2460 para uma lista de dígitos)

10101001100101001( usado nesta resposta minha ):

  • •a½₄Ƶ6®í• são 9 bytes (gerados pelo gerador inteiro grande compactado)
  • •1∊}•2вJ tem 8 bytes (gerados pelo gerador de lista inteira compactada com junção adicionada)
  • Mas, nesse caso, •1∊}•bcom 6 bytes seria a melhor opção (lista inteira compactada, com um para binário em vez de , que se associa implicitamente)

[85,30,29,39,28,37,33,88,31,40,34,89,35,41,32,90,36,38,42,43,44,60,45,61,46,62,47,63,48,64,49,65,81,50,66,51,67,52,68,53,69,86,54,70,87,55,71,56,72,82,57,73,79,80,58,74,59,75,76,77,78,83,84]( usado nesta resposta minha ):

Kevin Cruijssen
fonte
12

Entrada implícita

Nos dias em que 05AB1E foi lançado, a entrada implícita era bastante nova e sofisticada. Atualmente, parece necessário para acompanhar outras linguagens competitivas (como Jelly, MATL, Pyth, etc.).

For example, when you want to add two numbers, you can do II+:

I    # Input_1.
 I   # Input_2.
  +  # Add them up.

Teste aqui


No entanto, usando entrada implícita , podemos reduzir para apenas 1 byte, a saber +:

+    # Take two numbers implicitly and add them up.

Teste aqui


Isso só acontece quando o comprimento da pilha é menor que a área do operador. Um último exemplo é 3+. A aridade do +operador é 2 enquanto houver apenas 1 elemento na pilha:

3    # Push the number 3 on top of the stack.
 +   # Request implicit input and add to the 3.

Teste aqui

Adnan
fonte
8

Substrings

£é o comando para obter os primeiros bcaracteres da string a.
ex: "hello_world"5£ -> "hello"

Mas se bfor uma lista de índices, em vez disso, divide a cadeia de caracteres em partes (até) desses tamanhos.
ex: "hello_world"5L£ -> ['h', 'el', 'lo_', 'worl', 'd']

Emigna
fonte
8

Variáveis ​​predefinidas

Eles estão um pouco ocultos no 05AB1E. Aqui está uma lista de todas as variáveis ​​predefinidas:

  • ¾, pressiona 0se o counter_variable não for alterado antes deste comando.
  • X, pressiona 1se a variável X não for alterada antes deste comando com U.
  • Y, pressiona 2se a variável Y não for alterada antes deste comando com V.
  • ®, pressiona -1se o registro não for alterado antes deste comando com ©.
  • ¯, empurra [](matriz vazia) se nada for adicionado ao global_array antes deste comando.
  • ¸, empurra [""]uma pilha vazia se não houver entrada. (Obrigado, Emigna, por encontrar este.)
Adnan
fonte
24
¾empurra 0 => isso é o mais não-mnemônico possível
Fatalize 16/16
6
@Fatalize: 0 também empurra 0. ¾empurra uma variável de contador que é inicializada como 0. Se você deseja apenas pressionar 0, é claro que 0 é mais natural, mas se você deseja pressionar 5,0,7, 5¾7é 2 bytes menor que 5 0 7.
Emigna
7
Na época, eu ¾quis dizer .75, e uma vez eu venci Pyth com esse fato . Estas linguagens de golfe newfangled não têm uma pista sobre mnemônicos ...
ETHproductions
31
Não faço ideia do que todos vocês estão falando: p. print(3 / 4)em Python 2 me dá 0.
Adnan
2
Se no início, Mempurra -Inf.
mbomb007
7

Usando a tela ( Λou )

Como não fazia parte dos documentos, e o @Adnan está atualmente muito ocupado para escrevê-lo, pedi permissão para adicioná-lo como uma dica aqui por enquanto.

A função Canvas ( Λou ) pode ser usada para desenhar linhas ASCII na tela. Possui três parâmetros obrigatórios:

  • a Comprimento: o tamanho da (s) linha (s). Pode ser um número inteiro único ou uma lista de números inteiros
  • b String: os caracteres que queremos exibir. Pode ser um único caractere, uma string, uma lista de caracteres ou uma lista de strings (nos últimos três casos, ele usará todos eles um por um, incluindo o contorno)
  • c Direção: a direção na qual as linhas de caracteres devem ser desenhadas. Em geral, temos os dígitos[0,7]das direções, para as quais podemos usar uma ou várias. Existem também algumas opções especiais que exigem um determinado caractere (mais sobre isso mais tarde).

Os dígitos da direção são [0,7]mapeados para as seguintes direções:

7   0   1
  ↖ ↑ ↗
6 ← X → 2
  ↙ ↓ ↘
5   4   3

Alguns exemplos 05AB1E respondem onde o Canvas é usado:

Vamos fazer algo semelhante ao último, então suponha que usamos a Λfunção Canvas com os três parâmetros a seguir:

  • a :[3,3,5,5,7,7,9,9]
  • b :!@#
  • c :[0,2,4,6]

Isso dará a seguinte saída:

  !@#!@#!
  #     @
  @ #!@ #
  ! @ # !
  # ! ! @
  @   @ #
  !#@!# !
        @
@!#@!#@!#

Experimente online.

Então, como isso funciona? Bem, aqui estão as etapas com essas entradas acima:

  1. Desenhar 3caracteres ( !@#) para cima (direção 0)
  2. Desenhar 3-1caracteres ( !@) para a direita (direção 2)
  3. Desenhar 5-1caracteres ( #!@#) para baixo (direção 4)
  4. Desenhar 5-1caracteres ( !@#!) para a esquerda (direção 6)
  5. Desenhar 7-1caracteres ( @#!@#!) para cima (direção 0)
  6. Desenhar 7-1caracteres ( @#!@#!) para a direita (direção 2)
  7. Desenhar 9-1caracteres ( @#!@#!@#) para baixo (direção 4)
  8. Desenhar 9-1caracteres ( !@#!@#!@) para a esquerda (direção 6)

O -1existem porque as linhas se sobrepõem. Portanto, os dois primeiros passos são:

#
@
!

E

 !@

Qual combinado é:

#!@
@
!

Algumas notas menores:

Kevin Cruijssen
fonte
1
Eu nem sabia que 05AB1E tinha uma tela!
precisa
Como ... como você descobriu isso? Código fonte?
Magic Octopus Urn
1
@MagicOctopusUrn A maioria desta resposta de @Adnan (PS: sua resposta mais recente também é bem explicada ). Pelo +×8que eu realmente procurei no código fonte.
Kevin Cruijssen 9/04
5

Estourar ou obter

Como em outros idiomas baseados em pilha, as funções do 05AB1E geralmente pop (consomem) suas entradas da pilha e enviam suas saídas para a pilha.

No entanto, algumas funções obtêm suas entradas da pilha sem consumi-las. Um exemplo é a headfunção, ¬que produz o primeiro elemento da lista de entrada. Veja um exemplo de programa aqui: ¬+. Isso adiciona o primeiro número da lista de entrada a cada número dessa lista.

Para saber quais funções aparecem e quais são exibidas, consulte a coluna correspondente no arquivo de informações da função .

Luis Mendo
fonte
@NeilA. Obrigado! Link atualizado
Luis Mendo
3

Condicionais e loops

Loops e condicionais recebem automaticamente colchetes no final de um programa, portanto, você só precisará adicioná-los no código se precisar de algo fora do loop / condicional.

Por exemplo, este programa (não jogado) que cria uma lista dos primeiros nnúmeros primos não precisa de colchetes. [¹¾Q#NpiNˆ¼

Mas se quiséssemos executar alguma operação na lista resultante, por exemplo, usando delta, precisaríamos fechar o loop primeiro. [¹¾Q#NpiNˆ¼]¯¥

Emigna
fonte
3

Pequenas 05AB1E dicas de golfe

Vai expandir isso com pequenas dicas de golfe que aprendi ao longo do caminho. (Apenas iniciei 05AB1E pessoalmente.)

  • D(duplicado) e Ð(triplicado) em combinação com s(troca) e Š(troca tripla a,b,cpara c,a,b) geralmente são mais curtos do que usar ©(salvar em variável global ) e ®(empurrar variável global ) dentro de loops. Isso salvou um byte nesta resposta minha , assim como dois nesta resposta minha .
  • ½(se 1, aumente counter_variable em 1) não é necessário no final de a µ(enquanto counter_variable ! = a, do ...), pois é feito implicitamente ( salvo um byte nesta resposta minha ).
  • .Bdivide implicitamente em novas linhas. Isso foi útil nesta minha resposta quando estávamos procurando uma alternativa para ¡(dividir) enquanto mantivemos itens vazios (NOTA: A solução na resposta vinculada não funciona quando os elementos contêm espaços à direita após a divisão.) - Espero que um builtin ser adicionado para dividir, mas manter as linhas vazias no futuro.
  • (qual dos dígitos do número inteiro de entrada pode dividir igualmente o número inteiro de entrada) conterá o próprio número dos dígitos 0(em vez de erros de divisão por zero). Por exemplo, 1053resultará em[1,1053,0,1] (1053 é divisível por 1 e 3; não é divisível por 5; e fornece um erro de divisão por zero para 0). Isso foi bastante útil nessa minha resposta , assumindo o poder da lista, pois apenas 1é verdade em 05AB1E e todo o resto é falsey. SÖPresultando em truthy ( 1) significa, portanto, que um número inteiro de entrada é divisível igualmente por cada um de seus dígitos.
  • Depois de ver û(palindromize uma determinada string), fiquei surpreso por não haver um is_palindrome embutido. Mas, mais tarde, percebi que apenas 2 bytes são necessários para realizar isso, que são ÂQ(where Âis bifurcate, que é a abreviação de DR: Duplicate & Reverse copy; eQ é para verificar se os dois principais valores na pilha são iguais).
  • Quando você deseja filtrar uma lista por várias coisas, geralmente é mais barato ter vários filtros soltos do que todos combinados em um. Como quando você tem dois filtros, precisará de algo como Ds*(duplicar, trocar, multiplicar para agir como AND lógico) vs (fechar o primeiro filtro, filtrar novamente) ao usar dois filtros. Por exemplo: neste desafio , temos que listar todos os números de quatro dígitos, contendo pelo menos um 0e com uma soma de dígitos igual a 9. O uso de um intervalo [1000,10000]cobre o número de quatro dígitos, mas você terá mais dois filtros. Inicialmente eu usei ₄4°ŸʒD0åsSO9Q*(14 bytes), mas usando dois filtros, um byte pode ser salvo: ₄4°Ÿʒ0å}ʒSO9Q(13 bytes). (Que mais tarde foi jogado para ₄4°ŸεW°ö9Q(10 bytes) por @Grimy.)
  • Quando você deseja compactar com número inteiro 0como preenchedor, você pode usar . Um problema com isso, no entanto, é que o preenchimento 0se tornará uma sequência "0", portanto, se você tentar classificar mais tarde com sequências mistas e números inteiros, provavelmente isso não dará o resultado desejado. Aqui um exemplo de como ele irá classificar as listas internas zipados: 0ζ€{. Isso pode ser corrigido através da adição de uma conversão explícita para int ( ï) após o fecho de correr, e só então tipo: 0ζï€{. No entanto, o uso da ¾constante como 0no preenchimento de zip fará com que ele permaneça um número inteiro em vez de uma string durante o zip. Então, ¾ζ€{você salvará um byte aqui. Esta dica foi fornecida pelo @ Mr.Xcoder para salvar um byte nesta resposta minha .
  • Se você deseja somar os dígitos de vários números em uma lista, você pode usar €SO. No entanto, o mais curto é o uso , que vetoriza automaticamente. Esta dica foi fornecida pelo @Grimy para salvar um byte aqui (e 2 bytes aqui ).
  • Se você está lidando apenas com números inteiros não negativos e deseja verificar dentro de um filtro se é 0 ou 1, é claro que você pode usar o óbvio 2‹. No entanto, usar !(fatorial) também resultará apenas em 1 (verdade) para 0e 1, e qualquer outro valor resultará em algo mais alto (e, portanto, falsey, pois somente 1é verdade em 05AB1E). Esta dica foi fornecida pelo @Grimy para salvar um byte aqui .
Kevin Cruijssen
fonte
2

Vetorização automática

Observe que alguns operadores em 05AB1E se vetorizam automaticamente em matrizes. Por exemplo, o código 5L3+que é desmontado para o seguinte pseudocódigo:

[1, 2, 3, 4, 5] + 3

se tornaria:

[4, 5, 6, 7, 8]

Se não for vetorizado automaticamente, você também poderá usar o operador. Ele pega um comando de caractere único e executa esse operador (monádico) em cada elemento. Um exemplo para dividir cada elemento é o seguinte código ( tente aqui ):

€S

Enquanto o Soperador normal dividiria cada elemento na matriz e a nivelaria em uma única matriz ( tente aqui ).

Adnan
fonte
Como você atribui ao enésimo elemento em uma matriz?
Andrew Savinykh
@AndrewSavinykh No momento, não há um construtor para isso, mas é algo que eu quero implementar.
Adnan
@ Adnan eu encontrei uma maneira de fazê-lo. Crie outra lista que tenha o valor a ser atribuído também no enésimo índice. Em seguida, mescle as listas usando ñprecedido pelo valor de n(o índice). Você está em
Home
@ mbomb007 Isso é possível, o único problema é que você não pode modificar a matriz posteriormente, uma vez que o comando merge usa apenas seqüências de caracteres como argumentos (e converte a lista em uma sequência de caracteres).
Adnan
2

Ordenação das entradas

A ordem em que você recebe a entrada pode ter um efeito drástico no seu código e, muitas vezes, se você estiver usando spara trocar a parte superior da pilha pela próxima coisa mais alta na pilha, não está pensando no problema corretamente. Tente reordenar as entradas e verifique se você pode se livrar da necessidade de trocar, trocando as entradas com antecedência, adicionando-as à pilha mais cedo ou duplicando-as em algum lugar. O I&O mais óbvio pode ser a resposta 05AB1E menos bem-sucedida.

Urna de polvo mágico
fonte
2

05AB1E Golfe ASCII-Art

O código abaixo ajuda a transformar o ASCII-art em 05AB1E usando uma conversão de base personalizada.

|»©ÐÙSDŠ¢øΣθ}R€н¬®sÅ?iD2£RDŠKsì}J©žLR‡®gö₅B®s"•ÿ•“ÿ“ÅвJ"

Experimente online.

Isso é realizado por:

  1. Listando os caracteres exclusivos no desenho ASCII.
  2. Encomende-os quantas vezes eles ocorrerem na cadeia de caracteres em ordem decrescente (caracteres que ocorrem com menos frequência).
  3. Inverta os dois primeiros itens se o desenho ASCII começar com o caractere mais ocorrente (para evitar 0s iniciais no número inteiro compactado).
  4. Mapeie os caracteres da entrada 0-9A-Za-znessa ordem, cada caractere distinto obtendo seu próprio caractere de mapeamento, até que todos sejam substituídos.
  5. Compacte-o com base, usando a base mais alta necessária para substituir (com base na quantidade de caracteres exclusivos).
  6. Base converta-o novamente em base-255 (para compactação 05AB1E).
  7. Tudo formato no formato: •<compressed_integer>•“<sorted_distinct_characters>“ÅвJ.

O permite compactar também aspas "; o Åвusará essa sequência para converter em base o número inteiro gerado usando a sequência como base personalizada; e Junirá todos esses caracteres em uma única sequência, que é emitida implicitamente.

Aceita padrões com até 62 caracteres únicos, bons para arte ASCII.
Quanto menor a quantidade de caracteres únicos, melhor a compactação.


Exemplo de saída para Desenhar o diagrama de tempo digital XNOR (214 bytes, 9 caracteres únicos):

    ┌─┐ ┌─┐ ┌─────┐ ┌─┐ ┌─┐ ┌───┐  
A ──┘ └─┘ └─┘     └─┘ └─┘ └─┘   └──
  ┌───┐ ┌───┐ ┌─┐ ┌─────┐   ┌─┐ ┌─┐
B ┘   └─┘   └─┘ └─┘     └───┘ └─┘ └
    ┌─────┐   ┌─┐   ┌─┐   ┌───┐   
X ──┘     └───┘ └───┘ └───┘   └────

Seria:

05AB1E , 106 bytes

•I£.µ*:]ó±øqaµb₄ΘYQmœ¹µû₄p´ζÂĆ_5ŠKÑ×ðòË|₄#¹¶úôÂ-Í|¯ε¼É₂ïδ&é–9»ÞFò1î×HÃBjý2ĆÉ≠FYÂÂèC j‘£Å₅Œ•“─ └┘┐┌
XBA“ÅвJ

Experimente online.

(106/214) * 100 = 49,53% do tamanho da string original da arte ASCII.

Qual é o mesmo número de bytes que meu envio real para esse desafio no 05AB1E (legado).


Explicação do código:

NOTA: O código não é absolutamente um jogo de golfe. Foi rapidamente escrito para converter a arte ASCII na compressão mais eficiente, por isso é bastante feio e longo ..

               # Take multi-line input
  ©              # Store it in the register to reuse later                         
ÐÙS              # Only leave unique characters (as list)
   DŠ¢ø          # Map it with the count for each of those characters
       Σθ}R      # Sort it based on that count (highest to lowest)
           €н    # Remove the count again, so the sorted characters remain
¬®sÅ?i           # If the input starts with the most occurring character:
      D2£RDŠKsì} #  Swap the first two characters in the list
J©               # Join everything together, and store it in the register to reuse later
  žLR           # Map each character to [0-9A-Za-z]
      ®gö        # Get the amount of unique characters, and convert it to that Base
         B      # And then convert that to Base-255
®s               # Push the string and swap so the compressed integer is at the top again
  "•ÿ•“ÿ“ÅвJ"    # Insert it in the correct output format
                 #  `•<compressed_integer>•“<sorted_distinct_characters>“ÅвJ`
"•ÿ•"            # (after which the result is output implicitly with trailing newline)
Urna de polvo mágico
fonte
1
A propósito, desde que 05AB1E alterou a página de códigos, a base máxima é alterada de 214 para 255 .
Adnan
1
Talvez algo a acrescentar à sua resposta (ou modificar o gerador com), mas se menos de 10 caracteres distintos estiverem sendo utilizados na arte ASCII, você poderá jogar com dois bytes. Ou seja, seu gerador fornece esse 22-byter , mas pode ser esse 20-byter .
Kevin Cruijssen 29/10
@KevinCruijssen, a idéia era o que eu estava tentando transmitir, não afirmando realmente que o gerador é algo bom: P. Sinceramente, duvido que ele ainda funcione com osabie. Escrevi isso há muito tempo!
9334 Octopus Magic Urn
@MagicOctopusUrn Não tenho certeza se é executado na reescrita do Elixir, mas certamente ainda funciona na versão herdada. Eu já editei a Base-214 para a Base-255 há cerca de metade de um ano atrás, como foi mencionado no comentário de Adnan acima. Além disso, ele funciona muito bem e eu o usei algumas vezes (apesar de jogar golfe cada vez mais.;)). A geração da string e do número funciona muito bem!
21418 Kevin Kelijsen em
Aqui está uma versão melhorada. (Muito feio e rápido, mas funciona). Seria o seu exemplo de 108 bytes em vez de 113. As melhorias que fiz foram: classificar primeiro os caracteres distintos na ocorrência mais alta (a menos que a ocorrência mais alta seja o primeiro caractere; nesse caso, ele trocará os dois caracteres principais) para que os compactados número inteiro é o menor possível; usando em <str><compr_int><int>вèJvez do seu <compr_int><int>BžLR<str>‡; e usar, em vez de "como aspas, para "fazer parte da entrada.
Kevin Cruijssen
1

Strings e ints são tipos iguais

Não é algo que todos concordam, mas funciona.

Considere os dois programas a seguir:

4 5+
"4""5"+

Ambos resultam em 9 . Isso ocorre porque cada valor é avaliado primeiro (com ast.literal_eval). Por isso, podemos executar todos os operadores de manipulação de strings nas entradas e todos os operadores de manipulação int nas strings.

Por exemplo, 12345ûpalindromiza o número 12345, resultando em 123454321. Depois disso, podemos fazer as contas regulares nesse número.

12345û50000-

Isso resultaria em: 123404321 .

Adnan
fonte
0

Loops e iteradores ocultos

05AB1E possui os seguintes loops e iteradores normais:

  • F, que itera através de 0 .. n-1 .
  • G, que itera através de 1 .. n-1 .
  • ƒ, que itera através de 0 .. n .
  • v, que itera sobre cada elemento s [0], s [1], .., s [n] .
  • ʒ, que não é exatamente um loop, mas um comando de filtro por . Abusamos deste comando por seu comportamento não intencional de percorrer cada elemento.

Usando esses loops, podemos derivar os seguintes loops ocultos :

  • Em vez de gF, você pode usar o vque também possui um Níndice que pode ser usado.
  • A vy -> ʒsubstituição é um pouco mais complicada:
    • Você precisa imprimir imediatamente os resultados. Isso suprime a impressão automática ao imprimir a parte superior da pilha.
    • O trecho de código é executado em uma nova pilha temporária . Isso significa que fragmentos dependentes da pilha não podem ser usados.
    • yNão é possível invocar nesse tipo de loop.
Adnan
fonte
Eu sei que isso foi postado há um ano, mas não são [, µe εtambém parte do Loops / iterações normal?
Kevin Cruijssen
Além disso, yé possível invocar algumas delas agora.
Magic Octopus Urn