Toda a sua base 97 nos pertence

18

Muitas linguagens de programação são escritas usando apenas ASCII, guias e novas linhas imprimíveis. Esses 97 caracteres são armazenados em bytes de 8 bits (que são realmente capazes de conter 256 caracteres diferentes!), O que é terrivelmente ineficiente - especialmente no golfe de código, onde cada byte conta! Nesse desafio, você poderá reduzir sua pontuação usando a conversão base.

Desafio

Seu programa / função usa uma seqüência de caracteres ou matriz de caracteres como entrada, que depois interpreta como um número de base 97 . Em seguida, ele converte isso em um número de base 256 e conta o número de símbolos (ou seja, bytes) necessários para representar esse número. Essa contagem será o valor de saída / retorno do seu programa / função.

Um exemplo simples usando base-2 e base-10 (binário e decimal): se a entrada for 10110, a saída será 2, pois 10110 2 = 22 10 (dois dígitos necessários para representar a saída). Da mesma forma, 1101 2 se torna 13 10 , dando uma saída de 2 também, e 110 2 se torna 6 10 , então a saída seria 1.

A sequência de entrada pode conter todos os 95 caracteres imprimíveis ASCII, bem como a nova linha \ne a guia literal \t, que cria um alfabeto de origem de 97 símbolos para sua conversão base. O alfabeto exacta será, assim, (substituindo a \te \ncom separador literal real e nova linha; nota o espaço literal seguinte a nova linha) :

\t\n !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~

Observe que a ordem desse alfabeto é importante: por exemplo, a base-97 \tcorresponde ao decimal 0e !ao decimal 3.

Alguns casos de teste: (você não precisa manipular uma string vazia)

Input                             Output
'[email protected]'                  15
'All your base are belong to us!'     26
'       abcd'                          9
'~      abcd'                         10
'ABCDEFGHIJK'                          9
'zyxwvutsrpq'                         10
'{".~"}.~'                             7
'\t\t\t\t\t\t\t\t'                     1 (with \t a literal tab; the result is 0, which can be represented with 1 byte)
'!\t\t\t\t\t\t\t\t'                    7 (with \t a literal tab)

Pontuação

  1. Se sua entrada usar apenas ASCII imprimível, nova linha e / ou guia: A pontuação do seu programa será a saída do seu programa, quando for fornecido seu próprio código-fonte como entrada.

  2. Se a sua entrada usar caracteres que não sejam ASCII, nova linha ou guia imprimíveis: A pontuação do seu programa é simplesmente o número de bytes, como no .

Sanchises
fonte
3
Se você tem uma sugestão de título melhor do que esse meme desatualizado , fique à vontade para publicá-la nos comentários!
Sanchises 15/08/19
Você percebeu que esse desafio poderia ser vencido com uma resposta de linguagem composta apenas por guias.
precisa saber é
@ppperry Para ser sincero, tenho pouca paciência para essas respostas. Sim, eu percebi isso, mas até que alguém possa realmente armazenar o programa em seu sistema, isso não receberá meu voto positivo.
Sanchises 15/08/19

Respostas:

7

Python 2 , pontuação 73 72 71

Edit: -1 graças a @ Jonathan Allan

def f(l,z=0):
	for i in map(ord,l):z+=i-[30,9][i<32];z*=97
	print(len(bin(z))-2)/8or 1

Experimente online!

Halvard Hummel
fonte
apenas um /deve ser OK eu acho
Jonathan Allan
or 1pode ser substituído por |1nesta instância.
Jonathan Allan
1
@ JonathanAllan Isso produz resultados diferentes (errados).
Sanchises 15/08/19
Ah, sim, será>. <- estava pensando em obter um zero lá, mas será bit a bit ou com os outros números também.
Jonathan Allan
@JonathanAllan Exatamente. Funcionará para resultados ímpares, mas adicionará um aos resultados pares.
Sanchises 15/08/19
5

Japt , pontuação 19 (23 bytes)

nHo127 uA9 md)sG l /2 c

Teste online!

Por coincidência, não acho que isso possa ser praticado, mesmo com caracteres não ASCII ...

Explicação

UnHo127 uA9 md)sG l /2 c   Implicit: U = input string, A = 10, G = 16, H = 32
  Ho127                    Create the range [32, 33, ..., 126].
        uA9                Insert 9 and 10 at the beginning of this range.
            md             Map each to a character, yielding ["\t", "\n", " ", "!", ... "~"].
Un            )            Convert U to a number via this alphabet ("\t" -> 0, "~" -> 96, etc.)
               sG          Convert this number to a base-16 (hexadecimal) string.
                  l        Take the length of this string.
                    /2 c   Divide by two and round up to get the length in base-256.
                           Implicit: output result of last expression
ETHproductions
fonte
5

Gelatina ,  18  17 bytes - pontuação  18  17

-1 byte graças a Erik the Outgolfer (não há necessidade de uma lista de listas para a tradução)

O“µœ½þ‘y_30ḅ97b⁹L

Experimente online!

Quão?

