Zwiększ identyfikator GUID


30

Inspirowany najnowszym artykułem Daily WTF ...

Napisz program lub funkcję, która pobiera GUID (ciąg znaków w formacie XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX, w którym każdy X reprezentuje cyfrę szesnastkową), i wyświetla GUID z przyrostem o jeden.

Przykłady

>>> increment_guid('7f128bd4-b0ba-4597-8f35-3a2f2756dfbb')
'7f128bd4-b0ba-4597-8f35-3a2f2756dfbc'
>>> increment_guid('06b86883-f3e7-4f9d-87c5-a047e89a19fa')
'06b86883-f3e7-4f9d-87c5-a047e89a19fb'
>>> increment_guid('89f25f2f-2f7b-4aa6-b9d7-46a98e3cb2cf')
'89f25f2f-2f7b-4aa6-b9d7-46a98e3cb2d0'
>>> increment_guid('89f25f2f-2f7b-4aa6-b9d7-46a98e3cb29f')
'89f25f2f-2f7b-4aa6-b9d7-46a98e3cb2a0'
>>> increment_guid('8e0f9835-4086-406b-b7a4-532da46963ff')
'8e0f9835-4086-406b-b7a4-532da4696400'
>>> increment_guid('7f128bd4-b0ba-4597-ffff-ffffffffffff')
'7f128bd4-b0ba-4598-0000-000000000000'

Uwagi

  • W przeciwieństwie do artykułu z linkiem, zwiększenie identyfikatora GUID kończącego się na F musi „przenosić” do poprzedniej cyfry szesnastkowej. Zobacz przykłady powyżej.
  • Możesz założyć, że dane wejściowe nie będą ffffffff-ffff-ffff-ffff-ffffffffffff.
  • W przypadku cyfr szesnastkowych powyżej 9 możesz użyć dużej (AF) lub małej (af) wielkości liter.
  • Tak, identyfikatory GUID mogą zaczynać się od 0.
  • Dane wyjściowe muszą składać się z dokładnie 32 cyfr szesnastkowych i 4 łączników w oczekiwanym formacie, w tym wszelkich niezbędnych początkowych znaków 0.
  • Nie musisz zachowywać numeru wersji ani innych ustalonych bitów identyfikatora GUID. Załóżmy, że jest to tylko 128-bitowa liczba całkowita, w której żaden z bitów nie ma żadnego specjalnego znaczenia. Podobnie zakłada się, że identyfikatory GUID są sortowane w prostej kolejności leksykograficznej, a nie w kolejności binarnej GUIDstruktury systemu Windows .
  • Jeśli pisanie funkcji, wejście może być dowolnej sekwencji z eksploatacji chartypu danych: string, char[], List<char>, itd.

1
Czy mamy pozostawić 6 ustalonych bitów w UUIDv4 nienaruszonych?
Filip Haglund

2
@FilipHaglund: Nie, po prostu traktuj GUID jako liczbę 128-bitową, gdzie żaden z bitów nie ma żadnego specjalnego znaczenia. Podobnie zakłada się, że identyfikatory GUID są sortowane w prostej kolejności leksykograficznej, a nie w kolejności binarnej GUIDstruktury systemu Windows .
dan04

3
Sugerowany przypadek testowy: 89f25f2f-2f7b-4aa6-b9d7-46a98e3cb29faby upewnić się, że odpowiedzi mogą dokonać przejścia 9 -> a.
Kamil Drakari

1
@dana: Możesz użyć dowolnego typu danych, dla którego twój język odpowiada C # foreach (char ch in theInput).
dan04

Odpowiedzi:


7

05AB1E , 17 15 18 bajtów

Zaoszczędzono 2 bajty dzięki Kevinowi Cruijssenowi

'-K1ìH>h¦Ž¦˜S·£'-ý

Wypróbuj online! lub jako pakiet testowy

Wyjaśnienie

'-K                  # remove "-" from input
   1ì                # prepend a 1 (to preserve leading 0s)
     H               # convert from hex to base 10
      >              # increment
       h             # convert to hex from base 10
        ¦            # remove the extra 1
         Ž¦˜S·       # push [8, 4, 4, 4, 12]
              £      # split into parts of these sizes
               '-ý   # join on "-"

