Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature Request: Compose Scrambles #77

Open
DougCube opened this issue Dec 24, 2024 · 11 comments
Open

Feature Request: Compose Scrambles #77

DougCube opened this issue Dec 24, 2024 · 11 comments

Comments

@DougCube
Copy link

It would be good to have a way to compose scrambles (of different formats):

  1. state ∘ state => state
  2. state ∘ alg => state
  3. alg ∘ state => state
  4. alg ∘ alg => state
  5. alg ∘ alg => alg

Number 2 is the most useful in the flow of creating multi-stage solvers that start from a state instead of an alg. (Which is needed in random-state scramble generators, you generate a random state, solve it, and the inverse of the solve alg is the scramble alg.) Number 1 seems to be the most basic to include since --showpositions has a mechanism to convert algs to states anyways. Thus, having a way to accomplish 1 can give 2, 3, and 4 nearly for free. I can't think of a situation requiring number 3, but might as well. Number 5 is trivial, but listed for completeness sake.

@lgarron
Copy link
Member

lgarron commented Dec 24, 2024

If you are using JavaScript or Rust, then cubing/kpuzzle and cubing::kpuzzle are quite fully featured. Are you able to use either of those?

@DougCube
Copy link
Author

Maybe, but it's written in TypeScript and I never learned it. I mainly code in C/C++.
The KPuzzle documentation might be more useful with examples of usage. I started looking into using Cubing/Alg for other needs but it doesn't do everything I want, such as giving the alg length in OBTM, and I doubt it supports puzzles besides 3x3x3 since the walkthrough doesn't show setting a puzzle.

Obviously, I'm trying to chain together executions of TWSearch.
I'm tempted to write a program that does this sort of scramble composition thing.
I also plan on making one to generate definition files.

@lgarron
Copy link
Member

lgarron commented Dec 26, 2024

The KPuzzle documentation might be more useful with examples of usage. I started looking into using Cubing/Alg for other needs but it doesn't do everything I want, such as giving the alg length in OBTM, and I doubt it supports puzzles besides 3x3x3 since the walkthrough doesn't show setting a puzzle.

Thanks, that's very useful to know! We do indeed have support for this but currently only for 3x3x3:

import { Alg } from "cubing/alg";
import {
  ExperimentalCommonMetric,
  experimentalCountMetricMoves,
} from "cubing/notation";
import { cube3x3x3 } from "cubing/puzzles";

console.log(
  experimentalCountMetricMoves(
    cube3x3x3,
    ExperimentalCommonMetric.OuterBlockTurnMetric,
    new Alg("[2U, r' D r]"),
  ),
);

https://codepen.io/lgarron/pen/RNbgmYJ?editors=1010

I've filed cubing/cubing.js#350 to keep track of this.

@lgarron
Copy link
Member

lgarron commented Dec 26, 2024

Obviously, I'm trying to chain together executions of TWSearch.
I'm tempted to write a program that does this sort of scramble composition thing.

For what it's worth, we're working on phase composition in the Rust code, and I want a good API for this. If you would like to describe any details about your use case, they'd be helpful!

@DougCube
Copy link
Author

I was just going to have a Bash script that made iterative calls to twsearch with different definition files and construct intermediate scramables between each call. It works fine when the initial scramble is an alg, but when it is a state, such as for implementing a random-state solver (leading to a random-state scramble generator), then it's not clear how to tack on a partial solution alg to the initial state.

I ended up spending a few hours today and coding up an entire TWS definition file parser that produces data structures making it easy to apply moves to a puzzle state. But it's probably only 1/3 of the way done... I need to use a portion of it to parse a SCR file, then execute the moves on to the state, then print the new state.

@DougCube
Copy link
Author

There would have to be a way to specify an accending series of puzzle definitions somehow. For example, on of my intermediate CH2 definitions has TIPs and WINGs omitted, just CORNERs and MIDGEs, but I partition the 24 MIDGEs into three sets of 8 for each of M/E/S. The original, full definition file has tip turn moves that are no-ops at this stage, and I need a way to handle stuff like that gracefully. Currently, TWSearch errors-out when reading an alg that includes such moves.

@lgarron
Copy link
Member

lgarron commented Dec 26, 2024

Sounds like you could use apply_mask(…).

pub(crate) fn apply_mask(
source_pattern: &KPattern,
mask_pattern: &KPattern,
) -> Result<KPattern, PuzzleError> {

Would you be interested in doing a video call pairing session some time to see what we can apply to your solver?

Alternatively, do you already have definitions for all the intermediate states?

@DougCube
Copy link
Author

I have never learned Rust. I probable should tho.
I just finished coding a program to do what I need in applying algs to states.
I've done a fair bit of validation on it now and might change the github for it to public.

And for doing that sort of masking, I wrote a small Bash script:

if [ "$#" -lt 1 ]; then
    echo "ERROR: the syntax is '$0 <tws file> [set1 to remove] [set2 to remove]...'!" >&2
    exit 1
fi

file="$1"; shift
temp1="/tmp/def_omit_sets1.out"
temp2="/tmp/def_omit_sets2.out"

# remove comments and leading empty lines
sed '/#/d;/./,$!d' "$file" > "$temp1"

for x in "$@"; do
    sed -r 's/^Name ([^[:space:]]+)/Name \1_NO_'"$x"'/;/^Set '"$x"'/d' "$temp1" > "$temp2"
    awk '/^'"$x"'/{f=1; next} f && !/^[0-9]/{f=0} !f' "$temp2" > "$temp1"
done
sed -r -z 's/Move [^[:space:]]+\nEnd\n\n//g' "$temp1"

The last line removes the Moves which are rendered null. And I append something useful to the puzzle "Name" field.

@rokicki
Copy link
Collaborator

rokicki commented Dec 27, 2024 via email

@DougCube
Copy link
Author

That would have been good to know a few days ago. But I immediately started coding up my own *.tws and *.scr file parser and got it working. Composing the permutations forwards and backwards was obvious, but I couldn't figure out how to compose the orientations with it until I wrote tiny testcases and ran a bunch of --showpositions commands to reverse-engineer a correct procedure.

It took me 290 lines of C code and is very robust, but can only handle moves like U, U2, ..., U9 and U', U2', ..., U9' whereas after experiementing I found that TWsearch can handle two-digit move-multipliers, or at least show them when giving the "Created new moves" line.

@DougCube
Copy link
Author

Alternatively, do you already have definitions for all the intermediate states?

I'm revisiting a project I was working on 13 months ago, and got a full CH2 solver down to 14 stages with a lot of intermediate definition files created -- way more than 14 while trying different options. My first test scramble was a random-move scramble from the Steven's python scramble generator. I could keep appending to the scramble manually. But the goal was always to generate a random-state to solve. I incorrectly assumed that TWSearch was capable of generating random-state scrambles, but now that I looked into it, it's random 500-move, and without a way to specify the length. TWSearch should probably implement a random-state generator.

When I got a multi-stage procedure working, I switched to using a state scramble input, but faced this major hurdle of composing alg with initial state and appearently gave up back then. I've picked it up after working on other things like an FTO solver.

But recently, it's occured to me that the first stage I have it running takes far too long and am suspecting a performance issue in TWSearch itself when dealing with the large set of canonical moves and perhaps not pruning agressively enough.

A bit off topic: I now have a nifty FTO solver that converts input scramble to wide moves, then runs TWSearch with only U,F,L,R,Uw,Fw,Lw,Rw moves, then converts output algs back to U,F,L,R,D,B,BR,BL to leverage having locked corner piece in the back and only needing to define 2 orientations for corner pieces instead of 4.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants