Toutes vos bases 97 nous appartiennent

18

De nombreux langages de programmation sont écrits en utilisant uniquement ASCII imprimable, des onglets et des nouvelles lignes. Ces 97 caractères sont ensuite stockés dans des octets de 8 bits (qui sont en fait capables de contenir 256 caractères différents!), Ce qui est terriblement inefficace - en particulier dans le code-golf, où chaque octet compte! Dans ce défi, vous pourrez réduire votre score en utilisant la conversion de base.

Défi

Votre programme / fonction prend une chaîne ou un tableau de caractères en entrée, qu'il interprète ensuite comme un nombre en base 97 . Il convertit ensuite cela en un nombre de base 256 et compte le nombre de symboles (c'est-à-dire d'octets) nécessaires pour représenter ce nombre. Ce nombre sera la valeur de sortie / retour de votre programme / fonction.

Un exemple simple utilisant base-2 et base-10 (binaire et décimal): si l'entrée est 10110, la sortie serait 2, puisque 10110 2 = 22 10 (deux chiffres nécessaires pour représenter la sortie). De même, 1101 2 devient 13 10 , ce qui donne également une sortie de 2, et 110 2 devient 6 10 , donc la sortie serait 1.

La chaîne d'entrée peut contenir les 95 caractères ASCII imprimables, ainsi que la nouvelle ligne \net l'onglet littéral \t, ce qui crée un alphabet source de 97 symboles pour votre conversion de base. L'alphabet exact sera donc (en remplaçant le \tet \npar l'onglet littéral réel et la nouvelle ligne; notez l'espace littéral suivant la nouvelle ligne) :

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

Notez que l'ordre de cet alphabet est important: par exemple, la base-97 \tcorrespond à la décimale 0et !correspond à la décimale 3.

Quelques tests: (vous n'avez pas besoin de gérer une chaîne vide)

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)

Notation

  1. Si votre entrée utilise uniquement ASCII imprimable, nouvelle ligne et / ou onglet: Le score de votre programme sera la sortie de votre programme, lorsqu'il recevra son propre code source en entrée.

  2. Si votre entrée utilise des caractères non imprimables ASCII, saut de ligne ou tabulation: le score de votre programme est simplement le nombre d'octets, comme dans .

Sanchises
la source
3
Si vous avez une meilleure suggestion de titre que ce mème obsolète , n'hésitez pas à le poster dans les commentaires!
Sanchises
Saviez-vous que ce défi pouvait être remporté avec une réponse en langue composée uniquement d'onglets.
pppery
@ppperry Pour être honnête, j'ai très peu de patience pour de telles réponses. Oui, je m'en suis rendu compte, mais tant que quelqu'un ne pourra pas réellement stocker le programme sur son système, cela n'obtiendra pas mon vote positif.
Sanchises

Réponses:

7

Python 2 , score 73 72 71

Edit: -1 grâce à @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

Essayez-le en ligne!

Halvard Hummel
la source
juste un /devrait être OK je pense
Jonathan Allan
or 1peut être remplacé par |1dans ce cas.
Jonathan Allan
1
@JonathanAllan Cela donne des résultats différents (faux).
Sanchises
Oh, ouais ça le fera>. <- pensait que ça n'obtiendrait qu'un zéro mais ça allait au niveau du bit ou avec les autres nombres aussi.
Jonathan Allan
@JonathanAllan Exactement. Cela fonctionnera pour des résultats impairs, mais cela en ajoutera un aux résultats pairs.
Sanchises
5

Japt , score 19 (23 octets)

nHo127 uA9 md)sG l /2 c

Testez-le en ligne!

Par coïncidence, je ne pense pas que cela puisse être joué beaucoup, même avec des caractères non ASCII ...

Explication

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

Gelée ,  18  17 octets - score  18  17

-1 octet grâce à Erik le Outgolfer (pas besoin de liste de listes pour la traduction)

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

Essayez-le en ligne!

Comment?

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

--Le meilleur que j'ai obtenu avec ASCII seulement est un score de 29 :

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

- c'est aussi extrêmement inefficace. Il traduit les ordinaux comme ci-dessus, mais la conversion à partir de la base 97 est obtenue en répétant les valeurs et en sommant, plutôt qu'en utilisant la multiplication directe - c'est-à-dire que pour convertir, {".~"}.~il obtient les index ajustés [93,4,16,96,4,95,16,96]puis inverse ( U) et les répète pour faire [[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]]puis additionner, convertit en base 256 et obtient la longueur (s'il n'a pas manqué de mémoire: p).

Jonathan Allan
la source
3

J , 36 octets, score = 30

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

Essayez-le en ligne!

J utilise uniquement les caractères ASCII 7 bits pour ses primitives.

Explication

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
miles
la source
3

Gaia , 14 octets, score 14

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

Essayez-le en ligne!

Explication

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.

ASCII uniquement

C'est le meilleur que j'ai pu trouver en utilisant uniquement ASCII, ce qui donne un score de 19:

9c10c8373c'R+e]$;B256Bl

La difficulté réside dans la conversion des entrées. La seule façon raisonnable de convertir à partir du système base-97 est d'utiliser B, car le mappage nécessite le non-ASCII ¦. De plus, il n'existe actuellement aucun moyen de créer une plage de caractères sans mapper csur une plage de nombres, ce qui pose le même problème. La meilleure solution que j'ai pu voir était de construire la chaîne ₵Ret de l'évaluer.

