My python one-liner scramble generator

towwdso

Member
Joined
Sep 13, 2010
Messages
22
274 bytes
its a world record, I guess. (until someone do it on perl...)
Code:
c,a,l,f,g=__import__('random').choice,['FB','UD','RL'],[],lambda y:lambda x:x in y,lambda y:lambda x:x not in y;h=[l.append(c(filter(g(l[-1:]),c(filter(g(filter(f(a),[''.join(l[-2:][::x]) for x in [-1,1]])),a))))) for u in range(25)];print ' '.join([h+c(" '2",) for h in l])

It works. copy and paste onto python interpreter. Or save it on a .py file.
You could also tweak it to generate a lot of scrambles:

just put a
Code:
for n in range(12):
in the beggining,
and in DOS do:

Code:
scramble.py > output.txt

result:

file: output.txt
---------------------------------------------------------------------------------------
R' U2 D' L' R' D2 R2 U F B L' U B D F U' F' L' B' F' L' U2 D' R D2
B' U2 D2 F L R B' U2 D F' R F' R' B' F' R L2 D' B F D U R2 L2 U2
D2 U2 F L2 D F B' U D F B L' R' U' D' R2 F L2 D' U2 L2 B' R F U
L B' D U2 R2 B2 F' D' U2 L' F' B U' D F2 L' R B2 F2 U' D L' B U L'
F' U2 F2 B2 D' U L U2 B L B2 R F D2 R' U B2 L2 R' U2 D2 B U' L U
D U2 F U B2 L2 R U D2 R' U F' U L2 R B2 F' U R' D' B F' L' U L
R D2 U' R' F R L2 U' F' U' D' L2 D' B2 U' D' L R F2 D U2 F' B2 R L
D2 U' R U' L R F U' D R' U' F D R2 B' R' B2 R F' B2 U B F' L' U2
D2 U2 F B2 L' R2 U L2 U2 L2 D B' F U D' F B' D' U B' F' L D L' B'
D U' L' D' U' F' D' U2 L' R' B D2 F' B' L F' R' L2 F R U R B2 F U

:)

EDIT:
Code:
from random import*;c=choice;w,l=['RL','UD','BF'],[]
for u in range(25):
 a=c(w)
 if sum([ord(x) for x in l[-2:]]) in [158,153,136]:
  while l[-1] in a:a=c(w)
 t=c(a)
 while l[-1:]==[t]:t=c(a)
 l=l+[t]

print ' '.join([x+c(" '2") for x in l])
============================================

from random import*;c=choice;w,l=['RL','UD','BF'],[]
def k():
 m=[y.replace(l[-1],'') for y in w] if l[-1:] else w
 h=[int(''.join(l[-2:]) in [x,x[::-1]]) for x in w]
 if 1 in h:m.pop(h.index(1))
 return m

for u in range(25):
 l.append(c(c(k())))

print ' '.join([x+c(" '2") for x in l])
first is 242 chars but is brute force.
second is 288 chars but is more pythonic.
 
Last edited:
That's kind of horrible looking, and I'm not sure 275ish characters counts as a single line, but nice job.

EDIT: hey, since you're only using d once, could you do this?:
Code:
c,a,l,f,g=__import__('random').choice,['FB','UD','RL'],[],lambda y:lambda x:x in y,lambda y:lambda x:x not in y;h=[l.append(c(filter(g(l[-1:]),c(filter(g(filter(f(a),[''.join(l[-2:][::x]) for x in [-1,1]])),a))))) for u in range(25)];print ' '.join([h+c(" '2") for h in l])
 
Last edited:
its a world record, I guess. (until someone do it on perl...)

Or Mathematica.

