Tăng một HƯỚNG DẪN


30

Lấy cảm hứng từ một bài báo WTF hàng ngày gần đây ...

Viết chương trình hoặc hàm lấy GUID (chuỗi ở định dạng XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX, trong đó mỗi X đại diện cho một chữ số thập lục phân) và xuất ra GUID tăng thêm một.

Ví dụ

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

Ghi chú

  • Không giống như trong bài viết được liên kết, việc tăng GUID kết thúc bằng F phải có thể mang theo chữ số hex trước đó. Xem ví dụ trên.
  • Bạn có thể cho rằng đầu vào sẽ không được ffffffff-ffff-ffff-ffff-ffffffffffff.
  • Đối với các chữ số hex trên 9, bạn có thể sử dụng trường hợp trên (AF) hoặc dưới (af).
  • Có, GUID có thể bắt đầu bằng a 0.
  • Đầu ra của bạn phải bao gồm chính xác 32 chữ số hex và 4 dấu gạch nối ở định dạng mong đợi, bao gồm mọi 0s hàng đầu cần thiết .
  • Bạn không phải bảo toàn số phiên bản hoặc các bit cố định khác của GUID. Giả sử nó chỉ là một số nguyên 128 bit trong đó không có bit nào có ý nghĩa đặc biệt. Tương tự, GUID được giả định sắp xếp theo thứ tự từ điển đơn giản hơn là theo thứ tự nhị phân của GUIDcấu trúc Windows .
  • Nếu viết một chức năng, đầu vào có thể của bất kỳ chuỗi-of- charkiểu dữ liệu: string, char[], List<char>vv

1
Chúng ta có nên để nguyên 6 bit cố định trong UUIDv4 không?
Filip Haglund

2
@FilipHaglund: Không, chỉ coi GUID là số 128 bit, trong đó không có bit nào có ý nghĩa đặc biệt. Tương tự, GUID được giả định sắp xếp theo thứ tự từ điển đơn giản hơn là theo thứ tự nhị phân của GUIDcấu trúc Windows .
dan04

3
Trường hợp thử nghiệm được đề xuất: 89f25f2f-2f7b-4aa6-b9d7-46a98e3cb29fđể đảm bảo rằng câu trả lời có thể thực hiện quá trình chuyển đổi 9 -> a.
Kamil Drakari

1
@dana: Bạn có thể sử dụng bất kỳ loại dữ liệu nào tương đương với ngôn ngữ của C # của bạn foreach (char ch in theInput).
dan04

Câu trả lời:


7

05AB1E , 17 15 18 byte

Đã lưu 2 byte nhờ Kevin Cruijssen

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

Hãy thử trực tuyến! hoặc như một bộ thử nghiệm

Giải trình

'-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, bạn đánh tôi với nó .. Có một cái gì đó rất giống, nhưng žKÃthay vì '-K. Btw, bạn có thể lưu 2 byte bằng cách thay đổi •É]•S3+thành ަ˜S·.
Kevin Cruijssen

@KevinCruijssen: Cảm ơn! Tôi không biết bao nhiêu lần tôi đã quên mất rằng đó Žlà một điều bây giờ ...
Emigna

Tôi không chấp nhận câu trả lời này vì ai đó đã chỉ ra rằng nó sẽ giảm 0 điểm. Hãy sửa chữa.
dan04

@ dan04: Gọi tốt! Tôi đã không nghĩ về điều đó. Nên sửa ngay bây giờ :)
Emigna


11

JavaScript (ES6), 85 byte

Chuỗi đầu ra là chữ thường.

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

Hãy thử trực tuyến!

Đã bình luận

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 byte

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

Hãy thử trực tuyến!

Không nhập khẩu hoặc chuyển đổi hex.

Điều này quét từ mặt sau của chuỗi, di chuyển từng ký tự dọc theo chu kỳ 0123456789abcdef, với -chính nó. Sau khi nó chạm vào một biểu tượng khác fhoặc -, nó dừng quét sang trái và chỉ trả lại phần còn lại không thay đổi. Giải pháp này không dành riêng cho định dạng UUID - bất kỳ số khối nào của bất kỳ số lượng chữ cái hex nào cũng sẽ hoạt động.

