text:
Totally Cubular
Create a program or function to unjumble a 9x9x9 cube of digits by rotating individual 3x3 cubes within it.
This is similar to (but, I suspect, a bit harder than) my Flippin' Squares question.
Input
Input will be a 9x9x9 cube. I'm not going to be as strict over the input as I was last time, 3d arrays are allowed, arrays of strings are allowed, arrays of arrays of characters are allowed, etc.
I will be strict on what you can input into your program though - only the digits that make up the cube. No additional information like dimensions or anything else can be given as input.
Here is an example cube:
123456789   234567891   345678912
234567891   345678912   456789123
345678912   456789123   567891234
456789123   567891234   678912345
567891234   678912345   789123456
678912345   789123456   891234567
789123456   891234567   912345678
891234567   912345678   123456789
912345678   123456789   234567891

456789123   567891234   678912345
567891234   678912345   789123456
678912345   789123456   891234567
789123456   891234567   912345678
891234567   912345678   123456789
912345678   123456789   234567891
123456789   234567891   345678912
234567891   345678912   456789123
345678912   456789123   567891234

789123456   891234567   912345678
891234567   912345678   123456789
912345678   123456789   234567891
123456789   234567891   345678912
234567891   345678912   456789123
345678912   456789123   567891234
456789123   567891234   678912345
567891234   678912345   789123456
678912345   789123456   891234567

The 9x9 square in the top left is the cross-section of the bottom layer of the cube. The square in the top-middle is the next layer up, then the top-right, the middle-left and so on through to the bottom-right, which is the top layer.
This cube is the target state. As you can see the digits increase in the positive x, y and z directions, looping back to 1 when they pass 9.
Sub-cubes
You solve this puzzle by manipulating 3x3 sub-cubes within the main cube.
Each sub-cube is identified by the X Y Z position of its centre within the main cube. Because each sub-cube must be a 3x3 cube, X, Y and Z can only be between 1 and 7 (inclusive). Point 0 0 0 is at the back-bottom-left and the values increase to the right, upwards and toward the front.
Example sub-cubes from the target state (all other values set to 0 to highlight the cube in question):
1 1 1:

123000000   234000000   345000000
234000000   345000000   456000000
345000000   456000000   567000000
000000000   000000000   000000000
000000000   000000000   000000000
000000000   000000000   000000000
000000000   000000000   000000000
000000000   000000000   000000000
000000000   000000000   000000000

000000000   000000000   000000000
000000000   000000000   000000000
000000000   000000000   000000000
000000000   000000000   000000000
000000000   000000000   000000000
000000000   000000000   000000000
000000000   000000000   000000000
000000000   000000000   000000000
000000000   000000000   000000000

000000000   000000000   000000000
000000000   000000000   000000000
000000000   000000000   000000000
000000000   000000000   000000000
000000000   000000000   000000000
000000000   000000000   000000000
000000000   000000000   000000000
000000000   000000000   000000000
000000000   000000000   000000000

7 1 1:

000000789   000000891   000000912
000000891   000000912   000000123
000000912   000000123   000000234
000000000   000000000   000000000
000000000   000000000   000000000
000000000   000000000   000000000
000000000   000000000   000000000
000000000   000000000   000000000
000000000   000000000   000000000

000000000   000000000   000000000
000000000   000000000   000000000
000000000   000000000   000000000
000000000   000000000   000000000
000000000   000000000   000000000
000000000   000000000   000000000
000000000   000000000   000000000
000000000   000000000   000000000
000000000   000000000   000000000

000000000   000000000   000000000
000000000   000000000   000000000
000000000   000000000   000000000
000000000   000000000   000000000
000000000   000000000   000000000
000000000   000000000   000000000
000000000   000000000   000000000
000000000   000000000   000000000
000000000   000000000   000000000

1 7 1:

000000000   000000000   000000000
000000000   000000000   000000000
000000000   000000000   000000000
000000000   000000000   000000000
000000000   000000000   000000000
000000000   000000000   000000000
000000000   000000000   000000000
000000000   000000000   000000000
000000000   000000000   000000000

000000000   000000000   000000000
000000000   000000000   000000000
000000000   000000000   000000000
000000000   000000000   000000000
000000000   000000000   000000000
000000000   000000000   000000000
000000000   000000000   000000000
000000000   000000000   000000000
000000000   000000000   000000000

789000000   891000000   912000000
891000000   912000000   123000000
912000000   123000000   234000000
000000000   000000000   000000000
000000000   000000000   000000000
000000000   000000000   000000000
000000000   000000000   000000000
000000000   000000000   000000000
000000000   000000000   000000000

1 1 7:

000000000   000000000   000000000
000000000   000000000   000000000
000000000   000000000   000000000
000000000   000000000   000000000
000000000   000000000   000000000
000000000   000000000   000000000
789000000   891000000   912000000
891000000   912000000   123000000
912000000   123000000   234000000

000000000   000000000   000000000
000000000   000000000   000000000
000000000   000000000   000000000
000000000   000000000   000000000
000000000   000000000   000000000
000000000   000000000   000000000
000000000   000000000   000000000
000000000   000000000   000000000
000000000   000000000   000000000

000000000   000000000   000000000
000000000   000000000   000000000
000000000   000000000   000000000
000000000   000000000   000000000
000000000   000000000   000000000
000000000   000000000   000000000
000000000   000000000   000000000
000000000   000000000   000000000
000000000   000000000   000000000

Manipulation
Each move you make will be a rotation of one of the sub-cubes. You will be able to rotate a cube around any one of its axes; 1, 2 or 3 quarter turns.
Rotation will be specified by first naming the axis you wish to rotate around, then the number of quarter turns you wish to rotate.
Example rotations (using unique values for each item here to make the rotations more obvious):
ABC   JKL   STU
DEF   MNO   VWX
GHI   PQR   YZ*

X1

STU   VWX   YZ*
JKL   MNO   PQR
ABC   DEF   GHI

X rotations rotate towards the back (or anti-clockwise as viewed from the left-hand side).
ABC   JKL   STU
DEF   MNO   VWX
GHI   PQR   YZ*

Y1

CFI   LOR   UX*
BEH   KNQ   TWZ
ADG   JMP   SVY

Y rotations rotate anti-clockwise as viewed from above.
ABC   JKL   STU
DEF   MNO   VWX
GHI   PQR   YZ*

Z1

SJA   TKB   ULC
VMD   WNE   XOF
YPG   ZQH   *RI

Z rotations rotate anti-clockwise as viewed from the front.
Output
Your output should be a list of moves required to take the given input back to the target state.
Each move should name the sub-cube and how it should be rotated:
111X1

Block at X=1, Y=1, Z=1, rotated 1 quarter turn around the X axis.

426Y3

Block at X=4, Y=2, Z=6, rotated 3 quarter turns around the Y axis.

789Z2

Block at X=7, Y=8, Z=9, rotated 2 quarter turn around the Z axis.

So an example output might be something like:
111X1
789Z2
426Y3

This is my preferred output - a list of newline separated moves where each line describes one move - and this is the kind of output my verification program will expect. That said, I'll be somewhat flexible on the output, so a long string of moves (for example) is okay (it'll just take me a little longer to verify).
I think this is probably enough of a challenge as it is, but let's make it code-golf just to spice it up a bit more.
Utilities
This is a program that will generate a random scrambling of the cube. It outputs the scrambled cube, the sequence of moves that generated it and those moves reversed as a possible solution.
Alternatively, it has a function that will take a scrambled function and a sequence of moves as input and then verify that it returns the target cube.
The program, along with a couple of files containing a test input solution for verification, the target cube and a cube I used to test the rotate functions, can be found at: https://github.com/gazrogers/CodegolfCubularRandomiser
import random

target = [[['1', '2', '3', '4', '5', '6', '7', '8', '9'], ['2', '3', '4', '5', '6', '7', '8', '9', '1'], ['3', '4', '5', '6', '7', '8', '9', '1', '2'], ['4', '5', '6', '7', '8', '9', '1', '2', '3'], ['5', '6', '7', '8', '9', '1', '2', '3', '4'], ['6', '7', '8', '9', '1', '2', '3', '4', '5'], ['7', '8', '9', '1', '2', '3', '4', '5', '6'], ['8', '9', '1', '2', '3', '4', '5', '6', '7'], ['9', '1', '2', '3', '4', '5', '6', '7', '8']], [['2', '3', '4', '5', '6', '7', '8', '9', '1'], ['3', '4', '5', '6', '7', '8', '9', '1', '2'], ['4', '5', '6', '7', '8', '9', '1', '2', '3'], ['5', '6', '7', '8', '9', '1', '2', '3', '4'], ['6', '7', '8', '9', '1', '2', '3', '4', '5'], ['7', '8', '9', '1', '2', '3', '4', '5', '6'], ['8', '9', '1', '2', '3', '4', '5', '6', '7'], ['9', '1', '2', '3', '4', '5', '6', '7', '8'], ['1', '2', '3', '4', '5', '6', '7', '8', '9']], [['3', '4', '5', '6', '7', '8', '9', '1', '2'], ['4', '5', '6', '7', '8', '9', '1', '2', '3'], ['5', '6', '7', '8', '9', '1', '2', '3', '4'], ['6', '7', '8', '9', '1', '2', '3', '4', '5'], ['7', '8', '9', '1', '2', '3', '4', '5', '6'], ['8', '9', '1', '2', '3', '4', '5', '6', '7'], ['9', '1', '2', '3', '4', '5', '6', '7', '8'], ['1', '2', '3', '4', '5', '6', '7', '8', '9'], ['2', '3', '4', '5', '6', '7', '8', '9', '1']], [['4', '5', '6', '7', '8', '9', '1', '2', '3'], ['5', '6', '7', '8', '9', '1', '2', '3', '4'], ['6', '7', '8', '9', '1', '2', '3', '4', '5'], ['7', '8', '9', '1', '2', '3', '4', '5', '6'], ['8', '9', '1', '2', '3', '4', '5', '6', '7'], ['9', '1', '2', '3', '4', '5', '6', '7', '8'], ['1', '2', '3', '4', '5', '6', '7', '8', '9'], ['2', '3', '4', '5', '6', '7', '8', '9', '1'], ['3', '4', '5', '6', '7', '8', '9', '1', '2']], [['5', '6', '7', '8', '9', '1', '2', '3', '4'], ['6', '7', '8', '9', '1', '2', '3', '4', '5'], ['7', '8', '9', '1', '2', '3', '4', '5', '6'], ['8', '9', '1', '2', '3', '4', '5', '6', '7'], ['9', '1', '2', '3', '4', '5', '6', '7', '8'], ['1', '2', '3', '4', '5', '6', '7', '8', '9'], ['2', '3', '4', '5', '6', '7', '8', '9', '1'], ['3', '4', '5', '6', '7', '8', '9', '1', '2'], ['4', '5', '6', '7', '8', '9', '1', '2', '3']], [['6', '7', '8', '9', '1', '2', '3', '4', '5'], ['7', '8', '9', '1', '2', '3', '4', '5', '6'], ['8', '9', '1', '2', '3', '4', '5', '6', '7'], ['9', '1', '2', '3', '4', '5', '6', '7', '8'], ['1', '2', '3', '4', '5', '6', '7', '8', '9'], ['2', '3', '4', '5', '6', '7', '8', '9', '1'], ['3', '4', '5', '6', '7', '8', '9', '1', '2'], ['4', '5', '6', '7', '8', '9', '1', '2', '3'], ['5', '6', '7', '8', '9', '1', '2', '3', '4']], [['7', '8', '9', '1', '2', '3', '4', '5', '6'], ['8', '9', '1', '2', '3', '4', '5', '6', '7'], ['9', '1', '2', '3', '4', '5', '6', '7', '8'], ['1', '2', '3', '4', '5', '6', '7', '8', '9'], ['2', '3', '4', '5', '6', '7', '8', '9', '1'], ['3', '4', '5', '6', '7', '8', '9', '1', '2'], ['4', '5', '6', '7', '8', '9', '1', '2', '3'], ['5', '6', '7', '8', '9', '1', '2', '3', '4'], ['6', '7', '8', '9', '1', '2', '3', '4', '5']], [['8', '9', '1', '2', '3', '4', '5', '6', '7'], ['9', '1', '2', '3', '4', '5', '6', '7', '8'], ['1', '2', '3', '4', '5', '6', '7', '8', '9'], ['2', '3', '4', '5', '6', '7', '8', '9', '1'], ['3', '4', '5', '6', '7', '8', '9', '1', '2'], ['4', '5', '6', '7', '8', '9', '1', '2', '3'], ['5', '6', '7', '8', '9', '1', '2', '3', '4'], ['6', '7', '8', '9', '1', '2', '3', '4', '5'], ['7', '8', '9', '1', '2', '3', '4', '5', '6']], [['9', '1', '2', '3', '4', '5', '6', '7', '8'], ['1', '2', '3', '4', '5', '6', '7', '8', '9'], ['2', '3', '4', '5', '6', '7', '8', '9', '1'], ['3', '4', '5', '6', '7', '8', '9', '1', '2'], ['4', '5', '6', '7', '8', '9', '1', '2', '3'], ['5', '6', '7', '8', '9', '1', '2', '3', '4'], ['6', '7', '8', '9', '1', '2', '3', '4', '5'], ['7', '8', '9', '1', '2', '3', '4', '5', '6'], ['8', '9', '1', '2', '3', '4', '5', '6', '7']]]

# Because of how we read the data in,
# the first index into the 3D array is the y-index (bottom layer first, top layer last),
# then the z-index (back first, front last),
# then the x-index (left first, right last)
def getinput(filename):
    f = open(filename)
    string = f.read().split('\n\n')
    cube = '\n\n'.join(string[:-1])
    solution = string[-1]
    lists = [list(z) for y in [x.split('\n') for x in cube.split('\n\n')] for z in y]
    return [[lists[i:i + 9] for i in xrange(0, len(lists), 9)], solution]

def output(data):
    return '\n'.join([''.join(row) for layer in data for row in layer+[[]]])

def getsubcube(cube, x, y, z):
    x = clamp(x, 1, 7)
    y = clamp(y, 1, 7)
    z = clamp(z, 1, 7)
    return [[[char for char in row[x-1:x+2]] for row in layer[z-1:z+2]] for layer in cube[y-1:y+2]]

def replacesubcube(cube, subcube, x, y, z):
    newcube = cube
    for ypos in range(y-1, y+2):
        for zpos in range(z-1, z+2):
            for xpos in range(x-1, x+2):
                newcube[ypos][zpos][xpos] = subcube[ypos-y+1][zpos-z+1][xpos-x+1]
    return newcube

def clamp(n, minn, maxn):
    return max(min(n, maxn), minn)

def rotateX(cube, n):
    newcube = cube
    for _ in range(n):
        newcube = [
            [newcube[2][0], newcube[1][0], newcube[0][0]],
            [newcube[2][1], newcube[1][1], newcube[0][1]],
            [newcube[2][2], newcube[1][2], newcube[0][2]]
        ]
    return newcube

# algorithm shamelessly stolen from http://stackoverflow.com/a/496056/618347
def rotateY(cube, n):
    newcube = cube
    for _ in range(n):
        newcube = [zip(*x)[::-1] for x in newcube]
    return newcube

# Easier to define in terms of rotateX and rotateY
def rotateZ(cube, n):
    newcube = cube
    for _ in range(n):
        newcube = rotateY(rotateX(rotateY(newcube, 1), 3), 3)
    return newcube

def randomisecube(cube):
    newcube = cube
    generator = ""
    solution = ""
    funclist = [[rotateX, "X"], [rotateY, "Y"], [rotateZ, "Z"]]
    for _ in range(random.randint(10, 100)):
        x = random.randint(1, 7)
        y = random.randint(1, 7)
        z = random.randint(1, 7)
        rotateFunc = random.choice(funclist)
        numRots = random.randint(1,3)
        subcube = getsubcube(newcube, x, y, z)
        subcube = rotateFunc[0](subcube, numRots)
        newcube = replacesubcube(newcube, subcube, x, y, z)
        generator = generator + str(x) + str(y) + str(z) + rotateFunc[1] + str(numRots) + '\n'
        solution = str(x) + str(y) + str(z) + rotateFunc[1] + str(4-numRots) +'\n' + solution
    return [generator, solution, newcube]

def verifysoltuion(cube, solution):
    newcube = cube
    funclist = {"X": rotateX, "Y": rotateY, "Z": rotateZ}
    for move in solution.split('\n'):
        movelist = list(move)
        subcube = getsubcube(newcube, int(movelist[0]), int(movelist[1]), int(movelist[2]))
        subcube = funclist[movelist[3]](subcube, int(movelist[4]))
        newcube = replacesubcube(newcube, subcube, int(movelist[0]), int(movelist[1]), int(movelist[2]))
    return newcube == target

# Code to generaterandom cubes - Uncomment/Comment as necessary
# answer = randomisecube(target)
# print "Cube:"
# print output(answer[2])
# print "Generated by:"
# print answer[0]
# print "Possible solution:"
# print answer[1]

# Code to verify solution - Uncomment/Comment as necessary
[cube, solution] = getinput('testsolution.txt')
print verifysoltuion(cube, solution)

Tests
These tests were generated by the above randomiser, and so were scrambled by at most 100 moves. Your solution can be as long as it needs to be, but maybe the 100 move limit will help optimise your solution?
Please provide the solutions to these 3 test input in your answer.
Test input 1:
123456789
234567891
345678912
456789123
789891234
876912567
452123456
891234345
912345678

234567343
567878432
494519521
389891234
678212563
787823898
876934747
932145456
143256789

367178219
656269321
585491432
473539887
567643478
841298787
999145658
341256567
569367891

671784748
589855639
476966521
932129776
343778327
234145696
583991565
492312891
121498912

782395434
678214325
219761216
121656732
654283676
147858989
454789143
543678762
432565123

893989123
767391214
188896395
932595488
823214582
982397151
323654737
456562673
567456234

782193876
843218765
952931654
145859915
954823491
165758963
212517631
567651264
678912345

893214987
936727876
145326765
234941691
365634212
476732473
565696714
678789145
789123456

912345678
121478789
232345891
321834912
474787123
585498214
678919195
789123456
891234567

Test input 2:
185636789
678739121
519278992
141447183
589128734
633462125
784723456
891234567
912345678

298549121
267393832
455767823
567871244
867759645
269367236
178936767
912349478
123474589

369458912
654952363
543641434
432916575
732127236
821952912
939567891
367876789
414545691

476757893
562797914
678584189
782123678
697416367
714369554
821896365
258525219
323656712

517897654
698914565
282863873
563618741
236599478
188638387
934513698
145691383
256345123

645954345
762323456
158232167
732595252
743256541
452348691
349698262
414719873
593828934

787489436
878954347
989147298
193981213
288582371
585432832
678817943
789923554
698734145

891298567
914981178
115494319
652149626
145671787
476352173
569121634
678732645
787643556

912345678
123452789
214265178
395226739
494989628
167211984
454915125
523121236
891234567

Test input 3:
123451989
234569191
345328252
456234741
237343128
126936765
713843412
828754587
912345678

234262871
367173982
623782193
512398873
571216319
277388484
619218545
986145456
126436789

567671782
178986783
955897676
544226619
969891856
881294145
592347934
153289345
235341671

678567523
745167854
363476523
465341976
168816567
979317432
524498132
452368119
355244782

789823434
654758929
914871838
846936797
967127256
828876952
652985148
586792767
257965893

678934345
712597456
163996745
967168692
823779385
784193941
565874315
476963894
345158234

789165456
895276195
214325294
891861983
936319871
125176912
454789123
367128954
691219765

891254367
912387678
345476589
932157991
143498162
276987493
789456912
678725843
745854654

912343278
123476589
456565491
123914312
234165123
567328234
678934321
767123432
856212543

Cubular hells

Sorry if I missed it, but - what's the target final state; is it specified here? I'm assuming it's 9 squares of all 1s, then 2s, then 3s, etc, but I must've missed it.

@HyperNeutrino "This cube is the target state. As you can see the digits increase in the positive x, y and z directions, looping back to 1 when they pass 9." underneath the first example cube

Rust, 38250 14716 bytes
use std::{io::{stdin,Read},ops::{Add,Index,IndexMut,Sub},collections::HashSet,fmt::{self,Write}};use lazy_static::lazy_static;use regex::Regex;use tap::Tap;use hashbag::HashBag;trait Ta:l+Sized{fn V(&mut self,d(A,o,D):d){let mut ha=A;if A[o]>1{ha[o]-=1;}else{ha[o]+=1;}let Da=if o==c::X{c::Y}else{c::X};self.u(d(ha,o,D));self.u(d(A,Da,2));self.u(d(ha,o,-D));self.u(d(A,Da,2));self.u(d(A,o,-D));}fn Bb(&mut self,q:Vec<d>){for m in q{self.V(m);}}}impl<T:l>Ta for T{}trait l{fn get(&self,e:b)->B;fn K(&self,e:b)->B;fn u(&mut self,m:d);fn j(&self)->b;fn ia(&mut self,q:Vec<d>){for m in q{self.u(m);}}}impl<T:l+?Sized>l for&mut T{fn get(&self,e:b)->B{(**self).get(e)}fn K(&self,e:b)->B{(**self).K(e)}fn u(&mut self,m:d){(**self).u(m)}fn j(&self)->b{(**self).j()}}lazy_static!{static ref Ea:[[[B;9];9];9]={#[inline(never)]fn pa<F:Fn((u8,I))->T,I:Copy,T>(N:F)->impl Fn(I)->[T;9]{move|i|{[N((0,i)),N((1,i)),N((2,i)),N((3,i)),N((4,i)),N((5,i)),N((6,i)),N((7,i)),N((8,i)),]}}pa(pa(pa(|(x,(y,(z,_)))|B((x+y+z)%18))))(())};}impl l for[[[B;9];9];9]{fn get(&self,e:b)->B{self[e.0][e.1][e.2]}fn K(&self,e:b)->B{Ea[e.0][e.1][e.2]}fn u(&mut self,mut m:d){m.2=m.2.rem_euclid(4);if m.2==0{return;}let Fa=m.0-b(1,1,1);let Ua:Vec<_>=self.slice(Fa,b(3,3,3)).iter().map(|(p,v)|(p.M(m.1,m.2,3)+Fa,v)).collect();for(e,ja)in Ua{self[e.0][e.1][e.2]=ja;}}fn j(&self)->b{b(9,9,9)}}struct qa<'a,C:l>{g:&'a C,e:b,}impl<'a,C:l>Iterator for qa<'a,C>{type Item=(b,B);fn next(&mut self)->Option<Self::Item>{let j=self.g.j();if self.e.2==j.2{return None;}let Va=Some((self.e,self.g.get(self.e)));self.e.0+=1;if self.e.0>=j.0{self.e.0=0;self.e.1+=1;if self.e.1>=j.1{self.e.1=0;self.e.2+=1;}}Va}fn size_hint(&self)->(usize,Option<usize>){let j=self.g.j();let Ga=j.0*j.1*j.2-self.e.0-self.e.1*j.0-self.e.2*j.0*j.1;(Ga,Some(Ga))}}trait Wa:l+Sized{fn iter<'a>(&'a self)->qa<'a,Self>{qa{g:self,e:b(0,0,0),}}}impl<T:l>Wa for T{}struct ka<C:l>{g:C,o:c,}impl<C:l>ka<C>{fn sa(&self,e:b)->b{e.P(self.o,self.j()[self.o])}}impl<C:l>l for ka<C>{fn get(&self,e:b)->B{self.g.get(self.sa(e))}fn K(&self,e:b)->B{self.g.K(self.sa(e))}fn u(&mut self,mut m:d){m.0=self.sa(m.0);if m.1!=self.o{m.2=-m.2;}self.g.u(m);}fn j(&self)->b{self.g.j()}}trait Xa:l+Sized{fn P(self,o:c)->ka<Self>{ka{g:self,o}}}impl<T:l>Xa for T{}trait Ya:l{fn Cb(&mut self)->bool{self.iter().all(|(e,ja)|ja==self.K(e))}}impl<T:l>Ya for T{}fn main(){let mut Ha=String::new();stdin().read_to_string(&mut Ha).unwrap();let mut g=Ia(Zb(&Ha[..]).unwrap());g.ab();}struct Ia([[[B;9];9];9]);impl l for Ia{fn get(&self,e:b)->B{self.0.get(e)}fn K(&self,e:b)->B{self.0.K(e)}fn j(&self)->b{self.0.j()}fn u(&mut self,m:d){println!("{}",db(&m));self.0.u(m);}}#[derive(Clone)]struct d(b,c,i8);trait eb{fn ba(self)->Self;}impl eb for Vec<d>{fn ba(mut self)->Self{self.reverse();for m in self.iter_mut(){m.2=-m.2;}self}}fn db(d(b(x,y,z),o,D):&d)->String{format!("{}{}{}{}{}",x,y,z,match o{c::X=>"X",c::Y=>"Y",c::Z=>"Z",},D.rem_euclid(4).to_string())}fn Zb(str:&str)->Result<[[[B;9];9];9],String>{let str=str.to_lowercase();let str=str.trim();let charset=if str.contains('a'){"0a1b2c3d4e5f6g7h8i"}else if str.contains('0'){"012345678"}else{"123456789"};let mut z=0;let mut g:[[[B;9];9];9]=Default::default();lazy_static!{static ref fb:Regex=Regex::new(r"\s*\n\s*\n\s*").unwrap();}for ua in fb.split(str){let ua=ua.trim();let mut O=z;for(y,la)in ua.split("\n").enumerate(){let la=la.trim();O=z;let gb=if la.chars().nth(1)==Some(' '){""}else{""};for ra in la.split(gb).filter(|x|*x!=""){let ra=ra.trim();for(x,char)in ra.chars().filter(|x|*x!=' ').enumerate(){if x>=9||y>=9||O>=9{dbg!((x,y,O));return Err(format!("Invalid g j{:?}",(x,y,O)));}let mut ta=if let Some(index)=charset.find(char){index as u8}else{return Err(format!("Invalid character{:?}",char));};if ta%2!=((x+y+O)%2)as u8{if charset.len()==9{ta+=9}else{return Err(format!("Invalid parity at position{:?}",(x,y,O)));}};g[x][y][O].0=ta;}O+=1;}}z=O;}if<[_]>::iter(&g).flatten().flatten().collect::<HashBag<_>>()!=<[_]>::iter(&*Ea).flatten().flatten().collect(){return Err(format!("Invalid piece counts"));}Ok(g)}#[derive(Clone,Copy,PartialEq,Eq,Hash)]struct b(usize,usize,usize);impl b{fn H(mut self,h:c,k:c)->b{let f=self[h];self[h]=self[k];self[k]=f;self}fn P(mut self,o:c,E:usize)->b{self[o]=E-1-self[o];self}fn M(self,o:c,D:i8,E:usize)->b{let mut ca=self;for _ in 0..(D.rem_euclid(4)){ca=match o{c::X=>ca.H(c::Y,c::Z).P(c::Y,E),c::Y=>ca.H(c::Z,c::X).P(c::Z,E),c::Z=>ca.H(c::X,c::Y).P(c::X,E),};}ca}fn parity(self)->usize{(self.0+self.1+self.2)%2}fn va(self,min:b,E:b)->bool{true&&self.0>=min.0&&self.0<=E.0&&self.1>=min.1&&self.1<=E.1&&self.2>=min.2&&self.2<=E.2}}impl Add for b{type Output=b;fn add(self,Q:Self)->Self::Output{b(self.0+Q.0,self.1+Q.1,self.2+Q.2)}}impl Sub for b{type Output=b;fn sub(self,Q:Self)->Self::Output{b(self.0-Q.0,self.1-Q.1,self.2-Q.2)}}#[derive(Copy,Clone,PartialEq,Eq)]enum c{X=0,Y=1,Z=2,}impl Index<c>for b{type Output=usize;fn index(&self,index:c)->&Self::Output{match index{c::X=>&self.0,c::Y=>&self.1,c::Z=>&self.2,}}}impl IndexMut<c>for b{fn index_mut(&mut self,index:c)->&mut Self::Output{match index{c::X=>&mut self.0,c::Y=>&mut self.1,c::Z=>&mut self.2,}}}struct wa<C:l>{g:C,min:b,j:b,}impl<C:l>l for wa<C>{fn get(&self,e:b)->B{self.g.get(e+self.min)}fn K(&self,e:b)->B{self.g.K(e+self.min)}fn u(&mut self,mut m:d){m.0=m.0+self.min;self.g.u(m)}fn j(&self)->b{self.j}}trait hb:l+Sized{fn slice(self,min:b,j:b)->wa<Self>{wa{g:self,min,j,}}}impl<T:l>hb for T{}trait ib:l+Sized{fn ab(&mut self){let j=self.j();let mut min=b(0,0,0);let mut E=j;for&o in[c::Z,c::Y,c::X].iter(){for _ in 0..((j[o]-5+1/*round Eb*/)/2){self.jb(o,min,E);min[o]+=1;}for _ in 0..((j[o]-5)/2){self.kb(o,min,E);E[o]-=1;}}self.slice(min,b(5,5,5)).W(Ja).W(Ka).W(La).W(Ma);}}trait lb:l{fn jb(&mut self,o:c,min:b,E:b){self.slice(min,E-min).H(c::Z,o).W(xa);}fn kb(&mut self,o:c,min:b,E:b){self.slice(min,E-min).H(c::Z,o).P(c::X).P(c::Y).P(c::Z).W(xa);}}impl<T:l>ib for T{}impl<T:l>lb for T{}struct xa;impl aa for xa{fn L<C:l>(&self,g:&C,e:b)->t{let j=g.j();let b(x,y,z)=e;if z!=0{return t::da;};let index=y*j.0+x;if y+2>=j.1{if x+2>=j.0{t::G{index,w:b(j.0-4+j.1-y,j.1-1,5+x-j.0),q:vec![d(b(j.0-2,j.1-2,1),c::X,1),d(b(j.0-2,j.1-2,1),c::Y,-1),d(b(j.0+j.1-5-y,j.1-2,4+x-j.0),c::Y,1,),d(b(j.0-2,j.1-2,1),c::Y,1),d(b(j.0-2,j.1-2,1),c::X,-1),],}}else{t::G{index,w:b(x,j.1-1,5+y-j.1),q:vec![d(b(x+1,j.1-2,1),c::X,1),d(b(x+1,j.1-2,4+y-j.1),c::X,-1),d(b(x+1,j.1-2,1),c::X,-1),],}}}else{if x+2>=j.0{t::G{index,w:b(j.0-1,y,5+x-j.0),q:vec![d(b(j.0-2,y+1,1),c::Y,-1),d(b(j.0-2,y+1,4+x-j.0),c::Y,1),d(b(j.0-2,y+1,1),c::Y,1),],}}else{t::G{index,w:e+b(0,0,2),q:vec![d(e+b(1,1,1),c::Y,-1)],}}}}fn J<C:l>(&self,g:&mut C,h:b,k:b){mb(g.slice(b(0,0,1),g.j()-b(0,0,1)),h-b(0,0,1),k-b(0,0,1),);}}fn mb<C:l>(mut g:C,mut h:b,k:b){if h.parity()!=k.parity(){panic!("Cannot move between positions of different parities");}while h!=k{ya(&mut g,c::X,&mut h,k);ya(&mut g,c::Y,&mut h,k);ya(&mut g,c::Z,&mut h,k);}}fn ya<C:l>(g:C,o:c,h:&mut b,k:b){let nb=g.H(c::X,o);let mut Na=h.H(c::X,o);ob(nb,&mut Na,k.H(c::X,o));*h=Na.H(c::X,o)}fn ob<C:l>(mut g:C,h:&mut b,k:b){let ja=g.get(*h);let j=g.j();while h.0!=k.0{let mut A=b(0,0,0);let D;if h.0<k.0{A.0=h.0+1}else{A.0=h.0-1}if(h.0+1==k.0||k.0+1==h.0)&&h.0!=0&&h.0!=j.0-1{A.0=h.0}if h.1<=1{A.1=h.1+1;D=if h.0<k.0{1}else{3}}else{A.1=h.1-1;D=if h.0<k.0{3}else{1}}if h.2<=1{A.2=1}else{A.2=h.2-1}g.u(d(A,c::Z,D));*h=(*h-(A-b(1,1,1))).M(c::Z,D,3)+(A-b(1,1,1));}}struct Ma;impl aa for Ma{fn J<C:l>(&self,ma:&mut C,h:b,k:b){}fn L<C:l>(&self,ma:&C,e:b)->t{let ea=true&&e.0>=1&&e.0<=3&&e.1>=1&&e.1<=3&&e.2>=1&&e.2<=3&&e.parity()==1&&e.0!=2&&e.1!=2&&e.2!=2;if!ea{return t::na;}let fa=match e{b(1,1,1)=>return t::da,b(3,3,1)=>vec![],b(1,3,1)=>vec![d(b(2,3,2),c::Y,-1)],b(3,1,1)=>vec![d(b(3,2,2),c::X,1)],b(x,y,3)=>vec![d(b(2,2,3),c::Z,if x==1{if y==1{2}else{-1}}else{if y==1{1}else{0}},),d(b(2,3,2),c::Y,1),],_=>unreachable!(),};let mut q=fa.clone();q.extend_from_slice(&pb);q.extend(fa.ba());t::G{index:if e==b(3,2,1){1}else{0},w:b(1,1,1),q,}}fn u<C:l>(&self,g:&mut C,m:d){g.V(m);}}static pb:[d;17]=[d(b(2,3,2),c::Y,-1),d(b(3,2,2),c::X,-1),d(b(2,2,1),c::Z,-1),d(b(3,2,2),c::X,1),d(b(2,2,1),c::Z,-1),d(b(3,2,2),c::X,-1),d(b(2,2,1),c::Z,1),d(b(3,2,2),c::X,1),d(b(2,3,2),c::Y,1),d(b(3,2,2),c::X,-1),d(b(2,2,1),c::Z,1),d(b(3,2,2),c::X,1),d(b(2,2,1),c::Z,-1),d(b(3,2,2),c::X,1),d(b(2,3,2),c::Y,-1),d(b(3,2,2),c::X,-1),d(b(2,3,2),c::Y,1),];struct Ka;impl aa for Ka{fn J<C:l>(&self,g:&mut C,h:b,k:b){fn f(e:b)->i8{if e.0==1{if e.1==1{0}else{1}}else{if e.1==1{3}else{2}}}g.V(d(b(2,2,h.2),c::Z,f(h)-f(k)));if k.2!=h.2{g.V(d(b(2,k.1,2),c::Y,-((k.0+k.2-1)as i8)));}}fn L<C:l>(&self,ma:&C,e:b)->t{let ea=e.va(b(1,1,1),b(3,3,3))&&e.parity()==1;if!ea{return t::na;}match e{b(x,2,2)=>t::G{index:0,w:b(x,1,1),q:vec![d(b(x,2,1),c::X,1),d(b(x,1,2),c::X,-1),d(b(x,2,1),c::X,-1),d(b(x,1,2),c::X,1),],},b(2,y,2)=>t::G{index:0,w:b(1,y,1),q:vec![d(b(1,y,2),c::Y,1),d(b(2,y,1),c::Y,-1),d(b(1,y,2),c::Y,-1),d(b(2,y,1),c::Y,1),],},b(2,2,z)=>t::G{index:0,w:b(1,1,z),q:vec![d(b(2,1,z),c::Z,1),d(b(1,2,z),c::Z,-1),d(b(2,1,z),c::Z,-1),d(b(1,2,z),c::Z,1),],},_=>t::da,}}fn u<C:l>(&self,g:&mut C,m:d){g.V(m);}}struct La;impl aa for La{fn J<C:l>(&self,ma:&mut C,h:b,k:b){}fn L<C:l>(&self,ma:&C,e:b)->t{let ea=e.va(b(1,1,1),b(3,3,3))&&e.parity()==0&&e!=b(2,2,2);if!ea{return t::na;}let fa=match e{b(3,2,1)=>return t::da,b(1,2,1)=>vec![],b(x,y,3)=>vec![d(b(2,2,3),c::Z,if x==3{2}else if y==3{1}else if y==1{-1}else{0},),d(b(1,2,2),c::X,2),],b(x,y,2)=>vec![d(b(2,2,2),c::Z,if x==3{if y==3{1}else{2}}else{if y==3{0}else{-1}},),d(b(1,2,2),c::X,-1),],b(2,y,1)=>vec![d(b(2,2,2),c::X,2),d(b(2,2,3),c::Z,if y==3{-1}else{1}),d(b(1,2,2),c::X,2),],_=>unreachable!(),};let mut q=fa.clone();q.extend_from_slice(&qb);q.extend(fa.ba());t::G{index:if e==b(3,2,1){1}else{0},w:b(3,2,1),q,}}fn u<C:l>(&self,g:&mut C,m:d){g.V(m);}}static qb:[d;14]=[d(b(3,2,2),c::X,-1),d(b(2,2,1),c::Z,1),d(b(3,2,2),c::X,1),d(b(2,2,1),c::Z,-1),d(b(3,2,2),c::X,1),d(b(2,3,2),c::Y,-1),d(b(3,2,2),c::X,2),d(b(2,2,1),c::Z,-1),d(b(3,2,2),c::X,1),d(b(2,2,1),c::Z,-1),d(b(3,2,2),c::X,-1),d(b(2,2,1),c::Z,1),d(b(3,2,2),c::X,1),d(b(2,3,2),c::Y,1),];lazy_static!{static ref za:Vec<d>=vec![d(b(1,2,2),c::Z,1),d(b(2,3,2),c::Z,-1),d(b(1,2,2),c::Z,-1),d(b(2,3,2),c::Z,1),];static ref Oa:Vec<d>=za.clone().ba();}struct Ja;impl aa for Ja{fn J<C:l>(&self,g:&mut C,h:b,k:b){let A=b(2,2,2);if h.parity()!=k.parity(){panic!("Cannot move between positions of different parities");}if h==k{return;}if h.parity()==1{fn Aa(e:b)->bool{((e.0==2)as u8+(e.1==2)as u8+(e.2==2)as u8)==2}if Aa(h){if Aa(k){fn Pa(e:b)->(c,i8){let o=if e.0!=2{c::X}else if e.1!=2{c::Y}else{c::Z};(o,if e[o]==3{1}else{-1})}let(Qa,rb)=Pa(h);let(Ba,sb)=Pa(k);if Qa==Ba{g.u(d(A,if Ba==c::X{c::Y}else{c::X},2,))}else{let(tb,ub)=match(Qa,Ba){(c::X,c::Y)=>(c::Z,1),(c::Y,c::X)=>(c::Z,-1),(c::Z,c::X)=>(c::Y,1),(c::X,c::Z)=>(c::Y,-1),(c::Y,c::Z)=>(c::X,1),(c::Z,c::Y)=>(c::X,-1),_=>unreachable!(),};g.u(d(A,tb,rb*sb*ub));}}else{self.J(g,h,b(2,2,1));g.ia(Oa.clone());self.J(g,b(1,3,1),k);}}else{if Aa(k){self.J(g,h,b(1,3,1));g.ia(za.clone());self.J(g,b(2,2,1),k);}else{fn f(e:b)->i8{if e.0==1{if e.1==1{0}else{1}}else{if e.1==1{3}else{2}}}g.u(d(A,c::Z,f(h)-f(k)));if k.2!=h.2{g.u(d(A,c::Y,-((k.0+k.2-1)as i8)));}}}}else{if h==A{g.ia(Oa.clone());self.J(g,b(1,3,2),k);}else if k==A{self.J(g,h,b(1,3,2));g.ia(za.clone());}else if h.2!=k.2{let mut h=h;while h.2!=k.2{let o=if h.0==2{c::Y}else{c::X};let ga=if o==c::Y{-1}else{1};g.u(d(A,o,ga));h=h.M(o,ga,5);}self.J(g,h,k);}else{fn f(e:b)->i8{if e.0<=2&&e.1==1{3}else if e.0==3&&e.1<=2{2}else if e.0>=2&&e.1==3{1}else{0}}g.u(d(A,c::Z,f(h)-f(k)));}}}fn L<C:l>(&self,g:&C,e:b)->t{match e{b(2,2,2)=>t::G{index:100,w:b(2,2,2),q:vec![],},p if vb(p)=>t::da,_=>match e{p if p.0>=3||p.1>=3=>self.L(g,e.M(c::Z,1,5)).tap_mut(|x|x.M(c::Z,-1,5)),p if p.2>=1=>{let(o,ga)=if p.1==0{(c::X,1)}else{(c::Y,-1)};self.L(g,e.M(o,ga,5)).tap_mut(|x|x.M(o,-ga,5))}p if p.1>p.0=>self.L(g,e.H(c::X,c::Y)).tap_mut(|x|x.H(c::X,c::Y)),b(0,0,0)=>t::G{index:0,w:b(2,2,2),q:vec![d(b(1,1,1),c::Z,2),d(b(1,1,1),c::X,1),],},b(1,0,0)=>t::G{index:1,w:b(2,3,2),q:vec![d(b(1,1,1),c::Z,1),d(b(1,1,1),c::Y,-1),d(b(2,2,2),c::Z,2),d(b(1,1,1),c::Y,1),d(b(1,1,1),c::Z,-1),],},b(2,0,0)=>t::G{index:2,w:b(2,2,2),q:vec![d(b(2,3,2),c::Z,-1),d(b(1,1,1),c::Z,1),d(b(1,1,1),c::Y,-1),d(b(2,3,2),c::Z,1),d(b(1,1,1),c::Y,1),d(b(1,1,1),c::Z,-1),],},b(1,1,0)=>t::G{index:3,w:b(3,3,2),q:vec![d(b(1,1,1),c::Z,1),d(b(1,1,1),c::Y,2),d(b(2,2,2),c::Z,2),d(b(1,1,1),c::Y,2),d(b(1,1,1),c::Z,-1),],},b(2,1,0)=>t::G{index:4,w:b(1,2,2),q:vec![d(b(2,3,2),c::Z,-1),d(b(1,1,1),c::Z,-1),d(b(1,1,1),c::X,2),d(b(2,3,2),c::Z,1),d(b(1,1,1),c::X,2),d(b(1,1,1),c::Z,1),],},b(2,2,0)=>t::G{index:5,w:b(2,3,3),q:vec![d(b(1,1,1),c::Z,1),d(b(1,1,1),c::Y,2),d(b(3,3,2),c::X,1),d(b(1,1,1),c::Y,2),d(b(1,1,1),c::Z,-1),d(b(3,3,2),c::X,-1),],},_=>unreachable!(),},}}}fn vb(p:b)->bool{p.va(b(1,1,1),b(3,3,3))}trait aa{fn L<C:l>(&self,g:&C,e:b)->t;fn J<C:l>(&self,g:&mut C,h:b,k:b);fn u<C:l>(&self,g:&mut C,m:d){g.u(m);}fn wb<C:l>(&self,g:&mut C){let mut oa=<HashSet<b>>::new();let mut Ra:Vec<_>=g.iter().filter_map(|(e,_)|match self.L(g,e){t::G{index,w,q,}=>Some((e,index,w,q)),_=>None,}).collect();Ra.sort_by_key(|x|x.1);for(e,_,w,q)in Ra{oa.insert(e);let Sa=g.K(e);if g.get(e)==Sa{continue;}let h=g.iter().find(|&(p,v)|{v==Sa&&!matches!(self.L(g,p),t::na)&&!oa.contains(&p)}).unwrap().0;if let t::G{q:xb,w:yb,..}=self.L(g,h){for m in xb.ba(){self.u(g,m);}self.J(g,yb,w);}else{self.J(g,h,w);}for m in q{self.u(g,m);}}}}trait zb:l+Sized{fn W<S:aa>(&mut self,bb:S)->&mut Self{bb.wb(self);self}}impl<T:l>zb for T{}enum t{G{index:usize,w:b,q:Vec<d>,},da,na,}impl t{fn H(&mut self,h:c,k:c){match self{Self::G{w,q,..}=>{*w=w.H(h,k);for m in q.iter_mut(){m.2=-m.2;m.0=m.0.H(h,k);if m.1==h{m.1=k;}else if m.1==k{m.1=h;}else{m.1;}}}_=>{}}}fn M(&mut self,o:c,D:i8,E:usize){let D=D.rem_euclid(4);if D==0{return;}match self{Self::G{w,q,..}=>{*w=w.M(o,D,E);for m in q.iter_mut(){m.0=m.0.M(o,D,E);if match(o,D){(c::X,1)|(c::Y,3)=>m.1==c::Z,(c::Y,1)|(c::Z,3)=>m.1==c::X,(c::Z,1)|(c::X,3)=>m.1==c::Y,(_,_)=>m.1!=o,}{m.2=-m.2;}if D!=2{m.1=match(o,m.1){(c::Y,c::Z)|(c::Z,c::Y)=>c::X,(c::Z,c::X)|(c::X,c::Z)=>c::Y,(c::X,c::Y)|(c::Y,c::X)=>c::Z,_=>o,};}}}_=>{}}}}struct Ca<C:l>{g:C,h:c,k:c,}impl<C:l>l for Ca<C>{fn get(&self,e:b)->B{self.g.get(e.H(self.h,self.k))}fn K(&self,e:b)->B{self.g.K(e.H(self.h,self.k))}fn u(&mut self,mut m:d){if self.h!=self.k{m.0=m.0.H(self.h,self.k);m.2=-m.2;if m.1==self.h{m.1=self.k;}else if m.1==self.k{m.1=self.h;}}self.g.u(m)}fn j(&self)->b{self.g.j().H(self.h,self.k)}}trait Ab:l+Sized{fn H(self,h:c,k:c)->Ca<Self>{Ca{g:self,h,k,}}}impl<T:l>Ab for T{}#[derive(PartialEq,Eq,Copy,Clone,Hash,Default)]struct B(u8);

The solution is hosted on GitHub. Running cargo run in the root
directory will take the cube from stdin and output a list of moves that solves
the inputted cube. Input can be in any of the forms from the question and this
answer. The output will use a modified coordinate system by default, but can be
changed to use the question's coordinate system by changing line 27.
If you'd like to play with the cube and see how it's solved, I've created an
interactive visualization.
If you'd like to read about how it's solved, I've written a long detailed
explanation with interactive illustrations of the process.
Explanation
Coordinate System
This explanation will use a slightly different coordinate system than the challenge.
X is left-to-right, Y is top-to-bottom, and Z is front-to-back.
Here are 3 different visualizations of the axes:
   z
  / E F
 /  G H
* - - x
| A B
| C D
y

A B  E F
C D  G H

0 x  z ·
y ·  · ·

Positions as 'xyz':
000 100   001 101
010 110   011 111

Rotations are clockwise looking down the axis (right-hand rule).
Here is a visualization of the 3 unit rotations:
cube:       X1(cube):
0 x  z ·    z ·  · ·
y ·  · ·    0 x  y ·

cube:       Y1(cube):
0 x  z ·    x ·  0 z
y ·  · ·    · ·  y ·

cube:       Z1(cube):
0 x  z ·    y 0  · z
y ·  · ·    · x  · ·

0-indexing
The original challenge 1-indexes the pieces, which complicates
the modulo arithmetic. This explanation will use 0-indexing, where the pieces
are numbered 0-8.
1-indexing
1 2 3 4 5 6 7 8 9
2 3 4 5 6 7 8 9 1
...

0-indexing
0 1 2 3 4 5 6 7 8
1 2 3 4 5 6 7 8 0
...

Parity
Pieces are locked in to a checkerboard pattern; pieces from odd places
can only go to odd places, and likewise for even.
This means that there are actually 18 kinds of pieces.
0 in an even position -->  0 1 2 3 4 5 6 7 8
                           1 2 3 4 5 6 7 8 0 <-- 0 in an odd position
                           ...

This brings us to...
Alternate Notation
Because there are 18 kinds of pieces, it's helpful to have 18 distinct symbols.
From now on, this explanation will use an adapted, alpha-numeric notation, where
all even-parity pieces are numbers, and all odd-parity pieces are letters.
0-indexed
0 1 2 3 4 5 6 7 8
1 2 3 4 5 6 7 8 0
2 3 4 5 6 7 8 0 1
3 4 5 6 7 8 0 1 2
...

Alpha-numeric
0 a 1 b 2 c 3 d 4
a 1 b 2 c 3 d 4 e
1 b 2 c 3 d 4 e 5
b 2 c 3 d 4 e 5 f
...

Links
Throughout this explanation, links to cube states will be used to illustrate the
process. Here's a scrambled cube, and a solved cube.
Some links will illustrate a set of moves. First, it will show the goal state,
followed by the start state of the cube. Then, for each move, it will first
highlight the positions that will be affected, and then show the result of the
move. Here's an example of a small algorithm.
Additionally, some links with moves will emphasize certain pieces. The bordered
pieces are the focus, and the highlighted pieces are pieces that will/must
remain unchanged. Here's an example of the previous algorithm with
highlights. Sometimes, only a subset of the
unchanged pieces will be highlighted, to make it easier to track the rotations.
Approach to Solving
To solve the cube, we iterate through the positions in some order and solve each of
them without unsolving the previous positions.
Positions can be in two states: solved & unsolved. When solving a position,
pieces in solved positions may be moved but must be restored to ensure the solved
positions are ultimately unchanged.
A position is solved by the following process:

Locate a piece of the correct value in any unsolved position.
Move the piece to the correct position without ultimately changing any solved
position.

#1 is fairly self-explanatory, so the rest of this explanation focuses on #2.
At various times throughout solving the cube, we'll denote an unsolved section of the
cube as the "pool". We'll then divide #2 into 3 parts:

Move the piece into the pool.
Move the piece around in the pool.
Move the piece out of the pool into the correct position.

To accomplish this, we'll need to define two helpers:

We'll figure out how to move a piece from any position in the pool to any
other position of the same parity in the pool.
Then, for each unsolved position outside of the pool, we'll choose a convenient
"source" position in the pool and figure out a list of moves that will move a piece
from the source position to the position we're solving.

Using these two helpers, we can refine the above process:

Move the piece into the pool.

Execute the reverse of the moves supplied by helper #2.

Move the piece around in the pool.

Use helper #1.

Move the piece out of the pool into the correct position.

Execute the moves supplied by helper #2.

We will now formalize and define this logic.
Overview
At a high level, the solving method is broken into three stages.

Solving the outer shell (everything but the center 5×5×5)
Solving the inner shell (the center 5×5×5 excluding the center 3×3×3)
Solving the center 3×3×3

Each stage consists of a few steps.
Step Structure
In each step, the puzzle positions are paritioned into 3 classifications:

'active': unsolved positions that will be solved by the step
'done': previously solved positions
'pool': unsolved positions

A step is executed by iterating through the 'active' positions and solving each
position by executing the following prodecure:

Locate a piece of the correct value in any unsolved position.
Move the piece into the pool.
Move the piece within the pool to a 'source' position in the pool.
Move the piece from the 'source' position to the target position.

All of the above steps must be performed without ultimately changing any piece
in a previously solved 'active' position or any piece in a 'done' position.
Step Definition
Thus, a step is defined by:

A partition of the puzzle pieces
A way to move a piece from any 'pool' position to any other 'pool'
position of the same parity (without ultimately changing any piece in an
'active' or 'done' position)
For each 'active' position:

An index indicating when to solve this position
A convenient source 'pool' position
A list of moves that will move a piece from the specified 'pool' position
to this position (without ultimately changing any piece in an 'active'
position with a lower index or any piece in a 'done' position)

Stage 1: Solving the outer shell
In this stage, we'll solve everything but the center 5×5×5.
We'll accomplish this with 12 steps, each step solving a face of the unsolved
portion of the 9×9×9. We could go in any order; the implementation follows this
ordering (as it looked nice):

The Z=0 plane (after)
The Z=1 plane (after)
The Z=8 plane (after)
The Z=7 plane (after)
The Y=0 plane (after)
The Y=1 plane (after)
The Y=8 plane (after)
...
...
...
...
The X=7 plane (after)

Stage 1, Step 1: Solving the Z=0 face
All positions with Z=0 are 'active', and all other positions are 'pool'.
The most interesting part of this step involves the 'active' positions.  The
'active' positions fall into 3 categories based on their location:
A A A A A A A A B B
A A A A A A A A B B
A A A A A A A A B B
A A A A A A A A B B
A A A A A A A A B B
A A A A A A A A B B
A A A A A A A A B B
B B B B B B B B C C
B B B B B B B B C C

We'll solve each 'active' position from left-to-right, then top-to-bottom.
The examples that follow focus solely on the moves after the piece is moved
into the 'source' position.
A positions are the easiest to solve, as they only require one rotation;
here's an example for one A position.
B positions are a little more complicated. Because they're near the
edge, we can't use the same technique as in A. This means that we'll have to
move some of the pieces we've previously solved, but we also need to make sure
to restore them to the correct position afterwards. Here's an example
of how this is accomplished for one B position.
If you've played with puzzle cubes before, the technique used in that algorithm
may be familiar. Essentially, we're rotating the target position to a more
convenient place, moving the piece in, and then undoing the rotation of the
target position.
Last and certainly not least, we have C positions, which are surrounded on all
sides. Solving them is similar to B positions, but a little more complicated.
Here's an example for one C position.
Moving pieces within the pool is rather simple, as there's a lot of room, and the
pool is a rectangular prism; here is an example for one case. A full
explanation of the algorithm is omitted, as it is not very novel.
Stage 1, Steps 2-12
These steps follow the same pattern as Step 1, just on different faces within
the cube.
Stage 2: Solving the inner shell
At this point, everything is solved except for the inner 5×5×5.
After this stage, everything except the inner 3×3×3 will be solved.
This stage is not part of Stage 1 because some of the algorithms used in Stage 1
require more space than is available in the 5×5×5.
This stage consists of a single step.
All positions outside of in center 5×5×5 are 'done' and will not be changed
(even temporarily). Positions in the center 3×3×3 are 'pool', and the remainder
are 'active'.
Stage 2, Moving between 'pool' positions
Moving pieces between 'pool' positions is more complex in this step, because of
the limited space. To describe how pieces are moved, we'll first divide the pool
into 4 sections, pictured below.
P T P  T Q T  P T P
T Q T  Q U Q  T Q T
P T P  T Q T  P T P

P positions are the corners, Q positions are the face centers, T positions
are the edges, and the singular U position is the cube center.
P and Q positions all have odd parity, and T and U positions all have
even. Thus, pieces can be moved freely between P and Q positions, and T and
U positions, but not between P and T positions, P and U positions,
etc.
Thus, there are 8 possible cases:

P: From a P position to another P position
Q: From a Q position to another Q position
T: From a T position to another T position
U: From the U position to itself
PQ: From a P position to a Q position
QP: From a Q position to a P position
TU: From a T position to the U position
UT: From the U position to a T position

Case U is very trivial, since it is accomplished by doing nothing. Cases P, Q,
T are fairly trivial, and can be accomplished simply by rotating the center
3×3×3.
Cases PQ, QP, TU, UT are where things get interesting — remember that these
must be accomplished without ultimately changing any piece outside of the pool,
the center 3×3×3.
Cases QP & UT are the reverse of cases PQ & TU, respectively, so we will focus
on the later two cases.
Cases PQ & TU are both based off of the following algorithm that we'll call
INTO_CENTER, which moves a piece from position X into position U whilst
preserving everything outside of the center 3×3×3.
· · ·  · · ·  · · ·
· · ·  · U ·  · · ·
· · ·  X · ·  · · ·

Here is INTO_CENTER in action.
First, Case TU. We can accomplish it with the follwing procedure:

Move the piece from the original T position to position V using Case T.
Use INTO_CENTER to move the piece from position V to position U.

· · ·  · · ·  · T ·
· · ·  · U ·  · · ·
· · ·  V · ·  · · ·

Onto Case PQ. If you look at the moves in INTO_CENTER (linked above), you
might notice two things:

All of the moves rotate around the Z axis
All of the moves are at Z=4

These two properties mean that INTO_CENTER has the same effect on the Z=3
and Z=5 layers as it does on the Z=4 layer we focused on.
This means that we can accomplish Case PQ with the following procedure:

Move the piece from the original P position to position R, using Case P.
Use INTO_CENTER to move the piece from position R to position S.
Move the piece from position S to the destination Q position, using Case
Q.

· · ·  · · ·  · · P
· S ·  · · ·  · · ·
R · ·  · Q ·  · · ·

Stage 2, Moving pieces to 'active' positions
Now that we have a method to move pieces between 'pool' positions, we can move
on to describing the 'active' positions.
First, we'll break up the 'active' positions into a few categories, and then
we'll describe each category.
We'll label the categories A-F; the partition is pictured below.
A B C B A  B D E D B  C E F E C  B D E D B  A B C B A
B D E D B  D · · · D  E · · · E  D · · · D  B D E D B
C E F E C  E · · · E  F · · · F  E · · · E  C E F E C
B D E D B  D · · · D  E · · · E  D · · · D  B D E D B
A B C B A  B D E D B  C E F E C  B D E D B  A B C B A

The categories will be solved in alphabetical order; all A positions are
solved, then all B positions, etc.
For each category, we'll focus on the behavior of only one position; all of the
others follow by symmetry. Specifically, we'll focus on the following positions:
A B C · ·  · · · · ·  · · · · ·  · · · · ·  · · · · ·
· D E · ·  · · · · ·  · · · · ·  · · · · ·  · · · · ·
· · F · ·  · · · · ·  · · · · ·  · · · · ·  · · · · ·
· · · · ·  · · · · ·  · · · · ·  · · · · ·  · · · · ·
· · · · ·  · · · · ·  · · · · ·  · · · · ·  · · · · ·

When solving a position, care must be taken to not ultimately change any other
position that is outside of the 5×5×5 or in an earlier or current category.
The below diagrams are maps of the 5×5×5. # represents a position that must be
ultimately unchanged, + represents a 'pool' position, and X is the 'pool'
position that we'll later establish as our source 'pool' position.
First up are A positions.
A · · · #  · · · · ·  · · · · ·  · · · · ·  # · · · #
· · · · ·  · + + + ·  · + + + ·  · + + + ·  · · · · ·
· · · · ·  · + + + ·  · + X + ·  · + + + ·  · · · · ·
· · · · ·  · + + + ·  · + + + ·  · + + + ·  · · · · ·
# · · · #  · · · · ·  · · · · ·  · · · · ·  # · · · #

Solving this position is rather trivial. We'll set our source 'pool' position to
be in the center, and to solve the A position we'll simply rotate the piece in.
Let's move on to B positions.
# B · # #  # · · · #  · · · · ·  # · · · #  # # · # #
# · · · #  · + + + ·  · + + + ·  · + + + ·  # · · · #
· · · · ·  · + + + ·  · + + + ·  · + + + ·  · · · · ·
# · · · #  · + + + ·  · + X + ·  · + + + ·  # · · · #
# # · # #  # · · · #  · · · · ·  # · · · #  # # · # #

Here, there are more locked-in pieces, meaning that we can't just simply rotate
the piece in. Thus, we'll have to do a little bit of maneuvering.
It's getting a bit tighter, but C positions are rather similar to B
positions.
# # C # #  # · · · #  # · · · #  # · · · #  # # # # #
# · · · #  · + + + ·  · + + + ·  · + + + ·  # · · · #
# · · · #  · + + + ·  · + X + ·  · + + + ·  # · · · #
# · · · #  · + + + ·  · + + + ·  · + + + ·  # · · · #
# # # # #  # · · · #  # · · · #  # · · · #  # # # # #

Onto D positions.
# # # # #  # # · # #  # · · · #  # # · # #  # # # # #
# D · # #  # + + + #  · + + + ·  # + + + #  # # · # #
# · · · #  · + + + ·  · + + + ·  · + + + ·  # · · · #
# # · # #  # + + + #  · + + + ·  # + + X #  # # · # #
# # # # #  # # · # #  # · · · #  # # · # #  # # # # #

It's getting cramped! Time for E positions.
# # # # #  # # # # #  # # · # #  # # # # #  # # # # #
# # E # #  # + + + #  # + + + #  # + + + #  # # # # #
# # · # #  # + + + #  · X + + ·  # + + + #  # # · # #
# # # # #  # + + + #  # + + + #  # + + + #  # # # # #
# # # # #  # # # # #  # # · # #  # # # # #  # # # # #

Finally, F positions. There is almost no room to work with here, but we can
squeeze the piece in by rotating the corner cube and then one of the edge
cubes.
# # # # #  # # # # #  # # # # #  # # # # #  # # # # #
# # # # #  # + + + #  # + + + #  # + + + #  # # # # #
# # F # #  # + + + #  # + + + #  # + + + #  # # # # #
# # # # #  # + + + #  # + + + #  # + X + #  # # # # #
# # # # #  # # # # #  # # # # #  # # # # #  # # # # #

Stage 3: Solving the center 3×3×3
At this point, everything but the center 3×3×3 is solved. At the
end of this stage, it will be entirely solved.
Stage 3 will be broken into 3 steps:

Solving the center cross
Solving the edges
Solving the corners

Thin Moves
Before moving on to Step 1, we're going to introduce a very useful set of
algorithms: thin moves. These allow us to rotate "flat" 1×3×3 sections of the
cube, without affecting other pieces.
In subsequent examples, thin moves are shown as lines labeled with a t — this
is a shorthand for the sequence of regular moves that comprise the thin move.
Here's an example of the shorthand for a quarter-turn rotation on
Z.
Here are the moves that comprise the previous thin move.
Stage 3, Step 1: Solving the center cross
Again, the center cross is this set of pieces.
As a precursor, we're going to solve the center-most piece first, because we can
simply use the 'pool'-to-'pool' algorithm from Stage 2, Step 1. Afterwards,
everything but the outer shell of the 3×3×3 will be solved and we
can proceed to the novel parts of this step.
The partition for this step is as follows:

'active': all pieces in the center cross other than the center
piece that we just solved.
'done': all pieces outside of the center 3×3×3, along with the
center piece.
'pool': all of the corners and edges.

Here's a diagram of the positions like in the previous stage.
X · +   · # ·   + · +
· A ·   # # #   · # ·
+ · +   · # ·   + · +

Moving pieces between 'pool' positions is rather simple. We can use thin moves
to rotate the corners and edges of a face of the 3×3×3 without affecting the
center cross. Here's an example of moving one of the
corners.
To move pieces from a 'pool' position to an 'active' position, we use a
planar variation of INTO_CENTER that uses thin
moves (THINTO_CENTER).
Similarity to a Rubik's Cube
At this point, all positions except the corners and edges of the 3×3×3 are
solved.
The center 3×3×3 is now rather similar to a Rubik's Cube:

The center cross is solved, and the unsolved pieces are either edges or
corners; in a Rubik's Cube, the center cross is fixed and is therefore always
solved.
Because corners and edges are of different parities, corners cannot swap with
edges. Likewise, in a Rubik's Cube, corners cannot swap with edges.
We can either use thin moves to rotate 1×3×3 slices, or regular moves to
rotate the whole 3×3×3. These are the same moves you can make in a Rubik's
Cube.

In fact, the rest of the puzzle is simpler than a Rubik's Cube:

In a Rubik's Cube, every piece in unique, but in this, some of the pieces are
interchangable.
In a Rubik's Cube, corners can be in one of three orientations, and edges can
be in one of two; in this, pieces don't have orientations.

To solve the rest of the cube, we'll use thin moves to solve it like a Rubik's
Cube, using the Old Pochmann (1, 2) method.
Stage 3, Step 2
In this step, the remainder of the cube will be divided as follows, where A
and B represent 'active' positions, and C represents the singular 'pool'
position.
· A ·   A · A   · A ·
B · C   · · ·   A · A
· A ·   A · A   · A ·

First, we'll solve all A positions. Then, we'll solve the B position.
Nothing needs to be done to solve the C position, as all other pieces of the
same parity will have been solved.
We'll focus on this A position; other A positions are solved similarly:
· # ·   # # #   · # ·
# # +   # # #   # # #
· A ·   # # #   · # ·

Since the C position is the only 'pool' position, our source position will
always be C.
To solve this A position, we'll execute the following procedure:

Use thin moves to rotate the piece in this A position to the B position.
Swap the pieces in the B and C positions.
Reverse the moves in #1.

To accomplish #2, we'll use an algortihm known as the
T Permutation, which swaps the pieces in the B and C
positions, and swaps the pieces in the P and Q positions:
· · P   · · ·   · · ·
B · C   · · ·   · · ·
· · Q   · · ·   · · ·

Thus, the above procedure will swap the pieces in the B and C positions and
swap the pieces in the P and Q positions. Note that we must be careful not
to disturb the pieces in the P and Q positions in #1, as otherwise #2 will
have undesirable effects on the rest of the cube.
As we solve all of the B positions, the pieces in the P and Q positions
keep swapping back and forth, but we don't care, as they are both unsolved.
Finally, to solve the B and C positions, if they're not already solved, we'll
apply the T Permutation to swap them.
Note: usually, Old Pochmann will involve two additional algorithms for this
step, the Ja and Jb permutations. These are
used to simplify some of the swaps, but are not strictly necessary.
Stage 3, Step 3
This step is rather similar to Step 2.
In this step, the remainder of the cube will be divided as follows, where A
and B represent 'active' positions, and C represents the singular 'pool'
position.
C · A   · · ·   A · A
· · ·   · · ·   · · ·
A · B   · · ·   A · A

Like the previous step, we'll first solve all A positions, and then solve the
B position. As before, nothing needs to be done to solve the C position, as
all other pieces of the same parity will have been solved.
We'll focus on this A position; other A positions are solved similarly:
+ # #   # # #   # # #
# # #   # # #   # # #
A # #   # # #   # # #

To solve this A position, we'll execute the following procedure:

Use thin moves to rotate the piece in this A position to the B position.
Swap the pieces in the B and C positions.
Reverse the moves in #1.

To accomplish #2, we'll use an algorithm known as the
Y Permutation, which swaps the pieces in theB and C
positions, and swaps the pieces in the P and Q positions:
C P ·   · · ·   · · ·
Q · ·   · · ·   · · ·
· · B   · · ·   · · ·

Thus, the above procedure will swap the pieces in the B and C positions and
swap the pieces in the P and Q positions. The P and Q positions were
previously solved and have the same solved value, so swapping them does nothing.
Finally, to solve the B and C positions, if they're not already solved, we'll
apply the Y Permutation to swap them.
The puzzle is now entirely solved.
Note: in the Old Pochmann method, there is usually a step in between solving
the edges and corners: possibly using the Ra Permutation to
resolve parity. However, because the edges that the Y Permutation swaps are of
equal value, this is unnecessary in our case.
Conclusion
We did it!
Thanks for reading the explanation; I hope you enjoyed it! If you haven't
already, I highly suggest checking out the interactive visualization.
If you have any questions, comments, or feedback, please leave a comment or ping
me in chat!

Wow. After so long, I seriously doubted anyone would ever answer this. I need to read the answer properly, and check the test cases, but it looks like the big green tick (and the extra 1000 bounty I promised) are yours.

I'm having a hard time verifying this. It looks (based on what I'm seeing in your excellent visualization) like your 'X' instruction behaves the same as mine, but the 'Y' and 'Z' are swapped and (I think) your 'Y' works clockwise instead of anti-clockwise. I ran my first test case through your tool at the command line (cargo run as given above) and sent the output to a file. I prepended the test case to the file and then input it into my verification program (as given in the question) and it outputs 'false'. I think it's either the axis swap thing, or the 0-8/1-9 difference causing the fail.

@Gareth Yes, by default it outputs in my alternate coordinate system; if you change line 27 in main.rs to use get_compat_move_str, it will use the challenge's coordinate system and pass your verification program. The golfed version always outputs in the alternate coordinate system, since the output format was flexible and it saved some bytes :)

Excellent, thanks. The bounty will have to be awarded in installments, I'm afraid - the limit is 500 per bounty. And I can't award the bounty for 24 hours after setting it...

is it possible for you to post the ungolfed version? i dont understand anything :P

@DialFrost The ungolfed version is hosted on GitHub

@DialFrost (the explanation is probably much easier to understand than the source code (and thoroughly explains what the code does); if you have questions about either, though, please don't hesitate to ask!)

source: Stack Exchange

license: Creative Commons - Attribution Share-Alike - https://creativecommons.org/licenses/by-sa/3.0/

all_licenses: Creative Commons - Attribution Share-Alike - https://creativecommons.org/licenses/by-sa/4.0/

sort: votes


text:
convert tabs to spaces
Write the shortest possible code which converts tabs to spaces in the input. Tab size should be supplied as a parameter or be hardcoded in the code in a single place.
Spaces on output should point to the right column, e.g. (\t represents a tab character):
a\tb
aa\tb
aaa\tb
aaaa\tb

should become (for tab size 4):
a   b
aa  b
aaa b
aaaa    b

Of course there can be more than one tab in a line.
Line separator and tab character should match the system defaults (e.g. ASCII 10 and 9 on Unix).

I think this would be too trivial in any language with RegExp support.
And there is also a coreutils utility expand which does just this.

Possible duplicate

Related

I did not notice it was already there, is there a way to delete a question?

Possible duplicate

In the future, please post your challenges in the Sandbox and let it sit there for a couple of days.

Hi mik, You can use the delete button at the bottom-left of the question, next to edit :)

The linked dupe was not a dupe at all in my opinion as it only requires to replace some tabs with a constant amount of spaces, whereas here all tabs need to be converted to a varying amount of spaces based on there position.

As for the other proposed dupe (Expand tabs), that's closer but also more involved and requires parsing of a tabstop specification string, so I wouldn't necessarily consider it a dupe either.

Should we assume the non-whitespace parts of the input will all be ASCII range characters, or any Unicode character? Makes a difference for iteration in some languages, among other things.

Perl 5, 36 bytes
1while s/	/$"x($^I-length($`)%$^I)/e

Try it online!
Tab length is controlled with -i command-line parameter.

Python 2, 106 bytes
def f(s,w):
 for l in s.split('\n'):
  L=''
  for x in l.split('\t'):L+=' '*(w-(len(L)%w))+x
  print L[w:]

Try it online!

Vim, 16 bytes
:se ts=4 et
:ret

you can combine setting the two options on a single line and shorten :set to :se

I would expect the settings unchanged at the end.

Pyth, 24 bytes
VQ=+k:NJ"   "d=.[kd|nNJ4)k

Try it here
Explanation
VQ=+k:NJ"   "d=.[kd|nNJ4)k
VQ                      )    For each character in the input...
  =+k:NJ"   "d               ... add the character with tab replaced by space
                             to k (initially empty)...
              =.[kd          ... then pad k with spaces...
                   |nNJ4     ... to the nearest multiple of 4 if the character
                             is a tab and 1 otherwise.
                         k   Output k.

Alternatively, if we want to input the tab length, we can do so with Vz=+k:NJ" "d=.[kd|nNJQ)k.
Try it here.

Java 11, 134 bytes
n->s->{for(var l:s.split("\n")){var t="";for(var p:l.split("\t"))t+=" ".repeat(n-t.length()%n)+p;System.out.println(t.substring(n));}}

This time an answer for which I correctly read the challenge.. >.>
Try it online.
NOTE: Because Java 11 isn't on TIO yet, the String.repeat(int) has been emulated with repeat(String,int) for the same byte-count.
Explanation:
n->s->{                      // Method with int & String parameters and String return-type
  for(var l:s.split("\n")){  //  Split the input by newlines, and loop over the lines:
    var t="";                //   Temp-String, starting empty
    for(var p:l.split("\t")) //   Split the line by tabs, and loop over the parts
      t+=" ".repeat(n-t.length()%n)
                             //    Append `n - length_of_t modulo-n` amount of spaces,
         +p;                 //    as well as part `p` to the temp-String
      System.out.println(    //    Print with trailing new-line:
        t                    //     The temp-String `t`
         .substring(n));}}   //      after we've removed the trailing spaces

Excel VBA, 118
An anonymous VBE immediate window function that takes an input string from range [A1] and an input tab length from range [B1], and outputs to the console.
For Each l In Split([A1],vbLf):Do:i=InStr(1,l,"\t"):l=Replace(l,"\t",Space([B1]-(i-1)Mod[B1]),,1):Loop While i:?l:Next

Ungolfed
Public Sub tabReplace(ByRef value As String, Optional tabLen As Integer = 4)
    Dim line, index As Integer
    For Each line In Split(value, vbLf)
        Do
            Let index = InStr(1, line, "\t")
            Let line = Replace(line, "\t", Space(tabLen - (index - 1) Mod tabLen), , 1)
        Loop While index
        Debug.Print line
    Next
End Sub

Python 2, 103 bytes
def F(I,c):
 while'\t'in I:t=I.find('\t');I=I.replace('\t',' '*(c-(t+~I[:t].rfind('\n'))%c),1)
 print I

Try it online!
I wanted to evade split and use some replace (tbh I've started with regex).
I replace each \t with c-(t+~I[:t].rfind('\n'))%c number of spaces. Where t - index of current \t and t+~I[:t].rfind('\n') is distance to the closest \n (or start of string) on left.

Wolfram Language (Mathematica), 40 bytes
StringReplace[#,"	"->Array[" "&,4]<>""]&

Try it online!
Sadly, Mathematica doesn't let you multiply a string by a number to duplicate it, otherwise it would be shorter than Perl.

Explanation:
StringReplace[#, Replace all instances of
"  " a tab character
->Array[" " with an array of spaces
,4] four long
<>""]& joined to the empty string.

the answer should preserve columns, and not always add 4 spaces

I don't understand, sorry.

a tab after a single another character at the beginning of the line should be converted to 3 spaces, not 4; look at the example in the question

all_licenses: Creative Commons - Attribution Share-Alike - https://creativecommons.org/licenses/by-sa/3.0/


text:
Your very own "for" instruction
Your very own "for" instruction
Assuming you have the following input : a, b, c, d
Input can be in one-line using any format "a/b/c/d" or "a,b,c,d" etc..
You can also have 4 inputs.
You must code the following behaviour (pseudo-code here) :
var i = <a>
while (i <b> <c>)
    print i
    i = i + <d>
    print "\n"

Here are some tests cases :
input : 1,<,10,1
output :
1
2
3
4
5
6
7
8
9

One more :
input : 20,>,10,1
output :
20
21
22
23
24
25
26
27
...
infinite loop / program crashes

a is an integer, the initial value of i.
b is a string or a char, it can't be something else, the comparator used in the ending condition of the
for loop.
b can and must be one of the following strings :
- ">"
- "<"

c is an integer, the number used in the ending condition of the for
loop.
d is an integer that is added to i at every loop.

This is code-golf, the shortest answer wins !

Can the numbers be returned from a function as a list/sequence, rather than printed to stdout?

@smls Nope sorry, the output must be like the examples !

It says my code should follow the pseudo-code and there's a print "\n", but I am using javascript's alert for each line. Would that be acceptable, or would I have to use console.log instead making my answer longer?

You can use the alert function as a way to ouput but you can't use multiple alerts. Something like alert("23\n24\n25"); would work whereas alert("23"); alert("24"); alert(25); wouldn't

JavaScript (ES6),  44  43 56 bytes
Saved 1 byte thanks to ETHproductions
Edit: fixed to comply with output requirements
(a,b,c,d)=>{for(s='';eval(a+b+c);a+=d)s+=a+`
`;alert(s)}

Test

let f =

(a,b,c,d)=>{for(s='';eval(a+b+c);a+=d)s+=a+`
`;alert(s)}

f(1,'<',7,2)

Nice use of scope!

I think you can rearrange the eval to save a byte: (a,b,c,d)=>{for(;eval(a+b+c);a+=d)alert(a)}

@ETHproductions Ah, yes. Nice one!

That's a 44 with a tutu!

This doesn't follow the specification where output is line-by-line with U+000A after every line.

@Joey I last edited this before it was an explicit requirement, so I'm not sure I'm absolutely required to comply to the updated rules. I don't know the exact policy, though, so that's fixed anyway.

Hm, hard to tell in hindsight from the edit history of the question. For my taste it's still not very well specified and comes down mostly to »Do whatever you want, as long as it vaguely resembles the task«. I guess I like having stricter task descriptions in general and I also like a correctness-first approach to solutions. Back when I used to post tasks here I nearly always supplied test scripts that could be used to unambiguously decide whether a solution was passing or not.

Javascript (ES6), 47 42 48 Bytes
Wanted to make the for version but someone was faster, so here's the recursive version.
(b,c,d)=>F=a=>eval(a+b+c)&&console.log(a)|F(a+d)

You need to add f= before and call it like f(b,c,d)(a).
Many thanks to Arnauld for the awesome golf.
alert changed to console.log because of output specification

@Arnauld Thanks, that's a pretty cool golf. I just asked him, so let's see if he accepts it.

Glad to see it accepted. ;)

This doesn't follow the specification where output is line-by-line with U+000A after every line.

@Joey That's just pseudo-code, but I'll ask OP about this.

@Masterzagh: There was a question about alternative output formats already which was denied.

Pure bash, 35
I assume its OK  just to plug the parameters into the standard for loop:
for((i=$1;i$2$3;i+=$4));{ echo $i;}

Try it online.

Haha, bash makes it really easy

Jelly, 12 bytes
Ṅ+⁶µ⁴;⁵¹vµ¿t

Try it online!
Jelly has a lot of ways to tersely do iteration, create ranges, etc.. However, mirroring C++'s behaviour exactly is fairly hard, due to special cases like the increment being 0, the loop ending before it starts (due to the inequality being backwards), and the increment going in the wrong direction (thus meaning the exit condition of the loop can't be met naturally). As such, this solution is basically a direct translation of the C++, even though that makes it rather more low-level than a Jelly program normally is. Luckily, C++ has undefined behaviour on signed integer overflow (the question uses int), meaning that a program can do anything in that case, and thus there's no need to try to mimic the overflow behaviour.
Explanation
Ṅ+⁶µ⁴;⁵¹vµ¿t
   µ     µ¿   While loop; while ((⁴;⁵¹v) counter) do (counter = (Ṅ+⁶)counter).
    ⁴;⁵       Second input (b) appended to third input (c), e.g. "<10"
        v     Evaluate, e.g. if the counter is 5, "<10" of the counter is true
       ¹      No-op, resolves a parser ambiguity
Ṅ             Output the counter, plus a newline
 +⁶           Add the fourth input (d)
           t  Crashes the program (because the counter is not a list)

Crashing the program is the tersest way to turn off Jelly's implicit output (otherwise, it would output the final value of the counter); it generates a bunch of error messges on stderr, but we normally consider that to be allowed.
Incidentally, the loop counter is initialised with the current value before the loop starts. As the loop appears at the start of the program, that'll be the first input.

You could change t to Ḋ to have no crash. The dequeue results in an empty list for which Jelly's implicit print yields nothing.

@JonathanAllan: It doesn't, what it actually does is to create a range from 2 to the given value, which is definitely visible on an implicit print.

Ah, I must've tested that theory with a loop ending in negative territory; indeed a range is implicitly created.

Uhm, this is 12 characters, but it's not 12 bytes right?

@Cruncher: Jelly uses its own encoding in which each character used by the language is represented by a single byte (it only uses 256 different characters). The reason it doesn't use something better-known like code page 437 is to make it easier to type (I mean, it's not that easy to type, but it's easier than a language like gs2 would be). A hexdump of this program would be 12 bytes long.

Ahhh okay that's cool :)

Python 2, 50 bytes
a,b,c,d=input()
while eval(`a`+b+`c`):print a;a+=d

Try it online!

R, 63 bytes
function(a,b,c,d)while(do.call(b,list(a,c))){cat(a,"\n");a=a+d}

Java, 58 bytes
(a,b,c,d)->{for(;b>61?a>c:a<c;a+=d)System.out.println(a);}

Is there a reason to create i? Could you skip the initialization part and just use a? Also, using the ASCII value  of '>' (62) saves a byte.

Following Riley's comment, you can do b>61

I don't believe this compiles.

@ChiefTwoPencils It's a function. You have to write a test program around it in order to compile it.

@wizzwizz4, obviously. But that still doesn't work. Give it a shot. Plus, my understanding is all bytes required to run it counts.

@ChiefTwoPencils That's only programs, not functions. This is an anonymous function, so you'll need to assign it to a variable then call it with the necessary parameters. (Unless you mean that there are syntax errors, which is possible, but it looks to me like perfectly valid Java code (and even C code, excluding anonymous function and System.out.))

As mentioned by Riley & KritixiLithos, you don't need i. In addition, you can change b=='>' to b>61. So it becomes: (a,b,c,d)->{for(;b>61?a>c:a<c;a+=d)System.out.println(a);} (58 bytes) @ChiefTwoPencils (See the link to see how you can compile and run this.)

SmileBASIC, 53 bytes
INPUT A,B$,C,D
S=ASC(B$)-61WHILE S*A>S*C?A
A=A+D
WEND

Explanation:
INPUT A,B$,C,D
IF B$=="<" THEN S=-1 ELSE S=1 'get comparison direction
I=A
WHILE S*I>S*C 'loop while I is less than/greater than the end
 PRINT I
 INC I,D
WEND

This uses the fact that X<Y is the same as -X>-Y

I'll trust you for this one, I don't have a 3DS to test :)

I have Petit Computer, so cool idea! I will try something like this sometime...

You could use a READ statement, saving 1 byte.

@ckjbgames how?

@12Me21 Check the SmileBASIC manuals. It should be in the list of instructions for SmileBASIC.

I know how READ works, but where would I use it in this program?

@12Me21 Where the INPUT statement is.

I don't think that's allowed, since you'd have to edit the file to change the DATA.

05AB1E, 22 20 bytes
[D²`'>Q"‹›"è.V_#D,³+

Try it online!
Explanation
[                       # start loop
 D                      # copy top of stack (current value of a)
  ²`                    # push b,c to stack
    '>Q                 # compare b to ">" for equality
       "‹›"             # push this string
           è            # index into the string with this result of the equality check
            .V          # execute this command comparing a with c
              _#        # if the condition is false, exit loop (and program)
                D,      # print a copy of the top of the stack (current value of a)
                  ³+    # increment top of stack (a) by d

Any input format is accepted so the second version is okay :)

Stacked, 34 bytes
@d@c@b[show d+][:c b tofunc!]while

Try it online! (Testing included.) This is a function that expects the stack to look like:
a b c d

For example:
1 '<' 10 2
@d@c@b[show d+][:c b tofunc!]while

Explanation
@d@c@b[show d+][:c b tofunc!]while
@d@c@b                               assign variables
               [............]while   while:
                :c                   duplicate "i" and push c
                   b tofunc!         convert b to a function and execute it
      [.......]                      do:
       show                          output "i" without popping
            d+                       and add the step to it

Plain TeX, 88 bytes
\newcount\i\def\for#1 #2 #3 #4 {\i#1\loop\the\i\endgraf\advance\i#4\ifnum\i#2#3\repeat}

The command \for provides the requested function. Save this as for.tex and then run it and enter the variable values at the command line: pdftex '\input for \for 1 < 5 1 \bye' The variable values must be separated by spaces.

Python 2, 45 bytes
exec"i=%d\nwhile i%c%d:print i;i+=%d"%input()

Try it online!
A very literal implementation of the spec. Takes the code template, substitutes in the inputs via string formatting, and executes it.

C++, 80
Whoops, this is C++ not C. Was a bit confused by the question.
void f(int a,char b,int c,int d){for(;b==62?a>c:a<c;a+=d)cout<<a<<endl;}

Is this C or C++?

Which implementation of C++?  (I'm curious how you're getting something akin to using namespace std for free).

Doesn't i have to start at a, not 0? You can just use a and skip i altogether and use the ASCII value of '>'. for(;b==62?a>c:a<c;a+=d)

Doesn't work for f(1,'<'3,1);

Ack... yeah, requires the math on both sides; for(b-=61;b*a>b*c;a+=d) works for a single byte; but so does for(;b-62?a<c:a>c;a+=d).

...for another byte see my comment for gurka's C solution.

(future reference:) b==62 could also be written as b>61, since < is 60. I'm assuming the input is always correct

C, 52 51 bytes
-1 byte thanks to H Walters
f(a,b,c,d){for(;b&2?a>c:a<c;a+=d)printf("%d\n",a);}

Try it online!

Sorry for the mistake in the pseudo-code, i increments after each print :)

Use b&2 instead of b^60 for another byte.

Python 3, 52 bytes
def f(a,b,c,d):
 while[a>c,a<c][b<'>']:print(a);a+=d

repl.it

Clever use of lists !

Common Lisp, 82 80 79 73 64 bytes
(defmacro f(a b c d)`(do((i,a(+ i,d)))((not(,b i,c)))(print i)))

Test
(f 1 < 10 1)

1
2
3
4
5
6
7
8
9
NIL
CL-USER>

-9 bytes thanks to PrzemysławP.

Perhaps you can save 9 bytes, by defining a macro. (defmacro f(a b c d)<insert backqoute here>(do((i,a(+ i,d)))((not(,b i,c)))(print i))) Usage: (f 1 < 10 1)

@PrzemysławP Thanks again !

Pip, 14 bytes
W Va.b.ca:d+Pa

Takes four command-line arguments. Supports negative & floating point numbers and comparison operators < > = <= >= !=. Try it online!
                a,b,c,d are cmdline args
W               While loop with the following condition:
  Va.b.c          Concatenate a,b,c and eval
            Pa  Print a with newline (expression also returns value of a)
        a:d+    Add d to that and assign back to a

Jelly, 8 bytes
ḢṄ+⁹;µV¿

This is a dyadic link that takes a,b,c as its left argument and d as its right one. Output may be infinite and goes to STDOUT.
Try it online!
How it works
ḢṄ+⁹;µV¿  Dyadic link.
          Left argument:  a,b,c (integer, character, integer)
          Right argument: d     (integer)

       ¿  While...
      V     the eval atom applied to a,b,c returns 1:
     µ       Combine the links to the left into a chain and apply it to a,b,c.
Ḣ              Head; pop and yield a from a,b,c.
 Ṅ             Print a, followed by a linefeed.
  +⁹           Add a and the right argument (d) of the dyadic link.
    ;          Concatenate the result and the popped argument of the chain,
               yielding a+d,b,c.

Command-line arguments use Python syntax and cannot distinguish between a character and a singleton string. If you want to use CLAs, you have to insert an F to flatten the array.

Now I want to delete half my comment as it's obsolete, whilst keeping the other half. I guess I'll just repeat the relevant half and delete the rest: "Oh, bleh, you defined it as a function so you could disregard the implicit output under PPCG rules. I should have thought of that."

Python 3, 61 bytes
One liner:
e=input;exec(f'i={e()}\nwhile i{e()}{e()}:print(i);i+={e()}')

Welcome to the site! Nice use of the new literal string interpolation feature. I think you might be able to save a byte by replacing \t with a space.

Thank you.still the same size after removing the \n\t after third e()

Haskell, 66 64 bytes
f a b c d|last$(a<c):[a>c|b>"<"]=print a>>f(a+d)b c d|1<3=pure()

Try it online! Usage:
Prelude> f 0 "<" 9 2
0
2
4
6
8

Ruby, 43 41 bytes
->a,*i,d{a=d+p(a)while eval"%s"*3%[a,*i]}

If b can be taken in as a Ruby symbol instead of a string, you get 38 bytes:
->a,b,c,d{a=d+p(a)while[a,c].reduce b}

Try either solution online!

PHP, 69 65 bytes
for(list(,$i,$b,$c,$d)=$argv);$b<"="?$i<$c:$i>$c;$i+=$d)echo"$i
";

Run with '-r'; provide command line arguments as input.
For just one byte more 4 more bytes, I can take every operator:
for(list(,$i,$b,$c,$d)=$argv;eval("return $i$b$c;");$i+=$d)echo"$i
";

Yeah, evil eval. Did you know that it can return something?

Shorthand destructuring [,$i,$b,$c,$d]=$argv; would  save 4 more bytes;
but PHP 7.1 postdates the challenge.

Neat ! I wasn't sure when creating the challenge if I should include every common operators, then I remembered that they aren't all the same (~= for != in Lua for example)

Woah, eval IS evil.

It seems to me that you can use PHP 7.1 to make it shorter. If it is not so the use of list saves 4 Bytes plus 4 Bytes with short syntax

@PHP 7.1 postdates the challenge; but thanks for list().

Bash (+Unix Tools), 29 bytes
Golfed
bc<<<"for(x=$1;x$2$3;x+=$4)x"

Test
./forloop 1 '<' 10 1
1
2
3
4
5
6
7
8
9

Ha.  I was just about to post the exact same thing!  +1

Groovy, 51 bytes
{a,b,c,d->while(Eval.me("$a$b$c")){println a;a+=d}}

This is an unnamed closure. Try it Online!
Caution - If you want to test this with groovy console, make sure you kill the entire process when the input causes an infinite loop. I noticed this after it consumed ~5 gigs of RAM.

Perl 6, 44 bytes
{.say for $^a,*+$^d...^*cmp$^c!= $^b.ord-61}

How it works
{                                          }  # A lambda.
          $^a                                 # Argument a.
             ,*+$^d                           # Iteratively add d,
                   ...^                       # until (but not including the endpoint)
                       *cmp$^c                # the current value compared to c
                                              # (less=-1, same=0, more=1)
                              != $^b.ord-61.  # isn't the codepoint of the b minus 61.
 .say for                                     # Print each number followed by a newline.

If it's okay to return a (potentially infinite) sequence of numbers as a value of type Seq, instead of printing the numbers to stdout, the .say for part could be removed, bringing it down to 35 bytes.

Clojure, 66 63 bytes
#(when((if(= %2"<")< >)% %3)(println %)(recur(+ % %4)%2 %3 %4))

-3 bytes by factoring out the loop. I'm "abusing" the init parameter to act as the running accumulator.
Recursive solution (with TCO). See comments in pregolfed code. I tried a non-TCO recursive solution, and it ended up being 67 bytes.
I'd love to see this beat in Clojure! I think this is the smallest I can get it.
(defn my-for [init-num com-str com-num inc-num]
  (let [op (if (= com-str "<") < >)] ; Figure out which operator to use
    (when (op init-num com-num) ; When the condition is true, print and recur
      (println init-num)
      (recur (+ init-num inc-num) com-str com-num inc-num))))
    ; Else, terminate (implicit)

Oh I didn't notice this answer. #(when(({">">"<"<}%2)% %3)(println %)(recur(+ % %4)%2 %3 %4)) would be 61 bytes, combining your when with my ({">">"<"<}%2).

Clojure, 66 bytes
#(loop[i %](if(({">">"<"<}%2)i %3)(do(println i)(recur(+ i %4)))))

This could have been 55 bytes as< and > are functions in Clojure:
(def f #(loop[i %](if(%2 i %3)(do(println i)(recur(+ i %4))))))
(f 1 < 10 1)

I like the use of the map here. I would have never thought that that would have beaten my way. Also interesting that both of our initial counts were the same, despite slightly different approaches.

Allowing b to be a function would give an unfair advantage to some languages :)

True, but I think most languages I know of wouldn't benefit much from allowing < instead of "<", except Clojure.

@Sygmei True. It would be freakin sweet though. Can't blame you making that call.

OP said characters are fine instead of strings for the comparison operators btw. That should save a couple bytes.

Can't Haskell use that advantage too ?

I don't know Haskell :( Using strictly chars doesn't help because {\> >\< <} is same length as {">">"<"<}. {\>>\<<} isn't parsed correctly at least on Nightcode. Using symbols < and > is shown in the 55 byte example already.

@Sygmei Idk exactly how the Haskell answer works. It potentially allows for some compression in Clojure because the character for "less than" is \<, which is 1 character shorter than a string representation of "<". Whether or not you gain from that depends on the situation unfortunately.

QBIC, 51 40 bytes
:;::{?a┘a=a+c~A=@<`|~a>=b|_X]\~a<=b|_X

