# 三色旗

## 解法

1. 如果圖中W所在的位置為白色，則W+1，表示未處理的部份移至至白色群組。
2. 如果W部份為藍色，則B與W的元素對調，而B與W必須各+1，表示兩個群組都多了一個元素。
3. 如果W所在的位置是紅色，則將W與R交換，但R要減1，表示未處理的部份減1。

## 演算法

``Procedure MOVE(Flags[])     w = 0    b = 0    r = LENGTH(Flags) - 1    WHILE(Flags[w] == 'B' && w < LENGTH(Flags))         b = b + 1        w = w + 1        WHILE(Flags[r] == 'R' && r > 0)        r = r - 1    WHILE(w <= r)        IF(Flags[w] == 'W')            w = w + 1        ELSE IF(Flags[w] == 'B')            SWAP(Flags[], b, w)            b = b + 1            w = w + 1        ELSE            SWAP(Flags[], r, w)            r = r - 1``

``````def adjust(flags) {
b = 0
w = 0
r = flags.length() - 1
while flags.get(w) == 'B' and w < flags.length() {
w += 1
}
while flags.get(r) == 'R' and r > 0 {
r -= 1
}
while w <= r {
switch flags.get(w) {
case 'W'
w += 1
case 'B'
flags.swap(b, w)
w += 1
b += 1
default
flags.swap(r, w)
r -= 1
}
}
return flags
}

flags = 'RWBBWRWR'.split('')

``#include <stdio.h> #include <stdlib.h> #include <string.h> #define SWAP_FLAGS(x, y) { char temp; \                     temp = flags[x]; \                     flags[x] = flags[y]; \                     flags[y] = temp; }void printFlags(char* flags) {    int i;     for(i = 0; i < strlen(flags); i++) {        printf("%c ", flags[i]);     }    printf("\n");     }void adjust(char* flags) {    int w = 0;    int b = 0;    int r = strlen(flags) - 1;    while(flags[w] == 'B' && w < strlen(flags)) { b++; w++; }    while(flags[r] == 'R' && r > 0) { r--; }    while(w <= r) switch(flags[w]) {        case 'W':               w++;               break;        case 'B':               SWAP_FLAGS(b, w);               b++; w++;               break;        case 'R':               SWAP_FLAGS(r, w);               r--;    }}int main() {    char flags[] = {'R', 'W', 'B', 'W', 'W',                     'B', 'R', 'B', 'W', 'R', '\0'};     printFlags(flags);    adjust(flags);    printFlags(flags);    return 0; } ``

``import java.util.*;public class Flags {    private static void swap(char[] arr, int x, int y) {        char tmp = arr[x]; arr[x] = arr[y]; arr[y] = tmp;    }        public static String adjust(String flags) {        char[] fs = flags.toCharArray();                int b = 0, w = 0, r = fs.length - 1;        while(fs[w] == 'B' && w < fs.length) { b++; w++; }        while(fs[r] == 'R' && r > 0) { r--; }        while(w <= r) switch(fs[w]) {            case 'W':                 w++;                break;            case 'B':                 swap(fs, b, w);                b++; w++;                 break;            case 'R':                 swap(fs, r, w);                r--;        }                return new String(fs);    }        public static void main(String[] args) {        System.out.println(adjust(args[0]));    }}``

``def adjust(flags):    w = 0    r = len(flags) - 1    while flags[w] == "B" and w < len(flags):        w += 1    while flags[r] == "R" and r > 0:        r -= 1    while w <= r:        if flags[w] == "W":            w += 1        elif flags[w] == "B":            flags.insert(0, flags.pop(w))            w += 1        elif flags[w] == "R":            flags.append(flags.pop(w))            r -= 1    return flagsflags = list(input("輸入三色旗順序（ex. RWBBWRWR）："))flags = adjust(flags)print("移動順序後：", str(flags))``

``def adjust(flags: List[Char]) = {    def categorize(bw: List[Char], remain: List[Char],                    r: List[Char]): List[Char] = remain match {                           case Nil   => bw ++ r        case x::xs => x match {            case 'W' => categorize(bw ++ List(x), xs, r)            case 'B' => categorize(x::bw, xs, r)            case 'R' => categorize(bw, xs, x::r)        }            }    categorize(Nil, flags, Nil)}print("輸入三色旗順序（ex. RWBBWRWR）：")adjust(readLine.toList).foreach(print)``

``# encoding: big5def adjust(flags)    w = 0    r = flags.length - 1    while flags[w] == "B" && w < r        w += 1    end    while flags[r] == "R" && r > 0        r -= 1    end    while w <= r        case flags[w]        when "W"            w += 1        when "B"            flags.insert(0, flags.slice!(w))            w += 1        when "R"            flags << flags.slice!(w)            r -= 1        end    end        flagsendprint "輸入三色旗順序（ex. RWBBWRWR）："flags = gets.chomp!flags = adjust(flags)print "移動順序後：#{flags} \n"``

``function adjust(flags) {    var fs = flags.split("");    var w = 0;    var r = fs.length - 1;    while(fs[w] === 'B' && w < fs.length) { w++; }    while(fs[r] === 'R' && r > 0) { r--; }    while(w <= r) switch(fs[w]) {        case 'W':            w++;             break;        case 'B':            fs.unshift(fs.splice(w, 1));            w++;            break;        case 'R':            fs.push(fs.splice(w, 1));            r--;    }    return fs.join("");    }print(adjust("RWBWRWBW").toString());``

``adjust flags = categorize [] flags []               where categorize bw [] r = bw ++ r                     categorize bw (x:xs) r = case x of                              'W' -> categorize (bw ++ [x]) xs r                             'B' -> categorize (x:bw) xs r                             'R' -> categorize bw xs (x:r)               main = print \\$ adjust "WBRRWBWRBWW"``

``````categorize(BW, [], R, BWRFlags) :- append(BW, R, BWRFlags).

categorize(BW, [w|T], R, BWRFlags) :- append(BW, [w], BWFlags),
categorize(BWFlags, T, R, BWRFlags).

categorize(BW, [b|T], R, BWRFlags) :-
categorize([b | BW], T, R, BWRFlags).

categorize(BW, [r|T], R, BWRFlags) :- append(R, [r], RFlags),
categorize(BW, T, RFlags, BWRFlags).

adjust(Flags, BWRFlags) :- categorize([], Flags, [], BWRFlags).

main(_) :-
adjust([w, b, r, r, w, b, w, r, b, w, w], BWRFlags),
writef("%p\n", [BWRFlags]).``````