Trường hợp cơ bản [str,f][s[-1]in'f-'](s[:-1])là một mẹo mà tôi chưa từng thấy được sử dụng trong một sân golf trước đây. Nó chấm dứt đệ quy mà không cần bất kỳ if, and, or, hoặc kiểm soát dòng chảy dâm khác.

Dựa trên điều kiện [s[-1]in'f-']của ký tự cuối cùng, mã sẽ trả về f(s[:-1])hoặc chỉ s[:-1]không thay đổi. Vì strlà danh tính trên các chuỗi, chúng ta có thể chọn một trong các hàm [str,f]và áp dụng nó cho s[:-1]. Lưu ý rằng cuộc gọi đệ quy fkhông được thực hiện nếu không được chọn, giải quyết vấn đề phổ biến mà Python háo hức đánh giá các tùy chọn không sử dụng, dẫn đến hồi quy vô hạn trong các lần truy cập.


tốt, có bộ não của tôi cho buổi sáng.
don sáng

3

APL (Dyalog Unicode) , 46 byte SBCS

Chức năng tiền tố ẩn danh.

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

Hãy thử trực tuyến!

⎕CY'dfns'c op y thư viện "dfns" (để lấy hexdec )

(... )
 lập luận
 khác với
'-' một dấu gạch ngang
(... )@ trên tập con gồm các địa điểm tại đó các tiêu chí trên là đúng, áp dụng:
dec¨ chuyển đổi mỗi nhân vật thập lục phân cho một số thập phân
 ... @32tại vị trí 32 (chữ số cuối cùng), được áp dụng:
  1+ tăng
16(... )⍣≡ liên tục áp dụng với trái lập luận 16 cho đến khi ổn định:
  = so sánh (cho mặt nạ nơi các chữ số thập lục phân 16)
  1⌽ một bước theo chu kỳ xoay trái (đây là các bit thực hiện)
  |+ vào đó, thêm phần còn lại phân chia khi chia (bằng mười sáu, do đó làm cho tất cả 16 thành 0)  lần lượt chữ số vào chiều dài-một ký tự thập lục phân đại diện ε nlist (flatten)
1hex


3

Java 11, 152 149 111 108 byte

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

-38 byte cảm ơn @ OlivierGrégoire .
-3 byte chỉ nhờ @ ASCII .

Hãy thử trực tuyến.

Giải trình:

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

Câu trả lời cũ 149 byte:

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");}

Hãy thử trực tuyến.

Giải trình:

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 Chưa nghĩ đến việc sử dụng UUID thực tế! Đẹp và ngắn hơn thay thế. : D
Kevin Cruijssen


-1 nhiều hơn với var thay vì dài
ASCII - chỉ




2

Võng mạc 0.8.2 , 21 byte

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

Hãy thử trực tuyến! Liên kết bao gồm các trường hợp thử nghiệm. 9trở thành a. Giải thích: regex khớp với tất cả các dấu f-s cộng với một ký tự đứng trước. Việc chuyển ngữ sau đó tăng theo chu kỳ các ký tự đó như thể chúng là các chữ số hex. Cách tiếp cận thay thế, cũng 21 byte:

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

Hãy thử trực tuyến! Liên kết bao gồm các trường hợp thử nghiệm. Hoạt động bằng cách hạ thấp đầu vào để đơn giản hóa việc chuyển ngữ. Do đó sẽ là 15 byte nếu nó chỉ phải hỗ trợ chữ thường. Hãy thử trực tuyến! Liên kết bao gồm các trường hợp thử nghiệm.


2

MATLAB, 138 byte

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

Đã sửa lỗi trong trường hợp một đoạn là tất cả số không. Cũng chơi golf rất nhiều bằng cách lạm dụng thử / bắt. Kết quả ròng: 0 byte được lưu.

Cố gắng 'gian lận' bằng cách sử dụng java.util.UUIDthất bại vì longgiá trị được trả về java.util.UUID.get[Most/Least]SignificantBitsđược chuyển đổi thành giá trị doublephát sinh mất độ chính xác. Tôi mời bạn hãy nhìn vào cái bàn này và im lặng thốt lên "... nhưng tại sao? "

Giải trình

