Skip to content

ArhanChaudhary/qter

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

The qter logo


PROJECT STATUS: almost MVP; many features incomplete

Qter is a human-friendly Rubik's cube computer. This means you can compile a computer program and then act as a computer processor by physically turning a Rubik's cube to affect its computation, even if you have no knowledge of how computers work. Following is an example executable program that accepts an index as user input and computes the corresponding Fibonacci number. It is written in our custom Rubik's cube file format named Q:

fib.q

Puzzles
A: 3x3

1  | input "Which Fibonacci number to calculate: "
           B2 U2 L F' R B L2 D2 B R' F L
           max-input 8
2  | solved-goto UFR 4
3  | goto 5
4  | halt "The number is: 0"
5  | D L' F L2 B L' F' L B' D' L'
6  | L' F' R B' D2 L2 B' R' F L' U2 B2
7  | solved-goto UFR 9
8  | goto 10
9  | halt "The number is: "
          L D B L' F L B' L2 F' L D'
          counting-until DL DFL
10 | solved-goto DL DFL 13
11 | L U' B R' L B' L' U' L U R2 B R2 D2 R2 D'
12 | goto 10
13 | L' F' R B' D2 L2 B' R' F L' U2 B2
14 | solved-goto UFR 16
15 | goto 17
16 | halt "The number is: "
          F2 L2 U2 D' R U' B L' B L' U'
          counting-until FR DRF
17 | solved-goto FR DRF 20
18 | D' B' U2 B D' F' D L' D2
     F' R' D2 F2 R F2 R2 U' R'
19 | goto 17
20 | L' F' R B' D2 L2 B' R' F L' U2 B2
21 | solved-goto UFR 23
22 | goto 24
23 | halt "The number is: "
          U L' R' F' U' F' L' F2 L U R
          counting-until UF
24 | solved-goto UF 6
25 | B R2 D' R B D F2 U2 D'
     F' L2 F D2 F B2 D' L' U'
26 | goto 24

This was compiled from our custom high level programming language named QAT (Qter Assembly Text):

fib.qat

.registers {
    A, B, C, D <- 3x3 builtin (30, 18, 10, 9)
}

.macro fib-shuffle {
    ($R1:reg $R2:reg $R3:reg $counter:reg) => {
        dec $counter
        if solved $counter {
            halt "The number is" $R1
        }
        while not-solved $R1 {
            dec $R1
            inc $R2
            inc $R3
        }
    }
}

input "Which Fibonacci number to calculate:" D
if solved D {
    halt "The number is: 0"
}
inc B
loop {
    fib-shuffle B A C D
    fib-shuffle A C B D
    fib-shuffle C B A D
}

Table of Contents

Physically running qter

The Q file format

The Q file format is qter's representation of a computer program in an executable Rubik's cube language. The file format was designed in such a way that, with only basic Rubik's cube knowledge, a human can physically manipulate a twisty puzzle to execute a program and perform a meaningful computation.

Qter doesn't just support 3x3x3 cubes, but it works with any twisty puzzle in the shape of a platonic solid. Since most people are most familiar with the 3x3x3 cube, we will introduce qter with the aforementioned from now on.

Q files are expected to be read from top to bottom. Each line indicates an instruction, the simplest of which is just an algorithm to perform on the cube. For example:

Puzzles
A: 3x3

1 | U' R2
2 | L D'
...

The Puzzles declaration specifies the types of twisty puzzles used. In this example, it is declaring that you must start with a 3x3x3 cube, and that it has the name "A". The name is unimportant in this example, but becomes important when operating on multiple cubes. The instructions indicate that you must perform the algorithm U' R2 L D' on the Rubik's cube, given in standard move notation. You must begin with the cube solved before following the instructions.

The Q file format also includes special instructions that involve the twisty puzzle but require additional logic. These logical instructions are designed to be simple enough for humans to understand and perform.