Dang, pobiłeś mnie do tego .. Miałem coś bardzo podobnego, ale z žKÃzamiast '-K. Przy okazji możesz zapisać 2 bajty, zmieniając •É]•S3+na Ž¦˜S·.
Kevin Cruijssen

@KevinCruijssen: Dzięki! Nie wiem, ile razy zapominałem, że Žto już coś takiego ...
Emigna

Nie zaakceptowałem tej odpowiedzi, ponieważ ktoś zauważył, że spadnie ona do wiodących zer. Proszę napraw.
dan04

@ dan04: Dobra rozmowa! Nie myślałem o tym. Należy naprawić teraz :)
Emigna,


11

JavaScript (ES6), 85 bajtów

Łańcuch wyjściowy jest pisany małymi literami.

s=>(g=(c,x=+('0x'+s[--n])+!!c)=>1/x?g(x>>4)+(x&15).toString(16):~n?g(c)+'-':'')(n=36)

Wypróbuj online!

Skomentował

s => (                   // s = GUID
  g = (                  // g = recursive function taking:
    c,                   //   c = carry from the previous iteration
    x = +('0x' + s[--n]) //   x = decimal conversion of the current digit
        + !!c            //       add the carry
  ) =>                   //
    1 / x ?              // if x is numeric:
      g(x >> 4) +        //   do a recursive call, using the new carry
      (x & 15)           //   and append the next digit
      .toString(16)      //   converted back to hexadecimal 
    :                    // else:
      ~n ?               //   if n is not equal to -1:
        g(c)             //     do a recursive call, leaving the current carry unchanged
        + '-'            //     and append a hyphen
      :                  //   else:
        ''               //     stop recursion
)(n = 36)                // initial call to g with n = 36 and a truthy carry

5

Python 2 , 82 bajty

q='f0123456789abcdef--'
f=lambda s:[str,f][s[-1]in'f-'](s[:-1])+q[q.find(s[-1])+1]

Wypróbuj online!

Brak importu lub konwersji heksadecymalnej.

To skanuje od tyłu sznurka, przesuwając każdą postać w całym cyklu 0123456789abcdef, -do samego siebie. Po trafieniu w symbol inny niż flub -przestaje skanować w lewo i po prostu zwraca pozostałą część bez zmian. To rozwiązanie nie jest specyficzne dla formatu UUID - działałaby dowolna liczba bloków o dowolnej liczbie liter szesnastkowych.

Podstawowy przypadek [str,f][s[-1]in'f-'](s[:-1])to sztuczka, której wcześniej nie widziałem w golfie. To kończy rekurencję bez if, and, orlub innego jednoznacznego przepływu sterowania.

W zależności [s[-1]in'f-']od stanu ostatniego znaku kod albo zwraca, f(s[:-1])albo po prostu s[:-1]pozostaje niezmieniony. Ponieważ strjest to tożsamość na ciągach, możemy wybrać jedną z funkcji [str,f]i zastosować ją s[:-1]. Zauważ, że wywołanie rekurencyjne fnie jest wykonywane, jeśli nie zostanie wybrane, omijając typowy problem, który Python chętnie ocenia nieużywane opcje, co prowadzi do nieskończonego regresji w rekurencjach.


Cóż, rano idzie mi mózg.
don bright

3

APL (Dyalog Unicode) , 46 bajtów SBCS

Anonimowa ukryta funkcja prefiksu.

CY'dfns'
(∊1hex 16(|+1⌽=)⍣≡1+@32dec¨)@('-'≠⊢)

Wypróbuj online!

⎕CY'dfns'c op y bibliotekę „dfns” (aby uzyskać hexidec )

()
 Argument
 różni się od
'-' myślnika
()@ w podzbiorze składającym się z miejsc, w których spełnione jest powyższe kryterium, zastosuj:
dec¨ przekonwertuj każdy znak szesnastkowy na liczbę dziesiętną
 … @32w pozycji 32 (ostatnia cyfra), zastosuj:
  1+ przyrost
16()⍣≡ stosuj wielokrotnie lewy argument 16 do stabilnego:
  = porównaj (daje maskę, gdzie cyfry szesnastkowe wynoszą 16)
  1⌽ cyklicznie obracaj jeden krok w lewo (jest to bit przenoszący)
  |+ do tego, dodaj resztę podziału po podzieleniu (przez szesnaście, dzięki czemu wszystkie 16 na 0)  obróć cyfry w reprezentacji znaków szesnastkowych o długości jeden ϵ nlist (spłaszczony)
