Skip to content

Instantly share code, notes, and snippets.

@jianminchen
Created April 3, 2016 20:46
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jianminchen/5e3002256642454eae747da2bde26ab3 to your computer and use it in GitHub Desktop.
Save jianminchen/5e3002256642454eae747da2bde26ab3 to your computer and use it in GitHub Desktop.
Reverse Shuffle merge - get score 16.67 - still need to continue
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ReverseMergeString
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine(reverseMerge(Console.ReadLine()));
}
/*
* Failed test case:
* bdabaceadaedaaaeaecdeadababdbeaeeacacaba
* output:
* aaaaaabaaceededecbdb
* aaaaaabaaceededecbdb
* aaaaaabaaceaeaaadead"
* Julia's output "cdeadababdbeaeeacacaba" string
* Failed test case:
* djjcddjggbiigjhfghehhbgdigjicafgjcehhfgifadihiajgciagicdahcbajjbhifjiaajigdgdfhdiijjgaiejgegbbiigida
*
* output:
* aaaaabccigicgjihidfiejfijgidgbhhehgfhjgiibggjddjjd
*/
public static string reverseMerge(string s)
{
if (!canBeReverseMerged(s))
return "";
int len = s.Length;
int half = len / 2;
int[] A = getCountArray(s);
int[] skipLog = getHalf(A);
String output = "";
for (int i = len -1; i >=0 && output.Length < half; i-- )
{
char c = s[i];
if (outputCheckSayNO(A, output, c))
continue;
if (haveToAdd(skipLog, c) ||
( firstOneNonzero(skipLog, c) ||
!greedyCheckForwardSkip(skipLog, c)
))
output += c;
else
{
if (!canDecrement(skipLog, c))
return ""; // something is wrong
}
}
return output;
}
private static bool outputCheckSayNO(int[] A, string s, char c)
{
int count = getNo(s, c);
if (count >= A[c - 'a']/2)
return true;
else
return false;
}
private static int getNo(string s, char c)
{
int count = 0;
foreach (char si in s)
if (si == c)
count++;
return count;
}
private static bool needContinue(int[] skipLog)
{
for(int i=0;i<26;i++)
{
if (skipLog[i] > 0)
return true;
}
return false;
}
/*
*
*/
private static bool haveToAdd(int[] skipLog, char c)
{
return (skipLog[c - 'a'] == 0); // design flaw -
}
private static bool canDecrement(int[] A, char c)
{
int index = c - 'a';
A[index]--;
return (A[index] >= 0);
}
/*
* Skip rules - only two :
* 1. First, if there is one to skip before the input char
* 2. Second, if the char is the first one in the list, alway go to true
*/
private static bool greedyCheckForwardSkip(int[] A, char c)
{
int end = c - 'a';
for (int i = 0; i < end; i++)
{
if (A[i] > 0)
return true;
}
return false;
}
/*
* Skip rules - only two:
* 1. First, if there is one to skip before the input char
* 2. Second, if the char is the first one in the list, alway go to true
*/
[Obsolete]
private static bool greedyCheckBackwardSkip(int[] A, char c)
{
int start = c - 'a';
for (int i = 25; i > start; i--) // bug: index problem - why I am still need debugger here!!! 'c'-'a', should be c-'a'
{
if (A[i] > 0 && i != start) // bug: A[i], should be i
return true;
}
return false;
}
// c is first char nonzero
private static bool firstOneNonzero(int[] A, char c)
{
int end = c - 'a';
for (int i = 0; i < end; i++)
{
if (A[i] > 0 )
return false;
}
return true;
}
private static int[] getHalf(int[] A)
{
int[] ret = new int[26];
for(int i=0; i<26; i++)
{
ret[i] = A[i] / 2;
}
return ret;
}
private static bool isHalf(int[] B, int[] A)
{
for(int i=0;i<26;i++)
{
if (B[i] * 2 == A[i])
continue;
else
return false;
}
return true;
}
// assume both string have same length
// because it is reverse string
private static string smallOne(string tmpS1, string tmpS2)
{
string s1 = reverse(tmpS1);
string s2 = reverse(tmpS2);
int len = s1.Length;
for(int i=0;i<len;i++)
{
if (s1[i] < s2[i])
return tmpS1;
else if (s1[i] > s2[i])
return tmpS2;
}
// both are the same, any one
return tmpS1;
}
private static string reverse(string s)
{
StringBuilder newS = new StringBuilder();
for (int i = s.Length - 1; i >= 0; i--)
newS.Append(s[i].ToString());
return newS.ToString();
}
private static bool canBeReverseMerged(string s)
{
if (s == null || s.Length == 0) return true;
int[] A = new int[26];
for(int i=0; i < s.Length;i++)
{
A[s[i]-'a']++;
}
for(int i=0;i<26;i++)
{
if (A[i] % 2 == 1)
return false;
}
return true;
}
private static int[] getCountArray(string s)
{
int[] A = new int[26];
if (s == null || s.Length == 0) return A;
for (int i = 0; i < s.Length; i++)
{
A[s[i] - 'a']++;
}
return A;
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment