35
\$\begingroup\$

On 4chan, a popular game is get. Every post on the site gets a sequential post ID. Since you can't influence or determine them, people try to guess (at least a part of) their own post number, usually the first few digits. Another version of the game is called dubs, and it's goal is to get repeating digits at the end of the number (i.e 1234555).

Your task, if you wish to accept it, is to write a program that takes a post id as input (standard integer, you can assume below 2^32), and returns how many repeating digits are on the end.

Rules

  • Standard loopholes are disallowed.
  • The program can be a function, full program, REPL command, whatever works, really, as long as no external uncounted code/arguments are needed to run it.
  • Input can come from STDIN, function arguments, command line argument, file, whatever suits you.

Test Cases

Input: 14892093
Output: 1

Input: 12344444
Output: 5

Input: 112311
Output: 2

Input: 888888
Output: 6

Input: 135866667 //Post number I got on /pol/ few days ago, rip
Output: 1
\$\endgroup\$
11
  • 1
    \$\begingroup\$ Are we allowed to take input as string? \$\endgroup\$ Mar 28, 2017 at 9:11
  • 7
    \$\begingroup\$ @DeadPossum I would assume that's allowed, since you get a string anyway if you read the input from STDIN, command-line argument or file (which are all admissible input methods). \$\endgroup\$ Mar 28, 2017 at 9:19
  • 1
    \$\begingroup\$ Can we assume that the input will be greater than 0? \$\endgroup\$ Mar 28, 2017 at 10:01
  • 2
    \$\begingroup\$ Upvote for the dubs game! Check'em! \$\endgroup\$ Mar 28, 2017 at 12:31
  • 2
    \$\begingroup\$ Disappointed: The question ID on SE does not have dubs. \$\endgroup\$
    – Num Lock
    Mar 30, 2017 at 9:42

63 Answers 63

2
\$\begingroup\$

Clojure, 48 bytes

#(-> (partition-by identity (str %)) last count)

Usage: (#(-> (partition-by identity (str %)) last count) 123455)

=> 2

Ungolfed:

(defn count-digits [n]
                  (-> (partition-by identity (str n))
                      last
                      count))

Common Lisp, 82 bytes

(defun c (n) (if (eq (mod n 10) (floor (mod n 100) 10)) (+ 1 (c (floor n 10))) 1))

Ungolfed:

(defun c (n)
  (if (eq (mod n 10)
          (floor (mod n 100) 10))
      (+ 1 (c (floor n 10))) 1))
\$\endgroup\$
1
  • 1
    \$\begingroup\$ Welcome To PPCG! Wonderful first post, It looks like you have the basics of formatting down, just note that in the future you an make multiple answers if you use multiple languages (good for getting more rep :) ) \$\endgroup\$ Mar 31, 2017 at 1:50
2
\$\begingroup\$

Jelly, 4 bytes

ŒrṪṪ

Takes input as a string, returns a number.

Try it online!

Relatively simply, Œr Run-length encodes the input, pushes the last pair, then pushes its second item. Which thus gives us the length of consecutive digits at the end of the string.

\$\endgroup\$
2
\$\begingroup\$

Python 3 - 50 44 bytes

Full program (in Python 3, input() returns a string, no matter the input):

g=input();print(len(g)-len(g.rstrip(g[-1]))) 
\$\endgroup\$
0
2
\$\begingroup\$

ARM Thumb-2 (no divide instruction/libgcc), 38 bytes

Raw machine code:

b530 2400 250a 3401 2200 280a d302 3201
380a e7fa 0001 0010 2d0a bf08 460d 428d
d0f1 1e60 bd30

Uncommented asm:

        .text
        .arch armv6t2
        .globl dubs
        .thumb
        .thumb_func
dubs:
        push    {r4, r5, lr}
        movs    r4, #0
        movs    r5, #10
.Lloop:
        adds    r4, #1
        movs    r2, #0
.Ldivloop:
        cmp     r0, #10
        blo     .Ldivloop_end
        adds    r2, #1
        subs    r0, #10
        b       .Ldivloop
.Ldivloop_end:
        movs    r1, r0
        movs    r0, r2
        cmp     r5, #10
        it      eq
        moveq   r5, r1
        cmp     r5, r1
        beq     .Lloop
        subs    r0, r4, #1
        pop     {r4, r5, pc}

Explanation

C function signature:

// Assume: post_id != 0
uint32_t dubs(uint32_t post_id);

First, push registers and set up our dubs counter in r4:

dubs:
        push    {r4, r5, lr}
        movs    r4, #0

