Biorąc pod uwagę liczbę całkowitą, oblicz jej kod Levenshteina

10

Oświadczenie: Kodowanie Levenshtein jest całkowicie niezwiązane z metryką odległości edycyjnej Levenshtein .

<Wstaw tutaj długą historię o tym, dlaczego należy obliczać kody Levenshteina.>

Kod

Kodowanie Levenshteina to system przypisywania kodów binarnych nieujemnym liczbom całkowitym, który zachowuje pewną dziwną właściwość, która prawdopodobnie nie jest istotna dla tego wyzwania. Będziemy oznaczać ten kod jako L ( n ). Wikipedia opisuje to jako pięciostopniowy proces:

  1. Zainicjuj zmienną liczby kroków C na 1.
  2. Napisz binarną reprezentację liczby bez prowadzenia 1na początek kodu.
  3. Niech M będzie liczbą bitów zapisanych w kroku 2.
  4. Jeśli M nie jest równe 0, zwiększ C , powtórz od kroku 2, wpisując M jako nowy numer.
  5. Napisz bity C 1 i a 0na początku kodu.

Kod można jednak również opisać rekurencyjnie:

  1. Jeśli liczba wynosi 0, to jej kod to 0.
  2. Napisz binarną reprezentację liczby bez prowadzenia 1na początek kodu.
  3. Niech M będzie liczbą bitów zapisanych w kroku 2.
  4. Napisz L ( M ) na początku kodu.
  5. Napisz 1trochę na początku kodu.

Dla tych, którzy wolą przykłady, oto proces rekurencyjny dla L (87654321) z oznaczeniem konkatenacji:

Wyzwanie

Napisz program lub funkcję, która, biorąc pod uwagę liczbę n , wyprowadza ciąg bitów L ( n ) w dowolnym rozsądnym formacie (obejmuje to zwracanie liczby ze wspomnianymi bitami). Standardowe luki są, jak zawsze, niedozwolone.

Przykłady

Wejście: 5

Wynik: 1110001

Wejście: 30

Wynik: 111100001110

Wejście: 87654321

Wynik: 111110000101001001110010111111110110001

Wejście: 0

Wynik: 0

LegionMammal978
źródło

Odpowiedzi:

2

Galaretka , 13 11 bajtów

Ḣ;LÑ$;
BÇṀ¡

Wypróbuj online! lub zweryfikuj wszystkie przypadki testowe .

Jak to działa

Zgłoszenie składa się z pary wzajemnie rekurencyjnych linków.

BÇṀ¡    Main link. Argument: n

B       Convert n to binary.
   ¡    Execute...
 Ç        the helper link...
  Ṁ       m times, where m is the maximum of n's binary digits.

Ḣ;LÑ$;  Helper link. Argument: A (array of binary digits)

Ḣ       Head; remove and return the first element of A.
    $   Combine the two links to the left into a monadic chain.
  L       Yield the length (l) of A without its first element.
   Ñ      Call the main link with argument l.
 ;      Concatenate the results to both sides.
     ;  Append the tail of A.
Dennis
źródło
8

Haskell, 70 bajtów

b 0=[]
b n=b(div n 2)++[mod n 2]
f 0=[0]
f n|1:t<-b n=1:f(length t)++t

Definiuje funkcję f : Int -> [Int]. Na przykład f 5 == [1,1,1,0,0,0,1].

Lynn
źródło
5

Python, 49 bajtów

f=lambda n:n and'1%s'%f(len(bin(n))-3)+bin(n)[3:]

Przetestuj na Ideone .

Dennis
źródło
4

Mathematica, 61 bajtów

f@0={0};f@n_:=Join[{1},f@Length@#,#]&@Rest@IntegerDigits[n,2]
alephalpha
źródło
1
Jestem prawie pewien, że możesz zaoszczędzić kilka bajtów, definiując jednoargumentowy operator ±zamiast funkcji f.
Martin Ender
3

JavaScript (ES6), 54 52 bajtów

f=n=>(s=n.toString(2)).replace(1,_=>1+f(s.length-1))
<input type=number oninput=o.textContent=f(+this.value)><pre id=o>

Edycja: Zapisano 2 bajty dzięki @Arnauld.

Neil
źródło
Myślę, że możesz bezpiecznie używać replace(1,...zamiast replace(/1/,...=> 52 bajtów
Arnauld
2

Pyth, 12 bajtów

L&bX1.Bbyslb

Demonstracja

(Na ykońcu jest uruchomienie wynikowej funkcji na wejściu)

Wyjaśnienie:

L&bX1.Bbyslb
L               def y(b):
 &b             If b is 0, return 0. This is returned as an int, but will be cast
                to a string later.
          lb    Take the log of b
         s      Floor
        y       Call y recursively
   X1           Insert at position 1 into
     .Bb        Convert b to binary.
isaacg
źródło
1

SQF, 110

Funkcja rekurencyjna:

f={params[["i",0],["l",[]]];if(i<1)exitWith{[0]};while{i>1}do{l=[i%2]+l;i=floor(i/2)};[1]+([count l]call f)+l}

Zadzwoń jako: [NUMBER] call f

Zauważ, że tak naprawdę nie działa to dla 87654321 lub innych dużych liczb z powodu błędu w silniku ArmA. Chociaż prawdopodobnie zostanie to wkrótce naprawione i powinno działać zgodnie ze specyfikacją.

( Ten bilet tutaj )

Obrzydliwe
źródło
0

PHP, 116 114 bajtów

<?$f=function($i)use(&$f){$b=decbin($i);return!$b?0:preg_replace('/^1/',1 .$f(~~log10($b)),$b);};echo$f($argv[1]);

Podaj liczbę jako pierwszy argument.

Aktualizacja:

  • Zapisano bajt, zastępując strlen($b)-1go ~~log10($b)(w końcu zrozumiał, dlaczego wszyscy inni używają logarytmu) i inny, łącząc inaczej.
YetiCGN
źródło
0

Java 8 (pełny program), 257 249 bajtów

interface M{static void main(String[]a)throws Exception{int i=0,j;while((j=System.in.read())>10)i=i*10+j-48;System.out.print(L(i));}static String L(int i){if(i==0)return "0";String s=Integer.toString(i,2);return "1"+L(s.length()-1)+s.substring(1);}}

Wersja do odczytu z wyjaśnieniem (w większości jest to po prostu rekursja):

interface M {
    static void main(String[]a) throws Exception { // Using Exception is unadvised in real coding, but this is Code Gold
        int i = 0, j; // i stores the input; j is a temporary variable
        while ((j = System.in.read()) > 10) // Read the input to j and stop if it is a newline. Technically this stops for tabulators as well, but we shouldn't encounter any of those...
            i = i * 10 + j - 48; // Looping this step eventually reads the whole number in from System.in without using a reader (those take up a lot of bytes)
        System.out.print(L(i)); // Make a method call
    }

    static String L(int i) { // This gets the actual Levenshtein Code
        if (i == 0)
            return "0"; // The program gets a StackOverflowException without this part
        String s = Integer.toString(i, 2); // Shorter than toBinaryString
        return "1" + L(s.length() - 1) + s.substring(1); // Write in the first character (which is always a one), followed by the next L-code, followed by the rest of the binary string
    }
}

EDYCJA 1 : Zapisane 8 bajtów : Pierwszy znak ciągu binarnego to zawsze 1; dlatego zamiast używać s.charAt(0)lepszej opcji jest po prostu "1".

HyperNeutrino
źródło