Alle deine Base 97 gehören uns

18

Viele Programmiersprachen werden ausschließlich mit druckbarem ASCII, Tabulatoren und Zeilenumbrüchen geschrieben. Diese 97 Zeichen werden dann in 8-Bit-Bytes gespeichert (die tatsächlich 256 verschiedene Zeichen aufnehmen können!), Was einfach schrecklich ineffizient ist - insbesondere beim Code-Golfen, bei dem jedes Byte zählt! In dieser Herausforderung können Sie Ihre Punktzahl mithilfe der Basiskonvertierung reduzieren.

Herausforderung

Ihr Programm / Ihre Funktion verwendet eine Zeichenfolge oder ein Zeichenarray als Eingabe, die dann als Base-97- Zahl interpretiert wird . Es konvertiert dies dann in eine Basis-256- Zahl und zählt die Anzahl der Symbole (dh Bytes), die erforderlich sind, um diese Zahl darzustellen. Diese Anzahl ist der Ausgabe- / Rückgabewert Ihres Programms / Ihrer Funktion.

Ein einfaches Beispiel mit base-2 und base-10 (binär und dezimal): Wenn die Eingabe ist 10110, wäre die Ausgabe 2, da 10110 2 = 22 10 (zwei Ziffern zur Darstellung der Ausgabe erforderlich). In ähnlicher Weise wird 1101 2 zu 13 10 , was ebenfalls eine Ausgabe von 2 ergibt, und 110 2 wird zu 6 10 , so dass die Ausgabe 1 wäre.

Der Eingabestring kann alle 95 druckbaren ASCII - Zeichen enthält, sowie Newline \nund wörtliche Registerkarte \t, die eine schafft Quelle Alphabet von 97 Symbolen für Ihre Basis - Konvertierung. Das genaue Alphabet lautet daher (ersetzen Sie das \tund \ndurch das eigentliche Literal-Tab und die neue Zeile; beachten Sie das Literal-Leerzeichen nach der neuen Zeile) :

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

Beachten Sie, dass die Reihenfolge dieses Alphabets wichtig ist: Zum Beispiel \tentspricht base-97 der Dezimalzahl 0und !entspricht der Dezimalzahl 3.

Einige Testfälle: (Sie müssen keine leere Zeichenfolge verarbeiten)

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)

Wertung

  1. Wenn Ihr Eintrag nur druckbares ASCII, Zeilenvorschub und / oder Tabulator verwendet: Die Punktzahl Ihres Programms ist die Ausgabe Ihres Programms, wenn als Eingabe ein eigener Quellcode angegeben wird.

  2. Wenn Ihre Eingabe Zeichen enthält, die nicht in ASCII, Newline oder Tab gedruckt werden können: Die Punktzahl Ihres Programms entspricht einfach der Anzahl der Bytes, wie dies beim Fall ist .

Sanchises
quelle
3
Wenn Sie einen besseren Titelvorschlag als dieses veraltete Mem haben , können Sie ihn gerne in den Kommentaren veröffentlichen!
Sanchises
Wussten Sie, dass diese Herausforderung mit einer sprachlichen Antwort gewonnen werden kann, die nur aus Tabs besteht?
Paprika
@ppperry Um ehrlich zu sein, ich habe sehr wenig Geduld für solche Antworten. Ja, ich habe das erkannt, aber bis jemand das Programm tatsächlich auf seinem System speichern kann, wird es nicht meine Zustimmung finden.
Sanchises

Antworten:

7

Python 2 , Punktzahl 73 72 71

Edit: -1 danke an @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

Probieren Sie es online!

Halvard Hummel
quelle
Nur eines /sollte in Ordnung sein, denke ich
Jonathan Allan
or 1kann |1in diesem Fall durch ersetzt werden.
Jonathan Allan
1
@ JonathanAllan Das ergibt unterschiedliche (falsche) Ergebnisse.
Sanchises
Oh, ja, es wird>. <- Ich dachte, ich bekomme dort nur eine Null, aber es wird bitweise oder mit den anderen Zahlen auch.
Jonathan Allan
@ JonathanAllan Genau. Es funktioniert bei ungeraden Ergebnissen, aber es addiert eins zu geraden Ergebnissen.
Sanchises
5

Japt , Punktzahl 19 (23 Bytes)

nHo127 uA9 md)sG l /2 c

Online testen!

Zufällig glaube ich, dass dies auch mit Nicht-ASCII-Zeichen nicht viel zu tun hat ...

Erläuterung

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
quelle
5

Jelly ,  18  17 Bytes - Ergebnis  18  17

-1 byte dank Erik the Outgolfer (keine Liste von Listen für die Übersetzung nötig)

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

Probieren Sie es online!

Wie?

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

- Das Beste, was ich nur mit ASCII habe, ist eine Punktzahl von 29 :

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

- das ist auch extrem ineffizient. Es übersetzt die Ordnungszahlen wie oben, aber die Umrechnung von der Basis 97 erfolgt durch Wiederholen der Werte und Summieren, anstatt durch direkte Multiplikation. Das heißt, bei der Umrechnung werden {".~"}.~die angepassten Indizes abgerufen, [93,4,16,96,4,95,16,96]dann umgekehrt ( U) und wiederholt, um zu bilden [[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]]und dann zu summieren. konvertiert auf Basis 256 und erhält die Länge (wenn der Speicher nicht voll ist: p).

Jonathan Allan
quelle
3

J , 36 Bytes, Score = 30

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

Probieren Sie es online!

J verwendet nur die 7-Bit-ASCII-Zeichen für seine Grundelemente.

Erläuterung

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
Meilen
quelle
3

Gaia , 14 Bytes, Punktzahl 14

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

Probieren Sie es online!

Erläuterung

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.

Nur ASCII

Dies ist das Beste, was ich nur mit ASCII finden konnte, was eine Punktzahl von 19 ergibt:

9c10c8373c'R+e]$;B256Bl

Die Schwierigkeit liegt in der Umwandlung der Eingabe. Die einzige vernünftige Möglichkeit zur Konvertierung vom Base-97-System ist die Verwendung B, da für die Zuordnung Nicht-ASCII-Zeichen erforderlich sind ¦. Darüber hinaus gibt es derzeit keine Möglichkeit, einen Zeichenbereich zu erstellen, ohne ceinen Zahlenbereich zuzuordnen, was dasselbe Problem verursacht. Die beste Lösung, die ich sehen konnte, bestand darin, die Zeichenfolge zu konstruieren ₵Rund zu bewerten.

Geschäfts-Katze
quelle
Haben Sie versucht, eine reine ASCII-Version davon zu erstellen? Es kann sein, dass sich Ihre Punktzahl nicht verbessert (ich nehme an, ₵Rund ₵res ist nicht leicht zu ersetzen, obwohl es offensichtlich ist), aber es kann interessant sein, zu sehen, wie es verglichen wird.
Sanchises
@Sanchises Ich habe es getan, aber das kürzeste, das ich herausgefunden habe, war 19, da es sich um Code-Punkt 8373 handelt und ich auch keine Zeichenbereiche nur in ASCII ausführen kann, was ein wenig frustrierend ist, da der größte Teil dieses Programms ASCII ist.
Business Cat
Ja, es ist wirklich nahe daran, nur ASCII zu sein. Kurze Frage: Ich kenne Gaia nicht, habe aber gerade ein bisschen damit herumgespielt, aber gibt es eine Möglichkeit, eine Liste von Zahlen umzuwandeln? (wie caber auf jedes Zeichen angewendet, $zeigt nur alle Zahlen)
Sanchises
@Sanchises Sie müssten cüber die Liste abbilden , das wäre
Business Cat
Eigentlich ₵rist es einfach zu ersetzen, da ich es einfach verwenden könnte 256. Ich habe es nur verwendet, weil es 1 Byte kürzer ist und das Programm sowieso nicht nur ASCII war.
Business Cat
3

Python 2 , Punktzahl 60

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

Probieren Sie es online!

Zuordnung zu Base-97

Der Wert eines Zeichens ergibt sich aus ord(c)-[30,9][c<' ']: seinem ASCII-Code, minus 9 für Tabulatoren und Zeilenumbrüche (die ' 'lexikografisch vorangestellt sind ) oder minus 30 für alles andere.

