Game Theory in Balanced Ternary Numeral System | (Moving 3k steps at a time)

Just like base 2 Binary numeral system having 0s and 1s as digits, Ternary(Trinary) Numeral System is a base 3 number system having 0s, 1s and -1 as digits.
It’s better to use alphabet ‘Z’ in place of -1, since while denoting full ternary number -1 looks odd in between 1s and 0s.

Conversion of decimal into Balanced Ternary:
As in binary conversion, first represent the decimal number into the normal ternary system having 0, 1, 2 as reminders.
Now Iterating from the lowest digit safely skip any 0s and 1s, however turn 2 into Z and add 1 to the next digit. Turn 3 into 0 on the same terms( such digits are not present in the number initially but they can be encountered after increasing some 2s. )
Examples:

Decimal: 128
Ternary: 11202
Balanced Ternary: 1ZZZ1Z

Decimal: 1000
Ternary: 1102101
Balanced Ternary: 111Z101

C++

filter_none

edit
close

play_arrow

link
brightness_4
code

// C++ implementation of the approach
#include <bits/stdc++.h>
using namespace std;
  
// Numbers are in range of pow(3, 32)
int arr[32];
  
// Conversion of ternary into balanced ternary as
// start iterating from Least Significant Bit (i.e 0th), 
// if encountered 0 or 1, safely skip and pass carry 0 
// further 2, replace it to -1 and pass carry 1 further
// 3, replace it to 0 and pass carry 1 further
void balTernary(int ter)
{
    int carry = 0, base = 10;
    int i = 32;
    while (ter > 0) {
        int rem = ter % base;
        rem = rem + carry;
        if (rem == 0) {
            arr[i--] = 0;
            carry = 0;
        }
        else if (rem == 1) {
            arr[i--] = 1;
            carry = 0;
        }
        else if (rem == 2) {
            arr[i--] = -1;
            carry = 1;
        }
        else if (rem == 3) {
            arr[i--] = 0;
            carry = 1;
        }
        ter = ter / base;
    }
    if (carry == 1)
        arr[i] = 1;
}
  
// Similar to binary conversion
int ternary(int number)
{
    int ans = 0, rem = 1, base = 1;
    while (number > 0) {
        rem = number % 3;
        ans = ans + rem * base;
        number /= 3;
        base = base * 10;
    }
    return ans;
}
  
// Driver code
int main()
{
    int number = 3056;
  
    int ter = ternary(number);
    memset(arr, 0, sizeof(arr));
    balTernary(ter);
  
    int i = 0;
  
    // Moving on to first occupied bit
    while (arr[i] == 0) {
        i++;
    }
  
    // Printing
    for (int j = i; j <= 32; j++) {
  
        // Print 'Z' in place of -1
        if (arr[j] == -1)
            cout << 'Z';
        else
            cout << arr[j];
    }
  
    return 0;
}

chevron_right


Java

filter_none

edit
close

play_arrow

link
brightness_4
code

// Java implementation of the approach
import java.util.*;
  
class GFG
{
  
// Numbers are in range of pow(3, 32)
static int []arr = new int[33];
  
// Conversion of ternary into balanced ternary as
// start iterating from Least Significant Bit (i.e 0th), 
// if encountered 0 or 1, safely skip and pass carry 0 
// further 2, replace it to -1 and pass carry 1 further
// 3, replace it to 0 and pass carry 1 further
static void balTernary(int ter)
{
    int carry = 0, base = 10;
    int i = 32;
    while (ter > 0
    {
        int rem = ter % base;
        rem = rem + carry;
        if (rem == 0
        {
            arr[i--] = 0;
            carry = 0;
        }
        else if (rem == 1
        {
            arr[i--] = 1;
            carry = 0;
        }
        else if (rem == 2)
        {
            arr[i--] = -1;
            carry = 1;
        }
        else if (rem == 3
        {
            arr[i--] = 0;
            carry = 1;
        }
        ter = (int)(ter / base);
    }
    if (carry == 1)
        arr[i] = 1;
}
  
// Similar to binary conversion
static int ternary(int number)
{
    int ans = 0, rem = 1, base = 1;
    while (number > 0
    {
        rem = number % 3;
        ans = ans + rem * base;
        number = (int)(number/3);
        base = base * 10;
    }
    return ans;
}
  
// Driver code
public static void main(String args[])
{
    int number = 3056;
  
    int ter = ternary(number);
    Arrays.fill(arr,0);
    balTernary(ter);
  
    int i = 0;
  
    // Moving on to first occupied bit
    while (arr[i] == 0
    {
        i++;
    }
  
    // Printing
    for (int j = i; j <= 32; j++) 
    {
  
        // Print 'Z' in place of -1
        if (arr[j] == -1)
            System.out.print('Z');
        else
        System.out.print(arr[j]);
    }
}
}
  
// This code is contributed by SURENDRA_GANGWAR

chevron_right


Python3

filter_none

edit
close

play_arrow

link
brightness_4
code

# Python3 implementation of the approach 
  
# Numbers are in range of pow(3, 32) 
arr = [0] * 32
  
# Conversion of ternary into balanced ternary as 
# start iterating from Least Significant Bit (i.e 0th), 
# if encountered 0 or 1, safely skip and pass carry 0 
# further 2, replace it to -1 and pass carry 1 further 
# 3, replace it to 0 and pass carry 1 further 
def balTernary(ter): 
   
    carry, base, i = 0, 10, 31 
    while ter > 0:
        rem = (ter % base) + carry 
          
        if rem == 0:  
            arr[i] = 0 
            carry, i = 0, i-1 
           
        elif rem == 1:  
            arr[i] = 1 
            carry, i = 0, i-1 
           
        elif rem == 2:  
            arr[i] = -1 
            carry, i = 1, i-1 
           
        elif rem == 3:  
            arr[i] = 0 
            carry, i = 1, i-1 
           
        ter = ter // base 
       
    if carry == 1:
        arr[i] = 1 
   
# Similar to binary conversion 
def ternary(number): 
   
    ans, rem, base = 0, 1, 1 
    while number > 0:
        rem = number % 3 
        ans = ans + rem * base 
        number //= 3 
        base = base * 10 
       
    return ans 
   
# Driver code 
if __name__ == "__main__"
   
    number = 3056 
    ter = ternary(number) 
    balTernary(ter) 
  
    i = 0 
  
    # Moving on to first occupied bit 
    while arr[i] == 0:  
        i += 1
       
    # Printing 
    for j in range(i, 32):  
  
        # Print 'Z' in place of -1 
        if arr[j] == -1
            print('Z', end = "") 
        else:
            print(arr[j], end = "") 
       
# This code is contributed by Rituraj Jain

chevron_right


C#

// C# implementation of the approach
using System;

class GFG
{

// Numbers are in range of pow(3, 32)
static int []arr = new int[33];

// Conversion of ternary into balanced ternary as
// start iterating from Least Significant Bit (i.e 0th),
// if encountered 0 or 1, safely skip and pass carry 0
// further 2, replace it to -1 and pass carry 1 further
// 3, replace it to 0 and pass carry 1 further
static void balTernary(int ter)
{
int carry = 0, b = 10;
int i = 32;
while (ter > 0)
{
int rem = ter % b;
rem = rem + carry;
if (rem == 0)
{
arr[i–] = 0;
carry = 0;
}
else if (rem == 1)
{
arr[i–] = 1;
carry = 0;
}
else if (rem == 2)
{
arr[i–] = -1;
carry = 1;
}
else if (rem == 3)
{
arr[i–] = 0;
carry = 1;
}
ter = (int)(ter / b);
}
if (carry == 1)
arr[i] = 1;
}

// Similar to binary conversion
static int ternary(int number)
{
int ans = 0, rem = 1, b = 1;
while (number > 0)
{
rem = number % 3;
ans = ans + rem * b;
number = (int)(number / 3);
b = b * 10;
}
return ans;
}

// Driver code
public static void Main(String []args)
{
int number = 3056;

int ter = ternary(number);
balTernary(ter);

int i = 0;

// Moving on to first occupied bit
while (arr[i] == 0)
{
i++;
}

// Printing
for (int j = i; j <= 32; j++) { // Print 'Z' in place of -1 if (arr[j] == -1) Console.Write('Z'); else Console.Write(arr[j]); } } } // This code is contributed by Rajput-Ji [tabbyending]

Output:

111ZZ1ZZ

Recovering original decimal number from a balanced ternary number:-
Procedure:- Similarly as it’s done in binary to decimal conversion
Example:- 111ZZ1ZZ
3^7*(1) + 3^6*(1) + 3^5*(1) + 3^4*(-1) + 3^3*(-1) + 3^2*(1) + 3^1*(-1) + 3^0*(-1)
 = 2187 + 729 + 243 - 81 - 27 + 9 - 3 - 1 = 3056

Game Rules:
There are two robots allowed to move in steps on x-axis starting from 0.
They can make several steps starting from 0 but there are some limitations on their movement.
In k_t_h step robot will move exact 3^k units of distance.
In each step robot must choose one of the two directions left (x- coordinate decreases) or right (x-coordinate increases), in a particular step only one robot will move and another will wait.
It is not allowed to skip any step.

Statement:
Given two integers x1 and x2. Robot 1 and 2 are separately required to cover their respective distances x1 and x2. Is it possible??
If it is possible you won otherwise you lose.

Approach:
There is only one balanced ternary representation of each Decimal number (distance here), this means there is only one way to cover a particular distance satisfying above rules.
So, if it is possible to cover distances x1 and x2 such that when one robot moves other remains still and both can’t remain still at the same time then it’s a victory.

Logic:
First represent x1 and x2 as balanced ternary number using above procedure.
Iterate from LSB check:-
At a time(step) only one value should be 1 or Z.
Both can’t be 0 at the same time(step).

If rule breaks at any step it’s your lose otherwise you won.

Example:

Input: x1 = 6890, x2 = 18252
Output:
Balanced ternary representation of x1 = 01001101ZZ
Balanced ternary representation of x2 = 10Z1001000
Victory

Input: x1 = 18, x2 = 45
Output:
Balanced ternary representation of x1 = 01Z00
Balanced ternary representation of x2 = 1ZZ00
Defeat

Iterate bitwise over both the arrays and break wherever rule breaks.
To do first make length of both arrays equal by adding 0s at beginning of the shortest one, such that length becomes same.

Below is the implementation of the above approach:

C++

filter_none

edit
close

play_arrow

link
brightness_4
code

// C++ implementation of the approach
#include <bits/stdc++.h>
using namespace std;
  
// Function that returns true
// if the game cannot be won
bool isDefeat(string s1, string s2, int n)
{
    for (int i = 0; i < n; i++) {
        if ((s1[i] == '0' && s2[i] == '1')
            || (s1[i] == '1' && s2[i] == '0'))
            continue;
        else if ((s1[i] == '0' && s2[i] == 'Z')
                 || (s1[i] == 'Z' && s2[i] == '0'))
            continue;
        else {
            return true;
        }
    }
    return false;
}
  
// Driver code
int main()
{
    string s1 = { "01001101ZZ" };
    string s2 = { "10Z1001000" };
  
    // Common length
    int n = 10;
  
    if (isDefeat(s1, s2, n))
        cout << "Defeat";
    else
        cout << "Victory";
  
    return 0;
}

chevron_right


Java

filter_none

edit
close

play_arrow

link
brightness_4
code

// Java implementation of the approach
class GfG
{
      
// Function that returns true
// if the game cannot be won
static boolean isDefeat(String s1, String s2, int n)
{
    for (int i = 0; i < n; i++)
    {
        if ((s1.charAt(i) == '0' && s2.charAt(i) == '1')
            || (s1.charAt(i) == '1' && s2.charAt(i) == '0'))
            continue;
        else if ((s1.charAt(i) == '0' && s2.charAt(i) == 'Z')
                || (s1.charAt(i) == 'Z' && s2.charAt(i) == '0'))
            continue;
        else 
        {
            return true;
        }
    }
    return false;
}
  
// Driver code
public static void main(String[] args)
{
    String s1 = ("01001101ZZ" );
    String s2 = ("10Z1001000" );
  
    // Common length
    int n = 10;
  
    if (isDefeat(s1, s2, n))
        System.out.println("Defeat");
    else
        System.out.println("Victory");
  
}
}
  
// This code is contributed by Code_Mech

chevron_right


Python3

filter_none

edit
close

play_arrow

link
brightness_4
code

# Python3 implementation of the approach
  
# Function that returns true
# if the game cannot be won
def isDefeat(s1, s2, n):
  
    for i in range(n):
        if ((s1[i] == '0' and s2[i] == '1') or 
            (s1[i] == '1' and s2[i] == '0')):
            continue
        elif ((s1[i] == '0' and s2[i] == 'Z') or 
              (s1[i] == 'Z' and s2[i] == '0')):
            continue
        else:
            return True
          
    return False
  
# Driver code
s1 = "01001101ZZ"
s2 = "10Z1001000"
  
# Common length
n = 10
  
if (isDefeat(s1, s2, n)):
    print("Defeat")
else:
    print("Victory")
  
# This code is contributed by mohit kumar

chevron_right


C#

filter_none

edit
close

play_arrow

link
brightness_4
code

// C# implementation of the approach
using System;
  
class GfG
{
      
// Function that returns true
// if the game cannot be won
static bool isDefeat(string s1, string s2, int n)
{
    for (int i = 0; i < n; i++)
    {
        if ((s1[i] == '0' && s2[i] == '1')
            || (s1[i] == '1' && s2[i] == '0'))
            continue;
        else if ((s1[i] == '0' && s2[i] == 'Z')
                || (s1[i] == 'Z' && s2[i]== '0'))
            continue;
        else
        {
            return true;
        }
    }
    return false;
}
  
// Driver code
public static void Main()
{
    string s1 = ("01001101ZZ" );
    string s2 = ("10Z1001000" );
  
    // Common length
    int n = 10;
  
    if (isDefeat(s1, s2, n))
        Console.WriteLine("Defeat");
    else
        Console.WriteLine("Victory");
  
}
}
  
// This code is contributed by Code_Mech

chevron_right


PHP

filter_none

edit
close

play_arrow

link
brightness_4
code

<?php
// PHP implementation of the approach
// Function that returns true
// if the game cannot be won
function isDefeat($s1, $s2, $n)
{
    for ($i = 0; $i < $n; $i++)
    {
        if( ($s1[$i] == '0' && $s2[$i] == '1')
            || ($s1[$i] == '1' && $s2[$i] == '0'))
            continue;
        else if (($s1[$i] == '0' && $s2[$i] == 'Z')
                || ($s1[$i] == 'Z' && $s2[$i] == '0'))
            continue;
        else
        {
            return true;
        }
    }
    return false;
}
  
// Driver code
    $s1 = ("01001101ZZ" );
    $s2 = ("10Z1001000" );
  
    // Common length
    $n = 10;
  
    if (isDefeat($s1, $s2, $n))
        echo("Defeat");
    else
        echo("Victory");
  
// This code is contributed by Code_Mech

chevron_right


Output:

Victory


My Personal Notes arrow_drop_up

Check out this Author's contributed articles.

If you like GeeksforGeeks and would like to contribute, you can also write an article using contribute.geeksforgeeks.org or mail your article to contribute@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks.

Please Improve this article if you find anything incorrect by clicking on the "Improve Article" button below.