Welcome to the Speedsolving.com, home of the web's largest puzzle community! You are currently viewing our forum as a guest which gives you limited access to join discussions and access our other features.

Your code seems to make every other move an R or L turn, and the rest are never R or L turns. This does avoid canceling moves but it also provides far less possibilities than a normal scramble. The other scramblers in the thread were made to use all of the moves equally but also avoid cancellations - it's a little trickier, but see if you can make one that does that.

Edit: Typical output:
"U R F2 B' R2 U' D2 L2 U' L B' L2 U2 B' F U' L2 R D' B' D2 F U' R2 L' "
And you can get K from kx.com, they have a Q console and from there you can press \ to switch between Q and K. K is a lot less verbose but is missing several useful functions.

Only 63 characters, by my count. I think that's pretty solid.
(I had one that was 61 before until I realized it didn't allow sequences starting with 5.)

Explanation of what it does:

Spoiler

Let's first dissect this weird-looking function: {#&(=':x),2_&':5=+':x}. The curly braces signify a function, and it's implied that the argument is x, so we don't need to declare it. The expression f':x for a function f basically returns the list you get from applying f to each adjacent pair of elements of x. So +':x gives us a list of sums of two adjacent elements. 5=+':x gives us a list of bits, with a 1 set in every position where the sum of two adjacent elements is equal to 5. &':5=+':x gives us another list of bits, but this time there is a 1 only when there were two sums-to-5 in a row (which in this case represents sequences like LRL or UDU). The 2_ removes the first two elements from that so we don't get problems with sequences that start with 5 or 5 0. So that part gives us a 1 for each LRL-type sequence. The part to the left of the comma, =':x, gives us another list of bits, with a 1 for each repeated number (so, a sequence like RR). The comma joins those two sequences together; and then the #& at the left returns the number of 1s we have. So this whole function ends up giving us the number of bad sequences in our potential scramble.

In the middle we have {stuff}{25?6}/2#2. 2#2 makes a list of two 2's so we have (2 2) there. So what does this thing do? Well, f g/ x (with f and g functions) applies g to x repeatedly until f of the result is zero. Now 25?6 generates a list of 25 random integers from 0 to 5, so we are generating lists of 25 random integers until they pass the first function (i.e. the result is 0). We needed that 2#2 so the function would start off giving a 1; otherwise the expression would immediately terminate. Notice that a list passes the first function if it has zero mistakes - that is, the list of faces to move is valid. So great - now we have generated a random list of 25 faces until it was valid for making a scramble out of. The list will look something like this: 0 3 2 5 3 0 3 5 ...

The rest is more straightforward. Let's call the part we looked at so far X; then we have ,/("FRUDLB"@X),'25?" ","'2",'" ". The "FRUDLB"@X just indexes our list into the string "FRUDLB" so now we have a list of 25 letters, such as "FDUBDFDB...". The " ","'2",'" " at the far right generates a list of the 3 possible suffixes (" ", "' ", and "2 ") and the 25? chooses 25 random suffixes, just like the previous use of it. Finally, the ,' joins each move letter up with one of the suffixes, and the ,/ at the beginning takes the whole list of strings and joins it together into one. Pretty tricky, but it makes sense if you analyze it.

Let's first dissect this weird-looking function: {#&(=':x),2_&':5=+':x}. The curly braces signify a function, and it's implied that the argument is x, so we don't need to declare it. The expression f':x for a function f basically returns the list you get from applying f to each adjacent pair of elements of x. So +':x gives us a list of sums of two adjacent elements. 5=+':x gives us a list of bits, with a 1 set in every position where the sum of two adjacent elements is equal to 5. &':5=+':x gives us another list of bits, but this time there is a 1 only when there were two sums-to-5 in a row (which in this case represents sequences like LRL or UDU). The 2_ removes the first two elements from that so we don't get problems with sequences that start with 5 or 5 0. So that part gives us a 1 for each LRL-type sequence. The part to the left of the comma, =':x, gives us another list of bits, with a 1 for each repeated number (so, a sequence like RR). The comma joins those two sequences together; and then the #& at the left returns the number of 1s we have. So this whole function ends up giving us the number of bad sequences in our potential scramble.

In the middle we have {stuff}{25?6}/2#2. 2#2 makes a list of two 2's so we have (2 2) there. So what does this thing do? Well, f g/ x (with f and g functions) applies g to x repeatedly until f of the result is zero. Now 25?6 generates a list of 25 random integers from 0 to 5, so we are generating lists of 25 random integers until they pass the first function (i.e. the result is 0). We needed that 2#2 so the function would start off giving a 1; otherwise the expression would immediately terminate. Notice that a list passes the first function if it has zero mistakes - that is, the list of faces to move is valid. So great - now we have generated a random list of 25 faces until it was valid for making a scramble out of. The list will look something like this: 0 3 2 5 3 0 3 5 ...