Umwandlung in eine Zahl

Wir verwenden reduce, um den String in eine Zahl umzuwandeln. Dies entspricht dem Rechnen

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

Berechnen der Base-256-Länge

Der Rückgabewert von binist ein String, der ungefähr so ​​aussieht:

"0b10101100111100001101"

Nenne seine Länge L. Ein Wert mit einer n-bit-Binärdarstellung hat eine ceil(n/8)-bit-Basis-256-Darstellung. Wir können berechnen nals L-2; Auch ceil(n/8)kann geschrieben werden floor((n+7)/8)= n+7>>3, so ist unsere Antwort L-2+7>>3= L+5>>3.

Der Fall, dass die Eingabezeichenfolge den Wert 0 hat, wird als binRückgabe korrekt behandelt "0b0", sodass wir 3+5>>3= 1 zurückgeben.

Lynn
quelle
64
Halvard Hummel
@HalvardHummel ziemlich sicher, dass es sein sollte, c>=' 'oder Sie ordnen 23 statt 2 Leerzeichen zu. In normalem Code c>'\x1f'hätte mir Golf (ein Rohbyte) geholfen, aber das ist nicht druckbar ASCII ...
Lynn
Sie haben recht, mein böser
Halvard Hummel
2

APL, Punktzahl 24 (Bytes *)

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

Nimmt die Standardeinstellung an ⎕IO←1, andernfalls ändern Sie einfach ¯31 zu ¯30.

Erläuterung:

                   ⎕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

Beispiele:

      ⌈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 kann ⎕AVanstelle von Unicode in einem eigenen (von definierten ) älteren Zeichensatz geschrieben werden . Daher kann ein APL-Programm, das nur ASCII-Zeichen und APL-Symbole verwendet, mit 1 Zeichen = 1 Byte bewertet werden.

Tobia
quelle
Nicht alle APL-Symbole sind in ⎕AV(zumindest für Dyalog), wie z . Alle Ihre Symbole zählen jedoch jeweils als ein Byte. Also nicht jedes APL-Symbol = 1 Byte, wie Sie in der Fußnote angeben. (Ich dachte nur, ich würde es dich wissen lassen.) Und welchen APL-Dialekt verwendest du?
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)

Probieren Sie es online!

Wie?

Trennen Sie implizit die Zeichen der Eingabe ( -F), und speichern Sie alles in @F. Schließen Sie die implizite whileSchleife und starten Sie einen neuen Block ( }{) ( Danke, @Dom Hastings! ). Multiplizieren Sie für jedes Zeichen seinen Wert mit 97, um die entsprechende Potenz zu erhalten. Berechnen Sie die Anzahl der Zeichen, indem Sie die Größe der Summe in der Basis 256 mithilfe von Logarithmen ermitteln.

Xcali
quelle
1

Ruby , 70 Bytes, 58 Punkte

->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}

Probieren Sie es online!

Wert Tinte
quelle
1

MATL (19 Bytes), Punktzahl 16

9=?1}G9tQ6Y2hh8WZan

Nicht druckbare Zeichen (Tabulator, Zeilenvorschub) in der Eingabezeichenfolge werden durch Verketten ihrer ASCII-Codes ( 9, 10) mit dem Rest der Zeichenfolge eingegeben .

Der erste Teil 9=?1}Gist nur wegen eines Fehlers in der Funktion Za(Basiskonvertierung) erforderlich , der zum Fehlschlagen führt, wenn die Eingabe nur aus "Nullen" besteht (hier Tabulatoren). Es wird in der nächsten Version der Sprache behoben.

Erläuterung

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

Befunge-93, 83 79 Bytes, Ergebnis 74 65

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

Probieren Sie es hier aus!

Das Programm konvertiert zuerst die Eingabe in eine Basis-97-Zahl und zählt dann, wie viele Stellen für eine Basis-256-Zahl erforderlich sind. Daher ist die Zahl der Basis 97 sehr groß, sodass TIO für große Werte einen Maximalwert von 8 ausgibt. Der JS-Interpreter kümmert sich jedoch nicht darum und gibt den korrekten Wert aus.


quelle