Toda su base 97 nos pertenece

18

Muchos lenguajes de programación se escriben utilizando únicamente ASCII imprimible, pestañas y líneas nuevas. Estos 97 caracteres se almacenan en bytes de 8 bits (que en realidad son capaces de contener 256 caracteres diferentes), lo cual es terriblemente ineficiente, especialmente en el golf de código, ¡donde cada byte cuenta! En este desafío, podrá reducir su puntaje utilizando la conversión de base.

Desafío

Su programa / función toma una cadena o matriz de caracteres como entrada, que luego interpreta como un número base-97 . Luego convierte esto en un número base-256 y cuenta el número de símbolos (es decir, bytes) necesarios para representar este número. Este conteo será el valor de salida / retorno de su programa / función.

Un ejemplo simple usando base-2 y base-10 (binario y decimal): si la entrada es 10110, la salida sería 2, ya que 10110 2 = 22 10 (dos dígitos necesarios para representar la salida). Del mismo modo, 1101 2 se convierte en 13 10 , dando una salida de 2 también, y 110 2 se convierte en 6 10 , por lo que la salida sería 1.

La cadena de entrada puede contener los 95 caracteres ASCII imprimibles, así como la nueva línea \ny la pestaña literal \t, que crea un alfabeto fuente de 97 símbolos para su conversión base. El alfabeto exacto será (sustituyendo el \ty \ncon la pestaña literal real y la nueva línea; tenga en cuenta el espacio literal que sigue a la nueva línea) :

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

Tenga en cuenta que el orden de este alfabeto es importante: por ejemplo, base-97 \tcorresponde a decimal 0y !corresponde a decimal 3.

Algunos casos de prueba: (no necesita manejar una cadena vacía)

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)

Puntuación

  1. Si su entrada usa solo ASCII imprimible, nueva línea y / o pestaña: La puntuación de su programa será la salida de su programa, cuando se le dé su propio código fuente como entrada.

  2. Si su entrada usa caracteres que no son imprimibles ASCII, nueva línea o tabulación: La puntuación de su programa es simplemente el número de bytes, como en .

Sanchises
fuente
3
Si tiene una sugerencia de título mejor que este meme anticuado , ¡no dude en publicarlo en los comentarios!
Sanchises
¿Te diste cuenta de que este desafío podría ganarse con una respuesta en un idioma que consta de solo pestañas.
pppery
@ppperry Para ser honesto, tengo muy poca paciencia para esas respuestas. Sí, me di cuenta de esto, pero hasta que alguien realmente pueda almacenar el programa en su sistema, no va a obtener mi voto positivo.
Sanchises

Respuestas:

7

Python 2 , puntaje 73 72 71

Editar: -1 gracias 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

Pruébalo en línea!

Halvard Hummel
fuente
solo uno /debería estar bien, creo
Jonathan Allan
or 1puede ser reemplazado con |1en este caso.
Jonathan Allan
1
@JonathanAllan Eso arroja resultados diferentes (incorrectos).
Sanchises
Oh, sí, lo hará>. <- estaba pensando que solo obtendría un cero allí, pero también será bit a bit o con los otros números.
Jonathan Allan
@ JonathanAllan Exactamente. Funcionará para resultados impares, pero agregará uno a los resultados pares.
Sanchises
5

Japt , puntaje 19 (23 bytes)

nHo127 uA9 md)sG l /2 c

¡Pruébalo en línea!

Por coincidencia, no creo que esto pueda jugarse mucho incluso con personajes no ASCII ...

Explicación

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
ETHproducciones
fuente
5

Jelly ,  18  17 bytes - puntaje  18  17

-1 byte gracias a Erik the Outgolfer (no es necesario tener una lista de listas para la traducción)

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

Pruébalo en línea!

¿Cómo?

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

- Lo mejor que tengo con ASCII solo es un puntaje de 29 :

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

- Esto también es extremadamente ineficiente. Traduce los ordinales como arriba, pero la conversión de la base 97 se logra repitiendo los valores y sumando, en lugar de usar la multiplicación directa; es decir, al convertir {".~"}.~, obtiene los índices ajustados, [93,4,16,96,4,95,16,96]luego los invierte ( U) y los repite para hacer [[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]]y luego sumas, se convierte en base 256 y obtiene la longitud (si no se ha quedado sin memoria: p).

Jonathan Allan
fuente
3

J , 36 bytes, puntaje = 30

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

Pruébalo en línea!

J usa solo los caracteres ASCII de 7 bits para sus primitivas.

Explicación

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
millas
fuente
3

Gaia , 14 bytes, puntaje 14

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

Pruébalo en línea!

Explicación

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.

Solo ASCII

Esto es lo mejor que se me ocurre usando solo ASCII, dando una puntuación de 19:

9c10c8373c'R+e]$;B256Bl

La dificultad está en la conversión de entrada. La única forma razonable de convertir desde el sistema base-97 es usar B, ya que la asignación requiere el no ASCII ¦. Además, actualmente no hay una manera de hacer un rango de caracteres sin mapear cen un rango de números, que sufre el mismo problema. La mejor solución que pude ver fue construir la cadena ₵Ry evaluarla.

Gato de negocios
fuente
¿Intentaste hacer una versión ASCII única de esto? Es posible que no mejore su puntaje (supongo ₵Ry ₵rno es fácil de reemplazar, aunque obviamente lo es), pero puede ser interesante ver cómo se compara.
Sanchises
@Sanchises que hice, pero el más corto que se me ocurrió terminó siendo 19, ya que es el punto de código 8373 y tampoco puedo hacer rangos de caracteres en ASCII, lo cual es un poco frustrante ya que la mayoría de este programa es ASCII.
Business Cat
Sí, está muy cerca de ser solo ASCII. Pregunta rápida: No conozco a Gaia, pero jugué un poco con ella en este momento, pero ¿hay alguna forma de convertir una lista de números? (como cpero aplicado a cada personaje, $solo muestra todos los números)
Sanchises
@Sanchises Tendrías que mapear csobre la lista, que sería
Business Cat
En realidad, ₵res fácil de reemplazar, ya que podría usarlo 256en su lugar, solo lo usé porque es 1 byte más corto y el programa no era ASCII solo de todos modos.
Business Cat
3

Python 2 , puntaje 60

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

Pruébalo en línea!

Asignación a base-97

El valor de un carácter se obtiene mediante ord(c)-[30,9][c<' ']: su código ASCII, menos 9 para pestañas y líneas nuevas (que preceden ' 'lexicográficamente), o menos 30 para todo lo demás.

Convertir a un número

Usamos reducepara convertir la cadena en un número. Esto es equivalente a la computación

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

Base de cómputo de longitud 256

El valor de retorno de bines una cadena, que se parece a esto:

"0b10101100111100001101"

Llama a su longitud L. Un valor con una nrepresentación binaria -bit tiene una representación ceil(n/8)-bit base-256. Podemos calcular ncomo L-2; también, ceil(n/8)se puede escribir como floor((n+7)/8)= n+7>>3, entonces nuestra respuesta es L-2+7>>3= L+5>>3.

El caso en el que la cadena de entrada tiene el valor 0 se maneja correctamente, como binretornos "0b0", por lo que retornamos 3+5>>3= 1.

Lynn
fuente
64
Halvard Hummel
@HalvardHummel está bastante seguro de que debería ser c>=' 'o de lo contrario mapearía el espacio a 23 en lugar de 2. En el código ordinario, el golf c>'\x1f'(un byte sin procesar) me habría ayudado, pero eso no es ASCII imprimible ...
Lynn
Tienes razón, mi mal
Halvard Hummel
2

APL, puntaje 24 (bytes *)

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

Asume el valor predeterminado ⎕IO←1, de lo contrario simplemente cambie ¯31 a ¯30.

Explicación:

                   ⎕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

Ejemplos:

      ⌈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 se puede escribir en su propio juego de caracteres heredado (definido por ⎕AV) en lugar de Unicode; por lo tanto, un programa APL que solo usa caracteres ASCII y símbolos APL puede puntuarse como 1 char = 1 byte.

Tobia
fuente
No todos los símbolos APL están en ⎕AV(al menos para Dyalog), como . Sin embargo, todos sus símbolos cuentan como un byte cada uno. Por lo tanto, no todos los símbolos APL = 1 byte como dice en la nota al pie. (Solo pensé que te lo haría saber.) Además, ¿qué dialecto APL estás usando?
Zacharý
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)

Pruébalo en línea!

¿Cómo?

Implícitamente, separe los caracteres de la entrada ( -F), almacenando todo eso en @F. Cierre el whilebucle implícito y comience un nuevo bloque ( }{) (¡ Gracias, @Dom Hastings! ). Para cada personaje, multiplique su valor por 97 al poder apropiado. Calcule el número de caracteres encontrando el tamaño de la suma en base 256 usando logaritmos.

Xcali
fuente
1

MATL (19 bytes), puntaje 16

9=?1}G9tQ6Y2hh8WZan

Los caracteres no imprimibles (tabulación, nueva línea) en la cadena de entrada se ingresan contactando sus códigos ASCII ( 9, 10) con el resto de la cadena.

La parte inicial 9=?1}Gsolo es necesaria debido a un error en la función Za(conversión de base), que hace que falle cuando la entrada solo consta de "ceros" (pestañas aquí). Se solucionará en la próxima versión del idioma.

Explicación

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
fuente
1

Befunge-93, 83 79 bytes, puntaje 74 65

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

Pruébalo aquí!

El programa primero convierte la entrada a un número base-97, y luego cuenta cuántos dígitos se requieren para un número base-256. Como tal, el número base-97 es enorme, tan grande que TIO generará un valor máximo de 8 para valores grandes; sin embargo, al intérprete JS no le importa y generará el valor correcto.


fuente