Now, in order to reuse the loop, we use a "magic" value of 10 for the last digit in r5, and set it at the end of the loop.

        movs    r5, #10

Begin the count by incrementing the dubs counter:

.Lloop:
        adds    r4, #1

Now, we start our divmod loop to divide the ID by 10 and get the remainder.

The divided ID will be in r2 and the remainder will be in r0.

        movs    r2, #0
.Ldivloop:
        cmp     r0, #10
        blo     .Ldivloop_end
        adds    r2, #1
        subs    r0, #10
        b       .Ldivloop

That is basically this in C:

uint32_t quotient = 0;
while (dividend >= 10) {
    ++quotient;
    dividend -= 10;
}
uint32_t remainder = dividend;

This could probably be optimized. We ended up with the registers in the wrong spot, so we have to move things around. Specifically, we want the remainder in r1 and the divided ID in r0.

The biggest problem is dealing with movs either clobbering the flags or requiring hi registers. If it didn't do that, I would put it after the cmp.

.Ldivloop_end:
        movs    r1, r0
        movs    r0, r2

Now, we check for that magic number and set the lowest digit to that.

        cmp     r5, #10
        it      eq
        moveq   r5, r1

Now, check if the new remainder in r1 and loop if it is the same as the last digit.

        cmp     r5, r1
        beq     .Lloop

Move the dubs count into the return register and return. We are actually one too high so we have to correct it.

        subs    r0, r4, #1
        pop     {r4, r5, pc}
\$\endgroup\$
2
\$\begingroup\$

Vyxal, l, 2 bytes

Ġt

Try it Online!

need to get this to 2 bytes somehow – Razetime

Explained

Ġt
Ġ    # Group the integer into consecutive chunks
 t   # Take the tail of that list
     # The `-l` flag prints the length of TOS
\$\endgroup\$
1
  • \$\begingroup\$ need to get this to 2 bytes somehow \$\endgroup\$
    – Razetime
    Nov 19, 2020 at 4:01
1
\$\begingroup\$

C, 62 55 bytes

i,j;f(n){for(i=0,j=n%10;++i;n/=10)if(j-n%10)return--i;}

Try it online!

\$\endgroup\$
1
\$\begingroup\$

REXX, 50 bytes

