Wszystkie twoje bazy 97 należą do nas

18

Wiele języków programowania jest pisanych przy użyciu wyłącznie ASCII, zakładek i znaków nowej linii do wydruku. Te 97 znaków jest następnie zapisywanych w 8-bitowych bajtach (które są w stanie pomieścić 256 różnych znaków!), Co jest po prostu strasznie nieefektywne - szczególnie w grze w golfa, gdzie liczy się każdy bajt! W tym wyzwaniu będziesz w stanie obniżyć swój wynik za pomocą konwersji podstawowej.

Wyzwanie

Twój program / funkcja pobiera ciąg znaków lub tablicę znaków jako dane wejściowe, które następnie interpretuje jako liczbę podstawową 97 . Następnie konwertuje to na liczbę podstawową 256 i zlicza liczbę symboli (tj. Bajtów) niezbędnych do przedstawienia tej liczby. Liczba ta będzie wartością wyjściową / zwracaną przez twój program / funkcję.

Prosty przykład z użyciem base-2 i base-10 (binarny i dziesiętny): jeśli wejście jest 10110, wyjście będzie 2, ponieważ 10110 2 = 22 10 (dwie cyfry potrzebne do przedstawienia wyjścia). Podobnie 1101 2 staje się 13 10 , co daje również wynik 2, a 110 2 staje się 6 10 , więc wtedy wynik wyniósłby 1.

Ciąg wejściowy może zawierać wszystkie 95 znaków ASCII do wydrukowania, a także \ntabulację nowego wiersza i literału \t, która tworzy alfabet źródłowy 97 symboli dla konwersji podstawowej. Dokładna alfabet będzie zatem (zastępując \toraz \nz rzeczywistego karcie dosłownym i nowa linia; uwaga dosłowne następujące miejsca w nowej linii) :

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

Zauważ, że kolejność tego alfabetu jest ważna: na przykład base-97 \todpowiada dziesiętnej 0i !dziesiętnej 3.

Niektóre przypadki testowe: (nie musisz obsługiwać pustego ciągu)

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)

Punktacja

  1. Jeśli twój wpis używa tylko ASCII do wydruku, nowej linii i / lub tab: Wynik twojego programu będzie wyjściem twojego programu, jeśli podasz własny kod źródłowy jako dane wejściowe.

  2. Jeśli twój wpis używa znaków, które nie są drukowalne ASCII, nowej linii lub tabulacji: Wynik twojego programu to po prostu liczba bajtów, jak w .

Sanchises
źródło
3
Jeśli masz lepszą propozycję tytułu niż ten przestarzały mem , opublikuj go w komentarzach!
Sanchises
Czy zdałeś sobie sprawę, że to wyzwanie można wygrać dzięki odpowiedzi typu lenguage składającej się tylko z zakładek
pppery
@ppperry Szczerze mówiąc, mam bardzo mało cierpliwości do takich odpowiedzi. Tak, zdałem sobie z tego sprawę, ale dopóki ktoś nie będzie mógł przechowywać programu w swoim systemie, nie otrzymam mojej opinii.
Sanchises

Odpowiedzi:

7

Python 2 , wynik 73 72 71

Edycja: -1 dzięki @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

Wypróbuj online!

Halvard Hummel
źródło
/myślę, że tylko jedna powinna być OK
Jonathan Allan
or 1|1w tym przypadku może zostać zastąpione przez
Jonathan Allan
1
@JonathanAllan To daje różne (złe) wyniki.
Sanchises
Och, tak, będzie>. <- myślałem, że dostanie tylko zero, ale będzie bitowe lub z innymi liczbami.
Jonathan Allan
@JonathanAllan Dokładnie. Będzie działać dla nieparzystych wyników, ale doda jeden do parzystych wyników.
Sanchises
5

Japt , wynik 19 (23 bajtów)

nHo127 uA9 md)sG l /2 c

Przetestuj online!

Zbiegiem okoliczności, nie sądzę, że można w nią grać w golfa nawet przy znakach spoza ASCII ...

Wyjaśnienie

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
ETHprodukcje
źródło
5

Galaretka ,  18  17 bajtów - wynik  18  17

-1 bajt dzięki Erik the Outgolfer (nie ma potrzeby listy list do tłumaczenia)

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

Wypróbuj online!

W jaki sposób?

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

- Najlepsze, co mam tylko z ASCII, to wynik 29 :

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

- jest to również wyjątkowo nieefektywne. Tłumaczy porządki jak wyżej, ale konwersję z bazy 97 uzyskuje się przez powtórzenie wartości i sumowanie, zamiast bezpośredniego mnożenia - to znaczy do konwersji {".~"}.~, dostaje skorygowane indeksy, [93,4,16,96,4,95,16,96]następnie odwraca ( U) i powtarza je, aby wykonać, [[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]]a następnie sumuje, konwertuje na bazę 256 i pobiera długość (jeśli nie zabrakło jej pamięci: p).

Jonathan Allan
źródło
3

J , 36 bajtów, wynik = 30

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

Wypróbuj online!

J używa tylko 7-bitowych znaków ASCII w swoich operacjach podstawowych.

Wyjaśnienie

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
mile
źródło
3

Gaia , 14 bajtów, wynik 14

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

Wypróbuj online!

Wyjaśnienie

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.

Tylko ASCII

To najlepsze, co mogłem wymyślić używając tylko ASCII, dając wynik 19:

9c10c8373c'R+e]$;B256Bl

Trudność polega na konwersji danych wejściowych. Jedynym rozsądnym sposobem konwersji z systemu base-97 jest użycie B, ponieważ mapowanie wymaga kodu innego niż ASCII ¦. Ponadto, obecnie nie ma sposobu na stworzenie zasięgu postaci bez mapowania cna zakres liczbowy, który ma ten sam problem. Najlepszym rozwiązaniem, jakie mogłem zobaczyć, było skonstruowanie łańcucha ₵Ri sprawdzenie go.