Chat d'affaires
la source
Avez-vous essayé d'en créer une version ASCII uniquement? Il ne peut pas améliorer votre score (je suppose ₵Ret ₵rn'est pas facile à remplacer, bien que ce soit évidemment le cas), mais il peut être intéressant de voir comment il se compare.
Sanchises
@Sanchises que j'ai fait, mais le plus court que j'ai trouvé a fini par être 19, car c'est le point de code 8373 et je ne peux pas non plus faire de plages de caractères en ASCII seulement, ce qui est un peu frustrant car la plupart de ce programme est ASCII.
Business Cat
Oui, c'est très proche d'être ASCII uniquement. Question rapide: je ne connais pas Gaia mais je l'ai joué un peu avec tout à l'heure, mais existe-t-il un moyen de convertir une liste de nombres? (comme cmais appliqué à chaque personnage, $montre juste tous les nombres)
Sanchises
@Sanchises Vous devrez cartographier cla liste, ce qui serait
Business Cat
En fait, il ₵rest facile de remplacer car je pourrais simplement l'utiliser à la 256place, je ne l'ai utilisé que parce qu'il est plus court d'un octet et que le programme n'était pas ASCII de toute façon.
Business Cat
3

Python 2 , score 60

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

Essayez-le en ligne!

Correspondance avec la base 97

La valeur d'un caractère est obtenue par ord(c)-[30,9][c<' ']: son code ASCII, moins 9 pour les tabulations et les retours à la ligne (qui précèdent ' 'lexicographiquement), ou moins 30 pour tout le reste.

Conversion en un nombre

Nous utilisons reducepour convertir la chaîne en nombre. C'est équivalent à l'informatique

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

Longueur de base 256 de calcul

La valeur de retour de binest une chaîne qui ressemble un peu à ceci:

"0b10101100111100001101"

Appelez sa longueur L. Une valeur avec une nreprésentation binaire -bit a une représentation en ceil(n/8)base-256 bits. Nous pouvons calculer ncomme L-2; aussi, ceil(n/8)peut être écrit comme floor((n+7)/8)= n+7>>3, notre réponse est L-2+7>>3= L+5>>3.

Le cas où la chaîne d'entrée a la valeur 0 est traité correctement, comme des binretours "0b0", donc nous retournons 3+5>>3= 1.

Lynn
la source
64
Halvard Hummel
@HalvardHummel assez sûr que ce devrait être le cas c>=' 'ou vous mappez l' espace à 23 au lieu de 2. Dans le code ordinaire, le golf c>'\x1f'(un octet brut) m'aurait aidé, mais ce n'est pas ASCII imprimable…
Lynn
Vous avez raison, ma mauvaise
Halvard Hummel
2

APL, score 24 (octets *)

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

Suppose la valeur par défaut ⎕IO←1, sinon changez simplement ¯31 en ¯30.

Explication:

                   ⎕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

Exemples:

      ⌈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 peut être écrit dans son propre jeu de caractères hérité (défini par ⎕AV) au lieu d'Unicode; par conséquent, un programme APL qui utilise uniquement des caractères ASCII et des symboles APL peut être noté comme 1 caractère = 1 octet.

Tobia
la source
Tous les symboles APL ne sont pas ⎕AV(au moins pour Dyalog), tels que . Cependant, tous vos symboles comptent pour un octet chacun. Donc, pas tous les symboles APL = 1 octet comme vous le dites dans la note de bas de page. (Je pensais juste que je vous le ferais savoir.) De plus, quel dialecte APL utilisez-vous?
Zacharý
2

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

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

Essayez-le en ligne!

Comment?

Implicitement, séparez les caractères de l'entrée ( -F), en stockant tout cela dans @F. Fermez la whileboucle implicite et démarrez un nouveau bloc ( }{) ( Merci, @Dom Hastings! ). Pour chaque personnage, multipliez sa valeur par 97 à la puissance appropriée. Calculez le nombre de caractères en trouvant la taille de la somme en base 256 à l'aide de logarithmes.

Xcali
la source
1

Rubis , 70 octets, score 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}

Essayez-le en ligne!

Encre de valeur
la source
1

MATL (19 octets), score 16

9=?1}G9tQ6Y2hh8WZan

Les caractères non imprimables (tabulation, nouvelle ligne) dans la chaîne d'entrée sont entrés en contaténant leurs codes ASCII ( 9, 10) avec le reste de la chaîne.

La partie initiale 9=?1}Gn'est nécessaire qu'en raison d'un bogue dans la fonction Za(conversion de base), ce qui provoque son échec lorsque l'entrée se compose uniquement de "zéros" (onglets ici). Il sera corrigé dans la prochaine version de la langue.

Explication

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

Befunge-93, 83 79 octets, score 74 65

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

Essayez-le ici!

Le programme convertit d'abord l'entrée en un nombre en base 97, puis compte le nombre de chiffres requis pour un nombre en base 256. En tant que tel, le nombre de base 97 est énorme, si grand que TIO produira une valeur maximale de 8 pour les grandes valeurs; cependant, l'interpréteur JS s'en fiche et affichera la valeur correcte.


la source