O“µœ½þ‘y_30ḅ97b⁹L - Link: list of characters
O                 - convert from characters to ordinals
 “µœ½þ‘           - code-page indices = [9,30,10,31]
       y          - translate (9->30 and 10->31)
        _30       - subtract 30
           ḅ97    - convert from base 97
               ⁹  - literal 256
              b   - convert to base
                L - length of the result

--O melhor que eu tenho apenas com ASCII é uma pontuação de 29 :

O10,31,9,30y_30Ux"J_1 97*$$$SSb256L

- isso também é extremamente ineficiente. Ele converte os ordinais como acima, mas a conversão da base 97 é alcançada repetindo os valores e somando, em vez de usar a multiplicação direta - ou seja, para converter {".~"}.~, obtém os índices ajustados e [93,4,16,96,4,95,16,96]depois inverte ( U) e os repete para fazer [[96,96,..., 97⁷ times ...,96],[16,16,... 97⁶ times ...16],[95,95,... 97⁵ times ...95],[4,4,... 97⁴ times ...4],[96,96,... 97³ times ...96],,[16,16,... 97² times ...,16],[4,4,... 97 times ...4],[93]]e depois soma, converte na base 256 e obtém o comprimento (se não houver memória insuficiente: p).

Jonathan Allan
fonte
3

J , 36 bytes, pontuação = 30

256#@(#.inv)97x#.(u:9,10,32+i.95)&i.

Experimente online!

J usa apenas os caracteres ASCII de 7 bits para suas primitivas.

Explicação

256#@(#.inv)97x#.(u:9,10,32+i.95)&i.  Input: string S
                 (              )     Form 7-bit ASCII alphabet
                            i.95        Range [0, 95)
                         32+            Add 32
                    9,10,               Prepend 9 and 10
                  u:                    Convert to characters
                                 &i.  Index of each char in S in that alphabet
            97x#.                     Convert from base 97 to decimal
256   #.inv                           Convert to base 256
   #@                                 Length
milhas
fonte
3

Gaia , 14 bytes, pontuação 14

9c₸c₵R]$;B₵rBl

Experimente online!

Explicação

9c              Push a tab character. (done like this since tab isn't in the codepage)
  ₸c            Push a linefeed character.
    ₵R          Push all printable ASCII characters.
      ]$        Concatenate everything together.
        ;       Copy second-from-top, implicitly push input. Stack is now [ASCII input ASCII]
         B      Convert input from the base where the ASCII string is the digits.
          ₵rB   Convert that to the base where the code page is the digits (base 256).
             l  Get the length of the result.
                Implicitly output top of stack.

Apenas ASCII

Este é o melhor que eu poderia usar apenas ASCII, com uma pontuação de 19:

9c10c8373c'R+e]$;B256Bl

A dificuldade está na conversão de entrada. A única maneira razoável de converter do sistema base-97 é usar B, pois o mapeamento requer o não-ASCII ¦. Além disso, não existe atualmente uma maneira de criar um intervalo de caracteres sem mapear cum intervalo numérico, que sofre o mesmo problema. A melhor solução que pude ver foi construir ₵Re avaliar a string .

Gato de negócios
fonte
Você tentou fazer uma versão apenas ASCII disso? Não pode melhorar sua pontuação (suponho ₵Re ₵rnão são fáceis de substituir, embora , obviamente, é), mas pode ser interessante ver como ele se compara.
Sanchises 15/08/19
@Sanchises que eu fiz, mas o mais curto que eu criei acabou sendo 19, já que é o código 8373 e também não posso fazer intervalos de caracteres apenas em ASCII, o que é um pouco frustrante, pois a maior parte desse programa é ASCII.
Business Cat
Sim, é realmente perto de ser apenas ASCII. Pergunta rápida: Não conheço Gaia, mas brinquei um pouco agora, mas existe uma maneira de converter uma lista de números? (como c, mas aplicada a cada personagem, $apenas mostra todos os números)
Sanchises
@ Sanchises Você precisaria mapear ca lista, o que seria #
Business Cat
Na verdade, ₵ré fácil substituir, já que eu poderia usá-lo 256, apenas o usei porque é 1 byte menor e o programa não era apenas ASCII.
Business Cat
3

Python 2 , pontuação 60

lambda s:len(bin(reduce(lambda a,c:a*97+ord(c)-[30,9][c<' '],s,0)))+5>>3

Experimente online!

Mapeando para base-97

O valor de um caractere é obtido por ord(c)-[30,9][c<' ']: seu código ASCII, menos 9 para tabulações e novas linhas (que precedem ' 'lexicograficamente) ou menos 30 para todo o resto.

Convertendo para um número

Usamos reducepara converter a string em um número. Isso é equivalente à computação

a = 0
for c in s: a = a*97+ord(c)-[30,9][c<' ']
return a

Comprimento base 256 da computação

O valor de retorno de biné uma string, que se parece com isso:

"0b10101100111100001101"