Business Cat
źródło
Czy próbowałeś stworzyć wersję ASCII? To może nie poprawić twojego wyniku (przypuszczam ₵Ri ₵rnie są łatwe do zastąpienia, choć oczywiście jest), ale może być interesujące zobaczyć, jak to się porównuje.
Sanchises
@Sanchises zrobiłem, ale najkrótszy, jaki wymyśliłem, skończył 19 lat, ponieważ jest to kod 8373 i nie mogę również wykonywać zakresów znaków tylko w ASCII, co jest nieco frustrujące, ponieważ większość tego programu to ASCII.
Business Cat
Tak, jest naprawdę blisko bycia tylko ASCII. Szybkie pytanie: nie znam Gaii, ale bawiłem się nią trochę teraz, ale czy istnieje sposób na konwersję listy liczb? (jak, cale zastosowane do każdej postaci, $pokazuje tylko wszystkie liczby)
Sanchises
@ Sanchises Musiałbyś zmapować clistę, która byłaby
Business Cat
W rzeczywistości ₵rjest łatwa do wymiany, ponieważ mógłbym po prostu użyć 256zamiast tego, użyłem tego tylko, ponieważ jest o 1 bajt krótszy, a program i tak nie był tylko ASCII.
Business Cat
3

Python 2 , ocena 60

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

Wypróbuj online!

Mapowanie do base-97

Wartość znaku jest uzyskiwana przez ord(c)-[30,9][c<' ']: jego kod ASCII, minus 9 dla tabulatorów i znaków nowej linii (które poprzedzają ' 'leksykograficznie) lub minus 30 dla wszystkiego innego.

Konwersja na liczbę

Używamy reducedo konwersji ciągu na liczbę. Jest to równoważne z przetwarzaniem

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

Podstawa obliczeniowa-256 długości

Zwracana wartość binto ciąg znaków, który wygląda mniej więcej tak:

"0b10101100111100001101"

Nazwij jego długość L. Wartość z n-bitową reprezentacją binarną ma reprezentację ceil(n/8)-bit base-256. Możemy obliczyć njako L-2; również ceil(n/8)można zapisać jako floor((n+7)/8)= n+7>>3, więc naszą odpowiedzią jest L-2+7>>3= L+5>>3.

Przypadek, w którym łańcuch wejściowy ma wartość 0, jest obsługiwany poprawnie, ponieważ binzwraca "0b0", więc zwracamy 3+5>>3= 1.

Lynn
źródło
64
Halvard Hummel
@HalvardHummel całkiem pewny, że powinien, c>=' 'bo inaczej odwzorujesz przestrzeń na 23 zamiast 2. W zwykłym kodzie golfowym c>'\x1f'(surowy bajt) pomógłby mi, ale to nie jest drukowalne ASCII…
Lynn
Masz rację, mój zły
Halvard Hummel
2

APL, wynik 24 (bajtów *)

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

Zakłada wartość domyślną ⎕IO←1, w przeciwnym razie wystarczy zmienić ¯31 na ¯30.

Wyjaśnienie:

                   ⎕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

Przykłady:

      ⌈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 można zapisać we własnym starszym ⎕AVzestawie znaków (zdefiniowanym przez ) zamiast w Unicode; dlatego program APL, który używa tylko znaków ASCII i symboli APL, może zostać oceniony jako 1 znak = 1 bajt.

Tobia
źródło
Nie wszystkie symbole APL są w ⎕AV(przynajmniej dla Dyalog), takie jak . Wszystkie twoje symbole liczą się jednak jako jeden bajt. Tak więc nie każdy symbol APL = 1 bajt, jak podano w przypisie. (Pomyślałem, że dam ci znać.) Z którego dialektu APL korzystasz?
Zacharý
2

Perl 5 , 76 + 1 (-F) = 77 bajtów

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

Wypróbuj online!

W jaki sposób?

Niejawnie oddziel znaki wejściowe ( -F), przechowując je w @F. Zamknij niejawną whilepętlę i uruchom nowy blok ( }{) ( Dzięki, @Dom Hastings! ). Dla każdej postaci pomnóż jej wartość przez 97 do odpowiedniej mocy. Oblicz liczbę znaków, znajdując wielkość sumy w podstawie 256, używając logarytmów.

Xcali
źródło
1

Rubinowy , 70 bajtów, wynik 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}

Wypróbuj online!

Wartość tuszu
źródło
1

MATL (19 bajtów), wynik 16

9=?1}G9tQ6Y2hh8WZan

Znaki niedrukowalne (tab, znak nowej linii) w ciągu wejściowym wprowadza się, łącząc ich kody ASCII ( 9, 10) z resztą ciągu.

Część początkowa 9=?1}G jest konieczna tylko z powodu błędu w funkcji Za(konwersji podstawowej), który powoduje, że kończy się ona niepowodzeniem, gdy dane wejściowe składają się tylko z „zer” (tabulatory tutaj). Zostanie to naprawione w następnej wersji języka.

Wyjaśnienie

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
źródło
1

Befunge-93, 83 79 bajtów, wynik 74 65

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

Wypróbuj tutaj!

Program najpierw konwertuje dane wejściowe na liczbę base-97, a następnie liczy, ile cyfr jest wymaganych dla liczby base-256. W związku z tym liczba podstawowa 97 jest ogromna, tak duża, że ​​TIO wyświetli maksymalną wartość 8 dla dużych wartości; jednak interpreter JS nie dba o to i wyświetli poprawną wartość.


źródło