Fairshare between two and more

The Thue-Morse sequence is a sequence of ones and zeros that if two people take turns in the given order, the first persons turn for every '0' in the sequence, the second for every '1'; then this is shown to give a fairer, more equitable sharing of resources. (Football penalty shoot-outs for example, might not favour the team that goes first as much if the penalty takers take turns according to the Thue-Morse sequence and took 2^n penalties)

Task
Fairshare between two and more
You are encouraged to solve this task according to the task description, using any language you may know.

The Thue-Morse sequence of ones-and-zeroes can be generated by:

"When counting in binary, the digit sum modulo 2 is the Thue-Morse sequence"


Sharing fairly between two or more

Use this method:

When counting base b, the digit sum modulo b is the Thue-Morse sequence of fairer sharing between b people.


Task

Counting from zero;   using a function/method/routine to express an integer count in base b,
sum the digits modulo b to produce the next member of the Thue-Morse fairshare series for b people.


Show the first 25 terms of the fairshare sequence:

  •   For two people:
  •   For three people
  •   For five people
  •   For eleven people


Related tasks


See also



11l

Translation of: Python
F _basechange_int(=num, b)
   ‘
    Return list of ints representing positive num in base b
   ’
   I num == 0
      R [0]
   [Int] result
   L num != 0
      (num, V d) = divmod(num, b)
      result.append(d)
   R reversed(result)

F fairshare(b, n)
   [Int] r
   L(i) 0..
      r [+]= sum(_basechange_int(i, b)) % b
      I r.len == n
         L.break
   R r

