I need to create a turing machine that accepts the language a^1 b^j c^k where i >= j >= k, but I am not even really sure how to start. Turing machines in this context are a hard concept for me to grasp for some reason.
Turing machines can read and write to the tape and move back and forth over it. If you had a line of three colors of marbles how would you see if they arranged like the strings in your language? You could verify they're in order and then separately count each color and make sure the relationships hold. "greater than or equal to" is a binary relation so you'd probably check both pairs separately. This is really easy to envision using three extra tapes:
If we don't want to use extra tapes, how can we proceed? Well, we can go ahead and make sure the symbols are in the right order first... makes the rest neater. Then, we can "cross off" pairs of a and b until all b are exhausted (if we exhaust all a first, then halt_reject); then, un-cross the b and cross off pairs of b and c until you run out of c (if you run out of b first, halt_reject). Something like...
q t q' t' d
q0 # q1 # right //
q1 a q1 a right //
q1 b q2 b right //
q1 # q4 # left //
q2 b q2 b right // verify subset of
q2 c q3 c right // a*b*c*
q2 # q4 # left //
q3 c q3 c right //
q3 # q4 # left //
q4 a q4 a left //
q4 b q4 b left // reset input
q4 c q4 c left // tape to start
q4 # q5 # right //
q5 a q5 a right //
q5 A q5 A right // change susbtring a^j b^j
q5 b q6 B left // into substring A^j b^j
q5 B q5 B right // if run out of a, crash
q5 c q7 C left // if run out of b and no c, accept
q5 # h_a # left // if run out of b and c, continue
q6 a q5 A right //
q6 A q6 A left //
q6 B q6 B left //
q7 B q8 D right //
q7 C q7 C left // change substring B^k c^k
q7 D q7 D left // to substring D^k c^k
q8 D q8 D right // if run out of B, crash
q8 C q8 C right // if run out of c, accept
q8 c q7 C left //
q8 # h_a # left //
Example 1: aaabbc
(q0, [#]aaabbc#) -> (q1, #[a]aabbc#) -> (q1, #a[a]abbc#) //
-> (q1, #aa[a]bbc#) -> (q1, #aaa[b]bc#) -> (q2, #aaab[b]c#) // a*b*c*
-> (q2, #aaabb[c]#) -> (q3, #aaabbc[#]) -> (q4, #aaabb[c]#) //
-> (q4, #aaab[b]c#) -> (q4, #aaa[b]bc#) -> (q4, #aa[a]bbc#) //
-> (q4, #a[a]abbc#) -> (q4, #[a]aabbc#) -> (q4, [#]aaabbc#) // reset
-> (q5, #[a]aabbc#) //
-> (q5, #a[a]abbc#) -> (q5, #aa[a]bbc#) -> (q5, #aaa[b]bc#) //
-> (q6, #aa[a]Bbc#) -> (q5, #aaA[B]bc#) -> (q5, #aaAB[b]c#) // a^j b^j
-> (q6, #aaA[B]Bc#) -> (q6, #aa[A]BBc#) -> (q6, #a[a]ABBc#) // A^j B^j
-> (q5, #aA[A]BBc#) -> (q5, #aAA[B]Bc#) -> (q5, #aAAB[B]c#) //
-> (q5, #aAABB[c]#) -> (q7, #aAAB[B]C#) //
-> (q8, #aAABD[C]#) -> (q8, #aAABDC[#]) -> (ha, #aAABD[C]#) // B^k c^k
// D^k C^k