arg ''-1 # 1 n
say length(n)-length(strip(n,T,#))

Parse argument with empty string, causing parsing cursor to move to end of argument, then left one step, put remainder (one character) of argument in # variable, move to first character and put first word of argument in n variable.

Strip trailing characters equivalent to # from n and compare length to n.

\$\endgroup\$
1
\$\begingroup\$

Octave, 30 bytes

@(s)find(flip(diff([0 +s])),1)

Try it online!

\$\endgroup\$
1
\$\begingroup\$

Ruby, 28 22 bytes

->s{s[/(.)\1*$/].size}

Anonymous function that takes the number as a string.

\$\endgroup\$
1
  • 1
    \$\begingroup\$ I believe you can get the match of a regex in Ruby like s[/(.)\1*$/]. \$\endgroup\$
    – user81655
    Mar 28, 2017 at 13:57
1
\$\begingroup\$

JavaScript (ES6), 53 bytes

f=(n,i=1)=>(a=[...n]).pop()==a[a.length-1]?f(a,i+1):i
\$\endgroup\$
1
\$\begingroup\$

Japt, 23 bytes

¬â l ¥1?Ul :Uw ¬b@X¦UgJ

Try it online!

Explanation:

¬â l ¥1?Ul :Uw ¬b@X¦UgJ
¬                         // Split the input into an array of chars
 â                        // Return all unique permutations
   l ¥1                   // Check if the length is equal to 1
       ?                  // If yes, return: 
        Ul                //   The length of the input
            :             // Else, return:
             Uw           //   The input, reversed
                ¬         //   Split into an array of chars
                  @       //   Iterate through, where X is the iterative item
                 b        //   Return the first index where:
                   X¦     //     X != 
                     UgJ  //     The last char in the input
\$\endgroup\$
1
\$\begingroup\$

Befunge-93, 45 bytes

<_v#`0:~
pv>$00p110
p>00g-#v_10g1+10
  @.g01<

Try it online!

\$\endgroup\$
1
\$\begingroup\$

Haskell, 36 bytes

Without import solution (39 bytes)

f n=length.takeWhile(==last n)$reverse n

Note that a pointfree solution is longer (and less understandable): EDIT: since anonymous functions are allowed, let's shave off two bytes which brings us to 39 (still longer than 36):

(length.).takeWhile.(==).last<*>reverse

With import solution (36 bytes, 19 without import)

import Data.List
f=length.last.group

Run like f "2394398222222" either way

\$\endgroup\$
1
\$\begingroup\$

05AB1E, 3 bytes

Åγθ

Try it online or verify all test cases.

Or alternatively:

γθg

Try it online or verify all test cases.

Explanation:

Åγ   # Run-length decode the (implicit) input-integer
     #  i.e. 1333822 → [1,3,1,2]
  θ  # Pop and push the last item
     #  → 2
     # (which is output implicitly as result)

γ    # Split the (implicit) input-integer into parts of subsequent equal digits
     #  i.e. 1333822 → [1,333,8,22]
 θ   # Pop and push the last item
     #  → 22
  g  # Pop and push its length
     #  → 2
     # (which is output implicitly as result)
\$\endgroup\$
1
\$\begingroup\$

Pyth, 4 bytes

her9

Kinda surprised this hasn't been posted yet.

Try it online!

\$\endgroup\$
1
\$\begingroup\$

Ruby -nl, 16 bytes

Input is STDIN. Subtracts the position of the start of the dubs sequence from the length of the string (technically, the position of the end of the string).

p~/$/-~/(.)\1*$/

Try it online!

\$\endgroup\$
1
\$\begingroup\$

Japt, 6 bytes

ì òÎÌÊ

Try it or run all test cases

ì òÎÌÊ     :Implicit input of integer
ì          :To digit array
  ò        :Partition between truthy pairs
   Î       :   Sign of difference
    Ì      :Last element
     Ê     :Length
\$\endgroup\$
1
\$\begingroup\$

APL (Dyalog Extended), 9 bytes

⊃⍸⌽1,2≠/⍞

input as a string

1,2≠/ 1 concatenated with n-wise reduction with ≠, boolean mask of the starts of sections

reverse

⊃⍸ index of the first 1

Try it online!

\$\endgroup\$
1
  • \$\begingroup\$ @Razetime true, edited \$\endgroup\$
    – rak1507
    Nov 3, 2020 at 13:36
1
\$\begingroup\$

Stax, 4 bytes

E:GH

Run and debug it

\$\endgroup\$
1
\$\begingroup\$

x86_64 machine code, 24 bytes

Could probably be golfed a bit further.

Input and output is through rax as integers.

00000000  6a 0a 5d 31 f6 31 d2 f7  f5 89 d3 ff c6 31 d2 f7  |j.]1.1.......1..|
00000010  f5 39 d3 74 f6 89 f0 c3                           |.9.t....|

Disassembly (with explanation):

dubs:
  6a 0a                 push   0xa
  5d                    pop    rbp      ; set rbp to 10 (for divison)
  31 f6                 xor    esi,esi  ; zero counter
  31 d2                 xor    edx,edx  ; zero upper dividend
  f7 f5                 div    ebp      ; initial divide (can this be golfed into the other divide?)
  89 d3                 mov    ebx,edx  ; set ebx (repeating digit)
loop:
  ff c6                 inc    esi      ; inc counter
  31 d2                 xor    edx,edx  ; zero upper dividend (gets filled with remainder)
  f7 f5                 div    ebp      ; divide
  39 d3                 cmp    ebx,edx  ; compare repeating digit with digit 'popped'
  74 f6                 jz     loop     ; if equal keep looping
  89 f0                 mov    eax,esi  ; move counter to eax for output
  c3                    ret

Full program source to run subroutine:

; nasm -felf64 -odubs.o dubs.asm
; ld -odubs dubs.o
; ./dubs; echo $?

bits 64

section .text
    global _start

_start:
    mov rax, 12344444
    call dubs
    
    mov rdi, rax
    mov rax, 60
    syscall ; exit with return val as exit code
    
dubs:
    push 10
    pop rbp
    xor esi, esi
    xor edx, edx
    div ebp ; eax quot edx rem
    mov ebx, edx
loop:
    inc esi
    xor edx, edx
    div ebp ; eax quot edx rem
    cmp ebx, edx
    jz loop
    mov eax, esi
    ret
\$\endgroup\$
1
\$\begingroup\$

K (oK), 15 12 bytes

{+/&\|x=*|x}

Try it online!

Takes input as a string.

  • x=*|x compare each digit to the last digit of the input
  • &\| "turn off" 1bs occurring after first 0b, e.g. &\|110011b => 110000b
  • +/ take sum
\$\endgroup\$
1
\$\begingroup\$

Jelly, 3 bytes

ŒɠṪ

Try it online!

Well, there’s a 5 byte and a 4 byte Jelly answer, so might as well go for 3 bytes

How it works

ŒɠṪ - Main link. Takes l on the left as a list of digits
Œɠ  - Group adjacent equal values in l and get the lengths of each
  Ṫ - Get the last one
\$\endgroup\$
1
\$\begingroup\$

AWK, 44 bytes

{for(d=$1%10;$1%10~d;k++)$1=($1-d)/10;$1=k}1

This piece of code uses math, so should work only with numbers.

{
for(             # $1 is the input, but will be modified during the code.
    d=$1%10;     # before the loop, records the last digit of $1 to _d_,
    $1%10~d;     # and stops if the last digit of $1 is different from _d_.
    k++          # increments 1 to _k_ after each loop.
   )
   $1=($1-d)/10; # removes the last digit of $1 and divides by 10.
                 # this uses less bytes than int($1/10).

$1=k             # after the end of the looping, assigns the count variable _k_
                 # to $1, which will become the output.
}
1                # prints $1

Try it online!


AWK, 44 bytes

{for(i=n=split($1,a,e);a[i--]~a[n];)$1=n-i}1

This code treats the input as string. Works with all kinds of characters.

{
for(
    i=n=split($1,a,e); # splits the input to the _a_ array,
                       # using the _e_ empty variable as flag (i.e, a null character)
                       # also sets the number of elements of the array
                       # to the _i_ and _n_ variables

    a[i--]~a[n];       # loops while the _i_ and _n_ elements are equal
                       # this also decrements _i_ by 1 after the evaluation
   )
     $1=n-i            # during each loop, sets the output to n-i
}
1                      # prints $1

Try it online!

\$\endgroup\$
1
\$\begingroup\$

Thunno 2 tL, 1 byte

ġ

Attempt This Online!

Thunno 2, 3 bytes

ġtl

Attempt This Online!

Explanation

     # Implicit input
ġ    # Group consecutive digits together
 t   # Get the last item (also done by t flag)
  l  # And push the length (also done by L flag)
     # Implicit output
\$\endgroup\$
1
\$\begingroup\$

Raku, 18 bytes

{m/(.)$0*$/.chars}

Try it online!

m/(.)$0*$/ applies a regex to the input argument that matches any number of the same trailing characters. (In Raku, applying a regex to a number implicitly matches against its string representation.) Then .chars counts how many characters there are in the match.

\$\endgroup\$
1
\$\begingroup\$

Lua, 36 bytes

s=...print(#s:match(~~(s%10)..'+$'))

Try it online!

\$\endgroup\$
0
\$\begingroup\$

PHP 40chars

(Does not take into account php tags)

strlen(preg_match('/(.)\1*$/',$argv[1]))
\$\endgroup\$
1
  • \$\begingroup\$ I think you mean preg_match('/(.)\1*$/',$argv[1],$t);echo strlen($t[0]); or as alternative <?=strlen(preg_filter('/.*?((.)\2*)$/','\1',$argv[1])); \$\endgroup\$ Mar 31, 2017 at 2:08
0
\$\begingroup\$

C#, 49 bytes

i=>i.Reverse().TakeWhile(x=>x==i.Last()).Count();

Try it here

Full code

  using System;
  using System.Linq;

  class Program
  {
      static void Main()
      {
          Func<string, int> func = i=>i.Reverse().TakeWhile(x=>x==i.Last()).Count();

          Console.WriteLine(func("14892093"));
          Console.WriteLine(func("12344444"));
          Console.WriteLine(func("112311"));
          Console.WriteLine(func("888888"));
          Console.WriteLine(func("135866667"));
          Console.ReadLine();
      }
  }
\$\endgroup\$
0
\$\begingroup\$

Java 7, 64 62 bytes

Golfed:

int w(int x){int r=1,d=x%10;while((x/=10)%10==d)r++;return r;}

Ungolfed:

int w(int x)
{
    int r = 1, d = x % 10;
    while ((x /= 10) % 10 == d)
        r++;
    return r;
}

Try it online

\$\endgroup\$
0
\$\begingroup\$

Vim - 39

ix^[Y$d?[^^R=@@[len(@@)-2]^M]^Mcc^R=len(@2)^M

(^[, ^Ms and ^Rs are one char each)

  • insert non-number (for 88888 input), copy line, move to the end
  • delete searching backwards for a char other then the last char
  • replace line with length of deleted text
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.