Zróbmy trochę „enciph5r47g”

35

To jest odwrotność Let's do some „deciph4r4ng”


W tym wyzwaniu Twoim zadaniem jest zaszyfrowanie łańcucha. Na szczęście algorytm jest dość prosty: odczytywanie od lewej do prawej, każdy typowy znak pisania (zakres ASCII 32-126) musi być zastąpiony liczbą N (0-9), aby wskazać, że jest taki sam jak znak N + 1 pozycje przed nim. Wyjątkiem jest sytuacja, gdy znak nie pojawia się na poprzednich 10 pozycjach w oryginalnym ciągu. W takim przypadku powinieneś po prostu wydrukować znak ponownie. Skutecznie powinieneś być w stanie odwrócić operację od pierwotnego wyzwania.

Przykład

Łańcuch wejściowy "Programming"zostałby zakodowany w następujący sposób:

Przykład 1

Dlatego oczekiwany wynik to "Prog2am0in6".

Wyjaśnienia i zasady

  • Łańcuch wejściowy będzie zawierał wyłącznie znaki ASCII w zakresie od 32 do 126. Możesz założyć, że nigdy nie będzie pusty.
  • Oryginalny ciąg nie może zawierać żadnej cyfry.
  • Po zakodowaniu znaku można do niego odwoływać się kolejna cyfra. Na przykład "alpaca"należy zakodować jako "alp2c1".
  • Odnośniki nigdy nie będą owijać się wokół łańcucha: można odwoływać się tylko do poprzednich znaków.
  • Możesz napisać pełny program lub funkcję, która wydrukuje lub wyświetli wynik.
  • To jest kod golfowy, więc wygrywa najkrótsza odpowiedź w bajtach.
  • Standardowe luki są zabronione.

Przypadki testowe

Input : abcd
Output: abcd

Input : aaaa
Output: a000

Input : banana
Output: ban111

Input : Hello World!
Output: Hel0o W2r5d!

Input : this is a test
Output: this 222a19e52

Input : golfing is good for you
Output: golfin5 3s24o0d4f3r3y3u

Input : Programming Puzzles & Code Golf
Output: Prog2am0in6 Puz0les7&1Cod74G4lf

Input : Replicants are like any other machine. They're either a benefit or a hazard.
Output: Replicants 4re3lik448ny3oth8r5mac6in8.8T64y'r371it9376a1b5n1fit7or2a1h2z17d.
Inżynier Toast
źródło
6
Widzę, że twoje przypadki testowe zawsze używają najniższej możliwej cyfry dla każdej zamiany. Czy jest to wymagane zachowanie, czy też możemy użyć wyższych cyfr, jeśli istnieje więcej niż jedna możliwość?
Lew
@Leo Możesz użyć dowolnej cyfry 0-9, o ile jest poprawna.
Inżynier Toast
To jest jak enkoder z przejściem na przód , tyle że bez ruchu :)
rura

Odpowiedzi:

6

05AB1E , 20 19 18 bajtów

-2 Dzięki Emigna

õ¹vDyåiDykëy}?yìT£

Wypróbuj online!

õ                  # Push an empty string
 ¹v y              # For each character in input
   D               # Duplicate the string on the stack (call this S)
     åi            # If this character is in S
       Dyk         #   Push the index of that that character 
          ë }      # Else
           y       #   Push the character 
             ?     # Print without newline
              yì   # Prepend this character to S
                T£ # Remove all but the first 10 elements from S
Riley
źródło
Myślę, że również )¹vDyåiDykëy}?y¸ìT£działa.
Emigna,
Właściwie połączenie odpowiedzi z moją daje õIvDyåiDykëy}?yìT£18)
Emigna,
@Emigna Zapraszam do aktualizacji z tym :)
Riley,
Nie pomyślałbym o tym, gdyby nie twoja odpowiedź, więc powinieneś ją mieć. Dobra robota!
Emigna,
@Emigna Chyba to fair. Dzięki!
Riley,
12

Siatkówka , 24 23 bajty

(.)(?<=\1(.{0,9}).)
$.2

Wypróbuj online!

Dość prosta podstawienie wyrażenia regularnego. Dopasowujemy każdy znak i staramy się znaleźć jego kopię 0-9 znaków przed nim. Jeśli go znajdziemy, zastępujemy go liczbą znaków, które musieliśmy dopasować, aby dostać się do kopii.

Wyniki nie do końca pasują do przypadków testowych, ponieważ ta używa największej możliwej cyfry zamiast najmniejszej możliwej.

Martin Ender
źródło
4
Oszukiwanie o zmiennej długości to oszustwo: p
Dada,
8
@Dada Zmienny lookbehind to sposób oświecenia.
Martin Ender,
Niestety jest ... Jeśli się nudzisz, możesz je wdrożyć w Perlu!
Dada,
Zgodnie z komentarzem OP do pierwotnego zadania: „Możesz użyć dowolnej cyfry 0-9, o ile jest ona ważna.” ... tak duża, jak to możliwe, powinna być ważna
Doktor J
@DoktorJ tak, zmieniłem to po dodaniu przez OP tego wyjaśnienia.
Martin Ender,
8

JavaScript (ES6), 74 57 54 bajtów

Oszczędność 3 bajtów dzięki produktom ETH z genialnym p=/./gzamiast p={}(zainspirowany Neilem)

s=>s.replace(p=/./g,(c,i)=>(i=p[c]-(p[c]=i))>-11?~i:c)

Przypadki testowe

Arnauld
źródło
Ponieważ gwarantuje się, że ciąg nie będzie zawierał cyfry, możesz użyć szamiast niego p?
Neil,
(Udało mi się outgolf oryginalną findwersję przy użyciu lastIndexOf, co jest nieco zaskakujące, zważywszy, że jest 11 liter długo ....)
Neil
@Neil Nie jestem teraz przed komputerem, ale nie sądzę, żeby to działało, ponieważ ciągi JS są niezmienne.
Arnauld,
2
Mogę potwierdzić, że ustawienie właściwości literałów łańcuchowych nie działa. Ale ... wygląda na to, że działa z regex, więc myślę, że możesz zrobić, s=>s.replace(p=/./g,(c,i)=>(i=p[c]-(p[c]=i))>-10?~i:c)aby zaoszczędzić 3 bajty.
ETHprodukcje
1
@YOU Naprawdę nie wiem, co się tutaj wydarzyło, ale okazuje się, że wprowadziłem błąd dla wszystkich przeglądarek podczas mojej ostatniej edycji. To jest teraz naprawione. Dzięki za zauważenie!
Arnauld
7

Haskell , 72 66 bajtów

Dzięki Laikoni za grę w golfa 6 bajtów!

(a:r)%s=last(a:[n|(n,b)<-zip['0'..'9']s,b==a]):r%(a:s)
e%s=e
(%"")

Wypróbuj online!

Funkcja %utrzymuje częściowo przetworzony ciąg w odwrotnej kolejności w drugim argumencie, dzięki czemu jest w stanie przeszukać pierwsze 10 elementów tego ciągu w poszukiwaniu wystąpień badanego znaku. Przesłanie składa się z nienazwanej funkcji, (%"")która wywołuje poprzednią funkcję z pustym łańcuchem jako drugim argumentem.

Lew
źródło
f(a:s)=f s++(last$[a]:[show n|(n,b)<-zip[0..9]s,b==a])oszczędza dwa bajty.
Laikoni,
Poczekaj, f(a:s)=f s++[last$a:[n|(n,b)<-zip['0'..'9']s,b==a]]oszczędza jeszcze więcej.
Laikoni,
Cofanie w ruchu zamiast używania reverseoszczędza jeszcze jeden bajt: Wypróbuj online!
Laikoni,
@Laikoni Dziękuję, to wspaniale!
Leo
5

Python 2 , 64 bajty

s=''
for c in input():d=s[:~10:-1].find(c);s+=-d*c or`d`
print s

Wypróbuj online!

xnor
źródło
Jaki jest sens używania ~10po prostu nie mogę użyć -11?
Keatinge
3

Perl 5 , 36 bajtów

35 bajtów kodu + -p flaga.

s/(\D)(.{0,9})\K\1/length$2/e&&redo

Wypróbuj online!

Kilka wyjaśnień:
Celem jest zastąpienie znaku niecałkowitego ( \Dale odpowiada odsyłaczowi wstecznemu \1w moim wyrażeniu regularnym), który poprzedza mniej niż 10 znaków ( .{0,9}) i ten sam znak ( (\D)... \1) długością .{0,9}grupy ( length$2). I redopodczas gdy postacie zostaną zastąpione.

Dada
źródło
najwyraźniej .*nie jest wymagany, każdy poprawny znak w zakresie zanim zastąpiona cyfra będzie w porządku.
colsw 07.04.17
@ConnorLSW Tak, właśnie zobaczyłem aktualizację wyzwania i zmodyfikowałem swoją odpowiedź, dziękuję za zwrócenie jej uwagi.
Dada,
3

Python 2, 89 84 bajtów

m=input()[::-1];j=1;t=''
for i in m:s=m[j:].find(i);t=[i,`s`][0<s<10]+t;j+=1
print t

Wypróbuj online!

Iteruje przez ciąg w odwrotnej kolejności i buduje nowy ciąg z poprawnymi liczbami.

ćpun matematyki
źródło
3

Japt , 18 bajtów

£¯Y w bX s r"..+"X

Wypróbuj online!

Wyjaśnienie

£   ¯  Y w bX s r"..+"X
mXY{s0,Y w bX s r"..+"X}
                          // Implicit: U = input string
mXY{                   }  // Replace each char X and index Y in U by this function:
    s0,Y                  //   Take U.slice(0,Y), the part of U before this char.
         w bX             //   Reverse, and find the first index of X in the result.
                          //   This gives how far back this char last appeared, -1 if never.
              s           //   Convert the result to a string.
                r"..+"X   //   Replace all matches of /..+/ in the result with X.
                          //   If the index is -1 or greater than 9, this will revert to X.
                          // Implicit: output result of last expression
ETHprodukcje
źródło
2

JavaScript, 100 80 bajtów

x=>x.split``.map((c,b,a)=>{for(i=0;i++<=9&&a[b-i]!=c;);return i>9?c:i-1}).join``

Wypróbuj online!

Fəˈnɛtɪk
źródło
2

05AB1E , 20 bajtów

õIv¹N£RT£©yåi®ykëy}J

Wypróbuj online!

Wyjaśnienie

õ                     # push an empty string
 Iv                   # for each [index,char] [N,y] in input
   ¹N£                # push the first N characters of input
      R               # reverse
       T£             # take the first 10 characters of this string
         ©            # save a copy in register
          yåi         # if y is in this string
             ®yk      #   push the index of y in the string in register
                ë     # else 
                 y    #   push y
                  }   # end if
                   J  # join stack as one string
Emigna
źródło
2

Python 3, 125 118 bajtów

def p(x):print(x,end='')
l={}
for i,c in enumerate(input()):
 if l.get(c,i+9)<i+9:
  p(i-l[c]-1)
 else:
  p(c)
 l[c]=i

Wypróbuj online!

L3viathan
źródło
2

C (tcc) , 113 bajtów

Ponieważ funkcja tworzy kopię łańcucha wejściowego, maksymalny rozmiar danych wejściowych wynosi 98 znaków (więcej niż wystarcza, aby zmieścić najdłuższy testowy tekst). Oczywiście można to zmienić na dowolną inną wartość.

i,j;f(char*s){char n[99];strcpy(n,s);for(i=1;s[i];i++)for(j=i-1;j>-1&&i-j<11;j--)if(n[i]==n[j])s[i]=47+i-j;j=-1;}

Wypróbuj online!

Edytować

-15 bajtów. Dzięki Johan du Toit .

Maxim Michajłow
źródło
Agh! Ogranicz liczbę znaków do 98 i oszczędzaj sobie bajt!
rura
Ładne rozwiązanie, ale można zaoszczędzić kolejne 15 bajtów: i,j;f(char*s){char n[99];strcpy(n,s);for(i=1;s[i];i++)for(j=i-1;j>-1&&i-j<11;j--)if(n[i]==n[j])s[i]=47+i-j,j=-1;}
Johan du Toit
@JohanduToit Thanks! Mam jedno pytanie. Jak dokładnie s [i] działa jako warunek pętli for? Widziałem to wiele razy w odpowiedziach innych osób na tej stronie.
Maxim Mikhaylov
@Max Lawnboy. Pierwotnie miałeś następujące elementy: 's [i] ^' \ 0 '', które są skrótem dla 's [i]! =' \ 0 ''. Literał „\ 0” jest równy zero, więc możesz napisać go w ten sposób: 's [i]! = 0'. Instrukcja if w C sprawdza tylko, czy wartość ma wartość zerową lub niezerową, więc „! = 0” nie jest konieczne.
Johan du Toit,
100 bajtów
ceilingcat
2

Java 7, 102 101 bajtów

void a(char[]a){for(int b=a.length,c;--b>0;)for(c=b;c-->0&c+11>b;)if(a[c]==a[b])a[b]=(char)(b-c+47);}

Wypróbuj online!

-1 bajt dzięki Kevin Cruijssen . Zawsze lubię pretekst do korzystania z operatora.

Szturchać
źródło
Dlaczego --c>=0? Możesz go zastąpić, c-->0aby zapisać bajt.
Kevin Cruijssen
@KevinCruijssen Jakoś miałem w głowie, że potrzebowałem wcześniejszej obróbki, w przeciwnym razie rzeczywiste obliczenia byłyby błędne ... Niezły chwyt!
Poke
1

MATL, 31 30 bajtów

&=R"X@@f-t10<)l_)t?qV}xGX@)]&h

Wypróbuj w MATL Online!

Wyjaśnienie

        % Implicitly grab input as a string
&=      % Perform element-wise comparison with automatic broadcasting.
R       % Take the upper-triangular part of the matrix and set everything else to zero
"       % For each column in this matrix
X@      % Push the index of the row to the stack
@f      % Find the indices of the 1's in the row. The indices are always sorted in
        % increasing order
-       % Subtract the index of the row. This result in an array that is [..., 0] where
        % there is always a 0 because each letter is equal to itself and then the ...
        % indicates the index distances to the same letters
t10<)   % Discard the index differences that are > 9
l_)     % Grab the next to last index which is going to be the smallest value. If the index
        % array only contains [0], then modular indexing will grab that zero
t?      % See if this is non-zero...
  qV    % Subtract 1 and convert to a string
}       % If there were no previous matching values
  x     % Delete the item from the stack
  GX@)  % Push the current character
]       % End of if statement
&h      % Horizontally concatenate the entire stack
        % Implicit end of for loop and implicit display
Suever
źródło
Możesz być trochę zdenerwowany, ale ja super nie wiem, gdzie. Dane wejściowe this is a testdają this 222a1te52zamiast this 222a19e52. Drugi tnie jest konwertowany na 9.
Inżynier Toast
@EngineerToast Haha dzięki. Spojrzę na to.
Suever,
1

PHP, 104 bajtów

przyszłe rozwiązanie

for($i=0;$i<strlen($a=&$argn);$f[$l]=$i++)$a[$i]=is_int($f[$l=$a[$i]])&($c=$i-$f[$l]-1)<10?$c:$l;echo$a;

Rozwiązania wsteczne

Wersje online

PHP, 111 bajtów

for(;++$i<$l=strlen($a=&$argn);)!is_int($t=strrpos($argn,$a[-$i],-$i-1))?:($p=$l-$i-$t-1)>9?:$a[-$i]=$p;echo$a;

PHP, 112 bajtów

for(;++$i<$l=strlen($a=&$argn);)if(false!==$t=strrpos($argn,$a[-$i],-$i-1))($p=$l-$i-$t-1)>9?:$a[-$i]=$p;echo$a;

Wersja online

Jörg Hülsermann
źródło
1

REXX, 124 125 bajtów

a=arg(1)
b=a
do n=1 to length(a)
  m=n-1
  c=substr(a,n,1)
  s=lastpos(c,left(a,m))
  if s>0&m-s<=9 then b=overlay(m-s,b,n)
  end
say b
idrougge
źródło
Możesz być trochę zła. Nie znam REXX, ale zakładam, że błąd jest w linii 7, gdzie ma s<9zamiast s<10lub s<=9. Dane wejściowe this is a testdają this 222a1te52zamiast this 222a19e52. Drugi tnie jest konwertowany na 9. Wypróbuj online
Inżynier Toast
Dziękuję, to była głupia próba ogolenia jednego bajtu. Kod został naprawiony.
idrougge 12.04.17
1

C (gcc) , 117 103 bajtów

i,j;f(char*s){for(i=strlen(s)-1;s[i];i--)for(j=i-1;s[j]&&i-j<11;j--)if(s[i]==s[j]){s[i]=47+i-j;break;}}

Wypróbuj online!

103 bajty bez importu string.h, działa z ostrzeżeniem. Jeśli będzie to niezgodne z zasadami, pociągnę to

Ładny kod:

i,j;
f(char *s) {
    // Chomp backwards down the string
    for(i=strlen(s)-1; s[i]; i--)
        // for every char, try to match the previous 10
        for(j=i-1; s[j] && i-j < 11; j--)
            // If there's a match, encode it ('0' + (i-j))
            if (s[i] == s[j]) {
                s[i] = 47+i-j;
                break;
            }
}

Edycje:

  • Zmieniono z LLVM na gcc, aby umożliwić niejawną deklarację i, j, usunięto import lib.
  • Dodano opakowanie funkcji dla zapewnienia zgodności
Ian M.
źródło
Zaproponuj (i=strlen(s);s[--i];)zamiast(i=strlen(s)-1;s[i];i--)
ceilingcat