And three minutes after posting I realised I could simplify the terminator logic...
:;::      Consecutively read a, A$, b and c from the command line
{?a┘      Start an infinite loop; print a, add a newline to the source
a=a+c     increment a
~A=@<`|   If we are in LESS THAN mode
  ~a>=b   and IF we are no longer LESS
    |_X]  THEN QUIT, end if.
  \       ELSE (we're in GREATER THAN mode)
    ~a<=b IF we are no longer GREATER
    |_X   THEN QUIT
          The last IF and the loop are auto-closed

Batch, 94 bytes
@set i=%1
@set o=gtr
@if "%~2"=="<" set o=lss
:g
@if %i% %o% %3 echo %i%&set/ai+=%4&goto g

If it wasn't for the second parameter behaviour, it could be done in 53 bytes:
@for /l %%i in (%1,%4,%n%)do @if not %%i==%3 echo %%i

This simply does nothing if the step has the wrong sign. The extra test is because Batch's for loop allows the loop variable to equal the end value.

TI-Basic, 41 34 bytes
Prompt A,Str2,Str3,D
While expr("A"+Str2+Str3
Disp A
A+D->A
End

The way that a TI calculator works, many symbols are stored as a single byte. Prompt , Str2, Str3, While , expr(, Disp , ->, and End are all single-byte symbols. I count 29 bytes.

@Pavel Thanks for your interest! Although it's true that TI-Basic is tokenized, not all tokens are one byte. For example, Str2, Str3, and expr( are all two-byte tokens. To see a list of one-byte tokens, check out http://tibasicdev.wikidot.com/one-byte-tokens

dc, 47 bytes
dc, 48 bytes
Also Bash + Unix utilities, 29 bytes
dc (47 bytes):
1sb[_1sb]s zz?sdlb*sc[pld+lnx]sl[dlb*lcr<l]dsnx

Try it online!
Note that negative numbers must be entered with an underscore instead of a minus sign, because that's how dc accepts numeric input. So write, for example, _5 instead of -5.

dc can't read character or string input into a variable and process it (there's a more detailed explanation below), but I found two ways of working around this:
The 47-byte dc solution works on input that has argument1 and argument2 reversed, with spaces as the delimiter.  So counting from 1 up to (but not including) 10 in steps of 3 would be entered as:
< 1 10 3
If it's not acceptable to change the order of the arguments, I also give a 48-byte dc solution which keeps the original order of the arguments. This one uses zz as the delimiter between arguments.  So counting from 1 up to (but not including) 10 in steps of 3 again would use the following input line:
1zz<zz10zz3

Finally, the same ideas yield a 29-byte bash solution.

Details on dc's lack of string processing, and how this program deals with that:
Handling this problem in dc is tricky, because dc doesn't accept string or char input as most languages do. When dc reads an input string, it immediately runs that string as a dc program (a macro), and then discards the string. You can't store the characters of the string in memory and process them later, or in any other way.  This interferes with the requirement to have '<' or '>' in the input.
I'll show two ways around this.  In the solution above (47 bytes), we switch the order of the first two inputs. The input delimiter is the space character.  For example, to count from 1 up to (but not including) 10 in steps of 3, you'd input
< 1 10 3

Here's the idea behind this solution:
Macros in dc are stored in registers, and registers have single-character names. I store a macro in the register whose name is just a space character.
The program works by pushing a 0 and 1 on the stack before getting the input.  Then, when the input is run as a dc program (which is what dc does with input lines), the '<' or '>' character is executed as a command, which is a conditional macro execution of the macro whose name is the next char after the '<' or '>'. Specifically, the top two items on the stack are popped.  If the first item popped is < (respectively, >) the second item popped, the indicated macro is executed.  The next character (after the '<' or '>') is a space, so the macro that we've stored in the register whose name is the space char is the one executed if the condition holds.  But we had pushed 0 and 1 on the stack, so the first item popped was a 1, and the second item popped was a 0.  As a result, the macro is executed only if the conditional test was >, not <.  This lets us distinguish between '<' and '>' in the input.
The remaining items in the line are just numbers, and dc will simply push those numbers, in turn, on the stack.
Here's a detailed description.  Most of the time, the counting variable (i in the pseudocode in the problem statement) is stored at the top of the stack.
1sb             Store 1 in register b.  (b will end up being 1 for '<', and -1 for '>').
[_1sb]s         Note that there is a space after the second s.  So the space char is the name of a macro which stores -1 in b.
z               Push 0 on the stack.
z               Push 1 on the stack.
?               Accept input in the format above.  This will:
                    - Store 1 or -1 in b, depending on whether you've typed "<" or ">"
                    - Push each of the three numbers in turn on the stack.
sd              Save the increment in register d.
lb*sc           Save either limit or -limit in register c, depending on whether the input started with "<" or ">".
[pld+lnx]sl     Define a macro called l which is the body of our loop:
                    - Prints the top of the stack
                    - Adds the increment to the top of the stack.
                    - Calls macro n (the loop test).

 [dlb*lcr<l]dsn  Define a macro called n which is the test of the loop:
                    It checks to see if i (at the top of the stack) times b is less than c; if so, it calls macro l (looping back).
 x               Execute the loop test macro initially (a while loop needs to have a test at the top before entering the loop the first time).

On the other hand, the OP stated:
Input can be in one-line using any format "a/b/c/d" or "a,b,c,d" etc.

So maybe it isn't legitimate to switch the order and require b before a in the input.
Here's an alternative which keeps a, b, c, and d in their original order. We are allowed to use any delimiter; I'll use zz as the delimiter.  So counting from 1 up to (but not including) 10 in steps of 3 would be entered as:
1zz<zz10zz3

The new program, with zz-delimited input, is
dc (48 bytes):
1sb[_1sb]sz?sdiilb*sci[pld+lnx]sl[dlb*lcr<l]dsnx

This is one byte longer than the 47-byte first solution.
Try the zz-delimited version online!
I personally think the different-order < 1 10 3 formatting is more in the spirit of the problem, but maybe 1zz<zz10zz3 better meets the actual technical specification.
You could probably get a shorter solution if you allowed different delimiters between the different input arguments, but I don't think that's in the spirit of the problem.
Bash + Unix utilities, 29 bytes
You can turn the underlying idea above into a bash program (which calls dc); this avoids all the difficulties with "<" and ">", and it also simplifies handling the various numeric parameters, so it's only 29 bytes long, the same as @zeppelin's bash+bc answer.
bash version (29 bytes):
dc -e[p$4+d$3r$2l]sl$1d$3r$2l

Try the bash version online!
Here's a description of how the dc program inside the bash program works:
The value of i is stored at the top of the stack most of the time.
[      Start of macro (i is at the top of the stack). This macro will be called l.
p      Print i
$4+    i += (4th argument)
d      Duplicate i at the top of the stack.
$3     Push the 3rd argument onto the stack.
r      Swap the top two items on the stack, so i is at the top and arg3 is second
$2l    $2 is "<" or ">", causing the top two items to be popped from the stack, and macro l is then called (effectively looping back) if i < arg3 or i > arg3, respectively.
]sl    End of macro definition; store macro in register l.

$1     Push argument 1 onto the stack (i = 1st argument).
d$3r$2l Just as above, call macro l if i < arg3, or i > arg3, depending on whether arg2 is "<" or ">"

tcl, 52
proc F {a b c d} {while \$a$b$c {puts $a;incr a $d}}

demo

How is this using d to decide by how much to increment a?

@PaŭloEbermann: My mistake! UPDATED!

Pari/GP , 48 Bytes
f(a,b,c,d)=while(eval(Str(a,b,c)),print(a);a+=d)

Testing
f(4,"<",7,1)  \\ input
4             \\ output
5
6

C#, 77 bytes
(a,b,c,d)=>{for(int i=a;b==">"?i<c:i>c;i+=d){System.Console.Write(i+"\n");}};

F#, 71 106 97 bytes
fun a b c d->let i=ref a in while(b !i c)do printfn"%i%s"!i d;i:=!i+1;done
I didn't read the question fully!
fun a b c d->let i=ref a in while((if b='<'then(<)else(>))!i c)do printfn"%i%s"!i d;i:=!i+1;done

Ruby, 37 bytes
->a,b,c,d{(p a;a+=d)while a.send b,c}

A pretty straightforward solution. Unlike Value Ink's Ruby solution b doesn't have to be a Ruby symbol; just ints and a string/char as per the challenge. And it's still a byte under :)
Try it online

VBA, 87 Bytes
subroutine that does the thing
Sub f(a,b,c,d)
While IIf(b="<",a<c,a>c)
Debug.?a
a=a+d
Wend
End Sub

APL (Dyalog), 19 bytes
{⍵⍺⍺⍨⊃⍺:⋄⍺∇2⊃⍺+⎕←⍵}

This is an operator taking (c,d) as left argument, b as left operand, and a as right argument.
{ anonymous "something"
 ⍵ [if] the right argument
 ⍺⍺⍨ is not ber than (also signals that this is an operator)
 ⊃⍺ the first of the left arguments
 : then terminate
 ⋄ else
 ⍺∇ reuse the left argument to call the derived function (this operator with its operand) on
 2⊃ the second element of
 ⍺+ the left argument added to
 ⎕← the printed
 ⍵ right argument
}
Try it online!

Excel VBA, 47 Bytes
Anonymous VBE immediate window function that takes input as described in prompt from the range [A1:D1] on the ActiveSheet object and implicitly outputs back onto that object by modifying the value of the visible [A1].Value variable
While[If(B1="<",A1<C1,A1>C1)]:[A1]=[A1+D1]:Wend


text:
A boring version of yourself
A boring version of yourself
Have you ever dreamed of a boring version of you which types the text you just typed ?
No ? Because that's exactly what I'm challenging you to do !
The program needs to check how many time it took for the user to input a text at program launch and then retype the text again using the same period of time (approximatively).
Here's my Python3 implementation with additional information :
import time

start = time.time()
userInput = input("Cool human input :")
endHuman = time.time() - start
duration =  endHuman / len(userInput)
start = time.time()
print("Boring robot input : ", end="")
for i in userInput:
  print(i, end="")
  time.sleep(duration)
end = time.time() - start
print()
print(endHuman, "vs", end)

This is a code-challenge so be creative !
Here are the rules :

User must input the initial text, no program args
Text input length is > 0 (No need to check)
The sleep duration between each letter is not imposed, it can be (timeTookByUser / numberOfLetters) like in my implementation, it can be random (as long as the total time is approximatively equal), it can sleep for the total time at first and then print all (but it's not fun).
The "robot timer" must stop when the last letter is typed by the robot, you can't print everything and then sleep and end the program.
As long as the robot prints the text passed in input, you can print other stuff (additional informations etc..)
You don't have to use the console, you can input the text using a graphical text input and render it letter by letter using DELs but you will have to specify it in your answer
Be creative !

What is the winning criterion?

Should the robot reproduce the use of backspace, cursor moves, text overwriting, etc.?

@Luke Winner is the most creative solution I guess ?

@Arnauld Nope, it does not have to. But that would be a nice solution !

All challenges on PPCG must have an objective winning criterion, such as shortest code or fastest to run. I'd suggest shortest code (that is, [tag:code-golf]) for this particular challenge.

@ETHproductions Is "most amount of upvotes" a valid criterion ? As creative solutions may receive more upvotes it could be pretty objective criterion :)

Well, it is a valid criterion (you would use the [tag:popularity-contest] tag), but questions of that sort are generally discouraged.

Please be very careful using the Pop-Con tag (and do a bunch of reading beforehand).

@AdmBorkBork I don't think it's a duplicate since the goal here is to repeat ONE string using the same length of time and use that same length of time to display the same text creatively, I just saw that the popularity-contest tag is quite unpopular here (quite ironic). If people are against this tag, I won't create question with this tag again :)

Bash + linux utilities, 37
This will measure the time taken to enter each character (including backspaces) and play back verbatim.  Use ^C or ^D to end user input.
script -qta -csed\ d
scriptreplay -ta

Creates a temporary files typescript and a in the current directory.

I'll try that when I'll be on Linux :)

Wow ! Neat one :) Nice use of Linux utilities

You can actually get bash for windows if you like what you see. That is what Git for Windows uses.

That's cheating BTW, script and scriptreplay are not a bash utility or of any other shell I know. They are binaries. If this is considered a legitimate answer then I can put these two commands inside an executable called a and give ./a as an answer ;-D

@Saga.  The point is the language here is "Bash + linux utilities" and not "Pure Bash" (in which case the answer would only contain bash builtins).  On my vanilla Ubuntu machine, this includes old favourites such sed and script.  From the point of view of PPCG, these utilities effectively form a "standard library" to bash.  That they are implemented as binaries is an irrelevant implementation detail.  Look around - you'll see this seems to be well accepted by the PPCG community.

@saga ... If you would like to go in a different direction than this, then please make your suggestion as a meta question and we can see how the community reacts.

@saga BTW, your suggestion of creating an executable a is definitely considered cheating, as this would be considered as using a new language created after the challenge was posted.

@DigitalTrauma easy man, I overlooked the title :-)

@saga yes, this is a recreational site so I try to stay light-hearted.  However it is no longer fun if participants feel something is unfair.  I therefore take accusations of cheating quite seriously :)

MATLAB / Octave, 38 bytes
tic;x=input('','s');pause(toc);disp(x)

Starts a timer (tic) and prompts the user for input. Then the program pauses for however long it took for the user to input the text (toc) and prints out the input text.

Commands named tic and toc? That's genius :-)

MATL, 7 5 bytes
2 bytes saved thanks to @Luis
jZ`Y.

This solution will determine how long the user takes to enter the input and then wait that same amount before printing the user's input back to them all at once.
Unfortunately doesn't work online since the online interpreters don't support interactive input.

Explanation
        % Implicitly start the timer
j       % Grab user input as a string (will prompt the user)
Z`      % Stop the timer and return the elapsed time in seconds
Y.      % Pause for this many seconds
        % Implicitly display the user-input string

GIF in the post always makes it better !

Python 3.5, 61 bytes
from time import*
s,i=time(),input()
sleep(time()-s)
print(i)