Chame seu comprimento L. Um valor com uma nrepresentação binária de -bit possui uma representação de ceil(n/8)-bit base-256. Nós podemos calcular ncomo L-2; Além disso, ceil(n/8)pode ser escrito como floor((n+7)/8)= n+7>>3, então nossa resposta é L-2+7>>3= L+5>>3.

O caso em que a string de entrada tem o valor 0 é tratada corretamente, como binretornos "0b0", portanto retornamos 3+5>>3= 1.

Lynn
fonte
64
Halvard Hummel
@HalvardHummel bastante certeza de que deveria ser c>=' ', ou então você mapear o espaço para 23 em vez de 2. No golfe código comum c>'\x1f'(um byte raw) teria me ajudado, mas que não é ASCII imprimíveis ...
Lynn
Você está certo, meu mal
Halvard Hummel
2

APL, pontuação 24 (bytes *)

⌈256⍟97⊥97|118|¯31+⎕AV⍳⍞

Assume o padrão ⎕IO←1, caso contrário, basta alterar ¯31 para ¯30.

Explicação:

                   ⎕AV⍳⍞  Read a string and convert it to ASCII codepoints + 1
               ¯31+       Subtract 31, so that space = 2, bang = 3, etc.
           118|           Modulo 118, so that tab = 97, newline = 98
        97|               Modulo 97, so that tab = 0, newline = 1
     97⊥                  Decode number from base 97
⌈256⍟                     Ceiling of log base 256, to count number of digits

Exemplos:

      ⌈256⍟97⊥97|118|¯31+⎕AV⍳⍞
[email protected]
15
      ⌈256⍟97⊥97|118|¯31+⎕AV⍳⍞
All your base are belong to us!
26
      ⌈256⍟97⊥97|118|¯31+⎕AV⍳⍞
       abcd
9
      ⌈256⍟97⊥97|118|¯31+⎕AV⍳⍞
~      abcd
10

________________
*: APL pode ser gravado em seu próprio conjunto de caracteres herdado (definido por ⎕AV) em vez de Unicode; portanto, um programa APL que usa apenas caracteres ASCII e símbolos APL pode ser pontuado como 1 char = 1 byte.

Tobia
fonte
Nem todos os símbolos da APL estão ⎕AV(pelo menos para o Dyalog), como . Todos os seus símbolos contam como um byte cada. Portanto, nem todo símbolo de APL = 1 byte como você indica na nota de rodapé. (Apenas pensei em informar isso.) Além disso, qual dialeto da APL você está usando?
Zacharý 18/08/19
2

Perl 5 , 76 + 1 (-F) = 77 bytes

}{$d+=97**(@F+--$i)*((ord)-(/	|
/?9:30))for@F;say!$d||1+int((log$d)/log 256)

Experimente online!

Quão?

Implicitamente, separe os caracteres da entrada ( -F), armazenando tudo isso em @F. Feche o whileloop implícito e inicie um novo bloco ( }{) ( Obrigado, @Dom Hastings! ). Para cada personagem, multiplique seu valor por 97 para a potência apropriada. Calcule o número de caracteres localizando o tamanho da soma na base 256 usando logaritmos.

Xcali
fonte
1

Ruby , 70 bytes, pontuação 58

->n{x=0;n.bytes{|i|x+=i-(i<32?9:30);x*=97};a=x.to_s(2).size/8;a<1?1:a}

Experimente online!

Value Ink
fonte
1

MATL (19 bytes), pontuação 16

9=?1}G9tQ6Y2hh8WZan

Caracteres não imprimíveis (guia, nova linha) na sequência de entrada são inseridos contatenando seus códigos ASCII ( 9, 10) com o restante da sequência.

A parte inicial 9=?1}Gé necessária apenas devido a um erro na função Za(conversão de base), que causa falha quando a entrada consiste apenas em "zeros" (tabs aqui). Isso será corrigido na próxima versão do idioma.

Explicação

9=      % Implicitly input a string. Compare each entry with 9 (tab)
?       % If all entries were 9
  1     %   Push 1. this will be the ouput
}       % Else
  G     %   Push input string again
  9     %   Push 9 (tab)
  tQ    %   Duplicate, add 1: pushes 10 (newline)
  6Y2   %   Push string of all printable ASCII chars
  hh    %   Concatenate twice. This gives the input alphabet of 97 chars
  8W    %   Push 2 raised to 8, that is, 256. This represents the output
        %   alphabet, interpreted as a range, for base conversion
  Za    %   Base conversion. Gives a vector of byte numbers
  n     %   Length of that vector
        % End (implicit). Display (implicit)
Luis Mendo
fonte
1

Befunge-93, 83 79 bytes, pontuação 74 65

<v_v#-*52:_v#-9:_v#`0:~
 5v$
^6>>1>\"a"* +
 >*- ^   0$<
0_v#:/*4*88\+1\ $<
.@>$

Experimente aqui!

O programa primeiro converte a entrada em um número de base 97 e depois conta quantos dígitos são necessários para um número de base 256. Como tal, o número da base 97 é enorme, tão grande que o TIO produzirá um valor máximo de 8 para valores grandes; no entanto, o interpretador JS não se importa e produzirá o valor correto.


fonte