1hex


3

Java 11, 152 149 111 108 bajtów

s->{var b=s.getLeastSignificantBits()+1;return new java.util.UUID(s.getMostSignificantBits()+(b==0?1:0),b);}

-38 bajtów dzięki @ OlivierGrégoire .
-3 bajty dzięki tylko @ ASCII .

Wypróbuj online.

Wyjaśnienie:

s->{         // Method with UUID as both parameter and return-type
  var b=s.getLeastSignificantBits()
             //  Get the 64 least significant bits of the input-UUID's 128 bits as long
        +1;  //  And increase it by 1
  return new java.util.UUID(
             //  Return a new UUID with:
    s.getMostSignificantBits()
             //   The 64 most significant bits of the input-UUID's 128 bits as long
    +(b==0?  //    And if the 64 least significant bits + 1 are exactly 0:
       1     //     Increase the 64 most significant bits by 1 as well
      :      //    Else:
       0,    //     Don't change the 64 most significant bits by adding 0
     b);}    //   And the 64 least significant bits + 1

Stara 149 bajtów odpowiedź:

s->{var t=new java.math.BigInteger(s.replace("-",""),16);return(t.add(t.ONE).toString(16)).replaceAll("(.{4})".repeat(5)+"(.*)","$1$2-$3-$4-$5-$6");}

Wypróbuj online.

Wyjaśnienie:

s->{                              // Method with String as both parameter and return-type
  var t=new java.math.BigInteger( //  Create a BigInteger
         s.replace("-",""),       //  Of the input-string with all "-" removed
         16);                     //  Converted from Hexadecimal
  return(t.add(t.ONE)             //  Add 1
         .toString(16))           //  And convert it back to a Hexadecimal String
         .replaceAll("(.{4})".repeat(5)+"(.*)",
                                  //  And split the string into parts of sizes 4,4,4,4,4,rest
           "$1$2-$3-$4-$5-$6");}  //  And insert "-" after parts of size 8,4,4,4,
                                  //  and return it as result


@ OlivierGrégoire Nie myślałem o użyciu rzeczywistego UUID! Ładna i krótsza alternatywa. : D
Kevin Cruijssen


-1 więcej z var zamiast długiego
tylko ASCII




2

Retina 0.8.2 , 21 bajtów

T`FfdlL`0dlL`.[-Ff]*$

Wypróbuj online! Link zawiera przypadki testowe. 9staje się a. Objaśnienie: Wyrażenie regularne dopasowuje wszystkie końcowe fs oraz -s plus jeden poprzedni znak. Transliteracja następnie cyklicznie zwiększa te znaki, jakby były cyframi szesnastkowymi. Alternatywne podejście, również 21 bajtów:

T`L`l
T`fo`dl`.[-f]*$

Wypróbuj online! Link zawiera przypadki testowe. Działa poprzez obniżenie wejścia dla uproszczenia transliteracji. Byłby zatem 15 bajtów, gdyby miał obsługiwać tylko małe litery. Wypróbuj online! Link zawiera przypadki testowe.


2

MATLAB, 138 bajtów

a=1;Z=a;for r=flip(split(input(''),'-'))'
q=r{:};z=dec2hex(hex2dec(q)+a,nnz(q));try
z+q;a=0;catch
z=~q+48;end
Z=[z 45 Z];end;disp(Z(1:36))

Naprawiono błąd w przypadku, gdy fragment zawiera wszystkie zera. Grał też w golfa, nadużywając try / catch. Wynik netto: zapisano 0 bajtów.

Próba „oszukiwania” przy użyciu java.util.UUIDnie powiodła się, ponieważ longwartość zwrócona z java.util.UUID.get[Most/Least]SignificantBitsjest konwertowana na wartość, doublektóra powoduje utratę precyzji. Zapraszam do obejrzenia tego stołu i bezgłośnego powiedzenia „... ale dlaczego?

Wyjaśnienie

Do hex2decfunkcji wypluwa double, a więc nie może przetwarzać cały GUID jednocześnie w celu uniknięcia przekroczenia flintmax. Zamiast tego musimy przetworzyć fragment GUID metodą chunck, używając split. Zmienna asprawdza, czy musimy ją mieć, i oszukańczo jest to również początkowy przyrost, który dodajemy. Warunkiem przeniesienia jest to, czy długości oryginalnych i przyrostowych łańcuchów nie są już równe.

Oryginalna wersja miała niecałe 160 bajtów, więc chciałbym pomyśleć, że nie powinno to być łatwe do outgolfa.



2

C # (interaktywny kompilator Visual C #) , 77 bajtów

x=>{for(int i=35,c;(x[i]=(char)((c=x[i--])<48?c:c==57?65:c>69?48:c+1))<49;);}

Wypróbuj online!

-1 bajt dzięki @ASCIIOnly!

Anonimowa funkcja, która przyjmuje char[]dane wejściowe i wyjściowe poprzez modyfikację argumentu .

Dane wejściowe są skanowane od prawej do lewej i zastępowane przy użyciu następujących reguł.

  • The -Znak jest ignorowany, a proces jest kontynuowany
  • The FZnak jest przekształcany 0i przetwarzanie jest kontynuowane
  • The 9Postaci przekształca się Ai przetwarzanie zatrzymuje
  • Znaki A-Ei 0-8są zwiększane o 1, a przetwarzanie zostaje zatrzymane

2
==70->>69
Tylko ASCII,

Doskonałe - Dzięki :)
dana