Logical instructions

Following this section, you should be able to understand how to physically execute the example Fibonacci program provided at the beginning of this document. More complicated instructions are expanded upon in the next section.

  • goto <number>

    Jump to the specified line number instead of reading on to the next line. For example:

    Puzzles
    A: 3x3
    
    1 | U' R2
    2 | L D'
    3 | goto 1
    ...

    Indicates an infinite loop of performing U' R2 L D' on the Rubik's cube. After performing the algorithm, the goto instruction requires you to jump back to line 1 where you started.

  • solved-goto <number> <positions>

    If the specified positions on the puzzle each contain their solved piece, then jump to the line number specified as if it was a goto instruction. Otherwise, fall through and go to the next instruction. For example:

    Puzzles
    A: 3x3
    
    1 | U' R2
    2 | solved-goto 4 UFR UF
    3 | goto 1
    4 | L D'
    ...

    Indicates repeatedly performing U' R2 until the UFR corner position and UB edge position contain their solved pieces. Then, perform L D' on the Rubik's cube. Note that three faces uniquely identify any corner position and two faces uniquely identify any edge position on the Rubik's cube, hence UFR (up front right) and UF (up front).

    Determining if a position contains its solved piece slightly varies from puzzle to puzzle, but the idea remains the same. For the Rubik's cube, this is the case when each face of the piece at the position is the same color as its center.

    The following illustrates a successful solved-goto 4 UFR UF instruction where you would jump to line 4:

    A Rubik's cube with the UFR and UF positions solved

    The following illustrates an unsuccessful solved-goto 4 UFR UF instruction where you would skip it and continue to the next instruction. Note that all pieces specified need to be in their solved positions, not just one:

    A Rubik's cube with the UFR and UF positions unsolved

    For other twisty puzzles, see Other twisty puzzles.

  • input <prompt> <algorithm> max-input <number>

    This instruction facilitates arbitrary input from a user which will be stored and processed on the puzzle. To do so, repeat the given algorithm "your input" number of times. For example:

    Puzzles
    A: 3x3
    
    1 | input "Choose 0-5"
              R U R' U'
              max-input 5
    ...

    To input the number two, execute the algorithm (R U R' U') (R U R' U') on the Rubik's cube. Notice that if you try to execute R U R' U' six times, the cube will return to its solved state as if you had inputted the number zero. Thus, your input number must not be greater than five, and this is shown with the max-input 5 syntax.

    If a negative input is meaningful to the program you are executing, you can input negative one by performing the inverse of the algorithm. For example, negative two would be inputted as (U R U' R') (U R U' R').

  • halt <message> [<algorithm> counting-until <positions>]

    This instruction terminates the program and gives an output, and it is similar to the input instruction. To decode the output of the program, repeat the given algorithm until the positions given are solved (see the solved-goto instruction). The number of repetitions it took to solve the given pieces along with the specified message is considered the output of the program. For example:

    Puzzles
    A: 3x3
    
    1 | input "Choose 0-5"
              R U R' U'
              max-input 5
    2 | halt "You chose"
              U R U' R'
              counting-until UFR

    In this example, after performing the input and reaching the halt instruction, you would have to repeat U R U' R' until the UFR corner is solved. For example, if you inputted the number two by performing (R U R' U') (R U R' U'), the expected output will be two, since you have to perform U R U' R' twice to solve the UFR corner. Therefore, the expected output of the program is "You chose 2".

    If the program does not require giving a numeric output, then the algorithm may be left out. For example:

    Puzzles
    A: 3x3
    
    1 | halt "I halt immediately"
  • switch <letter>

    Put down your current puzzle and pick up a different one, labeled by letter in the Puzzles declaration. It is important that you do not rotate the puzzle when setting it aside or picking it back up. For example:

    Puzzles
    A: 3x3
    B: 3x3
    
    1 | U
    2 | switch B
    3 | R
    ...

    this program requires two Rubik's cubes to execute. The instructions indicate performing U on the first Rubik's cube and then R on the second. When the program starts, you are expected to be holding the first cube in the list.

