Haskell Largest String
import Data.Array (Array, bounds, elems, listArray, (!), (//))
largestString :: String -> String
largestString s0 = elems (go (len - 1) arr0 "")
where
len = length s0
arr0 = listArray (0, len - 1) s0 :: Array Int Char
safeAt arr idx
| idx >= 0 && idx <= snd (bounds arr) = Just (arr ! idx)
| otherwise = Nothing
go i arr cur
| i < 0 = arr
| otherwise =
let cur1 = (arr ! i) : cur
in if length cur1 == 3
then
let (arr1, i1) = handleTriplet i arr cur1
i2 = adjustEnd i1 arr1
in go (i2 - 1) arr1 ""
else go (i - 1) arr cur1
handleTriplet i arr cur
| cur == "abb" =
let arr' = arr // [(i, 'b'), (i + 1, 'a'), (i + 2, 'a')]
in (arr', skipIndex i arr')
| otherwise = (arr, i)
skipIndex i arr
| safeAt arr (i + 4) == Just 'b' = i + 4 + 1
| safeAt arr (i + 3) == Just 'b' = i + 3 + 1
| arr ! (i + 2) == 'b' = i + 2 + 1
| otherwise = i
adjustEnd i arr
| safeAt arr (i + 1) == Just 'b' = i + 1 + 1
| otherwise = i + 1
This builds the biggest valid string it can under the challenge rules by always choosing the best next character it is allowed to use.
Java Largest String
public class Solution {
public static String largestString(String s) {
char[] chars = s.toCharArray();
int len = chars.length;
StringBuilder cur = new StringBuilder();
for (int i = len - 1; i >= 0; i--) {
cur.insert(0, chars[i]);
if (cur.length() == 3) {
if (cur.toString().equals("abb")) {
chars[i] = 'b';
chars[i + 1] = 'a';
chars[i + 2] = 'a';
if (i + 4 < len && chars[i + 4] == 'b') {
i += 4 + 1;
} else if (i + 3 < len && chars[i + 3] == 'b') {
i += 3 + 1;
} else if (chars[i + 2] == 'b') {
i += 2 + 1;
}
}
if (chars[i + 1] == 'b') {
i += 1 + 1;
} else {
++i;
}
cur.setLength(0);
}
}
return new String(chars);
}
}
This builds the biggest valid string it can under the challenge rules by always choosing the best next character it is allowed to use.
Lisp Largest String
(defun largest-string (s)
(let* ((str (copy-seq s))
(len (length str))
(cur "")
(i (1- len)))
(loop while (>= i 0)
do (progn
(setf cur (concatenate 'string (string (char str i)) cur))
(when (= (length cur) 3)
(when (string= cur "abb")
(setf (char str i) #\b)
(setf (char str (+ i 1)) #\a)
(setf (char str (+ i 2)) #\a)
(cond
((and (< (+ i 4) len) (char= (char str (+ i 4)) #\b))
(incf i (+ 4 1)))
((and (< (+ i 3) len) (char= (char str (+ i 3)) #\b))
(incf i (+ 3 1)))
((char= (char str (+ i 2)) #\b)
(incf i (+ 2 1)))))
(if (char= (char str (+ i 1)) #\b)
(incf i (+ 1 1))
(incf i))
(setf cur ""))
(decf i)))
str))
This builds the biggest valid string it can under the challenge rules by always choosing the best next character it is allowed to use.
PHP Largest String
function largestString(string $s): string
{
$len = strlen($s);
$cur = '';
for ($i = $len - 1; $i >= 0; $i--) {
$cur = $s[$i] . $cur;
if (strlen($cur) === 3) {
if ($cur === 'abb') {
$s[$i] = 'b';
$s[$i + 1] = 'a';
$s[$i + 2] = 'a';
if (isset($s[$i + 4]) && $s[$i + 4] === 'b') {
$i += 4 + 1;
} elseif (isset($s[$i + 3]) && $s[$i + 3] === 'b') {
$i += 3 + 1;
} elseif ($s[$i + 2] === 'b') {
$i += 2 + 1;
}
}
if ($s[$i + 1] === 'b') {
$i += 1 + 1;
} else {
++$i;
}
$cur = '';
}
}
return $s;
}
This builds the biggest valid string it can under the challenge rules by always choosing the best next character it is allowed to use.
Python Largest String
def largest_string(s: str) -> str:
chars = list(s)
length = len(chars)
# instead of raising; this helper preserves that read behavior so the
# lookahead checks below can't index past the end of the list.
def char_at(idx: int) -> str:
return chars[idx] if 0 <= idx < length else ""
cur = ""
i = length - 1
while i >= 0:
cur = char_at(i) + cur
if len(cur) == 3:
if cur == "abb":
chars[i] = "b"
chars[i + 1] = "a"
chars[i + 2] = "a"
if char_at(i + 4) == "b":
i += 4 + 1
elif char_at(i + 3) == "b":
i += 3 + 1
elif chars[i + 2] == "b":
i += 2 + 1
if char_at(i + 1) == "b":
i += 1 + 1
else:
i += 1
cur = ""
i -= 1
return "".join(chars)
This builds the biggest valid string it can under the challenge rules by always choosing the best next character it is allowed to use.
Rust Largest String
fn largest_string(s: &str) -> String {
let mut bytes: Vec<u8> = s.bytes().collect();
let len = bytes.len() as i64;
let mut cur: Vec<u8> = Vec::new();
let mut i = len - 1;
while i >= 0 {
cur.insert(0, bytes[i as usize]);
if cur.len() == 3 {
if cur == b"abb" {
bytes[i as usize] = b'b';
bytes[i as usize + 1] = b'a';
bytes[i as usize + 2] = b'a';
if bytes.get(i as usize + 4) == Some(&b'b') {
i += 4 + 1;
} else if bytes.get(i as usize + 3) == Some(&b'b') {
i += 3 + 1;
} else if bytes.get(i as usize + 2) == Some(&b'b') {
i += 2 + 1;
}
}
if bytes.get(i as usize + 1) == Some(&b'b') {
i += 1 + 1;
} else {
i += 1;
}
cur.clear();
}
i -= 1;
}
String::from_utf8(bytes).unwrap()
}
This builds the biggest valid string it can under the challenge rules by always choosing the best next character it is allowed to use.
TypeScript Largest String
function largestString(s: string): string {
const chars = s.split("");
let cur = "";
let i = chars.length - 1;
while (i >= 0) {
cur = chars[i] + cur;
if (cur.length === 3) {
if (cur === "abb") {
chars[i] = "b";
chars[i + 1] = "a";
chars[i + 2] = "a";
if (chars[i + 4] !== undefined && chars[i + 4] === "b") {
i += 4 + 1;
} else if (chars[i + 3] !== undefined && chars[i + 3] === "b") {
i += 3 + 1;
} else if (chars[i + 2] === "b") {
i += 2 + 1;
}
}
if (chars[i + 1] === "b") {
i += 1 + 1;
} else {
i += 1;
}
cur = "";
}
i--;
}
return chars.join("");
}
This builds the biggest valid string it can under the challenge rules by always choosing the best next character it is allowed to use.
Bash Max Counters
max_counters() {
local _n=$1
local -n _a="$2"
local -n _out="$3"
local -a _counters
local _i
for ((_i = 0; _i < _n; _i++)); do _counters[_i]=0; done
local _maxCounter=0 _lastUpdate=0
local _condition=$(( _n + 1 ))
local _v
for _v in "${_a[@]}"; do
if (( _v <= _n )); then
local _index=$(( _v - 1 ))
if (( _counters[_index] < _lastUpdate )); then
_counters[_index]=$_lastUpdate
fi
(( _counters[_index]++ ))
(( _counters[_index] > _maxCounter )) && _maxCounter=${_counters[_index]}
fi
if (( _v == _condition )); then
_lastUpdate=$_maxCounter
fi
done
for _i in "${!_counters[@]}"; do
if (( _counters[_i] < _lastUpdate )); then
_counters[_i]=$_lastUpdate
fi
done
_out=("${_counters[@]}")
}
This delays the expensive “set all counters to max” work until it is really needed, which keeps the solution fast.
C++ Max Counters
#include <algorithm>
#include <vector>
std::vector<int> maxCounters(int n, const std::vector<int>& a)
{
std::vector<int> counters(n, 0);
int maxCounter = 0;
int lastUpdate = 0;
int condition = n + 1;
for (int v : a) {
if (v <= n) {
int index = v - 1;
if (counters[index] < lastUpdate) {
counters[index] = lastUpdate;
}
++counters[index];
maxCounter = std::max(maxCounter, counters[index]);
}
if (v == condition) {
lastUpdate = maxCounter;
}
}
for (int& c : counters) {
if (c < lastUpdate) {
c = lastUpdate;
}
}
return counters;
}
This delays the expensive “set all counters to max” work until it is really needed, which keeps the solution fast.
C# Max Counters
static int[] MaxCounters(int n, int[] a)
{
var counters = new int[n];
var maxCounter = 0;
var lastUpdate = 0;
var condition = n + 1;
foreach (var v in a)
{
if (v <= n)
{
var index = v - 1;
if (counters[index] < lastUpdate)
{
counters[index] = lastUpdate;
}
counters[index]++;
maxCounter = Math.Max(counters[index], maxCounter);
}
if (v == condition)
{
lastUpdate = maxCounter;
}
}
// apply all max operations to avoid O(M*N) complexity
for (int k = 0; k < counters.Length; k++)
{
if (counters[k] < lastUpdate)
{
counters[k] = lastUpdate;
}
}
return counters;
}
This delays the expensive “set all counters to max” work until it is really needed, which keeps the solution fast.