2

PowerShell, 101 bajtów

for($p=1;$d=+"$args"[--$i]){$d+=$p*(1-@{45=1;57=-7;70=23;102=55}.$d)
$p*=$d-in45,48
$r=[char]$d+$r}$r

Wypróbuj online!

Brak zewnętrznej biblioteki lub konwersji szesnastkowej. Dowolna długość łańcucha. Małe i duże litery są dozwolone. Wpisz ciąg pasujący do^[f-]*$Dopuszczalny jest również .

Ten skrypt skanuje od tyłu łańcucha i inrementuje każdy znak o wartość z hashtable:

  • -: przyrost = 1-1
  • 9: przyrost = 1 + 7, wynik =A
  • F: przyrost = 1-23, wynik =0
  • f: przyrost = 1-55, wynik =0
  • przyrost = 1 dla innych znaków

Następnie skrypt używa $p do ustalenia, czy należy zwiększyć bieżący znak.

Skrypt testowy:

$f = {

for($p=1;$d=+"$args"[--$i]){$d+=$p*(1-@{45=1;57=-7;70=23;102=55}.$d)
$p*=$d-in45,48
$r=[char]$d+$r}$r

}

@(
    ,('f','0')
    ,('F','0')
    ,('0','1')
    ,('9','A')
    ,('A','B')
    ,('a','b')
    ,('0-f','1-0')
    ,('0-F','1-0')
    ,("7f128bd4-b0ba-4597-8f35-3a2f2756dfbb","7f128bd4-b0ba-4597-8f35-3a2f2756dfbc")
    ,("06b86883-f3e7-4f9d-87c5-a047e89a19f9","06b86883-f3e7-4f9d-87c5-a047e89a19fa")
    ,("89f25f2f-2f7b-4aa6-b9d7-46a98e3cb2cf","89f25f2f-2f7b-4aa6-b9d7-46a98e3cb2d0")
    ,("8e0f9835-4086-406b-b7a4-532da46963ff","8e0f9835-4086-406b-b7a4-532da4696400")
    ,("7f128bd4-b0ba-4597-ffff-ffffffffffff","7f128bd4-b0ba-4598-0000-000000000000")
    ,("89f25f2f-2f7b-4aa6-b9d7-46a98e3cb29f","89f25f2f-2f7b-4aa6-b9d7-46a98e3cb2a0")
    ,("ffffffff-ffff-ffff-ffff-ffffffffffff","00000000-0000-0000-0000-000000000000")
) | % {
    $guid,$expected = $_
    $result = &$f $guid
    "$($result-eq$expected): $result"
}

Wydajność:

True: 0
True: 0
True: 1
True: A
True: B
True: b
True: 1-0
True: 1-0
True: 7f128bd4-b0ba-4597-8f35-3a2f2756dfbc
True: 06b86883-f3e7-4f9d-87c5-a047e89a19fA
True: 89f25f2f-2f7b-4aa6-b9d7-46a98e3cb2d0
True: 8e0f9835-4086-406b-b7a4-532da4696400
True: 7f128bd4-b0ba-4598-0000-000000000000
True: 89f25f2f-2f7b-4aa6-b9d7-46a98e3cb2A0
True: 00000000-0000-0000-0000-000000000000



1

PowerShell , 126 bajtów

$a=("{0:X32}" -f (1+[Numerics.BigInteger]::Parse($args[0]-replace"-", 'AllowHexSpecifier')));5..2|%{$a=$a.Insert(4*$_,"-")};$a

Wypróbuj online!

Dość trywialna odpowiedź. Pomyślałem, że dodam do listy ukochanego PowerShella :)



0

Perl 5, 64 bajtów

$c=reverse((1+hex s/-//gr)->as_hex);$c=~s/..$//;s/[^-]/chop$c/ge

Niezbędna liczba nawiasów powoduje, że jestem smutny, ale ->wiąże się bardzo mocno, jak->as_hex najszybszy sposób na uzyskanie danych wyjściowych w formacie szesnastkowym.

Uruchom z perl -Mbigint -p. Zasadniczo po prostu konwertuje liczbę na duży szesnastkowy, dodaje jeden, a następnie podtytula cyfry wyniku z powrotem do pierwotnej wartości, nie zmieniając myślników.


0

Rdza, 258 bajtów

let x=|s:&str|s.chars().rev().scan(1,|a,c|{let d=c.to_digit(16).unwrap_or(99);match(d,*a){(15,1)=>{*a=1;Some(0)}(0..=14,1)=>{*a = 0;Some(d + 1)}_=> Some(d),}}).collect::<Vec<u32>>().iter().rev().for_each(|d| print!("{}", std::char::from_digit(*d, 16).unwrap_or('-')));

tak, jest długi .. ale technicznie jest to jedyna linia z 1 wyrażeniem? i żadnych fantazyjnych bibliotek? i nie zawiesi się na wejściu Fuzz? Ungolf:

let x=|s:&str|s.chars().rev().scan(1, |a, c| {
            let d = c.to_digit(16).unwrap_or(99);
            match (d, *a) {
                (15, 1) => {*a = 1;Some(0)}
                (0..=14, 1) => {*a = 0;Some(d + 1)}
                _ => Some(d),
            }
        }).collect::<Vec<u32>>().iter().rev()
        .for_each(|d| print!("{}", std::char::from_digit(*d, 16).unwrap_or('-')));

spróbuj na rdzawym placu zabaw



0

16/32/64-bitowy kod zestawu x86, 28 bajtów

bajty: 83C623FDAC3C2D74FB403C3A7502B0613C677502B03088460173E9C3

kod:

     add esi, 35       ;point to end of string - 1
     std               ;go backwards
l1:  lodsb             ;fetch a character
     cmp al, '-'
     je  l1            ;skip '-'
     inc eax           ;otherwise increment
     cmp al, '9' + 1
     jne l2            ;branch if not out of numbers
     mov al, 'a'       ;otherwise switch '9'+1 to 'a'
l2:  cmp al, 'f' + 1   ;sets carry if less
     jne l3            ;branch if not out of letters
     mov al, '0'       ;otherwise switch 'f'+1 to '0'
                       ;and carry is clear
l3:  mov [esi + 1], al ;replace character
     jnb l1            ;and loop while carry is clear
     ret

Zadzwoń z ESI wskazującym GUID. Zamień ESI na SI dla 16-bitów lub RSI dla 64-bitów (i +2 bajty).


0

C (brzęk) , 62 bajty

g(char*i){for(i+=36;(*--i-45?*i+=*i-70?*i-57?1:8:-22:0)<49;);}

Wypróbuj online!


czekać. czy sprawdzanie małych / wielkich liter nic nie kosztuje ???
Tylko ASCII,

mam na myśli, że może obsługiwać zarówno małe, jak i wielkie litery bez żadnych kosztów bytount ?!
Tylko ASCII,

Ach ok .. ch-70% 32? : na „0” ... 64 i 96 są wielokrotnością 32, więc 70-6 i 102-6% 32.
AZTECCO

1
tak naprawdę nie musisz obsługiwać obu, więc 64
tylko ASCII

0

Common Lisp, 166 bajtów

(lambda(s &aux(r(format()"~32,'0x"(1+(parse-integer(remove #\- s):radix 16)))))(format()"~{~a~^-~}"(mapcar(lambda(x y)(subseq r x y))#1='(0 8 12 16 20 32)(cdr #1#))))

Wypróbuj online!

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.