# Question
Title: Compute the Redwolf Checksum™ of some data
*I will preface this by saying that I made this for fun; I have absolutely no formal knowledge on cryptography or error correction. Do not use this algorithm in anything remotely important.*

I was kind of bored a few days ago, so I decided to write a simple function to take some data and return an easily memorable (but not necessarily secure :p) checksum of it. The output format is a number of digits in base 36, between `0` and `z` (think of it like hexadecimal, but with all the letters used).

Your program or function will take two inputs: `data`, and `block_size`. The `data` will be a list of values `0` to `255`, and the `block_size` will be at least `4`. It will return a base 36 string (or list of values 0-36) with the length `block_size`.

Using `[182, 109, 211, 144, 65, 109, 105, 135, 151, 233]` and `4` as the inputs, this is how you would find the checksum:

1. The length of the `data` is padded with zeroes to a multiple of the `block_size`

```
182, 109, 211, 144, 65, 109, 105, 135, 151, 233, 0, 0

```
2. The `data` is broken into blocks based on the `block_size`

```
182  109  211  144
 65  109  105  135
151  233    0    0

```
3. For each item `n` of the resulting block, take the sum of all items at position `n` in one of the above blocks mod 256

```
  182  109  211  144
+  65  109  105  135
+ 151  233    0    0
--------------------
  142  195   60   23

```
4. Take the binary representation of each item in the result

```
10001110
11000011
00111100
00010111

```
5. For each item, add the least significant five bits of the next (wrapping) item, and the least significant bit of the (wrapping) item after that (note that this value can be higher than `256`)

```
   10001110   11000011   00111100   00010111
+     00011      11100      10111      01110
+         0          1          0          1
--------------------------------------------
   10010001   11100000   01010011   00100110

```
6. Convert back to decimal, and take the mod 36

```
1, 8, 11, 2

```
7. Covert into base 36

```
18b2

```

A reference implementation can be found here. Input and output can be in any reasonable manner.

This is , so shortest in bytes per language wins!

## Test cases

```
[]; 8                           -> 00000000
[0, 1, 2, 3, 4, 5, 6, 7]; 8     -> 14589cd8
[0, 1, 2, 3, 4, 5, 6, 7]; 6     -> eb589b
[0, 4, 2, 1]; 48                -> 473100000000000000000000000000000000000000000000
[195, 180, 1, 0]; 4             -> 0123
[31, 32, 65, 4]; 4              -> wxyz
[20, 8, 247, 41]; 4             -> tw4p
[250, 175, 225, 200]; 4         -> ewhb
[33]; 3                         -> (does not need to be handled)

```

# Answer
> 6 votes
## Thumb-2 (ARMv6T2, no div instructions), ~~118~~ ~~116~~ ~~112~~ 110 bytes (ascii base 36)/102 bytes (values)

I believe there is still some optimization room for sure.

Raw machine code, 16-bit hex little endian

Base 36 ASCII version:

```
b5f0 ebad 0d03 466f 001d 2600 3d01 557e
d1fc b151 5dbc f810 5b01 192d 55bd 1c76
429e bf08 2600 3901 d1f4 003c 1e9d 7866
78a1 f000 f80c 3d01 d1f9 7866 7839 f000
f806 783e 7879 f000 f802 449d bdf0 f814
0b01 f006 061f 0849 4170 3824 dafd f110
01fb bfc8 3027 3054 f802 0b01 4770

```

Without ASCII conversion ('values')

```
b5f0 ebad 0d03 466f 001d 2600 3d01 557e
d1fc b151 5dbc f810 5b01 192d 55bd 1c76
429e bf08 2600 3901 d1f4 003c 1e9d 7866
78a1 f000 f80c 3d01 d1f9 7866 7839 f000
f806 783e 7879 f000 f802 449d bdf0 f814
0b01 f006 061f 0849 4170 3824 dafd 3024
f802 0b01 4770

```

Uncommented assembly:

```
        .syntax unified
        .arch armv6t2
        .thumb
        .globl redwolf
        .thumb_func
redwolf:
        push    {r4-r7,lr}
        sub.w   sp, sp, r3
        mov     r7, sp
        movs    r5, r3
        movs    r6, #0
.Lmemset_loop:
        subs    r5, #1
        strb    r6, [r7, r5]
        bne     .Lmemset_loop
.Lmemset_loop_end:
        cbz     r1, .Lsum_loop_end
.Lsum_loop:
        ldrb    r4, [r7, r6]
        ldrb.w  r5, [r0], #1
        adds    r5, r4
        strb    r5, [r7, r6]
        adds    r6, #1
        cmp     r6, r3
        it      eq
        moveq   r6, #0
        subs    r1, #1
        bne     .Lsum_loop
.Lsum_loop_end:
        movs    r4, r7
        subs    r5, r3, #2
.Lchecksum_loop:
        ldrb    r6, [r4, #1]
        ldrb    r1, [r4, #2]
        bl      checksum
        subs    r5, #1
        bhi     .Lchecksum_loop
.Lchecksum_loop_end:
        ldrb    r6, [r4, #1]
        ldrb    r1, [r7]
        bl      checksum
        ldrb    r6, [r7]
        ldrb    r1, [r7, #1]
        bl      checksum
        add     sp, r3
        pop     {r4-r7, pc}

        .thumb_func
checksum:
        ldrb.w  r0, [r4], #1
        and.w   r6, r6, #31
        lsrs    r1, r1, #1
        adcs    r0, r6
.Lmodulo_loop:
        subs    r0, #36
        bge     .Lmodulo_loop
.Lmodulo_loop_end:
#ifdef ASCII
        cmp.w   r0, #9 - 36
        it      gt
        addgt   r0, #'a'-10-'0'
        adds    r0, #'0'+36
#else
        adds    r0, #36
#endif
        strb.w  r0, [r2], #1
        bx      lr

```

Try it online! (sorta)

### Explanation

C signature:

```
void redwolf(const uint8_t *data, size_t data_size, char *block, size_t block_size);

```

First, we push our registers and set up a VLA. (`uint8_t chars[block_size]`)

```
        push    {r4-r7,lr}
        sub.w   sp, sp, r3

```

Since we like narrow instructions, and there is no narrow `ldrb Rd, [Sp, Rn]` instruction, we use a frame pointer to cut down code size.

```
        mov     r7, sp

```

Zero out the VLA we created.

```
        movs    r5, r3
        movs    r6, #0
.Lmemset_loop:
        subs    r5, #1
        strb    r6, [r7, r5]
        bne     .Lmemset_loop

```

If we have data, sum everything up.

```
.Lmemset_loop_end:
        cbz     r1, .Lsum_loop_end
.Lsum_loop:
        ldrb    r4, [r7, r6]
        ldrb.w  r5, [r0], #1
        adds    r5, r4
        strb    r5, [r7, r6]

```

`r6 = (r6 + 1) % block_len` without division

```
        adds    r6, #1
        cmp     r6, r3
        it      eq
        moveq   r6, #0

```

Decrement data\_len and loop if non-zero.

```
        subs    r1, #1
        bne     .Lsum_loop

```

Now, we checksum the data and convert to base 36.

We do a simple loop for all but the last two bytes in `chars`, calling a subroutine (with a custom calling convention) to handle the arithmetic.

We pass the second two bytes as parameters, while `checksum()` will do `*r4++` to load the first byte and increment.

```
.Lsum_loop_end:
        movs    r4, r7
        subs    r5, r3, #2
.Lchecksum_loop:
        ldrb    r6, [r4, #1]
        ldrb    r1, [r4, #2]
        bl      checksum
        subs    r5, #1
        bne     .Lchecksum_loop

```

Process the wrapped data. I feel this could be optimized better.

```
.Lchecksum_loop_end:
        ldrb    r6, [r4, #1]
        ldrb    r1, [r7]
        bl      checksum
        ldrb    r6, [r7]
        ldrb    r1, [r7, #1]
        bl      checksum

```

Restore the stack, pop registers, and return.

```
        add     sp, r3
        pop     {r4-r7, pc}

```
checksum subroutine

We call `checksum` with `r6 = chars[i + 1]` and `r1 = chars[i + 2]`, with `r2` still pointing to `block`.

Load `chars[i]` from `r4` and increment the pointer. This is a step outlined from the other three calls.

```
        ldrb.w  r0, [r4], #1

```

Now we need to do `chars[i] + (chars[i + 1] & 31) + (chars[i + 2] & 1)`.

First, we mask the lowest five bits of `chars[i + 1]`.

```
        and.w   r6, r6, #31

```

Now, we use `lsrs` to get the lowest bit of `chars[i + 2]` in the carry flag...

```
        lsrs    r1, r1, #1

```

...so we can add them both with an add-with-carry. Done.

```
        adcs    r0, r6

```

Modulo by 36 using a naïve subtraction loop. No `udiv` required. Not that I would use it anyways - `movs` \+ `udiv` \+ `mls` would be 10 bytes, this is 4.

Note that this will end up negative, we need to add 36 after to get the correct result.

```
.Lmodulo_loop:
        subs    r0, #36
        bge     .Lmodulo_loop

```

Convert to base 36 (ascii version):

If r0 + 36 is \> 9, we add the additional offset to get it from `r0 + '0'` to `r0 + 'a' - 10`.

```
.Lmodulo_loop_end:
        cmp.w   r0, #9 - 36
        it      gt
        addgt   r0, #'a'-10-'0'
        adds    r0, #'0' + 36

```

Adjust offset (non-ascii)

If we are outputting integers, just add 36.

```
        adds    r0, #36

```

Store the char into block and increment the pointer.

```
        strb.w  r0, [r2], #1

```

Return back to the main function.

```
        bx      lr

```

# Answer
> 5 votes
# K (ngn/k), ~~84~~ ~~67~~ 63 bytes

-17 bytes by reshuffling things, inspired by @Neil's comment, -4 bytes from more golfing

```
{(`c$&2!&49\5673099)36!+/256 32 2!'y':(y+2)#+/(0N;y)#x,&y-y!#x}

```

Try it online!

* `+/(0N;y)#x,&y-y!#x` take the column-wise sum of the input split into `y`-length chunks (filling with 0s)
* `y':(y+2)#` build a list containing the original input, it rotated once, and it rotated twice
* `256 32 2!'` mod the original input by 256, the rotated-once input by 32, and the rotated-twice input by 2
* `36!+/` sum column-wise, modding by 36
* `(`c$&2!&49\5673099)` build list of base-36 characters (digits followed by lower case letters), which is indexed into by the results of the above

# Answer
> 4 votes
# , 59 bytes

```
(Num_j_,Alpha_j_){~]($!.0)36|[:+/256 32 2|i.@3|."{+/@([\~-)

```

Try it online!

* `([\~-)` data x split in blocks of size y, padded with zeros
* `+/@` sum each column
* `i.@3|."{` rotate row by 0, 1 and 2, so we get 3 rows
* `256 32 2|` mod rows by 256, 32 and 2
* `[:+/` sum again
* `36|` mod 36
* `]($!.0)` lengthen list to size of y, padded with zeros
* `(Num_j_,Alpha_j_){~` take the indices from `0…Z`

# Answer
> 4 votes
# 05AB1E, ~~24~~ 18 bytes

```
ιO₁%DÀ31&DÀÉ++₆%₆B

```

Try it online! or Try all cases!

**Commented**:

```
ι                    # create block_size lists of every block_size-th element
                     #   [data[0::block_size], data[1::block_size], ..., data[block_size-1::block_size]]
 O                   # sum each list
  ₁%                 # modulo 256
    DÀ               # duplicate the resulting list and rotate the copy left
      31&            # bitwise and 31 / take the 5 least significant bits
         DÀ          # duplicate this list and rotate left again
           É         # is the value odd? / least significant bit
            ++       # sum the three lists element-wise
              ₆%     # modulo 36
                ₆B   # convert to base 36

```

# Answer
> 3 votes
# JavaScript (ES6),  ~~122 121~~  114 bytes

Expects `(data)(block_size)`. Returns an array of characters.

```
a=>w=>a.map((v,i)=>b[i%w]+=v,b=new Uint8Array(w))&&[...b].map((v,j)=>((v+b[++j%w]%32+b[-~j%w]%2)%36).toString(36))

```

Try it online!

## Commented

### Step 1 to step 3

```
a.map((v, i) =>         // for each value v at position i in a[]:
  b[i % w] += v,        //   add v to b[i mod w]
                        //   there's an implicit modulo 256 because ...
  b = new Uint8Array(w) //   ... b[] is initialized to an array of w unsigned bytes
)                       // end of map()

```

### Step 4 to step 7

```
[...b]                  // we need to split b[] so that the results returned by the
                        // callback function of map() are not forced to unsigned bytes
.map((v, j) =>          // for each value v at position j in b[]:
  (                     //
    ( v +               //   compute the sum of v
      b[++j % w] % 32 + //   and b[(j + 1) mod w] mod 32
      b[-~j % w] % 2    //   and b[(j + 2) mod w] mod 2
    ) % 36              //   modulo 36
  ).toString(36)        //   converted to base-36
)                       // end of map()

```

# Answer
> 3 votes
# , 122 bytes

```
function(d,b,m=matrix)c(0:9,letters)[1+colSums(m(rowSums(m(c(d,!1:(b-sum(d|1)%%b)),b))%%256,b+1,b)[1:3,]%%2^c(8,5,1))%%36]

```

Try it online!

Output as a list of base 36 digits (lowercase).

# Answer
> 2 votes
# Pip, 87 bytes

```
Y($+_)%256M(@>g<>@g)ZD0
((,tALz)Jx)@_M($+_)%36M Z[{@RVTBa}My{FB((TBa)@>-5)}M(@>y)AL@yy]

```

Try it online!

This was much harder than I expected.

Input is taken as a list of lines. First line is `block_size`, rest of the lines are the data.

# Answer
> 2 votes
# Perl 5 `-a`, 96 bytes

```
$#r=<>-1;map$r[$i++%@r]+=$_,@F;say map{((0..9,a..z)x9)[$_%256+$r[++$j%@r]%32+$r[($j+1)%@r]%2]}@r

```

Try it online!

# Answer
> 2 votes
# Python 3.8 (pre-release), ~~161~~ 159 bytes

```
lambda d,b:(d:=d+[0]*(b-len(d)%b),r:=range(b),s:=[sum(d[i::b])%256for i in r],[[str(k:=(s[i]+(s[(i+1)%b]&31)+(s[(i+2)%b]&1))%36),chr(k+87)][k>9]for i in r])[2]

```

Try it online!

Edit:

* changed `range` to variable to reduce 2 characters

# Answer
> 1 votes
# Ruby, 106 bytes

```
->a,n,c=[0]*n{a.size.times{|i|c[i%n]+=a[i]&255};(1..n).map{|i|((c[i-1]+c[i%n]%32+c[-~i%n]%2)%36).to_s 36}}

```

Try it online!

# Answer
> 1 votes
# Charcoal, 29 bytes

```
⭆η⍘﹪ΣＥ851﹪↨Φθ¬﹪⁻⁻ξμιη¹Ｘ²Ｉλ³⁶φ

```

Try it online! Link is to verbose version of code. Explanation:

```
 η                              Block size
⭆                               Map over implicit range and join
      851                       Literal string `851`
     Ｅ                          Map over characters
            θ                   Data array
           Φ                   Filtered where
                 ξ              Data index
                ⁻               Minus
                  μ             Character index
               ⁻                Minus
                   ι            Outer index
              ﹪                 Modulo
                    η           Block size
             ¬                  Leaves no remainder
          ↨          ¹          Convert from base 1
         ﹪                      Modulo
                       ²        Literal `2`
                      Ｘ         Raised to power
                         λ      Current character
                        Ｉ       Cast to integer
    Σ                           Take the sum
   ﹪                            Modulo
                          ³⁶    Literal 36
  ⍘                         φ   Convert to 0-z
                                Implicitly print

```

At one point conversion from base 1 is used to take the sum in case the list is empty (in which case the conversion is zero but the sum is None).

# Answer
> 1 votes
# Pyth, 55 bytes

```
KeQJm%sd256.TchQKsm@+."/9ª!"G%++@Jd%@Jhd32%@Jhhd2 36K

```

Try it online!

---
Tags: code-golf, base-conversion, checksum
---


title: Rotating a 2D Matrix

text:
# Question
Title: Rotating a 2D Matrix
Let's say I have the following (2D) matrix:

```
[[1,  2,  3,  4 ],
 [5,  6,  7,  8 ],
 [9,  10, 11, 12],
 [13, 14, 15, 16]]

```

Rotate the matrix *counterclockwise* `R` times (not in 90 degree increments, just by 1 number each time),

```
1  2  3  4             2 3   4  8         3   4   8  12
5  6  7  8    -->      1 7  11 12   -->   2  11  10  16
9  10 11 12            5 6  10 16         1   7   6  15
13 14 15 16            9 13 14 15         5   9  13  14

```

Completed example:

Input:

```
2
[[1,  2,  3,  4 ],
 [5,  6,  7,  8 ],
 [9,  10, 11, 12],
 [13, 14, 15, 16]]

```

Output:

```
[[3,  4,  8, 12],
 [2, 11, 10, 16],
 [1,  7,  6, 15],
 [5,  9, 13, 14]]

```

(weird spaces are to align the numbers in nice columns)

The outer "ring" of the matrix rotates 2 counterclockwise, and the inner right rotates 2 also. In this matrix, there are only two rings.

An example with 1 "ring":

```
2
[[1, 2],
 [3, 4],
 [5, 6]]

```

Should output:

```
[[4, 6],
 [2, 5],
 [1, 3]]

```

Your challenge is to take in a matrix and an integer `R`, and output the translated version after `R` rotations.

Rotation of a 4x5 matrix is represented by the following figure:

**Constraints:**

* `2 ≤ M, N ≤ 100`, where M and N are the dimensions of the matrix. It is guaranteed that the minimum of M and N will be even.
* `1 ≤ R ≤ 80`, where r is number of rotations.
* The matrix will only ever contain positive integers.
* Values are not always distinct.
* The input should always be as a 2D array (if you can't take runtime input as a 2D array, then you just have to find another way to get input).

Another test case, with non-distinct values:

```
1
[[1, 1],
 [2, 2],
 [3, 3]]

```

Outputs:

```
[[1, 2],
 [1, 3],
 [2, 3]]

```

This is , so the shortest answer wins!

# Answer
# Jelly, ~~39~~ ~~38~~ ~~36~~ 35 bytes

```
ḢṚ;Ḣ€;Ṫ;Ṫ€Ṛ$,-ṙ\;"ß¹¡
FJ©ṁ¹Çy®ịFṁµ¡

```

Try it online!
> 6 votes

# Answer
# Octave, 210 bytes

```
function M=F(M,R);f=@(z)[-z/2:-1 !eye(!!mod(z,2)) 1:z/2];t=angle(f([x y]=size(M))'+f(y)*i);B=!!M;B(2:x-1,2:y-1)=0;d=bwdist(B,'ch');[~,I]=sortrows([d(:) t(:)]);for k=0:max(d(:));M(h)=shift(M(h=I(d(I)==k)),R);end

```

Try it on Octave Online!

Ungolfed version:

```
function M=F(M,R)
    [x y]=size(M);
    f=@(z)[-z/2:-1 !eye(!!mod(z,2)) 1:z/2];
    t=angle(f(x)'+f(y)*i);
    B=!!M;
    B(2:x-1,2:y-1)=0;
    d=bwdist(B,'chessboard');
    [~,I]=sortrows([d(:) t(:)]);
    for k=0:max(d(:))
        M(h)=shift(M(h=I(d(I)==k)),R);
    end
end
R=2;
M=randi(10,4,7)
F(M,R)

```

Explanation:

```
f=@(z)[-z/2:-1 !eye(!!mod(z,2)) 1:z/2];

```

A function that gets a number and generates a range that is ordered and centered for input 4 (even) generates `-2 -1 1 2`
for input 5(odd) generates `-2.5 -1.5 0 1 2`
only it should be ordered and centered

```
f(x)'+f(y)*i

```

a complex matrix generated from ranges

```
(-2,-2.5) (-2,-1.5) (-2,0) (-2,1) (-2,2)
(-1,-2.5) (-1,-1.5) (-1,0) (-1,1) (-1,2)
(1,-2.5)  (1,-1.5)  (1,0)  (1,1)  (1,2)
(2,-2.5)  (2,-1.5)  (2,0)  (2,1)  (2,2)

t=angle(f(x)'+f(y)*i);

```

Convert rectangular to polar coordinates and return angles so for each ring angles are sorted counteclockwise

```
-2.25  -2.50  3.14  2.68  2.36
-1.95  -2.16  3.14  2.36  2.03
-1.19  -0.98  0.00  0.79  1.11
-0.90  -0.64  0.00  0.46  0.79

B=!!M;
B(2:x-1,2:y-1)=0;

```

The following matrix generated

```
1   1   1   1   1
1   0   0   0   1
1   0   0   0   1
1   1   1   1   1

d=bwdist(B,'chessboard');

```

Computes the distance transform of B using chessboard distance to generate ring indices

```
0   0   0   0   0
0   1   1   1   0
0   1   1   1   0
0   0   0   0   0

```

for a 6 * 7 matrix we will have the following matrix

```
0   0   0   0   0   0   0
0   1   1   1   1   1   0
0   1   2   2   2   1   0
0   1   2   2   2   1   0
0   1   1   1   1   1   0
0   0   0   0   0   0   0

[~,I]=sortrows([d(:) t(:)]);

```

lexicographic sort first based on ring index and then by order of angle(indices of sorted elements returned)

```
    for k=0:max(d(:))
        M(h)=shift(M(h=I(d(I)==k)),R);
    end

```

and finally circular shift each ring.
> 6 votes

# Answer
# Python 3, ~~292~~ 288 bytes

```
_=eval
a=input().split()
b,a=int(a[0]),_("".join(a[1:]))[::-1]
c=len(a)
d=len(a[0])
e=range
f="int((i>=j and i+j<c-1)|2*(i>=c/2and i+d>j+c)|3*(i<c/2and i+j<d))"
l=[-1,1,0,0],[0,0,1,-1]
g=lambda x:[[x[i+l[0][_(f)]][j+l[1][_(f)]]for j in e(d)]for i in e(c)]
print(_("g("*b+"a"+")"*b)[::-1])

```

Takes input with newlines removed, but leaving a space after the number of increments to rotate it by.

## Explanation:

Instead of modeling the matrix as a series of concentric rings per the OP's suggestion, one can instead divide it into four regions where the elements travel either up, down, right, or left during a single rotation. This is the purpose of the long eval-ed string `f`: to determine which region each `i,j` combination falls into. Then, the result of that is looked up twice in `l`, giving the element that must rotate into position `i,j` in the next step. The function `g` that does all of this and forms the new matrix after a single step is then called repeatedly by evaling a generated string containing the representation of a nested function call.

When I made this originally, I accidentally caused the matrix to rotate clockwise instead of counterclockwise. Rather than doing a proper fix, I added two strategically placed copies of `[::-1]` to reverse the matrix before and after the rotation. These could probably be golfed off to ~~~280~~ 276 bytes, but I'm too lazy to do that.

Also, this is a quick untested port from a slightly longer Python 2 program, so forgive me if it doesn't work quite right. Here's the Python 2 code, anyways:

```
_=eval
a=raw_input().split()
b,a=int(a[0]),_("".join(a[1:]))[::-1]
c=len(a)
d=len(a[0])
e=xrange
f="int((i>=j and i+j<c-1)|2*(i>=c/2and i+d>j+c)|3*(i<c/2and i+j<d))"
l=[-1,1,0,0],[0,0,1,-1]
g=lambda x:[[x[i+l[0][_(f)]][j+l[1][_(f)]]for j in e(d)]for i in e(c)]
print _("g("*b+"a"+")"*b)[::-1]

```

EDIT: Golfed off 4 bytes by replacing `or` with `|` twice. `and` can't be helped, unfortunately.
> 4 votes

# Answer
# K (ngn/k), ~~78 76 60~~ 64 bytes

-16 bytes from using @ngn's version

+4 because of changes in the language (prototypes)

```
{(,()){(,y),+|x}/|,/{1_{1_y,*x}':x,,*x}'0N 4#-1_*'(*:)(|+1_)\x}/

```

Try it online!

* `{...}/` use the "do" variant of `/` to run the function `x` times, seeded with `y` and returning the last result. (each iteration rotates each ring of the input matrix one position)
* `(*:)(|+1_)\x` peel off the first row, rotating the remainder until there's nothing left, accumulating the results into a list
* `-1_*'` take the first item of each (i.e. the "top-most" slice of the outer ring). drop the last item, as it's empty
* `0N 4#` reshape the flat list into groups of four items; each group represents one "ring" of the input matrix
* `{...}'` for each ring...
    + `x,,*x` append a copy of the first ring slice
    + `1_{1_y,*x}':` for each slice of the ring, append the first item of the current slice to the previous slice, dropping the first value of the result. (this has the effect of rotating the values in each ring one position)
* `(,()){...}/|,/` set up a `/`, seeded with an empty list and run over the flattened and reversed ring slices...
    + `(,y),+|x` where we prepend each ring slice to the rotated and transposed result so far
> 3 votes

# Answer
# Perl, ~~330~~ 328 bytes

```
sub f{($r,$m)=@_;$h=@m=@$m;for$s(0..(($w=$#{$m[0]})<--$h?$w:$h)/2-.5){@_=(@{$m[$s]}[@x=$s..($x=$w-$s)],(map$m[$_][$x],@y=1+$s..($y=$h-$s)-1),reverse(@{$m[$y]}[@x]),(map$m[$h-$_][$s],@y));push@_,shift
for 1..$r;@{$m[$s]}[@x]=map shift,@x;$m[$_][$x]=shift for@y;@{$m[$y]}[@x]=reverse map shift,@x;$m[$h-$_][$s]=shift for@y}@$m=@m}

```

Try it on Ideone.

Ungolfed:

```
sub f {
    my ($r, $m) = @_;

    my @m = @$m;
    my $h = $#m;
    my $w = @{$m[0]} - 1;
    my $c = (($w < $h ? $w : $h) + 1) / 2 - 1;

    for my $s (0 .. $c) {
        my $x = $w - $s;
        my $y = $h - $s;
        my @x = $s .. $x;
        my @y = $s + 1 .. $y - 1;

        # One circle.
        @_ = (@{$m[$s]}[@x],
              (map { $m[$_][$x] } @y),
              reverse(@{$m[$y]}[@x]),
              (map { $m[$h - $_][$s] } @y));

        # Circular shift.
        push(@_, shift(@_)) for 1 .. $r;

        @{$m[$s]}[@x] = map { shift(@_) } @x;
        $m[$_][$x] = shift(@_) for @y;
        @{$m[$y]}[@x] = reverse(map { shift(@_) } @x);
        $m[$h - $_][$s] = shift(@_) for @y;
    }

    @$m = @m;
}

```
> 1 votes

---
Tags: code-golf, array, matrix
---


title: Test the endianness

text:
# Question
Title: Test the endianness
Given a UTF-16 string, test its endianness.

**Rules:**

1. As long as the input is in UTF-16 **without BOM**, its type doesn't matter. In C++ on Windows, it can be `std::wstring` or `std::u16string`. In Haskell, it can be `[Int16]` or `[Word16]`.
2. The endianness is tested by noncharacters. If the input contains a noncharacter, it is in wrong endianness.
3. If the original version and the endianness-swapped version both or neither contain a noncharacter, the test is inconclusive.
4. The type of the output must be well-ordered. Output 1 (or an equivalent enumerator) when the input is in right endianness, or -1 (or an equivalent enumerator) when the input must be endianness-swapped, or 0 (or an equivalent enumerator) when the test is inconclusive. For example, in Haskell, `Ordering` is a valid output type.
5. Wrong UTF-16 sequences are also treated as noncharacters. (So the noncharacters are: Encodings of code point from U+FDD0 to U+FDEF, encodings of code point U+XXFFFE and U+XXFFFF with XX from 00 to 10, and unpaired surrogates.)
6. As this is a code golf, the shortest code in bytes wins.

**Examples:**

Assume we're in Haskell, the system is a big-endian, and `Ordering` is the output type. When given the following byte sequence:

```
00 00 DB FF DF FE

```

Because it encodes the noncharacter U+10FFFE, the output must be:

```
LT

```

For the following byte sequence:

```
00 00 00 00 00 00

```

The output must be:

```
EQ

```

For the following byte sequence:

```
FE FF

```

Since the endianness-swapped version encodes the noncharacter U+FFFE, the output must be:

```
GT

```

# Answer
# ARM Thumb-2, ~~108~~ ~~90~~ 84 bytes

Machine code:

```
b5f2 2300 f000 f822 9900 000a 3a02 5a84
ba64 5284 d1fa 425b f000 f818 bdf2 5a44
f64f 56d0 1ba7 2f20 d313 0ae7 2f1b d10a
b179 3902 0ae7 d30c 5a42 0a97 2f36 d108
3209 eb04 2482 b227 3702 d202 3902 d5e6
3b01 4770

```

Commented assembly:

```
        .syntax unified
        .arch armv6t2
        .text
        .thumb
        .globl check_utf16
        .thumb_func
        // r0: string, r1: len in BYTES
        // The string will be clobbered as an internal buffer.
        // Returns in r3.
check_utf16:
        push    {r1, r4, r7, lr}
        // Set starting return value to 0. This will accumulate both results.
        movs    r3, #0
        // First, check little endian.
        // Yes, I did bl to the middle of a function. :P
        bl      .Ltest.entry
        // Reload the length, as test clobbered it.
        ldr     r1, [sp]
        // Byteswap the string.
        movs    r2, r1
.Lbswap_loop:
        // Looping backwards...
        subs    r2, #2
        // Load a halfword to r4,
        ldrh    r4, [r0, r2]
        // do a 16-bit byteswap,
        rev16   r4, r4
        // and store it back.
        strh    r4, [r0, r2]
        bne     .Lbswap_loop
.Lbswap_loop.end:
        // Negate r3 to make the start return value from native endianness positive.
        // Then, we subtract the big endian version from this to get the -1/0/1 result.
        negs    r3, r3
        // and call test again to check big endian
        bl      .Ltest.entry
        pop     {r1, r4, r7, pc}

.Ltest_loop:
        // Read the next character
        ldrh    r4, [r0, r1]
        // Check for FDD0-FDEF.
        // First we subtract 0xFDD0...
        movw    r2, #0xFDD0
        subs    r7, r4, r2
        // ...and if it is (unsigned) less than 0x20, it is
        // bad. Return false.
        cmp     r7, #0x20
        blo     .Lfalse

        // Is it a surrogate?
        // Equivalent to (r4 & 0xF800) != 0xD800
        lsrs    r7, r4, #11
        cmp     r7, #0xD800 >> 11
        bne     .Lnot_surrogate

        // NOTE: We are looping backwards, that is why we check
        // trail surrogates first.
.Lis_surrogate:
        // Beginning of string == unpaired surrogate == bad
        cbz     r1, .Lfalse
        // Decrement r1
        subs    r1, #2

        // Is it a trail surrogate? We already know it is
        // a surrogate, so we only check the trail bit.
        // Uses lsrs's carry flag to test the 10th bit.
        // Equivalent to (r4 & 0x400) == 0
        lsrs    r7, r4, #11
        bcc     .Lfalse

        // Load the preceeding (hopefully) lead surrogate to r2.
        ldrh    r2, [r0, r1]
        // Is it a lead surrogate?
        // Equivalent to (r2 & 0xFC00) != 0xD800
        lsrs    r7, r2, #10
        cmp     r7, #0xD800 >> 10
        bne     .Lfalse

        // We have two surrogates, let's merge them into a
        // full codepoint.
        //
        // Just kidding. We only need the low 16 bits, so we can take
        // a huge shortcut and let sxth correct any overflow.
        //
        // utfcpp showed us that converting a UTF-16 pair to UTF-32
        // is simply this:
        //     0xfca02400 + trail + (lead << 10)
        // where 0xfca02400 is the constant fold of this:
        //     0x10000 - (LEAD_SURROGATE_MIN << 10) - TRAIL_SURROGATE_MIN
        //
        // Since we are only using 16 bits, we can just add 0x2400
        // instead. That saves 4 bytes, as we can do a wide add.
        //
        // HOWEVER, we can do even better: 0x2400 has the low 10 bits
        // clear, and since we need to shift the lead surrogate 10
        // bits to the left, we can just add 0x2400 >> 10 (or 0x09)
        // to the lead surrogate, then do trail + (lead << 10).
        //
        // This means that instead of generating a 32-bit constant
        // into a register, we can use the immediate narrow form of
        // adds, saving 6 bytes (4 for literal, 2 for ldr).
        adds    r2, #0x2400 >> 10
        add.w   r4, r4, r2, lsl #10
.Lnot_surrogate:
        // At this point, r4 contains the low 16 bits of the
        // codepoint, and the upper bits are garbage.

        // Check for xxFFFE/F by sign extending and adding 2.
        // If it was, there will be a carry.
        // The act of sign extending eliminates all of those
        // garbage bits for us, allowing laziness in the surrogate
        // code.
        sxth    r7, r4
        adds    r7, #2
        bcs     .Lfalse

        .thumb_func
        // We actually bl here, so we can subtract first
        // on the first iteration.
        // The possibilities of assembly are endless.
.Ltest.entry:
        // Loop while we still have data.
        subs    r1, #2
        bpl     .Ltest_loop
.Ltrue:
        // Subtract 1 for true. This is negated for native endianness, and it
        // cancels out on both true.
        subs    r3, #1
.Lfalse:
        // return
        bx      lr

```

Test suite:

```
        .syntax unified
        .arch armv6t2
        .thumb
        // W+X because PIE sucks.
        .section ".writeable_text","awx",%progbits

.macro $TEST expected:req, argc:req, argv:vararg
        // Load string buffer into r0
        adr     r0, 1f
        // Convert element count to size in bytes by doubling.
        movs    r1, #\argc * 2
        // Skip over our constant pool
        b       3f
1:
        // The UTF-16 string
        .short \argv
        .align 2
2:
        // blatant abuse of macro stringification to avoid a printf loop :P
        .asciz "\argv"
        .align 2
3:
        // Call check_utf16
        bl      check_utf16
        // Stringified version of the UTF-16 string
        adr     r1, 2b
        // Expected
        movs    r2, #\expected
        // r3 is already in place
        adr     r0, .Lprintf_str
        // printf("{ %s } -> expected: %d, got: %d\n", STR(arr), expected, retval)
        bl      printf
.endm

        .globl main
        .thumb_func
main:
        push    {r4, lr}
        // Original test cases
        $TEST   -1, 3, 0x0000, 0xDBFF, 0xDFFE
        $TEST    0, 3, 0x0000, 0x0000, 0x0000
        $TEST    1, 1, 0xFEFF

        // I've added more test cases, feel free to take them
        // 1: D3FD becomes FDD3 when swapped, which is bad
        $TEST    1, 3, 0xD3FD, 0xD83D, 0xDE0F
        // 0: proper string with surrogates both ways
        $TEST    0, 3, 0x0A00, 0xD83D, 0xDE0F
        // -1: DF10 is a lone trail surrogate
        $TEST   -1, 1, 0xDF10
        // 1: D9E0 is a lone head surrogate
        $TEST    1, 1, 0xE0D9
        // 0: 0xffff is invalid in both endiannesses
        $TEST    0, 2, 0x0314, 0xFFFF
        pop     {r4, pc}
.Lprintf_str:
        .asciz "{ %s } -> expected: %d, got: %d\n"

```

Try it online! (sorta)

Has the following pseudo-signature:

```
int check_utf16(uint16_t *ptr, size_t length_in_bytes);

```

However, it is NOT C-callable, it returns in `r3` instead of `r0`.

Returns -1 if we need an endian swap, 0 if ambiguous, or 1 if we don't need an endian swap.

`lsrs` is the real MVP here. (☞^o^) ☞

Specifically, `lsrs`/`lsls` can do most usages of `ands` without setting up a constant or using a wide instruction. All of the "masking" operations can just be done by shifting right. This also lets us use a narrow `cmp`, as narrow `cmp` can only check `0-255`.

Additionally, I do a really dirty trick here: I only calculate the low 16 bits of a surrogate pair codepoint.

The optimized UTF-16 to UTF-32 conversion algorithm is this (magic number explained in comments):

```
uint32_t codepoint = 0xfca02400 + trail + (lead << 10);

```

However, `0xfca02400` is a 6 byte constant, 2 bytes for `ldr` and 4 bytes for the literal pool.

One thing to note is that I immediately discard the upper 16 bits of the codepoint by sign extending. Therefore, we only need to add the low 16 bits of the magic number, `0x2400`.

```
int16_t codepoint = 0x2400 + trail + (lead << 10);

```

This is much better, as we can do an immediate `add.w` instruction, saving 4 bytes.

However, `0x2400` has 10 trailing zero bits: it is simply `9 << 10`.

Therefore, we can do another optimization with the distributive property:

```
int16_t codepoint = trail + ((lead + (0x2400 >> 10)) << 10);
// int16_t codepoint = trail + ((lead + 9) << 10);

```

That is even better: we no longer need `add.w`, `9` fits perfectly into an immediate narrow `adds`, saving a total of 6 bytes!
> 5 votes

---
Tags: code-golf, string, unicode
---


title: Drag Race Countdown

text:
# Question
Title: Drag Race Countdown
# Challenge:

In a hypothetical scenario, the countdown timer for a race has *random intervals* between the counts, to prevent premature starting, e.g.

```
3 (0.82 seconds pass), 2 (0.67 seconds pass), 1

```

---

# Input:

nothing

---

# Output:

Write a program (or function) that prints the 3 numbers with a random time interval from 0.50 seconds to 1 second between each count.

---

# Note:

* The program must output each number (3 , 2 , 1) with the random (*any* number between 0.50 and 1 to the hundredths; no hard-coding) time interval between each. The precision of the random interval must go out to the hundreds (e.g: 0.52). You are not required to output the interval, only the count.
* As @JoKing clarified, I mean uniformly random (you can use the pseudo-random generator of your language.
* As many people have clarified, I really mean any 2-decimal number between 0.5 and 1. (0.50, 0.51, etc, all the way to 0.98, 0.99, 1)

---

This is , so the program with the lowest byte count wins.

# Answer
> 5 votes
# 05AB1E, 12 bytes

```
3LRε=₄D;ŸΩ.W

```

Try it online!

---

```
3LR          # Push [3,2,1]
   ε         # For each...
    =        # Print it.
     ₄       # Push 1000.
      D      # Duplicate top (1000).
       ;     # Divided by 2 (500).
        Ÿ    # Range from b to a ([1000 .. 500]).
         Ω   # Random pick.
          .W # Wait X ms.

```

---

Try it with debug enabled: Try it online!

# Answer
> 2 votes
# SmileBASIC, ~~64~~ 62 bytes

```
?3M?2M?1DEF M
M=MILLISEC
WHILE MILLISEC<M+500+RND(501)WEND
END

```

Unfortunately I can't use WAIT since that only supports intervals of 1/60 of a second (anything less isn't normally useful since input/output only update once per frame)

This requires adjustment depending on the speed of the system it's running on, so it might not be valid (46 bytes):

```
?3M?2M?1DEF M
FOR I=-66E4-RND(66E4)TO.NEXT
END

```

Invalid WAIT version (36 bytes):

```
?3WAIT 30+RND(30)?2WAIT 30+RND(30)?1

```

# Answer
> 2 votes
# , ~~46~~ 44 bytes

for an actual countdown:

```
for(i in 3:1){cat(i)
Sys.sleep(runif(1,.5))}

```

Try it online!

printing interval as I initially misunderstood the challenge (46 bytes) Thanks Giuseppe for saving 2 chars.

```
for(i in 3:1)cat(i,format(runif(1,.5),,2)," ")

```

Try it online!

# Answer
> 2 votes
# Python 2, 58 bytes

```
from time import*
for a in'321':print a;sleep(1-time()%.5)

```

Try it online!

I created a very simple random number generator that takes the seed time (as many people do).

---

Improvements

# Answer
> 1 votes
# JavaScript (Node.js), 75 65 60 bytes

* thanks to @Shaggy for reducing by 10 bytes
* thanks to @Kevin Cruijssen for reducing by 5 bytes

```
f=(i=3)=>i&&setTimeout(f,Math.random()*500+500,i-1,alert(i))

```

Try it online!

# Answer
> 1 votes
# Python 3, 122 bytes

```
import random as r,time
def w():time.sleep(abs(r.random()-.5)+.5)
print(3,end="");w();print(", 2",end="");w();print(", 1")

```

Try it online!

# Answer
> 1 votes
# APL+WIN, 37 bytes

```
3⋄r←⎕dl ↑n←.49+.01×2?51⋄2⋄r←⎕dl 1↓n⋄1

```

# Answer
> 1 votes
# Perl 5, 39 bytes

Gradually tweaked down to 39 bytes, thanks to @jonathan-allan + @xcali.

```
say-$_+select$a,$a,$a,1-rand.5for-3..-1

```

Try it online!

# Answer
> 1 votes
# Java 8, 86 bytes

```
v->{for(int i=0;++i<4;Thread.sleep((int)(Math.random()*500+500)))System.out.print(i);}

```

Prints without delimiter. If that is not allowed it's +2 bytes by changing `print` to `println` (new-line delimiter).

Try it online.
Prove the intervals are in the correct range of `[500, 1000)` ms.

**Explanation:**

```
v->{                        // Method with empty unused parameter and no return-type
  for(int i=0;++i<4;        //  Loop in range [1,4)
      Thread.sleep((int)(Math.random()*500+500)))
                            //    After every iteration: sleep for [500, 1000) ms randomly
     System.out.print(i);}  //   Print the current number

```

# Answer
> 1 votes
# Chip `-wingjj`, 33 bytes

```
0123456e7f s
???????p*9S!ZZZtaABb

```

Try it online!

In Chip, we cannot wait for exactly 1/100 of a second, but we can wait for 1/256 of a second, so we use that here.

`p`, when asked, will pause execution for the stack head (one byte) * 1/256 seconds. On each cycle, we always set the high bit of the stack (128/256) and set all other stack bits randomly (with the `?`'s). This gives an even distribution between 0.50 and 1.00 seconds.

Some of the args, `-w` and `-gjj`, specify that the input, instead of using stdin, should be a countdown from `0xFF` to `0x00` (then wrapping). We use this to provide the low two bits for counting down. All other output bits remain constant (at the value corresponding to ASCII `0`).

Finally, once we are done, we terminate the program with `t`, preventing a pause after the last number.

# Answer
> 1 votes
# Jelly, ~~21~~ 18 bytes

```
3RṚðṄṛ50r³÷³XœS@ð/

```

Try it online!

-3 bytes from xigoi.

## Explanation

from caird coinheringaahing.

```
3RṚðṄṛ50r³÷³XœS@ð/ - Main link. Takes no arguments on the left
3R                 - Generate the range [1, 2, 3]
  Ṛ                - Reverse it
   ð            ð  - Define a dyadic chain f(a, b):
    Ṅ              -   Print a
     ṛ             -   Replace a with b
      50r³         -   Yield a range [50, 51, ..., 100]
          ÷³       -   Divide each by 100; Yields [0.5, 0.51, ..., 1]
            X      -   Take a random element t
             œS@   -   Sleep for t seconds then return b
                 / - Reduce the range by the dyadic chain.
                     Remember, f(a, b) = b (with some side effects), so this runs:
                     f(f(3, 2), 1) = f(2, 1) = 1, printing a each time (3, 2, 1)

```

# Answer
> 1 votes
# Pyth, 12 bytes

```
V_S3N.d-1O.5

```

Try it online!

---

Python 3 translation:

```
V_S3         | for N in range(1, 4)[::-1]:
    N        |     print(N)
     .d-1O.5 |     time.sleep(1 - random.uniform(0, 0.5))

```

# Answer
> 1 votes
# Nim, 70 bytes

```
import os,random
randomize()
for i in[3,2,1]:echo i;sleep 500.rand+500

```

Try it online!

# Answer
> 0 votes
# \[GAWK\], 57 bytes

```
BEGIN{while(a++<2){print 4-a;sleep(rand()/2+0.5)}print 1}

```

Try it online!

---
Tags: code-golf, random
---


title: Find one-handed words

text:
# Question
Title: Find one-handed words
'exaggerated' is an example of a word which can be typed on the left hand, on a normal qwerty keyboard map. 'monopoly' is an example for the right hand.

Searching the unix `words` file for words that can be typed on one hand. Output should be two lines: space separated list of such words for the left hand, followed by the list for the right hand. e.g.

```
a abaft abase abased abases abate abated abates abbess abbesses ...
h hi hill hilly him hip hippo hippy ho hokum ...

```

The left-hand letters are:

```
qwertasdfgzxcvb

```

The right-hand letters are:

```
yuiophjklnm'

```

Uppercase letters count as one-handed; letters with diacritics count as two-handed and hence words containing them can be ignored.

# Answer
## sed, 78 bytes

```
1{x;s/^/! /;x};/^['h-puy]*$/IH;/^[a-gq-tv-xz]*$/I{G;x};${x;y/\n/ /;s/! */\n/p}

```

requires GNU sed, run with `sed -n -f words.sed < /usr/share/dict/words`
> 7 votes

# Answer
### Bash (100 89 chars)

```
for x in a-gq-tvwxz h-puy\'
do grep -iE ^[$x]*$ /usr/share/dict/words|tr '
' \
echo
done

```

Note that 21 chars go to the full path to the words file: if we're allowed to assume that pwd is /usr/share/dict then 16 of those can be saved.

Credit to chron for the shorter regexes.
> 7 votes

# Answer
## Bash, 86

```
for x in a-gq-tvwxz h-pyu\'
do egrep ^[$x]*$ /usr/share/dict/words|tr '
' \
echo
done

```

Taylors `for`, my egrep, chrons grouping of chars.

By definition, if you type by two hands blind, if you like to produce an uppercase letter, you always use the left hand to produce an uppercase character of the right hand and vice versa.

Of course you may produce an uppercase `W` with only the left hand, but you can produce `junk` with the left hand, too, if you like.
> 4 votes

# Answer
# Python 3.8 - 126 135 139 144 152 137 chars

```
r,a={*"YUIOPHJKLNM'"},'\n'
try:
 while w:=input():
  s={*w.upper()}
  if r|s==r:a=w+' '+a
  if s-r==s:a+=w+' '
except:print(a)

```

**edit:** handle upper case and apostrophe.

**edit 2:** move to python 3. get rid of `' '.join()`. use walrus operator. change `+=w` to `+=[w]` to fix bug.

**edit 3:** change printing to save 5 characters.

**edit 4:** change set creation from `set(iterable)` to `{*iterable}` to save 2 characters twice.

**edit 5:** change two lists to one string to hold result allowing one less assignment on the first line and one less print statement on the last line to save 9 characters.
> 3 votes

# Answer
## Python 2.7 (139 characters)

```
import os
a=set("yuiophjklnm'")
c=os.read(0,9**9).lower().split()
print'\n'.join([' '.join(filter(x,c))for x in a.isdisjoint,a.issuperset])

```
> 3 votes

# Answer
## Bourne shell, 55 chars

<sup>(Or any Bourne-like shell but `bash`, `zsh` or `yash`)</sup>

```
w=$1;f()echo `grep -ixe[$1]*<$w`;f a-gq-tvwxz;f h-puy\'

```

Called as `sh -f words.sh /usr/share/dict/words`. (of course, on systems where `sh` is actually `bash` like on some Linux distributions, use another Bourne-like shell like `ash`, `ksh`, `mksh`, `pdksh`, `posh`...)
> 3 votes

# Answer
## Javascript (node), 201 byte

```
f=require('fs');c=d='';r=(a=f.readFileSync('/dev/stdin')+c).split('\n');a.
replace(/[aqzxswcdevfrbgt]/ig,'').split('\n').map(function(k,i){k==r[i]&&(
d+=k+' ');!k.length&&(c+=r[i]+' ')});console.log(c,d)

```

This can probably be rewritten to a much shorter version in another language, but I just wanted to give node a try.

Run with `node words.js < /usr/share/dict/words`
> 2 votes

# Answer
# Q (121 140 Bytes)

Output isn't the exact same (backticks instead of spaces) but this is symptomatic of how Q displays string types.

```
i:read0`:/usr/share/dict/words;
0N!/:i:`$/:i where each (min each) each flip i in/:\:(x,upper x:"qwertasdfgzxcvb";y,upper y:"yuiophjklnm");

```

EDIT: Had to handle mixed case, +20 chars
> 2 votes

# Answer
## Ruby, 112 92 characters

EDIT: This is shorter, though not nearly as fun:

```
puts %w(a-gq-tv-xz 'h-puy).map{|r|File.read('/usr/share/dict/words').scan(/^[#{r}]+$/i)*' '}

```

Original:

```
puts File.read('/usr/share/dict/words').scan(/(^[a-gq-tv-xz]+$)|(^['h-puy]+$)/i).transpose.map{|w|w.compact*' '}

```

Pretty simple regex-based solution. As with the others, you could save some characters if you're allowed to pass the filename in ARGV or if it's assumed to be in your current directory.
> 2 votes

# Answer
## Python, 130 Bytes

```
a="\n"
b=""
try:
 while 1:v=raw_input();m=[x.lower()in"yuiophjklnm'"for x in v];v+=" ";a+=v*all(m);b+=0**any(m)*v
except:print b+a

```

Run with `python one_handed_words.py < /usr/share/dict/words`
> 2 votes

# Answer
## Haskell (191)

```
import Char
g x=all(`elem`x)
f m[]=m
f[x,y](w:ws)|g"quertasdfgzxcvb"w=f[w:x,y]ws|g"yuiophjklnm'"w=f[x,w:y]ws|1<2=f[x,y]ws
main=getContents>>=mapM(putStrLn.unwords).f[[],[]].lines.map toLower

```
> 2 votes

# Answer
## Perl, 72 bytes

```
$a{/^['h-puy]+$/i-/^[a-gq-tv-xz]+$/i}.=y/\n/ /rfor<>;print@a{1,-1,$,=$/}

```

run with `perl words.pl /usr/share/dict/words`
> 2 votes

# Answer
# Jelly, 26 24 25 bytes

```
Øqs€5⁾q'ṭZF€
ỴŒlfƑ¥ƇⱮ¢K€Y

```

Try it online!

## Explanation (older version)

```
Øqs€5⁾q'ṭZF€   Auxiliary niladic link
Øq             Lowercase QWERTY keyboard
  s€5          Split each row into chunks of at most 5 letters
     ⁾q'ṭ      Append the string "q'"
         Z     Zip (transpose)
          F€   Flatten each => ["qwertasdfgzxcvbq", "yuiophjklnm'"]

ỴŒlfƑƇⱮ¢K€Y   Main monadic link
Ỵ             Split on newlines
 Œl           Lowercase
      Ɱ¢      Map over the result of the auxiliary link:
     Ƈ          Filter by
    Ƒ             Invariant under
   f                Filtering by the right argument
        K€    Join each with spaces
          Y   Join with a newline

```
> 2 votes

# Answer
## Python, 243 chars

edit: here's a more compliant program according to the question:

```
import sys
def o(w):
 r="yuiophjklnm'";f=2;w=w.lower()
 for l in w:
  if(f==1)&(l in r)|(f==0)&(l not in r):return 2
  f=l not in r
 return f
y=[[],[],[]]
for w in sys.stdin.read().split('\n'):y[o(w)].append(w)
for i in y[0:2]:print' '.join(i)

```

invoke: `python onehanded.py > /usr/share/dict/words` or any other words file with newline-separated words

old: 141 chars, just a single-word function

returns `right` or `left` if `w` is onehanded, and `both` if both hands are used.

```
def o(w):
 r="yuiophjklnm'";f=2
 for l in w:
  if(f==1)&(l in r)|(f==0)&(l not in r):f=2;break
  f=[1,0][l in r]
 return'rlbieogfththt'[f::3]

```
> 1 votes

# Answer
# Q, 95 (111 with hardcoded dict path)

```
{`$'e[(w(&)l(w)in .Q.a except a)],(e:enlist)w(&)(l:all')(w:(_)read0 -1!`$x)in a:"yuiophjklnm'"}

```

usage

```
q){`$'e[(w(&)l(w)in .Q.a except a)],(e:enlist)w(&)(l:all')(w:(_)read0 -1!`$x)in a:"yuiophjklnm'"} "/usr/share/dict/words"
`a`a`aa`aa`aaa`aaa`aaaa`aaaaaa`aaas`aaberg`aae`aaee`aaf`aag`aar`aara`aarc`aas..
`h`h`hh`hi`hi`hi`hih`hiko`hikuli`hili`hill`hill`hillo`hilly`hilly`hilo`hilum`..

```

14 more chars if you hardcode it

```
`$'e[(w(&)l(w)in .Q.a except a)],(e:enlist)w(&)(l:all')(w:(_)read0`:/usr/share/dict/words)in a:"yuiophjklnm'"

```
> 1 votes

# Answer
# J, 109

```
1!:2&2;:^:_1('qwertasdfgzxcvb';'yuiophjkl''nm')((#@[>[:>./i.)&>/#]);:1!:1<'/usr/share/dict/words'[9!:37]0,3$_

```

I'm sure this can be done better, I don't know how to do string manipulation :-(
> 1 votes

# Answer
# Pyth, 44 bytes

```
Ljdf.A}RbrT0cQdy."az:ïÑý>Íï“"y"yuiophjklnm'
```

Try it online!

---

```
Ljdf.A}RbrT0cQdy."az:ïÑý>Íï“"y"yuiophjklnm' | # Python 3 Translation
---------------------------------------------+------------------------------
                                             | from operator import contains
                                             | from itertools import repeat
                                             | Q = eval(input())
L                                            | y = lambda b:
 jd                                          |   " ".join(
   f                                         |     filter(lambda T:
    .A                                       |       all(
      }R                                     |         map(contains,
        b                                    |           repeat(b),
         rT0                                 |           T.lower()
                                             |         )
                                             |       ),
            cQd                              |       Q.split(" ")
                                             |     )
                                             |   )
               y."az:ïÑý>Íï“"               | print(y("qwertasdfgzxcvb"))
                              y"yuiophjklnm' | print(y("yuiophjklnm'"))
```
> 1 votes

# Answer
**Python: 122**

```
import os
S=set("yuiophjklnm'")
c=os.read(0,9**9).lower().split()
print"\n".join(w for w in c if set(w)<=S or set(w)^S>=S)

```

Launched with:

```
python name_of_program.py < /usr/share/dict/words

```

---

The idea is mostly the same of Dillon Cower's, but I use `set(w)<=S` to indicate a subset while `set(w)^S>=S` for a disjoint set.
> 0 votes

---
Tags: code-golf
---


title: Compare version numbers

text:
# Question
Title: Compare version numbers
When we publish some software, we assign a version number to it. And users may want to update to the latest version of some software. So, it is the time to find out which version should be newer.

### Input

Input two version numbers as strings.

In the context of this challenge, we only support version numbers which are some digits joined by dots.

* A version number is a non-empty string which may only contain digits (`0` ~ `9`) and dots (`.`).
* Dots would not be the first / last character of a version number.
* There must be some digits between dots. No two dots may appear continuously.
* All numbers in a version number would be less than 216.

### Output

Compare the inputted version numbers and output whether first one is greater than / equals to / less than the second one. You are allowed to choose one of the following presentations:

* Use positive number / zero / negative number, while zero means equal;
* Use three constant distinct values;

### Comparing

You are not required to implement the algorithm described in this section. Your submission is valid as long as it result the same output with this algorithm.

* Version numbers are some decimal numbers joined by dots. We first split the two version numbers to arrays of numbers;
* Padding the ending of arrays with zeros to make them have same length;
* Compare from the first item to the last one:
    + If the two array items different, the greater number means greater version number
    + If they are the same, continue to compare the following items;
    + If all items in the array are equal, the two versions are equal.

### Testcases

```
version1  version2  result
2         1         >
1.0.0     1         =
1.0       1.0.0     =
1.2.42    1.2.41    >
1.1.56789 1.2.0     <
1.10      1.2       >
1.20      1.150     <
18.04     18.4      =
7.010     7.8       >
1.0.0.1.0 1.00.00.2 <
00.00.01  0.0.0.1   >
0.0.1     0.1       <
42.0      4.2.0     >
999.999   999.999.1 <
2018.08.1 2018.08   >

```

# Answer
# Python 2, ~~84~~ ~~79~~ 76 bytes

```
lambda*l:cmp(*map(lambda v:map(int,v.split('.')+[0]*len(`l`))[:len(`l`)],l))

```

Try it online!

Outputs `-1,0,1` for `<,=,>`
> 7 votes

# Answer
# 05AB1E (legacy), ~~15~~ ~~14~~ 13 bytes

```
'.¡0ζε`.S}0K¬

```

Outputs `-1 [] 1` for `< = >` respectively.

-1 byte thanks to *@Emigna*.

Try it online or verify all test cases.

**Explanation:**

```
'.¡              # Split on dots
                 #  i.e. ['1.0.1.1.0','1.00.2.0']
                 #   → [['1','0','1','1','0'],['1','00','2','0']]
   0ζ            # Zip, swapping rows and columns, using '0' as filler
                 #  i.e. [['1','0','1','1','0'],['1','00','2','0']]
                 #   → [['1','1'],['0','00'],['1','2'],['1','0'],['0','0']]
     ε   }       # Map each:
      `          #  Push both values to the stack
       .S        #  And calculate the signum (1 if a>b; -1 if a<b; 0 if a==b)
                 #   i.e. [['1','1'],['0','00'],['1','2'],['1','0'],['0','0']]
                 #    → [0,0,-1,1,0]
          0K     # Remove all zeros
                 #  i.e. [0,0,-1,1,0] → [-1,1]
            ¬    # Then take the head as result
                 #  i.e. [-1,1] → -1

```
> 7 votes

# Answer
# , 32 bytes

```
rank(numeric_version(scan(,"")))

```

Try it online!

Using an R builtin

Outputs `1 2`, `1.5 1.5`, `2 1` for less, equal, greater.

---

Best so far, without builtin :

### , ~~151 142 125~~ 107 bytes

```
function(v,L=strsplit(v,'\\.'))Find(c,sign(Reduce('-',Map(as.double,Map(c,L,Map(rep,0,rev(lengths(L))))))))

```

Try it online!

Unrolled code with explanation :

```
function(v){             # character vector of 2 elements as function arg;
  L=strsplit(v,'\\.')    # obtain a list of two character vectors
                         # with the separated version numbers;
  R=rev(lengths(L))      # store in vector R the lengths of the 2 vectors and reverse it;
  M1=Map(rep,0,R)        # create a list of 2 vector containing zeros
                         # repeated R[1] and R[2] times;
  M2=Map(c,L,M1)         # append to the vectors in list L the zeros in M1;
  M3=Map(as.double,M2)   # convert the character vectors in M2 to double;
  w=sign(Reduce('-',M3)  # compute the sign of element by element difference M[[1]] - M[[2]]);
  Find(c,w)            # returns the first non zero element in w, if none return NULL;
}
# N.B. as.double is necessary because "0XX" is interpreted as octal by strtoi unless
#      we use strtoi(x,10) which is exactly the same length of as.double(x)

```

Outputs `-1`, `NULL`, `1` for less, equal, greater.

---

Original concept, golfed down using `sapply`, `[<-` and `%*%`:

### , 129 bytes

```
function(x,y=strsplit(x,"\\."),w=sign(sapply(y,function(x)strtoi("[<-"(rep(0,max(lengths(y))),seq(x),x),10))%*%c(1,-1)))w[!!w][1]

```

Try it online!

Now you have a list of two equal-length vectors of integers. Calculate the pairwise differences using `Reduce` and output the first non-zero element using the tricky little `w[!!w][1]` form at the end.

Outputs `-1`, `NA`, `1` for less, equal, greater.
> 5 votes

# Answer
# Perl 6, ~~63 47~~ 22 bytes

```
{"v$^a cmp v$^b".EVAL}

```

Try it online!

Turns out that Perl 6 has a version type that pretty much fits the description. This is an anonymous code block that takes a list of two version strings and returns either `More`,`Same` or `Less`.

### Explanation:

```
{                    }  # Anonymous code block
 "             "        # Create a string of code
  v$^a cmp v$^b         # Comparing the two versions
                .EVAL   # And EVAL it

```

## Or, without built-in types for 47 bytes:

```
{first +*,[Z<=>] map *.split('.')[^@_.ords],@_}

```

Try it online!

Anonymous code block that takes two strings and returns `More` if the second is greater, `Less` if the second is smaller and `Nil` if they are equal.

### Explanation:

```
{                                             } # Anonymous code block
                 map *.split('.')          ,@_  # Split both strings by '.'
                                 [^@_.ords]     # Pad the lists by a lot
          [Z<=>]   # Zip the strings with the <=> operator
 first +*,  # Get the first value that when coerced to an int, is not 0

```
> 4 votes

# Answer
# APL (Dyalog Unicode), ~~18~~ 17 bytes

*1 byte saved thanks to @Adám for using `⍤1` instead of `∘↑(...)¨` and by changing the input format from a nested array to a matrix*

```
(⍋-⍒)(⍎¨∊∘⎕D⊆⊢)⍤1

```

Try it online!

Takes the input as a matrix of chars as the right argument, where each version string is on its own row. Outputs `¯1 1`, `0 0`, `1 ¯1` for `<`, `=`, `>` respectively.

`(⍎¨∊∘⎕D⊆⊢)⍤1` on each row

* `∊∘⎕D⊆⊢` group all occurrences of digits, that is, split on `.`
* `⍎¨` and convert each of these occurrences to a number

convert to a matrix, where the first input is on the top row and the second one in the bottom, padding with `0`s where necessary

`(⍋-⍒)` and

* `-` subtract
    + the indices into the rows which would sort them in descending order
    + same as the top but for ascending order
> 4 votes

# Answer
# Java (JDK 10), ~~201~~ ~~96~~ 89 bytes

```
java.util.Comparator.comparing(java.lang.module.ModuleDescriptor.Version::parse)::compare

```

Try it online!

Returns a negative number if the first version is smaller than the second one, a positive one if the first version is greater than the second one and `0` if they're equal.

Yep, that's some heavy work to "just" call a built-in!

## Credits
> 3 votes

# Answer
# Brachylog, ~~49~~ 40 bytes

```
+0|{~c[H,".",T]hị;T|ị;0|0}ᵐz{h-0&t↰₀|h-}

```

...It's still rather unimpressively lengthy.

Expects a list of two strings. Uses `positive number / zero / negative number` as `> / = / <`.

Try it online!

## Explanation

**Splitting the inputs**

Given an input that does not unify with `[0, 0]`, such as `["1.02.0", "1.2.0.1.0"]`, the below segment outputs, e.g., `[[1, "02.0"], [1, "2.0.1.0"]]`.

```
                            # unify the input with...
+0                          # : a list whose sum = 0 (output is 0)
  |{                     }ᵐ # : OR a list that when mapped...
    ~c                      # : : if the input string unifies with a list of the form...
      [H,".",T]             # : : : e.g. "1.02.0", H = "1", T = "02.0"
               hị           # : : : coerce the head to an integer
                 ;T         # : : : append the string T
                            # : : : "1.02.0" -> [1, "02.0"]
                   |ị       # : : OR it unifies with an integer
                     ;0     # : : : append 0
                            # : : : "1" -> [1, 0]
                       |0   # : : OR it unifies with 0
                            # : : : 0 -> [0]

```

**Comparing the inputs**

Given, e.g., `[[1, "02.0"], [1, "2.0.1.0"]]`, zips the sublists into `[[1, 1], ["02.0", "2.0.1.0"]]` and compares the values in the head (`[1,1]`). Recur on the second sublist. Note that the zip predicate `z` cycles through shorter lists so that zipping with `[0,0]` is equivalent to zipping with `[0]`, hence the previous step unifies `0` with `0` without further values appended.

```
z             # zip the sublists
 {          } # unify the result (r) with...
  h           # : take the head of the result
   -          # : : subtract the second value from the first
    0         # : : if the difference unifies with 0...
     &t↰₀     # : : recur on the tail of r
         |h-  # : OR unify with the difference of the elements of the head
              # : (equivalent to returning early)

```
> 3 votes

# Answer
# JavaScript (ES6), ~~73~~ 68 bytes

*Saved 5 bytes thanks to @redundancy*

Takes input as `(a)(b)`. Returns \\$0\\$ for *equal*, a positive integer for *greater than* or a negative integer for *less than*.

```
a=>b=>(a+[...b].fill`.`).split`.`.some((x,i)=>d=~b.split`.`[i]-~x)*d

```

Try it online!
> 3 votes

# Answer
# Python 2, 87 bytes

```
lambda*p:cmp(*zip(*map(lambda x,y:(x or 0,y or 0),*[map(int,u.split('.'))for u in p])))

```

Try it online!

Outputs -1,0,1 for \<,=,\>, respectively.
> 2 votes

# Answer
# Retina 0.8.2, 54 bytes

```
\d+
$*
+`^(.)(.*=)\1
$2
(.*=|^=.*)1.*
<
.*1.*=.*
>
\.

```

Try it online! Link includes test cases. Uses the separator value as the equality output, so for convenience the header converts the input separator to `=` but it could be anything not in `[.\d]`. Explanation:

```
\d+
$*

```

Convert to unary.

```
+`^(.)(.*=)\1
$2

```

Repeatedly delete the first character from each side until they differ or one side runs out. This is much faster than trying to match prefixes, although possibly not golfier. At this point, the strings are in one of several forms, which need to be decoded to a comparison result.

1. If neither string contains a `1` then the result is `=`
2. If the left string starts with a `1` then the result is `>`
3. If the right string starts with a `1` then the result is `<`
4. If the left string is empty then the result is `<`
5. At this point the right string is empty so the result is `>`

Another way of thinking about this is that if one string contains a `1` and the other does not start with a `1` then that string is greater, however that turns out to be a byte longer.

```
(.*=|^=.*)1.*
<

```

Check for case 3, or case 4 without case 1.

```
.*1.*=.*
>

```

If the left string still contains a `1` at this point then it is greater.

```
\.

```

Otherwise delete any left over `.`s.

# Firefox Browser Console REPL, 19 bytes

```
Services.vc.compare

```

I believe this internal function performs the required comparison. It returns -1, 0, or 1.
> 2 votes

# Answer
# C (gcc),  ~~140~~  134 bytes

This code outputs a negative, `0` or a positive for `<`,`=` or `>` respectively.

```
i;n;p;q;g(char*s){for(i=n=0;*s&&++n&&*s-46;i=i*10+*s++-48);i=i;}f(char*a,char*b){for(p=q=0;*a+*b&&p==q;b+=n)p=g(a),a+=n,q=g(b);a=p-q;}

```

Try it online!

# Edits:

* Saved 6 bytes thanks to ceilingcat !
> 2 votes

# Answer
# Ruby, 75 bytes

```
->a,b{c=d=0;c,d=[a,b].map{|f|f.slice!(/\d*./).to_i}while''<a+b&&c==d;c<=>d}

```

Try it online!
> 1 votes

# Answer
# Japt, ~~16~~ 11 bytes

*-5 bytes from @Shaggy*

Outputs:

* negative number for `<`
* (`null` or `0`) for `=`
* positive number for `>`

---

```
N®q.Ãy_r-Ãf

```

Try it online!
> 1 votes

# Answer
# JavaScript (Node.js), ~~105~~ ~~88~~ 80 bytes

*-17 bytes from @redundancy. Wow!*

*-8 bytes removing Math.sign. Thanks @tsh*

Returns a negative, zero or positive value

```
f=(a,b,r=/(\d*).?(.*)/)=>a+b&&+((a=r.exec(a))[1]-(b=r.exec(b))[1]||f(a[2],b[2]))

```

Try it online!
> 1 votes

# Answer
# Clean, ~~116~~ 111 bytes

```
import StdEnv,Text
?s=map toInt(split"."s)
$a b= @(?a)(?b)
@[h:t][u:v]|h==u= @t v=h-u
@l[]=sum l
@[]l= ~(sum l)

```

Try it online!

Outputs a negative number when the first argument is less than the second one, zero when they're equivalent, and a positive number when it is more than the second one.
> 0 votes

# Answer
# Swift 4+Foundation, ~~160 bytes (142+18)~~, 155 bytes (142+13)

### Import (13 bytes, including `;` to separate from the code):

This will import Foundation, but is 5 bytes shorter than `import Foundation`.

```
import UIKit;

```

### Header (not counted: the code is non-recursive):

```
let f:(String,String)->ComparisonResult =

```

### Code (142 bytes):

```
{var x={($0 as String).split{$0=="."}.count},a=$0,b=$1
while x(a)<x(b){a+=".0"}
while x(b)<x(a){b+=".0"}
return a.compare(b,options:.numeric)}

```

Try it online!

### Explanations

1. We append some trailing .0 for same number of components.
2. We compare components numerically.

### Returned constants

* ComparisonResult.orderedSame for =
* ComparisonResult.orderedAscending for \<
* ComparisonResult.orderedDescending for \>
> 0 votes

# Answer
# Swift 4, 155 bytes

### Header (not counted: the code is non-recursive):

```
let f:(String,String)->Bool? =

```

### Code

```
{let x:(String)->[Int]={$0.split{$0=="."}.map{Int($0)!}.reversed().drop{$0==0}.reversed()},a=x($0),b=x($1)
return a==b ?nil:a.lexicographicallyPrecedes(b)}

```

Try it online!

### Explanations

* We trim trailing .0.
* We compare components numerically.

### Returned constants

* nil for =
* true for \<
* false for \>
> 0 votes

# Answer
# JavaScript 64 bytes

```
a=>b=>(e=i=>(g=v=>v.split`.`[i]||0)(a)-g(b)||!a[i]-1&&e(i+1))(0)

```

Try it online!

With comments:

```
a=>b=>(                            // Main function takes arguments like ("1.2.42")("1.2.41")
    e=i=>                          // e(i) compares the ith number, returns >0, <0 or =0.
        (   g=v=>v.split`.`[i]||0  // g() returns the ith string or 0
        )(a)                       // call g(a)
        -g(b)                      // subtracting g(b) from g(a) casts strings to integer
        ||                         // If they are not equal return result now
        !a[i]-1 &&                 // recursion limited to a.length, always sufficient
        e(i+1)                     // next i
    )(0)                           // Start with i = 0

```
> 0 votes

# Answer
# Perl 5, 55 bytes

```
sub c{@_<2?sprintf"%9d"x9,split/\./,pop:-(c(pop)cmp c(pop))}

```

Try it online!
> 0 votes

# Answer
## Burlesque - 17 bytes

```
wd{'.;;)ri}m[^pcm

blsq ) "2018.08.1 2018.08"wd{'.;;)ri}m[^pcm
1
blsq ) "0.0.1 0.1"wd{'.;;)ri}m[^pcm
-1
blsq ) "1.1.56789 1.2.0"wd{'.;;)ri}m[^pcm
-1

```

If you want output in '\>\<=' then add `?i"<=>"j!!Q`.
> 0 votes

# Answer
# Powershell, 88 bytes

Returns `0` for equal, a `positive integer` for greater than or a `negative integer` for less than.

```
param($a,$b)+(($x=$a-split'\.')+($y=$b-split'\.')|%{$x[+$i]-$y[$i++]}|?{$_}|Select -f 1)

```

Less golfed test script:

```
$f = {

param($a,$b)
$x=$a-split'\.'
$y=$b-split'\.'
$z=$x+$y|%{
    $x[+$i]-$y[$i++]
}|?{$_}|Select -first 1
+$z             # convert $null to 0

}

@(
    ,("2"         ,"1"         , 1)
    ,("1.0.0"     ,"1"         , 0)
    ,("1.0"       ,"1.0.0"     , 0)
    ,("1.2.42"    ,"1.2.41"    , 1)
    ,("1.1.56789" ,"1.2.0"     ,-1)
    ,("1.10"      ,"1.2"       , 1)
    ,("1.20"      ,"1.150"     ,-1)
    ,("18.04"     ,"18.4"      , 0)
    ,("7.010"     ,"7.8"       , 1)
    ,("1.0.0.1.0" ,"1.00.00.2" ,-1)
    ,("00.00.01"  ,"0.0.0.1"   , 1)
    ,("0.0.1"     ,"0.1"       ,-1)
    ,("42.0"      ,"4.2.0"     , 1)
    ,("999.999"   ,"999.999.1" ,-1)
    ,("2018.08.1" ,"2018.08"   , 1)
) | % {
    $v1,$v2,$expected = $_
    $result = &$f $v1 $v2
    "$([Math]::Sign($result)-eq$expected): $result"
}

```

Output:

```
True: 1
True: 0
True: 0
True: 1
True: -1
True: 8
True: -130
True: 0
True: 2
True: -1
True: 1
True: -1
True: 38
True: -1
True: 1

```
> 0 votes

# Answer
# Dart, ~~277~~ 231 bytes

```
F(s,{t}){t=s.split('.').map(int.parse).toList();while(t.last<1)t.removeLast();return t;}f(a,b,{d,e,f,g,h,i=0}){d=F(b);e=F(a);g=d.length;h=e.length;f=h>g?g:h;for(;i<f;i++)if(e[i]!=d[i])return e[i]>d[i]?1:-1;return h>g?1:(h<g?-1:0);}

```

Try it online!

* -44 bytes by using variables to store length and using ternary in loop
* -2 bytes by removing the for brackets
> 0 votes

# Answer
# Zsh, ~~54~~ 50 bytes

***-4 bytes** by using `$@` instead of `$1\ $2`*

```
eval {autoload,}' is-at-least $'{@,2\ $1}';<<<$?;'

```

~~Try it online!~~  Try it online!

This `eval`s to the following eight statements:

```
autoload is-at-least $@       # loads the "is-at-least" function
<<<$?                         # success, prints 0
autoload is-at-least $2 $1    # redundant
<<<$?                         # success, prints 0
is-at-least $@                # exits 1 if $1 < $2
<<<$?
is-at-least $2 $1             # exits 1 if $2 < $1
<<<$?

```

So the three unique values are:

```
 cmp |  value
-----+------------------------------------------
  =  |  0<newline>0<newline>0<newline>0<newline>
  <  |  0<newline>0<newline>1<newline>0<newline>
  >  |  0<newline>0<newline>0<newline>1<newline>

```
> 0 votes

# Answer
# Jelly, 11 bytes

```
ṣ€”.Vz0I¬ÞḢ

```

Try it online!

May be stretching the rules a little, but going by this I/O default, it's allowed. This uses the output presentation:

> Use positive number / zero / negative number, while zero means equal;

but the output is wrapped as a singleton array

## How it works

```
ṣ€”.Vz0I¬ÞḢ - Main link. Takes a pair of versions [a, b] on the left
 €          - Over each:
ṣ ”.        -   Split on "."
    V       - Evaluate each numeric string to a number
     z0     - Transpose, filling with 0s
       I    - Take the differences of each pair
        ¬Þ  - Sort by logical NOT
              This shuffles 0 to the end and preserves the order of everything else
          Ḣ - Take the first element

```
> 0 votes

# Answer
# Perl 5 `-plF\.`, 50 bytes

```
@b=<>=~/\d+/g;1while@F+@b&&!($_=shift@F<=>shift@b)

```

Try it online!

Takes input on two lines.

| Output | Meaning |
| --- | --- |
| 1 | First version is greater |
| 0 | Versions are equal |
| -1 | Second version is greater |
> 0 votes

---
Tags: code-golf, string, number
---