Advanced instructions

The Q file format thus far is theoretically equivalent to a classical computer, as demonstrated in the computer architecture design section. This section details advanced instructions that the Q file format supports.

  • print <message> [<algorithm> counting-until <positions>]

    This is an optional instruction that you may choose to ignore. The print instruction serves as a secondary mechanism to produce output without exiting the program. The motivation stems from the fact that, without this instruction, the only form of meaningful output is the single number produced by the halt instruction.

    To execute this instruction, repeat the given algorithm until the positions are solved, analogous to the halt instruction. The number of repetitions this took is then the output of the print statement. Then, you must perform the inverse of the algorithm the same number of times, undoing what you just did and returning the puzzle to the state it was in before executing the print instruction. For example:

    Puzzles
    A: 3x3
    
    1 | R U R2 B2 U L U' L' D' R' D R B2 U2
    2 | print "This should output ten:"
              R U counting-until UFR UF
    3 | halt "This should also output ten:"
              R U counting-until UFR UF

    Like the halt instruction, including just a message is legal. In this case, you can skip this instruction as there is nothing to do. For example:

    Puzzles
    A: 3x3
    
    1 | print "Just a friendly debugging message :-)"
    ...

Talk about the stack here WIP (Henry you could write the rest of this section if you want)

  • push

    WIP

    Talking points:

    • Will need many puzzles
  • pop

    WIP

  • switch-top

    WIP

Other twisty puzzles

WIP

Talking points:

  • The Puzzles declaration accepts a hard-coded puzzle name or a PuzzleGeometry description
  • PuzzleGeometry is a format developed and designed by Tomas Rokicki that generates a puzzle definition from a simple description. You can read more about it here or use the format interactively on Twizzle Explorer (click "Config").

The QAT programming language

This section assumes moderate familiarity with an existing programming language, such as Python, JavaScript, or C.

Your first QAT program

A diagram of the qter compilation pipeline

If you have experience working with a compiled programming language, you know that to run a program, you compile your source code into machine code that the computer processor then interprets and executes. The qter compilation pipeline works similarly.

Qter's high level programming language is called QAT, or Qter Assembly Text.

WIP

Talking points:

  • bare bones QAT program without macros
    .registers {
        A, B <- 3x3 builtin (90, 90)
    }
    
        input "First number:" A
        input "Second number:" B
    sum_loop:
        add A 1
        add B 89
        solved-goto B found_sum
        goto sum_loop
    found_sum:
        add A 1
    divide_by_2:
        add A 89
        solved-goto A stop
        add A 89
        solved-goto A stop
        add B 1
        goto divide_by_2
    stop:
        halt "The average is" B
  • guide on how to use the CLI
  • explain variables (.registers declaration), labels, and primitive instructions

Metaprogramming

WIP

Talking points:

  • macros
  • .define
  • lua

Prelude

WIP

Talking points:

  • convenience macros like inc, dec, and control flow
  • Link to prelude and encourage its reference

The stack

WIP

Talking points:

  • functions and recursion

Computer architecture design

Qter is similar in many ways to how modern computers work, yet at the same time esoteric by nature. This section will start with a light background of how Rubik's cubes work and then elaborate on the unique properties that make qter possible.

Rubik's cube theory

WIP

Talking points:

  • Define move as a manipulation of the cube and algorithm as a sequence of moves
  • Optionally reintroduce standard move notation
  • Centers do not move
  • If you repeat a constant sequence of moves on the Rubik's cube starting from the solved state, you will eventually reach the solved state after enough repetitions & proof
  • The states that the repetitions of an algorithm visits before repeating form that algorithm's cycle
  • Define order as # of repetitions

Cycles are registers

WIP

Talking points:

  • A register is a unit of storage in a computer. Think of it like memory — it can stores a value and update the value stored any time
  • Use the U cycle to demonstrate a register of order 4 meaning it returns to its original state with 4 moves. Emphasize mod 4
  • The value of this cycle's corresponding register, is the Nth step (or index) of the algorithm
  • We have a way to increment a register by a constant
  • 1260 order is maximal [1] and not enough for any meaningful computation
  • Generalize the notion of a register to multiple cycles that coexist on the Rubik's cube
  • The set of pieces affected by a given cycle must not interfere with the set of pieces affected by any other cycle. Helpful to think no longer in terms of moves but in cycles as in these pieces may be moved but they are restored. If the pieces were to interfere, then this would mean modifying the value of one register has a side effect of modifying the value of another unintended register.
  • More registers mean more states 90*90 > 1260

Conditional branching

WIP

Talking points:

  • We have defined a way to represent a register on a Rubik's cube, but how does this bring us closer to a computer?
  • We are limited in what we can do if the only operation our computer is able to perform on its memory is adding a constant
  • Allow conditionally executing code
  • Recall from U cycle, when the pieces of a cycle are solved, the register value is 0 because there are zero repetitions of the algorithm
  • A piece is solved if the colors on each of its faces match the center of the corresponding side of a Rubik's cube
  • If a register value is zero, then we conditionally execute some code, if not, execute some other code

The Rubik's cube is a computer

WIP

Talking points:

  • store instruction memory separate to the cube
  • dissect an example
  • works with any twisty puzzle

Technical details

Cycle combination solver

Qter's cycle combination solver computes the optimal computer architecture for a puzzle using any amount of cycles.

Phase 1

WIP

Talking points

  • Based on [1]
  • Find all ways to assign cubies to orbits, then find the max order using partitions and priority queue
  • Pareto front

Phase 2

WIP

Talking points

  • Korf's algorithm
  • Symmetry and inverse reduction [2]

Experimental phase 3 with GAP

WIP

Talking points

  • Stabilizers
  • Conjugacy classes
  • Fork of optimal solver

About the authors

  • Arhan Chaudhary: Hi! I am a sophomore at Purdue University, and I have always been fascinated by Rubik's cubes since I learned how to solve them in middle school. I was greatly inspired by the Purdue Hackers community to begin this project, and have spent the better part of the entire school year working on it. I'm looking for Summer 2026 internships - and I'm particularly excited about working with startups. Read more about my work at my website.
  • Henry Rovnyak: (jumps off of a catwalk and lands behind you) Hello there! Like Arhan, I too am a sophomore at Purdue University. I'm interested in math and programming, and I met Arhan through this project and the Purdue Hackers community. I enjoy systems and scientific programming, but I also have a soft spot for theoretical work and frontend design. Arhan may or may not have gotten me addicted to cubes... I'm also interested in Summer 2026 internships, and you should consider checking out my website to see some of the other stuff I've been working on.
  • Asher Gray: Hello! I'm a data analyst and youtuber from the PNW. I started off making videos about solving Rubik's cubes blindfolded, and now focus on math and fun ways to visualize it. Lately I've been studying the theory of abelian groups, including the abelian subgroups of the Rubik's cube. I'm excited to have joined this project, such an interesting application of these ideas! You can find me on YouTube or enjoy some interactive math visualizations on my website.

References

[1] Bergvall, O., Hynning, E., Hedberg, M., Mickelin, J., & Masawe, P. (2010). On Rubik’s cube. Report, KTH Royal Institute of Technology (pp. 65-79).
[2] Rokicki, T., Kociemba, H., Davidson, M., & Dethridge, J. (2014). The diameter of the rubik's cube group is twenty. siam REVIEW, 56(4), 645-670.

Acknowledgements

About

A human-friendly Rubik's cube computer (WIP)

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Contributors 4

  •  
  •  
  •  
  •