The rest is more straightforward. Let's call the part we looked at so far X; then we have ,/("FRUDLB"@X),'25?" ","'2",'" ". The "FRUDLB"@X just indexes our list into the string "FRUDLB" so now we have a list of 25 letters, such as "FDUBDFDB...". The " ","'2",'" " at the far right generates a list of the 3 possible suffixes (" ", "' ", and "2 ") and the 25? chooses 25 random suffixes, just like the previous use of it. Finally, the ,' joins each move letter up with one of the suffixes, and the ,/ at the beginning takes the whole list of strings and joins it together into one. Pretty tricky, but it makes sense if you analyze it.

I'm obviously not gonna explain this in full detail, but the general gist is that we get a random position and then try 1, 2, ... moves until we find a solution. We look for solutions of n moves by generating all positions ceiling(n/2) moves away from solved and all positions floor(n/2) moves away from our position, and then matching every pair of elements and seeing if we get any successes. This isn't the fastest possible way to do this but it seems fast enough.

Sample output:
q)scramble[]
"U2 F2 U F2 U R2 U2 F R'"

Cool thing: this is actually significantly faster than the previous one, and the biggest reason is using "a[1]inter b 1" instead of "(raze a[1]~/:\:b 1)?1b". The old one would take about 10 seconds for particularly hard scrambles, but this one can do 100 scrambles in about 10 seconds.

from random import randint as r;a=b=8
for x in range(25):
c=b;b=a
while (a==b)+(a+b-5)*(a==c):a=r(0,5)
print("URFBLD"[a]+" '2"[r(0,2)])

A "one-liner":

Code:

from random import randint as r;d=[r(0,5) for x in range(50)];print(''.join(["URFBLD"[[d[y] for y in range(2,50) if 1-((d[y]==d[y-1])+(d[y]+d[y-1]-4)*(d[y]==d[y-2]))][z]]+" '2"[r(0,2)] for z in range(2,27)]))

Dayum, nice. I don't know much about Python, actually virtually nothing, but it looks extremely condensed.
I think I can pick up on certain things about the code that make sense to me though, so it isn't foreign language or anything, it just seems super cool how little code is required lol.

Bump because I think this is a cool thread and I think I have a kind of cute Ruby (2.0) solution

Code:

p (1..1.0/0).lazy.map{(1..25).map{"UDLRFB"[rand 6]}.join}.find{|s|!(/(.)\1|(UDU|DUD|LRL|RLR|FBF|BFB)/=~s)}.each_char.map{|c|c+["","'","2"].sample}.join" "

Neated up a bit with explanations:

Code:

p (1..1.0/0).lazy # infinite lazy enumerator
.map { (1..25).map { "UDLRFB"[rand 6] }.join } # make each element a list of faces
.find { |s| !(/(.)\1|(UDU|DUD|LRL|RLR|FBF|BFB)/ =~ s) } # find one that doesn't duplicate moves or RLR etc
.each_char.map { |c| c + ["","'","2"].sample } # suffixes
.join " "

Not the shortest at 154 chars, I'd like to see some improvements on it though!

I also didn't see any other functional-ish solutions, although I might have missed some. I'd like to see some functional attempts by others.

I think it might be similar to this one, but I'm not familiar enough with Perl to tell.

It's somewhat similar, but it appends one move at a time and chops it off if it causes a violation, repeat until 25 moves are built. Those like yours started with Michael's request [post=485880]two posts later[/post].

It's somewhat similar, but it appends one move at a time and chops it off if it causes a violation, repeat until 25 moves are built. Those like yours started with Michael's request [post=485880]two posts later[/post].

instead of initialising Math.random in r before the for loop, you could just move it to the c-part of a?b:c as it was unused anyway and we are not using the random function before that.

Python(128):

Code:

import random as l;r=l.randrange;a=2
for c in"a"*25:
b=a
while(a==b)+(a+b==5)*(a==c):a=r(6)
print"URFBLD"[a]+" '2"[r(3)],;c=b

So code that does strange stuff like U2 U2 isn't allowed(and strange spacing)?

If not:

Code:

from random import randint as r;m,l="UDLRFB"," '2";print " ".join(m[r(0,5)]+l[r(0,2)]for i in range(25))
[\code]
106 characters[/QUOTE]
you need:
fair distribution of moves
no moves on the same face after each other
no moves of the opposite face of the previous move but only if the past two were also opposite face turns