L(b) (2, 3, 5, 11)
   print(‘#2’.format(b)‘: ’String(fairshare(b, 25))[1 .< (len)-1])
Output:
 2: 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0, 1, 0, 0, 1, 0, 1, 1, 0, 0
 3: 0, 1, 2, 1, 2, 0, 2, 0, 1, 1, 2, 0, 2, 0, 1, 0, 1, 2, 2, 0, 1, 0, 1, 2, 1
 5: 0, 1, 2, 3, 4, 1, 2, 3, 4, 0, 2, 3, 4, 0, 1, 3, 4, 0, 1, 2, 4, 0, 1, 2, 3
11: 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 0, 2, 3, 4

ALGOL 68

BEGIN # Use the generalised Thue-Morse sequence to generate Fairshare        #
      # sequences for various numbers of people                              #
    # returns the digit sum of n in the specified base                       #
    PROC digit sum = ( INT n, base )INT:
         IF n = 0 THEN 0
         ELSE
             INT result := 0;
             INT v      := ABS n;
             WHILE v > 0 DO
                 result +:= v MOD base;
                 v   OVERAB base
             OD;
             result
         FI # digit sum # ;
    # show the first n terms of the fairshare sequence in the specified base #
    PROC show fairshare = ( INT n, base )VOID:
         BEGIN
             print( ( whole( base, -2 ), ":" ) );
             FOR i FROM 0 TO n - 1 DO
                 print( ( " ", whole( digit sum( i, base ) MOD base, -2 ) ) )
             OD;
             print( ( newline ) )
         END # show fairshare # ;
    
    show fairshare( 25,  2 );
    show fairshare( 25,  3 );
    show fairshare( 25,  5 );
    show fairshare( 25, 11 )
END
Output:
 2:  0  1  1  0  1  0  0  1  1  0  0  1  0  1  1  0  1  0  0  1  0  1  1  0  0
 3:  0  1  2  1  2  0  2  0  1  1  2  0  2  0  1  0  1  2  2  0  1  0  1  2  1
 5:  0  1  2  3  4  1  2  3  4  0  2  3  4  0  1  3  4  0  1  2  4  0  1  2  3
11:  0  1  2  3  4  5  6  7  8  9 10  1  2  3  4  5  6  7  8  9 10  0  2  3  4

APL

Works with: Dyalog APL
fairshare  ⊣|(+/¯1)
2 3 5 11 ∘.fairshare 0,⍳24
Output:
0 1 1 0 1 0 0 1 1 0  0 1 0 1 1 0 1 0 0 1  0 1 1 0 0
0 1 2 1 2 0 2 0 1 1  2 0 2 0 1 0 1 2 2 0  1 0 1 2 1
0 1 2 3 4 1 2 3 4 0  2 3 4 0 1 3 4 0 1 2  4 0 1 2 3
0 1 2 3 4 5 6 7 8 9 10 1 2 3 4 5 6 7 8 9 10 0 2 3 4

AppleScript

-- thueMorse :: Int -> [Int]
on thueMorse(base)
    -- Non-finite sequence of Thue-Morse terms for a given base.
    fmapGen(baseDigitsSumModBase(base), enumFrom(0))
end thueMorse


-- baseDigitsSumModBase :: Int -> Int -> Int
on baseDigitsSumModBase(b)
    script
        on |λ|(n)
            script go
                on |λ|(x)
                    if 0 < x then
                        Just(Tuple(x mod b, x div b))
                    else
                        Nothing()
                    end if
                end |λ|
            end script
            sum(unfoldl(go, n)) mod b
        end |λ|
    end script
end baseDigitsSumModBase


-------------------------- TEST ---------------------------
on run
    script rjust
        on |λ|(x)
            justifyRight(2, space, str(x))
        end |λ|
    end script
    
    script test
        on |λ|(n)
            |λ|(n) of rjust & " -> " & ¬
                showList(map(rjust, take(25, thueMorse(n))))
        end |λ|
    end script
    
    unlines({"First 25 fairshare terms for N players:"} & ¬
        map(test, {2, 3, 5, 11}))
end run


-------------------- GENERIC FUNCTIONS --------------------

-- Just :: a -> Maybe a
on Just(x)
    -- Constructor for an inhabited Maybe (option type) value.
    -- Wrapper containing the result of a computation.
    {type:"Maybe", Nothing:false, Just:x}
end Just


-- Nothing :: Maybe a
on Nothing()
    -- Constructor for an empty Maybe (option type) value.
    -- Empty wrapper returned where a computation is not possible.
    {type:"Maybe", Nothing:true}
end Nothing


-- Tuple (,) :: a -> b -> (a, b)
on Tuple(a, b)
    -- Constructor for a pair of values, possibly of two different types.
    {type:"Tuple", |1|:a, |2|:b, length:2}
end Tuple


-- enumFrom :: Enum a => a -> [a]
on enumFrom(x)
    script
        property v : missing value
        property blnNum : class of x is not text
        on |λ|()
            if missing value is not v then
                if blnNum then
                    set v to 1 + v
                else
                    set v to succ(v)
                end if
            else
                set v to x
            end if
            return v
        end |λ|
    end script
end enumFrom


-- fmapGen <$> :: (a -> b) -> Gen [a] -> Gen [b]
on fmapGen(f, gen)
    script
        property g : mReturn(f)
        on |λ|()
            set v to gen's |λ|()
            if v is missing value then
                v
            else
                g's |λ|(v)
            end if
        end |λ|
    end script
end fmapGen


-- foldl :: (a -> b -> a) -> a -> [b] -> a
on foldl(f, startValue, xs)
    tell mReturn(f)
        set v to startValue
        set lng to length of xs
        repeat with i from 1 to lng
            set v to |λ|(v, item i of xs, i, xs)
        end repeat
        return v
    end tell
end foldl


-- intercalateS :: String -> [String] -> String
on intercalate(delim, xs)
    set {dlm, my text item delimiters} to ¬
        {my text item delimiters, delim}
    set s to xs as text
    set my text item delimiters to dlm
    s
end intercalate


-- justifyRight :: Int -> Char -> String -> String
on justifyRight(n, cFiller, s)
    if n > length of s then
        text -n thru -1 of ((replicate(n, cFiller) as text) & s)
    else
        s
    end if
end justifyRight


-- map :: (a -> b) -> [a] -> [b]
on map(f, xs)
    -- The list obtained by applying f
    -- to each element of xs.
    tell mReturn(f)
        set lng to length of xs
        set lst to {}
        repeat with i from 1 to lng
            set end of lst to |λ|(item i of xs, i, xs)
        end repeat
        return lst
    end tell
end map


-- mReturn :: First-class m => (a -> b) -> m (a -> b)
on mReturn(f)
    -- 2nd class handler function lifted into 1st class script wrapper. 
    if script is class of f then
        f
    else
        script
            property |λ| : f
        end script
    end if
end mReturn


-- Egyptian multiplication - progressively doubling a list, appending
-- stages of doubling to an accumulator where needed for binary 
-- assembly of a target length
-- replicate :: Int -> a -> [a]
on replicate(n, a)
    set out to {}
    if 1 > n then return out
    set dbl to {a}
    
    repeat while (1 < n)
        if 0 < (n mod 2) then set out to out & dbl
        set n to (n div 2)
        set dbl to (dbl & dbl)
    end repeat
    return out & dbl
end replicate


-- showList :: [a] -> String
on showList(xs)
    "[" & intercalate(",", map(my str, xs)) & "]"
end showList


-- str :: a -> String
on str(x)
    x as string
end str


-- sum :: [Num] -> Num
on sum(xs)
    script add
        on |λ|(a, b)
            a + b
        end |λ|
    end script
    
    foldl(add, 0, xs)
end sum


-- take :: Int -> [a] -> [a]
-- take :: Int -> String -> String
on take(n, xs)
    set c to class of xs
    if list is c then
        if 0 < n then
            items 1 thru min(n, length of xs) of xs
        else
            {}
        end if
    else if string is c then
        if 0 < n then
            text 1 thru min(n, length of xs) of xs
        else
            ""
        end if
    else if script is c then
        set ys to {}
        repeat with i from 1 to n
            set v to |λ|() of xs
            if missing value is v then
                return ys
            else
                set end of ys to v
            end if
        end repeat
        return ys
    else
        missing value
    end if
end take


-- > unfoldl (\b -> if b == 0 then Nothing else Just (b, b-1)) 10
-- > [1,2,3,4,5,6,7,8,9,10]
-- unfoldl :: (b -> Maybe (b, a)) -> b -> [a]
on unfoldl(f, v)
    set xr to Tuple(v, v) -- (value, remainder)
    set xs to {}
    tell mReturn(f)
        repeat -- Function applied to remainder.
            set mb to |λ|(|2| of xr)
            if Nothing of mb then
                exit repeat
            else -- New (value, remainder) tuple,
                set xr to Just of mb
                -- and value appended to output list.
                set xs to ({|1| of xr} & xs)
            end if
        end repeat
    end tell
    return xs
end unfoldl


-- unlines :: [String] -> String
on unlines(xs)
    -- A single string formed by the intercalation
    -- of a list of strings with the newline character.
    set {dlm, my text item delimiters} to ¬
        {my text item delimiters, linefeed}
    set s to xs as text
    set my text item delimiters to dlm
    s
end unlines
Output:
First 25 fairshare terms for N players:
 2 -> [ 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0, 1, 0, 0, 1, 0, 1, 1, 0, 0]
 3 -> [ 0, 1, 2, 1, 2, 0, 2, 0, 1, 1, 2, 0, 2, 0, 1, 0, 1, 2, 2, 0, 1, 0, 1, 2, 1]
 5 -> [ 0, 1, 2, 3, 4, 1, 2, 3, 4, 0, 2, 3, 4, 0, 1, 3, 4, 0, 1, 2, 4, 0, 1, 2, 3]
11 -> [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10, 1, 2, 3, 4, 5, 6, 7, 8, 9,10, 0, 2, 3, 4]

Arturo

thueMorse: function [base, howmany][
    i: 0
    result: new []
    while [howmany > size result][
        'result ++ (sum digits.base:base i) % base
        i: i + 1
    ]

    return result
]

loop [2 3 5 11] 'b ->
    print [
        (pad.right "Base "++(to :string b) 7)++" =>" 
        join.with:" " map to [:string] thueMorse b 25 'x -> pad x 2
    ]
Output:
Base 2  =>  0  1  1  0  1  0  0  1  1  0  0  1  0  1  1  0  1  0  0  1  0  1  1  0  0 
Base 3  =>  0  1  2  1  2  0  2  0  1  1  2  0  2  0  1  0  1  2  2  0  1  0  1  2  1 
Base 5  =>  0  1  2  3  4  1  2  3  4  0  2  3  4  0  1  3  4  0  1  2  4  0  1  2  3 
Base 11 =>  0  1  2  3  4  5  6  7  8  9 10  1  2  3  4  5  6  7  8  9 10  0  2  3  4

BASIC

10 DEFINT A-Z
20 DIM B(4): B(1)=2: B(2)=3: B(3)=5: B(4)=11
30 FOR I=1 TO 4
40 B=B(I)
50 PRINT USING "###:";I;
60 FOR N=0 TO 24: GOSUB 100: PRINT USING "###";S;: NEXT N
70 PRINT
80 NEXT I
90 END
100 REM
101 REM S = N'th item of fairshare sequence for B people
102 REM
110 S=0: Z=N
120 S=S+Z MOD B: Z=Z\B: IF Z>0 THEN 120
130 S=S MOD B
140 RETURN
Output:
  1:  0  1  1  0  1  0  0  1  1  0  0  1  0  1  1  0  1  0  0  1  0  1  1  0  0
  2:  0  1  2  1  2  0  2  0  1  1  2  0  2  0  1  0  1  2  2  0  1  0  1  2  1
  3:  0  1  2  3  4  1  2  3  4  0  2  3  4  0  1  3  4  0  1  2  4  0  1  2  3
  4:  0  1  2  3  4  5  6  7  8  9 10  1  2  3  4  5  6  7  8  9 10  0  2  3  4

BCPL

get "libhdr"

let digitsum(n,b) =
    n < b -> n,
    n rem b + digitsum(n/b, b)

let fairshare(n,b) =
    digitsum(n,b) rem b

let start() be
$(  let bs = table 2, 3, 5, 11
    for bi = 0 to 3
    $(  writef("%I2:", bs!bi)
        for n = 0 to 24 do writef("%I2 ", fairshare(n, bs!bi))
        wrch('*N')
    $)
$)
Output:
 2: 0  1  1  0  1  0  0  1  1  0  0  1  0  1  1  0  1  0  0  1  0  1  1  0  0
 3: 0  1  2  1  2  0  2  0  1  1  2  0  2  0  1  0  1  2  2  0  1  0  1  2  1
 5: 0  1  2  3  4  1  2  3  4  0  2  3  4  0  1  3  4  0  1  2  4  0  1  2  3
11: 0  1  2  3  4  5  6  7  8  9 10  1  2  3  4  5  6  7  8  9 10  0  2  3  4

C

#include <stdio.h>
#include <stdlib.h>

int turn(int base, int n) {
    int sum = 0;
    while (n != 0) {
        int rem = n % base;
        n = n / base;
        sum += rem;
    }
    return sum % base;
}

void fairshare(int base, int count) {
    int i;

    printf("Base %2d:", base);
    for (i = 0; i < count; i++) {
        int t = turn(base, i);
        printf(" %2d", t);
    }
    printf("\n");
}

void turnCount(int base, int count) {
    int *cnt = calloc(base, sizeof(int));
    int i, minTurn, maxTurn, portion;

    if (NULL == cnt) {
        printf("Failed to allocate space to determine the spread of turns.\n");
        return;
    }

    for (i = 0; i < count; i++) {
        int t = turn(base, i);
        cnt[t]++;
    }

    minTurn = INT_MAX;
    maxTurn = INT_MIN;
    portion = 0;
    for (i = 0; i < base; i++) {
        if (cnt[i] > 0) {
            portion++;
        }
        if (cnt[i] < minTurn) {
            minTurn = cnt[i];
        }
        if (cnt[i] > maxTurn) {
            maxTurn = cnt[i];
        }
    }

    printf("  With %d people: ", base);
    if (0 == minTurn) {
        printf("Only %d have a turn\n", portion);
    } else if (minTurn == maxTurn) {
        printf("%d\n", minTurn);
    } else {
        printf("%d or %d\n", minTurn, maxTurn);
    }

    free(cnt);
}

int main() {
    fairshare(2, 25);
    fairshare(3, 25);
    fairshare(5, 25);
    fairshare(11, 25);

    printf("How many times does each get a turn in 50000 iterations?\n");
    turnCount(191, 50000);
    turnCount(1377, 50000);
    turnCount(49999, 50000);
    turnCount(50000, 50000);
    turnCount(50001, 50000);

    return 0;
}
Output:
Base  2:  0  1  1  0  1  0  0  1  1  0  0  1  0  1  1  0  1  0  0  1  0  1  1  0  0
Base  3:  0  1  2  1  2  0  2  0  1  1  2  0  2  0  1  0  1  2  2  0  1  0  1  2  1
Base  5:  0  1  2  3  4  1  2  3  4  0  2  3  4  0  1  3  4  0  1  2  4  0  1  2  3
Base 11:  0  1  2  3  4  5  6  7  8  9 10  1  2  3  4  5  6  7  8  9 10  0  2  3  4
How many times does each get a turn in 50000 iterations?
  With 191 people: 261 or 262
  With 1377 people: 36 or 37
  With 49999 people: 1 or 2
  With 50000 people: 1
  With 50001 people: Only 50000 have a turn

C#

Translation of: Java
using System;
using System.Collections.Generic;

class FairshareBetweenTwoAndMore
{
    static void Main(string[] args)
    {
        foreach (int baseValue in new List<int> { 2, 3, 5, 11 })
        {
            Console.WriteLine($"Base {baseValue} = {string.Join(", ", ThueMorseSequence(25, baseValue))}");
        }
    }

    private static List<int> ThueMorseSequence(int terms, int baseValue)
    {
        List<int> sequence = new List<int>();
        for (int i = 0; i < terms; i++)
        {
            int sum = 0;
            int n = i;
            while (n > 0)
            {
                // Compute the digit sum
                sum += n % baseValue;
                n /= baseValue;
            }
            // Compute the digit sum modulo baseValue.
            sequence.Add(sum % baseValue);
        }
        return sequence;
    }
}
Output:
Base 2 = 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0, 1, 0, 0, 1, 0, 1, 1, 0, 0
Base 3 = 0, 1, 2, 1, 2, 0, 2, 0, 1, 1, 2, 0, 2, 0, 1, 0, 1, 2, 2, 0, 1, 0, 1, 2, 1
Base 5 = 0, 1, 2, 3, 4, 1, 2, 3, 4, 0, 2, 3, 4, 0, 1, 3, 4, 0, 1, 2, 4, 0, 1, 2, 3
Base 11 = 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 0, 2, 3, 4

C++

Translation of: C
#include <iostream>
#include <vector>

int turn(int base, int n) {
    int sum = 0;
    while (n != 0) {
        int rem = n % base;
        n = n / base;
        sum += rem;
    }
    return sum % base;
}

void fairshare(int base, int count) {
    printf("Base %2d:", base);
    for (int i = 0; i < count; i++) {
        int t = turn(base, i);
        printf(" %2d", t);
    }
    printf("\n");
}

void turnCount(int base, int count) {
    std::vector<int> cnt(base, 0);

    for (int i = 0; i < count; i++) {
        int t = turn(base, i);
        cnt[t]++;
    }

    int minTurn = INT_MAX;
    int maxTurn = INT_MIN;
    int portion = 0;
    for (int i = 0; i < base; i++) {
        if (cnt[i] > 0) {
            portion++;
        }
        if (cnt[i] < minTurn) {
            minTurn = cnt[i];
        }
        if (cnt[i] > maxTurn) {
            maxTurn = cnt[i];
        }
    }

    printf("  With %d people: ", base);
    if (0 == minTurn) {
        printf("Only %d have a turn\n", portion);
    } else if (minTurn == maxTurn) {
        printf("%d\n", minTurn);
    } else {
        printf("%d or %d\n", minTurn, maxTurn);
    }
}

int main() {
    fairshare(2, 25);
    fairshare(3, 25);
    fairshare(5, 25);
    fairshare(11, 25);

    printf("How many times does each get a turn in 50000 iterations?\n");
    turnCount(191, 50000);
    turnCount(1377, 50000);
    turnCount(49999, 50000);
    turnCount(50000, 50000);
    turnCount(50001, 50000);

    return 0;
}
Output:
Base  2:  0  1  1  0  1  0  0  1  1  0  0  1  0  1  1  0  1  0  0  1  0  1  1  0  0
Base  3:  0  1  2  1  2  0  2  0  1  1  2  0  2  0  1  0  1  2  2  0  1  0  1  2  1
Base  5:  0  1  2  3  4  1  2  3  4  0  2  3  4  0  1  3  4  0  1  2  4  0  1  2  3
Base 11:  0  1  2  3  4  5  6  7  8  9 10  1  2  3  4  5  6  7  8  9 10  0  2  3  4
How many times does each get a turn in 50000 iterations?
  With 191 people: 261 or 262
  With 1377 people: 36 or 37
  With 49999 people: 1 or 2
  With 50000 people: 1
  With 50001 people: Only 50000 have a turn

Cowgol

include "cowgol.coh";

sub fairshare(index: uint16, base: uint16): (result: uint16) is
    result := 0;
    while index > 0 loop
        result := result + index % base;
        index := index / base;
    end loop;
    result := result % base;
end sub;

sub printSequence(amount: uint16, base: uint16) is
    print_i16(base);
    print(": ");
    var index: uint16 := 0;
    while index < amount loop
        print_i16(fairshare(index, base));
        print(" ");
        index := index + 1;
    end loop;
    print_nl();
end sub;

printSequence(25, 2);
printSequence(25, 3);
printSequence(25, 5);
printSequence(25, 11);
Output:
2: 0 1 1 0 1 0 0 1 1 0 0 1 0 1 1 0 1 0 0 1 0 1 1 0 0
3: 0 1 2 1 2 0 2 0 1 1 2 0 2 0 1 0 1 2 2 0 1 0 1 2 1
5: 0 1 2 3 4 1 2 3 4 0 2 3 4 0 1 3 4 0 1 2 4 0 1 2 3
11: 0 1 2 3 4 5 6 7 8 9 10 1 2 3 4 5 6 7 8 9 10 0 2 3 4

EasyLang

Translation of: Cowgol
func fairshare ind base .
   while ind > 0
      r += ind mod base
      ind = ind div base
   .
   r = r mod base
   return r
.
proc sequence n base . .
   write base & ": "
   for ind range0 n
      write (fairshare ind base) & " "
   .
   print ""
.
sequence 25 2
sequence 25 3
sequence 25 5
sequence 25 11

D

Translation of: Kotlin
import std.array;
import std.stdio;

int turn(int base, int n) {
    int sum = 0;
    while (n != 0) {
        int re = n % base;
        n /= base;
        sum += re;
    }
    return sum % base;
}

void fairShare(int base, int count) {
    writef("Base %2d:", base);
    foreach (i; 0..count) {
        auto t = turn(base, i);
        writef(" %2d", t);
    }
    writeln;
}

void turnCount(int base, int count) {
    auto cnt = uninitializedArray!(int[])(base);
    cnt[] = 0;

    foreach (i; 0..count) {
        auto t = turn(base, i);
        cnt[t]++;
    }

    auto minTurn = int.max;
    auto maxTurn = int.min;
    int portion = 0;
    foreach (num; cnt) {
        if (num > 0) {
            portion++;
        }
        if (num < minTurn) {
            minTurn = num;
        }
        if (maxTurn < num) {
            maxTurn = num;
        }
    }

    writef("  With %d people: ", base);
    if (minTurn == 0) {
        writefln("Only %d have a turn", portion);
    } else if (minTurn == maxTurn) {
        writeln(minTurn);
    } else {
        writeln(minTurn," or ", maxTurn);
    }
}

void main() {
    fairShare(2, 25);
    fairShare(3, 25);
    fairShare(5, 25);
    fairShare(11, 25);

    writeln("How many times does each get a turn in 50000 iterations?");
    turnCount(191, 50000);
    turnCount(1377, 50000);
    turnCount(49999, 50000);
    turnCount(50000, 50000);
    turnCount(50001, 50000);
}
Output:
Base  2:  0  1  1  0  1  0  0  1  1  0  0  1  0  1  1  0  1  0  0  1  0  1  1  0  0
Base  3:  0  1  2  1  2  0  2  0  1  1  2  0  2  0  1  0  1  2  2  0  1  0  1  2  1
Base  5:  0  1  2  3  4  1  2  3  4  0  2  3  4  0  1  3  4  0  1  2  4  0  1  2  3
Base 11:  0  1  2  3  4  5  6  7  8  9 10  1  2  3  4  5  6  7  8  9 10  0  2  3  4
How many times does each get a turn in 50000 iterations?
  With 191 people: 261 or 262
  With 1377 people: 36 or 37
  With 49999 people: 1 or 2
  With 50000 people: 1
  With 50001 people: Only 50000 have a turn

Delphi

Works with: Delphi version 6.0


procedure DoFairshare(Memo: TMemo; Base: integer);
{Display 25 fairshare sequence items}
var I, N, Sum: integer;
var S: string;
begin
S:=Format('Base - %2d: ',[Base]);
for I:= 0 to 25-1 do
    begin
    N:= I; Sum:= 0;  
    while N>0 do
    	begin
    	Sum:= Sum + (N mod Base);
    	N:= N div Base;
    	end;
    S:=S+' '+IntToStr(Sum mod Base);
    end;
Memo.Lines.Add(S);
end;


procedure ShowFairshare(Memo: TMemo);
begin
DoFairshare(Memo,2);
DoFairshare(Memo,3);
DoFairshare(Memo,5);
DoFairshare(Memo,11);
end;
Output:
Base -  2:  0 1 1 0 1 0 0 1 1 0 0 1 0 1 1 0 1 0 0 1 0 1 1 0 0
Base -  3:  0 1 2 1 2 0 2 0 1 1 2 0 2 0 1 0 1 2 2 0 1 0 1 2 1
Base -  5:  0 1 2 3 4 1 2 3 4 0 2 3 4 0 1 3 4 0 1 2 4 0 1 2 3
Base - 11:  0 1 2 3 4 5 6 7 8 9 10 1 2 3 4 5 6 7 8 9 10 0 2 3 4

Elapsed Time: 4.753 ms.


Draco

proc fairshare(word n, base) word:
    word result;
    result := 0;
    while n>0 do
        result := result + n % base;
        n := n / base
    od;
    result % base
corp

proc main() void:
    [4]word bases = (2,3,5,11);
    word b, n;
    for b from 0 upto 3 do
        write(bases[b]:2, ':');
        for n from 0 upto 24 do
            write(fairshare(n, bases[b]):3)
        od;
        writeln()
    od
corp
Output:
 2:  0  1  1  0  1  0  0  1  1  0  0  1  0  1  1  0  1  0  0  1  0  1  1  0  0
 3:  0  1  2  1  2  0  2  0  1  1  2  0  2  0  1  0  1  2  2  0  1  0  1  2  1
 5:  0  1  2  3  4  1  2  3  4  0  2  3  4  0  1  3  4  0  1  2  4  0  1  2  3
11:  0  1  2  3  4  5  6  7  8  9 10  1  2  3  4  5  6  7  8  9 10  0  2  3  4

Factor

Works with: Factor version 0.99 2020-01-23
USING: formatting kernel math math.parser sequences ;

: nth-fairshare ( n base -- m )
    [ >base string>digits sum ] [ mod ] bi ;

: <fairshare> ( n base -- seq )
    [ nth-fairshare ] curry { } map-integers ;

{ 2 3 5 11 }
[ 25 over <fairshare> "%2d -> %u\n" printf ] each
Output:
 2 -> { 0 1 1 0 1 0 0 1 1 0 0 1 0 1 1 0 1 0 0 1 0 1 1 0 0 }
 3 -> { 0 1 2 1 2 0 2 0 1 1 2 0 2 0 1 0 1 2 2 0 1 0 1 2 1 }
 5 -> { 0 1 2 3 4 1 2 3 4 0 2 3 4 0 1 3 4 0 1 2 4 0 1 2 3 }
11 -> { 0 1 2 3 4 5 6 7 8 9 10 1 2 3 4 5 6 7 8 9 10 0 2 3 4 }

FreeBASIC

Translation of: Visual Basic .NET
Function Turn(mibase As Integer, n As Integer) As Integer
    Dim As Integer sum = 0
    While n <> 0
        Dim As Integer re = n Mod mibase
        n \= mibase
        sum += re
    Wend
    Return sum Mod mibase
End Function

Sub Fairshare(mibase As Integer, count As Integer)
    Print Using "mibase ##:"; mibase;
    For i As Integer = 1 To count
        Dim As Integer t = Turn(mibase, i - 1)
        Print Using " ##"; t;
    Next i
    Print
End Sub

Sub TurnCount(mibase As Integer, count As Integer)
    Dim As Integer cnt(mibase), i
    For i = 1 To mibase
        cnt(i - 1) = 0
    Next i
    
    For i = 1 To count
        Dim As Integer t = Turn(mibase, i - 1)
        cnt(t) += 1
    Next i
    
    Dim As Integer minTurn = 4294967295 'MaxValue of uLong
    Dim As Integer maxTurn = 0 'MinValue of uLong
    Dim As Integer portion = 0
    For i As Integer = 1 To mibase
        Dim As Integer num = cnt(i - 1)
        If num > 0 Then portion += 1
        If num < minTurn Then minTurn = num
        If num > maxTurn Then maxTurn = num
    Next i
    
    Print Using "  With ##### people: "; mibase;
    If 0 = minTurn Then
        Print Using "Only & have a turn"; portion
    Elseif minTurn = maxTurn Then
        Print minTurn
    Else
        Print Using "& or &"; minTurn; maxTurn
    End If
End Sub

Fairshare(2, 25)
Fairshare(3, 25)
Fairshare(5, 25)
Fairshare(11, 25)

Print "How many times does each get a turn in 50000 iterations?"
TurnCount(191, 50000)
TurnCount(1377, 50000)
TurnCount(49999, 50000)
TurnCount(50000, 50000)
TurnCount(50001, 50000)
Sleep
Output:
Igual que la entrada de Visual Basic .NET.


Go

package main

import (
    "fmt"
    "sort"
    "strconv"
    "strings"
)

func fairshare(n, base int) []int {
    res := make([]int, n)
    for i := 0; i < n; i++ {
        j := i
        sum := 0
        for j > 0 {
            sum += j % base
            j /= base
        }
        res[i] = sum % base
    }
    return res
}

func turns(n int, fss []int) string {
    m := make(map[int]int)
    for _, fs := range fss {
        m[fs]++
    }
    m2 := make(map[int]int)
    for _, v := range m {
        m2[v]++
    }
    res := []int{}
    sum := 0
    for k, v := range m2 {
        sum += v
        res = append(res, k)
    }
    if sum != n {
        return fmt.Sprintf("only %d have a turn", sum)
    }
    sort.Ints(res)
    res2 := make([]string, len(res))
    for i := range res {
        res2[i] = strconv.Itoa(res[i])
    }
    return strings.Join(res2, " or ")
}

func main() {
    for _, base := range []int{2, 3, 5, 11} {
        fmt.Printf("%2d : %2d\n", base, fairshare(25, base))
    }
    fmt.Println("\nHow many times does each get a turn in 50000 iterations?")
    for _, base := range []int{191, 1377, 49999, 50000, 50001} {
        t := turns(base, fairshare(50000, base))
        fmt.Printf("  With %d people: %s\n", base, t)
    }
}
Output:
 2 : [ 0  1  1  0  1  0  0  1  1  0  0  1  0  1  1  0  1  0  0  1  0  1  1  0  0]
 3 : [ 0  1  2  1  2  0  2  0  1  1  2  0  2  0  1  0  1  2  2  0  1  0  1  2  1]
 5 : [ 0  1  2  3  4  1  2  3  4  0  2  3  4  0  1  3  4  0  1  2  4  0  1  2  3]
11 : [ 0  1  2  3  4  5  6  7  8  9 10  1  2  3  4  5  6  7  8  9 10  0  2  3  4]

How many times does each get a turn in 50000 iterations?
  With 191 people: 261 or 262
  With 1377 people: 36 or 37
  With 49999 people: 1 or 2
  With 50000 people: 1
  With 50001 people: only 50000 have a turn

Haskell

import Data.Bool (bool)
import Data.List (intercalate, unfoldr)
import Data.Tuple (swap)

------------- FAIR SHARE BETWEEN TWO AND MORE ------------

thueMorse :: Int -> [Int]
thueMorse base = baseDigitsSumModBase base <$> [0 ..]

baseDigitsSumModBase :: Int -> Int -> Int
baseDigitsSumModBase base n =
  mod
    ( sum $
        unfoldr
          ( bool Nothing
              . Just
              . swap
              . flip quotRem base
              <*> (0 <)
          )
          n
    )
    base

--------------------------- TEST -------------------------
main :: IO ()
main =
  putStrLn $
    fTable
      ( "First 25 fairshare terms "
          <> "for a given number of players:\n"
      )
      show
      ( ('[' :) . (<> "]") . intercalate ","
          . fmap show
      )
      (take 25 . thueMorse)
      [2, 3, 5, 11]

------------------------- DISPLAY ------------------------
fTable ::
  String ->
  (a -> String) ->
  (b -> String) ->
  (a -> b) ->
  [a] ->
  String
fTable s xShow fxShow f xs =
  unlines $
    s :
    fmap
      ( ((<>) . justifyRight w ' ' . xShow)
          <*> ((" -> " <>) . fxShow . f)
      )
      xs
  where
    w = maximum (length . xShow <$> xs)

justifyRight :: Int -> Char -> String -> String
justifyRight n c = (drop . length) <*> (replicate n c <>)
Output:
First 25 fairshare terms for a given number of players:

 2 -> [0,1,1,0,1,0,0,1,1,0,0,1,0,1,1,0,1,0,0,1,0,1,1,0,0]
 3 -> [0,1,2,1,2,0,2,0,1,1,2,0,2,0,1,0,1,2,2,0,1,0,1,2,1]
 5 -> [0,1,2,3,4,1,2,3,4,0,2,3,4,0,1,3,4,0,1,2,4,0,1,2,3]
11 -> [0,1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,0,2,3,4]

J

   fairshare=: [ | [: +/"1 #.inv

   2 3 5 11 fairshare"0 1/i.25
0 1 1 0 1 0 0 1 1 0  0 1 0 1 1 0 1 0 0 1  0 1 1 0 0
0 1 2 1 2 0 2 0 1 1  2 0 2 0 1 0 1 2 2 0  1 0 1 2 1
0 1 2 3 4 1 2 3 4 0  2 3 4 0 1 3 4 0 1 2  4 0 1 2 3
0 1 2 3 4 5 6 7 8 9 10 1 2 3 4 5 6 7 8 9 10 0 2 3 4


   NB. In the 1st 50000 how many turns does each get?  answered:
   <@({.,#)/.~"1 ] 2 3 5 11 fairshare"0 1/i.50000
+-------+-------+-------+-------+-------+------+------+------+------+------+-------+
|0 25000|1 25000|       |       |       |      |      |      |      |      |       |
+-------+-------+-------+-------+-------+------+------+------+------+------+-------+
|0 16667|1 16667|2 16666|       |       |      |      |      |      |      |       |
+-------+-------+-------+-------+-------+------+------+------+------+------+-------+
|0 10000|1 10000|2 10000|3 10000|4 10000|      |      |      |      |      |       |
+-------+-------+-------+-------+-------+------+------+------+------+------+-------+
|0 4545 |1 4545 |2 4545 |3 4545 |4 4546 |5 4546|6 4546|7 4546|8 4546|9 4545|10 4545|
+-------+-------+-------+-------+-------+------+------+------+------+------+-------+

Java

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

public class FairshareBetweenTwoAndMore {

    public static void main(String[] args) {
        for ( int base : Arrays.asList(2, 3, 5, 11) ) {
            System.out.printf("Base %d = %s%n", base, thueMorseSequence(25, base));
        }
    }
    
    private static List<Integer> thueMorseSequence(int terms, int base) {
        List<Integer> sequence = new ArrayList<Integer>();
        for ( int i = 0 ; i < terms ; i++ ) {
            int sum = 0;
            int n = i;
            while ( n > 0 ) {
                //  Compute the digit sum
                sum += n % base;
                n /= base;
            }
            //  Compute the digit sum module base.
            sequence.add(sum % base);
        }
        return sequence;
    }

}
Output:
Base 2 = [0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0, 1, 0, 0, 1, 0, 1, 1, 0, 0]
Base 3 = [0, 1, 2, 1, 2, 0, 2, 0, 1, 1, 2, 0, 2, 0, 1, 0, 1, 2, 2, 0, 1, 0, 1, 2, 1]
Base 5 = [0, 1, 2, 3, 4, 1, 2, 3, 4, 0, 2, 3, 4, 0, 1, 3, 4, 0, 1, 2, 4, 0, 1, 2, 3]
Base 11 = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 0, 2, 3, 4]

JavaScript

(() => {
    'use strict';

    // thueMorse :: Int -> [Int]
    const thueMorse = base =>
        // Thue-Morse sequence for a given base
        fmapGen(baseDigitsSumModBase(base))(
            enumFrom(0)
        )

    // baseDigitsSumModBase :: Int -> Int -> Int
    const baseDigitsSumModBase = base =>
        // For any integer n, the sum of its digits
        // in a given base, modulo that base.
        n => sum(unfoldl(
            x => 0 < x ? (
                Just(quotRem(x)(base))
            ) : Nothing()
        )(n)) % base


    // ------------------------TEST------------------------
    const main = () =>
        console.log(
            fTable(
                'First 25 fairshare terms for a given number of players:'
            )(str)(
                xs => '[' + map(
                    compose(justifyRight(2)(' '), str)
                )(xs) + ' ]'
            )(
                compose(take(25), thueMorse)
            )([2, 3, 5, 11])
        );

    // -----------------GENERIC FUNCTIONS------------------

    // Just :: a -> Maybe a
    const Just = x => ({
        type: 'Maybe',
        Nothing: false,
        Just: x
    });

    // Nothing :: Maybe a
    const Nothing = () => ({
        type: 'Maybe',
        Nothing: true,
    });

    // Tuple (,) :: a -> b -> (a, b)
    const Tuple = a => b => ({
        type: 'Tuple',
        '0': a,
        '1': b,
        length: 2
    });

    // compose (<<<) :: (b -> c) -> (a -> b) -> a -> c
    const compose = (...fs) =>
        x => fs.reduceRight((a, f) => f(a), x);

    // enumFrom :: Enum a => a -> [a]
    function* enumFrom(x) {
        // A non-finite succession of enumerable
        // values, starting with the value x.
        let v = x;
        while (true) {
            yield v;
            v = 1 + v;
        }
    }

    // fTable :: String -> (a -> String) -> (b -> String)
    //                      -> (a -> b) -> [a] -> String
    const fTable = s => xShow => fxShow => f => xs => {
        // Heading -> x display function ->
        //           fx display function ->
        //    f -> values -> tabular string
        const
            ys = xs.map(xShow),
            w = Math.max(...ys.map(length));
        return s + '\n' + zipWith(
            a => b => a.padStart(w, ' ') + ' -> ' + b
        )(ys)(
            xs.map(x => fxShow(f(x)))
        ).join('\n');
    };

    // fmapGen <$> :: (a -> b) -> Gen [a] -> Gen [b]
    const fmapGen = f =>
        function*(gen) {
            let v = take(1)(gen);
            while (0 < v.length) {
                yield(f(v[0]))
                v = take(1)(gen)
            }
        };

    // justifyRight :: Int -> Char -> String -> String
    const justifyRight = n =>
        // The string s, preceded by enough padding (with
        // the character c) to reach the string length n.
        c => s => n > s.length ? (
            s.padStart(n, c)
        ) : s;

    // length :: [a] -> Int
    const length = xs =>
        // Returns Infinity over objects without finite
        // length. This enables zip and zipWith to choose
        // the shorter argument when one is non-finite,
        // like cycle, repeat etc
        (Array.isArray(xs) || 'string' === typeof xs) ? (
            xs.length
        ) : Infinity;

    // map :: (a -> b) -> [a] -> [b]
    const map = f =>
        // The list obtained by applying f to each element of xs.
        // (The image of xs under f).
        xs => (Array.isArray(xs) ? (
            xs
        ) : xs.split('')).map(f);

    // quotRem :: Int -> Int -> (Int, Int)
    const quotRem = m => n =>
        Tuple(Math.floor(m / n))(
            m % n
        );

    // str :: a -> String
    const str = x => x.toString();

    // sum :: [Num] -> Num
    const sum = xs =>
        // The numeric sum of all values in xs.
        xs.reduce((a, x) => a + x, 0);

    // take :: Int -> [a] -> [a]
    // take :: Int -> String -> String
    const take = n =>
        // The first n elements of a list,
        // string of characters, or stream.
        xs => 'GeneratorFunction' !== xs
        .constructor.constructor.name ? (
            xs.slice(0, n)
        ) : [].concat.apply([], Array.from({
            length: n
        }, () => {
            const x = xs.next();
            return x.done ? [] : [x.value];
        }));


    // unfoldl :: (b -> Maybe (b, a)) -> b -> [a]
    const unfoldl = f => v => {
        // Dual to reduce or foldl.
        // Where these reduce a list to a summary value, unfoldl
        // builds a list from a seed value.
        // Where f returns Just(a, b), a is appended to the list,
        // and the residual b is used as the argument for the next
        // application of f.
        // Where f returns Nothing, the completed list is returned.
        let
            xr = [v, v],
            xs = [];
        while (true) {
            const mb = f(xr[0]);
            if (mb.Nothing) {
                return xs
            } else {
                xr = mb.Just;
                xs = [xr[1]].concat(xs);
            }
        }
    };

    // zipWith :: (a -> b -> c) -> [a] -> [b] -> [c]
    const zipWith = f =>
        xs => ys => {
            const
                lng = Math.min(length(xs), length(ys)),
                vs = take(lng)(ys);
            return take(lng)(xs)
                .map((x, i) => f(x)(vs[i]));
        };

    // MAIN ---
    return main();
})();
Output:
First 25 fairshare terms for a given number of players:
 2 -> [ 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0, 1, 0, 0, 1, 0, 1, 1, 0, 0 ]
 3 -> [ 0, 1, 2, 1, 2, 0, 2, 0, 1, 1, 2, 0, 2, 0, 1, 0, 1, 2, 2, 0, 1, 0, 1, 2, 1 ]
 5 -> [ 0, 1, 2, 3, 4, 1, 2, 3, 4, 0, 2, 3, 4, 0, 1, 3, 4, 0, 1, 2, 4, 0, 1, 2, 3 ]
11 -> [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10, 1, 2, 3, 4, 5, 6, 7, 8, 9,10, 0, 2, 3, 4 ]

jq

jq has a built-in for limiting a generator, but does not have a built-in for generating the integers in an arbitrary base, so we begin by defining `integers($base)` for generating integers as arrays beginning with the least-significant digit.

# Using a "reverse array" representations of the integers base b (b>=2),
# generate an unbounded stream of the integers from [0] onwards.
# E.g. for binary: [0], [1], [0,1], [1,1] ...

def integers($base):
  def add1:
    [foreach (.[], null) as $d ({carry: 1};
     if $d then ($d + .carry ) as $r
     | if $r >= $base
       then {carry: 1, emit: ($r - $base)}
       else {carry: 0, emit: $r }
       end
     elif (.carry == 0) then .emit = null
     else .emit = .carry
     end;
  select(.emit).emit)];
  
  [0] | recurse(add1);

def fairshare($base; $numberOfTerms):
  limit($numberOfTerms;
        integers($base) | add | . % $base);

# The task:
(2,3,5,11)
| "Fairshare \((select(.>2)|"among") // "between") \(.) people: \([fairshare(.; 25)])"
Output:

As for Julia.

Julia

fairshare(nplayers,len) = [sum(digits(n, base=nplayers)) % nplayers for n in 0:len-1]

for n in [2, 3, 5, 11]
    println("Fairshare ", n > 2 ? "among" : "between", " $n people: ", fairshare(n, 25))
end
Output:
Fairshare between 2 people: [0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0, 1, 0, 0, 1, 0, 1, 1, 0, 0]
Fairshare among 3 people: [0, 1, 2, 1, 2, 0, 2, 0, 1, 1, 2, 0, 2, 0, 1, 0, 1, 2, 2, 0, 1, 0, 1, 2, 1]
Fairshare among 5 people: [0, 1, 2, 3, 4, 1, 2, 3, 4, 0, 2, 3, 4, 0, 1, 3, 4, 0, 1, 2, 4, 0, 1, 2, 3]
Fairshare among 11 people: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 0, 2, 3, 4]

Kotlin

Translation of: Visual Basic .NET
fun turn(base: Int, n: Int): Int {
    var sum = 0
    var n2 = n
    while (n2 != 0) {
        val re = n2 % base
        n2 /= base
        sum += re
    }
    return sum % base
}

fun fairShare(base: Int, count: Int) {
    print(String.format("Base %2d:", base))
    for (i in 0 until count) {
        val t = turn(base, i)
        print(String.format(" %2d", t))
    }
    println()
}

fun turnCount(base: Int, count: Int) {
    val cnt = IntArray(base) { 0 }
    for (i in 0 until count) {
        val t = turn(base, i)
        cnt[t]++
    }

    var minTurn = Int.MAX_VALUE
    var maxTurn = Int.MIN_VALUE
    var portion = 0
    for (i in 0 until base) {
        val num = cnt[i]
        if (num > 0) {
            portion++
        }
        if (num < minTurn) {
            minTurn = num
        }
        if (num > maxTurn) {
            maxTurn = num
        }
    }

    print("  With $base people: ")
    when (minTurn) {
        0 -> {
            println("Only $portion have a turn")
        }
        maxTurn -> {
            println(minTurn)
        }
        else -> {
            println("$minTurn or $maxTurn")
        }
    }
}

fun main() {
    fairShare(2, 25)
    fairShare(3, 25)
    fairShare(5, 25)
    fairShare(11, 25)

    println("How many times does each get a turn in 50000 iterations?")
    turnCount(191, 50000)
    turnCount(1377, 50000)
    turnCount(49999, 50000)
    turnCount(50000, 50000)
    turnCount(50001, 50000)
}
Output:
Base  2:  0  1  1  0  1  0  0  1  1  0  0  1  0  1  1  0  1  0  0  1  0  1  1  0  0
Base  3:  0  1  2  1  2  0  2  0  1  1  2  0  2  0  1  0  1  2  2  0  1  0  1  2  1
Base  5:  0  1  2  3  4  1  2  3  4  0  2  3  4  0  1  3  4  0  1  2  4  0  1  2  3
Base 11:  0  1  2  3  4  5  6  7  8  9 10  1  2  3  4  5  6  7  8  9 10  0  2  3  4
How many times does each get a turn in 50000 iterations?
  With 191 people: 261 or 262
  With 1377 people: 36 or 37
  With 49999 people: 1 or 2
  With 50000 people: 1
  With 50001 people: Only 50000 have a turn

Lua

Translation of: D
function turn(base, n)
    local sum = 0
    while n ~= 0 do
        local re = n % base
        n = math.floor(n / base)
        sum = sum + re
    end
    return sum % base
end

function fairShare(base, count)
    io.write(string.format("Base %2d:", base))
    for i=1,count do
        local t = turn(base, i - 1)
        io.write(string.format(" %2d", t))
    end
    print()
end

function turnCount(base, count)
    local cnt = {}

    for i=1,base do
        cnt[i - 1] = 0
    end

    for i=1,count do
        local t = turn(base, i - 1)
        if cnt[t] ~= nil then
            cnt[t] = cnt[t] + 1
        else
            cnt[t] = 1
        end
    end

    local minTurn = count
    local maxTurn = -count
    local portion = 0
    for _,num in pairs(cnt) do
        if num > 0 then
            portion = portion + 1
        end
        if num < minTurn then
            minTurn = num
        end
        if maxTurn < num then
            maxTurn = num
        end
    end

    io.write(string.format("  With %d people: ", base))
    if minTurn == 0 then
        print(string.format("Only %d have a turn", portion))
    elseif minTurn == maxTurn then
        print(minTurn)
    else
        print(minTurn .. " or " .. maxTurn)
    end
end

function main()
    fairShare(2, 25)
    fairShare(3, 25)
    fairShare(5, 25)
    fairShare(11, 25)

    print("How many times does each get a turn in 50000 iterations?")
    turnCount(191, 50000)
    turnCount(1377, 50000)
    turnCount(49999, 50000)
    turnCount(50000, 50000)
    turnCount(50001, 50000)
end

main()
Output:
Base  2:  0  1  1  0  1  0  0  1  1  0  0  1  0  1  1  0  1  0  0  1  0  1  1  0  0
Base  3:  0  1  2  1  2  0  2  0  1  1  2  0  2  0  1  0  1  2  2  0  1  0  1  2  1
Base  5:  0  1  2  3  4  1  2  3  4  0  2  3  4  0  1  3  4  0  1  2  4  0  1  2  3
Base 11:  0  1  2  3  4  5  6  7  8  9 10  1  2  3  4  5  6  7  8  9 10  0  2  3  4
How many times does each get a turn in 50000 iterations?
  With 191 people: 261 or 262
  With 1377 people: 36 or 37
  With 49999 people: 1 or 2
  With 50000 people: 1
  With 50001 people: Only 50000 have a turn

Mathematica / Wolfram Language

ClearAll[Fairshare]
Fairshare[n_List, b_Integer : 2] := Fairshare[#, b] & /@ n
Fairshare[n_Integer, b_Integer : 2] := Mod[Total[IntegerDigits[n, b]], b]
Fairshare[Range[0, 24], 2]
Fairshare[Range[0, 24], 3]
Fairshare[Range[0, 24], 5]
Fairshare[Range[0, 24], 11]
Output:
{0,1,1,0,1,0,0,1,1,0,0,1,0,1,1,0,1,0,0,1,0,1,1,0,0}
{0,1,2,1,2,0,2,0,1,1,2,0,2,0,1,0,1,2,2,0,1,0,1,2,1}
{0,1,2,3,4,1,2,3,4,0,2,3,4,0,1,3,4,0,1,2,4,0,1,2,3}
{0,1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,0,2,3,4}

Nim

import math, strutils

#---------------------------------------------------------------------------------------------------

iterator countInBase(b: Positive): seq[Natural] =
  ## Yield the successive integers in base "b" as a sequence of digits.
  
  var value = @[Natural 0]
  yield value

  while true:

    # Add one to current value.
    var c = 1
    for i in countdown(value.high, 0):
      let val = value[i] + c
      if val < b:
        value[i] = val
        c = 0
      else:
        value[i] = val - b
        c = 1

    if c == 1:
      # Add a new digit at the beginning.
      # In this case, for better performances, we could have add it at the end.
      value.insert(c, 0)

    yield value

#---------------------------------------------------------------------------------------------------

func thueMorse(b: Positive; count: Natural): seq[Natural] =
  ## Return the "count" first elements of Thue-Morse sequence for base "b".
  
  var count = count
  for n in countInBase(b):
    result.add(sum(n) mod b)
    dec count
    if count == 0: break

#———————————————————————————————————————————————————————————————————————————————————————————————————

for base in [2, 3, 5, 11]:
  echo "Base ", ($base & ": ").alignLeft(4), thueMorse(base, 25).join(" ")
Output:
Base 2:  0 1 1 0 1 0 0 1 1 0 0 1 0 1 1 0 1 0 0 1 0 1 1 0 0
Base 3:  0 1 2 1 2 0 2 0 1 1 2 0 2 0 1 0 1 2 2 0 1 0 1 2 1
Base 5:  0 1 2 3 4 1 2 3 4 0 2 3 4 0 1 3 4 0 1 2 4 0 1 2 3
Base 11: 0 1 2 3 4 5 6 7 8 9 10 1 2 3 4 5 6 7 8 9 10 0 2 3 4

Pascal

Free Pascal

program Fairshare;
{$IFDEF FPC}{$MODE Delphi}{$Optimization ON,ALL}{$ENDIF}
{$IFDEF WINDOWS}{$APPTYPE CONSOLE}{$ENDIF}
uses
  sysutils;
const
  maxDigitCnt = 32;
type
  tdigit  = Uint32;
  tDgtSum = record
              dgts   : array[0..maxDigitCnt-1] of tdigit;
              dgtNum : Uint64;
              dgtsum : Uint64;//maxValue maxDigitCnt*(dgtBase-1)
              dgtBase,
              dgtThue : tDigit;
            end;
procedure OutDgtSum(const ds:tDgtSum);
var
  i : NativeInt;
Begin
  with ds do
  Begin
    writeln(' base ',dgtBase,' sum of digits :  ',dgtSum,' dec number ',dgtNum);
    i := Low(dgts);
    repeat
      write(dgts[i],'|');
      inc(i);
    until i > High(dgts);
    writeln;
  end;
end;

function IncDgtSum(var ds:tDgtSum):boolean;
//add 1 to dgts and corrects sum of Digits
//return false if overflow happens
var
  i,base_1 : NativeInt;
Begin
  with ds do
  begin
    i := High(dgts);
    base_1 := dgtBase-1;
    inc(dgtNum);
    repeat
      IF dgts[i] < base_1 then
      //add one and done
      Begin
        inc(dgts[i]);
        inc(dgtSum);
        BREAK;
      end
      else
      Begin
        dgts[i] := 0;
        dec(dgtSum,base_1);
      end;
      dec(i);
    until i < Low(dgts);
    dgtThue := dgtSum MOD (base_1+1);
    result := i < Low(dgts)
  end;  
end;

procedure CheckBase_N_Turns( base:tDigit;turns:NativeUInt);
var
  actualNo :tDgtSum;
  slots : array of Uint32;
  pSlots : pUint32;
  i : NativeUInt;
Begin
  fillchar(actualNo,SizeOf(actualNo),#0);
  setlength(slots,base);
  pSlots := @slots[0];
  actualNo.dgtBase := Base;
  Write(base:3,' [');
  while turns>0 do
  Begin
    inc(pSlots[actualNo.dgtThue],turns);
    IncDgtSum(actualNo);
    dec(turns);
  end;
  For i := 0 to Base-1 do
    write(pSlots[i],' ');  
  writeln(']');
end;

procedure SumBase_N_Turns( base:tDigit;turns:NativeUInt);
var
  actualNo :tDgtSum;
Begin
  fillchar(actualNo,SizeOf(actualNo),#0);
  actualNo.dgtBase := Base;
  Write(base:3,' [');
  while turns>1 do
  Begin
    write(actualNo.dgtThue,',');
    IncDgtSum(actualNo);
    dec(turns);
  end;
  writeln(actualNo.dgtThue,']');
end;

var
  turns : NativeInt;
Begin
  turns := 25;
  SumBase_N_Turns(2,turns);  SumBase_N_Turns(3,turns);
  SumBase_N_Turns(5,turns);  SumBase_N_Turns(11,turns);
    
  Writeln;
  writeln('Summing up descending numbers from turns downto 0');;
  turns := 2*3*5*11;
  Writeln(turns,' turns = 2*3*5*11');
  CheckBase_N_Turns(2,turns); CheckBase_N_Turns(3,turns);
  CheckBase_N_Turns(5,turns); CheckBase_N_Turns(11,turns);

  turns := sqr(2)*sqr(3)*sqr(5)*sqr(11);
  Writeln(turns,' turns = sqr(2)*sqr(3)*sqr(5)*sqr(11)');
  CheckBase_N_Turns(2,turns); CheckBase_N_Turns(3,turns);
  CheckBase_N_Turns(5,turns); CheckBase_N_Turns(11,turns);
end.
Output:
  2 [0,1,1,0,1,0,0,1,1,0,0,1,0,1,1,0,1,0,0,1,0,1,1,0,0]
  3 [0,1,2,1,2,0,2,0,1,1,2,0,2,0,1,0,1,2,2,0,1,0,1,2,1]
  5 [0,1,2,3,4,1,2,3,4,0,2,3,4,0,1,3,4,0,1,2,4,0,1,2,3]
 11 [0,1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,0,2,3,4]

Summing up descending numbers from turns downto 0
330 turns = 2*3*5*11
  2 [27307 27308 ]
  3 [18206 18204 18205 ]
  5 [10925 10924 10923 10922 10921 ]
 11 [4961 4953 4956 4959 4962 4965 4968 4971 4974 4977 4969 ]
108900 turns = sqr(2)*sqr(3)*sqr(5)*sqr(11)
  2 [2964829725 2964829725]
  3 [1976553150 1976553150 1976553150]
  5 [1185931890 1185931890 1185931890 1185931890 1185931890]
 11 [539059950 539059950 539059950 539059950 539059950 539059950 539059950 539059950 539059950 539059950 539059950]

Perl

Translation of: Raku
use strict;
use warnings;
use Math::AnyNum qw(sum polymod);

sub fairshare {
    my($b, $n) = @_;
    sprintf '%3d'x$n, map { sum ( polymod($_, $b, $b )) % $b } 0 .. $n-1;
}

for (<2 3 5 11>) {
    printf "%3s:%s\n", $_, fairshare($_, 25);
}
Output:
  2:  0  1  1  0  1  0  0  1  0  1  1  0  1  0  0  1  0  1  1  0  1  0  0  1  0
  3:  0  1  2  1  2  0  2  0  1  1  2  0  2  0  1  0  1  2  2  0  1  0  1  2  1
  5:  0  1  2  3  4  1  2  3  4  0  2  3  4  0  1  3  4  0  1  2  4  0  1  2  3
 11:  0  1  2  3  4  5  6  7  8  9 10  1  2  3  4  5  6  7  8  9 10  0  2  3  4

Phix

Translation of: Go
function fairshare(integer n, base)
    sequence res = repeat(0,n)
    for i=1 to n do
        integer j = i-1,
                t = 0
        while j>0 do
            t += remainder(j,base)
            j = floor(j/base)
        end while
        res[i] = remainder(t,base)
    end for
    return {base,res}
end function
 
constant tests = {2,3,5,11}
for i=1 to length(tests) do
    printf(1,"%2d : %v\n", fairshare(25, tests[i]))
end for
Output:
 2 : {0,1,1,0,1,0,0,1,1,0,0,1,0,1,1,0,1,0,0,1,0,1,1,0,0}
 3 : {0,1,2,1,2,0,2,0,1,1,2,0,2,0,1,0,1,2,2,0,1,0,1,2,1}
 5 : {0,1,2,3,4,1,2,3,4,0,2,3,4,0,1,3,4,0,1,2,4,0,1,2,3}
11 : {0,1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,0,2,3,4}

PL/M

100H:

BDOS: PROCEDURE (F,A); DECLARE F BYTE, A ADDRESS; GO TO 5; END BDOS;
EXIT: PROCEDURE; GO TO 0; END EXIT;
PRINT: PROCEDURE (S); DECLARE S ADDRESS; CALL BDOS(9,S); END PRINT;

PRINT$NUMBER: PROCEDURE (N);
    DECLARE S (7) BYTE INITIAL ('..... $');
    DECLARE (N, P) ADDRESS, C BASED P BYTE;
    P = .S(5);
DIGIT:
    P = P - 1;
    C = N MOD 10 + '0';
    N = N / 10;
    IF N > 0 THEN GO TO DIGIT;
    CALL PRINT(P);
END PRINT$NUMBER;

FAIR$SHARE: PROCEDURE (N, BASE) ADDRESS;
    DECLARE (N, BASE, SUM) ADDRESS;
    SUM = 0;
    DO WHILE N>0;
        SUM = SUM + N MOD BASE;
        N = N / BASE;
    END;
    RETURN SUM MOD BASE;
END FAIR$SHARE;

DECLARE BASES (4) BYTE INITIAL (2, 3, 5, 11);
DECLARE (I, N) BYTE;

DO I=0 TO LAST(BASES);
    CALL PRINT$NUMBER(BASES(I));
    CALL PRINT(.': $');
    DO N=0 TO 24;
        CALL PRINT$NUMBER(FAIR$SHARE(N, BASES(I)));
    END;
    CALL PRINT(.(13,10,'$'));
END;
CALL EXIT;
EOF
Output:
2 : 0 1 1 0 1 0 0 1 1 0 0 1 0 1 1 0 1 0 0 1 0 1 1 0 0
3 : 0 1 2 1 2 0 2 0 1 1 2 0 2 0 1 0 1 2 2 0 1 0 1 2 1
5 : 0 1 2 3 4 1 2 3 4 0 2 3 4 0 1 3 4 0 1 2 4 0 1 2 3
11 : 0 1 2 3 4 5 6 7 8 9 10 1 2 3 4 5 6 7 8 9 10 0 2 3 4

Python

Procedural

from itertools import count, islice

def _basechange_int(num, b):
    """
    Return list of ints representing positive num in base b

    >>> b = 3
    >>> print(b, [_basechange_int(num, b) for num in range(11)])
    3 [[0], [1], [2], [1, 0], [1, 1], [1, 2], [2, 0], [2, 1], [2, 2], [1, 0, 0], [1, 0, 1]]
    >>>
    """
    if num == 0:
        return [0]
    result = []
    while num != 0:
        num, d = divmod(num, b)
        result.append(d)
    return result[::-1]

def fairshare(b=2):
    for i in count():
        yield sum(_basechange_int(i, b)) % b

if __name__ == '__main__':
    for b in (2, 3, 5, 11):
        print(f"{b:>2}: {str(list(islice(fairshare(b), 25)))[1:-1]}")
Output:
 2: 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0, 1, 0, 0, 1, 0, 1, 1, 0, 0
 3: 0, 1, 2, 1, 2, 0, 2, 0, 1, 1, 2, 0, 2, 0, 1, 0, 1, 2, 2, 0, 1, 0, 1, 2, 1
 5: 0, 1, 2, 3, 4, 1, 2, 3, 4, 0, 2, 3, 4, 0, 1, 3, 4, 0, 1, 2, 4, 0, 1, 2, 3
11: 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 0, 2, 3, 4

Functional

'''Fairshare between two and more'''

from itertools import count, islice
from functools import reduce


# thueMorse :: Int -> [Int] -> [Int]
def thueMorse(base):
    '''Thue-Morse sequence for a given base.'''
    return fmapNext(baseDigitsSumModBase(base))(
        count(0)
    )


# baseDigitsSumModBase :: Int -> Int -> Int
def baseDigitsSumModBase(base):
    '''For any integer n, the sum of its digits
       in a given base, modulo that base.
    '''
    def go(n):
        return sum(unfoldl(
            lambda x: Just(divmod(x, base)) if 0 < x else Nothing()
        )(n)) % base

    return go


# -------------------------- TEST --------------------------
# main :: IO ()
def main():
    '''First 25 fairshare terms for a given number of players'''

    print(
        fTable(
            main.__doc__ + ':\n'
        )(repr)(
            lambda xs: '[' + ','.join(
                [str(x).rjust(2, ' ') for x in xs]
            ) + ' ]'
        )(
            compose(take(25), thueMorse)
        )([2, 3, 5, 11])
    )


# ------------------------ GENERIC -------------------------

# Just :: a -> Maybe a
def Just(x):
    '''Constructor for an inhabited Maybe (option type) value.
       Wrapper containing the result of a computation.
    '''
    return {'type': 'Maybe', 'Nothing': False, 'Just': x}


# Nothing :: Maybe a
def Nothing():
    '''Constructor for an empty Maybe (option type) value.
       Empty wrapper returned where a computation is not possible.
    '''
    return {'type': 'Maybe', 'Nothing': True}


# compose :: ((a -> a), ...) -> (a -> a)
def compose(*fs):
    '''Composition, from right to left,
       of a series of functions.
    '''
    def go(f, g):
        def fg(x):
            return f(g(x))
        return fg
    return reduce(go, fs, identity)


# fmapNext <$> :: (a -> b) -> Iter [a] -> Iter [b]
def fmapNext(f):
    '''A function f mapped over a
       possibly non-finite iterator.
    '''
    def go(g):
        v = next(g, None)
        while None is not v:
            yield f(v)
            v = next(g, None)
    return go


# fTable :: String -> (a -> String) ->
# (b -> String) -> (a -> b) -> [a] -> String
def fTable(s):
    '''Heading -> x display function -> fx display function ->
       f -> xs -> tabular string.
    '''
    def go(xShow, fxShow, f, xs):
        ys = [xShow(x) for x in xs]
        w = max(map(len, ys))
        return s + '\n' + '\n'.join(map(
            lambda x, y: y.rjust(w, ' ') + ' -> ' + fxShow(f(x)),
            xs, ys
        ))
    return lambda xShow: lambda fxShow: lambda f: lambda xs: go(
        xShow, fxShow, f, xs
    )

# identity :: a -> a
def identity(x):
    '''The identity function.'''
    return x


# take :: Int -> [a] -> [a]
# take :: Int -> String -> String
def take(n):
    '''The prefix of xs of length n,
       or xs itself if n > length xs.
    '''
    return lambda xs: (
        xs[0:n]
        if isinstance(xs, (list, tuple))
        else list(islice(xs, n))
    )


# unfoldl(lambda x: Just(((x - 1), x)) if 0 != x else Nothing())(10)
# -> [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
# unfoldl :: (b -> Maybe (b, a)) -> b -> [a]
def unfoldl(f):
    '''Dual to reduce or foldl.
       Where these reduce a list to a summary value, unfoldl
       builds a list from a seed value.
       Where f returns Just(a, b), a is appended to the list,
       and the residual b is used as the argument for the next
       application of f.
       When f returns Nothing, the completed list is returned.
    '''
    def go(v):
        x, r = v, v
        xs = []
        while True:
            mb = f(x)
            if mb['Nothing']:
                return xs
            else:
                x, r = mb['Just']
                xs.insert(0, r)
        return xs
    return go


# MAIN ---
if __name__ == '__main__':
    main()
Output:
First 25 fairshare terms for a given number of players:

 2 -> [ 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0, 1, 0, 0, 1, 0, 1, 1, 0, 0 ]
 3 -> [ 0, 1, 2, 1, 2, 0, 2, 0, 1, 1, 2, 0, 2, 0, 1, 0, 1, 2, 2, 0, 1, 0, 1, 2, 1 ]
 5 -> [ 0, 1, 2, 3, 4, 1, 2, 3, 4, 0, 2, 3, 4, 0, 1, 3, 4, 0, 1, 2, 4, 0, 1, 2, 3 ]
11 -> [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10, 1, 2, 3, 4, 5, 6, 7, 8, 9,10, 0, 2, 3, 4 ]

Quackery

digitsum is defined at Sum digits of an integer.

  [ dup dip digitsum mod ] is fairshare ( n n --> n )  

  ' [ 2 3 5 11 ]
  witheach
    [ dup echo say ": "
      25 times
        [ i^ over fairshare echo sp ] 
      drop cr ]
Output:
2: 0 1 1 0 1 0 0 1 1 0 0 1 0 1 1 0 1 0 0 1 0 1 1 0 0 
3: 0 1 2 1 2 0 2 0 1 1 2 0 2 0 1 0 1 2 2 0 1 0 1 2 1 
5: 0 1 2 3 4 1 2 3 4 0 2 3 4 0 1 3 4 0 1 2 4 0 1 2 3 
11: 0 1 2 3 4 5 6 7 8 9 10 1 2 3 4 5 6 7 8 9 10 0 2 3 4 

Racket

#lang racket

(define (Thue-Morse base)
  (letrec ((q/r (curryr quotient/remainder base))
           (inner (λ (n (s 0))
                    (match n
                      [0 (modulo s base)]
                      [(app q/r q r) (inner q (+ s r))]))))
    inner))

(define (report-turns B n)
  (printf "Base:\t~a\t~a~%" B (map (Thue-Morse B) (range n))))

(define (report-stats B n)
  (define TM (Thue-Morse B))
  (define h0 (for/hash ((b B)) (values b 0)))
  (define d (for/fold ((h h0)) ((i n)) (hash-update h (TM i) add1 0)))
  (define d′ (for/fold ((h (hash))) (([k v] (in-hash d))) (hash-update h v add1 0)))
  (define d′′ (hash-map d′ (λ (k v) (format "~a people have ~a turn(s)" v k))))
  (printf "Over ~a turns for ~a people:~a~%" n B (string-join d′′ ", ")))

(define (Fairshare-between-two-and-more)
  (report-turns 2 25)
  (report-turns 3 25)
  (report-turns 5 25)
  (report-turns 11 25)
  (newline)
  (report-stats 191 50000)
  (report-stats 1377 50000)
  (report-stats 49999 50000)
  (report-stats 50000 50000)
  (report-stats 50001 50000))

(module+ main
  (Fairshare-between-two-and-more))
Output:
Base:	2	(0 1 1 0 1 0 0 1 1 0 0 1 0 1 1 0 1 0 0 1 0 1 1 0 0)
Base:	3	(0 1 2 1 2 0 2 0 1 1 2 0 2 0 1 0 1 2 2 0 1 0 1 2 1)
Base:	5	(0 1 2 3 4 1 2 3 4 0 2 3 4 0 1 3 4 0 1 2 4 0 1 2 3)
Base:	11	(0 1 2 3 4 5 6 7 8 9 10 1 2 3 4 5 6 7 8 9 10 0 2 3 4)

Over 50000 turns for 191 people:42 people have 261 turn(s), 149 people have 262 turn(s)
Over 50000 turns for 1377 people:428 people have 37 turn(s), 949 people have 36 turn(s)
Over 50000 turns for 49999 people:49998 people have 1 turn(s), 1 people have 2 turn(s)
Over 50000 turns for 50000 people:50000 people have 1 turn(s)
Over 50000 turns for 50001 people:50000 people have 1 turn(s), 1 people have 0 turn(s)

Raku

(formerly Perl 6)

Works with: Rakudo version 2020.01

Add an extension showing the relative fairness correlation of this selection algorithm. An absolutely fair algorithm would have a correlation of 1 for each person (no person has an advantage or disadvantage due to an algorithmic artefact.) This algorithm is fair, and gets better the more iterations are done.

A lower correlation factor corresponds to an advantage, higher to a disadvantage, the closer to 1 it is, the fairer the algorithm. Absolute best possible advantage correlation is 0. Absolute worst is 2.

sub fairshare (\b) { ^∞ .hyper.map: { .polymod( b xx * ).sum % b } }

.say for <2 3 5 11>.map: { .fmt('%2d:') ~ .&fairshare[^25]».fmt('%2d').join: ', ' }

say "\nRelative fairness of this method. Scaled fairness correlation. The closer to 1.0 each person
is, the more fair the selection algorithm is. Gets better with more iterations.";

for <2 3 5 11 39> -> $people {
    print "\n$people people: \n";
    for $people * 1, $people * 10, $people * 1000 -> $iterations {
        my @fairness;
        fairshare($people)[^$iterations].kv.map: { @fairness[$^v % $people] += $^k }
        my $scale = @fairness.sum / @fairness;
        my @range = @fairness.map( { $_ / $scale } );
        printf "After round %4d: Best advantage: %-10.8g - Worst disadvantage: %-10.8g - Spread between best and worst: %-10.8g\n",
            $iterations/$people, @range.min, @range.max, @range.max - @range.min;
    }
}
 2: 0,  1,  1,  0,  1,  0,  0,  1,  1,  0,  0,  1,  0,  1,  1,  0,  1,  0,  0,  1,  0,  1,  1,  0,  0
 3: 0,  1,  2,  1,  2,  0,  2,  0,  1,  1,  2,  0,  2,  0,  1,  0,  1,  2,  2,  0,  1,  0,  1,  2,  1
 5: 0,  1,  2,  3,  4,  1,  2,  3,  4,  0,  2,  3,  4,  0,  1,  3,  4,  0,  1,  2,  4,  0,  1,  2,  3
11: 0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10,  0,  2,  3,  4

Relative fairness of this method. Scaled fairness correlation. The closer to 1.0 each person
is, the more fair the selection algorithm is. Gets better with more iterations.

2 people: 
After round    1: Best advantage: 0          - Worst disadvantage: 2          - Spread between best and worst: 2         
After round   10: Best advantage: 1          - Worst disadvantage: 1          - Spread between best and worst: 0         
After round 1000: Best advantage: 1          - Worst disadvantage: 1          - Spread between best and worst: 0         

3 people: 
After round    1: Best advantage: 0          - Worst disadvantage: 2          - Spread between best and worst: 2         
After round   10: Best advantage: 0.99310345 - Worst disadvantage: 1.0068966  - Spread between best and worst: 0.013793103
After round 1000: Best advantage: 0.99999933 - Worst disadvantage: 1.0000007  - Spread between best and worst: 1.3337779e-06

5 people: 
After round    1: Best advantage: 0          - Worst disadvantage: 2          - Spread between best and worst: 2         
After round   10: Best advantage: 1          - Worst disadvantage: 1          - Spread between best and worst: 0         
After round 1000: Best advantage: 1          - Worst disadvantage: 1          - Spread between best and worst: 0         

11 people: 
After round    1: Best advantage: 0          - Worst disadvantage: 2          - Spread between best and worst: 2         
After round   10: Best advantage: 0.99082569 - Worst disadvantage: 1.0091743  - Spread between best and worst: 0.018348624
After round 1000: Best advantage: 0.99999909 - Worst disadvantage: 1.0000009  - Spread between best and worst: 1.8183471e-06

39 people: 
After round    1: Best advantage: 0          - Worst disadvantage: 2          - Spread between best and worst: 2         
After round   10: Best advantage: 0.92544987 - Worst disadvantage: 1.0745501  - Spread between best and worst: 0.14910026
After round 1000: Best advantage: 0.99999103 - Worst disadvantage: 1.000009   - Spread between best and worst: 1.7949178e-05

REXX

Programming note:   the   base   function (as coded herein) handles bases from base ten up to   36.

/*REXX program calculates  N  terms of the fairshare sequence for some group of peoples.*/
parse arg n g                                    /*obtain optional arguments from the CL*/
if n=='' | n==","  then n= 25                    /*Not specified?  Then use the default.*/
if g=''  | g=","   then g=  2 3 5 11             /* "      "         "   "   "     "    */
                                                 /* [↑]  a list of a number of peoples. */
     do p=1  for words(g);        r= word(g, p)  /*traipse through the bases specfiied. */
     $= 'base' right(r, 2)': '                   /*construct start of the 1─line output.*/
        do j=0  for n;   $= $ right( sumDigs( base(j, r))  //  r, 2)','
        end   /*j*/                              /* [↑] append # (base R) mod R──►$ list*/
     say strip($, , ",")                         /*elide trailing comma from the $ list.*/
     end      /*p*/
exit                                             /*stick a fork in it,  we're all done. */
/*──────────────────────────────────────────────────────────────────────────────────────*/
base: parse arg #,b,,y;          @= 0123456789abcdefghijklmnopqrstuvwxyz;  @@= substr(@,2)
        do while #>=b; y= substr(@, #//b + 1, 1)y; #= #%b; end;  return substr(@, #+1, 1)y
/*──────────────────────────────────────────────────────────────────────────────────────*/
sumDigs: parse arg x; !=0; do i=1 for length(x); != !+pos(substr(x,i,1),@@); end; return !
output   when using the default inputs:
base  2:   0,  1,  1,  0,  1,  0,  0,  1,  1,  0,  0,  1,  0,  1,  1,  0,  1,  0,  0,  1,  0,  1,  1,  0,  0
base  3:   0,  1,  2,  1,  2,  0,  2,  0,  1,  1,  2,  0,  2,  0,  1,  0,  1,  2,  2,  0,  1,  0,  1,  2,  1
base  5:   0,  1,  2,  3,  4,  1,  2,  3,  4,  0,  2,  3,  4,  0,  1,  3,  4,  0,  1,  2,  4,  0,  1,  2,  3
base 11:   0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10,  0,  2,  3,  4

Ring

str    = []
people = [2,3,5,11]

result = people
for i in people
    str = []
    see "" + i + ": "
    fair(25, i)
    for n in result
        add(str,n)
    next
    showarray(str)
next
 
func fair n,base

     result = list(n)
     for i=1 to n
         j = i-1
         t = 0
         while j>0
               t = t + j % base
               j = floor(j/base)
         end
         result[i] = t % base
     next
 
func showarray vect
     svect = ""
     for n in vect
         svect += " " + n + ","
     next
     svect = left(svect, len(svect) - 1)
     ? "[" + svect + "]"
Output:
2: [ 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0, 1, 0, 0, 1, 0, 1, 1, 0, 0]
3: [ 0, 1, 2, 1, 2, 0, 2, 0, 1, 1, 2, 0, 2, 0, 1, 0, 1, 2, 2, 0, 1, 0, 1, 2, 1]
5: [ 0, 1, 2, 3, 4, 1, 2, 3, 4, 0, 2, 3, 4, 0, 1, 3, 4, 0, 1, 2, 4, 0, 1, 2, 3]
11: [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 0, 2, 3, 4]

RPL

DIGITS is defined at Sum digits of an integer.

D→B is a slightly modified version of the program defined at Non-decimal radices/Convert, using uppercase characters to be compatible with DIGITS

≪ → b
  ≪ "" SWAP 
     WHILE DUP REPEAT
       b MOD LAST / IP 
       SWAP DUP 9 > 55 48 IFTE + CHR
       ROT + SWAP
     END DROP
≫ ≫ 'D→B' STO

≪ → b
  ≪ { 0 } 1 24 FOR j 
       j b D→B DIGITS b MOD + NEXT 
≫ ≫ 'TASK' STO
2 TASK 3 TASK 5 TASK 11 TASK 
Output:
4: { 0 1 1 0 1 0 0 1 1 0 0 1 0 1 1 0 1 0 0 1 0 1 1 0 0 }
3: { 0 1 2 1 2 0 2 0 1 1 2 0 2 0 1 0 1 2 2 0 1 0 1 2 1 }
2: { 0 1 2 3 4 1 2 3 4 0 2 3 4 0 1 3 4 0 1 2 4 0 1 2 3 }
1: { 0 1 2 3 4 5 6 7 8 9 10 1 2 3 4 5 6 7 8 9 10 0 2 3 4 }

Ruby

Translation of: C
def turn(base, n)
    sum = 0
    while n != 0 do
        rem = n % base
        n = n / base
        sum = sum + rem
    end
    return sum % base
end

def fairshare(base, count)
    print "Base %2d: " % [base]
    for i in 0 .. count - 1 do
        t = turn(base, i)
        print " %2d" % [t]
    end
    print "\n"
end

def turnCount(base, count)
    cnt = Array.new(base, 0)

    for i in 0 .. count - 1 do
        t = turn(base, i)
        cnt[t] = cnt[t] + 1
    end

    minTurn = base * count
    maxTurn = -1
    portion = 0
    for i in 0 .. base - 1 do
        if cnt[i] > 0 then
            portion = portion + 1
        end
        if cnt[i] < minTurn then
            minTurn = cnt[i]
        end
        if cnt[i] > maxTurn then
            maxTurn = cnt[i]
        end
    end

    print "  With %d people: " % [base]
    if 0 == minTurn then
        print "Only %d have a turn\n" % portion
    elsif minTurn == maxTurn then
        print "%d\n" % [minTurn]
    else
        print "%d or %d\n" % [minTurn, maxTurn]
    end
end

def main
    fairshare(2, 25)
    fairshare(3, 25)
    fairshare(5, 25)
    fairshare(11, 25)

    puts "How many times does each get a turn in 50000 iterations?"
    turnCount(191, 50000)
    turnCount(1377, 50000)
    turnCount(49999, 50000)
    turnCount(50000, 50000)
    turnCount(50001, 50000)
end

main()
Output:
Base  2:   0  1  1  0  1  0  0  1  1  0  0  1  0  1  1  0  1  0  0  1  0  1  1  0  0
Base  3:   0  1  2  1  2  0  2  0  1  1  2  0  2  0  1  0  1  2  2  0  1  0  1  2  1
Base  5:   0  1  2  3  4  1  2  3  4  0  2  3  4  0  1  3  4  0  1  2  4  0  1  2  3
Base 11:   0  1  2  3  4  5  6  7  8  9 10  1  2  3  4  5  6  7  8  9 10  0  2  3  4
How many times does each get a turn in 50000 iterations?
  With 191 people: 261 or 262
  With 1377 people: 36 or 37
  With 49999 people: 1 or 2
  With 50000 people: 1
  With 50001 people: Only 50000 have a turn
Translation of: Sidef
def fairshare(base, upto) = (0...upto).map{|n| n.digits(base).sum % base}

upto = 25
[2, 3, 5, 11].each{|b| puts"#{'%2d' % b}: " + " %2d"*upto % fairshare(b, upto)}
Output:
 2:   0  1  1  0  1  0  0  1  1  0  0  1  0  1  1  0  1  0  0  1  0  1  1  0  0
 3:   0  1  2  1  2  0  2  0  1  1  2  0  2  0  1  0  1  2  2  0  1  0  1  2  1
 5:   0  1  2  3  4  1  2  3  4  0  2  3  4  0  1  3  4  0  1  2  4  0  1  2  3
11:   0  1  2  3  4  5  6  7  8  9 10  1  2  3  4  5  6  7  8  9 10  0  2  3  4

Rust

Translation of: Python
struct Digits {
    rest: usize,
    base: usize,
}

impl Iterator for Digits {
    type Item = usize;
    
    fn next(&mut self) -> Option<usize> {
        if self.rest == 0 {
            return None;
        }
        let (digit, rest) = (self.rest % self.base, self.rest / self.base);
        self.rest = rest;
        Some(digit)
    }
}

fn digits(num: usize, base: usize) -> Digits {
    Digits { rest: num, base: base }
}

struct FairSharing {
    participants: usize,
    index: usize,
}

impl Iterator for FairSharing {
    type Item = usize;
    fn next(&mut self) -> Option<usize> {
        let digit_sum: usize = digits(self.index, self.participants).sum();
        let selected = digit_sum % self.participants;
        self.index += 1;
        Some(selected)
    }
}

fn fair_sharing(participants: usize) -> FairSharing {
    FairSharing { participants: participants, index: 0 }
}

fn main() {
    for i in vec![2, 3, 5, 7] {
        println!("{}: {:?}", i, fair_sharing(i).take(25).collect::<Vec<usize>>());
    }
}
Output:
2: [0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0, 1, 0, 0, 1, 0, 1, 1, 0, 0]
3: [0, 1, 2, 1, 2, 0, 2, 0, 1, 1, 2, 0, 2, 0, 1, 0, 1, 2, 2, 0, 1, 0, 1, 2, 1]
5: [0, 1, 2, 3, 4, 1, 2, 3, 4, 0, 2, 3, 4, 0, 1, 3, 4, 0, 1, 2, 4, 0, 1, 2, 3]
7: [0, 1, 2, 3, 4, 5, 6, 1, 2, 3, 4, 5, 6, 0, 2, 3, 4, 5, 6, 0, 1, 3, 4, 5, 6]

Sidef

for b in (2,3,5,11) {
    say ("#{'%2d' % b}: ", 25.of { .sumdigits(b) % b })
}
Output:
 2: [0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0, 1, 0, 0, 1, 0, 1, 1, 0, 0]
 3: [0, 1, 2, 1, 2, 0, 2, 0, 1, 1, 2, 0, 2, 0, 1, 0, 1, 2, 2, 0, 1, 0, 1, 2, 1]
 5: [0, 1, 2, 3, 4, 1, 2, 3, 4, 0, 2, 3, 4, 0, 1, 3, 4, 0, 1, 2, 4, 0, 1, 2, 3]
11: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 0, 2, 3, 4]

Visual Basic .NET

Translation of: C
Module Module1

    Function Turn(base As Integer, n As Integer) As Integer
        Dim sum = 0
        While n <> 0
            Dim re = n Mod base
            n \= base
            sum += re
        End While
        Return sum Mod base
    End Function

    Sub Fairshare(base As Integer, count As Integer)
        Console.Write("Base {0,2}:", base)
        For i = 1 To count
            Dim t = Turn(base, i - 1)
            Console.Write(" {0,2}", t)
        Next
        Console.WriteLine()
    End Sub

    Sub TurnCount(base As Integer, count As Integer)
        Dim cnt(base) As Integer
        For i = 1 To base
            cnt(i - 1) = 0
        Next

        For i = 1 To count
            Dim t = Turn(base, i - 1)
            cnt(t) += 1
        Next

        Dim minTurn = Integer.MaxValue
        Dim maxTurn = Integer.MinValue
        Dim portion = 0
        For i = 1 To base
            Dim num = cnt(i - 1)
            If num > 0 Then
                portion += 1
            End If
            If num < minTurn Then
                minTurn = num
            End If
            If num > maxTurn Then
                maxTurn = num
            End If
        Next

        Console.Write("  With {0} people: ", base)
        If 0 = minTurn Then
            Console.WriteLine("Only {0} have a turn", portion)
        ElseIf minTurn = maxTurn Then
            Console.WriteLine(minTurn)
        Else
            Console.WriteLine("{0} or {1}", minTurn, maxTurn)
        End If
    End Sub

    Sub Main()
        Fairshare(2, 25)
        Fairshare(3, 25)
        Fairshare(5, 25)
        Fairshare(11, 25)

        Console.WriteLine("How many times does each get a turn in 50000 iterations?")
        TurnCount(191, 50000)
        TurnCount(1377, 50000)
        TurnCount(49999, 50000)
        TurnCount(50000, 50000)
        TurnCount(50001, 50000)
    End Sub

End Module
Output:
Base  2:  0  1  1  0  1  0  0  1  1  0  0  1  0  1  1  0  1  0  0  1  0  1  1  0  0
Base  3:  0  1  2  1  2  0  2  0  1  1  2  0  2  0  1  0  1  2  2  0  1  0  1  2  1
Base  5:  0  1  2  3  4  1  2  3  4  0  2  3  4  0  1  3  4  0  1  2  4  0  1  2  3
Base 11:  0  1  2  3  4  5  6  7  8  9 10  1  2  3  4  5  6  7  8  9 10  0  2  3  4
How many times does each get a turn in 50000 iterations?
  With 191 people: 261 or 262
  With 1377 people: 36 or 37
  With 49999 people: 1 or 2
  With 50000 people: 1
  With 50001 people: Only 50000 have a turn

V (Vlang)

Translation of: Go
fn fairshare(n int, base int) []int {
    mut res := []int{len: n}
    for i in 0..n {
        mut j := i
        mut sum := 0
        for j > 0 {
            sum += j % base
            j /= base
        }
        res[i] = sum % base
    }
    return res
}
 
fn turns(n int, fss []int) string {
    mut m := map[int]int{}
    for fs in fss {
        m[fs]++
    }
    mut m2 := map[int]int{}
    for _,v in m {
        m2[v]++
    }
    mut res := []int{}
    mut sum := 0
    for k, v in m2 {
        sum += v
        res << k
    }
    if sum != n {
        return "only $sum have a turn"
    }
    res.sort()
    mut res2 := []string{len: res.len}
    for i,_ in res {
        res2[i] = '${res[i]}'
    }
    return res2.join(" or ")
}
 
fn main() {
    for base in [2, 3, 5, 11] {
        println("${base:2} : ${fairshare(25, base):2}")
    }
    println("\nHow many times does each get a turn in 50000 iterations?")
    for base in [191, 1377, 49999, 50000, 50001] {
        t := turns(base, fairshare(50000, base))
        println("  With $base people: $t")
    }
}
Output:
 2 : [0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0, 1, 0, 0, 1, 0, 1, 1, 0, 0]
 3 : [0, 1, 2, 1, 2, 0, 2, 0, 1, 1, 2, 0, 2, 0, 1, 0, 1, 2, 2, 0, 1, 0, 1, 2, 1]
 5 : [0, 1, 2, 3, 4, 1, 2, 3, 4, 0, 2, 3, 4, 0, 1, 3, 4, 0, 1, 2, 4, 0, 1, 2, 3]
11 : [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 0, 2, 3, 4]

How many times does each get a turn in 50000 iterations?
  With 191 people: 261 or 262
  With 1377 people: 36 or 37
  With 49999 people: 1 or 2
  With 50000 people: 1
  With 50001 people: only 50000 have a turn

Wren

Translation of: Go
Library: Wren-fmt
Library: Wren-sort
import "./fmt" for Fmt
import "./sort" for Sort

var fairshare = Fn.new { |n, base|
    var res = List.filled(n, 0)
    for (i in 0...n) {
        var j = i
        var sum = 0
        while (j > 0) {
            sum = sum + (j%base)
            j = (j/base).floor
        }
        res[i] = sum % base
    }
    return res
}

var turns = Fn.new { |n, fss|
    var m = {}
    for (fs in fss) {
        var k = m[fs]
        if (!k) {
            m[fs] = 1
        } else {
            m[fs] = k + 1
        }
    }
    var m2 = {}
    for (k in m.keys) {
        var v = m[k]
        var k2 = m2[v]
        if (!k2) {
            m2[v] = 1
        } else {
            m2[v] = k2 + 1
        }
    }
    var res = []
    var sum = 0
    for (k in m2.keys) {
        var v = m2[k]
        sum = sum + v
        res.add(k)
    }
    if (sum != n) return "only %(sum) have a turn"
    Sort.quick(res)
    var res2 = List.filled(res.count, "")
    for (i in 0...res.count) res2[i] = res[i].toString
    return res2.join(" or ")
}

for (base in [2, 3, 5, 11]) {
    Fmt.print("$2d : $2d", base, fairshare.call(25, base))
}
System.print("\nHow many times does each get a turn in 50,000 iterations?")
for (base in [191, 1377, 49999, 50000, 50001]) {
    var t = turns.call(base, fairshare.call(50000, base))
    Fmt.print("  With $5d people: $s", base, t)
}
Output:
 2 :  0  1  1  0  1  0  0  1  1  0  0  1  0  1  1  0  1  0  0  1  0  1  1  0  0
 3 :  0  1  2  1  2  0  2  0  1  1  2  0  2  0  1  0  1  2  2  0  1  0  1  2  1
 5 :  0  1  2  3  4  1  2  3  4  0  2  3  4  0  1  3  4  0  1  2  4  0  1  2  3
11 :  0  1  2  3  4  5  6  7  8  9 10  1  2  3  4  5  6  7  8  9 10  0  2  3  4

How many times does each get a turn in 50,000 iterations?
  With   191 people: 261 or 262
  With  1377 people: 36 or 37
  With 49999 people: 1 or 2
  With 50000 people: 1
  With 50001 people: only 50000 have a turn

XPL0

proc Fair(Base); \Show first 25 terms of fairshare sequence
int  Base, Count, Sum, N, Q;
[RlOut(0, float(Base));  Text(0, ": ");
for Count:= 0 to 25-1 do
    [Sum:= 0;  N:= Count;
    while N do
        [Q:= N/Base;
        Sum:= Sum + rem(0);
        N:= Q;
        ];
    RlOut(0, float(rem(Sum/Base)));
    ];
CrLf(0);
];

[Format(3,0);
Fair(2);  Fair(3);  Fair(5);  Fair(11);
]
Output:
  2:   0  1  1  0  1  0  0  1  1  0  0  1  0  1  1  0  1  0  0  1  0  1  1  0  0
  3:   0  1  2  1  2  0  2  0  1  1  2  0  2  0  1  0  1  2  2  0  1  0  1  2  1
  5:   0  1  2  3  4  1  2  3  4  0  2  3  4  0  1  3  4  0  1  2  4  0  1  2  3
 11:   0  1  2  3  4  5  6  7  8  9 10  1  2  3  4  5  6  7  8  9 10  0  2  3  4

zkl

fcn fairShare(n,b){    // b<=36
   n.pump(List,'wrap(n){ n.toString(b).split("").apply("toInt",b).sum(0)%b })
}
foreach b in (T(2,3,5,11)){
   println("%2d: %s".fmt(b,fairShare(25,b).pump(String,"%2d ".fmt)));
}
Output:
 2:  0  1  1  0  1  0  0  1  1  0  0  1  0  1  1  0  1  0  0  1  0  1  1  0  0 
 3:  0  1  2  1  2  0  2  0  1  1  2  0  2  0  1  0  1  2  2  0  1  0  1  2  1 
 5:  0  1  2  3  4  1  2  3  4  0  2  3  4  0  1  3  4  0  1  2  4  0  1  2  3 
11:  0  1  2  3  4  5  6  7  8  9 10  1  2  3  4  5  6  7  8  9 10  0  2  3  4 

For any base > 1

fcn fairShare(n,base){
   sum,r := 0,0; while(n){ n,r = n.divr(base); sum+=r }
   sum%base
}
foreach b in (T(2,3,5,11)){
   println("%2d: %s".fmt(b,[0..24].pump(String,fairShare.fp1(b),"%2d ".fmt)));
}