Code:
StringJoin[ToString[#]<>(c=RandomChoice)[{" ","' ","2 "}]&/@(Flatten[RandomSample[#,Ceiling[Random[]*5/4]]&/@c[{{U,R},{F,B},{L,D}},25]]//.{a___,b_,b_,c___}:>{a,b,c})]

167 chars, still not tweetable. But I'm sure I could get it there, and coders like Stefan, Kociemba, or Rokicki could probably destroy us.
 
until someone do it on perl...

120 chars.

Code:
map{while(($m=int rand 6)==$b||($c+$b==5&&$c==$m)){}print qw(U R F B L D)[$m].qw( ' 2)[int rand 3]." ";$c=$b;$b=$m}1..25

But yeah, like Lucas said, I'm sure there's a bunch of people who could destroy this, since mine is pretty basic.

Edit: 115

Code:
map{$m=int rand 6while$c+$b==5&&$c==$m||$m==$b;print qw(U R F B L D)[$m].qw( ' 2)[int rand 3]." ";$c=$b;$b=$m}1..25

>_>
 
Last edited:
@qqref: yes, It was late night, I'll try to optmise the code some more now. mwahaha >:)
@VP7: yeah, it would be great too se your code.

ok guys, I don't have mathemathica or perl installed here (i had), but you know that the code should output a legal scramble right?
legal scramble: R L' U B U R2 L2 U B' L F2 ... etc
illegal scramble: U U' U2 U' U B F B F B F B F B2 B' B B B U R L' R R2 R R R R R R R R R R R ... you see what I mean
 
Ruby (1.9):
Code:
turns = [%w{R L}, %w{F B}, %w{D U}]
axis = rand t.size
output = (1..25).map do
  axis = (axis + rand(turns.size - 1) + 1) % turns.size
  t[axis].sample + ['', "'", '2'].sample
end.join(' ')

p output

That's 199 characters and it's still readable and pretty generic (it can be used to generate scrambles for cubes of all sizes).

After obfuscating it a bit, i got it down to 111 characters:
Code:
a=rand 3
o=(1..25).map{a=(a+rand(2)+1)%3;[%w{R L},%w{F B},%w{D U}][a].sample+['',"'",'2'].sample}.join(' ')
p o

Using p instead of puts is probably cheating, though. And i'm sure anyone who really knows Ruby can get this sub-100. I didn't spend more than a few minutes on it and i only used the most obvious shortcuts (like replacing variable names with its content).

sub 277 bytes

So you mean 276 bytes? Or 275 bytes? Or 200 bytes? Or 142 bytes? WTF? "sub" is really the most overused term amongst cubers. It's so annoying...
 
Last edited:
tim:

Doesn't run for me on Ruby 1.8.7, not sure what the exact problem is. But I can't run your code to verify?
Is your program capable of generating U2 D2 in a row? Ours are, and that's a good part of the challenge. ;-)
 
Last edited:
Doesn't run for me on Ruby 1.8.7, not sure what the exact problem is.
Yep, you need 1.9 for Array#sample

1) Does a actually need to be initialized randomly? Can save 5 bytes that way.
Yes, otherwise your first move will always be U/D.

2) Is your program capable of generating U2 D2 in a row? Ours are, and that's a good part of the challenge. ;-)

Of course not, since that would make the code longer ;). Actually i didn't know that's necessary. I might give it another try then.
 
So you mean 276 bytes? Or 275 bytes? Or 200 bytes? Or 142 bytes? WTF? "sub" is really the most overused term amongst cubers. It's so annoying...

I meant exactly 277 bytes. I wrote sub 1kb then I checked the atual size and just replaced 1KB with 277 bytes. my fault
now its 274 bytes actually. it's optimal, from the aproach I did.
 
I found that generating a single scramble of lenght 25000 is faster than generating 1000 scrambles of lenght 25 by 0.0092000007629999825 seconds. =P

generating 1000 scrambles times:
0.766000032425,
0.781000137329,
0.75,
0.81200003624,
0.75,
0.81299996376,
0.75,
0.796999931335,
0.765000104904,
0.827999830246

generating a single scramble of lenght 25000:

0.75,
0.765000104904,
0.780999898911,
0.719000101089,
0.81299996376,
0.766000032425,
0.81299996376,
0.766000032425,
0.796999931335,
0.75

obs: generating a single scramble and divide it later would not allow the second scramble to start with the last face turn.
example:
1) U R2 F B
2) B L2 U' F
woudn't happen
 
Last edited:
I tried my hand at JavaScript.

224 (EDIT: 216) chars:
Code:
function r(x){return Math.floor(Math.random()*x)}function s(){var d=b=j=c=a=4;for(;j<29;j++){while(a==c&&(d&b)>0){a=r(3);b=r(2)+1}if(a!=c)d=0;c=a;d+=b;document.write("RLFBUD".charAt(a*2+b-1)+" 2'".charAt(r(3))+" ")}}
 
Last edited:
i tried to make a scrambler and im doing it in batch because its the only thing i know. so what i have now is it generate a random number and depending on the number assign the move. and i know how to stop it from repeating moves, but i dont know how to repeat it for the 25 moves (i know about goto start, but i need different variables). the only thing i can think of is to repeat the code and change say %move1% to %move2% and so on. then display the scramble as: %move1% %move2% ...
how can i make it loop but use different variables?
 
Of course not, since that would make the code longer ;). Actually i didn't know that's necessary. I might give it another try then.
I think the distribution actually becomes better if you constantly change axes, but don't quote me on that. And it doesn't change the standard we're trying to match with programs here..
 
Code:
a=rand 3
p (1..25).map{a=(a+rand(2)+1)%3;[%w{R L},%w{F B},%w{D U}][a].sample+["","'","2"].sample}*" "
Just a few changes to tim's. Should work fine.
 
Back
Top