Các hex2decchức năng spits ra một double, vì vậy nó không thể xử lý toàn bộ GUID cùng một lúc để tránh vượt quá flintmax. Thay vào đó, chúng tôi phải xử lý đoạn GUID bằng chunck, bằng cách sử dụng split. Biến akiểm tra nếu chúng ta cần mang theo một cái, và gian lận cũng là gia số ban đầu chúng ta thêm vào. Điều kiện để thực hiện là liệu độ dài của chuỗi gốc và chuỗi tăng không còn bằng nhau nữa.

Phiên bản gốc chỉ dưới 160 byte, vì vậy tôi muốn nghĩ rằng điều này không dễ để vượt qua.



2

C # (Trình biên dịch tương tác Visual C #) , 77 byte

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

Hãy thử trực tuyến!

-1 byte nhờ @ASCIIOnly!

Hàm ẩn danh lấy char[]đầu vào và đầu ra bằng cách sửa đổi một đối số .

Đầu vào được quét từ phải sang trái và được thay thế bằng các quy tắc sau.

  • Các - vật bị bỏ qua và tiếp tục xử lý
  • Nhân Fvật được chuyển đổi thành0 và tiếp tục xử lý
  • 9tự được chuyển đổi thành Avà dừng xử lý
  • Các ký tự A-E0-8được tăng thêm 1 và dừng xử lý

2
==70->>69
ASCII - chỉ

Tuyệt vời - Cảm ơn :)
dana

2

Powershell, 101 byte

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

Hãy thử trực tuyến!

Không có thư viện bên ngoài hoặc chuyển đổi hex. Bất kỳ chiều dài chuỗi. Chữ thường và chữ hoa được cho phép Kết hợp chuỗi đầu vào^[f-]*$ cũng được cho phép.

Kịch bản lệnh này quét từ mặt sau của chuỗi và nhập từng char theo giá trị từ hashtable:

  • -: tăng = 1-1
  • 9: gia tăng = 1 + 7, kết quả =A
  • F: gia tăng = 1-23, kết quả =0
  • f: gia tăng = 1-55, kết quả =0
  • gia tăng = 1 cho các ký tự khác

Tiếp theo, tập lệnh sử dụng $pđể xác định xem có tăng char hiện tại hay không.

Kịch bản thử nghiệm:

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

Đầu ra:

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 byte

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

Hãy thử trực tuyến!

Câu trả lời khá tầm thường. Chỉ cần nghĩ rằng tôi sẽ nhận được PowerShell yêu quý được thêm vào danh sách :)



0

Perl 5, 64 byte

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

Số lượng dấu ngoặc đơn cần thiết ở đây làm tôi buồn, nhưng ->liên kết rất chặt chẽ, như->as_hex là cách nhanh nhất tôi có thể tìm thấy để có được đầu ra có định dạng thập lục phân.

Chạy với perl -Mbigint -p. Về cơ bản, nó chỉ chuyển đổi số thành thập lục phân bigint, thêm một và sau đó trừ các chữ số của kết quả trở lại giá trị ban đầu, không để lại dấu gạch ngang.


0

Rust, 258 byte

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('-')));

vâng, nó dài .. nhưng về mặt kỹ thuật chỉ có một dòng với 1 biểu thức? và không có thư viện ưa thích? và nó sẽ không sụp đổ trên một đầu vào 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('-')));

thử nó trên sân chơi rỉ sét



0

Mã lắp ráp 16/32 / 64-bit x86, 28 byte

byte: 83C623FDAC3C2D74FB403C3A7502B0613C677502B03088460173E9C3

mã:

     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

Gọi với ESI chỉ vào GUID. Thay thế ESI bằng SI cho 16 bit hoặc RSI cho 64 bit (và +2 byte).


0

C (tiếng kêu) , 62 byte

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

Hãy thử trực tuyến!


chờ đợi. kiểm tra chữ thường / chữ hoa không mất gì ???
ASCII - chỉ

ý tôi là, nó có thể xử lý cả chữ thường chữ hoa mà không mất phí
ASCII - chỉ

À ok .. ch-70% 32? : đến '0' ... 64 và 96 là bội số của 32 nên 70-6 và 102-6% 32.
AZTECCO

1
bạn thực sự không phải xử lý cả hai, vì vậy 64
ASCII - chỉ

0

Lisp chung, 166 byte

(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#))))

Hãy thử trực tuyến!

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.